Buffer rate scaled

There is a single function, and a single synthdef, both surrounding the use of buffer objects.

There is a playback problem in the synthdef regarding the rate: argument for PlayBuf.ar

~buffer =
{
	|x|

	Buffer.read
	(
		server: s // s.sampleRate_(44100)
		,
		path: ~samples[x] // ~samples rendered 27hz/44100
		,
		startFrame: 0
		,
		numFrames: -1
		,
		action:
		{
			|buffer|

			this.b_ // buffer
			(
				buffer.loadToFloatArray
				(
					index: 0
					,
					count: -1 
					,
					action:
					{
						|array| this.a_(array) // float array
					}
				)
			)
			.c_ // sets this.b & this.a
			{
				|array|

				Buffer.loadCollection
				(
					server: s,

					collection: array ? this.a,

					numChannels: 2,

					action:
					{
						|buffer|

						this.b_ // buffer
						(
							buffer.loadToFloatArray
							(
								index: 0
								,
								count: -1
								,
								action:
								{
									|array| this.a_(array) // float array
								}
							)
						)
					}
				)

				;b // return
			}
		}
	)

	;b // return
}

/***

(

SynthDef(\playbuf,
	{
		|bufnum rate|

		Out.ar(0,

			PlayBuf.ar
			(
				numChannels: 2,

				bufnum: bufnum,

				rate:
				(
					BufRateScale.kr(bufnum) * (rate / 27) // samples rendered 27 hZ
				)

				// ,trigger: 1,
				// ,startPos: 0,
				// ,loop: 0,
				// ,doneAction: 0
			)

			* Env.triangle(b.duration).kr(Done.freeSelf)
		)
	}
)
.play(s,
	[
		\bufnum, b.bufnum, \rate, 27
		// 27 * 2.pow(1)
		// 27 * 2.pow(2)
		// 27 * 2.pow(3)
		// 27 * 2.pow(4)
		// 27 * 2.pow(5)
		// 		...resulting synths are increasingly over pitched up it's octaves
		// 		...the 5th octave is only 864hz, yet sounds more than tripled over
	]
)

)

// rendered samples may be offset by a miscalculation factor of -6..6hZ, at worst

// the determined question is whether the synthdef handles it's rate argument correctly

***/

When I do this, I hear a clean, correctly pitched harmonic series – so rate is fine. The problem must be somewhere else.

b = Buffer.alloc(s, s.sampleRate, 1);

(
a = {
	RecordBuf.ar(
		SinOsc.ar(27),
		b, loop: 0, doneAction: 2
	)
}.play;
)

b.plot  // looks OK

(
SynthDef(\osc27, { |out, gate = 1, freq = 440, amp = 0.1|
	var eg = EnvGen.kr(Env.asr(releaseTime: 0.1), gate, doneAction: 2);
	var sig = PlayBuf.ar(1, b,
		rate: BufRateScale.kr(b) * (freq / 27),
		loop: 1
	);
	Out.ar(out, (sig * eg * amp).dup);
}).add;
)

(
p = Pbind(
	\instrument, \osc27,
	\freq, 110 * Pn(Pseries(1, 1, 16), inf),
	\dur, 0.25,
	\legato, 1
).play;
)

hjh

Thanks chief.

I was mostly inspired to make this post out of directly wondering if this line was the correct approach.

Perfect lesson & example, thanks again.