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.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



510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'lib/musa-dsl/music/scales.rb', line 510

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)


541
542
543
# File 'lib/musa-dsl/music/scales.rb', line 541

def a_frequency
  @a_frequency
end

#scale_systemClass<ScaleSystem> (readonly)

The parent scale system.

Returns:



545
546
547
# File 'lib/musa-dsl/music/scales.rb', line 545

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



725
726
727
728
729
# File 'lib/musa-dsl/music/scales.rb', line 725

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:



577
578
579
# File 'lib/musa-dsl/music/scales.rb', line 577

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:



595
596
597
# File 'lib/musa-dsl/music/scales.rb', line 595

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:



560
561
562
# File 'lib/musa-dsl/music/scales.rb', line 560

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



734
735
736
# File 'lib/musa-dsl/music/scales.rb', line 734

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 526

#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



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

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:



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
# File 'lib/musa-dsl/music/scales.rb', line 628

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:



668
669
670
671
672
673
674
675
# File 'lib/musa-dsl/music/scales.rb', line 668

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