Slink Filter

hey,

I think Ableton Lives Most used fx After the OTT preset is Self Vocoding, people put it on everything. Thats similiar to passing your input into exponentially spaced bandpass filters. I wanted to extend this idea inspired by this awesome m4l device which additionally warps the frequency response of the bandpass filters https://www.youtube.com/watch?v=l4pYxIouHgI
Do you have any other ideas, i would like to cover all of the features available in the device.

(
var filterBank = { |inSig, offset, density, rq = 0.05, min = 120, max = 16000|

    var numBands = 32;
    var freqs, amps, sigs;

    // Calculate logarithmic ratio
    var ratio = log2(max / min) / (numBands - 1);

    // Calculate frequencies
    freqs = (0..numBands - 1).collect{ |i|
        var localFreq = min * (2 ** ((i * ratio * density) + sin(i * offset)));
        min(localFreq, max);
    };

    // Calculate amplitudes
    amps = freqs.collect{ |localFreq|
        var fadeWidth = 2000;
        var fadeStart = max - fadeWidth;
        (1 - ((localFreq - fadeStart) / fadeWidth)).clip(0, 1);
    };

    // Apply band-pass filters and limiter
    sigs = BPF.ar([inSig], freqs, rq) * amps;
    sigs.sum;
};

var superSaw = { |freq, mix, detune|
	var detuneCurve = { |x|
		(10028.7312891634 * x.pow(11)) -
		(50818.8652045924 * x.pow(10)) +
		(111363.4808729368 * x.pow(9)) -
		(138150.6761080548 * x.pow(8)) +
		(106649.6679158292 * x.pow(7)) -
		(53046.9642751875 * x.pow(6)) +
		(17019.9518580080 * x.pow(5)) -
		(3425.0836591318 * x.pow(4)) +
		(404.2703938388 * x.pow(3)) -
		(24.1878824391 * x.pow(2)) +
		(0.6717417634 * x) +
		0.0030115596
	};
	var centerGain = { |x| (-0.55366 * x) + 0.99785 };
	var sideGain = { |x| (-0.73764 * x.pow(2)) + (1.2841 * x) + 0.044372 };
	var center = LFSaw.ar(freq);
	var freqs = [
		(freq - (freq * (detuneCurve.(detune)) * 0.11002313)),
		(freq - (freq * (detuneCurve.(detune)) * 0.06288439)),
		(freq - (freq * (detuneCurve.(detune)) * 0.01952356)),
		(freq + (freq * (detuneCurve.(detune)) * 0.01991221)),
		(freq + (freq * (detuneCurve.(detune)) * 0.06216538)),
		(freq + (freq * (detuneCurve.(detune)) * 0.10745242))
	];
	var side = freqs.collect{ |freq| LFSaw.ar(freq, Rand(-1, 1)) }.sum;
	var sig = (center * centerGain.(mix)) + (side * sideGain.(mix));
	HPF.ar(sig, freq);
};

SynthDef(\test, {
    var sig;
    sig = superSaw.(\freq.kr(440), 0.75, 0.35);
    sig = Pan2.ar(sig, \pan.kr(0));
    sig = sig * \amp.kr(-15.dbamp);
    sig = sig * Env.asr(0.001, 1, 0.001).ar(Done.freeSelf, \gate.kr(1));
    sig = Limiter.ar(sig);
    Out.ar(\out.kr(0), sig);
}).add;

SynthDef(\slink, {

    var inSig, sig;
    var density, offset;

    inSig = In.ar(\in.kr(0), 2);

    density = 0.85;//LFDNoise3.kr(0.01).linlin(-1, 1, 0, 1).lag(0.2);
    offset = SinOsc.kr(0.01).linlin(-1, 1, 0, 1).lag(0.2);

    sig = BHiShelf.ar(inSig, 1320, 0.5, 10);
    sig = filterBank.(sig, offset, density);

    ReplaceOut.ar(\out.kr(0), sig);
}).add;
)

(
Routine({

    var freqs = [57, 60, 64, 65, 70].midicps;

    s.bind {
        freqs.collect{ |freq|

            Synth(\test, [

                \freq, freq,
                
                \amp, -35.dbamp,
                \out, 0,

            ], addAction: \addToHead);

        };
    };

    s.sync;

    s.bind {

        Synth(\slink, [

            \in, 0,
            \out, 0,

        ], addAction: \addToTail);

    };

}).play;
)
4 Likes

Super cool! and some characters…

Im not really sure how to correctly calculate the offset.
Wrapping the offset into the sine function does only create some ripples, but i would like to have deep notches. When you dont wrap i * offset into the sine function, you get something like that, but you are also scaling the density when adjusting the offset, which is not what we want.

1 Like