Class: HeadMusic::Time::MeterMap
- Inherits:
-
Object
- Object
- HeadMusic::Time::MeterMap
- Defined in:
- lib/head_music/time/meter_map.rb
Overview
Manages meter (time signature) changes along a musical timeline
A MeterMap maintains a sorted list of meter changes at specific musical positions, allowing you to determine which meter is active at any point and iterate through meter segments for musical position calculations.
Instance Method Summary collapse
- #add_change(position, meter_or_identifier) ⇒ Object
-
#change_at(position) ⇒ MeterEvent?
The meter change starting exactly here.
- #clear_changes ⇒ Object
- #each_segment(from_position, to_position, &block) ⇒ Object
-
#events ⇒ Array<MeterEvent>
All meter events in chronological order.
-
#initialize(starting_meter: nil, starting_position: nil) ⇒ MeterMap
constructor
A new instance of MeterMap.
- #meter_at(position) ⇒ Object
- #remove_change(position) ⇒ Object
Constructor Details
#initialize(starting_meter: nil, starting_position: nil) ⇒ MeterMap
Returns a new instance of MeterMap.
26 27 28 29 30 31 32 33 |
# File 'lib/head_music/time/meter_map.rb', line 26 def initialize(starting_meter: nil, starting_position: nil) starting_meter = HeadMusic::Rudiment::Meter.get(starting_meter || "4/4") starting_position ||= MusicalPosition.new # The opening meter is not removable: a timeline with no meter at all # has no bars, so there is always one in force. @map = EventMap.new(removable_first_event: false) @map.add(starting_position, MeterEvent.new(starting_position, starting_meter)) end |
Instance Method Details
#add_change(position, meter_or_identifier) ⇒ Object
40 41 42 43 |
# File 'lib/head_music/time/meter_map.rb', line 40 def add_change(position, meter_or_identifier) meter = meter_or_identifier.is_a?(HeadMusic::Rudiment::Meter) ? meter_or_identifier : HeadMusic::Rudiment::Meter.get(meter_or_identifier) MeterEvent.new(position, meter).tap { |event| @map.add(position, event) } end |
#change_at(position) ⇒ MeterEvent?
Returns the meter change starting exactly here.
58 59 60 |
# File 'lib/head_music/time/meter_map.rb', line 58 def change_at(position) @map.change_at(position)&.value end |
#clear_changes ⇒ Object
49 50 51 |
# File 'lib/head_music/time/meter_map.rb', line 49 def clear_changes @map.clear end |
#each_segment(from_position, to_position, &block) ⇒ Object
62 63 64 65 66 |
# File 'lib/head_music/time/meter_map.rb', line 62 def each_segment(from_position, to_position, &block) @map.each_segment(from_position, to_position) do |start_position, end_position, event| block.call(start_position, end_position, event&.meter || events.first.meter) end end |
#events ⇒ Array<MeterEvent>
Returns all meter events in chronological order.
36 37 38 |
# File 'lib/head_music/time/meter_map.rb', line 36 def events @map.values end |
#meter_at(position) ⇒ Object
53 54 55 |
# File 'lib/head_music/time/meter_map.rb', line 53 def meter_at(position) @map.at(position)&.meter || events.first.meter end |
#remove_change(position) ⇒ Object
45 46 47 |
# File 'lib/head_music/time/meter_map.rb', line 45 def remove_change(position) @map.remove(position) end |