Class: Music::Performance::NoteSequenceExtractor

Inherits:
Object
  • Object
show all
Defined in:
lib/music-performance/conversion/note_sequence_extractor.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(notes, cents_per_step = 10) ⇒ NoteSequenceExtractor

Returns a new instance of NoteSequenceExtractor.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/music-performance/conversion/note_sequence_extractor.rb', line 44

def initialize notes, cents_per_step = 10
  @cents_per_step = cents_per_step
  @notes = notes.map {|n| n.clone }

  @notes.push Music::Transcription::Note.quarter
  (@notes.size-1).times do |i|
    NoteSequenceExtractor.fixup_links(@notes[i], @notes[i+1])
    NoteSequenceExtractor.replace_articulation(@notes[i], @notes[i+1])
  end
  @notes.pop
end

Instance Attribute Details

#notesObject (readonly)

Returns the value of attribute notes.



43
44
45
# File 'lib/music-performance/conversion/note_sequence_extractor.rb', line 43

def notes
  @notes
end

Class Method Details

For all link types:

- Remove link where source pitch is not in current note

For tie:

- Remove any bad tie (where the tying pitch does not exist in the next note).
- Replace any good tie with a slur.

For slur/legato:

- Remove any bad link (where the target pitch does not exist in the next note).

TODO: what to do about multiple links that target the same pitch?



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/music-performance/conversion/note_sequence_extractor.rb', line 13

def self.fixup_links note, next_note
  note.links.each do |pitch, link|
    if !note.pitches.include?(pitch)
      note.links.delete pitch
    elsif link.is_a? Music::Transcription::Link::Tie
      if next_note.pitches.include? pitch
        note.links[pitch] = Music::Transcription::Link::Slur.new(pitch)
      else
        note.links.delete pitch
      end
    elsif (link.is_a?(Music::Transcription::Link::Slur) ||
           link.is_a?(Music::Transcription::Link::Legato))
      unless next_note.pitches.include? link.target_pitch
        note.links.delete pitch
      end
    end
  end
end

.replace_articulation(note, next_note) ⇒ Object



32
33
34
35
36
37
38
39
40
41
# File 'lib/music-performance/conversion/note_sequence_extractor.rb', line 32

def self.replace_articulation note, next_note
  case note.articulation
  when Music::Transcription::Articulations::SLUR
    NoteLinker.fully_link(note, next_note, Music::Transcription::Link::Slur)
    note.articulation = Music::Transcription::Articulations::NORMAL
  when Music::Transcription::Articulations::LEGATO
    NoteLinker.fully_link(note, next_note, Music::Transcription::Link::Legato)
    note.articulation = Music::Transcription::Articulations::NORMAL
  end
end

Instance Method Details

#extract_sequencesObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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
# File 'lib/music-performance/conversion/note_sequence_extractor.rb', line 56

def extract_sequences
  sequences = []
  offset = 0

  @notes.each_index do |i|
    while @notes[i].pitches.any?
      elements = []

      j = i
      loop do
        note = @notes[j]
        pitch = note.pitches.pop
        dur = note.duration
        accented = note.accented
        link = note.links[pitch]

        case link
        when Music::Transcription::Link::Slur
          elements.push(SlurredElement.new(dur, pitch, accented))
        when Music::Transcription::Link::Legato
          elements.push(LegatoElement.new(dur, pitch, accented))
        when Music::Transcription::Link::Glissando
          elements += GlissandoConverter.glissando_elements(pitch, link.target_pitch, dur, accented)
        when Music::Transcription::Link::Portamento
          elements += PortamentoConverter.portamento_elements(pitch, link.target_pitch, @cents_per_step, dur, accented)
        else
          elements.push(FinalElement.new(dur, pitch, accented, note.articulation))
          break
        end

        j += 1
        break if j >= @notes.size || !@notes[j].pitches.include?(link.target_pitch)
      end

      sequences.push(NoteSequence.from_elements(offset,elements))
    end
    offset += @notes[i].duration
  end

  return sequences
end