Synthcore version 3 library: proposed signatures

Ernest's icon

Hi folks

While making my own synth I added several dozen methods to synthcore, and I never made a single file of all the methods, and I can improve the demo, even though I am physically deaf I can do that much. Here is the list of proposed signatures, should mostly be self explanatory, I'm also adding descriptions for all the inputs and outputs to the function code of course.

// TRANSENDENTALS, SATURATORS, & UP/DOWN CONVRTERS
    qcos(x);        // quick cosine approximation
    qsin(y);        // quick sine approximation
    qtan(x);        // quick tan approximation
    qtanh1(x);        // quick tanh approximation
    qtanh2(x);        // more precise tanh approximation
    db2a(db);        // quick and accurate db2a conversion
    qparabol(in1, shape);    // low-CPU U hyperbolic approximation
    parabol1(in1);        // parabolic saturator clipped to unity range
    parabol2(in1);         // parabolic saturator with 2x headroom
    paraboln(in1, slope);    // parabolic saturator with adjustable slope
    hyperbol(in1, x);    // hyperbolic saturator clipped to unity
    spline(x, z0, z1, z2, z3); // spline, x = offset between z1 and z2.
    spline2xUp(in1);     // Optimized 2x spline upconversion
    spline2xDn(in1, in2);     // Optimized 2x spline downconversion
    spline4xUp(in1);     // Optimized 4x spline upconversion
    spline4xDn(in1, in2, in3, in4); // Optimized 2x spline downconversion
    upsample(input);    // 3x upsample with sinc coefficients
    downsample(val1, val2, val3); // 3x downsample with sinc coefficients
