1

我编写了以下代码来定义一个 SynthDef,它将声音记录到作为参数之一传递的缓冲区中。

(
SynthDef(\recordTone, { |freq, bufnum, duration|
    var w = SinOsc.ar(freq) * XLine.ar(101,1,duration,add: -1) / 100;
    RecordBuf.ar(w!2,bufnum,loop: 0,doneAction: 2);
}).add;
)

我还有下面的代码,它为上述 SynthDef 调用 Synth 并尝试将缓冲区写入文件。

({
    var recordfn = { |freq, duration, fileName|
        var server = Server.local;
        var buf = Buffer.alloc(server,server.sampleRate * duration,2);

        Synth(\recordTone,[\freq, 440, \bufnum, buf.bufnum, \duration, duration]);
        buf.write(
            "/Users/minerva/Temp/snd/" ++ fileName ++ ".wav",
            "WAVE",
            "int16",
            completionMessage: ["b_free", buf.bufnum]
        );
    };

    recordfn.value(440,0.5,"test");

}.value)

正在创建输出文件,但不包含任何声音。我究竟做错了什么?我浏览了所有我能找到的 SuperCollider 文档,但似乎没有任何效果!非常感谢任何指针。

4

2 回答 2

3

根据 Dan S 的回答,我进行了一些更改以使其正常工作:

(
SynthDef(\playTone, { |freq, duration|
    var w = SinOsc.ar(freq) * XLine.ar(1001,1,duration,add: -1,doneAction:2) / 1000;
    Out.ar(0,w!2);
}).add;
)

(
SynthDef(\recordTone, { |buffer|
    RecordBuf.ar(In.ar(0,2), buffer, loop: 0, doneAction: 2);
}).add;
)

(Routine({
    var recordfn = { |freq, duration|
        var server = Server.local;
        var buffer = Buffer.alloc(server, server.sampleRate * duration, 2);

        server.sync;

        server.makeBundle(func: {
            var player = Synth(\playTone, [\freq, freq, \duration, duration]);
            var recorder = Synth.after(player, \recordTone, [\buffer, buffer]);
        });

        duration.wait;

        buffer.write(
            "/Users/minerva/Temp/snd/test.wav",
            "WAVE",
            "int16",
            completionMessage: ["/b_free", buffer]
        );
    };

    recordfn.value(440,0.1);

}).next)
于 2014-03-14T01:10:21.000 回答
2

您的主要问题是,在您的recordfn函数中,您正在实例化 SynthDef(即开始录制)并同时将缓冲区写入磁盘。显然,在您开始录制时,缓冲区中没有声音,因此 SuperCollider 完全按照您的要求进行操作,并将空的静音缓冲区作为文件写入。

解决方案:

  • 最基本的解决方案是调用一个函数开始录制,并在写入磁盘时调用一个单独的函数。
  • 或者,如果您想将所有内容合二为一,请考虑在您的函数中启动一个任务,以便等到缓冲区准备好写入磁盘。
  • 或代替 RecordBuf 使用DiskOut直接“假脱机”到磁盘。

第二件事:我现在不记得了,但我认为它可能是“WAV”而不是“WAVE”。

于 2014-03-13T08:49:41.943 回答