'VDiskIn.ar', the buffer created by Buffer.cueSoundFile and 'doneAction: Done.freeSelf' used in Line.kr, XLine.kr and EnvGen.kr

Dear users and developers,

I have found that VDiskIn does not entirely read the buffer created through Buffer.cueSoundFile when using Line.kr, XLine.kr and Env.kr with doneAction: Done.freeSelf.

I can hear a short sound in the following code by evaluating the second x.play.

(
~path = Platform.resourceDir +/+ "sounds/a11wlk01-44_1.aiff";
~soundFile = SoundFile.openRead(~path);
~soundFile.close;
~duration = ~soundFile.duration;
~cueBufferLoad = { Buffer.cueSoundFile(s, ~path, 0, ~soundFile.numChannels) };
)

~aCueBuffer = ~cueBufferLoad.()

(
x = { VDiskIn.ar(~aCueBuffer.numChannels, ~aCueBuffer, BufRateScale.kr(~aCueBuffer))!2 
* 
Env.linen(0.01, ~duration-0.02, 0.01).kr(doneAction: Done.freeSelf) }
)

x.play // 1st time

x.play // 2nd time. I hear a short sound.

~aCueBuffer.close; ~aCueBuffer.free;

I could resolve the problem by adding 0.2 seconds to the ~duration.

Does the access time that the server copies the data from the sound file into the buffer cause it? (I think it could be correct, but I am not sure.)

Or is it because of the usual latency of the server (s.latency)? (I do not think so, but I am perplexed.)

Thanks in advance for your help!

In your example, it looks like you’re first playing almost all of the file, then the first synth stops. Then you’re not re-cuing the file, and playing starting with the data still in the buffer (near the end of the file). I believe in this case that it will only play the very tail of the file.

One thing you haven’t stated is the expected behavior. Since you’re saying that the short sound is not right, I’ll assume that you’re expecting a long sound, and this probably means that you want it to start again from the beginning. To do that, you’d have to cue the file again. (You wouldn’t have to free and re-allocate the buffer, just close it and use the cueSoundFile instance method.)

If you’re going to use DiskIn for repeated playback, or segments, buffer management takes some care.

hjh

1 Like

Yes, it is.
However, in my example, EnvGen outputs the values of Env.linen precisely for the duration of the sound file and then stops the synth.

Oh, sorry!
I expect that DiskIn.ar plays the sound entirely without remaining the tail of the sound file in the buffer.
I should add an extra time, for example, 0.2 seconds, to the duration of Env, to let DiskIn.ar entirely play the sound without remaining the tail of the sound file in the buffer.

My problem is that I do not understand why DiskIn.ar need more time (0.2 secs) than the length of the sound file to play the sound file entirely.

Yes, indeed!
My experiences with .cueSoundFile as an instance method, i.e. re-cueing, were not so stable when I made a music file player in SuperCollider, which sequentially plays WAV and AIFF files — creating a new Buffer.cueSoundFile after closing and freeing an old Buffer.cueSoundFile was more stable than re-cueing an existing Buffer.cueSoundFile.

As I understand it, this is not really a valid expectation.

Stopping a (V)DiskIn synth, and then starting another one, does not reset the buffer’s state to any other position in the file. After that point, we could even call it “undefined behavior.”

If you want the second synth to play back from the beginning of the file, you have to tell the buffer to go back to the beginning. That’s the only way to be sure.

hjh

1 Like