Class: Musa::Scales::ScaleSystemTuning

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/musa-dsl/music/scales.rb

Overview

Scale system with specific A frequency tuning.

ScaleSystemTuning combines a ScaleSystem with a specific reference A frequency, providing access to scale kinds (major, minor, chromatic, etc.) tuned to that frequency.

Usage

Tunings are created via Musa::Scales::ScaleSystem.[]:

tuning = Scales[:et12][440.0]     # Standard pitch
baroque = Scales[:et12][415.0]    # Baroque pitch

Accessing Scales

By symbol:

tuning[:major][60]     # C major scale

By method name:

tuning.major[60]       # C major scale
tuning.minor[69]       # A minor scale

Chromatic scale:

tuning.chromatic[60]   # C chromatic scale

Examples:

Standard usage

tuning = Scales::Scales.default_system.default_tuning
c_major = tuning.major[60]
a_minor = tuning.minor[69]

Historical pitch

baroque = Scales[:et12][415.0]
scale = baroque.major[60]  # C major at A=415Hz

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(scale_system, a_frequency) ⇒ ScaleSystemTuning

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a tuning instance for a scale system.

Parameters:

  • scale_system (Class<ScaleSystem>)

    the ScaleSystem subclass

  • a_frequency (Numeric)

    reference A frequency in Hz



469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'lib/musa-dsl/music/scales.rb', line 469

def initialize(scale_system, a_frequency)
  @scale_system = scale_system
  @a_frequency = a_frequency
  @scale_kinds = {}

  @chromatic_scale_kind = self[@scale_system.chromatic_class.id]

  @scale_system.scale_kind_classes.each_key do |name|
    define_singleton_method name do
      self[name]
    end
  end
end

Instance Attribute Details

#a_frequencyFloat (readonly)

Reference A frequency in Hz.

Returns:

  • (Float)


500
501
502
# File 'lib/musa-dsl/music/scales.rb', line 500

def a_frequency
  @a_frequency
end

#scale_systemClass<ScaleSystem> (readonly)

The parent scale system.

Returns:



504
505
506
# File 'lib/musa-dsl/music/scales.rb', line 504

def scale_system
  @scale_system
end

Instance Method Details

#==(other) ⇒ Boolean

Checks tuning equality.

Tunings are equal if they have the same scale system and A frequency.

Parameters:

Returns:

  • (Boolean)

    true if equal



684
685
686
687
688
# File 'lib/musa-dsl/music/scales.rb', line 684

def ==(other)
  self.class == other.class &&
      @scale_system == other.scale_system &&
      @a_frequency == other.a_frequency
end

#chromaticScaleKind

Returns the chromatic scale kind.

Provides access to the chromatic scale, which contains all pitches in the scale system. Used as fallback for non-diatonic notes.

Examples:

tuning.chromatic[60]   # Chromatic scale at C

Returns:

  • (ScaleKind)

    chromatic scale kind instance

See Also:



536
537
538
# File 'lib/musa-dsl/music/scales.rb', line 536

def chromatic
  @chromatic_scale_kind
end

#frequency_of_pitch(pitch, root) ⇒ Float

Calculates frequency for a MIDI pitch.

Delegates to the scale system's frequency calculation using this tuning's A frequency as reference.

Examples:

tuning.frequency_of_pitch(69, 60)  # => 440.0 (A4)
tuning.frequency_of_pitch(60, 60)  # => ~261.63 (C4)

Parameters:

  • pitch (Numeric)

    MIDI pitch number (60 = middle C)

  • root (Numeric)

    root pitch of the scale (for non-equal temperaments)

Returns:

  • (Float)

    frequency in Hz

See Also:



554
555
556
# File 'lib/musa-dsl/music/scales.rb', line 554

def frequency_of_pitch(pitch, root)
  @scale_system.frequency_of_pitch(pitch, root, @a_frequency)
end

#get(scale_kind_class_id) ⇒ ScaleKind Also known as: []

Retrieves a scale kind by ID.

Creates and caches Musa::Scales::ScaleKind instances for efficient reuse.

Examples:

tuning[:major][60]   # C major scale
tuning[:minor][69]   # A minor scale

Parameters:

  • scale_kind_class_id (Symbol)

    scale kind identifier (e.g., :major, :minor)

