@@ -130,6 +130,7 @@ b.sendMsg("/predictor/predict",
130130// duet with the model
131131// feeds the model's predictions back to it as well as player input
132132(
133+ ~velocity_temp = 1 ;
133134~instrument_temp = 0.95 ;
134135~pitch_temp = 0.9 ;
135136~rhythm_temp = 1 ;
@@ -176,7 +177,8 @@ b.sendMsg("/predictor/reset");
176177 ~duet .if{kw.add(\exclude_instrument ); kw.add(~player_inst )};
177178 ~global_kws .(kw, [
178179 \min_time , \max_time , \allow_end ,
179- \instrument_temp , \pitch_temp , \rhythm_temp , \timing_temp
180+ \instrument_temp , \pitch_temp , \rhythm_temp , \timing_temp ,
181+ \velocity_temp
180182 ]);
181183
182184 // kw.postln;
@@ -208,16 +210,19 @@ MIDIdef.program(\switch, {
208210// MIDI from controller
209211MIDIdef .noteOff(\input_off , {
210212 arg vel, pitch, chan, src;
211- var t2 = Process .elapsedTime;
212- var dt = t2-(t?(t2-~delay )); //time since last note
213+ var t2, dt;
213214 var inst = ~player_inst ;
214215 var port_chan = ~prog2portchan .(inst);
215216
217+ // mark time of current note
218+ t2 = Process .elapsedTime;
219+ dt = t2-(t?(t2-~delay ));
220+ t = t2;
221+ ~player_t = t;
222+
216223 // cancel any pending predictions
217224 ~clear_pending_events .();
218225 // ~pending_predictions.postln;
219- //get a new prediction in light of current note
220- ~predict_event .(inst, pitch, dt, 0 );
221226
222227 ~player_sound .if{
223228 // release the previous note
@@ -227,9 +232,8 @@ MIDIdef.noteOff(\input_off, {
227232 port_chan[\port ].noteOff(port_chan[\chan ], pitch);
228233 };
229234
230- // mark time of current note
231- t = t2;
232- ~player_t = t;
235+ //get a new prediction in light of current note
236+ ~predict_event .(inst, pitch, dt, 0 );
233237
234238 ~step = ~step + 1 ;
235239
@@ -241,17 +245,19 @@ MIDIdef.noteOff(\input_off, {
241245});
242246MIDIdef .noteOn(\input_on , {
243247 arg vel, pitch, chan, src;
244- var t2 = Process .elapsedTime;
245- var dt = t2-(t?(t2-~delay )); //time since last note
248+ var t2, dt;
246249 var inst = ~player_inst ;
247250 var port_chan = ~prog2portchan .(inst);
248251
252+ // mark time of current note
253+ t2 = Process .elapsedTime;
254+ dt = t2-(t?(t2-~delay ));
255+ t = t2;
256+ ~player_t = t;
249257
250258 // cancel any pending events
251259 ~clear_pending_events .();
252260 // ~pending_predictions.postln;
253- //get a new prediction in light of current note
254- ~predict_event .(inst, pitch, dt, vel);
255261
256262 ~player_sound .if{
257263 // release the previous note (if not properly released by noteoff)
@@ -266,12 +272,10 @@ MIDIdef.noteOn(\input_on, {
266272 port_chan[\port ].noteOn(port_chan[\chan ], pitch, vel);
267273 };
268274
269- // mark time of current note
270- t = t2;
271- ~player_t = t;
275+ //get a new prediction in light of current note
276+ ~predict_event .(inst, pitch, dt, vel);
272277
273278 ~step = ~step + 1 ;
274- // ~step = 0;
275279
276280 ~player_held [pitch] = true ;
277281
@@ -290,127 +294,140 @@ OSCdef(\return, {
290294 var step = msg[6 ];
291295 var port_chan = ~prog2portchan .(inst);
292296
293-
294297 // time-to-next note gets 'censored' by the model
295298 // when over a threshold, in this case 10 seconds,
296299 // meaning it just predicts 10s rather than any longer time
297300 var censor = dt>=10.0 ;
298301
299302 // 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.
303+ // the earlier prediction is already voided, so it should be dropped here.
301304 var gate_event = (
302305 ~gate
303306 // && (~duet && (inst==~player_inst)).not
304307 && censor.not
305- && (~pending_predictions ==1 ));
308+ && (~pending_predictions ==1 )
309+ && (end==0 )
310+ );
306311
307312 ~pending_predictions = ~pending_predictions -1 ;
308-
309313 gate_event.if{
310- // cancel any pending notes
314+ // cancel any pending events
311315 // since they are voided by the new prediction
312316 ~clear_pending_events .();
313317 // schedule the predicted note
314318 ~pending_events .add(Routine {
315319 var t2, dt_actual;
316- (dt-~delay ).sleep;
317- (end==1 ).if{
318- // in this case don't schedule a note, and reset the model
319- // b.sendMsg("/predictor/reset");
320- //release the last note
321- ~synths .do(_ .release(1.0 ));
322- ~release_all .(127 );
323- // unset time so next note will have dt=0
324- // t = nil;
325- // \reset.postln
326- \end .postln;
320+ // wait until predicted time
321+ // TODO: this could be made exact by passing timestamps thru OSC?
322+ (dt-~delay ).max(0 ).sleep;
323+
324+ // get the actual time since last event
325+ t2 = Process .elapsedTime;
326+ dt_actual = t2 - t;
327+ // mark the actual time of current note
328+ t = t2;
329+ ~machine_t = t;
330+
331+ // play the current note
332+ ~synths [pitch]!?(_ .release(0.05 ));
333+ // send MIDI
334+ port_chan[\port ].noteOff(port_chan[\chan ], pitch, 64 );
335+ (vel > 0 ).if{
336+ ~use_synth .if{
337+ ~synths [pitch] = Synth (\pluck , [
338+ \freq , pitch.midicps, \vel , vel/127 ]);
339+ };
340+ // send MIDI
341+ port_chan[\port ].noteOn(port_chan[\chan ], pitch, vel)
327342 }{
328- t2 = Process .elapsedTime ;
329- dt_actual = t2 - t ;
343+ ~synths [pitch] = nil ;
344+ } ;
330345
331- // feed model its own prediction as input
332- ~predict_event .(inst, pitch, dt_actual, vel);
346+ // feed model its own prediction as input
347+ ~predict_event .(inst, pitch, dt_actual, vel);
348+
349+ // crudely draw note on piano GUI
350+ /*~gui.if{
351+ AppClock.sched(0,{k.keyDown(pitch)});
352+ AppClock.sched(0.2,{k.keyUp(pitch)});
353+ }*/
354+ // post the current note
355+ [\model , step, dt, inst, pitch, vel].postln;
333356
334- // play the current note
335- ~synths [pitch]!?(_ .release(0.05 ));
336- // send MIDI
337- port_chan[\port ].noteOff(port_chan[\chan ], pitch, 64 );
338- (vel > 0 ).if{
339- ~use_synth .if{
340- ~synths [pitch] = Synth (\pluck , [
341- \freq , pitch.midicps, \vel , vel/127 ]);
342- };
343- // send MIDI
344- port_chan[\port ].noteOn(port_chan[\chan ], pitch, vel)
345- }{
346- ~synths [pitch] = nil ;
347- };
348- // mark the actual time of current note
349- t = t2;
350- ~machine_t = t;
351- // crudely draw note on piano GUI
352- /*~gui.if{
353- AppClock.sched(0,{k.keyDown(pitch)});
354- AppClock.sched(0.2,{k.keyUp(pitch)});
355- }*/
356- // post the current note
357- [\model , step, dt, inst, pitch, vel, end].postln;
358- };
359357 ~step = ~step +1 ;
360358 // [\late, dt_actual-dt].postln;
361359 nil ;
362- }.play(SystemClock ))};
360+ }.play(SystemClock ));
361+ };
362+ (end==1 ).if{
363+ // b.sendMsg("/predictor/reset");
364+ //release the last note
365+ ~synths .do(_ .release(1.0 ));
366+ ~release_all .(127 );
367+ // unset time so next note will have dt=0
368+ // t = nil;
369+ // \reset.postln
370+ \end .postln;
371+ };
363372}, "/prediction" , nil );
364373)
365374
366375(
376+ t = nil ;
367377~gate = false ;
368378~duet = false ;
379+ ~allow_end = true ;
369380~instrument_temp = 0.95 ;
370381~pitch_temp = 0.9 ;
371- ~rhythm_temp = 0.9 ;
372- ~timing_temp = 0.05 ;
382+ ~rhythm_temp = 1 ;
383+ ~timing_temp = 0.1 ;
384+ ~min_time = nil ;//~delay;
385+ ~velocity_temp = 0 ;
373386// send a note manually if you don't have a MIDI controller:
374387~clear_pending_events .();
375388~synths .do(_ .release(1.0 ));
376389~release_all .(0 );
377390b.sendMsg("/predictor/reset" );
378- // ~player_inst = 128.rand+1;
379- // { MIDIdef.all[\input_on].func.value(128 .rand, 128.rand)}.defer(0.1 );
380- ~player_inst = 272 ;
381- {~gate = true ; MIDIdef .all[\input_on ].func.value(128 .rand, 60 .rand+30 )}.defer(0.2 );
391+ ~player_inst = 128 .rand+1 ;
392+ { ~gate = true ; MIDIdef .all[\input_on ].func.value(127 .rand+ 1 , 128 .rand)}.defer(0.2 );
393+ // ~player_inst = 272;
394+ // {~gate = true; MIDIdef.all[\input_on].func.value(128.rand+1, 27 .rand+60 )}.defer(0.2);
382395)
383396
384397(
398+ t = nil ;
385399~seq !?(_ .stop);
386400~gate = false ;
387401~duet = true ;
388- ~instrument_temp = 0.9 ;
402+ ~allow_end = false ;
403+ ~instrument_temp = 1 ;
389404~pitch_temp = 1 ;
390405~rhythm_temp = 1 ;
391- ~timing_temp = 0.05 ;
406+ ~timing_temp = 0.1 ;
407+ ~velocity_temp = 1 ;
392408~clear_pending_events .();
393409~release_all .(0 );
394410b.sendMsg("/predictor/reset" );
395411~player_inst = 272 ;
412+ s = 2 ;
396413{~seq = Routine {
397414 loop {
398415 MIDIdef .all[\input_on ].func.value(100 , 51 );
399416 MIDIdef .all[\input_on ].func.value(100 , 36 );
400- 0.12 .sleep;
417+ ( 0.12 *s) .sleep;
401418 MIDIdef .all[\input_off ].func.value(0 , 51 );
402- 0.005 .sleep;
419+ ( 0.005 *s) .sleep;
403420 MIDIdef .all[\input_on ].func.value(100 , 51 );
404- 0.125 .sleep;
421+ ( 0.125 *s) .sleep;
405422 MIDIdef .all[\input_on ].func.value(100 , 46 );
406- 0.22 .sleep;
423+ ( 0.22 *s) .sleep;
407424 MIDIdef .all[\input_off ].func.value(0 , 36 );
408- 0.01 .sleep;
425+ ( 0.01 *s) .sleep;
409426 MIDIdef .all[\input_off ].func.value(0 , 46 );
410- 0.02 .sleep;
427+ ( 0.02 *s) .sleep;
411428 }
412429}.play(SystemClock );
413- { ~gate =true }.defer(3 );
430+ { ~gate =true }.defer(4 );
414431}.defer(0.5 );
415432)
416433
0 commit comments