The problem with long buffers... examples?

Hello,
I thought I had understood the problem SC has with long buffers: something like when the index overflows the underlying data structure’s memory size, SC inevitably loses precision.
In the past, I thought I could hear examples of this behavior as sounding like downsampling. Now I’m not sure anymore, and can’t reproduce that glitch by, for example, indexing at half of a one hour buffer.
Has it been solved somehow, or (as I’m suspecting) I didn’t understand anything of this problem? Could anyone help me find some examples?

Thanks!

Ok, there’s this answer from esluyter on github: https://github.com/supercollider/supercollider/issues/3973.

The problem is more appearent at slower playback rates. Esluyter has examples, which I condensate like this:

b = Buffer.alloc(s,s.sampleRate*3600)
b.sine2([b.duration*100],[1],true,false);

{ 
	var start = [1,10,100,1000];
	BufRd.ar(1, b, 
		Phasor.ar(0, 0.3, start*BufSampleRate.ir(b), (start+1)*BufSampleRate.ir(b))
	) 
}.plot(0.01)


It appears also at rate 1, but for larger indices:

Esluyter proposes a IMHO brilliant solution with SuperBufRd:

{ 
	var start = [1,10,100,1000];
	SuperBufRd.ar(1, b, 
		SuperPhasor.ar(0, 0.3, start*BufSampleRate.ir(b), (start+1)*BufSampleRate.ir(b))
	) 
}.plot(0.01)

And now the question: this problem doesn’t seem to appear with PlayBuf or LoopBuf!

// these don't generate a squary plot!
{ 
	var start = [1,10,100,1000];
	PlayBuf.ar(1, b,0.3,1,start*BufSampleRate.ir(b)) 
}.plot(0.01);

{ 
	var start = [1,10,100,1000];
	LoopBuf.ar(1, b,0.3,1,start*BufSampleRate.ir(b),start*BufSampleRate.ir(b),(start+1)*BufSampleRate.ir(b)) 
}.plot(0.01)

Can anyone explain why is that?

P.S. : it is even worse with BufWr! (and again no problem with RecordBuf)

b = Buffer.alloc(s,s.sampleRate*3600);
{
	var start = 1000;
	BufWr.ar(
		SinOsc.ar(1000), b, 
		Phasor.ar(0, 0.5, start*BufSampleRate.ir(b), (start+1)*BufSampleRate.ir(b))
	) 
}.play;
{
	var start = 1000;
	SuperBufRd.ar(1, b, 
		SuperPhasor.ar(0, 0.5, start*BufSampleRate.ir(b), (start+1)*BufSampleRate.ir(b))
	) 
}.plot(0.001);

image

PlayBuf keeps its phase internally, so it isn’t limited to 32-bit floats.

  • BufRd/Wr: 32-bit float phase input (because all UGen inputs are 32-bit floats), loses precision at a certain level

  • PlayBuf: Internal phase can use 64-bit floats, still loses precision but much much much later.

hjh

2 Likes