Соединение нескольких ступеней параллельных синтезаторов с массивом шин в SuperCollider

Когда у меня есть 2 этапа нескольких параллельных синтезаторов, я могу подключить его к массиву шин. (Спасибо Dan S за ответ на предыдущий вопрос). Когда есть 3 этапа, это не похоже на работу.

(
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;
)

Еще один вред, который я здесь делаю, заключается в том, что каждый раз, когда я останавливаюсь и запускаю синтезатор, создаются новые экземпляры шин, которые в конечном итоге заканчиваются звуковыми шинами. Как я могу решить это?

1 ответ

Есть несколько проблем с вашим кодом (некоторые не имеют отношения к вашему вопросу):

а. send(s) напоминает о прошлом, в наши дни просто add предпочтительнее - вы можете обратиться к документации для их различий.

б. смешивать локальные переменные не рекомендуется var с экологическими (такими как ~sourceOut) если нет веских причин.

с. .collect(func) (или напрямую collect{/*function body here*/}) когда отправка в массив приводит к другому массиву, где каждый элемент является результатом func с соответствующим элементом исходного массива, переданного в качестве аргумента. Так вот:

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

вы нигде не используете оригинальные числа, вы просто создаете два массива, содержащих по 5 аудио-шин каждый. Непосредственное выполнение этого будет менее запутанным и более явным:

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

д. нет смысла вызывать z.do три раза.. вы можете вызвать его только один раз и поместить остальные в ту же функцию.

е. проверить свои маршруты... У вас есть две параллельные группы, и вы просто говорите, что я хочу, чтобы эти синтезаторы были в этой группе и эти другие после этой другой группы... Что вы действительно хотите сказать, так это то, что я хочу эти Synthпосле тех Synthс этой группой.

е. вы не освобождаете свои автобусы или синтезаторы, когда закончите... это утечка памяти:)

г. ты звонишь play на функцию, которая действительно хочет оценить... вы должны вызвать value вместо.

Этот код производит звук и очищает все, когда дона, заметьте, однако, что результат довольно скучный, потому что вы отфильтровали все верхний конец.

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};
});
Другие вопросы по тегам