// OSCILLATORS
    ramp(inc);        // Ramp generator
    ramp0(in1, linc);    // ramps to new in1 value by linc per clock
    rampsnc(inc, snc);    // Ramp, trig sync
    rampgate(inc, gate;{    // Ramp, gate sync
    rampphase(inc, phase, snc); // Ramp, phase snc
    rampsoft(inc, phase, thisosc, modosc);    // Ramp, soft snc
    rampsofter(inc, phase, thisosc, modosc); // Ramp, softer snc
    rampramp(inc, phase, mod);    // Ramp ramped snc
    rampramper(inc, phase, mod);    // Ramp, ramper snc
    parasine(inc);            // low-cpu sine osc approximation
    sine2sine(ramp, w1);         // sine shapes to octave doubler
    pulse(ramp, width);        // simple pulse
    pulse2(ramp, width);         // simple pulse
    tri(ramp, width);        // simple variable saw/tri
    tri2(ramp, width);        // same, with w in range 0~127
    triwave(ramp, width);        // Variable Tri/saw with linear AR
    pulse1(ramp, width, inc);    // anti-aliased pulse with width mod
    eptrpulse(ramp, inc, width);    //antialiasing slope for pulse osc
    eptrpulse3x(ramp, inc, width);    // 3x Oversampled AA Pulse
    sawup (fc, r1, inc, srx3, sr3d3, rsr);     // rising saw with EPTR AA
    sawdown(fc, ramp, inc, srx3, sr3d3, rsr); // falling saw with EPTR AA
    karplus(impulse, fc, dampen);        // Karplus oscillator
    karplusd(impulse, fc, d);        // diffused Karplus
    karplusm(impulse, fc, d);        // mod Karplus
    waveset(ramp, wave, waveset);    // waveset, 2-axis spline interp
    waveset0(sel, width, ramp);    // waveset, lin. interp
    noiselpf(fc,q,rsrxpi);            // LPF noise osc
    noisebpf(fc,q,rsrxpi);            // BPF noise osc
    noisehpf(fc,q,rsrxpi);            // HPF noise osc
    noisenotch(fc,q,rsrxpi);        // notched noise osc
    pinknoise();                // pink noie source
    noiseosc(type, p, fc, q, rsrxpi2);    // LP/BP/HP noise osc
    osc(sel, p, fc, wide, ph, snc, trg, osc, // multimode osc
        mod1, mod2, env, rsrms, srx3, sr3d3, rsrxpi2, rsr);
// MIXERS, PANNERS, & MODULATORS
    mixer3(x);         // -1~+1 input returns left+center+right amps
    pan1(pan);        // optimized pan with +3dB at center    
    pan2(pan, left, right); // optimized pan with +3dB at center
    smoother1(val);     // smoothing over ~46 clock cycles
    smoother2(val);     // slow smoothing for delay lines
    smoother3(val);     // slower smoothing for delay lines
    ramptrig(msecs, trg, rsrms);    // ramp, time in msecs
    line(input, inc);        // line~ emulation
    mod0(base, sel, m, q);     // Modulates base by value at sel in array q
    modClip(base, sel, m, min, max, q); // with min/max clipping
    modScale(base, sel, m, q);     // with amplitude modulation.
    modFold(base, sel, m, min, max, q); // folds into min/max
    ModFoldMix(base, sel, m, min, max, q); // mixes & fold into min/max
    modFoldDuo(base, sel1, sel2, a, b, min, max, q); // 2 modulators
    modRing(base, sel, m, src, a, b, q);    // ring modulation
// SINGLE/DUAL-POLE FILTERS
    static(input, a1, b0, b1);        //1-pole core
    staticlo(fc);                //1-pole low pass
    statichi(fc);                //1-pole high pass
    shelflo(fc, b);                //1-pole low shelf
    shelfhi(fc, b);                //1-pole high shelf
    shelf1core(input, a1, b0, b1);         // required for 1pole EQ
    loshelf12(src1, src2, pitch, db);    // Stereo 1-pole low-shelf
    hishelf12(src1, src2, pitch, db);    // Stereo 1-pole high-shelf
    shelf2corelo(input, a0, a1, b1, w);    // IIR core for 2P lo eq
    loshelf22(src1, src2, p, db); // Stereo 2-pole low-shelf
    shelf2corehi(input, a0, a1, b1);    // IIR core for 2P hi eq
    hishelf22(src1, src2, p, db);        // Stereo 2-pole high-shelf
    peakeq1core(input, w, d2, a0, a1, a2); // IIR core for peak eq
    peakeq1(input, p, db, bw);        // Mono peak filter
    peakeq12(src1, src2, p, db, bw);    // Stereo peak filter
    eqsel(src1, src2, lop, midp, hip, log, midg, hig, bw, mode); //multimode eq
// BIQUADS
    biquad0(input, a0, a1, a2, b1, b2);    // direct form 1
    biquad(input, a0, a1, a2, b1, b2);     // optimized form 2
    biquadlo(fc, Q, rsrxpi);        // simple lowpass
    biquadband(fc, Q, rsrxpi);        // simple bandpass
    biquadhi(fc, Q, rsrxpi);        // simple highpass
    biquadnotch(fc, Q, rsrxpi);        // simple notch
    biquadlo2(p, q, rsrxpi2);        // standard-range i/p low
    biquadlo3(p, q, rsrxpi2);        // qain-limiting low
    biquadband2(p, q, rsrxpi2);        // standard-range i/p band
    biquadband3(p, q, rsrxpi2);        // gain limiting band
    biquadband4(p, q, rsrxpi2);        // unity-gain band
    biquadhi2(p, q, rsrxpi2);        // standard-range i/p hi
    biquadhi3(p, q, rsrxpi2);        // gain limiting hi
    biquadamp(w, a0, a1, a2, b1, b2);    // filter gain at any freq
    biquadval(a0, a1, a2, b1, b2, fc, q);    // value at point
    biquadplot();                // plots lp/bp/hp graph
    biquadplot2()    // plots LP/BP/HP/NOTCH filter graph with scaling
// BUTTERWORTH STATE-VARIABLE FILTERS WITH GAIN-COMP AND SATURATION
    svf(input, wa, d1, f1, f1n, f2, lp, bp);// Butterworth core
    svfCore3(in1, w, d, d2, g1, g2);     // 3x-oversampled core
    filt(input, type, poles, drive, fc, q, srflt);    // Table-based gain
    svfCoeffs3x(f0, q0, s0, f4x, rsrx2pi);    // 3x coefficients
    filt3x(input,f0, q0, s0,         // 3x 6-way 2p/4p SV
        lx, bx, hx, f2x, l4x, b4x, h4x, f4x, rsrx2pi);
    svf5(in1, pitch, poles, res, sat, type, // 5-pole filter
        lclk, linc, pirsr);    // with 3x-oversampled saturation
    saturator5(in1, sat, lclk, linc) ; // 3x-oversampled saturator
// DYNAMICS    
    limit(left, right, lvl, window, attlo, atthi, rello, relhi);
    compander2(in1, type, amp, thresh, ratio, att, rel, lclk);
// LFOS & ENVELOPES
    lfo(sel,frq,wid,snc_en,trg,rsr,fourpi);    // basic LFO
    lfopoly(sel, frq, sprd, sprdlvl, sprdtype, // poly LFO
        wid, sncen, trg, fourpi, rsr);     // + amp & freq spread
    lfo2(lshape,w,f,ls,fm,la,las,lsnc,gtrg,rsr,q);    // + amp and freq mod
    env(trg, a, d, s, r, preslope); // simple ADSR
    adsr(gate,predelay,a,d,s,s2,rel);         // Dual-sustain ADSR
    adsrloop(trg,gate,predelay,a,d,s,s2,r,mode);    // + loop mode
    padsrloop(trg,gate,pre1, pre2,a,d,s,r,mode);    // PADSR + loop
    adbdsrloop(                    // ADBDSR + loop
        trg,gate,predelay,a,d1,brk,d2,s,r,mode);
    padbdsrloop(                    // PADBDSR + loop
        trg,gate,pre1,pre2,a,d1,brk,d2,s,r,mode);
// EFFECTS
    glide(pitch, inc, scale, key, type, pat); // glide/ arpeggiated gliss
    ping1(input1, input2, delayL, delayR, mix, // ping-pong delay
        cross, inpan, feedback);
    ping2(input1, input2, delayL, delayR, mix, // ping-pong + hi/lo cut
        cross, inpan, feedback, locut, hicut, time);
    flange(input,f_deep, f_rate, f_fb, f_cntr,     // stereo flange
        f_sat, f_mix)Delay delayF(24000, 2, feedback=1);
    chorus(left, right, cdel, deep, sprd, cmix,    // stereo 8x chorus
        s1, s2, s3, s4, s5, s6, s7, s8 );
    diffdelay(input, delay, diff);            // diffusion delay
    tankLeft(input, damp, decay);             // left reflections
    tankRight(input, damp, decay);         // right reflections
    reverb(left, right, pre, cut, damp, decay, lvl);// full reverb
    xyController(cx0, cx1, cxm, cy0, cy1, cym, q);     // 4-way XY mix

Ernest's icon

I added a routine to set function variables that are constant for a particular sample rate, voice count, etc, so they don't need to be calculated in the function every clock cycle, with a patch showing what they are.

erichonour's icon

This is a fantastic set already! I can think of things you could add (e.g. phaser in the effects list, spatialization tools beyond stereo) but I think this is already incredibly generous and I would hesitate to ask for more. I'm also not sure how valuable it would be to pack more of these sorts of things in anyway, since people often roll their own.

oh no's icon

i love pulsar synthesis most. and i love husserl (the phenomenologist). my dream would be Husserl16 with 16 outs (my music rooom has 16 speakers). thank you so much for Husserl2!

Ernest's icon

Well, the chorus function does a phaser, one merely sets the delay to 2-5 msec, the freq to 0.2~0.1 Hz, and feedback to zero. But the library could have an optimized version with only one phaser delay line instead of eight. But since I wrote the library I had a stroke that left me totally deaf, so although I do know how it works, I can't hear if it's working properly. If someone else wants to write it I'll put it in with credit.

Key and scale remapping. I used to fill a buffer with an uzi and a very long message, but it's far better in codebox:

To remap for any key, I think the method is simply:

scale(p, k, s){ // remaps pitch to key and scale
// p = midi pitch in range 11~127
// k = key: c=0, C#=1, D=2, etc.
// s = scale: chromatic=0, major=1, etc. See help patch for all scales.
return scale.peek( p - k, s) + k;
}

The same code should work in both gen~ and gen.

Ernest's icon

Due to lack of interest, I don't plan to do any more on it.

Jhn's icon

Hi, the list is already extensive indeed! If think about what could be added to the library, few ideas come to mind: pitch tracking, additive synthesis model with partials specified in frequency, phase and amplitude.

C Hausch's icon

dear ernest,
is there a way to still get a copy of the latest version 3 of the synthcore library? i'm happy to pay for it as well!
kind regards, c. hausch

Wyatt Donnelley-Power's icon

I second this! Is there any way to access the library? It looks like the link is down