Author |
Message |
someone
Joined: Apr 11, 2009 Posts: 9 Location: somewhere
|
Posted: Sun May 17, 2009 6:23 pm Post subject:
synth creation with loop |
 |
|
I wanted to see if someone had any suggestions for getting the rate at which synths are created in a loop to change in real-time. Here is an example of what I'm talking about:
var rate;
r = Routine({ loop{Synth(\test);
rate.wait;
}}).play;
Forgive me if there are a few mistakes in this code, as I am away from my computer that runs Supercollider. I hope you can get the gist of what I'm trying to do, though. I've got a SCSlider that changes the variable rate. While this gets close to what I'm going for, .wait isn't capable of immediately changing with a change in the value of rate. Is there a way to use a UGen (like Impulse) to trigger the creation of synths? |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Tue May 19, 2009 9:10 am Post subject:
|
 |
|
Ah, interesting!
The wait call schedules the routine to wake up again at a specific number of beats in the future. It isn't possible to change that. But, you could time travel by warping time, i.e. changing the speed of the clock.
You can create as many TempoClocks as you need and control their speeds independently. Then, I would say, wait a constant amount of time inside the routine and have the slider change the clock's tempo.
Code: | myClock = TempoClock.new(1); // 1 bps
r = Routine({
loop {
Synth(\test);
1.wait;
}
}).play(myClock);
slider.action = { myClock.tempo = (map the slider's 0-1 range onto bps here) };
// later, when you don't need the clock anymore,
// release the OS thread and garbage-collect
myClock.stop;
|
PS It's really helpful to get in the habit of indenting consistently for readability.
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
someone
Joined: Apr 11, 2009 Posts: 9 Location: somewhere
|
Posted: Tue May 19, 2009 6:31 pm Post subject:
|
 |
|
Okay. I tried using a TempoClock and it definitely worked as you said, only once I got the tempo up to around 100 (to get the Synths oscillating) slight inaccuracies in the scheduling became apparent. In other words, the frequency of the oscillating Synths seemed to vary ever so slightly. Is there a known issue with the accuracy of TempoClocks? |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
|
Back to top
|
|
 |
someone
Joined: Apr 11, 2009 Posts: 9 Location: somewhere
|
Posted: Wed May 20, 2009 7:24 pm Post subject:
|
 |
|
After reading the ServerTiming helpfile, I feel I have a better understanding of the cause of the scheduling inaccuracies. As for the solution using latency, though, I'm having difficulty seeing and hearing the difference with it - at least, from the examples in the helpfile. I ran the first example, heard the slight variations and saw them in the post window. Then I ran the second example (which uses latency) and it didn't seem like anything had changed.
Am I wrong in expecting the latency to sync the playback of the synths in both routines? |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Thu May 21, 2009 11:30 am Post subject:
|
 |
|
It should.
If you're on Windows, the audio driver latency might be too low. Booting the server on my winxp machine shows this:
Device options:
- MME : Microsoft Sound Mapper - Input (device #0 with 2 ins 0 outs)
- MME : SigmaTel Audio (device #1 with 2 ins 0 outs)
- MME : Microsoft Sound Mapper - Output (device #2 with 0 ins 2 outs)
- MME : SigmaTel Audio (device #3 with 0 ins 2 outs)
Booting with:
In: MME : SigmaTel Audio
Out: MME : SigmaTel Audio
Sample rate: 44100.000
Latency (in/out): 0.232 / 0.232 sec
SuperCollider 3 server ready..
What do you see there?
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Fri May 22, 2009 2:31 pm Post subject:
|
 |
|
Had another thought... depending on the sound you're using, granular synthesis UGens might be better for this than triggering one synth per grain.
Sound in a buffer: TGrains, Warp1, GrainBuf
With the JoshUGens from the sc3-plugins pack, there are sine-grain ugens and FM grain ugens.
Also, if the sound is in a buffer, convolution can be more cpu-friendly if the grain rate is high and the grains use exactly the same buffer (whereas the "real" granulators can move through a buffer).
Code: | // depending on your buffered sound, you might be able to just Buffer.read it
// but here, we're taking a random snippet out of a longer file
// without a windowing function, there will be a lot of ugly clicks
// so we do it the long way - load soundfile data into a client array,
// then multiply by an Envelope shape
b = Buffer.alloc(s, 10000, 1);
f = SoundFile.openRead("sounds/a11wlk01.wav");
f.seek(100000.rand);
f.readData(d = Signal.newClear(10000));
b.sendCollection(d * (Env(#[0, 1, 1, 0], #[0.25, 0.5, 0.25], \sin).discretize(10000)));
a = { |trigrate = 10|
var trig = Impulse.ar(trigrate);
Convolution2.ar(in: trig, kernel: b, trigger: 0, framesize: 4096) ! 2
}.play;
w = Window("grain rate", Rect(5, 100, 300, 50));
EZSlider(w, Rect(2, 2, 296, 20), "rate", ControlSpec(3, 400, \exp), { |slider|
a.set(\trigrate, slider.value)
}, 10);
w.front;
a.free;
w.close;
b.free;
f.close; // clean up thy file handles! |
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
someone
Joined: Apr 11, 2009 Posts: 9 Location: somewhere
|
Posted: Sun May 24, 2009 3:32 pm Post subject:
|
 |
|
Sorry for the delay in my response. Here is what is printed when I boot the server (I've got a Mac G5):
booting 57110
Number of Devices: 4
0 : "Built-in Audio"
1 : "MOTU 828"
2 : "PCI-424"
3 : "Aggregate Device"
"MOTU 828" Input Device
Streams: 2
0 channels 8
1 channels 2
"MOTU 828" Output Device
Streams: 2
0 channels 8
1 channels 2
SC_AudioDriver: sample rate = 48000.000000, driver's block size = 512
SuperCollider 3 server ready..
notification is on
The reason why I'm trying to use a routine is that I want to get a Synth oscillating that is using one of the grain UGens. I would ideally like to be able to granulate a sample and have the granulated output oscillate as well. |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Tue May 26, 2009 1:22 pm Post subject:
|
 |
|
It took awhile, but I remembered one factor here.
Synth onset is always at a control block boundary. If the rate of Synth creation is below the rate of perception, it isn't really a big deal (64/44100 < 2ms) but it is slightly inaccurate.
To solve that problem, use OffsetOut which measures the difference between the control block boundary time and the real sounding time, and adjust the output to start at exactly the indicated time.
OffsetOut.ar(bus, result) // instead of Out.ar(...)
There might be something else in your SynthDef to interfere, but I think this might help.
hjh _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
someone
Joined: Apr 11, 2009 Posts: 9 Location: somewhere
|
Posted: Wed May 27, 2009 4:40 pm Post subject:
|
 |
|
You got it. With the combination of the OffsetOut in the SynthDef and the latency in the sendBundle method used in the loop of the Routine, I'm getting exactly what I intended.
So when you say that Synth onset is at a control block boundary, does that mean that synths are only created at the beginning of a control cycle running at the control rate?
Also, wouldn't it always be advantageous to use OffsetOut over Out? |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Sun May 31, 2009 12:25 pm Post subject:
|
 |
|
someone wrote: | So when you say that Synth onset is at a control block boundary, does that mean that synths are only created at the beginning of a control cycle running at the control rate? |
Yes.
someone wrote: | Also, wouldn't it always be advantageous to use OffsetOut over Out? |
There might be some extra cpu overhead for OffsetOut, but if any, it wouldn't be much. There's probably no particular harm in using it everywhere. (Note, though, there is no OffsetOut.kr, because there are no sub-control-rate values for kr buses.)
A lot of applications don't demand sub-microsecond timing accuracy (humans can't detect separate attacks occurring less than 5-10 ms or so apart). It becomes an issue here because of the rate of synth creation and the desire to get oscillation in the range of hearing.
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
someone
Joined: Apr 11, 2009 Posts: 9 Location: somewhere
|
Posted: Sun May 31, 2009 5:42 pm Post subject:
|
 |
|
Thank you so much for helping me out with this issue. I appreciate your patience and assistance in finding the solution. |
|
Back to top
|
|
 |
|