0

如何将相位和幅度的 FFT 信息发送到 SuperCollider 中的振荡器组?似乎我误解了一些东西,但无法弄清楚我的代码有什么问题:

    msg = osc_message_builder.OscMessageBuilder(address = "/s_new 100 1 1 oscBank512")
    msg.add_arg(" amplitude ", amplitudes)
    msg.add_arg(" phase ",phases)
    msg.add_arg(" attackSynth ", 0.1)
    msg.add_arg(" releaseSynth", 0.5)
    msg = msg.build()
    client.send(msg)

所以我的振荡器库有 256 个 SinOsc,我想为它们发送幅度和相位信息,它们在那些数组中(幅度,相位)。但是 python-osc 不允许我这样做。它说:

ValueError:arg_type 必须是('f'、'i'、'b'、's'、'T'、'F')之一

那么我将如何正确构建该 OSC 消息呢?Python-osc 教程真的很小,在网上找不到任何帮助。我会使用 pyOSC 或 OSC,但 pip 无法安装它们,所以我坚持使用 python-osc。

振荡器组的 SuperCollider 代码:

    SynthDef.new(\oscBank512, {
    arg attackSynth=0.1, releaseSynth=0.1;
    var dmplitudeReceive = \dmplitudeReceive.kr( 0.0!256 );
    var phaseReceive = \phaseReceive.kr( 0.0!256 );
    var osc1, envelopeSynth, sig, amp, freq, phases, amps,out;

    freq = Array.fill(256, {
        arg i, j=(22050/256), k=(j/2);
        if(i==0){i*j}{(i*j)-k};
    });
    amp = EnvGen.kr(
            envelope: Env.perc(
                attackTime: attackSynth,
                releaseTime: releaseSynth,
                level: 1,
                curve: -4),
            doneAction: 2);

    sig = SinOsc.ar(freq:freq,  mul: dmplitudeReceive, phase: phaseReceive);
    sig = sig*amp;
    sig = Limiter.ar(in:Mix.new(sig), level:1);


    Out.ar(0, Pan2.ar(sig));
}).add;

dmplitudeReceive 故意用 d 命名。

4

2 回答 2

1

此消息中的地址应该只是“/s_new”,其他所有内容都是单独的参数。键和值按顺序进入消息,SuperCollider 应该能够将它们分类。

此代码一次添加一个参数及其类型。我原以为每个幅度和相位在您的 synthdef 中都有不同的名称,您必须单独处理。如果不是,它们最终可能会得到一个您可以解决的不同整数索引。

from pythonosc import osc_message_builder
from pythonosc import udp_client

client = udp_client.SimpleUDPClient('localhost', 57110)

amplitude = 0.5 # just adding one amplitude
phase = 0.5 # just adding one phase

msg = osc_message_builder.OscMessageBuilder(address = '/s_new')
msg.add_arg(100, arg_type='i')
msg.add_arg(1, arg_type='i')
msg.add_arg(1, arg_type='i')
msg.add_arg('oscBank512', arg_type='s')
msg.add_arg('amplitude', arg_type='s')
msg.add_arg(amplitude, arg_type='f')
msg.add_arg('phase', arg_type='s')
msg.add_arg(phase, arg_type='f')
msg.add_arg('attackSynth', arg_type='s')
msg.add_arg(0.1, arg_type='f')
msg.add_arg('releaseSynth', arg_type='s')
msg.add_arg(0.5, arg_type='f')
msg = msg.build()
client.send(msg)

不幸的是,python-osc 不支持 OSC 消息的数组类型,SuperCollider 使用该数组类型将参数数组发送到合成服务器。我不知道确实支持消息中的数组的 Python OSC 库,因此您可能必须考虑另一种方法来实现您想要的。

一种选择可能是使用一个振荡器来使用更简单的 synthdef,并根据需要生成 256 个(或更多!)。这样您就不必在创建一个 synthdef 时尝试发送 256 个值。

于 2017-02-27T09:28:11.320 回答
0

查看函数的参数add_argarg_value, arg_type=None。您正在尝试添加“键”和“值”,但无法添加“键”。

您只需“匿名”添加值。当您收到它们时,您可以通过了解添加它们的顺序来对它们进行解码。

于 2017-02-24T08:19:08.797 回答