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

Commit fd53601

Browse files
generate.scd
1 parent d26f05c commit fd53601

File tree

3 files changed

+42
-37
lines changed

3 files changed

+42
-37
lines changed

examples/notepredictor/analysis.scd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SynthDef(\analyzer, {
3434
)
3535

3636
(
37-
~clear_pending_notes.();
37+
~clear_pending_events.();
3838
b.sendMsg("/predictor/reset");
3939
~release_all.(0);
4040
~allow_end = false;
@@ -63,7 +63,7 @@ OSCdef(\analysis, {
6363
)
6464

6565
(
66-
~clear_pending_notes.();
66+
~clear_pending_events.();
6767
~release_all.(0);
6868
)
6969

examples/notepredictor/generate.scd

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ Server.default.options.outDevice_("Built-in Output");
9494
// Server.default.options.inDevice_("mic-buds");
9595
// Server.default.options.outDevice_("mic-buds");
9696
s.boot;
97-
~gui.if{
97+
/*~gui.if{
9898
k = MIDIKeyboard.new(bounds: Rect(0, 0, 500, 100), octaves:11, startnote:0)
99-
};
99+
};*/
100100
)
101101

102102
(
@@ -148,7 +148,7 @@ b.sendMsg("/predictor/predict",
148148
~player_held = false!128;
149149

150150
~pending_predictions = 0;
151-
~pending_notes = List[];
151+
~pending_events = List[];
152152
~step = 0;
153153

154154
t = nil;
@@ -167,7 +167,7 @@ b.sendMsg("/predictor/reset");
167167
}
168168
};
169169

170-
~predict_note = {
170+
~predict_event = {
171171
arg inst, pitch, dt, vel;
172172
var kw = List[
173173
\inst, inst, \pitch, pitch, \time, dt, \vel, vel,
@@ -186,7 +186,7 @@ b.sendMsg("/predictor/reset");
186186

187187
};
188188

189-
~clear_pending_notes = {~pending_notes.do{arg pp; pp.stop}.clear};
189+
~clear_pending_events = {~pending_events.do{arg pe; pe.stop}.clear};
190190

191191
// footswitch
192192
MIDIdef.program(\switch, {
@@ -214,10 +214,10 @@ MIDIdef.noteOff(\input_off, {
214214
var port_chan = ~prog2portchan.(inst);
215215

216216
// cancel any pending predictions
217-
~clear_pending_notes.();
217+
~clear_pending_events.();
218218
// ~pending_predictions.postln;
219219
//get a new prediction in light of current note
220-
~predict_note.(inst, pitch, dt, 0);
220+
~predict_event.(inst, pitch, dt, 0);
221221

222222
~player_sound.if{
223223
// release the previous note
@@ -227,9 +227,6 @@ MIDIdef.noteOff(\input_off, {
227227
port_chan[\port].noteOff(port_chan[\chan], pitch);
228228
};
229229

230-
// post the current note
231-
[\player, dt, inst, pitch, 0].postln;
232-
233230
// mark time of current note
234231
t = t2;
235232
~player_t = t;
@@ -238,6 +235,9 @@ MIDIdef.noteOff(\input_off, {
238235

239236
~player_held[pitch] = false;
240237

238+
// post the current note
239+
[\player, dt, inst, pitch, 0].postln;
240+
241241
});
242242
MIDIdef.noteOn(\input_on, {
243243
arg vel, pitch, chan, src;
@@ -247,11 +247,11 @@ MIDIdef.noteOn(\input_on, {
247247
var port_chan = ~prog2portchan.(inst);
248248

249249

250-
// cancel any pending predictions
251-
~clear_pending_notes.();
250+
// cancel any pending events
251+
~clear_pending_events.();
252252
// ~pending_predictions.postln;
253253
//get a new prediction in light of current note
254-
~predict_note.(inst, pitch, dt, vel);
254+
~predict_event.(inst, pitch, dt, vel);
255255

256256
~player_sound.if{
257257
// release the previous note (if not properly released by noteoff)
@@ -266,9 +266,6 @@ MIDIdef.noteOn(\input_on, {
266266
port_chan[\port].noteOn(port_chan[\chan], pitch, vel);
267267
};
268268

269-
// post the current note
270-
[\player, dt, inst, pitch, vel].postln;
271-
272269
// mark time of current note
273270
t = t2;
274271
~player_t = t;
@@ -277,6 +274,9 @@ MIDIdef.noteOn(\input_on, {
277274
// ~step = 0;
278275

279276
~player_held[pitch] = true;
277+
278+
// post the current note
279+
[\player, dt, inst, pitch, vel].postln;
280280
});
281281

282282
// OSC return from python
@@ -296,18 +296,22 @@ OSCdef(\return, {
296296
// meaning it just predicts 10s rather than any longer time
297297
var censor = dt>=10.0;
298298

299-
var gate_note = ~gate && (~duet && (inst==~player_inst)).not && censor.not && (~pending_predictions==1);
299+
// there may be multiple outstanding queries to the model. when there are, it means
300+
// the earlier prediction is already voided, so it should dropped here.
301+
var gate_event = (
302+
~gate
303+
// && (~duet && (inst==~player_inst)).not
304+
&& censor.not
305+
&& (~pending_predictions==1));
300306

301307
~pending_predictions = ~pending_predictions-1;
302-
// [\step, step].postln;
303308

304-
gate_note.if{
309+
gate_event.if{
305310
// cancel any pending notes
306-
// (there shouldn't be any, but might
307-
// be if there was a lot of fast MIDI input)
308-
~clear_pending_notes.();
311+
// since they are voided by the new prediction
312+
~clear_pending_events.();
309313
// schedule the predicted note
310-
~pending_notes.add(Routine{
314+
~pending_events.add(Routine{
311315
var t2, dt_actual;
312316
(dt-~delay).sleep;
313317
(end==1).if{
@@ -325,7 +329,7 @@ OSCdef(\return, {
325329
dt_actual = t2 - t;
326330

327331
// feed model its own prediction as input
328-
~predict_note.(inst, pitch, dt_actual, vel);
332+
~predict_event.(inst, pitch, dt_actual, vel);
329333

330334
// play the current note
331335
~synths[pitch]!?(_.release(0.05));
@@ -341,8 +345,6 @@ OSCdef(\return, {
341345
}{
342346
~synths[pitch] = nil;
343347
};
344-
// post the current note
345-
[\model, step, dt, inst, pitch, vel, end].postln;
346348
// mark the actual time of current note
347349
t = t2;
348350
~machine_t = t;
@@ -351,6 +353,8 @@ OSCdef(\return, {
351353
AppClock.sched(0,{k.keyDown(pitch)});
352354
AppClock.sched(0.2,{k.keyUp(pitch)});
353355
}*/
356+
// post the current note
357+
[\model, step, dt, inst, pitch, vel, end].postln;
354358
};
355359
~step = ~step+1;
356360
// [\late, dt_actual-dt].postln;
@@ -360,31 +364,32 @@ OSCdef(\return, {
360364
)
361365

362366
(
367+
~gate = false;
363368
~duet = false;
364-
~instrument_temp = 0.9;
369+
~instrument_temp = 0.95;
365370
~pitch_temp = 0.9;
366371
~rhythm_temp = 0.9;
367372
~timing_temp = 0.05;
368373
// send a note manually if you don't have a MIDI controller:
369-
~clear_pending_notes.();
374+
~clear_pending_events.();
370375
~synths.do(_.release(1.0));
371376
~release_all.(0);
372377
b.sendMsg("/predictor/reset");
373378
// ~player_inst = 128.rand+1;
374379
// {MIDIdef.all[\input_on].func.value(128.rand, 128.rand)}.defer(0.1);
375380
~player_inst = 272;
376-
{MIDIdef.all[\input_on].func.value(128.rand, 60.rand+30)}.defer(0.1);
381+
{~gate = true; MIDIdef.all[\input_on].func.value(128.rand, 60.rand+30)}.defer(0.2);
377382
)
378383

379384
(
380385
~seq!?(_.stop);
381386
~gate = false;
382387
~duet = true;
383388
~instrument_temp = 0.9;
384-
~pitch_temp = 0.9;
389+
~pitch_temp = 1;
385390
~rhythm_temp = 1;
386391
~timing_temp = 0.05;
387-
~clear_pending_notes.();
392+
~clear_pending_events.();
388393
~release_all.(0);
389394
b.sendMsg("/predictor/reset");
390395
~player_inst = 272;
@@ -405,12 +410,13 @@ b.sendMsg("/predictor/reset");
405410
0.02.sleep;
406411
}
407412
}.play(SystemClock);
408-
{ ~gate=true}.defer(3);
413+
{ ~gate=true }.defer(3);
409414
}.defer(0.5);
410415
)
411416

412417
(
418+
~gate = false;
413419
~seq!?(_.stop);
414-
~clear_pending_notes.();
420+
~clear_pending_events.();
415421
~release_all.(0);
416422
)

notepredictor/notepredictor/model.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def forward(self, instruments, pitches, times, velocities, ends, validation=Fals
284284
inst_params, pitch_params, time_params, vel_params = [
285285
proj(h) for proj,h in zip(self.projections, mode_hs)]
286286

287-
# get likelihoods of data for each modality
287+
# get likelihood of data for each modality
288288
inst_logits = F.log_softmax(inst_params, -1)
289289
inst_targets = instruments[:,1:,None] #batch, time, 1
290290
inst_log_probs = inst_logits.gather(-1, inst_targets)[...,0]
@@ -500,7 +500,6 @@ def predict(self,
500500
[fix_instrument, fix_pitch, fix_time, fix_vel],
501501
[torch.long, torch.long, torch.float, torch.float])]
502502

503-
# permute h_tgt, embs, modalities
504503
# if any modalities are determined, embed them
505504
# sort constrained modalities before unconstrained
506505
# TODO: option to skip modalities

0 commit comments

Comments
 (0)