[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [sc-dev] beat induction and TempoClock
I'm still wrestling with this issue. The code below illustrates my dilemma- given external clock, how do I best utilise existing SC3 objects for scheduling? I'm trying to get as exact a correlation between source on server and spawned synths on server as possible.
I'd appreciate any advice on best approach:
1. Do bookkeeping in custom SC Lang code
2. Kill existing clock and/or routine and create a new one whenever new beat information arrives inconsistent with old (seems excessive)
3. Change the C source for TempoClock to add the ability to set phase (at the moment you can only set period, all sorts of issues to do with how to update routines running on that clock etc)
4. Use a hack scheduler in the Lang like MIDISyncClock (seems a little unwieldy and won't have best timing characteristics... )
The code below is an example of 1, taking latency into account.
Thanks for any advice,
Nick
<x-tad-smaller>(
</x-tad-smaller><x-tad-smaller>\beep</x-tad-smaller><x-tad-smaller>,{arg freq=440;
</x-tad-smaller><x-tad-smaller>Line</x-tad-smaller><x-tad-smaller>.kr(1,0,0.1,doneAction:2));
}).load(s);
)
</x-tad-smaller>
<x-tad-smaller>(
</x-tad-smaller><x-tad-smaller>var</x-tad-smaller><x-tad-smaller> lastbeat;
</x-tad-smaller><x-tad-smaller>arg</x-tad-smaller><x-tad-smaller> val; if(val.cmdName==</x-tad-smaller><x-tad-smaller>OSCresponder</x-tad-smaller><x-tad-smaller>.remove(val)}); });
s.latency=0.25; </x-tad-smaller><x-tad-smaller>//make it obvious for testing purposes</x-tad-smaller><x-tad-smaller>
lastbeat=</x-tad-smaller><x-tad-smaller>Main</x-tad-smaller><x-tad-smaller>.elapsedTime;
</x-tad-smaller><x-tad-smaller>\beattrain</x-tad-smaller><x-tad-smaller>,{
</x-tad-smaller><x-tad-smaller>var</x-tad-smaller><x-tad-smaller> tempo,beat;
tempo=</x-tad-smaller><x-tad-smaller>LFNoise0</x-tad-smaller><x-tad-smaller>.ar(0.3,1.0,2.0);
beat=</x-tad-smaller><x-tad-smaller>Impulse</x-tad-smaller><x-tad-smaller>.ar(tempo);
</x-tad-smaller><x-tad-smaller>SendTrig</x-tad-smaller><x-tad-smaller>.ar(beat,100,tempo);
</x-tad-smaller><x-tad-smaller>Out</x-tad-smaller><x-tad-smaller>.ar(1,beat);
}).play(s);
r = </x-tad-smaller><x-tad-smaller>Routine</x-tad-smaller><x-tad-smaller>({
</x-tad-smaller><x-tad-smaller>var</x-tad-smaller><x-tad-smaller> error, startbeat;
</x-tad-smaller><x-tad-smaller>//aware of its position when restarts? (must code that in) will complete any outstanding wait first</x-tad-smaller><x-tad-smaller>
[</x-tad-smaller><x-tad-smaller>"restart"</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>thisThread</x-tad-smaller><x-tad-smaller>.clock.beats, </x-tad-smaller><x-tad-smaller>thisThread</x-tad-smaller><x-tad-smaller>.clock.elapsedBeats].postln;
{
[</x-tad-smaller><x-tad-smaller>"1"</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>thisThread</x-tad-smaller><x-tad-smaller>.clock.beats, </x-tad-smaller><x-tad-smaller>thisThread</x-tad-smaller><x-tad-smaller>.clock.elapsedBeats].postln;
s.sendBundle(s.latency, [</x-tad-smaller><x-tad-smaller>\s_new</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>\beep</x-tad-smaller><x-tad-smaller>, s.nextNodeID,0,1]);
</x-tad-smaller><x-tad-smaller>//must compensate for latency in this error calculation- still goes out</x-tad-smaller><x-tad-smaller>
</x-tad-smaller><x-tad-smaller>//wait depends on how much we're out from imposed beat</x-tad-smaller><x-tad-smaller>
error= (((</x-tad-smaller><x-tad-smaller>thisThread</x-tad-smaller><x-tad-smaller>.clock.tempo))%1.0;
(1.0-error).wait;
}.loop;
});
</x-tad-smaller><x-tad-smaller>TempoClock</x-tad-smaller><x-tad-smaller>.default.elapsedBeats.postln;
</x-tad-smaller><x-tad-smaller>TempoClock</x-tad-smaller><x-tad-smaller>.default.tempo)), r);
o=</x-tad-smaller><x-tad-smaller>arg</x-tad-smaller><x-tad-smaller> time, responder, msg;
</x-tad-smaller><x-tad-smaller>//msg.postln;</x-tad-smaller><x-tad-smaller>
if(msg[2]==100,{</x-tad-smaller><x-tad-smaller>"beat"</x-tad-smaller><x-tad-smaller>.postln;
</x-tad-smaller><x-tad-smaller>//but need now to be a beat </x-tad-smaller><x-tad-smaller>
lastbeat=</x-tad-smaller><x-tad-smaller>Main</x-tad-smaller><x-tad-smaller>.elapsedTime;
</x-tad-smaller><x-tad-smaller>TempoClock</x-tad-smaller><x-tad-smaller>.default.tempo=msg[3];
});
}).add;
)
</x-tad-smaller>