[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [sc-users] automated buffer -- How's that get in there?!?
Before I delve in, can I doublecheck one thing with you? Are you going to keep the recorded audio in memory in buffers, or read from and write to files every time?
I realized later I made a mistake with the Synth call. It should be:
Synth(\filter, [\sourcebufnum, sourcebuf.buffer.bufnum, \targetbufnum, targetbuf.buffer.bufnum]);
Basically what I'm thinking is (this is mostly real code, with comments indicating where you might want to change things):
<x-tad-smaller>~watcher = </x-tad-smaller><x-tad-smaller>NodeWatcher</x-tad-smaller><x-tad-smaller>.newFrom(s);
~stateManager = { </x-tad-smaller><x-tad-smaller>|buffer, node, endState = \ready|</x-tad-smaller><x-tad-smaller>
buffer.state = </x-tad-smaller><x-tad-smaller>\busy</x-tad-smaller><x-tad-smaller>; </x-tad-smaller><x-tad-smaller>// don't let anyone else use this buffer</x-tad-smaller><x-tad-smaller>
</x-tad-smaller><x-tad-smaller>// below is to make sure the state changes when the synth stops</x-tad-smaller><x-tad-smaller>
~watcher.register(node);
</x-tad-smaller><x-tad-smaller>Updater</x-tad-smaller><x-tad-smaller>(node, { </x-tad-smaller><x-tad-smaller>|node, flag|</x-tad-smaller><x-tad-smaller>
(flag == </x-tad-smaller><x-tad-smaller>\n_end</x-tad-smaller><x-tad-smaller>).if({
buffer.state = endState;
});
node.releaseDependants;
});
};
</x-tad-smaller><x-tad-smaller>// obviously you want to change this</x-tad-smaller><x-tad-smaller>
~filters = #[</x-tad-smaller><x-tad-smaller>\nameOfFilterSynth1</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>\nameOfFilterSynth2</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>\nameOfFilterSynth3</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>\nameOfFilterSynth4</x-tad-smaller><x-tad-smaller>...];
r = </x-tad-smaller><x-tad-smaller>Task</x-tad-smaller><x-tad-smaller>({
</x-tad-smaller><x-tad-smaller>var</x-tad-smaller><x-tad-smaller> buf1, buf2, node;
loop {
</x-tad-smaller><x-tad-smaller> // you might change the weights in the wchoose
// if you need other events, you can add the keys here</x-tad-smaller><x-tad-smaller>
#[</x-tad-smaller><x-tad-smaller>\record</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>\play</x-tad-smaller><x-tad-smaller>, </x-tad-smaller><x-tad-smaller>\filter</x-tad-smaller><x-tad-smaller>].wchoose(#[0.25, 0.25, 0.5]).switch
{ </x-tad-smaller><x-tad-smaller>\record</x-tad-smaller><x-tad-smaller> } {
buf1 = ~pool.select({ </x-tad-smaller><x-tad-smaller>|b|</x-tad-smaller><x-tad-smaller> b.state == </x-tad-smaller><x-tad-smaller>\empty</x-tad-smaller><x-tad-smaller> }).tryPerform(</x-tad-smaller><x-tad-smaller>\choose</x-tad-smaller><x-tad-smaller>);
buf1.notNil.if({
node = </x-tad-smaller><x-tad-smaller>\recorder</x-tad-smaller><x-tad-smaller>, [</x-tad-smaller><x-tad-smaller>\targetbufnum</x-tad-smaller><x-tad-smaller>, buf1.buffer.bufnum]);
~stateManager.value(buf1, node);
});
}
{ </x-tad-smaller><x-tad-smaller>\play</x-tad-smaller><x-tad-smaller> } {
buf1 = ~pool.select({ </x-tad-smaller><x-tad-smaller>|b|</x-tad-smaller><x-tad-smaller> b.state == </x-tad-smaller><x-tad-smaller>\ready</x-tad-smaller><x-tad-smaller> }).tryPerform(</x-tad-smaller><x-tad-smaller>\choose</x-tad-smaller><x-tad-smaller>);
buf1.notNil.if({
node = </x-tad-smaller><x-tad-smaller>\player</x-tad-smaller><x-tad-smaller>, [</x-tad-smaller><x-tad-smaller>\sourcebufnum</x-tad-smaller><x-tad-smaller>, buf1.buffer.bufnum]);
~stateManager.value(buf1, node);
});
}
{ </x-tad-smaller><x-tad-smaller>\filter</x-tad-smaller><x-tad-smaller> } {
buf1 = ~pool.select({ </x-tad-smaller><x-tad-smaller>|b|</x-tad-smaller><x-tad-smaller> b.state == </x-tad-smaller><x-tad-smaller>\ready</x-tad-smaller><x-tad-smaller> }).tryPerform(</x-tad-smaller><x-tad-smaller>\choose</x-tad-smaller><x-tad-smaller>);
buf2 = ~pool.select({ </x-tad-smaller><x-tad-smaller>|b|</x-tad-smaller><x-tad-smaller> b.state == </x-tad-smaller><x-tad-smaller>\empty</x-tad-smaller><x-tad-smaller> }).tryPerform(</x-tad-smaller><x-tad-smaller>\choose</x-tad-smaller><x-tad-smaller>);
(buf1.notNil and: { buf2.notNil }).if({
node = </x-tad-smaller><x-tad-smaller>Synth</x-tad-smaller><x-tad-smaller>(~filters.choose, [</x-tad-smaller><x-tad-smaller>\sourcebufnum</x-tad-smaller><x-tad-smaller>, buf1.buffer.bufnum,
</x-tad-smaller><x-tad-smaller>\targetbufnum</x-tad-smaller><x-tad-smaller>, buf2.target.bufnum]);
~stateManager.value(buf1, node);
~stateManager.value(buf2, node);
};
rrand(4.0, 20.0).wait; </x-tad-smaller><x-tad-smaller>// how many beats to wait until the next event?</x-tad-smaller><x-tad-smaller>
}
});
r.play;
r.stop;</x-tad-smaller>
You might rearrange the flow of control a bit. If you choose the buffers before doing the #[\record...].wchoose, you could choose the event intelligently (e.g., if there are no ready buffers, then record is the most logical event to fire).
I guess the other possible disconnect is about passing the buffer number to the synth ... at the time of choosing the buffer, the synth node doesn't exist on the server. The argument list in the Synth() (really, "Synth.new()") creates the synth node and initializes the arguments in one operation.
In addition, I'm not sure how the Routine is going to know how to pick the correct buffer to pass to the synth if I have one with a \ready and one with \empty.
Since both are needed for the operation, you pass both of them: sourcebufnum and targetbufnum. There's no limit that you may pass only one buffer number. You can have as many numeric arguments in a Synth as you can fit into an 8K UDP packet (which is a lot!). Those arguments can correspond to anything.
Hope that helps,
James
: H. James Harkins
: jamshark70@xxxxxxxxxxxxxxxxx
: http://www.dewdrop-world.net
.::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..:
"Come said the Muse,
Sing me a song no poet has yet chanted,
Sing me the universal." -- Whitman