Class: Musa::Transcriptors::FromGDV::ToMIDI::Turn

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

Overview

Turn transcriptor for MIDI playback.

Expands turn ornaments into a four-note figure that circles around the main note. A turn is a melodic embellishment consisting of the note above, the principal note, the note below, and the principal note again.

Turn Types

  • .turn or .turn(:up) - Start with upper neighbor (upper, main, lower, main)
  • .turn(:down) or .turn(:low) - Start with lower neighbor (lower, main, upper, main)

Processing

Given .turn on a note:

{ grade: 0, duration: 1r, turn: true }

Expands to four equal notes:

[
  { grade: 1, duration: 1/4r },    # Upper neighbor
  { grade: 0, duration: 1/4r },    # Main note
  { grade: -1, duration: 1/4r },   # Lower neighbor
  { grade: 0, duration: 1/4r }     # Main note
]

Each note gets 1/4 of the original duration.

Process: .turn

Examples:

Upper turn

turn = Turn.new
gdv = { grade: 0, duration: 1r, turn: true }
result = turn.transcript(gdv, base_duration: 1/4r, tick_duration: 1/96r)
# => [
#   { grade: 1, duration: 1/4r },   # +1
#   { grade: 0, duration: 1/4r },   # 0
#   { grade: -1, duration: 1/4r },  # -1
#   { grade: 0, duration: 1/4r }    # 0
# ]

Lower turn

gdv = { grade: 0, duration: 1r, turn: :down }
# => [
#   { grade: -1, duration: 1/4r },  # -1
#   { grade: 0, duration: 1/4r },   # 0
#   { grade: 1, duration: 1/4r },   # +1
#   { grade: 0, duration: 1/4r }    # 0
# ]

Instance Method Summary collapse

Instance Method Details

#transcript(gdv, base_duration:, tick_duration:) ⇒ Array<Hash>, Hash

Transcribes turn to four-note sequence.

Parameters:

  • gdv (Hash)

    GDV event possibly containing :turn

  • base_duration (Rational)

    base duration unit

  • tick_duration (Rational)

    minimum tick duration

Returns:

  • (Array<Hash>, Hash)

    array with turn notes, or unchanged event



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/musa-dsl/transcription/from-gdv-to-midi.rb', line 342

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

  if turn
    start = :up

    check(turn) do |turn|
      case turn
      when true, :up
        start = :up
      when :down, :low
        start = :down
      end
    end

    duration = gdv[:duration] / 4r

    gdvs = []

    case start
    when :up
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 1; gdv[:duration] = duration }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += -1; gdv[:duration] = duration }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
    when :down
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += -1; gdv[:duration] = duration }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 1; gdv[:duration] = duration }
      gdvs << gdv.clone.tap { |gdv| gdv[:grade] += 0; gdv[:duration] = duration }
    end

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