Title: Expanding SuperCollider Noise Synthesis with Multichannel Output and JitLib Integration

Title: Expanding SuperCollider Noise Synthesis with Multichannel Output and JitLib Integration

Body:

Hi everyone,

I’ve been working on a SuperCollider patch for noise synthesis and modulation, and I wanted to share and discuss some enhancements to the code, including multichannel output and proper use of the JitLib library. Here’s a breakdown of the original setup and the modifications to include JitLib for better multichannel management. Can you please explain me how to properly do this, by explaining me how to correctly write the code, by addressing jitlib multichannel expansion correctly?

Original Code Overview

The initial code snippet sets up a basic noise synthesis environment with frequency modulation, multiple noise sources, and a selected waveform. Here’s a quick rundown of what the original code does:

  1. Server Reboot and ProxySpace Setup:

    (
    s = Server.default;
    s.reboot;
    )
    
    p = ProxySpace.push(s);
    
  2. Noise Synthesis and Modulation Definition:

    ~out1 = {Mix.fill(32,{
        var freqMod, modDepth, signal, waveform, noise1, noise2, noiseSources;
    
        // Modulate frequency with nested SinOsc.kr
        freqMod = rrand(0.5,2)*XLine.kr(0.01, 10, 60, doneAction: 2); // Frequency modulation
        modDepth = SinOsc.kr(freqMod, mul: freqMod); // Depth modulation
        signal = SinOsc.kr(modDepth, mul: modDepth); // Further modulation
    
        // Create an array of noise sources with modulation applied
        noiseSources = [
            { LFDNoise0.kr(signal) },
            { LFDNoise1.kr(signal) },
            { LFDNoise3.kr(signal) },
            { LFDClipNoise.kr(signal) },
        ];
    
        // Select a waveform
        waveform = [Saw, Pulse].choose;
    
        // Select two noise sources and apply them with an offset
        noise1 = noiseSources.choose;
        noise2 = noiseSources.choose;
    
        // Generate the audio signal with selected waveform and noise sources
        FreeVerb.ar(
            waveform.ar(
                [
                    TRand.kr(99, 2000, noise1),
                    TRand.kr(99, 2000, noise2)
                ]
            ),
            mul: 1/32 // Set output volume
        )
    })};
    
    // Play ~out1
    ~out1.play;
    

Best,

The code runs fine for me and produces a stereo signal. How many channels were you expecting?

As for multichannel expansion in JITLIB, if the NodeProxy ~out1 has not been previously defined, it will take on the number of channels of the signal that you give it – in this case, 2 channels. However, if you previously used a different number of channels in ~out1, JITLIB assumes you want to keep the same number of channels unless you set the reshaping parameter to \elastic or \expanding. You can also hardcode the number of channels with ~out1.mold(numChannels).

Aside from that, the only issues I see with your code are:

  1. There are 32 FreeVerbs running. This is very CPU heavy, so I would consider moving the FreeVerb outside the loop, perhaps use FreeVerb2 on the stereo signal.
  2. noise1 and noise2 could potentially use the same noise signal (both are noiseSources.choose). I would probably scramble the noiseSources and then choose the first 2.
noiseSources = [
    LFDNoise0,
    LFDNoise1,
    LFDNoise3,
    LFDClipNoise
].scramble;

// Select two noise sources and apply them with an offset
noise1 = noiseSources[0].kr(signal);
noise2 = noiseSources[1].kr(signal);