Connecting multiple stages of parallel synths, with array of buses, in superCollider

血红的双手。 提交于 2019-12-11 12:56:23

问题


When I have 2 stages of multiple parallel synths, I am able to connect it with an array of buses. (Thanks to Dan S for the answer to a previous question). When there is a 3 stage, this doesn't seem to work.

(
SynthDef(\siny, { arg freq, outBus=0; Out.ar( outBus, SinOsc.ar(freq!2,0,0.2) ) } ).send(s);
SynthDef(\filter, { arg cFreq,q=0.8, inBus, outBus=0; Out.ar( outBus, BPF.ar(In.ar(inBus), cFreq!2, 1/q ) ) } ).send(s);
)

(
var z = [100,500,1000,1500,200];
~sourceOut = z.collect{ Bus.audio(s) };
~sineOut = z.collect{ Bus.audio(s) };
~sine_Group = ParGroup.new;
~myGroup    = ParGroup.new;

{
z.do({ arg val, index; Synth( \siny, [\freq: val, \outBus: ~sourceOut[index]], ~sine_Group ) });
z.do({ arg val, index; Synth.after(~sine_Group, \filter, [\inBus: ~sourceOut[index], \outBus: ~sineOut[index],\cFreq: 200, \q: 20 ], ~myGroup) });
z.do({ arg val, index; Synth.after(~myGroup, \filter, [\inBus: ~sineOut[index], \cFreq: 200, \q: 20]) });

}.play;
)

Another harm that I am doing here is, everytime I stop and run the synth, new instances of busses are created and eventually run out of audio buses. How can I solve this?


回答1:


There are a number of issues with your code (some irrelevant with your question):

a. send(s) is a reminiscent of the past, these days simply add is preferable - you may consult the documentation for their differences.

b. it's not a good practice to mix local variables var with environmental ones (such as ~sourceOut) unless there is some good reason.

c. .collect(func) (or directly collect{/*function body here*/}) when send to an array results to another array where each element is the result of the func with the respective element of the original array passed as an argument. So here:

var z = [100,500,1000,1500,200];
~sourceOut = z.collect{ Bus.audio(s) };
~sineOut = z.collect{ Bus.audio(s) };

you don't use the original numbers anywhere, you just create two arrays containing 5 Audio buses each. Directly doing so would be less confusing and more explicit:

~sourceOut = Array.fill(5,{Bus.audio(s)});
~sineOut = Array.fill(5,{Bus.audio(s)});

d. there's no point in calling z.do three times.. you can call it just once and put the rest in the same function.

e. check you routings... You have two parallel groups and you're merely saying that I want these synths on that group and these others after that other group.. What you really want to say is that I want these Synths after those Synths on that group.

f. you don't free your Buses or your Synths when done... this is a memory leak :)

g. you call play on a function that want to evaluate really... you should call value instead.

This code does produces sound and cleans up everything when don, note however that the result is pretty boring because you've filtered all the higher-end.

s.waitForBoot({ // this is a routine

    var frequencies = [100,500,1000,1500,200];
    var sources = Array.fill(frequencies.size,{Bus.audio(s)});
    var filters = Array.fill(frequencies.size,{Bus.audio(s)});
    var parGroups = Array.fill(2,{ParGroup.new});
    var sineSynths;
    var firstOrderFilters;
    var secondOrderFilters;

    SynthDef(\siny, {
        arg freq, outBus=0;
        Out.ar( outBus, SinOsc.ar(freq!2,0,0.2));
    }).add;
    SynthDef(\filter, {
        arg cFreq,q=0.8, inBus, outBus=0;
        Out.ar( outBus, BPF.ar(In.ar(inBus), cFreq!2, 1/q ) )
    }).add;
    s.sync; // wait for the synthdefs to load

    frequencies.do{ arg freq, index;
        sineSynths = sineSynths.add( Synth(\siny, [\freq: freq.postln, \outBus: sources[index]],
            parGroups[0])); // create synths and add them in the sineSynths Array
        firstOrderFilters = firstOrderFilters.add(
            Synth.after(sineSynths[index], \filter, [\inBus: sources[index],
                \outBus: filters[index], \cFreq: 200, \q: 20 ], parGroups[1]));
        secondOrderFilters = secondOrderFilters.add(
            Synth.after(firstOrderFilters[index], \filter, [\inBus: filters[index],
                \outBus: 0, \cFreq: 200, \q: 20 ], parGroups[1]));
    };

    10.wait; // wait 10 seconds;

    // clean up everything
    sineSynths.do{arg i; i.free};
    firstOrderFilters.do{arg i; i.free};
    secondOrderFilters.do{arg i; i.free};
    sources.do{arg i; i.free};
    filters.do{arg i; i.free};
});


来源:https://stackoverflow.com/questions/35167856/connecting-multiple-stages-of-parallel-synths-with-array-of-buses-in-supercoll

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!