class Music::Transcription::MeasureScore
Attributes
meter_changes[RW]
start_meter[RW]
Public Class Methods
new(start_meter, start_tempo, meter_changes: {}) { |self| ... }
click to toggle source
Calls superclass method
# File lib/music-transcription/model/measure_score.rb, line 7 def initialize start_meter, start_tempo, meter_changes: {}, tempo_changes: {}, parts: {}, program: Program.new @start_meter = start_meter @meter_changes = meter_changes super(start_tempo, tempo_changes: tempo_changes, program: program, parts: parts) yield(self) if block_given? end
unpack(packing)
click to toggle source
# File lib/music-transcription/packing/measure_score_packing.rb, line 16 def self.unpack packing unpacked_start_meter = Meter.parse(packing["start_meter"]) unpacked_mcs = Hash[ packing["meter_changes"].map do |k,v| v = v.clone v[0] = Meter.parse(v[0]) [k, Change.from_ary(v) ] end ] note_score = NoteScore.unpack(packing) new(unpacked_start_meter, note_score.start_tempo, meter_changes: unpacked_mcs, tempo_changes: note_score.tempo_changes, program: note_score.program, parts: note_score.parts ) end
valid_tempo_types()
click to toggle source
# File lib/music-transcription/model/measure_score.rb, line 25 def self.valid_tempo_types NoteScore.valid_tempo_types + [ Tempo::BPM ] end
Public Instance Methods
==(other)
click to toggle source
Calls superclass method
# File lib/music-transcription/model/measure_score.rb, line 56 def ==(other) return super(other) && @start_meter == other.start_meter && @meter_changes == other.meter_changes end
beat_duration_at(moff)
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 93 def beat_duration_at moff beat_durations.select {|k,v| k <= moff }.max[1] end
beat_durations()
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 126 def beat_durations bdurs = @meter_changes.map do |offset,change| [ offset, change.value.beat_duration ] end.sort if bdurs.empty? || bdurs[0][0] != 0 bdurs.unshift([0,@start_meter.beat_duration]) end return bdurs end
check_meterchange_durs()
click to toggle source
# File lib/music-transcription/model/measure_score.rb, line 49 def check_meterchange_durs nonzero_duration = @meter_changes.select {|k,v| !v.is_a?(Change::Immediate) } if nonzero_duration.any? raise NonZeroError, "meter changes #{nonzero_duration} are not immediate" end end
check_meterchange_offsets()
click to toggle source
# File lib/music-transcription/model/measure_score.rb, line 42 def check_meterchange_offsets badoffsets = @meter_changes.select {|k,v| k != k.to_i } if badoffsets.any? raise NonIntegerError, "meter changes #{badoffsets} have non-integer offsets" end end
check_meterchange_types()
click to toggle source
# File lib/music-transcription/model/measure_score.rb, line 35 def check_meterchange_types badtypes = @meter_changes.select {|k,v| !v.value.is_a?(Meter) } if badtypes.any? raise TypeError, "meter change values #{nonmeter_values} are not Meter objects" end end
check_methods()
click to toggle source
Calls superclass method
# File lib/music-transcription/model/measure_score.rb, line 16 def check_methods super() + [:check_startmeter_type, :check_meterchange_types, :check_meterchange_durs, :check_meterchange_offsets] end
check_startmeter_type()
click to toggle source
# File lib/music-transcription/model/measure_score.rb, line 29 def check_startmeter_type unless @start_meter.is_a? Meter raise TypeError, "start meter #{@start_meter} is not a Meter object" end end
convert_parts(mnoff_map = self.measure_note_map)
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 31 def convert_parts mnoff_map = self.measure_note_map Hash[ @parts.map do |name,part| new_dcs = Hash[ part.dynamic_changes.map do |moff,change| noff = mnoff_map[moff] noff2 = mnoff_map[moff + change.duration] [noff, change.resize(noff2-noff)] end ] new_notes = part.notes.map {|n| n.clone } [name, Part.new(part.start_dynamic, notes: new_notes, dynamic_changes: new_dcs)] end ] end
convert_program(mnoff_map = self.measure_note_map)
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 44 def convert_program mnoff_map = self.measure_note_map Program.new( @program.segments.map do |seg| mnoff_map[seg.first]...mnoff_map[seg.last] end ) end
convert_tempo_changes(tempo_class, mnoff_map = self.measure_note_map)
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 52 def convert_tempo_changes tempo_class, mnoff_map = self.measure_note_map tcs = {} bdurs = beat_durations @tempo_changes.each do |moff,change| bdur = bdurs.select {|x,y| x <= moff}.max[1] tempo = change.value case change when Change::Immediate tcs[mnoff_map[moff]] = Change::Immediate.new(tempo.convert(tempo_class,bdur)) when Change::Gradual start_moff, end_moff = moff, moff + change.duration start_noff, end_noff = mnoff_map[start_moff], mnoff_map[end_moff] dur = end_noff - start_noff cur_noff, cur_bdur = start_noff, bdur more_bdurs = bdurs.select {|x,y| x > moff && x < end_moff } if more_bdurs.any? more_bdurs.each do |next_moff, next_bdur| next_noff = mnoff_map[next_moff] tcs[cur_noff] = Change::Partial.new( tempo.convert(tempo_class, cur_bdur), dur, cur_noff - start_noff, next_noff - start_noff) cur_noff, cur_bdur = next_noff, next_bdur end tcs[cur_noff] = Change::Partial.new( tempo.convert(tempo_class, cur_bdur), dur, cur_noff - start_noff, dur) else tcs[start_noff] = Change::Gradual.new( tempo.convert(tempo_class, cur_bdur), end_noff - start_noff) end when Change::Partial raise NotImplementedError, "No support yet for converting partial tempo changes." end end return tcs end
measure_durations()
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 138 def measure_durations mdurs = @meter_changes.map do |offset,change| [ offset, change.value.measure_duration ] end.sort if mdurs.empty? || mdurs[0][0] != 0 mdurs.unshift([0,@start_meter.measure_duration]) end return Hash[ mdurs ] end
measure_note_map()
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 27 def measure_note_map Conversion::measure_note_map(measure_offsets,measure_durations) end
measure_offsets()
click to toggle source
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 97 def measure_offsets moffs = Set.new([0.to_r]) @tempo_changes.each do |moff,change| moffs.add(moff) if change.duration > 0 moffs.add(moff + change.duration) end end @meter_changes.keys.each {|moff| moffs.add(moff) } @parts.values.each do |part| part.dynamic_changes.each do |moff,change| moffs.add(moff) if change.duration > 0 moffs.add(moff + change.duration) end end end @program.segments.each do |seg| moffs.add(seg.first) moffs.add(seg.last) end return moffs.sort end
pack()
click to toggle source
Calls superclass method
# File lib/music-transcription/packing/measure_score_packing.rb, line 5 def pack hash = super() hash["start_meter"] = start_meter.to_s hash["meter_changes"] = Hash[ meter_changes.map do |offset,change| a = change.pack a[0] = a[0].to_s [offset,a] end ] return hash end
to_note_score(tempo_class = Tempo::QNPM)
click to toggle source
Convert to NoteScore
object by first converting measure-based offsets to note-based offsets, and eliminating the use of meters. Also, tempo is to non-BPM tempo.
# File lib/music-transcription/conversion/measure_score_conversion.rb, line 8 def to_note_score tempo_class = Tempo::QNPM unless valid? raise NotValidError, "Current MeasureScore is invalid, so it can not be \ converted to a NoteScore. Validation errors: #{self.errors}" end unless NoteScore.valid_tempo_types.include? tempo_class raise TypeError, "The desired tempo class #{tempo_class} is not valid for a NoteScore." end mnoff_map = self.measure_note_map parts = convert_parts(mnoff_map) prog = convert_program(mnoff_map) tcs = convert_tempo_changes(tempo_class, mnoff_map) start_tempo = @start_tempo.convert(tempo_class,@start_meter.beat_duration) NoteScore.new(start_tempo, parts: parts, program: prog, tempo_changes: tcs) end
validatables()
click to toggle source
Calls superclass method
# File lib/music-transcription/model/measure_score.rb, line 21 def validatables super() + [ @start_meter ] + @meter_changes.values.map {|v| v.value} end