Changing buffer while synth running

I want to load a new buffer into a synth, while the synth running. I thought specifying the buf as argument and then doing synth.set(\bf, ~new_buf) would do, but I get ^^ ERROR: Message 'addKr' not understood. RECEIVER: nil instead. Here is my synth definition, has any one any ideas why this can’t be done?

synth = {
    var pointer, pitch;
    pointer = Saw.ar((BufDur.kr(\bf.kr(b)).reciprocal/0.01)).range(0, 1);
	Splay.ar(
		Warp1.ar(
			numChannels: 1,
			bufnum: \bf.kr(b),
			pointer: pointer,
			freqScale: BufRateScale.ir(\bf.kr(b)) * SinOsc.ar(
				Array.geom(sz, 0.5, 1.01)
			).range(0.4, 2).round(Array.geom(sz, 0.1, 1.5)),
			windowSize: 0.5,
			envbufnum: u,
			overlaps: 40,
			windowRandRatio: 0,
			interp: interp,
			mul: amp1
		)
	)
};

Don’t know what’s going on from the example, could you post a minimal example that we can run.

Either way, this line

should probably be BufRateScale.kr

I simplified the example down to the following, which does work! Something must be going on in my synth which prevents resetting the buffer:
(btw. thanks for you hint, I corrected the kr rate)
So, this works:

(
x = {
    var pointer;
    pointer = Saw.ar((BufDur.kr(\bf.kr(b)).reciprocal)).range(0, 1);
	Warp1.ar(
			numChannels: 1,
			bufnum: \bf.kr(b),
			pointer: pointer
		)
}.play;
)

Could you post the full stack trace for this? A .set call shouldn’t be trying to add UGens.

Also, your time pointer should be LFSaw. I doubt that you want Gibbs effect wiggling in your control signal.

hjh

1 Like

I think the problem is with using \bf.kr twice - I don’t think you can do that. Instead, assign it to a variable inside the synthdef (function) and use that variable in multiple places:

var pointer;
var buffer = \bf.kr(b);
    pointer = Saw.ar((BufDur.kr(buffer).reciprocal)).range(0, 1);
	Warp1.ar(
			numChannels: 1,
			bufnum: buffer,
			pointer: pointer
		)

Actually that’s fine – NamedControl collapses multiple uses of the same name down to one control.

I think the key is in the stack trace – a .set call has no reason to go into addKr, except maybe in JITLib, but the example gives no indication of using JITLib. Without evidence of how that specific error is occurring, it’s just speculation.

hjh

Wow, great that you also comment on other parts of my code. Why is LFSaw here different from Saw? Why shouldn’t I use Saw?

Also the trace-back:

ERROR: Message 'addKr' not understood.
RECEIVER:
   nil
ARGS:
   Symbol 'bf'
Instance of Buffer {    (0x55a224f782e8, gc=D4, fmt=00, flg=00, set=03)
  instance variables [8]
    server : instance of Server (0x55a2208db278, size=30, set=5)
    bufnum : Integer 0
    numFrames : Integer 169750
    numChannels : Integer 1
    sampleRate : Float 44100.000000   00000000 40E58880
    path : "/home/amte/Desktop/piano-in-11_8-298.wav"
    startFrame : Integer 0
    doOnInfo : nil
}
PATH: /home/amte/zeug/Kammermusik_git/skizz.scd
CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	Nil:handleError
		arg this = nil
		arg error = <instance of DoesNotUnderstandError>
	Thread:handleError
		arg this = <instance of Thread>
		arg error = <instance of DoesNotUnderstandError>
	Object:throw
		arg this = <instance of DoesNotUnderstandError>
	Object:doesNotUnderstand
		arg this = nil
		arg selector = 'addKr'
		arg args = [*2]
	NamedControl:init
		arg this = <instance of NamedControl>
		var prefix = nil
		var str = "bf"
	Meta_NamedControl:new
		arg this = <instance of Meta_NamedControl>
		arg name = 'bf'
		arg values = [*1]
		arg rate = 'control'
		arg lags = nil
		arg fixedLag = false
		arg spec = nil
		var res = nil
	< FunctionDef in closed FunctionDef >
		var pointer = nil
		var pitch = nil
	Interpreter:interpretPrintCmdLine
		arg this = <instance of Interpreter>
		var res = nil
		var func = <instance of Function>
		var code = "x.set(\bf, c)"
		var doc = nil
		var ideClass = <instance of Meta_ScIDE>
	Process:interpretPrintCmdLine
		arg this = <instance of Main>
^^ ERROR: Message 'addKr' not understood.
RECEIVER: nil

It’s a very strange stack trace – if x is a Synth, then there’s no reason for the .set call to rebuild the SynthDef. This means there’s something about your scenario that you haven’t told, yet – is x perhaps a NodeProxy?

I note that your first code example a/ doesn’t assign anything to x (so x is unknown to forum readers) – but you’re calling x.set (the call stack confirms this) – I don’t have enough information to make sense of this – and b/ also doesn’t call .play on the function (so, as written, your code example isn’t playing anything that could be set).

I think you’ll need to explain exactly what you’re doing, and not leave steps out. Some of the situation is not visible from here.

Saw is for audio signals. Audio signals should be anti-aliased. Look up “Gibbs effect” to learn more about what that means. (There’s plenty of material online about this; I’m too tired to write my own short treatise about it here, with apologies.)

The pos input to the granulator is not an audio signal. It’s a control signal. You generally want a pure geometric shape for control signals.

hjh

1 Like