thanks for your inspiration, i implemented some of your ideas but in a little different style.
I tried to make some simple and easy to try out use case for demonstration purposes with a sinus synth. you can use any midi controllers .cc or control (potis, faders) output for my code. I append some [vel, note, ch] array to some other array at position ~playhead. then i just playback the array in a loop after the recording is finished.
can you tell me the advantages of using a buffer instead of an array? Is there any problem when creating a very large array? I assume there is some performance issues? when i set the ~wait period in my later shown code to a value of 0.001, it gets buggy for when the array gets larger sizes than 25000. Maybe its also not a good idea to use a 2 dimensional array. it would be generally better with buffers i assume?
@shiihs yeah also came to mind spontaneously. was experimenting with different looper approaches a little earlier. i didnt try to implement the gimmicks you have, since i think its too complicated to share code if too much is implemented. i was more curious how to effectively implement the core of this idea. i feel everything else, like a start, stop, overdub, needs to be adapted to what you want to do with it anyways.
here is the code:
//this is a midi recorder & playback for midi control
//it is written for demonstration reasons and therefore no special gimmicks are implemented
//this code has a lot more .postln; commands than required for testing and showcase reasons
//for a better overview and worse performance, set the ~wait period to a larger value
~wait = 0.01;
// ~wait = 0.2; //for a good overview
//~wait = 0.001; //gets buggy for array sizes of >30000
//initiate midi client and connect everything
(
MIDIClient.init;
//midi out for linux
~midiOut = MIDIOut(0, MIDIClient.destinations[0].uid);
//is this for windows? i dont know...
// ~midiOut = MIDIOut(0);
MIDIIn.connectAll;
)
//some simple sinus synth
(SynthDef(\sinhit,{
|freq=440, amp=0.1|
Out.ar(0,amp*SinOsc.ar(freq.lag(0.2)!2));
}).add;
);
x = Synth(\sinhit);
//some simple sinus synth control
//does take any control midi input and changes the pitch of the sinus synth
(
y = MIDIdef.cc(\cc_sinhit,{
arg vel, note, ch, src;
[vel,note,ch,src].postln;
x.set(\freq,vel/127*770+110);
})
)
//recording the midi input
//~recordControl array is created and every ~wait period the midi control
//is written to some index of this array
(
//control for recording
y = MIDIdef.cc(\cc_record,{
arg vel, note, ch, src;
"record".postln;
~recordControl[~playhead] = [vel,note,ch];
});
//set up a 2d array, if the entry is [-1], then there is no playback for this index
~recordControl = [[-1]];
~playhead = 0;
r = Routine({{
~recordControl = ~recordControl ++ [[-1]];
~playhead= ~playhead+1;
~playhead.postln;
~wait.wait;
}.loop}).play;
)
//stop the recording and free the recording synth
(
r.stop;
y.free;
)
//playback of the recorded midi in loop according to the array: [vel,note,ch]
(
~playhead = 0;
p = Routine({{
var action;
~playhead = (~playhead+1)%~recordControl.size;
action = ~recordControl[~playhead];
[~playhead, action].postln;
//only output control when a action is made
if(action[0]>=0){
~midiOut.control(action[2],action[1],action[0])
};
~wait.wait;
}.loop}).play;
)
//stop the looping of the recorded midi input
p.stop;