经过大量研究,我想出了一个解决方案:使用控制总线来获取值。我们将一个函数作为输入 (f),然后将其播放到总线上。
然后,我们通过调用总线上的 get 方法并提供允许我们从抛出的函数中提取值的函数来从该总线读取数据。
~mkscalarfun = {
arg f={ 0 };
var last = 0.0;
var mbus = Bus.control(s, 1);
var pf = f.play(s,mbus);
var scalarf = {
mbus.get({|v| last = v;});
last;
};
scalarf; // This is a function
};
// Create a closure that includes the bus
~mousescalarf = ~mkscalarfun.({ MouseX.kr(1, 4, 1); });
~mousescalarf.();
~mousescalarf.().rand.wait;
我不确定这个解决方案有多惯用,或者它是否合适,或者它的性能如何。
此解决方案的一个问题是 pf 是隐藏的,因此您无法阻止它。
一种替代方法是使用 OO 解决方案,在扩展目录中创建一个类:
MakeScalarKR {
var last;
var mbus;
var pf;
var f;
*new { arg sbase,f;
^super.new.init(sbase,f)
}
init {
arg sbase,myf;
f = myf;
last = 0.0;
mbus = Bus.control(sbase, 1);
pf = f.play(sbase, mbus);
}
v {
mbus.get({|x| last=x;});
^last
}
free {
pf.free
}
}
然后你可以像这样调用这个类:
~mkr = MakeScalarKR(s,{ MouseX.kr(10,400,1) });
~mkr.v()