Skip to content
This repository was archived by the owner on Nov 23, 2023. It is now read-only.

Commit bc773e9

Browse files
linnstrument display example; sweep_time and pitch_topk options
1 parent 722776f commit bc773e9

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
(
2+
~use_linn = true; // use linnstrument
3+
~gui = false; // use keyboard GUI
4+
MIDIIn.connectAll;
5+
b = NetAddr.new("127.0.0.1", 9999);
6+
Server.default.options.inDevice_("Built-in Microph");
7+
Server.default.options.outDevice_("Built-in Output");
8+
// Server.default.options.inDevice_("mic-buds");
9+
// Server.default.options.outDevice_("mic-buds");
10+
~gui.if{
11+
k = MIDIKeyboard.new(bounds: Rect(0, 0, 500, 100), octaves:11, startnote:0)
12+
};
13+
~linn_reset = {
14+
~linn.allLightsOff;
15+
~linn.setNoteOnAction({arg x,y,degree,freq,amp,midinote;
16+
var t2 = Process.elapsedTime;
17+
var dt = t2-(t?t2); //time since last note
18+
19+
// release the previous note
20+
~synth!?(_.release(0.1));
21+
22+
// attack the current note with the old pitch
23+
~synth = Synth(\pluck, [\freq, freq, \vel, amp]);
24+
25+
//
26+
b.sendMsg("/predictor/predict",
27+
\pitch, midinote, \time, dt, \vel, amp*127,
28+
\pitch_topk, 5);
29+
30+
// mark time of current note
31+
t = t2;
32+
});
33+
};
34+
s.waitForBoot{
35+
~use_linn.if{
36+
~linn = IILinnstrument.new(nil);
37+
~linn_reset.();
38+
};
39+
SynthDef(\pluck, {
40+
var vel = \vel.kr;
41+
var signal = Saw.ar(\freq.kr(20), 3e-2) * EnvGate.new(1);
42+
var fr = 2.pow(Decay.ar(Impulse.ar(0), 3)*6*vel+8);
43+
signal = BLowPass.ar(signal, fr)*vel;
44+
Out.ar([0,1], signal);
45+
}).add
46+
};
47+
)
48+
49+
~linn_reset.()
50+
51+
52+
// ~linn.setNoteOnAction({}); ~linn.setNoteOffAction({});
53+
54+
55+
// measure round-trip latency
56+
(
57+
OSCdef(\return, {
58+
arg msg, time, addr, recvPort;
59+
(Process.elapsedTime - t).postln;
60+
}, '/prediction', nil);
61+
t = Process.elapsedTime;
62+
b.sendMsg("/predictor/predict",
63+
\pitch, 60+12.rand, \time, 0, \vel, 0,
64+
\index_pitch, 0,
65+
\sweep_time, true,
66+
// \fix_time, 0,
67+
// \fix_vel, 0
68+
);
69+
)
70+
71+
72+
// NetAddr.localAddr // retrieve the current IP and port
73+
// thisProcess.openPorts; // list all open ports
74+
75+
// model chooses pitches
76+
(
77+
// set the delay for more precise timing
78+
~delay = 0.2;
79+
80+
~gate = 1;
81+
82+
~reset = {
83+
t = Process.elapsedTime;
84+
b.sendMsg("/predictor/reset");
85+
// ~synth!?{~synth.free};
86+
s.freeAll;
87+
~synth = nil;
88+
b.sendMsg("/predictor/predict",
89+
\pitch, 128, \time, 0, \vel, 0,
90+
\pitch_topk, 5);
91+
92+
};
93+
~reset.();
94+
~linn_reset.();
95+
96+
// footswitch
97+
MIDIdef.program(\switch, {
98+
arg num, chan, src;
99+
num.switch
100+
{1}{~gate = 0}
101+
{2}{~gate = 1}
102+
{3}{
103+
~gate = 0;
104+
SystemClock.clear;
105+
b.sendMsg("/predictor/reset");
106+
y.release;
107+
SystemClock.clear;
108+
};
109+
~gate.postln;
110+
});
111+
112+
// OSC return from python
113+
OSCdef(\return, {
114+
arg msg, time, addr, recvPort;
115+
var pitches, dts;
116+
var last_pitch = nil;
117+
var colormap = [8,3,10,9,1];
118+
var color = 0;
119+
// whhyyyy are OSC arrays not handled by supercollider
120+
var stack = List[List[]];
121+
msg.do{arg item;
122+
case
123+
{item==$[}{stack.add(List[])}
124+
{item==$]}{var tmp = stack.pop; stack.last.add(tmp)}
125+
{true}{stack.last.add(item)};
126+
};
127+
msg = stack[0];
128+
pitches = msg[1];
129+
dts = msg[2];
130+
131+
~linn.allLightsOff;
132+
pitches.do{arg pitch;
133+
8.do{arg row;
134+
~linn.lightOnMIDI(pitch,row,colormap[color]);
135+
// [pitch, row].postln
136+
};
137+
color = color + 1 % colormap.size;
138+
};
139+
140+
msg.postln;
141+
}, "/prediction", nil);
142+
)
143+
144+
~reset.()
145+
// send a note manually if you don't have a midi controller
146+
MIDIdef.all[\input].func.(64, 16) //velocity, "pitch"
147+
148+
// load another model
149+
// b.sendMsg("/predictor/load", "/path/to/checkpoint");

0 commit comments

Comments
 (0)