Returns:

Raises:

  • (KeyError)

    if scale kind not found

See Also:



519
520
521
# File 'lib/musa-dsl/music/scales.rb', line 519

def get(scale_kind_class_id)
  @scale_kinds[scale_kind_class_id] ||= @scale_system.scale_kind_class(scale_kind_class_id).new self
end

#inspectString Also known as: to_s

Returns string representation.

Returns:

  • (String)

    human-readable description



693
694
695
# File 'lib/musa-dsl/music/scales.rb', line 693

def inspect
  "<ScaleSystemTuning: scale_system = #{@scale_system} a_frequency = #{@a_frequency}>"
end

#notes_in_octaveInteger

Returns the number of notes in one octave. Delegated from Musa::Scales::ScaleSystem.notes_in_octave.

Returns:

  • (Integer)

    notes per octave (e.g., 12 for chromatic)



# File 'lib/musa-dsl/music/scales.rb', line 485


#offset_of_interval(name) ⇒ Integer

Returns semitone offset for a named interval. Delegated from Musa::Scales::ScaleSystem.offset_of_interval.

Parameters:

  • name (Symbol)

    interval name (e.g., :M3, :P5)

Returns:

  • (Integer)

    semitone offset



496
# File 'lib/musa-dsl/music/scales.rb', line 496

def_delegators :@scale_system, :notes_in_octave, :offset_of_interval

#scale_kinds(**metadata_criteria) {|kind_class| ... } ⇒ Array<ScaleKind>

Returns scale kinds matching the given metadata criteria.

Without arguments, returns all registered scale kinds. With keyword arguments, filters by metadata values. With a block, filters using custom predicate on ScaleKind class.

Examples:

All scale kinds

tuning.scale_kinds
# => [major_kind, minor_kind, dorian_kind, ...]

Filter by metadata

tuning.scale_kinds(family: :diatonic)
tuning.scale_kinds(brightness: -1..1)
tuning.scale_kinds(character: :jazz)

Filter with block

tuning.scale_kinds { |klass| klass.[:has_leading_tone] }

Combined

tuning.scale_kinds(family: :greek_modes) { |klass| klass.[:brightness] < 0 }

Parameters:

  • metadata_criteria (Hash)

    metadata key-value pairs to match

Yields:

  • (kind_class)

    optional block for custom filtering

Yield Parameters:

  • kind_class (Class<ScaleKind>)

    the ScaleKind subclass

Yield Returns:

  • (Boolean)

    true to include this scale kind

Returns:

See Also:



587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/musa-dsl/music/scales.rb', line 587

def scale_kinds(**, &block)
  result = @scale_system.scale_kind_classes.keys.map { |id| self[id] }

  unless .empty?
    result = result.select do |kind|
      matches_metadata?(kind.class, )
    end
  end

  if block
    result = result.select { |kind| block.call(kind.class) }
  end

  result
end

#search_chord_in_scales(chord, roots: nil, **metadata_criteria) ⇒ Array<Musa::Chords::Chord>

Searches for a chord across multiple scale types.

Iterates through the specified scale kinds and pitch roots to find all scales that contain the given chord. Returns chords with their containing scale as context.

Examples:

Search G7 in greek mode scales

tuning = Scales.et12[440.0]
g7 = tuning.major[60].dominant.chord :seventh
tuning.search_chord_in_scales(g7, family: :greek_modes)

Search with brightness filter

tuning.search_chord_in_scales(g7, brightness: -1..1)

Search in all scale types

tuning.search_chord_in_scales(g7)

Parameters:

  • chord (Musa::Chords::Chord)

    the chord to search for

  • roots (Range, Array, nil) (defaults to: nil)

    pitch offsets to search (default: 0...notes_in_octave)

  • metadata_criteria (Hash)

    metadata filters for scale kinds

Returns:

See Also:



627
628
629
630
631
632
633
634
# File 'lib/musa-dsl/music/scales.rb', line 627

def search_chord_in_scales(chord, roots: nil, **)
  roots ||= 0...notes_in_octave
  kinds = filtered_scale_kind_ids(**)

  kinds.flat_map do |kind_id|
    self[kind_id].find_chord_in_scales(chord, roots: roots)
  end
end