在SuperCollider中:如何将控制率变量下采样到标量值?
例如,我有一个标量全局叫做~delay,一些函数关心这个值。他们认为它是一个标量。我想在该变量上设置包络生成器,以便通过控制速率变量进行更改。或者使用MouseX.kr,如果我可以将MouseX.kr的单个值转换为标量值,我会很高兴。
假设我无法重构代码以允许k-rate全局,因此我需要从控制速率变量中对单个值进行采样或下采样。</ p>
我不能这样做:
MouseX.kr(1, 4, 1).rand.wait;
但我对此很满意:
downSample(MouseX.kr(1, 4, 1)).rand.wait;
或者
~mousex = MouseX.kr(1, 4, 1)
...
downSample(~mousex).rand.wait
答案 0 :(得分:1)
这是经典的SuperCollider language-vs-server问题。您希望在语言端计算中使用MouseX(表示服务器对鼠标位置的了解)。 (“为什么分裂?为什么语言不能使用相同的对象知道呢?” - 好吧,想象两个进程在不同的机器上运行 - 不同的鼠标......)
要使用该语言获得鼠标位置,最好使用以下方法之一:
Platform.getMouseCoords // SC up to 3.6
GUI.cursorPosition // SC recent versions
如果您确定要使用该语言的服务器数据,那么您自己通过Bus发送的答案是一种方法。最新版本的SuperCollider有方法
Bus.getSynchronous
Bus.setSynchronous
依赖于语言和服务器之间的新“共享内存接口”。如果两者都在同一台机器上,那么这可能是一种很好的方法,可以避免异步请求信息的延迟。
答案 1 :(得分:0)
经过大量研究后,我想出了一个解决方案:使用控制总线获取值。我们将函数作为输入(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()