Supercollider: Applying FX to a group seems to affect other groups

139 Views Asked by At

I have created separate groups on supercollider for each instrument so that I may apply FX, like echo, to the group and only affect one instrument rather than all instruments playing on that sc server.

On the node tree, the echo synthdef correctly appears in the required group (box) and the FX is applied to the instrument in that group, but ALSO incorrectly applying echo to the nodes in other groups on the same server.

What I have noticed is that it affects all higher number groups and not lower number groups. Applying FX (echo) to group 1 or group 2 also applies the same FX to groups 3,4,5,6,7,8, etc., but applying FX to group 8 does NOT seem to affect groups 1,2,3,4,5,6,& 7.

I have tested this on the following systems/versions....

  • supercollider version (1:3.10.0+repack-1ubuntu2) on ubuntu (Linux Optiplex-3010 5.4.0-70-generic #78-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux)

  • supercollider version (1:3.10.0+repack-1+rpi1) on Linux raspberrypi 4.19.75-v7l+ #1270 SMP armv7l GNU/Linux

  • supercollider version (1:3.8.0~repack-2) on Linux advent 5.0.0-32-generic #34~18.04.2-Ubuntu SMP 2019 i686 i686 i686 GNU/Linux

Is this a known bug? Can I make any manual changes to the supercollider code to resolve this? If not, then it will have to be a separate RPi4 for each instrument, underutilising each RPi and increasing project costs significantly.

Regards to all SCcoders,

Phil

Requested code:

(SynthDef(\echo,{|in, out, length = 1, fb = 0.6, sep = 1|
   var input = In.ar(in, 2);
   var feedback = LocalIn.ar(2);
   var output = LeakDC.ar(feedback*fb + input);
   LocalOut.ar(DelayC.ar(output, length, sep));
   ReplaceOut.ar(out, output);
}).writeDefFile("/home/phil/Supercollider/syndef");)

I instigate the echo via OSC over tcp/ip, but essentially it would be called by:

/s_new s 'echo' i 1028 i 0 i 8     //in this case 1028 is the node for track 8 
                                   //and 8 is the SC group 

and adjusted by:

/n_set i 1028 s 'fb' f 0.7

UPDATE: In answer to Fizz's comment about...

how I created groups, initially in the startup.scd file and then clear every time the live performance stops and create every time the live performance starts...

oscStream.Clear();
oscStream << osc::BeginBundleImmediate
<< osc::BeginMessage("/g_freeAll") <<  1 << osc::EndMessage
<< osc::BeginMessage("/clearSched") <<  osc::EndMessage
<< osc::EndBundle;
transmitSocketMelody1.Send(oscStream.Data(),oscStream.Size());

oscStream.Clear();
oscStream << osc::BeginMessage("/g_new") <<  1 << 0 << 0 
<< osc::EndMessage;
transmitSocketMelody1.Send(oscStream.Data(),oscStream.Size());

oscStream.Clear();
oscStream << osc::BeginMessage("/g_new") <<  2 << 0 << 0 
<< osc::EndMessage;
transmitSocketMelody1.Send(oscStream.Data(),oscStream.Size());

which is the equivalent of...

s.sendMsg(\g_freeAll, 0);    
s.sendMsg(\clearSched);
s.sendMsg(\g_new,1,0,0);      
s.sendMsg(\g_new,2,0,0);  

Order that I create synthdefs...

The echo synthdef (already shown above) is the first created via the supercollider startup.scd file.

Then the sound synthdefs are created in numerical order Piano1, Piano2, Piano3, etc... also via the supercollider startup.scd file.

s.sendMsg(\b_allocRead, 101,"piano-p-c4.wav"); //buffer 101
SynthDef.new("piano1", {|amp=1, freq|
    var output,sig,sig2;
    sig=PlayBuf.ar(2, 101, freq/523.25, doneAction:2);  
    sig=sig*amp;
    sig = Splay.ar(sig);
    Out.ar(0,sig!2);
}).store;

s.sendMsg(\b_allocRead, 111,"piano-p-c5.wav"); //buffer 111
SynthDef.new("piano2", {|amp=1, freq|
    var sig;
    sig=PlayBuf.ar(2, 111, freq/523.25, doneAction:2);
    sig=sig*amp;
    sig = Splay.ar(sig);
    Out.ar(0,sig!2);
}).store;

The piano synthdefs are played live from the commands..

oscStream_melody1 << osc::BeginMessage("/s_new")
 << "piano1"
 << NextSCNode  << 0  << 1
 << "freq" << OscFrequency[OSCOctave][OSCNote]
 << "amp"  << Melody1Amplitude*Melody1Volume
 << osc::EndMessage
transmitSocketMelody1.Send(oscStream_melody1.Data(),oscStream_melody1.Size());

oscStream_melody2 << osc::BeginMessage("/s_new")
 << "piano2"
 << NextSCNode  << 0  << 2
 << "freq" << OscFrequency[OSCOctave][OSCNote]
 << "amp"  << Melody2Amplitude*Melody2Volume
 << osc::EndMessage;
 transmitSocketMelody2.Send(oscStream_melody2.Data(),oscStream_melody2.Size());

which is the equivalent of...

s.sendMsg("/s_new","\piano1",1234, 0, 1,"freq",440,"amp", 0.8)
s.sendMsg("/s_new","\piano2",1235, 0, 2,"freq",880,"amp", 0.7)

echo is turned on, modified and off live thus...

s.sendMsg(\s_new,'echo',1001,0,X); //where X is the group to apply to
s.sendMsg(\n_set, 1001,'fb',0.5,'length',1,'sep',1); 
s.sendMsg(\n_free, 1001);

but this turns on the echo for all groups with higher numbers, e.g group2, group3, group4 etc.

Whereas if reverb is set on group2 it affects group3, group4, etc but not group1.

1

There are 1 best solutions below

1
On

Without seeing any code, this is hard to answer, but I wonder if you are using buses? Your instrument group should output to an echo bus and that bus should output to where you wish the sound to go next - another FX bus or to 0.

You'd want to draw a block diagram of your groups, connecting inputs and outputs. Keep in mind that any FX group can take ins from multiple places, but will only have one output. This means you may end up running the same FX synth more than once, for example, if you want echo on groups A and B, but then you want group B to go to a compressor afterwards.

Make sure to declare every bus, give it a good variable name and remember to pass it as an argument on synth creation.