music-performance 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d523ae35fe6714368362b37241e3ffd10c0e2982
4
- data.tar.gz: 3604e251beb16c2095e9c9d8e90b889b0bb385a7
3
+ metadata.gz: f0aee433423e514dcf3e7c43cf3e41bedb419773
4
+ data.tar.gz: 935623cdf53a375dbbe7931f4bbc06857144a3eb
5
5
  SHA512:
6
- metadata.gz: bc6d3bf49947281586e433f301048c6a64eff08611aa8a8565c40a4a60f52f1357b8436feb56d5d92cc1a400bdf63e3d99c161ccf24960e81c75ffc9cc18cc33
7
- data.tar.gz: f4104ce48fbc02e4790df8511d6afadf668466578ffa5ee0e2ee43b0014c840ae988f3eb1bbb36a1d9cae169ce43289cd62c5caa5eaaf055659a2c02a05ab674
6
+ metadata.gz: 377e4df3573ca96e8b9307f87d8a4dc1cb5aef5bc709c841137649e7c973764b050ac3c2b0777188898c3d663305ec45cf31685a6839a0190f10ead2e9e495b4
7
+ data.tar.gz: 136086c85244cbcc75168c7de393ceec0df3d1ec6266aff023b8b21876d37c9f07dbacd2cb0f0735319eb1a232139fcc5bbbe020c0156d53d44de9b409971cf0
@@ -1,9 +1,36 @@
1
1
  module Music
2
2
  module Performance
3
3
 
4
- NoteOnEvent = Struct.new(:notenum, :accented)
5
- NoteOffEvent = Struct.new(:notenum)
6
- VolumeExpressionEvent = Struct.new(:volume)
4
+ class MidiEvent
5
+ def <=> other
6
+ ORDERING[self] <=> ORDERING[other]
7
+ end
8
+
9
+ class NoteOn < MidiEvent
10
+ attr_reader :notenum, :accented
11
+ def initialize notenum, accented
12
+ @notenum, @accented = notenum, accented
13
+ end
14
+ end
15
+
16
+ class NoteOff < MidiEvent
17
+ attr_reader :notenum
18
+ def initialize notenum
19
+ @notenum = notenum
20
+ end
21
+ end
22
+
23
+ class Expression < MidiEvent
24
+ attr_reader :volume
25
+ def initialize volume
26
+ @volume = volume
27
+ end
28
+ end
29
+
30
+ ORDERING = {
31
+ NoteOff => 0, Expression => 1, NoteOn => 2
32
+ }
33
+ end
7
34
 
8
35
  end
9
36
  end
@@ -3,6 +3,8 @@ module Performance
3
3
 
4
4
  class PartSequencer
5
5
  def initialize part, dynamics_sample_rate: 50, cents_per_step: 10
6
+ replace_portamento_with_glissando(part.notes)
7
+
6
8
  extractor = NoteSequenceExtractor.new(part.notes, cents_per_step)
7
9
  note_sequences = extractor.extract_sequences
8
10
  note_events = gather_note_events(note_sequences)
@@ -10,7 +12,7 @@ class PartSequencer
10
12
  dynamic_events = gather_dynamic_events(part.start_dynamic,
11
13
  part.dynamic_changes, dynamics_sample_rate)
12
14
 
13
- @events = (note_events + dynamic_events).sort_by {|x| x[0] }
15
+ @events = (note_events + dynamic_events).sort
14
16
  end
15
17
 
16
18
  def make_midi_track midi_sequence, part_name, channel, ppqn
@@ -25,12 +27,12 @@ class PartSequencer
25
27
  end
26
28
 
27
29
  track.events << case event
28
- when NoteOnEvent
30
+ when MidiEvent::NoteOn
29
31
  vel = MidiUtil.note_velocity(event.accented)
30
32
  MIDI::NoteOn.new(channel, event.notenum, vel, delta)
31
- when NoteOffEvent
33
+ when MidiEvent::NoteOff
32
34
  MIDI::NoteOff.new(channel, event.notenum, 127, delta)
33
- when VolumeExpressionEvent
35
+ when MidiEvent::Expression
34
36
  MIDI::Controller.new(channel, MIDI::CC_EXPRESSION_CONTROLLER, event.volume, delta)
35
37
  end
36
38
 
@@ -41,13 +43,15 @@ class PartSequencer
41
43
 
42
44
  private
43
45
 
44
- #def add_event events_hash, offset, event
45
- # if events_hash.has_key? offset
46
- # events_hash[offset].push event
47
- # else
48
- # events_hash[offset] = [ event ]
49
- # end
50
- #end
46
+ def replace_portamento_with_glissando notes
47
+ notes.each do |note|
48
+ note.links.each do |pitch,link|
49
+ if link.is_a? Music::Transcription::Link::Portamento
50
+ note.links[pitch] = Music::Transcription::Link::Glissando.new(link.target_pitch)
51
+ end
52
+ end
53
+ end
54
+ end
51
55
 
52
56
  def gather_note_events note_sequences
53
57
  note_events = []
@@ -65,8 +69,8 @@ class PartSequencer
65
69
  on_at = offset
66
70
  off_at = (i < (pitches.size - 1)) ? pitches[i+1][0] : note_seq.stop
67
71
 
68
- note_events.push [on_at, NoteOnEvent.new(note_num, accented)]
69
- note_events.push [off_at, NoteOffEvent.new(note_num)]
72
+ note_events.push [on_at, MidiEvent::NoteOn.new(note_num, accented)]
73
+ note_events.push [off_at, MidiEvent::NoteOff.new(note_num)]
70
74
  end
71
75
  end
72
76
  return note_events
@@ -91,7 +95,7 @@ class PartSequencer
91
95
  unless sample == prev
92
96
  offset = Rational(i,sample_rate)
93
97
  volume = MidiUtil.dynamic_to_volume(sample)
94
- dynamic_events.push [offset, VolumeExpressionEvent.new(volume)]
98
+ dynamic_events.push [offset, MidiEvent::Expression.new(volume)]
95
99
  end
96
100
  prev = sample
97
101
  end
@@ -102,8 +102,6 @@ class ScoreCollator
102
102
  cur_notes[-1].duration -= overshoot
103
103
  cur_offset = seg.last
104
104
  end
105
-
106
- cur_notes[-1].links.clear
107
105
  end
108
106
 
109
107
  post_remainder = seg.last - cur_offset
@@ -2,6 +2,6 @@
2
2
  module Music
3
3
  module Performance
4
4
  # music-performance version
5
- VERSION = "0.2.1"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
@@ -82,6 +82,24 @@ describe ScoreCollator do
82
82
  end
83
83
  end
84
84
  end
85
+
86
+ it 'should preserve links' do
87
+ notes = Parsing::notes("1Db4~Bb4")
88
+ score = Score.new(
89
+ FOUR_FOUR,120,
90
+ parts: { "lead" => Part.new(Dynamics::MP, notes: notes) },
91
+ program: Program.new([0..1,0..1]),
92
+ )
93
+ collator = ScoreCollator.new(score)
94
+ parts = collator.collate_parts
95
+
96
+ notes = parts["lead"].notes
97
+ notes.size.should eq 2
98
+ notes.each do |note|
99
+ note.links.should have_key(Db4)
100
+ note.links[Db4].should be_a Link::Glissando
101
+ end
102
+ end
85
103
  end
86
104
 
87
105
  describe '#collate_tempo_changes' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: music-performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Tunnell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-29 00:00:00.000000000 Z
11
+ date: 2014-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler