Some supercollider code - music (or noise otherwise)

some code i created. 80% of the work here was done for me. i revamped the specifications of the code in a later stage using chatgpt, although chatgpt only gave me half accurate answers and i had to revamp most of it. how can this be better written, possibly with less bugs, and in a better way?

// Reboot the server and set up the proxy space
s = Server.default;
s.reboot;
p = ProxySpace.push(s);

(
// Define a helper function to generate Gendy1 and Gendy2 sounds
~generateGendy = {
	var freqStart=322; var freqEnd=145; var duration=120;

    var minfreq = Line.kr(start: freqStart, end: freqEnd, dur: duration);
    var maxfreq = Line.kr(start: freqStart, end: 2000, dur: duration);

    [
        Gendy1.ar(
            minfreq: minfreq * TRand.kr(lo: 0.125, hi: 8, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10)))),
            maxfreq: maxfreq * TRand.kr(lo: 0.125, hi: 8, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10))))
        ),
        Gendy2.ar(
            minfreq: minfreq * TRand.kr(lo: 0.125, hi: 8, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10)))),
            maxfreq: maxfreq * TRand.kr(lo: 0.125, hi: 8, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10))))
        )
    ]
};

// Define a helper function for noise generation
~generateNoise = {
    var freqStart=1; var freqEnd=18; var duration=120;

    var noise0 = LFDNoise0.ar(
        freq: Line.kr(start: freqStart, end: freqEnd, dur: duration) * TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10))))
    );
    var noise3 = LFDNoise3.ar(
        freq: Line.kr(start: 32, end: 11, dur: duration) * TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10))))
    );

    Limiter.ar(in: LeakDC.ar(in: [noise0, noise3]))
};
)

(
// Sequence to generate sound events
t = Task({
    // Generate and play Gendy sounds

    ~out=~generateGendy; ~out.play;
    120.wait;

    ~out=~generateNoise; ~out.play;
    120.wait;

    ~out=~generateGendy; ~out.play;
    120.wait;

    ~out=~generateNoise; ~out.play;
    120.wait;

    ~out=~generateGendy; ~out.play;
    120.wait;

    ~sineOutput = Mix.fill(n: 32, function: { SinOsc.ar(freq: Line.kr(start: 800, end: rrand(200, 2000), dur: 360, doneAction: 2)) }) * (1 / 32) * 0.125;
    ~out=~sineOutput; ~out.play;
    360.wait;

    // Free all resources and stop the server
    Server.freeAll;
}).play;
)

// Start recording
s.record;

and here is a synthdef version

// Reboot the server and set up the proxy space
s = Server.default;
s.reboot;

// Gendy sound generation
(
SynthDef(\generateGendy, {
    var freqStart = 322;
    var freqEnd = 145;
    var duration = 120;

    var minfreq, maxfreq;
    var minfreqLine, maxfreqLine;

    // Generate the frequency lines
    minfreqLine = Line.kr(freqStart, freqEnd, duration);
    maxfreqLine = Line.kr(freqStart, 2000, duration);

    // Apply TRand modulation on the frequency lines using Impulse
    minfreq = minfreqLine * TRand.kr(lo: 0.125, hi: 8, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10))));
    maxfreq = maxfreqLine * TRand.kr(lo: 0.125, hi: 8, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10))));

    Out.ar(0, [
        Gendy1.ar(minfreq: minfreq, maxfreq: maxfreq),
        Gendy2.ar(minfreq: minfreq, maxfreq: maxfreq)
    ]);
}).add;
)


// Noise generation
(
SynthDef(\generateNoise, {
    var freqStart = 1;
    var freqEnd = 18;
    var duration = 120;

    var noise0, noise3;
    var freqLine0, freqLine3;

    // Frequency lines for noise generation
    freqLine0 = Line.kr(freqStart, freqEnd, duration);
    freqLine3 = Line.kr(32, 11, duration);

    // Apply TRand modulation on the noise frequencies using Impulse
    noise0 = LFDNoise0.ar(freq: freqLine0 * TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10)))));
    noise3 = LFDNoise3.ar(freq: freqLine3 * TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: TRand.kr(lo: 0.25, hi: 4, trig: Impulse.kr(freq: 1/10)))));

    // Output the noise with leak DC filtering and limiter
    Out.ar(0, Limiter.ar(in: LeakDC.ar(in: [noise0, noise3])));
}).add;

(
SynthDef(\sineOutput, {
    var freqStart, freqEnd, sineWaves;

    // Generate random frequency range
    freqStart = 800;

    // Create the sine waves with linearly changing frequencies
    sineWaves = Mix.fill(n: 32, function: {
        SinOsc.ar(
            freq: Line.kr(start: freqStart, end: rrand(200, 2000), dur: 360)
        )
    });

    // Output the mix of sine waves, scaled down
    Out.ar(0, sineWaves * (1 / 32) * 0.125);
}).add;
)


)


(
// Sequence to generate sound events
t = Task({
	b=Synth(\generateGendy).value;
	120.wait; b.free;

	b=Synth(\generateNoise).value;
    120.wait; b.free;

	b=Synth(\generateGendy).value;
	120.wait; b.free;

	b=Synth(\generateNoise).value;
    120.wait; b.free;

	b=Synth(\generateGendy).value;
	120.wait; b.free;

	b=Synth(\sineOutput).value;
    360.wait;

    Server.freeAll;
}).play;
)

// Start recording
s.record;
1 Like

What you have looks pretty good. You should definitely use arguments/controls instead of variables, which are not externally controllable. What you have works, but it’s rather inflexible.

freqStart, freqEnd, duration for example would all be more sensible as arguments so you can control them later. I also personally tend to always make the first argument to the Out UGen an argument/control.

You also do not need to call .value on a Synth. You can just put:
b = Synth(\generateGendy);

You would call .value if it were a function, but it’s just a Synth. Calling a Synth will just instantiate it on the server and play it for you.

I’m also not sure what the logic behind freeing everything on every server at the end of the task is. You can start the recording in the task, stop it at the end of the task, and free the synths instead. What you have isn’t wrong, it’s just odd in this context since it looks like you’ve only booted one server…