Class: HeadMusic::Rudiment::Tempo

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/rudiment/tempo.rb

Overview

Represents a musical tempo with a beat value and beats per minute

Constant Summary collapse

SECONDS_PER_MINUTE =
60
NANOSECONDS_PER_SECOND =
1_000_000_000
NANOSECONDS_PER_MINUTE =
(NANOSECONDS_PER_SECOND * SECONDS_PER_MINUTE).freeze
NAMED_TEMPO_DEFAULTS =
{
  larghissimo: ["quarter", 24],       # 24–40 bpm
  adagissimo: ["quarter", 32],        # 24–40 bpm
  grave: ["quarter", 32],             # 24–40 bpm
  largo: ["quarter", 54],             # 40–66 bpm
  larghetto: ["quarter", 54],         # 44–66 bpm
  adagio: ["quarter", 60],            # 44–66 bpm
  adagietto: ["quarter", 68],         # 46–80 bpm
  lento: ["quarter", 72],             # 52–108 bpm
  marcia_moderato: ["quarter", 72],   # 66–80 bpm
  andante: ["quarter", 78],           # 56–108 bpm
  andante_moderato: ["quarter", 88],  # 80–108 bpm
  andantino: ["quarter", 92],         # 80–108 bpm
  moderato: ["quarter", 108],         # 108–120 bpm
  allegretto: ["quarter", 112],       # 112–120 bpm
  allegro_moderato: ["quarter", 116], # 116–120 bpm
  allegro: ["quarter", 120],          # 120–156 bpm
  molto_allegro: ["quarter", 132],    # 124–156 bpm
  allegro_vivace: ["quarter", 132],   # 124–156 bpm
  vivace: ["quarter", 156],           # 156–176 bpm
  vivacissimo: ["quarter", 172],      # 172–176 bpm
  allegrissimo: ["quarter", 172],     # 172–176 bpm
  presto: ["quarter", 180],           # 168–200 bpm
  prestissimo: ["quarter", 200]      # 200 bpm and over
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(beat_value, beats_per_minute) ⇒ Tempo



58
59
60
61
# File 'lib/head_music/rudiment/tempo.rb', line 58

def initialize(beat_value, beats_per_minute)
  @beat_value = HeadMusic::Rudiment::RhythmicValue.get(beat_value)
  @beats_per_minute = beats_per_minute.to_f
end

Instance Attribute Details

#beat_valueObject (readonly)

Returns the value of attribute beat_value.



9
10
11
# File 'lib/head_music/rudiment/tempo.rb', line 9

def beat_value
  @beat_value
end

#beats_per_minuteObject (readonly)

Returns the value of attribute beats_per_minute.



9
10
11
# File 'lib/head_music/rudiment/tempo.rb', line 9

def beats_per_minute
  @beats_per_minute
end

Class Method Details

.get(identifier) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/head_music/rudiment/tempo.rb', line 40

def self.get(identifier)
  @tempos ||= {}
  key = HeadMusic::Utilities::HashKey.for(identifier)
  if NAMED_TEMPO_DEFAULTS.key?(identifier.to_s.to_sym)
    beat_value, beats_per_minute = NAMED_TEMPO_DEFAULTS[identifier.to_s.to_sym]
    @tempos[key] ||= new(beat_value, beats_per_minute)
  elsif identifier.to_s.match?(/=|at/)
    parts = identifier.to_s.split(/\s*(=|at)\s*/)
    unit = parts[0]
    bpm = parts[2] || parts[1]  # Handle both "q = 120" and "q at 120bpm"
    bpm_value = bpm.to_s.gsub(/[^0-9]/, "").to_i
    @tempos[key] ||= new(standardized_unit(unit), bpm_value)
  else
    @tempos[key] ||= new("quarter", 120)
  end
  @tempos[key]
end

.standardized_unit(unit) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/head_music/rudiment/tempo.rb', line 78

def self.standardized_unit(unit)
  return "quarter" if unit.nil?

  # Use RhythmicValue parser to handle all formats (shorthand, fractions, British names, dots, etc.)
  rhythmic_value = HeadMusic::Rudiment::RhythmicValue.get(unit)
  rhythmic_value&.unit ? rhythmic_value.to_s : "quarter"
end

Instance Method Details

#beat_duration_in_nanosecondsObject



68
69
70
71
# File 'lib/head_music/rudiment/tempo.rb', line 68

def beat_duration_in_nanoseconds
  @beat_duration_in_nanoseconds ||=
    NANOSECONDS_PER_MINUTE / beats_per_minute
end

#beat_duration_in_secondsObject



63
64
65
66
# File 'lib/head_music/rudiment/tempo.rb', line 63

def beat_duration_in_seconds
  @beat_duration_in_seconds ||=
    SECONDS_PER_MINUTE / beats_per_minute
end

#tick_duration_in_nanosecondsObject



73
74
75
76
# File 'lib/head_music/rudiment/tempo.rb', line 73

def tick_duration_in_nanoseconds
  @tick_duration_in_nanoseconds ||=
    beat_duration_in_nanoseconds / ticks_per_beat
end