PlayBuf vs BufRd for slow playback

I’ve tried two methods of buffer playback at slower-than-1 speed:

  • One is a simple PlayBuf with a rate argument set to (-1/4)
  • One is a BufRd + linear envelope, moving from samples at -1/4 rate

Played back-to-back, the two examples sound noticeably different. Not in pitch, but possibly providing more or less detail in certain frequency ranges. Before I provide a reproducer, is this known behavior? Do the two methods interpolate “in-between” samples differently, and if so is one method more accurate or otherwise preferable?

Thanks!

b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");

(
{
	var bufrd, playbuf;
	
	bufrd = BufRd.ar(1, b, Phasor.ar(0, BufRateScale.kr(b) * (-1/4), 0, BufFrames.kr(b)), interpolation: 4);
	playbuf = PlayBuf.ar(1, b, -1/4, loop: 1);
	
	(bufrd - playbuf).poll; // silent
}.play
)

PlayBuf uses cubic interpolation internally, whereas BufRd uses linear interpolation by default (source). This null test is successful on my end (note the cubic interpolation setting for BufRd, but even with the default linear interpolation the residual noise is very low - <= 80dB - when the rate is held constant). Maybe a reproducer is necessary here?

One other difference is that PlayBuf’s internal phase is double-precision while BufRd’s phase input can be only single-precision. At 1/4 rate, this is probably not significant. At very slow rates, it might be.

hjh

1 Like

[…] Maybe a reproducer is necessary here?

In the process of making a reproducer, I found the answer: it really is the linear vs. cubic interpolation.

Here’s a simple example. The difference is clearly audible to me.

s.waitForBoot {

b = Buffer.read(s, "/foo/bar.wav"); // a 1-channel, 48k sample. The server's also running at 48k.

Routine {

   3.do {
      play { PlayBuf.ar(1, b, -1/4, startPos: 48000) ! 2 };
      4.wait;
   };
   3.do {
      play {
         var phase, br;
         phase = EnvGen.ar(Env([48000,0], [4], curve: \linear));
         br = BufRd.ar(1, b, phase); // add ``interpolation: 4``` to get the same sound as PlayBuf
         br ! 2
      };
      4.wait;
   }

}.play

}

After listening to this sample hundreds of times, I can say the default interpolation: 2 sounds really bad compared to cubic.

1 Like