Class: Musikov::MarkovBuilder
- Inherits:
-
Object
- Object
- Musikov::MarkovBuilder
- Defined in:
- lib/musikov/markov_builder.rb
Overview
This class is responsible for building the markov chain map from midi sequences. For every sequence, a “quarter” duration will be extracted and every note duration will be mapped in the possible values on the duration table. From a note and a specifc duration, MidiElements will be created representing a state on the markov chain.
Instance Method Summary collapse
-
#add(sequence) ⇒ Object
Add a midi sequence to the model.
-
#build ⇒ Object
Build the markov chain for each instrument on the input midi file(s).
-
#initialize ⇒ MarkovBuilder
constructor
Initialize the hashes used to build the markov chain of note elements.
Constructor Details
#initialize ⇒ MarkovBuilder
Initialize the hashes used to build the markov chain of note elements.
-
The value_chain is a hash containing a list of note events by instrument.
-
The duration table is a dynamic generated hash (generated from the “quarter” duration value) that maps
a the duration of the notes to a string representation.
60 61 62 63 |
# File 'lib/musikov/markov_builder.rb', line 60 def initialize @value_chain = Hash.new @duration_table = Hash.new("unknow") end |
Instance Method Details
#add(sequence) ⇒ Object
Add a midi sequence to the model. From each sequence, different tracks (instruments) will be analyzed. Each sequence has a “tempo” that defines the “quarter” duration in ticks. From the “quarter” duration, creates a duration table containg (almost) every possible note duration. Creates markov chain elements by the value of the played note and the duration string mapped from the duration table.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/musikov/markov_builder.rb', line 72 def add(sequence) # Obtains a quarter duration for this sequence quarter_note_length = sequence.note_to_delta('quarter') # Create the duration table based on the sequence's "quarter" value create_duration_table(quarter_note_length) # For each instrument on the sequence... sequence.each { |track| # Program change of the current track program_change = nil # Create a list of midi elements for an instrument elements = [] # Iterates the track event list... track.each { |event| # Consider only "NoteOn" events since they represent the start of a note event (avoid duplication with "NoteOff"). if event.kind_of?(MIDI::NoteOnEvent) then # From its correspondent "NoteOff" element, extract the duration of the note event. duration = event.off.time_from_start - event.time_from_start + 1 # Maps the duration in ticks to a correspondent string on the duration table. duration_representation = @duration_table[duration] # In the case that the note do not correspond to anything in the table, # we just truncate it to the closest value. if duration_representation.nil? or duration_representation == "unknow" then new_duration = 0 # Infinity value simulation smallest_difference = 1.0/0 @duration_table.each { |key, value| difference = (duration - key).abs if difference < smallest_difference then smallest_difference = difference new_duration = key end } duration_representation = @duration_table[new_duration] end # Create new markov chain state and put into the "elements" list elements << MidiElement.new(event.note_to_s, duration_representation) elsif event.kind_of?(MIDI::ProgramChange) then program_change = event.program end } if program_change.nil? program_change = 1 end @value_chain[program_change] ||= elements unless elements.empty? } end |
#build ⇒ Object
Build the markov chain for each instrument on the input midi file(s)
130 131 132 133 134 135 136 137 |
# File 'lib/musikov/markov_builder.rb', line 130 def build model_by_instrument = {} @value_chain.each{ |key, value| model_by_instrument[key] = MarkovModel.new(value) } return model_by_instrument end |