-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplay_score.rb
66 lines (61 loc) · 1.32 KB
/
play_score.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
require 'score.rb'
#require 'midilib_javabacked'
require 'java'
require 'midi_java/event.rb'
def play(score,tempo=nil)
require 'pp'
#pp score
wrap=ScoreWrap.new(score)
seqer = javax.sound.midi.MidiSystem.sequencer
seqer.open
seqer.sequence = wrap
seqer.tempo_in_bpm=tempo if tempo
seqer.start
while (seqer.is_running)
sleep 1
end
seqer.close
nil
end
class ScoreWrap < javax.sound.midi.Sequence
def initialize(sc,ppqn=480)
@score=sc
@ppqn=ppqn
super(javax.sound.midi.Sequence::PPQ,@ppqn)
end
def getTracks
@tracks ||= @score.tracks.map do |t|
TrackWrap.new(t,@ppqn)
end.to_java("javax.sound.midi.Track".to_sym)
end
def getResolution
@ppqn
end
end
class TrackWrap < javax.sound.midi.Track
def initialize(t,ppqn)
super()
@all_events = if t.nil?
[]
else
phrase_start_time=0
t.map do |phrase|
notes=phrase.notes.map do |n|
on=MIDI::NoteOn.new(phrase.channel,n[:note],n[:vel] || 64,0) #some assumptions here
off=MIDI::NoteOff.new(phrase.channel,n[:note],64,n[:len]*ppqn)
on.time_from_start=phrase_start_time+n[:from_start]*ppqn
off.time_from_start=phrase_start_time+(n[:from_start]+n[:len])*ppqn
[on,off]
end
phrase_start_time+=phrase.length*ppqn
notes
end.flatten.sort
end
end
def get(i)
@all_events[i]
end
def size
@all_events.length
end
end