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 }
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
# ]

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



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/musa-dsl/transcription/from-gdv-to-midi.rb', line 361

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