Class: Musa::Transcriptors::FromGDV::ToMIDI::Trill

Inherits:
Musa::Transcription::FeatureTranscriptor show all
Defined in:
lib/musa-dsl/transcription/from-gdv-to-midi.rb

Overview

Process: .tr

Instance Method Summary collapse

Methods inherited from Musa::Transcription::FeatureTranscriptor

#check

Constructor Details

#initialize(duration_factor: nil) ⇒ Trill

Returns a new instance of Trill.



120
121
122
# File 'lib/musa-dsl/transcription/from-gdv-to-midi.rb', line 120

def initialize(duration_factor: nil)
  @duration_factor = duration_factor || 1/4r
end

Instance Method Details

#transcript(gdv, base_duration:, tick_duration:) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/musa-dsl/transcription/from-gdv-to-midi.rb', line 124

def transcript(gdv, base_duration:, tick_duration:)
  tr = gdv.delete :tr

  if tr
    note_duration = base_duration * @duration_factor

    check(tr) do |tr|
      case tr
      when Numeric # duration factor
        note_duration *= base_duration * tr.to_r
      end
    end

    used_duration = 0r
    last = nil

    gdvs = []

    check(tr) do |tr|
      case tr
      when :low # start with lower note
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = -1); gdv[:duration] = note_duration }
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
        used_duration += 2 * note_duration

      when :low2 # start with upper note but go to lower note once
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = note_duration }
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = -1); gdv[:duration] = note_duration }
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
        used_duration += 4 * note_duration

      when :same # start with the same note
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }
        used_duration += note_duration
      end
    end

    2.times do
      if used_duration + 2 * note_duration <= gdv[:duration]
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = note_duration }
        gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration }

        used_duration += 2 * note_duration
      end
    end

    while used_duration + 2 * note_duration * 2/3r <= gdv[:duration]
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = note_duration * 2/3r }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = note_duration * 2/3r }

      used_duration += 2 * note_duration * 2/3r
    end

    duration_diff = gdv[:duration] - used_duration
    if duration_diff >= note_duration
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 1); gdv[:duration] = duration_diff / 2 }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += (last = 0); gdv[:duration] = duration_diff / 2 }

    elsif duration_diff > 0
      gdvs[-1][:duration] += duration_diff / 2
      gdvs[-2][:duration] += duration_diff / 2
    end

    super gdvs, base_duration: base_duration, tick_duration: tick_duration
  else
    super
  end
end