Urgent shot in the dark -- Audible clicks when spawning shreds when SndBuf reads from disk
This is a shot-in-the-dark... At the last minute, the person who was responsible for doing the sound with a Kyma system, couldn't get it to trigger sounds with MIDI (for some reason or another) and I'm stepping up and doing the whole show with pre-recorded material in ChucK. (I know, I know -- I'm crazy.) It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio. Now, I know that one way around this is to pre-load all the files into SndBuf objects and then trigger them to play using Events. The only trouble is that there are 73 files for this piece and some of them are pretty large. I'm afraid of eating all my RAM / bringing everything to a grinding halt. I'm posting my entire script at the end of the email. If anyone has any thoughts, please send them along. Otherwise, we'll just deal with the way things are. Best, Mike -- http://michaelclemow.com http://semiotech.org // ---- CODE ---- // "/Users/michaelclemow/chuck/Sandresky/sounds/" => string dirPrefix; // osc event creator function fun OscEvent createOscEvent( string address, int port ) { OscRecv recv; port => recv.port; recv.listen(); recv.event( address ) @=> OscEvent oe; return oe; } // play file function fun void playFile(string filename) { SndBuf l, r; l.chunks(1024); r.chunks(1024); r.read(filename); l.read(filename); 0.2 => l.gain => r.gain; l.channel(0); l => dac.chan(0); l => dac.chan(2); r.channel(1); r => dac.chan(1); r => dac.chan(3); l.pos(0); r.pos(0); l.play(1); r.play(1); r.length() => now; me.yield(); } createOscEvent( "/play, s", 12000 ) @=> OscEvent oe; string file; 9999 => int last; fun void killLast() { createOscEvent( "/killlast, i", 12000 ) @=> OscEvent kill; while( kill => now ) { if( kill.nextMsg() ) { kill.getInt() => int k; <<< "killing last id:", last >>>; Machine.remove( last ); } me.yield(); } } fun void playListen() { while( oe => now ) { if( oe.nextMsg() ) { oe.getString() => file; // spawn player (spork ~playFile( dirPrefix + file )).id() => last; me.yield(); <<< "playing", file, "id", last >>>; } me.yield(); } } <<< "spawning listeners" >>>; spork ~killLast(); spork ~playListen(); me.yield(); 0 => int seconds; // wait for messages and play files <<< "listening..." >>>; while(true) { 1::second => now; //<<< seconds++ >>>; } // --- END CODE --- //
Mike, Just some thoughts. When you kill the "last shred" that was playing, the audio signal drops to 0 (or to the first sample of the next WAV file), which may cause clicks. Also, reading an entire file (or part of it) between two samples may not be feasible, which will not only cause a click, but the realtime timing will also be lost (ChucK will wait for the entire file to be read in.) I'd use an Envelope for the first problem and I'd try changing chunk size for the second. (Or maybe pre-read the next file to be played, if it can be determined beforehand.) I hope I could help a little Szilveszter (Hillaby) mike clemow escribió:
This is a shot-in-the-dark...
At the last minute, the person who was responsible for doing the sound with a Kyma system, couldn't get it to trigger sounds with MIDI (for some reason or another) and I'm stepping up and doing the whole show with pre-recorded material in ChucK. (I know, I know -- I'm crazy.)
It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio.
Now, I know that one way around this is to pre-load all the files into SndBuf objects and then trigger them to play using Events. The only trouble is that there are 73 files for this piece and some of them are pretty large. I'm afraid of eating all my RAM / bringing everything to a grinding halt.
I'm posting my entire script at the end of the email. If anyone has any thoughts, please send them along. Otherwise, we'll just deal with the way things are.
Best, Mike
Mike, if you record the audio from ChucK using a WvOut like this: dac.chan(0) => Gain g => WvOut w => blackhole; "tmp.wav" => w.wavFilename; do you hear the click in the resulting tmp.wav? If not, then the problem is with reading a file between samples. If yes, then the abrupt sample change may play a role, too. Szilveszter (Hillaby) Szilveszter Tóth escribió:
Mike,
Just some thoughts.
When you kill the "last shred" that was playing, the audio signal drops to 0 (or to the first sample of the next WAV file), which may cause clicks. Also, reading an entire file (or part of it) between two samples may not be feasible, which will not only cause a click, but the realtime timing will also be lost (ChucK will wait for the entire file to be read in.)
I'd use an Envelope for the first problem and I'd try changing chunk size for the second. (Or maybe pre-read the next file to be played, if it can be determined beforehand.)
I hope I could help a little Szilveszter (Hillaby)
mike clemow escribió:
This is a shot-in-the-dark...
At the last minute, the person who was responsible for doing the sound with a Kyma system, couldn't get it to trigger sounds with MIDI (for some reason or another) and I'm stepping up and doing the whole show with pre-recorded material in ChucK. (I know, I know -- I'm crazy.)
It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio.
Now, I know that one way around this is to pre-load all the files into SndBuf objects and then trigger them to play using Events. The only trouble is that there are 73 files for this piece and some of them are pretty large. I'm afraid of eating all my RAM / bringing everything to a grinding halt.
I'm posting my entire script at the end of the email. If anyone has any thoughts, please send them along. Otherwise, we'll just deal with the way things are.
Best, Mike
Hi Szilveszter, Kassen,
Thanks for the quick response! It's definitely the reads between
samples that's causing the issue, because I only kill the last shred
twice during the piece. The dropouts occur only when spawning new
shreds.
I've already set the chunk-size to 1024... I assume that this is
samples, although the documentation says "frames."
I'll try preloading the files in a big array and see if I run out of RAM.
Thanks so much!!!
Mike
2009/11/8 Szilveszter Tóth
Mike,
if you record the audio from ChucK using a WvOut like this:
dac.chan(0) => Gain g => WvOut w => blackhole; "tmp.wav" => w.wavFilename;
do you hear the click in the resulting tmp.wav? If not, then the problem is with reading a file between samples. If yes, then the abrupt sample change may play a role, too.
Szilveszter (Hillaby)
Szilveszter Tóth escribió:
Mike,
Just some thoughts.
When you kill the "last shred" that was playing, the audio signal drops to 0 (or to the first sample of the next WAV file), which may cause clicks. Also, reading an entire file (or part of it) between two samples may not be feasible, which will not only cause a click, but the realtime timing will also be lost (ChucK will wait for the entire file to be read in.)
I'd use an Envelope for the first problem and I'd try changing chunk size for the second. (Or maybe pre-read the next file to be played, if it can be determined beforehand.)
I hope I could help a little Szilveszter (Hillaby)
mike clemow escribió:
This is a shot-in-the-dark...
At the last minute, the person who was responsible for doing the sound with a Kyma system, couldn't get it to trigger sounds with MIDI (for some reason or another) and I'm stepping up and doing the whole show with pre-recorded material in ChucK. (I know, I know -- I'm crazy.)
It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio.
Now, I know that one way around this is to pre-load all the files into SndBuf objects and then trigger them to play using Events. The only trouble is that there are 73 files for this piece and some of them are pretty large. I'm afraid of eating all my RAM / bringing everything to a grinding halt.
I'm posting my entire script at the end of the email. If anyone has any thoughts, please send them along. Otherwise, we'll just deal with the way things are.
Best, Mike
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Mike,
"Frame" is just shorthand for (usually interleaved) samples for every
channel at a particular moment. So, a stereo frame is two samples,
quadrophonic frame is four samples, etc.
As another effort, WvIn says:
Small files are completely read into local memory
during instantiation. Large files are read
incrementally from disk. The file size threshold
and the increment size values are defined in
WvIn.h.
I did some sleuthing and the threshold is 5 MB (ugen_stk.h : 1106), so
if your files are larger than that than this might make it work. If
not, if nothing else works, and if you already have a working build,
you could try changing that line in ugen_stk.h and rebuilding to see
if it helps. Good luck!
Andrew
On Sun, Nov 8, 2009 at 10:10 AM, mike clemow
Hi Szilveszter, Kassen,
Thanks for the quick response! It's definitely the reads between samples that's causing the issue, because I only kill the last shred twice during the piece. The dropouts occur only when spawning new shreds.
I've already set the chunk-size to 1024... I assume that this is samples, although the documentation says "frames."
I'll try preloading the files in a big array and see if I run out of RAM.
Thanks so much!!!
Mike
2009/11/8 Szilveszter Tóth
: Mike,
if you record the audio from ChucK using a WvOut like this:
dac.chan(0) => Gain g => WvOut w => blackhole; "tmp.wav" => w.wavFilename;
do you hear the click in the resulting tmp.wav? If not, then the problem is with reading a file between samples. If yes, then the abrupt sample change may play a role, too.
Szilveszter (Hillaby)
Szilveszter Tóth escribió:
Mike,
Just some thoughts.
When you kill the "last shred" that was playing, the audio signal drops to 0 (or to the first sample of the next WAV file), which may cause clicks. Also, reading an entire file (or part of it) between two samples may not be feasible, which will not only cause a click, but the realtime timing will also be lost (ChucK will wait for the entire file to be read in.)
I'd use an Envelope for the first problem and I'd try changing chunk size for the second. (Or maybe pre-read the next file to be played, if it can be determined beforehand.)
I hope I could help a little Szilveszter (Hillaby)
mike clemow escribió:
This is a shot-in-the-dark...
At the last minute, the person who was responsible for doing the sound with a Kyma system, couldn't get it to trigger sounds with MIDI (for some reason or another) and I'm stepping up and doing the whole show with pre-recorded material in ChucK. (I know, I know -- I'm crazy.)
It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio.
Now, I know that one way around this is to pre-load all the files into SndBuf objects and then trigger them to play using Events. The only trouble is that there are 73 files for this piece and some of them are pretty large. I'm afraid of eating all my RAM / bringing everything to a grinding halt.
I'm posting my entire script at the end of the email. If anyone has any thoughts, please send them along. Otherwise, we'll just deal with the way things are.
Best, Mike
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- http://michaelclemow.com http://semiotech.org _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Andrew,
Oh... wait, I'm using SndBuf, not WvIn. Should I not do that?
I'm going to try to re-write this to pre-load and see what happens...
thanks for all your help!
mike
On Sun, Nov 8, 2009 at 10:21 AM, Andrew C. Smith
Mike,
"Frame" is just shorthand for (usually interleaved) samples for every channel at a particular moment. So, a stereo frame is two samples, quadrophonic frame is four samples, etc.
As another effort, WvIn says:
Small files are completely read into local memory during instantiation. Large files are read incrementally from disk. The file size threshold and the increment size values are defined in WvIn.h.
I did some sleuthing and the threshold is 5 MB (ugen_stk.h : 1106), so if your files are larger than that than this might make it work. If not, if nothing else works, and if you already have a working build, you could try changing that line in ugen_stk.h and rebuilding to see if it helps. Good luck!
Andrew
On Sun, Nov 8, 2009 at 10:10 AM, mike clemow
wrote: Hi Szilveszter, Kassen,
Thanks for the quick response! It's definitely the reads between samples that's causing the issue, because I only kill the last shred twice during the piece. The dropouts occur only when spawning new shreds.
I've already set the chunk-size to 1024... I assume that this is samples, although the documentation says "frames."
I'll try preloading the files in a big array and see if I run out of RAM.
Thanks so much!!!
Mike
2009/11/8 Szilveszter Tóth
: Mike,
if you record the audio from ChucK using a WvOut like this:
dac.chan(0) => Gain g => WvOut w => blackhole; "tmp.wav" => w.wavFilename;
do you hear the click in the resulting tmp.wav? If not, then the problem is with reading a file between samples. If yes, then the abrupt sample change may play a role, too.
Szilveszter (Hillaby)
Szilveszter Tóth escribió:
Mike,
Just some thoughts.
When you kill the "last shred" that was playing, the audio signal drops to 0 (or to the first sample of the next WAV file), which may cause clicks. Also, reading an entire file (or part of it) between two samples may not be feasible, which will not only cause a click, but the realtime timing will also be lost (ChucK will wait for the entire file to be read in.)
I'd use an Envelope for the first problem and I'd try changing chunk size for the second. (Or maybe pre-read the next file to be played, if it can be determined beforehand.)
I hope I could help a little Szilveszter (Hillaby)
mike clemow escribió:
This is a shot-in-the-dark...
At the last minute, the person who was responsible for doing the sound with a Kyma system, couldn't get it to trigger sounds with MIDI (for some reason or another) and I'm stepping up and doing the whole show with pre-recorded material in ChucK. (I know, I know -- I'm crazy.)
It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio.
Now, I know that one way around this is to pre-load all the files into SndBuf objects and then trigger them to play using Events. The only trouble is that there are 73 files for this piece and some of them are pretty large. I'm afraid of eating all my RAM / bringing everything to a grinding halt.
I'm posting my entire script at the end of the email. If anyone has any thoughts, please send them along. Otherwise, we'll just deal with the way things are.
Best, Mike
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- http://michaelclemow.com http://semiotech.org _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Here you go. I think this is what you need. WvIn seems quite simplistic compared to SndBuf. I can't really see why anyone would use it. Kas. [ugen]: SndBuf - sound buffer ( now interpolating ) - reads from a variety of file formats - see examples: sndbuf.ckhttp://chuck.cs.princeton.edu/doc/examples/basic/sndbuf.ck *(control parameters)* - *.read* - ( string , WRITE only ) - loads file for reading - *.chunks - ( int, READ/WRITE ) - size of chunk (# of frames) to read on-demand; 0 implies entire file, default; must be set before reading to take effect.* - *.samples* - ( int , READ only ) - get number of samples - *.length* - ( dur, READ only ) - get length as duration - *.channels* - ( int , READ only ) - get number of channels - *.pos* - ( int , READ/WRITE ) - set position ( 0 < p < .samples ) - *.rate* - ( float , READ/WRITE ) - set/get playback rate ( relative to file's natural speed ) - *.interp* - ( int , READ/WRITE ) - set/get interpolation ( 0=drop, 1=linear, 2=sinc ) - *.loop* - ( int , READ/WRITE ) - toggle looping - *.freq* - ( float , READ/WRITE ) - set/get loop rate ( file loops / second ) - *.phase* - ( float , READ/WRITE ) - set/get phase position ( 0-1 ) - *.channel* - ( int , READ/WRITE ) - sel/get channel ( 0 < p < .channels ) - *.phaseOffset* - ( float , READ/WRITE ) - set/get a phase offset - *.write* - ( string , WRITE only ) - loads a file for writing ( or not )
Hello!
we ran the 2pm show with some difficulty. mixing all the files to
mono and pre-loading everything worked (using almost 1gb of RAM). the
mono bounces were all clipped.
of course, it's supposed to be a 4-channel piece... ;-)
we had some sensor and code issues. We stopped and started over a
couple of times. but basically the ChucK part worked perfectly. :D
Thanks SOOOOO much for all your help, everyone. I think that the 8pm
show will be better.
Kas, I was using buf.chunks(1024), but it looked in Activity Monitor
like it was loading the whole file anyway. hrm...
More soon!
-Mike
2009/11/8 Kassen
Here you go. I think this is what you need. WvIn seems quite simplistic compared to SndBuf. I can't really see why anyone would use it.
Kas.
[ugen]: SndBuf
sound buffer ( now interpolating ) reads from a variety of file formats see examples: sndbuf.ck
(control parameters)
.read - ( string , WRITE only ) - loads file for reading .chunks - ( int, READ/WRITE ) - size of chunk (# of frames) to read on-demand; 0 implies entire file, default; must be set before reading to take effect. .samples - ( int , READ only ) - get number of samples .length - ( dur, READ only ) - get length as duration .channels - ( int , READ only ) - get number of channels .pos - ( int , READ/WRITE ) - set position ( 0 < p < .samples ) .rate - ( float , READ/WRITE ) - set/get playback rate ( relative to file's natural speed ) .interp - ( int , READ/WRITE ) - set/get interpolation ( 0=drop, 1=linear, 2=sinc ) .loop - ( int , READ/WRITE ) - toggle looping .freq - ( float , READ/WRITE ) - set/get loop rate ( file loops / second ) .phase - ( float , READ/WRITE ) - set/get phase position ( 0-1 ) .channel - ( int , READ/WRITE ) - sel/get channel ( 0 < p < .channels ) .phaseOffset - ( float , READ/WRITE ) - set/get a phase offset .write - ( string , WRITE only ) - loads a file for writing ( or not )
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Mike; we ran the 2pm show with some difficulty. mixing all the files to
mono and pre-loading everything worked (using almost 1gb of RAM).
Oh, well, that's what the RAM is there for :-).
the mono bounces were all clipped.
Whoopsie. It happens.
of course, it's supposed to be a 4-channel piece... ;-)
:-)
we had some sensor and code issues. We stopped and started over a couple of times. but basically the ChucK part worked perfectly. :D
For all of it's crash-prone-ness I do find that ChucK is quite predictable; once you have your code working it'll keep working. I don't think I ever had a crash or glitch on stage (aside from livecoding).
Thanks SOOOOO much for all your help, everyone. I think that the 8pm show will be better.
No problem; I enjoy this kind of thing. If any pictures or recordings materialise do post; I'd like to see what you've been up to but don't stress for my sake.
Kas, I was using buf.chunks(1024), but it looked in Activity Monitor like it was loading the whole file anyway. hrm...
Lovely! Another bug found. We need to keep Ge on his toes; I hear he eats quite a lot, let's keep him busy to compensate ;-). I have actually been working on a similar problem lately ( http://bottomfeeder.ca/top/?p=71 ). It's quite hard. I said it before but I feel that ChucK could use a syntax for "load this file as quickly as you can without glitches but no quicker". The matter has been debated on the wiki with regard to fileIO but I still feel that the interaction between the highly abstracted ChucK syntax (that assumes a infinitely fast computer even while meant to facilitate a good trade between sound quality and CPU usage) and the finite resources of the underlying system could use some attention.
More soon!
Good luck! Kas.
Howdy, On Nov 8, 2009, at 1:38 PM, Kassen wrote:
Kas, I was using buf.chunks(1024), but it looked in Activity Monitor like it was loading the whole file anyway. hrm...
Lovely! Another bug found. We need to keep Ge on his toes; I hear he eats quite a lot, let's keep him busy to compensate ;-). I have actually been working on a similar problem lately ( http://bottomfeeder.ca/top/?p=71 ). It's quite hard. I said it before but I feel that ChucK could use a syntax for "load this file as quickly as you can without glitches but no quicker". The matter has been debated on the wiki with regard to fileIO but I still feel that the interaction between the highly abstracted ChucK syntax (that assumes a infinitely fast computer even while meant to facilitate a good trade between sound quality and CPU usage) and the finite resources of the underlying system could use some attention.
Quick question: how is Activity Monitor being used to make this conclusion? If you are looking purely at total memory usage, one thing to consider is that SndBuf allocates memory to store the entire file in memory as soon as it is opened, regardless of your chunk size. Not that, like, ChucK has never had a bug or anything... just want to make sure we're not chasing shadows. spencer
Spencer;,
Quick question: how is Activity Monitor being used to make this conclusion?
Oh, yes, that makes sense, not in the last place to avoid memory fragmentation. I'd like to run some tests on this. Would it do to start loading a large file with a low chunk size, then immediately try to read from the end (which shouldn't yet be loaded)? When should these chunks be loaded at all? Is this affected by advancing time only or perhaps when the UGen graph has cycles to spare at the end of a block? maybe it's affected but SndBuf's .pos() and .rate() (considering the last may be negative if we'd like to play the file backwards)? Right now this might be of a lot of use to me too so I'd like to spend some time investigating whether there is a issue here and, if not, exactly how we can make the most of this feature. What should prober behaviour be?
Not that, like, ChucK has never had a bug or anything... just want to make sure we're not chasing shadows.
That sounds sensible, yes. Ok, then it's on to phase two of the "blame ChucK, ask questions later" process. :-) Kas.
Kas wrote: don't know why anyone would use WvIn... I think I did some testing once that showed WvIn as faster (more voices without clix) PRC
Perry; I think I did some testing once that showed WvIn as faster (more voices
without clix)
Ah, yes, that makes perfect sense as it's more modest feature-wise. I could see how that would be useful in a situation like Mike's where you have many different samples and perhaps no need for interpolation. Another solution to this kind of thing that I considered for my own situation is using trickery to figure out when we are not making any sound and pre-loading sounds that will be needed in the future during that time and not when we are more busy. Stuttering silence is, after all, still silence. Probably a good idea for step sequencers using short samples and where it's easy to figure out where the rests from the pattern memory are and less great for generative drones. I think Ableton using pre-loading of the first bit of all clips that may be triggered and uses the time that buys to ready HD streaming. That seems like a sound strategy but personally I don't think I've ever needed more memory than I have ram in the past 5 or so years. Yours, Kas.
Silvester; do you hear the click in the resulting tmp.wav? If not, then the problem is
with reading a file between samples. If yes, then the abrupt sample change may play a role, too.
I should clarify that ChucK doesn't need to calculate one sample per samp. If that were the case then I think any non-trivial file-loading would cause issues, which is of course untrue. ChucK doesn't hand values to the soundcard one by one, instead it does so in blocks of tens, hundreds or thousands of samples (always a power of 2). The thing that needs to be done is calculate -say- 512 samples in a duration of 512::samp so assuming there is no heavy processing going on we can deal with any peaks in cpu usage by increasing the block size by enough. Timing-wise the loading still occurs "in between samples" but then again; so does all our other code. I hope that clarifies things a bit. Shout if I misunderstood you. Yours, Kas.
Hi Kassen, I'm sure it was me who misunderstood something... This is what I thought: When Mike's script sporks a new playFile() shred, this tells Chuck to read in two SndBufs and connect them to dac _before_ the next sample is calculated. I may be wrong, though Szilveszter (Hillaby) Kassen escribió:
Silvester;
do you hear the click in the resulting tmp.wav? If not, then the problem is with reading a file between samples. If yes, then the abrupt sample change may play a role, too.
I should clarify that ChucK doesn't need to calculate one sample per samp. If that were the case then I think any non-trivial file-loading would cause issues, which is of course untrue.
ChucK doesn't hand values to the soundcard one by one, instead it does so in blocks of tens, hundreds or thousands of samples (always a power of 2). The thing that needs to be done is calculate -say- 512 samples in a duration of 512::samp so assuming there is no heavy processing going on we can deal with any peaks in cpu usage by increasing the block size by enough.
Timing-wise the loading still occurs "in between samples" but then again; so does all our other code.
I hope that clarifies things a bit. Shout if I misunderstood you.
Yours, Kas. ------------------------------------------------------------------------
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Szilveszter; This is what I thought:
When Mike's script sporks a new playFile() shred, this tells Chuck to read in two SndBufs and connect them to dac _before_ the next sample is calculated.
Yes, that's right. However, that doesn't mean ChucK needs to do it before a samp has passed. ChucK needs to calculate -say- 1024 samples as well as do things like loading a file in the time-span of 1024::samp. The longer the block becomes the more any sudden peaks in system usage can be spread out. In ChucK syntax we pretend things like loading files are instantaneous, but of course they are not in reality; even a simple multiplication will take some time to be calculated. This convenient and expressive way of looking at the computer that we use works very well.... until the underlying system can no longer cope with the strain at which point we'll see the reality below it shine through. BTW, your test of writing to a wave file to see whether there are glitches there won't work; ChucK will always write to wave files correctly, even when it runs out of cpu. In that case the audible sound will glitch but all samples will be calculated and written. In the mini you can see this happen; the displayed value of "now" will start lagging and as soon as the processing intensive bit is over "now" will be increasing faster than a second per second until it has caught up. Hope that helps, Kas.
Mike; (I know, I know -- I'm crazy.)
:-) this does remind me that I need to document and file a big relating to assignment and -probably- over-zealous GC that I found Friday night, a few hours before show-time.
It's 9:25am here on the East Coast of the U.S. We're onstage at 2pm and 8pm. I have a script that receives OSC messages from a Java program. The messages contain the string name of a file to play. It's a simple stereo file (I'm already working with a very kludgy way of playing stereo files--loading it twice into two buffers). But every time I spawn a new thread, the file loads from disk and there's an audible click, or drop in audio.
Ok, I don't have the time to hack at your code as I need to help clean up from Friday's party this afternoon. Also; my systems aren't your systems, being equipped with different drives and CPU. As this is a system-specific issue it makes no sense for me to test fixes here. But; * First place for speedy fixes of system-overload-related clicks is increase the buffer size when starting ChucK. The price is latency, of course, but we're on a deadline. * I think SndBuf can block-load parts of the file instead of fetching it all at once. Look into that. This sounds like the most structural solution to me but I think few people use that feature so it might have bugs. *Pre loading all files into a big array of SndBuf's that aren't chucked to the dac will not cost CPU, just memory. In this case you'd play them by connecting them and sporking the relevant shred (remembering to disconnect them later). This won't grind things to a halt cpu-wise. It might cost a lot of memory. Verify you don't happen to have that much ram. If not consider batch-converting them all down to CD quality if they aren't already. If they are already at CD quality you could see what happens when the computer would get down to virtual memory; the OS might have special tricks there to speed things up that ChucK lacks. Good luck! Kas.
participants (6)
-
Andrew C. Smith
-
Kassen
-
mike clemow
-
Perry R Cook
-
Spencer Salazar
-
Szilveszter Tóth