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
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
|
class RecEvent {
dur pit;
MidiMsg @msg;
}
Queue buffer;
/* FIXME: custom nanoKONTROL events */
if (me.args() > 0)
me.exit();
MidiOut mout;
MidiIn min;
/* always open MIDI Through port, actual connection is done by Jack */
if (!min.open(0))
me.exit();
if (!mout.open(0))
me.exit();
<<< "MIDI device:", min.num(), " -> ", min.name() >>>;
1 => int on_channel; /* Scene 2 */
false => int recording;
time start;
false => int looping;
fun void
do_playback(int looping)
{
if (buffer.peek() == null)
return;
while (true) {
for (buffer.head.next @=> Element @cur; cur != null; cur.next @=> cur) {
cur.payload $ RecEvent @=> RecEvent @recev;
recev.pit => now;
recev.msg => mout.send;
<<< "PLAY Channel:", recev.msg.data1 & 0x0F,
"Command:", recev.msg.data1 & 0xF0,
"Controller:", recev.msg.data2,
"Value:", (recev.msg.data3 $ float)/127 >>>;
}
if (!looping)
break;
}
<<< "PLAY FIN", 1 >>>;
}
Shred @playback_shred;
while (min => now) {
while (MidiMsg msg => min.recv) {
msg.data1 & 0x0F => int channel;
msg.data1 & 0xF0 => int cmd;
(msg.data3 $ float)/127 => float value;
//<<< "Channel:", channel, "Command:", cmd, "Controller:", msg.data2, "Value:", value >>>;
channel == on_channel && cmd == 0xB0 => int is_cmd;
if (is_cmd && msg.data2 == 44) {
if (value $ int => recording) {
now => start;
buffer.flush();
}
} else if (is_cmd && msg.data2 == 45) {
if (value $ int) {
if (playback_shred != null)
playback_shred.exit();
spork ~ do_playback(looping) @=> playback_shred;
}
} else if (is_cmd && msg.data2 == 46) {
if (value $ int && playback_shred != null) {
playback_shred.exit();
null @=> playback_shred;
}
} else if (is_cmd && msg.data2 == 49) {
value $ int => looping;
} else if (recording) {
<<< "REC Channel:", channel, "Command:", cmd, "Controller:", msg.data2, "Value:", value >>>;
RecEvent recev => buffer.push;
now - start => recev.pit;
msg @=> recev.msg;
now => start;
}
}
}
|