Faust Examples

This page contains an overview of the examples folder of the Faust distribution. Examples are organized by category and should all be executable in the online editor by clicking on the “Try it Yourself” button.

ambisonics

fourSourcesToOcto

declare name "fourSourcesToOcto";
declare version "1.0";
declare author "CICM";
declare license "BSD";
declare copyright "(c)CICM 2013";

import("stdfaust.lib");

r1 = hslider("Radius1", 1.0, 0, 5, 0.001) : si.smooth(ba.tau2pole(0.02));
a1 = hslider("Angle1", 0, ma.PI*(-2), ma.PI*2, 0.001) : si.smooth(ba.tau2pole(0.02));
r2 = hslider("Radius2", 1.0, 0, 5, 0.001) : si.smooth(ba.tau2pole(0.02));
a2 = hslider("Angle2", 0, ma.PI*(-2), ma.PI*2, 0.001) : si.smooth(ba.tau2pole(0.02));
r3 = hslider("Radius3", 1.0, 0, 5, 0.001) : si.smooth(ba.tau2pole(0.02));
a3 = hslider("Angle3", 0, ma.PI*(-2), ma.PI*2, 0.001) : si.smooth(ba.tau2pole(0.02));
r4 = hslider("Radius4", 1.0, 0, 5, 0.001) : si.smooth(ba.tau2pole(0.02));
a4 = hslider("Angle4", 0, ma.PI*(-2), ma.PI*2, 0.001) : si.smooth(ba.tau2pole(0.02));

process(sig1, sig2, sig3, sig4) = ho.map(3, sig1, r1, a1), ho.map(3, sig2, r2, a2), ho.map(3, sig3, r3, a3), ho.map(3, sig4, r4, a4) :> ho.optimInPhase(3) : ho.decoder(3, 8);

oneSourceToStereo

declare name "oneSourceToStereo";
declare version "1.0";
declare author "CICM";
declare license "BSD";
declare copyright "(c)CICM 2013";

import("stdfaust.lib");

r1 = hslider("Radius", 1.0, 0, 5, 0.001) : si.smooth(ba.tau2pole(0.02));
a1 = hslider("Angle", 0, ma.PI*(-2), ma.PI*2, 0.001) : si.smooth(ba.tau2pole(0.02));

process(sig) = ho.map(7, sig, r1, a1) : ho.optimInPhase(7) : ho.decoderStereo(7);

analysis

dbmeter

declare name        "dbmeter";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-------------------------------------------------
// A dB Vumeter
//-------------------------------------------------

import("stdfaust.lib");


vmeter(x)       = attach(x, envelop(x) : vbargraph("[unit:dB]", -70, 10));
hmeter(x)       = attach(x, envelop(x) : hbargraph("[unit:dB]", -70, 10));

envelop         = abs : max(ba.db2linear(-70)) : ba.linear2db : min(10)  : max ~ -(80.0/ma.SR);
null(x)         = attach(0,x);
process         = hgroup("8 channels dB meter", par(i,8, vgroup("%i", vmeter : null)));

FFT

// Radix 2 FFT, decimation in time, real and imag parts interleaved

declare name    "FFT"; // Faust Fourier Transform :-)
declare author  "JOS";
declare license "STK-4.3";

import("stdfaust.lib");

N=32; // FFT size (power of 2)
// Number of frequency bins (including dc and SR/2) is N/2+1

No2 = N>>1;
signal = amp * cosine with {
  cosine = select2(k==0,
         select2(k==No2,
            2.0*os.oscrc(f(k)), // 2x since negative-frequencies not displayed
            1-1':+~*(-1) // Alternating sequence: 1, -1, 1, -1
            ),
           1.0); // make sure phase is zero (freq jumps around)
  f(k) = float(k) * ma.SR / float(N); // only test FFT bin frequencies
  k = hslider("[2] FFT Bin Number",N/4,0,No2,0.001) : int <: _,dpy : attach;
  dpy = hbargraph("[3] Measured FFT Bin Number",0,No2);
  amp = hslider("[4] Amplitude",0.1,0,1,0.001);
};

process = signal : dm.fft_spectral_level_demo(N) <: _,_;

spectralLevel

declare name "spectralLevel";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Demonstrates mth_octave_spectral_level in a standalone GUI.";

import("stdfaust.lib");

process = dm.spectral_level_demo;

spectralTiltLab

// example exercising filters.lib's spectral_tilt_demo

declare name "spectralTiltLab";

import("stdfaust.lib");

N = 10; // Number of pole-zero pairs to use

process = sig(dm.sawtooth_demo) 
     : stg(ba.bypass1(bp,dm.spectral_tilt_demo(N)))
    <: sag(dm.spectral_level_demo) 
with {
    bp = stg(checkbox("[0] Bypass Spectral Tilt"));
    stg(x) = vgroup(
     "[1] Spectral Tilt Filter [tooltip: See Faust's filters.lib for spectral_tilt_demo]",x);
    sig(x) = vgroup(
     "[2] Test Signal [tooltip: See Faust's oscillator.lib for sawtooth_demo]",x);
    sag(x) = vgroup(
     "[4] Spectrum Analyzer [tooltip: See Faust's filters.lib for spectral_level_demo]",x);
};

vumeter

declare name        "vumeter";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-------------------------------------------------
// Simple vumeter
//-------------------------------------------------

import("stdfaust.lib");


vmeter(x)       = attach(x, envelop(x) : vbargraph("[2][unit:dB]", -70, +5));
hmeter(x)       = attach(x, envelop(x) : hbargraph("[2][unit:dB]", -70, +5));

envelop         = abs : max ~ -(1.0/ma.SR) : max(ba.db2linear(-70)) : ba.linear2db;

process         = hmeter,hmeter;

bela

AdditiveSynth_Analog

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Additive synthesizer, must be used with OSC message to program sound.
// It as 8 harmonics. Each have it's own volume envelope.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : vol0 (volum of fundamental)
// ANALOG_1 : vol1
// ...
// ANALOG_7 : vol7
//
// OSC messages (see BELA console for precise adress)
// For each harmonics (%rang indicate harmonic number, starting at 0) :
// A%rang : Attack
// D%rang : Decay
// S%rang : Sustain
// R%rang : Release
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// GENERAL
midigate = button("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 10, 0.01);

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

partiel(rang) = os.oscrs(gFreq*(rang+1))*volume
    with {
        // UI
        vol = hslider("vol%rang[BELA: ANALOG_%rang]", 1, 0, 1, 0.001);
     
        a = 0.01 * hslider("A%rang", 1, 0, 400, 0.001);
        d = 0.01 * hslider("D%rang", 1, 0, 400, 0.001);
        s = hslider("S%rang", 1, 0, 1, 0.001);
        r = 0.01 * hslider("R%rang", 1, 0, 800, 0.001);

        volume = ((en.adsr(a,d,s,r,midigate))*vol) : max (0) : min (1);
    };

process = par(i, 8, partiel(i)) :> / (8);

AdditiveSynth

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Additive synthesizer, must be used with OSC message to program sound.
// It as 8 harmonics. Each have it's own volume envelope.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// OSC messages (see BELA console for precise adress)
// For each harmonics (%rang indicate harmonic number, starting at 0) :
// vol%rang : General Volume        (vol0 control the volume of the fundamental)
// A%rang : Attack
// D%rang : Decay
// S%rang : Sustain
// R%rang : Release
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// GENERAL
midigate = button("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 10, 0.01);

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

partiel(rang) = os.oscrs(gFreq*(rang+1))*volume
    with {
        // UI
        vol = hslider("vol%rang", 1, 0, 1, 0.001);
     
        a = 0.01 * hslider("A%rang", 1, 0, 400, 0.001);
        d = 0.01 * hslider("D%rang", 1, 0, 400, 0.001);
        s = hslider("S%rang", 1, 0, 1, 0.001);
        r = 0.01 * hslider("R%rang", 1, 0, 800, 0.001);

        volume = ((en.adsr(a,d,s,r,midigate))*vol) : max (0) : min (1);
    };

process = par(i, 8, partiel(i)) :> / (8);

crossDelay2

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Stereo Delay with feedback and crossfeedback (L to R and R to L feedback).
// And pitch shifting on feedback.
// A pre-delay without feedback is added for a wider stereo effect.
//
// Designed to use the Analog Input for parameters controls.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// ANALOG IN:
// ANALOG 0 : Pre-Delay L
// ANALOG 1 : Pre-Delay R
// ANALOG 2 : Delay L
// ANALOG 3 : Delay R
// ANALOG 4 : Cross feedback
// ANALOG 5 : Feedback
// ANALOG 6 : Pitchshifter L
// ANALOG 7 : Pitchshifter R
//
// Available by OSC :  (see BELA console for precise adress)
// Feedback filter:
// crossLF : Crossfeedback Lowpass
// crossHF : Crossfeedback Highpass
// feedbLF : Feedback Lowpass
// feedbHF : Feedback Highpass
//
///////////////////////////////////////////////////////////////////////////////////////////////////

preDelL = ba.sec2samp(hslider("delR[BELA: ANALOG_0]", 1,0,2,0.001)):si.smoo;
preDelR = ba.sec2samp(hslider("delR[BELA: ANALOG_1]", 1,0,2,0.001)):si.smoo;
delL    = ba.sec2samp(hslider("delL[BELA: ANALOG_2]", 1,0,2,0.001)):si.smoo;
delR    = ba.sec2samp(hslider("delR[BELA: ANALOG_3]", 1,0,2,0.001)):si.smoo;

crossLF = hslider("crossLF", 12000, 20, 20000, 0.001);
crossHF = hslider("crossLF", 60, 20, 20000, 0.001);
feedbLF = hslider("feedbLF", 12000, 20, 20000, 0.001);
feedbHF = hslider("feedbHF", 60, 20, 20000, 0.001);

CrossFeedb = hslider("CrossFeedb[BELA: ANALOG_4]", 0.0, 0., 1, 0.001):si.smoo;
feedback = hslider("feedback[BELA: ANALOG_5]", 0.0, 0., 1, 0.001):si.smoo;

pitchL = hslider("shiftL[BELA: ANALOG_6]", 0,-12,12,0.001):si.smoo;
pitchR = hslider("shiftL[BELA: ANALOG_7]", 0,-12,12,0.001):si.smoo;

routeur(a,b,c,d) = ((a*CrossFeedb):fi.lowpass(2,crossLF):fi.highpass(2,crossHF))+((b*feedback):fi.lowpass(2,feedbLF):fi.highpass(2,feedbHF))+c,
                    ((b*CrossFeedb):fi.lowpass(2,crossLF):fi.highpass(2,crossHF))+((a*feedback):fi.lowpass(2,feedbLF):fi.highpass(2,feedbHF))+d;

process = (de.sdelay(65536, 512,preDelL),de.sdelay(65536, 512,preDelR)):(routeur : de.sdelay(65536, 512,delL) , de.sdelay(65536, 512,delR))~(ef.transpose(512, 256, pitchL) , ef.transpose(512, 256, pitchR));

FMSynth2_Analog

import("all.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple FM synthesizer.

///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : Modulator frequency ratio
// ANALOG_1 : Attack
// ANALOG_2 : Decay/Release
// ANALOG_3 : Sustain
//
// MIDI:
// CC 1 : FM feedback on modulant oscillator.
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// GENERAL, Keyboard
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 1, 0, 1, 0.01);

// modwheel:
feedb = (gFreq-1) * (hslider("feedb[midi:ctrl 1]", 0, 0, 1, 0.001) : si.smoo);
modFreqRatio = hslider("ratio[BELA: ANALOG_0]",2,0,20,0.01) : si.smoo;

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

//=================================== Parameters Mapping =================================
//========================================================================================
// Same for volum & modulation:
volA = hslider("A[BELA: ANALOG_1]",0.01,0.01,4,0.01);
volDR = hslider("DR[BELA: ANALOG_2]",0.6,0.01,8,0.01);
volS = hslider("S[BELA: ANALOG_3]",0.2,0,1,0.01);
envelop = en.adsre(volA,volDR,volS,volDR,midigate);

// modulator frequency
modFreq = gFreq * modFreqRatio;

// modulation index
FMdepth = envelop * 1000 * midigain;

// Out Amplitude
vol = envelop;

//============================================ DSP =======================================
//========================================================================================

FMfeedback(frq) = (+(_,frq):os.osci) ~ (* (feedb));
FMall(f) = os.osci(f+ (FMdepth*FMfeedback(f*modFreqRatio)));

process = FMall(gFreq) * vol;

FMSynth2

import("all.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple FM synthesizer.
// 2 oscillators and FM feedback on modulant oscillator
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
//
// CC 1 : FM feedback on modulant oscillator.
// CC 14 : Modulator frequency ratio.
//
// CC 73 : Attack
// CC 76 : Decay
// CC 77 : Sustain
// CC 72 : Release
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// GENERAL, Keyboard
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 1, 0, 1, 0.01);

// modwheel:
feedb = (gFreq-1) * (hslider("feedb[midi:ctrl 1]", 0, 0, 1, 0.001) : si.smoo);
modFreqRatio = hslider("ratio[midi:ctrl 14]",2,0,20,0.01) : si.smoo;

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

//=================================== Parameters Mapping =================================
//========================================================================================
// Same for volum & modulation:
volA = hslider("A[midi:ctrl 73]",0.01,0.01,4,0.01);
volD = hslider("D[midi:ctrl 76]",0.6,0.01,8,0.01);
volS = hslider("S[midi:ctrl 77]",0.2,0,1,0.01);
volR = hslider("R[midi:ctrl 72]",0.8,0.01,8,0.01);
envelop = en.adsre(volA,volD,volS,volR,midigate);

// modulator frequency
modFreq = gFreq*modFreqRatio;

// modulation index
FMdepth = envelop * 1000 * midigain;

// Out Amplitude
vol = envelop;

//============================================ DSP =======================================
//========================================================================================

FMfeedback(frq) = (+(_,frq):os.osci ) ~ (* (feedb));
FMall(f) = os.osci(f+(FMdepth*FMfeedback(f*modFreqRatio)));

process = FMall(gFreq) * vol;

FMSynth2_FX_Analog

import("all.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple FM synthesizer.
// 2 oscillators and FM feedback on modulant oscillator
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : Modulator frequency ratio
// ANALOG_1 : Attack
// ANALOG_2 : Decay/Release
// ANALOG_3 : Sustain
//
// MIDI:
// CC 1 : FM feedback on modulant oscillator.
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// GENERAL, Keyboard
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 1, 0, 1, 0.01);

// modwheel:
feedb = (gFreq-1) * (hslider("feedb[midi:ctrl 1]", 0, 0, 1, 0.001) : si.smoo);
modFreqRatio = hslider("ratio[BELA: ANALOG_0]",2,0,20,0.01) : si.smoo;

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

//=================================== Parameters Mapping =================================
//========================================================================================
// Same for volum & modulation:
volA = hslider("A[BELA: ANALOG_1]",0.01,0.01,4,0.01);
volDR = hslider("DR[BELA: ANALOG_2]",0.6,0.01,8,0.01);
volS = hslider("S[BELA: ANALOG_3]",0.2,0,1,0.01);
envelop = en.adsre(volA,volDR,volS,volDR,midigate);

// modulator frequency
modFreq = gFreq * modFreqRatio;

// modulation index
FMdepth = envelop * 1000 * midigain;

// Out Amplitude
vol = envelop;

//============================================ DSP =======================================
//========================================================================================

FMfeedback(frq) = (+(_,frq):os.osci) ~ (* (feedb));
FMall(f) = os.osci(f+ (FMdepth*FMfeedback(f*modFreqRatio)));

//#################################################################################################//
//##################################### EFFECT SECTION ############################################//
//#################################################################################################//
//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
// This version use ANALOG IN to controle some of the parameters.
// Other parameters continue to be available by MIDI or OSC.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_4 : Distortion Drive
// ANALOG_5 : Flanger Dry/Wet
// ANALOG_6 : Reverberation Dry/Wet
// ANALOG_7 : Reverberation Room size
//
// MIDI:
// CC 7 : Volume
// CC 10 : Pan
//
// CC 13 : Flanger Delay
// CC 13 : Flanger Delay
// CC 94 : Flanger Feedback
//
// CC 95 : Reverberation Damp
// CC 90 : Reverberation Stereo Width
// 
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
volFX   = hslider("volume[midi:ctrl 7]",1,0,1,0.001);   // Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive   = hslider("drive[BELA: ANALOG_4]",0.3,0,1,0.001);

// Flanger
curdel  = hslider("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb      = hslider("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw    = hslider("dryWetFlang[BELA: ANALOG_5]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[BELA: ANALOG_7]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[BELA: ANALOG_6]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effect = _ *(volFX) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

process = FMall(gFreq) * vol;

FMSynth2_FX

import("all.lib");


///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple FM synthesizer.
// 2 oscillators and FM feedback on modulant oscillator
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
//
// CC 1     : FM feedback on modulant oscillator.
// CC 14    : Modulator frequency ratio.
//
// CC 73    : Attack
// CC 76    : Decay
// CC 77    : Sustain
// CC 72    : Release
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// GENERAL, Keyboard
midigate        = button ("gate");
midifreq        = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain        = nentry("gain", 1, 0, 1, 0.01);

// modwheel:
feedb = (gFreq-1) * (hslider("feedb[midi:ctrl 1]", 0, 0, 1, 0.001) : si.smoo);
modFreqRatio = hslider("ratio[midi:ctrl 14]",2,0,20,0.01) : si.smoo;

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

//=================================== Parameters Mapping =================================
//========================================================================================
// Same for volum & modulation:
volA = hslider("A[midi:ctrl 73]",0.01,0.01,4,0.01);
volD = hslider("D[midi:ctrl 76]",0.6,0.01,8,0.01);
volS = hslider("S[midi:ctrl 77]",0.2,0,1,0.01);
volR = hslider("R[midi:ctrl 72]",0.8,0.01,8,0.01);
envelop = en.adsre(volA,volD,volS,volR,midigate);

// modulator frequency
modFreq = gFreq*modFreqRatio;

// modulation index
FMdepth = envelop * 1000 * midigain;

// Out Amplitude
vol = envelop;

//============================================ DSP =======================================
//========================================================================================

FMfeedback(frq) = ( +(_,frq):os.osci ) ~ (* (feedb));
FMall(f) = os.osci(f+ (FMdepth*FMfeedback(f*modFreqRatio)));

//#################################################################################################//
//##################################### EFFECT SECTION ############################################//
//#################################################################################################//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
// (All are available by OSC)
//
// CC 7 : Volume
// CC 10 : Pan
//
// CC 92 : Distortion Drive
//
// CC 13 : Flanger Delay
// CC 93 : Flanger Dry/Wet
// CC 94 : Flanger Feedback
//
// CC 12 : Reverberation Room size
// CC 91 : Reverberation Dry/Wet
// CC 95 : Reverberation Damp
// CC 90 : Reverberation Stereo Width
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
volFX = hslider("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive = hslider("drive[midi:ctrl 92]",0.3,0,1,0.001);

// Flanger
curdel  = hslider("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb = hslider("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw = hslider("dryWetFlang[midi:ctrl 93]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[midi:ctrl 12]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[midi:ctrl 91]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effect = _ *(volFX) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

process = FMall(gFreq) * vol;

FXChaine2

import("stdfaust.lib");

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// A complete Stereo FX chain with:
//      CHORUS
//      PHASER
//      DELAY
//      REVERB
//
// Designed to use the Analog Input for parameters controls.
//
// CONTROLES ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ANALOG IN:
// ANALOG 0 : Chorus Depth
// ANALOG 1 : Chorus Delay
// ANALOG 2 : Phaser Dry/Wet
// ANALOG 3 : Phaser Frequency ratio
// ANALOG 4 : Delay Dry/Wet
// ANALOG 5 : Delay Time
// ANALOG 6 : Reverberation Dry/Wet
// ANALOG 7 : Reverberation Room size
//
// Available by OSC :  (see BELA console for precise adress)
// Rate         : Chorus LFO modulation rate (Hz)
// Deviation    : Chorus delay time deviation.
//
// InvertSum    : Phaser inversion of phaser in sum. (On/Off)
// VibratoMode  : Phaser vibrato Mode. (On/Off)
// Speed        : Phaser LFO frequency
// NotchDepth   : Phaser LFO depth
// Feedback     : Phaser Feedback
// NotchWidth   : Phaser Notch Width
// MinNotch1    : Phaser Minimal frequency
// MaxNotch1    : Phaser Maximal Frequency
//
// Damp         : Reverberation Damp
// Stereo       : Reverberation Stereo Width
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

process = chorus_stereo(dmax,curdel,rate,sigma,do2,voices) : phaserSt : xdelay : reverb;

// CHORUS (from SAM demo lib) //////////////////////////////////////////////////////////////////////////////////////////////////////////
voices = 8; // MUST BE EVEN

pi = 4.0*atan(1.0);
periodic  = 1;

dmax = 8192;
curdel = dmax * vslider("Delay[BELA: ANALOG_1]", 0.5, 0, 1, 1) : si.smooth(0.999);
rateMax = 7.0; // Hz
rateMin = 0.01;
rateT60 = 0.15661;

rate = vslider("Rate", 0.5, rateMin, rateMax, 0.0001): si.smooth(ba.tau2pole(rateT60/6.91));
depth = vslider("Depth [BELA: ANALOG_0]", 0.5, 0, 1, 0.001) : si.smooth(ba.tau2pole(depthT60/6.91));
// (dept = dry/wet)

depthT60 = 0.15661;
delayPerVoice = 0.5*curdel/voices;
sigma  = delayPerVoice * vslider("Deviation",0.5,0,1,0.001) : si.smooth(0.999);

do2 = depth;   // use when depth=1 means "multivibrato" effect (no original => all are modulated)

chorus_stereo(dmax,curdel,rate,sigma,do2,voices) =
      _,_ <: *(1-do2),*(1-do2),(*(do2),*(do2) <: par(i,voices,voice(i)):>_,_) : ro.interleave(2,2) : +,+;
      voice(i) = de.fdelay(dmax,min(dmax,del(i)))/(i+1)
    with {
       angle(i) = 2*pi*(i/2)/voices + (i%2)*pi/2;
       voice(i) = de.fdelay(dmax,min(dmax,del(i))) * cos(angle(i));

         del(i) = curdel*(i+1)/voices + dev(i);
         rates(i) = rate/float(i+1);
         dev(i) = sigma *
             os.oscp(rates(i),i*2*pi/voices);
    };

// PHASER (from demo lib.) /////////////////////////////////////////////////////////////////////////////////////////////////////////////
phaserSt = _,_ <: _, _, phaser2_stereo : dry_wetST(dwPhaz)
    with {

        invert = checkbox("InvertSum");
        vibr = checkbox("VibratoMode"); // In this mode you can hear any "Doppler"

        phaser2_stereo = pf.phaser2_stereo(Notches,width,frqmin,fratio,frqmax,speed,mdepth,fb,invert);

        Notches = 4; // Compile-time parameter: 2 is typical for analog phaser stomp-boxes

        speed  = hslider("Speed", 0.5, 0, 10, 0.001);
        depth  = hslider("NotchDepth", 1, 0, 1, 0.001);
        fb     = hslider("Feedback", 0.7, -0.999, 0.999, 0.001);

        width  = hslider("NotchWidth",1000, 10, 5000, 1);
        frqmin = hslider("MinNotch1",100, 20, 5000, 1);
        frqmax = hslider("MaxNotch1",800, 20, 10000, 1) : max(frqmin);
        fratio = hslider("NotchFreqRatio[BELA: ANALOG_3]",1.5, 1.1, 4, 0.001);
        dwPhaz = vslider("dryWetPhaser[BELA: ANALOG_2]", 0.5, 0, 1, 0.001); 

        mdepth = select2(vibr,depth,2); // Improve "ease of use"
    };

// DELAY (with feedback and crossfeeback) //////////////////////////////////////////////////////////////////////////////////////////////
delay = ba.sec2samp(hslider("delay[BELA: ANALOG_5]", 1,0,2,0.001));
preDelL = delay/2;
delL    = delay;
delR    = delay;

crossLF = 1200;

CrossFeedb  = 0.6;
dwDel       = vslider("dryWetDelay[BELA: ANALOG_4]", 0.5, 0, 1, 0.001);

routeur(a,b,c,d) = ((a*CrossFeedb):fi.lowpass(2,crossLF))+c,
                    ((b*CrossFeedb):fi.lowpass(2,crossLF))+d;

xdelay = _,_ <: _,_,((de.sdelay(65536, 512,preDelL),_):
        (routeur : de.sdelay(65536, 512,delL) ,de.sdelay(65536, 512,delR) ) ~ (_,_)) : dry_wetST(dwDel);

// REVERB (from freeverb_demo) /////////////////////////////////////////////////////////////////////////////////////////////////////////
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[BELA: ANALOG_7]", 0.5, 0, 1, 0.001)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo",0.5,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[BELA: ANALOG_6]", 0.2, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wetST(dw,x1,x2,y1,y2) = (wet*y1 + dry*x1),(wet*y2 + dry*x2)
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

GrainGenerator

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Grain Generator.
// Another granular synthesis example.
// This one is not finished, but ready for more features and improvements...
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// ANALOG IN:
// ANALOG 0 : Population: 0=almost nothing. 1=Full grain
// ANALOG 1 : Depth of each grin, in ms.
// ANALOG 2 : Position in the table = delay 
// ANALOG 3 : Speed = pitch change of the grains
// ANALOG 4 : Feedback
//
///////////////////////////////////////////////////////////////////////////////////////////////////

import("all.lib");

// FOR 4 grains - MONO

// UI //////////////////////////////////////////
popul = 1 - hslider("population[BELA: ANALOG_0]", 1, 0, 1, 0.001);  // Coef 1= maximum; 0 = almost nothing (0.95)
taille = hslider("taille[BELA: ANALOG_1]", 100, 4, 200, 0.001 );        // Size in millisecondes
decal = 1 - hslider("decal[BELA: ANALOG_2]",0,0,1,0.001);               // read position compared to table srite position

speed = hslider("speed[BELA: ANALOG_3]", 1, 0.125, 4, 0.001);

feedback = hslider("feedback[BELA: ANALOG_4]",0,0,2,0.001); 

freq = 1000/taille;
tmpTaille = taille*ma.SR/ 1000;
clocSize = int(tmpTaille + (tmpTaille*popul*10)); // duration between 2 clicks

// CLK GENERAL /////////////////////////////////
// 4 clicks vers 4 generateurs de grains.
// (idem clk freq/4 et un compteur...)
detect1(x) = select2 (x < 10, 0, 1);
detect2(x) = select2 (x > clocSize*1/3, 0, 1) : select2 (x < (clocSize*1/3)+10, 0, _);
detect3(x) = select2 (x > clocSize*2/3, 0, 1) : select2 (x < (clocSize*2/3)+10, 0, _);
detect4(x) = select2 (x > clocSize-10, 0, 1);
cloc = (%(_,clocSize))~(+(1)) <: (detect1: trig),(detect2: trig),(detect3: trig),(detect4: trig);

// SIGNAUX Ctrls Player ////////////////////////
trig = _<:_,mem: >;
envelop = *(2*PI):+(PI):cos:*(0.5):+(0.5);

rampe(f, t) = delta : (+ : select2(t,_,delta<0) : max(0)) ~ _ : raz
    with {
        raz(x) = select2 (x > 1, x, 0);
        delta = sh(f,t)/ma.SR;
        sh(x,t) = ba.sAndH(t,x);
    };

rampe2(speed, t) = delta : (+ : select2(t,_,delta<0) : max(0)) ~ _ 
    with {
        delta = sh(speed,t);
        sh(x,t) = ba.sAndH(t,x);
    };

// RWTable //////////////////////////////////////
unGrain(input, clk) = (linrwtable( wf , rindex) : *(0.2 * EnvGrain))
    with {
        SR = 44100;
        buffer_sec = 1;
        size = int(SR * buffer_sec);
        init = 0.;

        EnvGrain = clk : (rampe(freq) : envelop);   

        windex = (%(_,size) ) ~ ( +(1) );
        posTabl = int(ba.sAndH(clk, windex));
        rindex = %(int(rampe2(speed, clk)) + posTabl + int(size * decal), size);

        wf = size, init, int(windex), input;
    };

// LINEAR_INTERPOLATION_RWTABLE //////////////////////////////////
// read rwtable with linear interpolation
// wf : waveform to read ( wf is defined by (size_buffer,init, windex, input ))
// x  : position to read (0 <= x < size(wf)) and float
// nota: rwtable(size, init, windex, input, rindex)

linrwtable(wf,x) = linterpolation(y0,y1,d)
    with {
        x0 = int(x);                //
        x1 = int(x+1);              //
        d  = x-x0;
        y0 = rwtable(wf,x0);        //
        y1 = rwtable(wf,x1);        //
        linterpolation(v0,v1,c) = v0*(1-c)+v1*c;
    };

// FINALISATION /////////////////////////////////////////////////////////////////////////////////////
routeur (a, b, c, d, e) = a, b, a, c, a, d, a, e;

processus = _ , cloc : routeur : (unGrain, unGrain, unGrain, unGrain) :> fi.dcblockerat(20);
process = _,_: ((+(_,_) :processus) ~(*(feedback))),((+(_,_) :processus) ~(*(feedback)));

granulator

// FROM FAUST DEMO
// Designed to use the Analog Input for parameters contrôles.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// ANALOG IN:
// ANALOG 0 : Grain Size
// ANALOG 1 : Speed
// ANALOG 2 : Probability
// (others analog inputs are not used)
//
///////////////////////////////////////////////////////////////////////////////////////////////////

process = vgroup("Granulator", environment {
    declare name "Granulator";
    declare author "Adapted from sfIter by Christophe Lebreton";

    /* =========== DESCRIPTION =============

    - The granulator takes very small parts of a sound, called GRAINS, and plays them at a varying speed
    - Front = Medium size grains
    - Back = short grains
    - Left Slow rhythm
    - Right = Fast rhythm
    - Bottom = Regular occurrences
    - Head = Irregular occurrences 
    */

    import("stdfaust.lib");

    process = hgroup("Granulator", *(excitation : ampf));

    excitation = noiseburst(gate,P) * (gain);
    ampf = an.amp_follower_ud(duree_env,duree_env);

    //----------------------- NOISEBURST ------------------------- 

    noiseburst(gate,P) = no.noise : *(gate : trigger(P))
        with { 
            upfront(x) = (x-x') > 0;
            decay(n,x) = x - (x>0)/n; 
            release(n) = + ~ decay(n); 
            trigger(n) = upfront : release(n) : > (0.0);
        };

    //-------------------------------------------------------------

    P = freq; // fundamental period in samples
    freq = hslider("[1]GrainSize[BELA: ANALOG_0]", 200,5,2205,1);
    // la frequence donne la largeur de bande extraite du bruit blanc
    Pmax = 4096; // maximum P (for de.delay-line allocation)

    // PHASOR_BIN //////////////////////////////
    phasor_bin (init) =  (+(float(speed)/float(ma.SR)) : fmod(_,1.0)) ~ *(init);
    gate = phasor_bin(1) :-(0.001):pulsar;
    gain = 1;
                            
    // PULSAR //////////////////////////////
    //Le pulsar permet de creer une 'pulsation' plus ou moins aleatoire (proba).

    pulsar = _<:((_<(ratio_env)):@(100))*(proba>(_,abs(no.noise):ba.latch)); 
    speed = hslider ("[2]Speed[BELA: ANALOG_1]", 10,1,20,0.0001):fi.lowpass(1,1);

    ratio_env = 0.5;
    fade = (0.5); // min > 0 pour eviter division par 0

    proba = hslider ("[3]Probability[BELA: ANALOG_2]", 70,50,100,1) * (0.01):fi.lowpass(1,1);
    duree_env = 1/(speed: / (ratio_env*(0.25)*fade));
}.process);

repeater

// REPEATER:
// Freeze and repeat a small part of input signal 'n' time'
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// ANALOG IN:
// ANALOG 0 : Duration (ms) between 2 repeat series (500 to 2000 ms)
// ANALOG 1 : Duration of one repeat (2 to 200 ms)
// ANALOG 2 : Number of repeat
//
///////////////////////////////////////////////////////////////////////////////////////////////////

import("all.lib");

process = _, _ , (pathClock : compteurUpReset2(nbRepet): rampePlayer, _) : routageIO : rec_play_table , rec_play_table;

///////////////////////////////////////////////////////////////////////////////////////////////////

// General loop duration
MasterTaille =hslider("MasterTaille[BELA: ANALOG_0]", 500, 200, 2000,0.01);
MasterClocSize = int(MasterTaille*ma.SR/ 1000);

// Depth of repeat fragments
taille =hslider("taille[BELA: ANALOG_1]", 50, 2, 200,0.01);
clocSize = int(taille*ma.SR/ 1000);

// Number of repeat fragments
nbRepet = int (hslider("nbRepet[BELA: ANALOG_2]",4,1,16,1) );

trig = _<:_,mem: >;

routageIO (a, b, c, d) = a, c, d, b, c, d;
rec_play_table(input, inReadIndex, reset) = ( rwtable( wf , rindex):fi.dcblockerat(20) )
    with {
        SR = 44100;
        buffer_sec = 2;
        size = int(SR * buffer_sec);
        init = 0.;

        windex = (%(_,size))~(+(1):*(1-reset)); 
        rindex = (%( int(inReadIndex),size));

        wf = size, init, int(windex), input;
    };

MasterClock = (%(_,MasterClocSize))~(+(1)) : detect
    with {
        detect(x) = select2 (x < 100, 0, 1);
    };

SlaveClock(reset) = (%(_,clocSize))~(+(1):*(1-reset));
detect1(x) = select2 (x < clocSize/2, 0, 1);

pathClock = MasterClock <: trig, _ : SlaveClock, _ : detect1, _ ;

compteurUpReset2(nb, in, reset) = ((in:trig), reset : (routage : memo2)~_), reset
    with {
        memo2(a, b)     = (ba.if(b>0.5, 0, _) )~(+(a));
        compare(value)  = ba.if(value>nb, 1, 0); // :trig;
        routage(d,e,f)  = e , (f, compare(d) : RSLatch <: +(f));
    };

RSLatch(R, S) = latch(S,R)
    with {
        trig = _<:_,mem: >;
        latch(S,R) = _~( ba.if(R>0.5, 0, _) : ba.if(S>0.5,1,_) );
    };

rampePlayer(reset) = rampe
    with {
        rst = reset : trig;
        rampe = _~(+(1):*(1-rst));
        toZero = _ : ba.if(reset<0.5,0,_);
    };

simpleFX_Analog

import("stdfaust.lib");
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
// This version use ANALOG IN to controle some of the parameters.
// Other parameters continue to be available by MIDI or OSC.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_4 : Distortion Drive
// ANALOG_5 : Flanger Dry/Wet
// ANALOG_6 : Reverberation Dry/Wet
// ANALOG_7 : Reverberation Room size
//
// MIDI:
// CC 7  : Volume
// CC 10 : Pan
//
// CC 13 : Flanger Delay
// CC 13 : Flanger Delay
// CC 94 : Flanger Feedback
//
// CC 95 : Reverberation Damp
// CC 90: Reverberation Stereo Width
// 
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
vol = hslider("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive   = hslider ("drive[BELA: ANALOG_4]",0.3,0,1,0.001);

// Flanger
curdel  = hslider("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb      = hslider("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw    = hslider("dryWetFlang[BELA: ANALOG_5]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[BELA: ANALOG_7]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[BELA: ANALOG_6]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effets = _ *(vol) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

process = effets;

simpleFX

import("stdfaust.lib");
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
// (All are available by OSC)
//
// CC 7  : Volume
// CC 10 : Pan
//
// CC 92 : Distortion Drive
//
// CC 13 : Flanger Delay
// CC 93 : Flanger Dry/Wet
// CC 94 : Flanger Feedback
//
// CC 12 : Reverberation Room size
// CC 91 : Reverberation Dry/Wet
// CC 95 : Reverberation Damp
// CC 90 : Reverberation Stereo Width
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
vol = hslider ("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive = hslider ("drive[midi:ctrl 92]",0.3,0,1,0.001);

// Flanger
curdel = hslider ("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb = hslider ("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw = hslider ("dryWetFlang[midi:ctrl 93]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Panoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[midi:ctrl 12]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[midi:ctrl 91]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effets = _ *(vol) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

process = effets;

simpleSynth_Analog

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// A very simple subtractive synthesizer with 1 VCO 1 VCF.
// The VCO Waveform is variable between Saw and Square
// The frequency is modulated by an LFO
// The envelope control volum and filter frequency
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : waveform (Saw to square)
// ANALOG_1 : Filter Cutoff frequency
// ANALOG_2 : Filter resonance (Q)
// ANALOG_3 : Filter Envelope Modulation
//
// MIDI:
// CC 79 : Filter keyboard tracking (0 to X2, default 1)
//
// Envelope
// CC 73 : Attack
// CC 76 : Decay
// CC 77 : Sustain
// CC 72 : Release
//
// CC 78 : LFO frequency (0.001Hz to 10Hz)
// CC 1  : LFO Amplitude (Modulation)
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// HUI //////////////////////////////////////////////////
// Keyboard
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 0.5, 0.01);// MIDI KEYBOARD

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

// VCO
wfFade = hslider("waveform[BELA: ANALOG_0]",0.5,0,1,0.001):si.smoo;

// VCF
res = hslider("resonnance[BELA: ANALOG_2]",0.5,0,1,0.001):si.smoo;
fr = hslider("fc[BELA: ANALOG_1]", 10, 15, 12000, 0.001):si.smoo;
track = hslider("tracking[midi:ctrl 79]", 1, 0, 2, 0.001);
envMod = hslider("envMod[BELA: ANALOG_3]",50,0,100,0.01):si.smoo;

// ENV
att = 0.01 * (hslider ("attack[midi:ctrl 73]",0.1,0.1,400,0.001));
dec = 0.01 * (hslider ("decay[midi:ctrl 76]",60,0.1,400,0.001));
sust = hslider ("sustain[midi:ctrl 77]",0.2,0,1,0.001);
rel = 0.01 * (hslider ("release[midi:ctrl 72]",100,0.1,400,0.001));

// LFO
lfoFreq = hslider ("lfoFreq[midi:ctrl 78]",6,0.001,10,0.001):si.smoo;
modwheel = hslider ("modwheel[midi:ctrl 1]",0,0,0.5,0.001):si.smoo;

// PROCESS /////////////////////////////////////////////
allfreq = (midifreq * pitchwheel) + LFO;
// VCF
cutoff = ((allfreq * track) + fr + (envMod * midigain * env)) : min(ma.SR/8);

// VCO
oscillo(f) = (os.sawtooth(f)*(1-wfFade))+(os.square(f)*wfFade);

// VCA
volume = midigain * env;

// Enveloppe
env = en.adsre(att,dec,sust,rel,midigate);

// LFO
LFO = os.lf_triangle(lfoFreq)*modwheel*10;

// SYNTH ////////////////////////////////////////////////
synth = (oscillo(allfreq) :ve.moog_vcf(res,cutoff)) * volume;

// PROCESS /////////////////////////////////////////////
process = synth;

simpleSynth

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// A very simple subtractive synthesizer with 1 VCO 1 VCF.
// The VCO Waveform is variable between Saw and Square
// The frequency is modulated by an LFO
// The envelope control volum and filter frequency
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
//
// CC 70 : waveform (Saw to square)
// CC 71 : Filter resonance (Q)
// CC 74 : Filter Cutoff frequency
// CC 79 : Filter keyboard tracking (0 to X2, default 1)
// CC 75 : Filter Envelope Modulation
//
// Envelope
// CC 73 : Attack
// CC 76 : Decay
// CC 77 : Sustain
// CC 72 : Release
//
// CC 78 : LFO frequency (0.001Hz to 10Hz)
// CC 1 : LFO Amplitude (Modulation)
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// HUI //////////////////////////////////////////////////
// Keyboard
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 0.5, 0.01);// MIDI KEYBOARD

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

// VCO
wfFade= hslider("waveform[midi:ctrl 70]",0.5,0,1,0.001):si.smoo;

// VCF
res = hslider("resonnance[midi:ctrl 71]",0.5,0,1,0.001):si.smoo;
fr = hslider("fc[midi:ctrl 74]", 10, 15, 12000, 0.001):si.smoo;
track = hslider("tracking[midi:ctrl 79]", 1, 0, 2, 0.001);
envMod  = hslider("envMod[midi:ctrl 75]",50,0,100,0.01):si.smoo; 

// ENV
att = 0.01 * (hslider ("attack[midi:ctrl 73]",0.1,0.1,400,0.001));
dec = 0.01 * (hslider ("decay[midi:ctrl 76]",60,0.1,400,0.001));
sust = hslider ("sustain[midi:ctrl 77]",0.1,0,1,0.001);
rel = 0.01 * (hslider ("release[midi:ctrl 72]",100,0.1,400,0.001));

// LFO
lfoFreq = hslider("lfoFreq[midi:ctrl 78]",6,0.001,10,0.001):si.smoo;
modwheel = hslider("modwheel[midi:ctrl 1]",0,0,0.5,0.001):si.smoo;

// PROCESS /////////////////////////////////////////////
allfreq = (midifreq * pitchwheel) + LFO;
// VCF
cutoff = ((allfreq * track) + fr + (envMod * midigain * env)) : min(ma.SR/8);

// VCO
oscillo(f) = (os.sawtooth(f)*(1-wfFade))+(os.square(f)*wfFade);

// VCA
volume = midigain * env;

// Enveloppe
env = en.adsre(att,dec,sust,rel,midigate);

// LFO
LFO = os.lf_triangle(lfoFreq)*modwheel*10;

// SYNTH ////////////////////////////////////////////////
synth = (oscillo(allfreq) :ve.moog_vcf(res,cutoff)) * volume;

// PROCESS /////////////////////////////////////////////
process = synth;

simpleSynth_FX_Analog

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// A very simple subtractive synthesizer with 1 VCO 1 VCF.
// The VCO Waveform is variable between Saw and Square
// The frequency is modulated by an LFO
// The envelope control volum and filter frequency
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : waveform (Saw to square)
// ANALOG_1 : Filter Cutoff frequency
// ANALOG_2 : Filter resonance (Q)
// ANALOG_3 : Filter Envelope Modulation
//
// MIDI:
// CC 79    : Filter keyboard tracking (0 to X2, default 1)
//
// Envelope
// CC 73    : Attack
// CC 76    : Decay
// CC 77    : Sustain
// CC 72    : Release
//
// CC 78    : LFO frequency (0.001Hz to 10Hz)
// CC 1     : LFO Amplitude (Modulation)
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// HUI //////////////////////////////////////////////////
// Keyboard
midigate = button("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 0.5, 0.01);// MIDI KEYBOARD

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

// VCO
wfFade = hslider("waveform[BELA: ANALOG_0]",0.5,0,1,0.001):si.smoo;

// VCF
res = hslider("resonnance[BELA: ANALOG_2]",0.5,0,1,0.001):si.smoo;
fr = hslider("fc[BELA: ANALOG_1]", 10, 15, 12000, 0.001):si.smoo;
track = hslider("tracking[midi:ctrl 79]", 1, 0, 2, 0.001);
envMod  = hslider("envMod[BELA: ANALOG_3]",50,0,100,0.01):si.smoo; 

// ENV
att = 0.01 * (hslider ("attack[midi:ctrl 73]",0.1,0.1,400,0.001));
dec = 0.01 * (hslider ("decay[midi:ctrl 76]",60,0.1,400,0.001));
sust = hslider ("sustain[midi:ctrl 77]",0.2,0,1,0.001);
rel = 0.01 * (hslider ("release[midi:ctrl 72]",100,0.1,400,0.001));

// LFO
lfoFreq = hslider("lfoFreq[midi:ctrl 78]",6,0.001,10,0.001):si.smoo;
modwheel = hslider("modwheel[midi:ctrl 1]",0,0,0.5,0.001):si.smoo;

// PROCESS /////////////////////////////////////////////
allfreq = (midifreq * pitchwheel) + LFO;
// VCF
cutoff = ((allfreq * track) + fr + (envMod * midigain * env)) : min(ma.SR/8);

// VCO
oscillo(f) = (os.sawtooth(f)*(1-wfFade))+(os.square(f)*wfFade);

// VCA
volume = midigain * env;

// Enveloppe
env = en.adsre(att,dec,sust,rel,midigate);

// LFO
LFO = os.lf_triangle(lfoFreq)*modwheel*10;

// SYNTH ////////////////////////////////////////////////
synth = (oscillo(allfreq) :ve.moog_vcf(res,cutoff)) * volume;

//#################################################################################################//
//##################################### EFFECT SECTION ############################################//
//#################################################################################################//
//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
// This version use ANALOG IN to controle some of the parameters.
// Other parameters continue to be available by MIDI or OSC.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_4 : Distortion Drive
// ANALOG_5 : Flanger Dry/Wet
// ANALOG_6 : Reverberation Dry/Wet
// ANALOG_7 : Reverberation Room size
//
// MIDI:
// CC 7     : Volume
// CC 10    : Pan
//
// CC 13    : Flanger Delay
// CC 13    : Flanger Delay
// CC 94    : Flanger Feedback
//
// CC 95    : Reverberation Damp
// CC 90    : Reverberation Stereo Width
// 
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
volFX   = hslider ("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive   = hslider ("drive[BELA: ANALOG_4]",0.3,0,1,0.001);


// Flanger
curdel  = hslider ("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb      = hslider ("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw    = hslider ("dryWetFlang[BELA: ANALOG_5]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[BELA: ANALOG_7]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[BELA: ANALOG_6]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effect = _ *(volFX) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

// PROCESS /////////////////////////////////////////////
process = synth;

simpleSynth_FX

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// A very simple subtractive synthesizer with 1 VCO 1 VCF.
// The VCO Waveform is variable between Saw and Square
// The frequency is modulated by an LFO
// The envelope control volum and filter frequency
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
//
// CC 70 : waveform (Saw to square)
// CC 71 : Filter resonance (Q)
// CC 74 : Filter Cutoff frequency
// CC 79 : Filter keyboard tracking (0 to X2, default 1)
// CC 75 : Filter Envelope Modulation
//
// Envelope
// CC 73 : Attack
// CC 76 : Decay
// CC 77 : Sustain
// CC 72 : Release
//
// CC 78 : LFO frequency (0.001Hz to 10Hz)
// CC 1 : LFO Amplitude (Modulation)
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// HUI //////////////////////////////////////////////////
// Keyboard
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 0.5, 0.01);// MIDI KEYBOARD

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

// VCO
wfFade = hslider("waveform[midi:ctrl 70]",0.5,0,1,0.001):si.smoo;

// VCF
res = hslider("resonnance[midi:ctrl 71]",0.5,0,1,0.001):si.smoo;
fr = hslider("fc[midi:ctrl 74]", 10, 15, 12000, 0.001):si.smoo;
track = hslider("tracking[midi:ctrl 79]", 1, 0, 2, 0.001);
envMod  = hslider("envMod[midi:ctrl 75]",50,0,100,0.01):si.smoo; 

// ENV
att = 0.01 * (hslider ("attack[midi:ctrl 73]",0.1,0.1,400,0.001));
dec = 0.01 * (hslider ("decay[midi:ctrl 76]",60,0.1,400,0.001));
sust = hslider ("sustain[midi:ctrl 77]",0.1,0,1,0.001);
rel = 0.01 * (hslider ("release[midi:ctrl 72]",100,0.1,400,0.001));

// LFO
lfoFreq = hslider ("lfoFreq[midi:ctrl 78]",6,0.001,10,0.001):si.smoo;
modwheel= hslider ("modwheel[midi:ctrl 1]",0,0,0.5,0.001):si.smoo;

// PROCESS /////////////////////////////////////////////
allfreq = (midifreq * pitchwheel) + LFO;

// VCF
cutoff= ((allfreq * track) + fr + (envMod * midigain * env)) : min(ma.SR/8);

// VCO
oscillo(f) = (os.sawtooth(f)*(1-wfFade))+(os.square(f)*wfFade);

// VCA
volume = midigain * env;

// Enveloppe
env = en.adsre(att,dec,sust,rel,midigate);

// LFO
LFO = os.lf_triangle(lfoFreq)*modwheel*10;

// SYNTH ////////////////////////////////////////////////
synth = (oscillo(allfreq) :ve.moog_vcf(res,cutoff)) * volume;

//#################################################################################################//
//##################################### EFFECT SECTION ############################################//
//#################################################################################################//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
// (All are available by OSC)
//
// CC 7 : Volume
// CC 10 : Pan
//
// CC 92 : Distortion Drive
//
// CC 13 : Flanger Delay
// CC 93 : Flanger Dry/Wet
// CC 94 : Flanger Feedback
//
// CC 12 : Reverberation Room size
// CC 91 : Reverberation Dry/Wet
// CC 95 : Reverberation Damp
// CC 90 : Reverberation Stereo Width
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
volFX = hslider ("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive = hslider ("drive[midi:ctrl 92]",0.3,0,1,0.001);

// Flanger
curdel = hslider ("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb = hslider ("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw = hslider ("dryWetFlang[midi:ctrl 93]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[midi:ctrl 12]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[midi:ctrl 91]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effect = _ *(volFX) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

// PROCESS /////////////////////////////////////////////
process = synth;

WaveSynth_Analog

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple demo of wavetable synthesis. A LFO modulate the interpolation between 4 tables.
// It's possible to add more tables step.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : Wave travelling
// ANALOG_1 : LFO Frequency
// ANALOG_2 : LFO Depth (wave travel modulation)
// ANALOG_3 : Release
//
// MIDI:
// CC 73 : Attack
// CC 76 : Decay
// CC 77 : Sustain
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// GENERAL
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain  = nentry("gain", 0.5, 0, 1, 0.01);

waveTravel = hslider("waveTravel[BELA: ANALOG_0]",0,0,1,0.01);

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

// LFO
lfoDepth = hslider("lfoDepth[BELA: ANALOG_2]",0,0.,1,0.001):si.smoo;
lfoFreq  = hslider("lfoFreq[BELA: ANALOG_1]",0.1,0.01,10,0.001):si.smoo;
moov = ((os.lf_trianglepos(lfoFreq) * lfoDepth) + waveTravel) : min(1) : max(0);

volA = hslider("A[midi:ctrl 73]",0.01,0.01,4,0.01);
volD = hslider("D[midi:ctrl 76]",0.6,0.01,8,0.01);
volS = hslider("S[midi:ctrl 77]",0.2,0,1,0.01);
volR = hslider("R[BELA: ANALOG_3]",0.8,0.01,8,0.01);
envelop = en.adsre(volA,volD,volS,volR,midigate);

// Out Amplitude
vol = envelop * midigain;

WF(tablesize, rang) = abs((fmod ((1+(float(ba.time)*rang)/float(tablesize)), 4.0 ))-2) -1.;

// 4 WF maxi with this version:
scanner(nb, position) = -(_,soustraction) : *(_,coef) : cos : max(0)
    with {
        coef = 3.14159 * ((nb-1)*0.5);
        soustraction = select2( position>0, 0, (position/(nb-1)) );
    };

wfosc(freq) = (rdtable(tablesize, wt1, faze)*(moov : scanner(4,0)))+(rdtable(tablesize, wt2, faze)*(moov : scanner(4,1)))
            + (rdtable(tablesize, wt3, faze)*(moov : scanner(4,2)))+(rdtable(tablesize, wt4, faze)*(moov : scanner(4,3)))
    with {
        tablesize = 1024;
        wt1 = WF(tablesize, 16);
        wt2 = WF(tablesize, 8);
        wt3 = WF(tablesize, 6);
        wt4 = WF(tablesize, 4);
        faze = int(os.phasor(tablesize,freq));
    };

process = wfosc(gFreq) * vol;

WaveSynth

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple demo of wavetable synthesis. A LFO modulate the interpolation between 4 tables.
// It's possible to add more tables step.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
//
// CC 1 : LFO Depth (wave travel modulation)
// CC 14 : LFO Frequency
// CC 70 : Wave travelling
//
// CC 73 : Attack
// CC 76 : Decay
// CC 77 : Sustain
// CC 72 : Release
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// GENERAL
midigate = button ("gate");
midifreq = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain = nentry("gain", 0.5, 0, 1, 0.01);

waveTravel = hslider("waveTravel [midi:ctrl ]",0,0,1,0.01);

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

// LFO
lfoDepth = hslider ("lfoDepth[midi:ctrl 1]",0,0.,1,0.001):si.smoo;
lfoFreq  = hslider ("lfoFreq[midi:ctrl 14]",0.1,0.01,10,0.001):si.smoo;
moov = ((os.lf_trianglepos(lfoFreq) * lfoDepth) + waveTravel) : min(1) : max(0);

volA = hslider("A[midi:ctrl 73]",0.01,0.01,4,0.01);
volD = hslider("D[midi:ctrl 76]",0.6,0.01,8,0.01);
volS = hslider("S[midi:ctrl 77]",0.2,0,1,0.01);
volR = hslider("R[midi:ctrl 72]",0.8,0.01,8,0.01);
envelop = en.adsre(volA,volD,volS,volR,midigate);

// Out Amplitude
vol = envelop * midigain ;

WF(tablesize, rang) = abs((fmod ((1+(float(ba.time)*rang)/float(tablesize)), 4.0 ))-2) -1.;

// 4 WF maxi with this version:
scanner(nb, position) = -(_,soustraction) : *(_,coef) : cos : max(0)
with{
    coef = 3.14159 * ((nb-1)*0.5);
    soustraction = select2( position>0, 0, (position/(nb-1)) );
};

wfosc(freq) = (rdtable(tablesize, wt1, faze)*(moov : scanner(4,0)))+(rdtable(tablesize, wt2, faze)*(moov : scanner(4,1)))
                + (rdtable(tablesize, wt3, faze)*(moov : scanner(4,2)))+(rdtable(tablesize, wt4, faze)*(moov : scanner(4,3)))
with {
    tablesize = 1024;
    wt1 = WF(tablesize, 16);
    wt2 = WF(tablesize, 8);
    wt3 = WF(tablesize, 6);
    wt4 = WF(tablesize, 4);
    faze = int(os.phasor(tablesize,freq));
};

process = wfosc(gFreq) * vol;

WaveSynth_FX_Analog

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple demo of wavetable synthesis. A LFO modulate the interpolation between 4 tables.
// It's possible to add more tables step.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_0 : Wave travelling
// ANALOG_1 : LFO Frequency
// ANALOG_2 : LFO Depth (wave travel modulation)
// ANALOG_3 : Release
//
// MIDI:
// CC 73    : Attack
// CC 76    : Decay
// CC 77    : Sustain
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// GENERAL
midigate        = button ("gate");
midifreq        = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain        = nentry("gain", 0.5, 0, 1, 0.01);

waveTravel      = hslider("waveTravel[BELA: ANALOG_0]",0,0,1,0.01);

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

// LFO
lfoDepth = hslider("lfoDepth[BELA: ANALOG_2]",0,0.,1,0.001):si.smoo;
lfoFreq  = hslider("lfoFreq[BELA: ANALOG_1]",0.1,0.01,10,0.001):si.smoo;
moov = ((os.lf_trianglepos(lfoFreq) * lfoDepth) + waveTravel) : min(1) : max(0);

volA = hslider("A[midi:ctrl 73]",0.01,0.01,4,0.01);
volD = hslider("D[midi:ctrl 76]",0.6,0.01,8,0.01);
volS = hslider("S[midi:ctrl 77]",0.2,0,1,0.01);
volR = hslider("R[BELA: ANALOG_3]",0.8,0.01,8,0.01);
envelop = en.adsre(volA,volD,volS,volR,midigate);

// Out Amplitude
vol = envelop * midigain ;

WF(tablesize, rang) = abs((fmod ((1+(float(ba.time)*rang)/float(tablesize)), 4.0 ))-2) -1.;

// 4 WF maxi with this version:
scanner(nb, position) = -(_,soustraction) : *(_,coef) : cos : max(0)
    with {
        coef = 3.14159 * ((nb-1)*0.5);
        soustraction = select2( position>0, 0, (position/(nb-1)) );
    };

wfosc(freq) = (rdtable(tablesize, wt1, faze)*(moov : scanner(4,0)))+(rdtable(tablesize, wt2, faze)*(moov : scanner(4,1)))
                + (rdtable(tablesize, wt3, faze)*(moov : scanner(4,2)))+(rdtable(tablesize, wt4, faze)*(moov : scanner(4,3)))
    with {
        tablesize = 1024;
        wt1 = WF(tablesize, 16);
        wt2 = WF(tablesize, 8);
        wt3 = WF(tablesize, 6);
        wt4 = WF(tablesize, 4);
        faze = int(os.phasor(tablesize,freq));
    };

//#################################################################################################//
//##################################### EFFECT SECTION ############################################//
//#################################################################################################//
//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
// This version use ANALOG IN to controle some of the parameters.
// Other parameters continue to be available by MIDI or OSC.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// ANALOG IMPLEMENTATION:
//
// ANALOG_4 : Distortion Drive
// ANALOG_5 : Flanger Dry/Wet
// ANALOG_6 : Reverberation Dry/Wet
// ANALOG_7 : Reverberation Room size
//
// MIDI:
// CC 7 : Volume
// CC 10 : Pan
//
// CC 13 : Flanger Delay
// CC 13 : Flanger Delay
// CC 94 : Flanger Feedback
//
// CC 95 : Reverberation Damp
// CC 90 : Reverberation Stereo Width
// 
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
volFX = hslider("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive = hslider ("drive[BELA: ANALOG_4]",0.3,0,1,0.001);

// Flanger
curdel  = hslider("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb = hslider("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw = hslider("dryWetFlang[BELA: ANALOG_5]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[BELA: ANALOG_7]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[BELA: ANALOG_6]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effect = _ *(volFX) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

process = wfosc(gFreq) * vol;

WaveSynth_FX

import("stdfaust.lib");

///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Simple demo of wavetable synthesis. A LFO modulate the interpolation between 4 tables.
// It's possible to add more tables step.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
//
// CC 1     : LFO Depth (wave travel modulation)
// CC 14    : LFO Frequency
// CC 70    : Wave travelling
//
// CC 73    : Attack
// CC 76    : Decay
// CC 77    : Sustain
// CC 72    : Release
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// GENERAL
midigate        = button ("gate");
midifreq        = nentry("freq[unit:Hz]", 440, 20, 20000, 1);
midigain        = nentry("gain", 0.5, 0, 1, 0.01);

waveTravel      = hslider("waveTravel [midi:ctrl ]",0,0,1,0.01);

// pitchwheel
pitchwheel = hslider("bend [midi:pitchwheel]",1,0.001,10,0.01);

gFreq = midifreq * pitchwheel;

// LFO
lfoDepth = hslider("lfoDepth[midi:ctrl 1]",0,0.,1,0.001):si.smoo;
lfoFreq  = hslider("lfoFreq[midi:ctrl 14]",0.1,0.01,10,0.001):si.smoo;
moov = ((os.lf_trianglepos(lfoFreq) * lfoDepth) + waveTravel) : min(1) : max(0);

volA = hslider("A[midi:ctrl 73]",0.01,0.01,4,0.01);
volD = hslider("D[midi:ctrl 76]",0.6,0.01,8,0.01);
volS = hslider("S[midi:ctrl 77]",0.2,0,1,0.01);
volR = hslider("R[midi:ctrl 72]",0.8,0.01,8,0.01);
envelop = en.adsre(volA,volD,volS,volR,midigate);

// Out Amplitude
vol = envelop * midigain ;

WF(tablesize, rang) = abs((fmod ((1+(float(ba.time)*rang)/float(tablesize)), 4.0 ))-2) -1.;

// 4 WF maxi with this version:
scanner(nb, position) = -(_,soustraction) : *(_,coef) : cos : max(0)
    with {
        coef = 3.14159 * ((nb-1)*0.5);
        soustraction = select2( position>0, 0, (position/(nb-1)) );
    };

wfosc(freq) = (rdtable(tablesize, wt1, faze)*(moov : scanner(4,0)))+(rdtable(tablesize, wt2, faze)*(moov : scanner(4,1)))
                + (rdtable(tablesize, wt3, faze)*(moov : scanner(4,2)))+(rdtable(tablesize, wt4, faze)*(moov : scanner(4,3)))
    with {
        tablesize = 1024;
        wt1 = WF(tablesize, 16);
        wt2 = WF(tablesize, 8);
        wt3 = WF(tablesize, 6);
        wt4 = WF(tablesize, 4);
        faze = int(os.phasor(tablesize,freq));
    };

//#################################################################################################//
//##################################### EFFECT SECTION ############################################//
//#################################################################################################//
// Simple FX chaine build for a mono synthesizer.
// It controle general volume and pan.
// FX Chaine is:
//      Drive
//      Flanger
//      Reverberation
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// MIDI IMPLEMENTATION:
// (All are available by OSC)
//
// CC 7 : Volume
// CC 10 : Pan
//
// CC 92 : Distortion Drive
//
// CC 13 : Flanger Delay
// CC 93 : Flanger Dry/Wet
// CC 94 : Flanger Feedback
//
// CC 12 : Reverberation Room size
// CC 91 : Reverberation Dry/Wet
// CC 95 : Reverberation Damp
// CC 90 : Reverberation Stereo Width
//
///////////////////////////////////////////////////////////////////////////////////////////////////

// VOLUME:
volFX = hslider("volume[midi:ctrl 7]",1,0,1,0.001);// Should be 7 according to MIDI CC norm.

// EFFECTS /////////////////////////////////////////////
drive   = hslider ("drive[midi:ctrl 92]",0.3,0,1,0.001);

// Flanger
curdel  = hslider("flangDel[midi:ctrl 13]",4,0.001,10,0.001);
fb = hslider("flangFeedback[midi:ctrl 94]",0.7,0,1,0.001);
fldw = hslider("dryWetFlang[midi:ctrl 93]",0.5,0,1,0.001);
flanger = efx
    with {
        fldel = (curdel + (os.lf_triangle(1) * 2) ) : min(10);
        efx = _ <: _, pf.flanger_mono(10,fldel,1,fb,0) : dry_wet(fldw);
    };

// Pannoramique:
panno = _ : sp.panner(hslider ("pan[midi:ctrl 10]",0.5,0,1,0.001)) : _,_;

// REVERB (from freeverb_demo)
reverb = _,_ <: (*(g)*fixedgain,*(g)*fixedgain :
    re.stereo_freeverb(combfeed, allpassfeed, damping, spatSpread)),
    *(1-g), *(1-g) :> _,_
    with {
        scaleroom   = 0.28;
        offsetroom  = 0.7;
        allpassfeed = 0.5;
        scaledamp   = 0.4;
        fixedgain   = 0.1;
        origSR = 44100;

        damping = vslider("Damp[midi:ctrl 95]",0.5, 0, 1, 0.025)*scaledamp*origSR/ma.SR;
        combfeed = vslider("RoomSize[midi:ctrl 12]", 0.7, 0, 1, 0.025)*scaleroom*origSR/ma.SR + offsetroom;
        spatSpread = vslider("Stereo[midi:ctrl 90]",0.6,0,1,0.01)*46*ma.SR/origSR;
        g = vslider("dryWetReverb[midi:ctrl 91]", 0.4, 0, 1, 0.001);
        // (g = Dry/Wet)
    };

// Dry-Wet (from C. LEBRETON)
dry_wet(dw,x,y) = wet*y + dry*x
    with {
        wet = 0.5*(dw+1.0);
        dry = 1.0-wet;
    };

// ALL
effect = _ *(volFX) : ef.cubicnl_nodc(drive, 0.1) : flanger : panno : reverb;

process = wfosc(gFreq) * vol;

delayEcho

echo

// WARNING: This a "legacy example based on a deprecated library". Check misceffects.lib
// for more accurate examples of echo functions

declare name        "echo";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";
//-----------------------------------------------
//              A Simple Echo
//-----------------------------------------------

import("stdfaust.lib");

process = vgroup("echo-simple", ef.echo1s);

quadEcho

// WARNING: This a "legacy example based on a deprecated library". Check misceffects.lib
// for more accurate examples of echo functions

declare name        "quadEcho";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2007";

//-----------------------------------------------
//              A 1 second quadriphonic Echo
//-----------------------------------------------

import("stdfaust.lib");

process = vgroup("stereo echo", multi(ef.echo1s, 4))
    with{ 
        multi(f,1) = f;
        multi(f,n) = f,multi(f,n-1);
    };                          
    

smoothDelay

declare name    "smoothDelay";
declare author  "Yann Orlarey";
declare copyright "Grame";
declare version "1.0";
declare license "STK-4.3";

//--------------------------process----------------------------
//
//  A stereo smooth delay with a feedback control
//  
//  This example shows how to use sdelay, a delay that doesn't
//  click and doesn't transpose when the delay time is changed
//-------------------------------------------------------------

import("stdfaust.lib");

process = par(i, 2, voice)
    with 
    { 
        voice   = (+ : de.sdelay(N, interp, dtime)) ~ *(fback);
        N       = int(2^19); 
        interp  = hslider("interpolation[unit:ms][style:knob]",10,1,100,0.1)*ma.SR/1000.0; 
        dtime   = hslider("delay[unit:ms][style:knob]", 0, 0, 5000, 0.1)*ma.SR/1000.0;
        fback   = hslider("feedback[style:knob]",0,0,100,0.1)/100.0; 
    };

stereoEcho

// WARNING: This a "legacy example based on a deprecated library". Check misceffects.lib
// for more accurate examples of echo functions

declare name        "stereoEcho";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2007";

//-----------------------------------------------
//              A 1 second Stereo Echo
//-----------------------------------------------

import("stdfaust.lib");

process = vgroup("stereo echo", (ef.echo1s, ef.echo1s));

tapiir

declare name        "tapiir";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//======================================================
//
//                  TAPIIR
//    (from Maarten de Boer's Tapiir)
//
//======================================================

import("stdfaust.lib");

dsize       = 524288;

// user interface
//---------------
tap(n)      = vslider("tap %n", 0,0,1,0.1);
in(n)       = vslider("input %n", 1,0,1,0.1);
gain        = vslider("gain", 1,0,1,0.1);
del         = vslider("delay (sec)", 0, 0, 5, 0.01) * ma.SR;

// mixer and matrix
//-----------------------------------------------------------
mixer(taps,lines)   =   par(i,taps,*(tap(i))),
                        par(i,lines,*(in(i)))
                        :>  *(gain);

matrix(taps,lines)  = ( si.bus(lines+taps)
                        <: tgroup("",
                                par(i, taps,
                                    hgroup("Tap %i",
                                        mixer(taps,lines) : de.delay(dsize,del))))
                      ) ~ si.bus(taps);

// tapiir
//--------
tapiir(taps,lines)  =   vgroup("Tapiir",
                            si.bus(lines)
                            <: (matrix(taps,lines), si.bus(lines))
                            <: vgroup( "outputs", par( i, lines, hgroup("output %i", mixer(taps,lines)) ) )
                        );

process             =  tapiir(6,2);

dynamic

compressor

declare name "compressor";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Compressor demo application";

import("stdfaust.lib");

process = dm.compressor_demo;

distortion

declare name "distortion";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Distortion demo application.";

import("stdfaust.lib");

process = dm.cubicnl_demo;

gateCompressor

declare name "gateCompressor";

import("stdfaust.lib");

process = 
// ol.sawtooth_demo <: 
//      el.gate_demo : ef.compressor_demo :> fi.spectral_level_demo <: _,_;
   vgroup("[1]", dm.sawtooth_demo) <:
   vgroup("[2]", dm.gate_demo) : 
   vgroup("[3]", dm.compressor_demo) :>
   vgroup("[4]", dm.spectral_level_demo) <:
    _,_;

noiseGate

declare name "noiseGate";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Gate demo application.";

import("stdfaust.lib");

process = dm.gate_demo;

volume

declare name        "volume";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-----------------------------------------------
//          Volume control in dB
//-----------------------------------------------

import("stdfaust.lib");

gain        = vslider("[1]", 0, -70, +4, 0.1) : ba.db2linear : si.smoo;

process     = *(gain);

filtering

APF

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "APF";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = APF(x,F,G,Q);

bandFilter

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name        "bandFilter";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

import("stdfaust.lib");

//---------------------second order filter--------------------------
// filter(Q,F,G)
//              Q : quality factor [1..100]
//              F : frequency (Hz)
//              G : gain [0..1]
//------------------------------------------------------------------

filter(Q,F,G)   = fi.TF2(  (1 +  K/Q + K*K)     / D,
                         2 * (K*K - 1)      / D,
                        (1 - K/Q + K*K)     / D,
                         2 * (K*K - 1)      / D,
                        (1 - V*K/Q + K*K)   / D
                     )
        with {
                V = ba.db2linear(G);
                K = tan(ma.PI*F/ma.SR);
                D = 1 + V*K/Q + K*K;
        };

//--------------- Band Filter with user interface ------------------
// bandfilter(F)
//              F : default frequency (Hz)
//
//------------------------------------------------------------------

bandfilter(F)   = filter(   nentry("Q factor [style:knob]",50,0.1,100,0.1),
                            nentry("freq [unit:Hz][style:knob]", F, 20, 20000, 1),
                            0 - vslider("gain [unit:dB]", 0, -50, 50, 0.1)
                        );

//------------------------- Process --------------------------------

process         = vgroup("Bandfilter", bandfilter(1000));

BPF

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "BPF";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = BPF(x,F,G,Q);

cryBaby

declare name "cryBaby";
declare description "Application demonstrating the CryBaby wah pedal emulation";
import("stdfaust.lib");
process = dm.crybaby_demo;

DNN

// Forward Deep Neural Net (DNN), any number of layers of any size each

declare name    "DNN";
declare author  "JOS";
declare license "STK-4.3";

import("stdfaust.lib");

layerSizes = (8,5,8); // autoencoder with 8 in & out, 5-state hidden layer
w(m,n,k) = m*100+n*10+k; // placeholder weights: m=layer, n=fromNode, k=destNode

M = ba.count(layerSizes);
N(l) = ba.take(l+1,layerSizes); // Nodes per layer

process = seq(m, M-1, layer(m))
// look at weights:
// process = par(m,M,par(n,N(m),par(k,N(m),w(m,n,k))))
with {
  layer(m) = weights(m) :> nonlinearities(m);
  nonlinearities(m) = bus(N(m)*N(m+1)) :> par(n,N(m+1),nl(n));
  weights(m) = bus(N(m)) <: par(n,N(m),(bus(N(m+1))<:wts(m,n)));
  wts(m,n) = bus(N(m+1)) : par(k,N(m+1),*(w(m,n,k)));
  nl(n,x) = x * (x>0); // ReLU
  bus(N) = par(k,N,_);
};

filterBank

declare name "filterBank";
declare description "Graphic Equalizer consisting of a filter-bank driving a bank of faders";

import("stdfaust.lib");

process = dm.filterbank_demo;

graphicEqLab

declare name "graphicEqLab";
declare description "Signal generators through a filter bank with spectrum analysis display";

import("stdfaust.lib");

process = 
// ol.sawtooth_demo : fl.filterbank_demo : fl.spectral_level_demo <: _,_;
 vgroup("[1]",dm.sawtooth_demo) : 
 vgroup("[2]",dm.filterbank_demo) : 
 vgroup("[3]",dm.spectral_level_demo) <:
  _,_;

highShelf

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "highShelf";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = highShelf(x,F,G,Q);

HPF

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "HPF";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = HPF(x,F,G,Q);

lfBoost

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name        "lfboost";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//------------------------------------------------------------------
//  DAFX, Digital Audio Effects (Wiley ed.)
//  chapter 2   : filters
//  section 2.3 : Equalizers
//  page 53     : second order shelving filter design
//------------------------------------------------------------------

import("stdfaust.lib");

//----------------------low frequency boost filter -------------------------------
// lfboost(F,G)
//              F : frequency (in Hz)
//              G : gain (in dB)
//
//--------------------------------------------------------------------------------

lfboost(F,G)    = fi.TF2((1 + sqrt(2*V)*K + V*K*K) / denom,
                        2 * (V*K*K - 1) / denom,
                        (1 - sqrt(2*V)*K + V*K*K) / denom,
                        2 * (K*K - 1) / denom,
                        (1 - sqrt(2)*K + K*K) / denom)
        with {
            V           = ba.db2linear(G);
            K           = tan(ma.PI*F/ma.SR);
            denom       = 1 + sqrt(2)*K + K*K;
        };

//====================low frequency boost process ===============================

process = vgroup("lowboost", lfboost(nentry("freq [unit:Hz][style:knob]", 100, 20, 150, 1),
                                    vslider("gain [unit:dB]", 0, -20, 20, 0.1)));

lowBoost

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name        "lowboost";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//------------------------------------------------------------------
//  DAFX, Digital Audio Effects (Wiley ed.)
//  chapter 2   : filters
//  section 2.3 : Equalizers
//  page 53     : second order shelving filter design
//------------------------------------------------------------------

import("stdfaust.lib");

//------------------- low-frequency shelving boost (table 2.3) --------------------

V0(g)           = pow(10,g/20.0);
K(fc)           = tan(ma.PI*fc/ma.SR);
square(x)       = x*x;
denom(fc)       = 1 + sqrt(2)*K(fc) + square(K(fc));

lfboost(fc, g)  = fi.TF2((1 + sqrt(2*V0(g))*K(fc) + V0(g)*square(K(fc))) / denom(fc),
                        2 * (V0(g)*square(K(fc)) - 1) / denom(fc),
                        (1 - sqrt(2*V0(g))*K(fc) + V0(g)*square(K(fc))) / denom(fc),
                        2 * (square(K(fc)) - 1) / denom(fc),
                        (1 - sqrt(2)*K(fc) + square(K(fc))) / denom(fc));

//------------------------------ User Interface -----------------------------------

freq                = hslider("[1]freq [unit:Hz][style:knob]", 1000, 20, 20000, 0.1);
gain                = hslider("[2]gain [unit:dB][style:knob]", 0, -20, 20, 0.1);

//----------------------------------- Process -------------------------------------

process             = vgroup("low-freq shelving boost", lfboost(freq,gain));

lowCut

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name        "lowcut";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//------------------------------------------------------------------
//  DAFX, Digital Audio Effects (Wiley ed.)
//  chapter 2   : filters
//  section 2.3 : Equalizers
//  page 53     : second order shelving filter design
//------------------------------------------------------------------

import("stdfaust.lib");

//------------------- low-frequency shelving cut (table 2.3) --------------------

V0(g)           = pow(10,g/-20.0);
K(fc)           = tan(ma.PI*fc/ma.SR);
squ(x)      = x*x;
denom(fc,g)     = 1 + sqrt(2*V0(g))*K(fc) + V0(g)*squ(K(fc));

lfcut(fc, g)    = fi.TF2((1 + sqrt(2)*K(fc) + squ(K(fc))) / denom(fc,g),
                        2 * (squ(K(fc)) - 1) / denom(fc,g),
                        (1 - sqrt(2)*K(fc) + squ(K(fc))) / denom(fc,g),
                        2 * (V0(g)*squ(K(fc)) - 1) / denom(fc,g),
                        (1 - sqrt(2*V0(g))*K(fc) + V0(g)*squ(K(fc))) / denom(fc,g));

//------------------------------ User Interface -----------------------------------

freq            = hslider("freq [unit:Hz][style:knob]", 100, 20, 5000, 1);
att             = hslider("attenuation [unit:dB][style:knob]", 0, -96, 10, 0.1);

//----------------------------------- Process -------------------------------------

process         = vgroup("low-freq shelving cut", lfcut(freq,att));

lowShelf

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "lowShelf";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = lowShelf(x,F,G,Q);

LPF

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "LPF";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = LPF(x,F,G,Q);

moogVCF

declare name "moogVCF";
declare description "Exercise and compare three Moog VCF implementations";

import("stdfaust.lib");

process = dm.moog_vcf_demo;

notch

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "notch";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = notch(x,F,G,Q);

parametricEqLab

declare name "parametricEqLab";
declare description "Demonstrate the Parametric Equalizer sections on test signals with spectrum analysis display";

import("stdfaust.lib");

//process = ol.sawtooth_demo : fl.parametric_eq_demo :
//          fl.mth_octave_spectral_level_demo(2) <: _,_;
process =
  vgroup("[1]", dm.sawtooth_demo) :
  vgroup("[2]", dm.parametric_eq_demo) :
  vgroup("[3]", dm.mth_octave_spectral_level_demo(2))
  <: _,_;

parametricEqualizer

declare name "parametricEqualizer";
declare description "Exercise and compare Parametric Equalizer sections on test signals";

import("stdfaust.lib");

process = dm.parametric_eq_demo;

peakingEQ

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "peakingEQ";

import("maxmsp.lib");

G = hslider("Gain [unit:dB]", 0, -10, 10, 0.1);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = peakingEQ(x,F,G,Q);

peakNotch

// WARNING: This a "legacy example based on a deprecated library". Check filters.lib
// for more accurate examples of filter functions

declare name "peakNotch"; 

import("maxmsp.lib");

G = hslider("Gain [unit: lin]", 1, 0, 8, 0.01);
F = hslider("Freq", 1000, 100, 10000, 1);
Q = hslider("Q", 1, 0.01, 100, 0.01);

process(x) = peakNotch(x,F,G,Q);

spectralTilt

declare name "spectralTilt";
declare description "Demonstrate the Spectral Tilt effect on test signals";

import("stdfaust.lib");

O = 2; // filter order

process = dm.spectral_tilt_demo(2);

vcfWahLab

import("stdfaust.lib");
declare description "Demonstrate competing variable-lowpass-filter effects on test signals with spectrum analysis display";

declare name "vcfWahLab";

// process = ol.sawtooth_demo : 
//    el.crybaby_demo : el.moog_vcf_demo : el.wah4_demo : 
//    fl.spectral_level_demo <: _,_;
process = 
 vgroup("[1]", dm.sawtooth_demo) : 
 vgroup("[2]", dm.crybaby_demo) : 
 vgroup("[3]", dm.wah4_demo) : 
 vgroup("[4]", dm.moog_vcf_demo) : 
 vgroup("[5]", dm.spectral_level_demo) <:
  _,_;

vocoder

declare name "Vocoder";
declare version "0.0";
declare author "RM";
declare description "Use example of the vocoder function where an impulse train is used as excitation.";

import("stdfaust.lib");

process = dm.vocoder_demo;

wahPedal

declare name "wahPedal";
declare description "Demonstrate the Fourth-Order Wah pedal (similar to the Moog VCF)";

import("stdfaust.lib");

process = dm.wah4_demo;

gameaudio

bubble

declare name "bubble";
declare description "Production of a water drop bubble sound.";
declare license "MIT";
declare copyright "(c) 2017: Yann Orlarey, GRAME";

import("stdfaust.lib");


//---------------------------`bubble`--------------------------
// bubble(f0, trig) : produces a water drop bubble sound
//
// #### Usage
//
// ```
// bubble(f0, trig) : _
// ```
//
// Where:
//
// * ` f0 `: base frequency of bubble sound
// * `trig`: trigs the bubble sound on the rising front
//
// #### Example
//
// ```
// button("drop") : bubble(600) : _
// ```
//
// #### Reference:
//
// <http://www.cs.ubc.ca/~kvdoel/publications/tap05.pdf>
//------------------------------------------------------------

bubble(f0,trig) = os.osc(f) * (exp(-damp*time) : si.smooth(0.99))
    with {
        damp = 0.043*f0 + 0.0014*f0^(3/2);
        f = f0*(1+sigma*time);
        sigma = eta * damp;
        eta = 0.075;
        time = 0 : (select2(trig>trig'):+(1)) ~ _ : ba.samp2sec;
    };

process = button("drop") : bubble(hslider("v:bubble/freq", 600, 150, 2000, 1)) <: dm.freeverb_demo;

rain

//----------------------`rain`--------------------------
// A very simple rain simulator
//
// #### Usage
//
// ```
//  rain(d,l) : _,_
// ```
//
// Where:
//
// * `d`: is the density of the rain: between 0 and 1
// * `l`: is the level (volume) of the rain: between 0 and 1
//
//----------------------------------------------------------

import("stdfaust.lib");

rain(density,level) = no.multinoise(2) : par(i, 2, drop) : par(i, 2, *(level))
    with {
        drop = _ <: @(1), (abs < density) : *;
    };

process  =  rain (
                hslider("v:rain/density", 300, 0, 1000, 1) / 1000,
                hslider("v:rain/volume", 0.5, 0, 1, 0.01)
            );

wind

//----------------------`wind`--------------------------
// A very simple wind simulator, based on a filtered white noise
//
// #### Usage
//
// ```
//  wind(f) : _
// ```
//
// Where:
//
// * `f`: is the force of the wind: between 0 and 1
//
//----------------------------------------------------------

import("stdfaust.lib");

wind(force) = no.multinoise(2) : par(i, 2, ve.moog_vcf_2bn(force,freq)) : par(i, 2, *(force))
    with {
        freq = (force*87)+1 : ba.pianokey2hz;
    };

process = wind ( hslider("v:wind/force",0.66,0,1,0.01) : si.smooth (0.997) );

generator

filterOsc

declare name "filterOSC";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Simple application demoing filter based oscillators.";

import("stdfaust.lib");

process = dm.oscrs_demo;

noise

// WARNING: This a "legacy example based on a deprecated library". Check noises.lib
// for more accurate examples of noise functions

declare name        "Noise";
declare version     "1.1";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2009";

//-----------------------------------------------------------------
// Noise generator and demo file for the Faust math documentation
//-----------------------------------------------------------------

<mdoc>
\section{Presentation of the "noise.dsp" Faust program}
This program describes a white noise generator with an interactive volume, using a random function.

\subsection{The random function}
The \texttt{random} function describes a generator of random numbers, which equation follows. You should notice hereby the use of an integer arithmetic on 32 bits, relying on integer wrapping for big numbers.
<equation>random</equation>

\subsection{The noise function}
The white noise then corresponds to:
<equation>noise</equation>
</mdoc>

random  = +(12345)~*(1103515245);
noise   = random/2147483647.0;

<mdoc>
\subsection{Just add a user interface element to play volume!}
Endly, the sound level of this program is controlled by a user slider, which gives the following equation: 
<equation>process</equation>
</mdoc>

<mdoc>
\section{Block-diagram schema of process}
This process is illustrated on figure 1.
<diagram>process</diagram>
</mdoc>

process = noise * vslider("Volume[style:knob][acc: 0 0 -10 0 10]", 0.5, 0, 1, 0.1);

<mdoc>
\section{Notice of this documentation}
You might be careful of certain information and naming conventions used in this documentation:
<notice/>

\section{Listing of the input code}
The following listing shows the input Faust code, parsed to compile this mathematical documentation.
<listing/>
</mdoc>

noiseMetadata

// WARNING: This a "legacy example based on a deprecated library". Check noises.lib
// for more accurate examples of noise functions

<mdoc>
\title{<metadata>name</metadata>}
\author{<metadata>author</metadata>}
\date{\today}
\maketitle

\begin{tabular}{ll}
    \hline
    \textbf{name}       & <metadata>name</metadata> \\
    \textbf{version}    & <metadata>version</metadata> \\
    \textbf{author}     & <metadata>author</metadata> \\
    \textbf{license}    & <metadata>license</metadata> \\
    \textbf{copyright}  & <metadata>copyright</metadata> \\
    \hline
\end{tabular}
\bigskip
</mdoc>
//-----------------------------------------------------------------
// Noise generator and demo file for the Faust math documentation
//-----------------------------------------------------------------

declare name        "noiseMetadata"; // avoid same name as in noise.dsp
declare version     "1.1";
declare author      "Grame";
declare author      "Yghe";
declare license     "BSD";
declare copyright   "(c)GRAME 2009";

<mdoc>
\section{Presentation of the "noise.dsp" Faust program}
This program describes a white noise generator with an interactive volume, using a random function.

\subsection{The random function}
</mdoc>

random  = +(12345)~*(1103515245);

<mdoc>
The \texttt{random} function describes a generator of random numbers, which equation follows. You should notice hereby the use of an integer arithmetic on 32 bits, relying on integer wrapping for big numbers.
<equation>random</equation>

\subsection{The noise function}
</mdoc>

noise   = random/2147483647.0;

<mdoc>
The white noise then corresponds to:
<equation>noise</equation>

\subsection{Just add a user interface element to play volume!}
</mdoc>

process = noise * vslider("Volume[style:knob]", 0, 0, 1, 0.1);

<mdoc>
Endly, the sound level of this program is controlled by a user slider, which gives the following equation: 
<equation>process</equation>

\section{Block-diagram schema of process}
This process is illustrated on figure 1.
<diagram>process</diagram>

\section{Notice of this documentation}
You might be careful of certain information and naming conventions used in this documentation:
<notice />

\section{Listing of the input code}
The following listing shows the input Faust code, parsed to compile this mathematical documentation.
<listing mdoctags="false" dependencies="false" distributed="false" />
</mdoc>

osc

declare name        "osc";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2009";

//-----------------------------------------------
//          Sinusoidal Oscillator
//-----------------------------------------------

import("stdfaust.lib");

vol             = hslider("volume [unit:dB]", 0, -96, 0, 0.1) : ba.db2linear : si.smoo ;
freq            = hslider("freq [unit:Hz]", 1000, 20, 24000, 1);

process         = vgroup("Oscillator", os.osc(freq) * vol);

osci

declare name        "osci";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2009";

//-----------------------------------------------
//          Sinusoidal Oscillator
//      (with linear interpolation)
//-----------------------------------------------

import("stdfaust.lib");

vol             = hslider("volume [unit:dB]", 0, -96, 0, 0.1) : ba.db2linear : si.smoo ;
freq            = hslider("freq [unit:Hz]", 1000, 20, 24000, 1);

process         = vgroup("Oscillator", os.osci(freq) * vol);

sawtoothLab

declare name "sawtoothLab";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "An application demonstrating the different sawtooth oscillators of Faust.";

import("stdfaust.lib");

process = dm.sawtooth_demo;

virtualAnalog

declare name "VirtualAnalog";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Virtual analog oscillator demo application.";

import("stdfaust.lib");

process = dm.virtual_analog_oscillator_demo;

virtualAnalogLab

declare name "virtualAnalogLab";

import("stdfaust.lib");

process = 
 vgroup("[1]", dm.virtual_analog_oscillator_demo) : 
 vgroup("[2]", dm.moog_vcf_demo) : 
 vgroup("[3]", dm.spectral_level_demo)
 // See also: vgroup("[3]", dm.fft_spectral_level_demo(32))
  <: _,_;

misc

capture

declare name        "capture";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-------------------------------------------------
//      Capture : record up to 8s of sound and
//      playback the recorded sound in loop
//-------------------------------------------------

import("stdfaust.lib");

B = button("Capture");  // Capture sound while pressed
I = int(B);             // convert button signal from float to integer
R = (I-I') <= 0;        // Reset capture when button is pressed
D = (+(I):*(R))~_;      // Compute capture duration while button is pressed: 0..NNNN0..MMM


capture = *(B) : (+ : de.delay(8*65536, D-1)) ~ *(1.0-B) ;

level       = hslider("level (db)", 0, -96, 4, 0.1) : ba.db2linear : si.smoo;

process     = vgroup( "Audio Capture", capture : *(level) ) ;

matrix

declare name        "matrix";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-----------------------------------------------
// Audio Matrix : N inputs x M outputs
//-----------------------------------------------

import("stdfaust.lib");

Fader(in)       = ba.db2linear(vslider("Input %in", -10, -96, 4, 0.1));
Mixer(N,out)    = hgroup("Output %out", par(in, N, *(Fader(in)) ) :> _ );
Matrix(N,M)     = tgroup("Matrix %N x %M", par(in, N, _) <: par(out, M, Mixer(N, out)));

process = Matrix(8, 8);

midiTester

declare name        "midiTester";
declare version     "1.0";
declare author      "Vincent Rateau, GRAME";
declare license     "GPL v3";
declare reference   "www.sonejo.net";

// FAUST MIDI TESTER

process = _*0, (vgroup("FAUST MIDI TESTER", hgroup("[1]", controltester, noteontester, noteofftester, midiclocktester), hgroup("[2]", kattester, pctester, chattester, pitchwheeltester) :> _)) : attach;

///////////////////////////

//Ctrl tester (ctrl ): tester(midi in, midi out)
controltester = vgroup("CTRL IN/OUT", valuetest(50,51), booltest(100,101))
with{
valuetest(i,o) = hslider("Ctrl Value IN (Ctrl %i) [midi:ctrl %i]", 60, 0, 127, 1) : hbargraph("Ctrl Value OUT (Ctrl %o) [midi:ctrl %o]", 0, 127);
booltest(i,o) = checkbox("Ctrl Bool IN (Ctrl %i) [midi:ctrl %i]") : hbargraph("Ctrl Bool OUT (Ctrl %o) [midi:ctrl %o]", 0, 1);
};

//Note tester (keyon) : tester(midi in, midi out)
noteontester = vgroup("NOTE ON IN/OUT", valuetest(50,51), booltest(100,101))
with{
valuetest(i,o) = hslider("NoteOn Value IN (Note %i) [midi:keyon %i]", 60, 0, 127, 1) : hbargraph("NoteOn Value OUT (Note %o) [midi:keyon %o]", 0, 127);
booltest(i,o) = checkbox("NoteOn Bool IN (Note %i) [midi:keyon %i]") : hbargraph("NoteOn Bool OUT (Note %o) [midi:keyon %o]", 0, 1);
};

//Note tester (keyoff) : tester(midi in, midi out)
noteofftester = vgroup("NOTE OFF IN/OUT", valuetest(50,51), booltest(100,101))
with{
valuetest(i,o) = hslider("NoteOff Value IN (Note %i) [midi:keyoff %i]", 60, 0, 127, 1) : hbargraph("NoteOff Value OUT (Note %o) [midi:keyoff %o]", 0, 127);
booltest(i,o) = checkbox("NoteOff Bool IN (Note %i) [midi:keyoff %i]") : hbargraph("NoteOff Bool OUT (Note %o) [midi:keyoff %o]", 0, 1);
};

//Midisync tester
midiclocktester = vgroup("MIDI SYNC (IN)", clock, startstop)
with{
clock = checkbox("MIDI clock signal [midi:clock]");
startstop = checkbox("MIDI START/STOP [midi:start] [midi:stop]");
};

//Key Aftertouch tester (keypress) : tester(midi in, midi out)
kattester = vgroup("KEY AFTERTOUCH (KAT) IN/OUT",valuetest(50,51), booltest(100,101))
with{
valuetest(i,o) = hslider("Note KAT Value IN (Note %i) [midi:keypress %i]", 60, 0, 127, 1) : hbargraph("Note KAT Value OUT (Note %o) [midi:keypress %o]", 0, 127);
booltest(i,o) = checkbox("Note KAT Bool IN (Note %i) [midi:keypress %i]") : hbargraph("Note KAT Bool OUT (Note %o) [midi:keypress %o]", 0, 1);
};

//ProgramChange tester (pgm) : tester(midi in, midi out)
pctester = vgroup("PROGRAM CHANGE (PC) IN/OUT",valuetest(50,51), booltest(100,101))
with{
valuetest(i,o) = hslider("ProgramChange Value IN (PC %i) [midi:pgm %i]", 60, 0, 127, 1) : hbargraph("ProgramChange Value OUT (PC %o) [midi:pgm %o]", 0, 127);
booltest(i,o) = checkbox("ProgramChange Bool IN (PC %i) [midi:pgm %i]") : hbargraph("ProgramChange Bool OUT (PC %o) [midi:pgm %o]", 0, 1);
};

//Channel Aftertourch tester (chanpress) : tester(midi in, midi out)
chattester = vgroup("CHANNEL AFTERTOUCH (CHAT) IN/OUT",valuetest(50,51), booltest(100,101))
with{
valuetest(i,o) = hslider("Note CHAT Value IN (Note %i) [midi:chanpress %i]", 60, 0, 127, 1) : hbargraph("Note CHAT Value OUT (Note %o) [midi:chanpress %o]", 0, 127);
booltest(i,o) = checkbox("Note CHAT Bool IN (Note %i) [midi:chanpress %i]") : hbargraph("Note CHAT Bool OUT (Note %o) [midi:chanpress %o]", 0, 1);
};

//Pitchwheel tester (pitchwheel) : tester(midi in, midi out)
pitchwheeltester = vgroup("PITCHWHEEL IN/OUT",valuetest, booltest)
with{
valuetest = hslider("Pitchwheel Value IN  [midi:pitchwheel]", 0, -8192, 8191, 1) : hbargraph("Pitchwheel Value OUT[midi:pitchwheel]", -8192, 8191);
booltest = checkbox("Pitchwheel Bool IN [midi:pitchwheel]") : hbargraph("Pitchwheel Bool OUT [midi:pitchwheel]", 0, 1);
};

switcher

declare name        "switcher";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2007";

//-----------------------------------------------
// Switch between two stereo sources. 
// Useful to compare these two sources
// The parameter c\in{0,1} indicates the 
// channels to select
//-----------------------------------------------

switch(c,x0,x1,y0,y1) = sel(c,x0,y0), sel(c,x1,y1)
                            with { 
                                sel(c,x,y) = (1-c)*x + c*y; 
                            };
    
process = switch(hslider("source 0 <-> source 1",0,0,1,1));

                 

tester2

declare name        "tester2";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2014";

//-----------------------------------------------
// Stereo Audio Tester : send a test signal (sine, 
// noise, pink) on a stereo channel
//-----------------------------------------------

import("stdfaust.lib");

pink    = f : (+ ~ g) with {
    f(x) = 0.04957526213389*x - 0.06305581334498*x' + 0.01483220320740*x'';
    g(x) = 1.80116083982126*x - 0.80257737639225*x';
};

// User interface
//----------------
transition(n) = \(old,new).(ba.if(old<new, min(old+1.0/n,new), max(old-1.0/n,new))) ~ _;

vol  = hslider("[2] volume [unit:dB]", -96, -96, 0, 1): ba.db2linear : si.smoo;
freq = hslider("[1] freq [unit:Hz][scale:log]", 440, 40, 20000, 1);
wave = nentry("[3] signal [style:menu{'white noise':0;'pink noise':1;'sine':2}]", 0, 0, 2, 1) : int;
dest = nentry("[4] channel [style:radio{'none':0;'left':1;'right':2;'both':3}]", 0, 0, 3, 1) : int;

testsignal  = no.noise, pink(no.noise), os.osci(freq): select3(wave);

process     = vgroup("Stereo Audio Tester",
                testsignal*vol 
                <: par(i, 2, *((dest & (i+1)) != 0 : transition(4410))) 
            );

tester

declare name        "tester";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-----------------------------------------------
// Tester : tests louspeakers
// Send a test signal( sine, noise, pink) to one 
// of 8 loudspeakers
//-----------------------------------------------

import("stdfaust.lib");

// TODO: this should be rewritten with the pink noise function of noises.lib
pink    = f : (+ ~ g) with {
    f(x) = 0.04957526213389*x - 0.06305581334498*x' + 0.01483220320740*x'';
    g(x) = 1.80116083982126*x - 0.80257737639225*x';
};

// User interface
//----------------
vol             = hslider("[2] volume [unit:dB]", -96, -96, 0, 1): ba.db2linear : si.smoo;
freq            = hslider("[1] freq [unit:Hz]", 1000, 10, 20000, 1);
dest            = hslider("[3] destination", 0, 0, 8, 1);

testsignal      = os.osci(freq)*checkbox("sine wave")
                + no.noise * checkbox("white noise")
                + pink(no.noise) * ba.db2linear(20)  * checkbox("pink noise");

process         = vgroup( "Audio Tester", 
                    testsignal*vol 
                    <: par(i, 8, *(dest==i)) 
                  );

UITester

declare name "UITester";
declare version "1.0";
declare author "O. Guillerminet";
declare license "BSD";
declare copyright "(c) O. Guillerminet 2012";

vbox =          vgroup("vbox", 
                    checkbox("check1"),
                    checkbox("check2"),
                    nentry("knob0[style:knob]", 60, 0, 127, 0.1));

sliders =       hgroup("sliders",
                    vslider("vslider1", 60, 0, 127, 0.1),
                    vslider("vslider2", 60, 0, 127, 0.1),
                    vslider("vslider3", 60, 0, 127, 0.1));

knobs =         hgroup("knobs",
                    vslider("knob1[style:knob]", 60, 0, 127, 0.1),
                    vslider("knob2[style:knob]", 60, 0, 127, 0.1), 
                    vslider("knob3[style:knob]", 60, 0, 127, 0.1));

smallhbox1 =        hgroup("small box 1",
                    vslider("vslider5 [unit:Hz]", 60, 0, 127, 0.1),
                    vslider("vslider6 [unit:Hz]", 60, 0, 127, 0.1),
                    vslider("knob4[style:knob]", 60, 0, 127, 0.1),
                    nentry("num1 [unit:f]", 60, 0, 127, 0.1),
                    vbargraph("vbar1", 0, 127));

smallhbox2 =        hgroup("small box 2",
                    vslider("vslider7 [unit:Hz]", 60, 0, 127, 0.1),
                    vslider("vslider8 [unit:Hz]", 60, 0, 127, 0.1),
                    vslider("knob5[style:knob]", 60, 0, 127, 0.1),
                    nentry("num2 [unit:f]", 60, 0, 127, 0.1),
                    vbargraph("vbar2", 0, 127));

smallhbox3 =        hgroup("small box 3",
                    vslider("vslider9 [unit:Hz]", 60, 0, 127, 0.1),
                    vslider("vslider10 [unit:m]", 60, 0, 127, 0.1),
                    vslider("knob6[style:knob]", 60, 0, 127, 0.1),
                    nentry("num3 [unit:f]", 60, 0, 127, 0.1),
                    vbargraph("vbar3", 0, 127));

subhbox1 =      hgroup("sub box 1",
                    smallhbox2,
                    smallhbox3);

vmisc =         vgroup("vmisc",
                    vslider("vslider4 [unit:Hz]", 60, 0, 127, 0.1),
                    button("button"),
                    hslider("hslider [unit:Hz]", 60, 0, 127, 0.1),
                    smallhbox1,
                    subhbox1,
                    hbargraph("hbar", 0, 127));

hmisc =         hgroup("hmisc",
                    vslider("vslider4 [unit:f]", 60, 0, 127, 0.1),
                    button("button"),
                    hslider("hslider", 60, 0, 127, 0.1),
                    nentry("num [unit:f]", 60, 0, 127, 0.1),
                    vbargraph("vbar", 0, 127),
                    hbargraph("hbar", 0, 127));

//------------------------- Process --------------------------------

process =       tgroup("grp 1",
                    vbox,
                    sliders,
                    knobs,
                    vmisc,
                    hmisc);

old

freeverb

// WARNING: freeverb has been reimplemented in reverbs.lib: this version is deprecated

declare name        "freeverb";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c) GRAME 2006";
declare reference   "https://ccrma.stanford.edu/~jos/pasp/Freeverb.html";

//======================================================
//
//                      Freeverb
//        Faster version using fixed delays (20% gain)
//
//======================================================

// Constant Parameters
//--------------------

fixedgain   = 0.015; //value of the gain of fxctrl
scalewet    = 3.0;
scaledry    = 2.0;
scaledamp   = 0.4;
scaleroom   = 0.28;
offsetroom  = 0.7;
initialroom = 0.5;
initialdamp = 0.5;
initialwet  = 1.0/scalewet;
initialdry  = 0;
initialwidth= 1.0;
initialmode = 0.0;
freezemode  = 0.5;
stereospread= 23;
allpassfeed = 0.5; //feedback of the delays used in allpass filters


// Filter Parameters
//------------------

combtuningL1    = 1116;
combtuningL2    = 1188;
combtuningL3    = 1277;
combtuningL4    = 1356;
combtuningL5    = 1422;
combtuningL6    = 1491;
combtuningL7    = 1557;
combtuningL8    = 1617;

allpasstuningL1 = 556;
allpasstuningL2 = 441;
allpasstuningL3 = 341;
allpasstuningL4 = 225;


// Control Sliders
//--------------------
// Damp : filters the high frequencies of the echoes (especially active for great values of RoomSize)
// RoomSize : size of the reverberation room
// Dry : original signal
// Wet : reverberated signal

dampSlider      = hslider("Damp",0.5, 0, 1, 0.025)*scaledamp;
roomsizeSlider  = hslider("RoomSize", 0.9, 0, 1, 0.025)*scaleroom + offsetroom;
wetSlider       = hslider("Wet", 0.9, 0, 1, 0.025);
combfeed        = roomsizeSlider;


// Comb and Allpass filters
//-------------------------

allpass(dt,fb) = (_,_ <: (*(fb),_:+:@(dt)), -) ~ _ : (!,_);

comb(dt, fb, damp) = (+:@(dt)) ~ (*(1-damp) : (+ ~ *(damp)) : *(fb));


// Reverb components
//------------------

monoReverb(fb1, fb2, damp, spread)
    = _ <:  comb(combtuningL1+spread, fb1, damp),
            comb(combtuningL2+spread, fb1, damp),
            comb(combtuningL3+spread, fb1, damp),
            comb(combtuningL4+spread, fb1, damp),
            comb(combtuningL5+spread, fb1, damp),
            comb(combtuningL6+spread, fb1, damp),
            comb(combtuningL7+spread, fb1, damp),
            comb(combtuningL8+spread, fb1, damp)
        +>
            allpass (allpasstuningL1+spread, fb2)
        :   allpass (allpasstuningL2+spread, fb2)
        :   allpass (allpasstuningL3+spread, fb2)
        :   allpass (allpasstuningL4+spread, fb2)
        ;

stereoReverb(fb1, fb2, damp, spread)
    = + <:  monoReverb(fb1, fb2, damp, 0), monoReverb(fb1, fb2, damp, spread);


// fxctrl : add an input gain and a wet-dry control to a stereo FX
//----------------------------------------------------------------

fxctrl(g,w,Fx) =  _,_ <: (*(g),*(g) : Fx : *(w),*(w)), *(1-w), *(1-w) +> _,_;

// Freeverb
//---------

freeverb = vgroup("Freeverb", fxctrl(fixedgain, wetSlider, stereoReverb(combfeed, allpassfeed, dampSlider, stereospread)));

process = freeverb;

phasing

flanger

declare name "flanger";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Flanger effect application.";

import("stdfaust.lib");

process = dm.flanger_demo;

phaser

declare name "phaser";
declare version "0.0";
declare author "JOS, revised by RM";
declare description "Phaser demo application.";

import("stdfaust.lib");

process = dm.phaser2_demo;

phaserFlangerLab

declare name "phaserFlangerLab";

import("stdfaust.lib");

//process = ol.sawtooth_demo <: 
//  el.flanger_demo : el.phaser2_demo :> fl.spectral_level_demo <: _,_;

fx_stack = 
 vgroup("[1]", dm.sawtooth_demo) <:
 vgroup("[2]", dm.flanger_demo) : 
 vgroup("[3]", dm.phaser2_demo);

level_viewer(x,y) = attach(x, vgroup("[4]", dm.spectral_level_demo(x+y))),y;

process = fx_stack : level_viewer;

physicalModeling

brass

declare name "Brass";
declare description "Simple brass instrument physical model with physical parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.brass_ui <: _,_;

brassMIDI

declare name "BrassMIDI";
declare description "Simple MIDI-controllable brass instrument physical model with physical parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.brass_ui_MIDI <: _,_;

churchBell

declare name "ChurchBell";
declare description "Generic church bell physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.churchBell_ui <: _,_;

clarinet

declare name "Clarinet";
declare description "Simple clarinet physical model with physical parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.clarinet_ui <: _,_;

clarinetMIDI

declare name "ClarinetMIDI";
declare description "Simple MIDI-controllable clarinet physical model with physical parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.clarinet_ui_MIDI <: _,_;

djembeMIDI

declare name "DjembeMIDI";
declare description "Simple MIDI-controllable djembe physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.djembe_ui_MIDI <: _,_;

elecGuitarMIDI

declare name "ElecGuitarMidi";
declare description "Simple electric guitar model without effect chain.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

// TODO: We could potentially add an audio effect chain here

process = pm.elecGuitar_ui_MIDI <: _,_;

englishBell

declare name "EnglishChurchBell";
declare description "English church bell physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.englishBell_ui <: _,_;

flute

declare name "Flute";
declare description "Simple flute physical model with physical parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.flute_ui <: _,_;

fluteMIDI

declare name "FluteMIDI";
declare description "Simple MIDI-controllable flute physical model with physical parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.flute_ui_MIDI <: _,_;

frenchBell

declare name "FrenchChurchBell";
declare description "French church bell physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.frenchBell_ui <: _,_;

germanBell

declare name "GermanChurchBell";
declare description "German church bell physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.germanBell_ui <: _,_;

guitarMIDI

declare name "GuitarMidi";
declare description "Simple acoustic guitar model with steel strings.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.guitar_ui_MIDI <: _,_;

karplus

declare name "KarplusStrong";
declare description "Simple call of the Karplus-Strong model for the Faust physical modeling library";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.ks_ui_MIDI <: _,_;

marimbaMIDI

// WARNING: this model is incomplete and is only here for testing purposes

declare name "MarimbaMIDI";
declare description "Simple MIDI-controllable marimba physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.marimba_ui_MIDI <: _,_;

modularInterpInstrMIDI

declare name "ModularInterpInstrMidi";
declare description "String instrument with a modular body";
declare license "MIT";
declare copyright "(c)Romain Michon & John Granzow, CCRMA (Stanford University), GRAME, University of Michigan";

import("stdfaust.lib");

process = pm.modularInterpInstr_ui_MIDI <: _,_;

nylonGuitarMIDI

declare name "NylonGuitarMidi";
declare description "Simple acoustic guitar model with nylon strings.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.nylonGuitar_ui_MIDI <: _,_;

russianBell

declare name "RussianChurchBell";
declare description "Russian church bell physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.russianBell_ui <: _,_;

standardBell

declare name "StandardChurchBell";
declare description "Standard church bell physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.standardBell_ui <: _,_;

violin

declare name "Violin";
declare description "Simple violin physical model controlled with continuous parameters.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.violin_ui <: _,_;

violinMIDI

declare name "ViolinMidi";
declare description "Simple MIDI-controllable violin physical model.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.violin_ui_MIDI <: _,_;

vocalBP

declare name "Vocal BandPass";
declare description "Simple source-filter vocal synthesizer.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.SFFormantModelBP_ui <: _,_;

vocalBPMIDI

declare name "Vocal BandPass MIDI";
declare description "Simple MIDI-controllable source-filter vocal synthesizer.";
declare license "MIT";
declare copyright "(c)Romain Michon, CCRMA (Stanford University), GRAME";

import("stdfaust.lib");

process = pm.SFFormantModelBP_ui_MIDI <: _,_;

vocalFOF

declare name "Vocal FOF";
declare description "FOF vocal synthesizer.";
declare license "MIT";
declare copyright "(c)Mike Olsen, CCRMA (Stanford University)";

import("stdfaust.lib");

process = pm.SFFormantModelFofSmooth_ui <: _,_;

vocalFOFMIDI

declare name "Vocal FOF MIDI";
declare description "MIDI-controllable FOF vocal synthesizer.";
declare license "MIT";
declare copyright "(c)Mike Olsen, CCRMA (Stanford University)";

import("stdfaust.lib");

process = pm.SFFormantModelFofSmooth_ui_MIDI <: _,_;

pitchShifting

pitchShifter

declare name        "pitchShifter";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

 //--------------------------------------
 // very simple real time pitch shifter
 //--------------------------------------
 
import("stdfaust.lib");

pitchshifter = vgroup("Pitch Shifter", ef.transpose(
                                    hslider("window (samples)", 1000, 50, 10000, 1),
                                    hslider("xfade (samples)", 10, 1, 10000, 1),
                                    hslider("shift (semitones) ", 0, -12, +12, 0.1)
                                  )
                );

process = pitchshifter;

psychoacoustic

harmonicExciter

declare exciter_name "harmonicExciter";
declare exciter_author "Priyanka Shekar (pshekar@ccrma.stanford.edu), revised by RM";
declare exciter_copyright "Copyright (c) 2013 Priyanka Shekar";
declare exciter_version "1.0";
declare exciter_license "MIT License (MIT)";
declare description "Psychoacoustic harmonic exciter, with GUI";

import("stdfaust.lib");

process = dm.exciter;

reverb

fdnRev

declare name "fdnRev";
declare version "0.0";
declare author "JOS, Revised by RM";
declare description "A feedback delay network reverb.";

import("stdfaust.lib");

process = dm.fdnrev0_demo(16,5,3);

freeverb

declare name "freeverb";
declare version "0.0";
declare author "RM";
declare description "Freeverb demo application.";

import("stdfaust.lib");

process = dm.freeverb_demo;

reverbDesigner

declare name "reverbDesigner";

import("stdfaust.lib");

N = 16;     // Feedback Delay Network (FDN) order (power of 2, 2 to 16)
NB =  5;    // Number of T60-controlled frequency-bands (3 or more)
BSO =  3;   // Order of each lowpass/highpass bandsplit (odd positive integer)

process = dm.fdnrev0_demo(N,NB,BSO);

reverbTester

declare name "reverbTester";
declare version "0.0";
declare author "RM";
declare description "Handy test inputs for reverberator demos below.";

import("stdfaust.lib");

process = dm.stereo_reverb_tester;

zitaRev

declare name "zitaRev";
declare version "0.0";
declare author "JOS, Revised by RM";
declare description "Example GUI for `zita_rev1_stereo` (mostly following the Linux `zita-rev1` GUI).";

import("stdfaust.lib");

process = dm.zita_rev1; 

zitaRevFDN

declare name "zitaRevFDN";
declare version "0.0";
declare author "JOS, Revised by RM";
declare description "Reverb demo application based on `zita_rev_fdn`.";

import("stdfaust.lib");

process = dm.zita_rev_fdn_demo;

SAM

smartKeyboard

acGuitar

//############################### acGuitar.dsp #################################
// Faust instrument specifically designed for `faust2smartkeyb` where 6 virtual
// nylon strings can be strummed and plucked using a dedicated keyboard. The
// extra "strumming keyboard" could be easily replaced by an external strumming
// interface while the touch screen could keep being used to change the pitch
// of the strings.
//
// ## `SmartKeyboard` Use Strategy
//
// The first 6 keyboards implement each individual string of the instrument. A
// seventh keybaord is used a strumming/plucking interface. As mentionned
// previously, it could be easily replaced by an external interface.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets.
// However it was specifically designed to be used with `faust2smartkeyb`. For
// best results, we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp acGuitar.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Aug. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//##############################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'7',
    'Max Keyboard Polyphony':'0',
    'Rounding Mode':'2',
    'Keyboard 0 - Number of Keys':'14',
  'Keyboard 1 - Number of Keys':'14',
    'Keyboard 2 - Number of Keys':'14',
    'Keyboard 3 - Number of Keys':'14',
    'Keyboard 4 - Number of Keys':'14',
    'Keyboard 5 - Number of Keys':'14',
    'Keyboard 6 - Number of Keys':'6',
    'Keyboard 0 - Lowest Key':'52',
    'Keyboard 1 - Lowest Key':'57',
    'Keyboard 2 - Lowest Key':'62',
    'Keyboard 3 - Lowest Key':'67',
    'Keyboard 4 - Lowest Key':'71',
    'Keyboard 5 - Lowest Key':'76',
    'Keyboard 0 - Send Keyboard Freq':'1',
    'Keyboard 1 - Send Keyboard Freq':'1',
    'Keyboard 2 - Send Keyboard Freq':'1',
    'Keyboard 3 - Send Keyboard Freq':'1',
    'Keyboard 4 - Send Keyboard Freq':'1',
    'Keyboard 5 - Send Keyboard Freq':'1',
    'Keyboard 6 - Piano Keyboard':'0',
    'Keyboard 6 - Send Key Status':'1',
    'Keyboard 6 - Key 0 - Label':'S0',
    'Keyboard 6 - Key 1 - Label':'S1',
    'Keyboard 6 - Key 2 - Label':'S2',
    'Keyboard 6 - Key 3 - Label':'S3',
    'Keyboard 6 - Key 4 - Label':'S4',
    'Keyboard 6 - Key 5 - Label':'S5'
}";

import("stdfaust.lib");

// SMARTKEYBOARD PARAMS
kbfreq(0) = hslider("kb0freq",164.8,20,10000,0.01);
kbbend(0) = hslider("kb0bend",1,0,10,0.01);
kbfreq(1) = hslider("kb1freq",220,20,10000,0.01);
kbbend(1) = hslider("kb1bend",1,0,10,0.01);
kbfreq(2) = hslider("kb2freq",293.7,20,10000,0.01);
kbbend(2) = hslider("kb2bend",1,0,10,0.01);
kbfreq(3) = hslider("kb3freq",392,20,10000,0.01);
kbbend(3) = hslider("kb3bend",1,0,10,0.01);
kbfreq(4) = hslider("kb4freq",493.9,20,10000,0.01);
kbbend(4) = hslider("kb4bend",1,0,10,0.01);
kbfreq(5) = hslider("kb5freq",659.2,20,10000,0.01);
kbbend(5) = hslider("kb5bend",1,0,10,0.01);
kb6kstatus(0) = hslider("kb6k0status",0,0,1,1) <: ==(1) | ==(4) : int;
kb6kstatus(1) = hslider("kb6k1status",0,0,1,1) <: ==(1) | ==(4) : int;
kb6kstatus(2) = hslider("kb6k2status",0,0,1,1) <: ==(1) | ==(4) : int;
kb6kstatus(3) = hslider("kb6k3status",0,0,1,1) <: ==(1) | ==(4) : int;
kb6kstatus(4) = hslider("kb6k4status",0,0,1,1) <: ==(1) | ==(4) : int;
kb6kstatus(5) = hslider("kb6k5status",0,0,1,1) <: ==(1) | ==(4) : int;

// MODEL PARAMETERS
// strings length
sl(i) = kbfreq(i)*kbbend(i) : pm.f2l : si.smoo;
// pluck position is controlled by the x axis of the accel
pluckPosition =
    hslider("pluckPosition[acc: 1 0 -10 0 10]",0.5,0,1,0.01) : si.smoo;

// ASSEMBLING MODELS
// number of strings
nStrings = 6;
guitar = par(i,nStrings,
    kb6kstatus(i) : ba.impulsify : // using "raw" impulses to drive the models
    pm.nylonGuitarModel(sl(i),pluckPosition)) :> _;

process = guitar <: _,_;

bells

//################################ bells.dsp ###################################
// Faust instrument specifically designed for `faust2smartkeyb` where the
// physical models of 4 different bells can be played using screen pads. The
// models are taken from `physmodels.lib`.
//
// ## `SmartKeyboard` Use Strategy
//
// The `SmartKeyboard` interface is used to implement percussion pads where
// the X/Y position of fingers is retrieved to control the strike position on
// the bells.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets.
// However it was specifically designed to be used with `faust2smartkeyb`. For
// best results, we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp bells.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Aug. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//##############################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'2',
    'Max Keyboard Polyphony':'0',
    'Keyboard 0 - Number of Keys':'2',
  'Keyboard 1 - Number of Keys':'2',
    'Keyboard 0 - Send Freq':'0',
  'Keyboard 1 - Send Freq':'0',
    'Keyboard 0 - Piano Keyboard':'0',
  'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 0 - Send Key Status':'1',
    'Keyboard 1 - Send Key Status':'1',
    'Keyboard 0 - Send X':'1',
    'Keyboard 0 - Send Y':'1',
    'Keyboard 1 - Send X':'1',
    'Keyboard 1 - Send Y':'1',
    'Keyboard 0 - Key 0 - Label':'English Bell',
    'Keyboard 0 - Key 1 - Label':'French Bell',
    'Keyboard 1 - Key 0 - Label':'German Bell',
    'Keyboard 1 - Key 1 - Label':'Russian Bell'
}";

import("stdfaust.lib");

// SMARTKEYBOARD PARAMS
kb0k0status = hslider("kb0k0status",0,0,1,1) : min(1) : int;
kb0k1status = hslider("kb0k1status",0,0,1,1) : min(1) : int;
kb1k0status = hslider("kb1k0status",0,0,1,1) : min(1) : int;
kb1k1status = hslider("kb1k1status",0,0,1,1) : min(1) : int;
x = hslider("x",1,0,1,0.001);
y = hslider("y",1,0,1,0.001);

// MODEL PARAMETERS
strikeCutoff = 6500;
strikeSharpness = 0.5;
strikeGain = 1;
// synthesize 10 modes out of 50
nModes = 10;
// resonance duration is 30s
t60 = 30;
// number of excitation pos (retrieved from model)
nExPos = 7;
// computing excitation position from X and Y
exPos = min((x*2-1 : abs),(y*2-1 : abs))*(nExPos-1) : int;

// ASSEMBLING MODELS
bells =
    (kb0k0status : pm.strikeModel(10,strikeCutoff,strikeSharpness,strikeGain) : pm.englishBellModel(nModes,exPos,t60,1,3)) +
    (kb0k1status : pm.strikeModel(10,strikeCutoff,strikeSharpness,strikeGain) : pm.frenchBellModel(nModes,exPos,t60,1,3)) +
    (kb1k0status : pm.strikeModel(10,strikeCutoff,strikeSharpness,strikeGain) : pm.germanBellModel(nModes,exPos,t60,1,2.5)) +
    (kb1k1status : pm.strikeModel(10,strikeCutoff,strikeSharpness,strikeGain) : pm.russianBellModel(nModes,exPos,t60,1,3)) :> *(0.2);

process = bells <: _,_;

bowed

//##################################### bowed.dsp ########################################
// Faust instrument specifically designed for `faust2smartkeyb` implementing a
// non-polyphonic synthesizer (e.g., physical model; etc.) using a combination of
// different types of UI elements.
//
// ## `SmartKeyboard` Use Strategy
//
// 5 keyboards are declared (4 actual keyboards and 1 control surface). We want to
// disable the voice allocation system and we want to activate a voice on start-up
// so that all strings are constantly running so we set `Max Keyboard Polyphony` to
// 0. Since we don't want the first 4 keyboards to send the X and Y position of
// fingers on the screen, we set `Send X` and `Send Y` to 0 for all these keyboards.
// Similarly, we don't want the fifth keyboard to send pitch information to the synth
// so we set `Send Freq` to 0 for that keyboard. Finally, we deactivate piano keyboard
// mode for the fifth keyboard to make sure that color doesn't change when the key is
// touch and that note names are not displayed.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp midiOnly.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'5',
    'Max Keyboard Polyphony':'0',
    'Rounding Mode':'1',
    'Keyboard 0 - Number of Keys':'19',
    'Keyboard 1 - Number of Keys':'19',
    'Keyboard 2 - Number of Keys':'19',
    'Keyboard 3 - Number of Keys':'19',
    'Keyboard 4 - Number of Keys':'1',
    'Keyboard 4 - Send Freq':'0',
    'Keyboard 0 - Send X':'0',
    'Keyboard 1 - Send X':'0',
    'Keyboard 2 - Send X':'0',
    'Keyboard 3 - Send X':'0',
    'Keyboard 0 - Send Y':'0',
    'Keyboard 1 - Send Y':'0',
    'Keyboard 2 - Send Y':'0',
    'Keyboard 3 - Send Y':'0',
    'Keyboard 0 - Lowest Key':'55',
    'Keyboard 1 - Lowest Key':'62',
    'Keyboard 2 - Lowest Key':'69',
    'Keyboard 3 - Lowest Key':'76',
    'Keyboard 4 - Piano Keyboard':'0',
    'Keyboard 4 - Key 0 - Label':'Bow'
}";

import("stdfaust.lib");

// parameters
f = hslider("freq",400,50,2000,0.01);
bend = hslider("bend",1,0,10,0.01);
keyboard = hslider("keyboard",0,0,5,1) : int;
key = hslider("key",0,0,18,1) : int;
x = hslider("x",0.5,0,1,0.01) : si.smoo;
y = hslider("y",0,0,1,0.01) : si.smoo;

// mapping
freq = f*bend;
// dirty motion tracker
velocity = x-x' : abs : an.amp_follower_ar(0.1,1) : *(8000) : min(1);

// 4 "strings"
synthSet = par(i,4,synth(localFreq(i),velocity)) :> _
with{
    localFreq(i) = freq : ba.sAndH(keyboard == i) : si.smoo;
    synth(freq,velocity) = sy.fm((freq,freq + freq*modFreqRatio),index*velocity)*velocity
    with{
        index = 1000;
        modFreqRatio = y*0.3;
    };
};

process = synthSet <: _,_;

brass

//############################### brass.dsp ###################################
// Faust instrument specifically designed for `faust2smartkeyb` where a
// trumpet physical model is controlled using some of the built-in sensors of
// the device and the touchscreen. Some of these elements could be replaced by
// external controllers (e.g., breath/mouth piece controller).
//
// ## `SmartKeyboard` Use Strategy
//
// 1 keyboard is used to implement the pistons of the trumpet (3 keys) and the
// other allows to control the lips tension.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets.
// However it was specifically designed to be used with `faust2smartkeyb`. For
// best results, we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp brass.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Aug. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//##############################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'2',
    'Max Keyboard Polyphony':'0',
    'Keyboard 0 - Number of Keys':'1',
  'Keyboard 1 - Number of Keys':'3',
    'Keyboard 0 - Send Freq':'0',
  'Keyboard 1 - Send Freq':'0',
    'Keyboard 0 - Piano Keyboard':'0',
  'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 0 - Send Key X':'1',
    'Keyboard 1 - Send Key Status':'1',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Key 0 - Label':'Lips Tension',
    'Keyboard 1 - Key 0 - Label':'P1',
    'Keyboard 1 - Key 1 - Label':'P2',
    'Keyboard 1 - Key 2 - Label':'P3'
}";

import("stdfaust.lib");

// SMARTKEYBOARD PARAMS
kb0k0x = hslider("kb0k0x",0,0,1,1);
kb1k0status = hslider("kb1k0status",0,0,1,1) : min(1) : int;
kb1k1status = hslider("kb1k1status",0,0,1,1) : min(1) : int;
kb1k2status = hslider("kb1k2status",0,0,1,1) : min(1) : int;

// MODEL PARAMETERS
// pressure is controlled by accelerometer
pressure = hslider("pressure[acc: 1 1 -10 0 10]",0,0,1,0.01) : si.smoo;
breathGain = 0.005; breathCutoff = 2000;
vibratoFreq = 5; vibratoGain = 0;
//pitch when no pistons are pushed
basePitch = 48; // C4
// calculate pitch shift in function of piston combination
pitchShift =
  ((kb1k0status == 0) & (kb1k1status == 1) & (kb1k2status == 0))*(1) +
  ((kb1k0status == 1) & (kb1k1status == 0) & (kb1k2status == 0))*(2) +
  ((kb1k0status == 1) & (kb1k1status == 1) & (kb1k2status == 0))*(3) +
  ((kb1k0status == 0) & (kb1k1status == 1) & (kb1k2status == 1))*(4) +
  ((kb1k0status == 1) & (kb1k1status == 0) & (kb1k2status == 1))*(5) +
  ((kb1k0status == 1) & (kb1k1status == 1) & (kb1k2status == 1))*(6);
// tube length is calculated based on piston combination
tubeLength = basePitch-pitchShift : ba.midikey2hz : pm.f2l : si.smoo;
// lips tension is controlled using pad on screen
lipsTension = kb0k0x : si.smoo;
// default mute value
mute = 0.5;

// ASSEMBLING MODEL
model =
    pm.blower(pressure,breathGain,breathCutoff,vibratoFreq,vibratoGain) :
  pm.brassModel(tubeLength,lipsTension,mute);

process = model <: _,_;

clarinet

//############################### clarinet.dsp #################################
// Faust instrument specifically designed for `faust2smartkeyb` where a
// clarinet physical model is controlled by an interface implementing
// fingerings similar to that of a the real instrument. The pressure of the
// breath in the mouthpiece of the clarinet is controlled by blowing on the
// built-in microphone of the device.
//
// ## `SmartKeyboard` Use Strategy
//
// The device is meant to be held with 2 hands vertically in order to put all
// fingers on the screen at the same time. Key combinations determine the
// pitch of the instrument. A single voice is constantly ran.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets.
// However it was specifically designed to be used with `faust2smartkeyb`. For
// best results, we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] clarinet.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Aug. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//##############################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'2',
    'Max Keyboard Polyphony':'0',
    'Keyboard 0 - Number of Keys':'4',
  'Keyboard 1 - Number of Keys':'5',
    'Keyboard 0 - Send Freq':'0',
  'Keyboard 1 - Send Freq':'0',
    'Keyboard 0 - Piano Keyboard':'0',
  'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 0 - Send Key Status':'1',
    'Keyboard 1 - Send Key Status':'1',
    'Keyboard 0 - Key 3 - Label':'O+',
    'Keyboard 1 - Key 4 - Label':'O-'
}";

import("stdfaust.lib");

// SMARTKEYBOARD PARAMS
kb0k0status = hslider("kb0k0status",0,0,1,1) : min(1) : int;
kb0k1status = hslider("kb0k1status",0,0,1,1) : min(1) : int;
kb0k2status = hslider("kb0k2status",0,0,1,1) : min(1) : int;
kb0k3status = hslider("kb0k3status",0,0,1,1) : min(1) : int;
kb1k0status = hslider("kb1k0status",0,0,1,1) : min(1) : int;
kb1k1status = hslider("kb1k1status",0,0,1,1) : min(1) : int;
kb1k2status = hslider("kb1k2status",0,0,1,1) : min(1) : int;
kb1k3status = hslider("kb1k3status",0,0,1,1) : min(1) : int;
kb1k4status = hslider("kb1k4status",0,0,1,1) : min(1) : int;

// MODEL PARAMETERS
reedStiffness = hslider("reedStiffness[acc: 1 1 -10 0 10]",0,0,1,0.01) : si.smoo;
basePitch = 73; // C#4
pitchShift = // calculate pitch shfit in function of "keys" combination
  ((kb0k0status == 0) & (kb0k1status == 1) & (kb0k2status == 0) &
        (kb1k0status == 0) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-1) + // C
    ((kb0k0status == 1) & (kb0k1status == 0) & (kb0k2status == 0) &
        (kb1k0status == 0) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-2) + // B
    ((kb0k0status == 1) & (kb0k1status == 0) & (kb0k2status == 1) &
        (kb1k0status == 0) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-3) + // Bb
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 0) &
        (kb1k0status == 0) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-4) + // A
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 0) &
        (kb1k0status == 1) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-5) + // G#
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 0) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-6) + // G
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 0) & (kb1k1status == 1) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-7) + // F#
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 1) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-8) + // F
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 1) & (kb1k1status == 1) & (kb1k2status == 0) &
        (kb1k3status == 0))*(-9) + // E
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 1) & (kb1k1status == 1) & (kb1k2status == 0) &
        (kb1k3status == 1))*(-10) + // Eb
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 1) & (kb1k1status == 1) & (kb1k2status == 1) &
        (kb1k3status == 0))*(-11) + // D
    ((kb0k0status == 0) & (kb0k1status == 0) & (kb0k2status == 0) &
        (kb1k0status == 0) & (kb1k1status == 0) & (kb1k2status == 0) &
        (kb1k3status == 1))*(-12) + // C#
    ((kb0k0status == 1) & (kb0k1status == 1) & (kb0k2status == 1) &
        (kb1k0status == 1) & (kb1k1status == 1) & (kb1k2status == 1) &
        (kb1k3status == 1))*(-13); // C
octaveShiftUp = +(kb0k3status : ba.impulsify)~_; // counting up
octaveShiftDown = +(kb1k4status : ba.impulsify)~_; // counting down
octaveShift = (octaveShiftUp-octaveShiftDown)*(12);
// tube length is just smoothed: could be improved
tubeLength = basePitch+pitchShift+octaveShift : ba.midikey2hz : pm.f2l : si.smoo;
bellOpening = 0.5;

// ASSEMBLING MODEL
model(pressure) = pm.clarinetModel(tubeLength,pressure,reedStiffness,bellOpening);

// pressure is estimated from mic signal
process = an.amp_follower_ud(0.02,0.02)*0.7 : model <: _,_;

crazyGuiro

//################################### crazyGuiro.dsp #####################################
// A simple smart phone "Guiro" where the touch screen is used to drive the instrument and
// select its pitch and where the x and y axis of the accelerometer control the
// resonance properties of the instrument.
//
// ## `SmartKeyboard` Use Strategy
//
// Since the sounds generated by this synth are very short, the strategy here is to take
// advantage of the polyphony capabilities of the iOSKeyboard architecture by creating
// a new voice every time a new key is pressed. Since the `SmartKeyboard` interface has a
// large number of keys here (128), lots of sounds are generated when sliding a
// finger across the keyboard. Also, it's interesting to notice that the `freq` parameter
// is not used here. Instead `keyboard` and `key` are used which allows us to easily
// make custom mappings.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] crazyGuiro.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

import("stdfaust.lib");


//========================= Smart Keyboard Configuration =================================
// 8 keyboards, each has 16 keys, none of them display key names.
//========================================================================================

declare interface "SmartKeyboard{
    'Number of Keyboards':'8',
    'Keyboard 0 - Number of Keys':'16',
    'Keyboard 1 - Number of Keys':'16',
    'Keyboard 2 - Number of Keys':'16',
    'Keyboard 3 - Number of Keys':'16',
    'Keyboard 4 - Number of Keys':'16',
    'Keyboard 5 - Number of Keys':'16',
    'Keyboard 6 - Number of Keys':'16',
    'Keyboard 7 - Number of Keys':'16',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 2 - Piano Keyboard':'0',
    'Keyboard 3 - Piano Keyboard':'0',
    'Keyboard 4 - Piano Keyboard':'0',
    'Keyboard 5 - Piano Keyboard':'0',
    'Keyboard 6 - Piano Keyboard':'0',
    'Keyboard 7 - Piano Keyboard':'0'
}";


//================================ Instrument Parameters =================================
// Creates the connection between the synth and the mobile device
//========================================================================================

// the current keyboard
keyboard = hslider("keyboard",0,0,2,1);
// the current key of the current keyboard
key = hslider("key",0,0,2,1);
// the wet factor of the reverb
wet = hslider("wet[acc: 0 0 -10 0 10]",0,0,1,0.01);
// the resonance factor of the reverb
res = hslider("res[acc: 1 0 -10 0 10]",0.5,0,1,0.01);
// smart keyboard gate parameter
gate = button("gate");


//=================================== Parameters Mapping =================================
//========================================================================================

// the resonance frequency of each click of the Guiro changes in function of
// the selected keyboard and key on it
minKey = 50; // min key of lowest keyboard
keySkipKeyboard = 8; // key skip per keyboard
drumResFreq = (key+minKey)+(keyboard*keySkipKeyboard) : ba.midikey2hz;
reverbWet = wet : si.smoo;
reverbRes = wet : si.smoo;

// filter q
q = 8;

//============================================ DSP =======================================
//========================================================================================

reverb(wet,res)  =  _ <: *(1-wet),(*(wet) : re.mono_freeverb(res, 0.5, 0.5, 0)) :> _;

process = sy.popFilterDrum(drumResFreq,q,gate) : reverb(wet,res) <: _,_;

drums

//##################################### drums.dsp ########################################
// Faust instrument specifically designed for `faust2smartkeyb` where 3 drums can
// be controlled using pads. The X/Y postion of fingers is detected on each key
// and use to control the strike postion on the virtual membrane.
//
// ## `SmartKeyboard` Use Strategy
//
// The drum physical model used here is implemented to be generic so that its
// fundamental frequency can be changed for each voice. `SmartKeyboard` is used
// in polyphonic mode so each new strike on the interface corresponds to a new
// new voice.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp drums.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

// Interface with 2 keyboards of 2 and 1 keys (3 pads)
// Static mode is used so that keys don't change color when touched
// Note labels are hidden
// Piano Keyboard mode is deactivated so all the keys look the same
declare interface "SmartKeyboard{
    'Number of Keyboards':'2',
    'Keyboard 0 - Number of Keys':'2',
    'Keyboard 1 - Number of Keys':'1',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 1 - Static Mode':'1',
    'Keyboard 0 - Send X':'1',
    'Keyboard 0 - Send Y':'1',
    'Keyboard 1 - Send X':'1',
    'Keyboard 1 - Send Y':'1',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 0 - Key 0 - Label':'High',
    'Keyboard 0 - Key 1 - Label':'Mid',
    'Keyboard 1 - Key 0 - Label':'Low'
}";

import("stdfaust.lib");

// standard parameters
gate = button("gate");
x = hslider("x",1,0,1,0.001);
y = hslider("y",1,0,1,0.001);
keyboard = hslider("keyboard",0,0,1,1) : int;
key = hslider("key",0,0,1,1) : int;

drumModel = pm.djembe(rootFreq,exPos,strikeSharpness,gain,gate)
with{
    // frequency of the lowest drum
    bFreq = 60;
    // retrieving pad ID (0-2)
    padID = 2-(keyboard*2+key);
    // drum root freq is computed in function of pad number
    rootFreq = bFreq*(padID+1);
    // excitation position
    exPos = min((x*2-1 : abs),(y*2-1 : abs));
    strikeSharpness = 0.5;
    gain = 2;
};

process = drumModel <: _,_;

dubDub

//################################### dubDub.dsp #####################################
// A simple smartphone abstract instrument than can be controlled using the touch
// screen and the accelerometers of the device.
//
// ## `SmartKeyboard` Use Strategy
//
// The idea here is to use the `SmartKeyboard` interface as an X/Y control pad by just
// creating one keyboard with on key and by retrieving the X and Y position on that single
// key using the `x` and `y` standard parameters. Keyboard mode is deactivated so that
// the color of the pad doesn't change when it is pressed.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] dubDub.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

declare name "dubDub";

import("stdfaust.lib");

//========================= Smart Keyboard Configuration =================================
// (1 keyboards with 1 key configured as a pad.
//========================================================================================

declare interface "SmartKeyboard{
    'Number of Keyboards':'1',
    'Keyboard 0 - Number of Keys':'1',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Send X':'1',
    'Keyboard 0 - Send Y':'1'
}";


//================================ Instrument Parameters =================================
// Creates the connection between the synth and the mobile device
//========================================================================================

// SmartKeyboard X parameter
x = hslider("x",0,0,1,0.01);
// SmartKeyboard Y parameter
y = hslider("y",0,0,1,0.01);
// SmartKeyboard gate parameter
gate = button("gate");
// modulation frequency is controlled with the x axis of the accelerometer
modFreq = hslider("modFeq[acc: 0 0 -10 0 10]",9,0.5,18,0.01);
// general gain is controlled with the y axis of the accelerometer
gain = hslider("gain[acc: 1 0 -10 0 10]",0.5,0,1,0.01);


//=================================== Parameters Mapping =================================
//========================================================================================

// sawtooth frequency
minFreq = 80;
maxFreq = 500;
freq = x*(maxFreq-minFreq) + minFreq : si.polySmooth(gate,0.999,1);

// filter q
q = 8;

// filter cutoff frequency is modulate with a triangle wave
minFilterCutoff = 50;
maxFilterCutoff = 5000;
filterModFreq = modFreq : si.smoo;
filterCutoff = (1-os.lf_trianglepos(modFreq)*(1-y))*(maxFilterCutoff-minFilterCutoff)+minFilterCutoff;

// general gain of the synth
generalGain = gain : ba.lin2LogGain : si.smoo;


//============================================ DSP =======================================
//========================================================================================

process = sy.dubDub(freq,filterCutoff,q,gate)*generalGain <: _,_;

elecGuitar

//################################### elecGuitar.dsp #####################################
// Faust instruments specifically designed for `faust2smartkeyb` where an electric
// guitar physical model is controlled using an isomorphic keyboard. Rock on!
//
// ## `SmartKeyboard` Use Strategy
//
// we want to create an isomorphic keyboard where each keyboard is monophonic and
// implements a "string". Keyboards should be one fourth apart from each other
// (more or less like on a guitar). We want to be able to slide between keyboards
// (strum) to trigger a new note (voice) and we want new fingers on a keyboard to
// "steal" the pitch from the previous finger (sort of hammer on).
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect elecGuitarEffecr.dsp elecGuitar.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017:
// https://ccrma.stanford.edu/~rmichon
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

// Interface with 6 monophonic keyboards one fourth apart from each other
declare interface "SmartKeyboard{
    'Number of Keyboards':'6',
    'Max Keyboard Polyphony':'1',
    'Keyboard 0 - Number of Keys':'13',
    'Keyboard 1 - Number of Keys':'13',
    'Keyboard 2 - Number of Keys':'13',
    'Keyboard 3 - Number of Keys':'13',
    'Keyboard 4 - Number of Keys':'13',
    'Keyboard 5 - Number of Keys':'13',
    'Keyboard 0 - Lowest Key':'72',
    'Keyboard 1 - Lowest Key':'67',
    'Keyboard 2 - Lowest Key':'62',
    'Keyboard 3 - Lowest Key':'57',
    'Keyboard 4 - Lowest Key':'52',
    'Keyboard 5 - Lowest Key':'47',
    'Rounding Mode':'2'
}";

import("stdfaust.lib");

// standard parameters
f = hslider("freq",300,50,2000,0.01);
bend = hslider("bend[midi:pitchwheel]",1,0,10,0.01) : si.polySmooth(gate,0.999,1);
gain = hslider("gain",1,0,1,0.01);
s = hslider("sustain[midi:ctrl 64]",0,0,1,1); // for sustain pedal
t = button("gate");

// mapping params
gate = t+s : min(1);
freq = f*bend : max(60); // min freq is 60 Hz

stringLength = freq : pm.f2l;
pluckPosition = 0.8;
mute = gate : si.polySmooth(gate,0.999,1);

process = pm.elecGuitar(stringLength,pluckPosition,mute,gain,gate) <: _,_;

fm

//###################################### fm.dsp ##########################################
// A simple smart phone percussion abstract sound toy based on an FM synth.
//
// ## `SmartKeyboard` Use Strategy
//
// The idea here is to use the `SmartKeyboard` interface as an X/Y control pad by just
// creating one keyboard with on key and by retrieving the X and Y position on that single
// key using the `x` and `y` standard parameters. Keyboard mode is deactivated so that
// the color of the pad doesn't change when it is pressed.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] crazyGuiro.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

declare name "fm";

import("stdfaust.lib");

//========================= Smart Keyboard Configuration =================================
// (1 keyboards with 1 key configured as a pad.
//========================================================================================

declare interface "SmartKeyboard{
    'Number of Keyboards':'1',
    'Keyboard 0 - Number of Keys':'1',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Send X':'1',
    'Keyboard 0 - Send Y':'1'
}";

//================================ Instrument Parameters =================================
// Creates the connection between the synth and the mobile device
//========================================================================================

// SmartKeyboard X parameter
x = hslider("x",0,0,1,0.01);
// SmartKeyboard Y parameter
y = hslider("y",0,0,1,0.01);
// SmartKeyboard gate parameter
gate = button("gate") ;
// mode resonance duration is controlled with the x axis of the accelerometer
modFreqRatio = hslider("res[acc: 0 0 -10 0 10]",1,0,2,0.01) : si.smoo;

//=================================== Parameters Mapping =================================
//========================================================================================

// carrier frequency
minFreq = 80;
maxFreq = 500;
cFreq = x*(maxFreq-minFreq) + minFreq : si.polySmooth(gate,0.999,1);

// modulator frequency
modFreq = cFreq*modFreqRatio;

// modulation index
modIndex = y*1000 : si.smoo;

//============================================ DSP =======================================
//========================================================================================

// since the generated sound is pretty chaotic, there is no need for an envelope generator
fmSynth = sy.fm((cFreq,modFreq),(modIndex))*(gate : si.smoo)*0.5;

process = fmSynth;

frog

//################################### frog.dsp #####################################
// A simple smart phone abstract instrument than can be controlled using the touch
// screen and the accelerometers of the device.
//
// ## `SmartKeyboard` Use Strategy
//
// The idea here is to use the `SmartKeyboard` interface as an X/Y control pad by just
// creating one keyboard with on key and by retrieving the X and Y position on that single
// key using the `x` and `y` standard parameters. Keyboard mode is deactivated so that
// the color of the pad doesn't change when it is pressed.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] frog.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

declare name "frog";

import("stdfaust.lib");

//========================= Smart Keyboard Configuration =================================
// (1 keyboards with 1 key configured as a pad.
//========================================================================================

declare interface "SmartKeyboard{
    'Number of Keyboards':'1',
    'Keyboard 0 - Number of Keys':'1',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Send X':'1',
    'Keyboard 0 - Send Y':'1'
}";

//================================ Instrument Parameters =================================
// Creates the connection between the synth and the mobile device
//========================================================================================

// SmartKeyboard X parameter
x = hslider("x",0,0,1,0.01);
// SmartKeyboard Y parameter
y = hslider("y",0,0,1,0.01);
// SmartKeyboard gate parameter
gate = button("gate");
// the cutoff frequency of the filter is controlled with the x axis of the accelerometer
cutoff = hslider("cutoff[acc: 0 0 -10 0 10]",2500,50,5000,0.01);

//=================================== Parameters Mapping =================================
//========================================================================================

maxFreq = 100;
minFreq = 1;
freq = x*(maxFreq-minFreq) + minFreq : si.polySmooth(gate,0.999,1);

maxQ = 40;
minQ = 1;
q = (1-y)*(maxQ-minQ) + minQ : si.smoo;
filterCutoff = cutoff : si.smoo;

//============================================ DSP =======================================
//========================================================================================

process = sy.dubDub(freq,filterCutoff,q,gate) <: _,_;

harp

//######################################## harp.dsp ######################################
// A simple smart phone based harp (if we dare to call it like that). 
//
// ## `SmartKeyboard` Use Strategy
//
// Since the sounds generated by this synth are very short, the strategy here is to take
// advantage of the polyphony capabilities of the iOSKeyboard architecture by creating
// a new voice every time a new key is pressed. Since the `SmartKeyboard` interface has a 
// large number of keys here (128), lots of sounds are generated when sliding a 
// finger across the keyboard.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] harp.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

declare name "harp";

import("stdfaust.lib");

//========================= Smart Keyboard Configuration ================================= 
// (8 keyboards with 16 keys configured as a pitch matrix.
//========================================================================================

declare interface "SmartKeyboard{
    'Number of Keyboards':'8',
    'Keyboard 0 - Number of Keys':'16',
    'Keyboard 1 - Number of Keys':'16',
    'Keyboard 2 - Number of Keys':'16',
    'Keyboard 3 - Number of Keys':'16',
    'Keyboard 4 - Number of Keys':'16',
    'Keyboard 5 - Number of Keys':'16',
    'Keyboard 6 - Number of Keys':'16',
    'Keyboard 7 - Number of Keys':'16',
    'Keyboard 0 - Lowest Key':'40',
    'Keyboard 1 - Lowest Key':'45',
    'Keyboard 2 - Lowest Key':'50',
    'Keyboard 3 - Lowest Key':'55',
    'Keyboard 4 - Lowest Key':'60',
    'Keyboard 5 - Lowest Key':'65',
    'Keyboard 6 - Lowest Key':'70',
    'Keyboard 7 - Lowest Key':'75',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 2 - Piano Keyboard':'0',
    'Keyboard 3 - Piano Keyboard':'0',
    'Keyboard 4 - Piano Keyboard':'0',
    'Keyboard 5 - Piano Keyboard':'0',
    'Keyboard 6 - Piano Keyboard':'0',
    'Keyboard 7 - Piano Keyboard':'0'
}";

//================================ Instrument Parameters =================================
// Creates the connection between the synth and the mobile device
//========================================================================================

// the string resonance in second is controlled by the x axis of the accelerometer
res = hslider("res[acc: 0 0 -10 0 10]",2,0.1,4,0.01);
// Smart Keyboard frequency parameter
freq = hslider("freq",400,50,2000,0.01);
// Smart Keyboard gate parameter
gate = button("gate");

//=================================== Parameters Mapping =================================
//========================================================================================

stringFreq = freq;

//============================================ DSP =======================================
//========================================================================================

process = sy.combString(freq,res,gate);

midiOnly

//################################### midiOnly.dsp ######################################
// Faust instrument specifically designed for `faust2smartkeyb` implementing a MIDI
// controllable app where the mobile device's touch screen is used to control
// specific parameters of the synth continuously using two separate X/Y control surfaces.
//
// ## `SmartKeyboard` Use Strategy
//
// The `SmartKeyboard` configuration for this instrument consists in a single keyboard
// with two keys. Each key implements a control surface. `Piano Keyboard` mode is
// disabled so that key names are not displayed and that keys don't change color when
// touched. Finally, `Send Freq` is set to 0 so that new voices are not allocated by
// the touch screen and that the `freq` and `bend` parameters are not computed.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp midiOnly.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

// Interface with 4 polyphnic keyboards of 13 keys with the same config
declare interface "SmartKeyboard{
    'Number of Keyboards':'1',
    'Keyboard 0 - Number of Keys':'2',
    'Keyboard 0 - Send Freq':'0',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Send Key X':'1',
    'Keyboard 0 - Key 0 - Label':'Mod Index',
    'Keyboard 0 - Key 1 - Label':'Mod Freq'
}";

import("stdfaust.lib");

f = hslider("freq",300,50,2000,0.01);
bend = hslider("bend[midi:pitchwheel]",1,0,10,0.01) : si.polySmooth(gate,0.999,1);
gain = hslider("gain",1,0,1,0.01);
key = hslider("key",0,0,1,1) : int;
kb0k0x = hslider("kb0k0x[midi:ctrl 1]",0.5,0,1,0.01) : si.smoo;
kb0k1x = hslider("kb0k1x[midi:ctrl 1]",0.5,0,1,0.01) : si.smoo;
s = hslider("sustain[midi:ctrl 64]",0,0,1,1);
t = button("gate");

// fomating parameters
gate = t+s : min(1);
freq = f*bend;
index = kb0k0x*1000;
modFreqRatio = kb0k1x;

envelope = gain*gate : si.smoo;

process = sy.fm((freq,freq + freq*modFreqRatio),index*envelope)*envelope <: _,_;

multiSynth

//################################### multiSynth.dsp ######################################
// Faust instrument specifically designed for `faust2smartkeyb` where 4 keyboards
// are used to control 4 independent synths.
//
// ## `SmartKeyboard` Use Strategy
//
// The `SmartKeyboard` configuration is relatively simple for this example and
// only consists in four polyphonic keyboards in parallel. The `keyboard` standard
// parameter is used to activate specific elements of the synthesizer.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp multiSynth.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

// Interface with 4 polyphnic keyboards of 13 keys with the same config
declare interface "SmartKeyboard{
    'Number of Keyboards':'4',
    'Rounding Mode':'2',
    'Inter-Keyboard Slide':'0',
    'Keyboard 0 - Number of Keys':'13',
    'Keyboard 1 - Number of Keys':'13',
    'Keyboard 2 - Number of Keys':'13',
    'Keyboard 3 - Number of Keys':'13',
    'Keyboard 0 - Lowest Key':'60',
    'Keyboard 1 - Lowest Key':'60',
    'Keyboard 2 - Lowest Key':'60',
    'Keyboard 3 - Lowest Key':'60',
    'Keyboard 0 - Send Y':'1',
    'Keyboard 1 - Send Y':'1',
    'Keyboard 2 - Send Y':'1',
    'Keyboard 3 - Send Y':'1'
}";

import("stdfaust.lib");

// standard parameters
f = hslider("freq",300,50,2000,0.01);
bend = hslider("bend[midi:pitchwheel]",1,0,10,0.01) : si.polySmooth(gate,0.999,1);
gain = hslider("gain",1,0,1,0.01);
s = hslider("sustain[midi:ctrl 64]",0,0,1,1); // for sustain pedal
t = button("gate");
y = hslider("y[midi:ctrl 1]",1,0,1,0.001) : si.smoo;
keyboard = hslider("keyboard",0,0,3,1) : int;

// fomating parameters
gate = t+s : min(1);
freq = f*bend;
cutoff = y*4000+50;

// oscillators
oscilators(0) = os.sawtooth(freq);
oscilators(1) = os.triangle(freq);
oscilators(2) = os.square(freq);
oscilators(3) = os.osc(freq);

// oscs are selected in function of the current keyboard
synths = par(i,4,select2(keyboard == i,0,oscilators(i))) :> fi.lowpass(3,cutoff) : *(envelope)
with{
    envelope = gate*gain : si.smoo;
};

process = synths <: _,_;

toy

//##################################### toy.dsp #######################################
// Faust sound toy specifically designed for `faust2smartkeyb` where a funny
// synth can be controlled using several fingers on the screen and the built-in
// accelerometer.
//
// ## `SmartKeyboard` Use Strategy
//
// We just want a blank screen where the position of the different fingers on
// the screen can be tracked and retrieved in the Faust object. For that, we
// create one keyboard with one key, that should fill the screen. We ask the
// interface to not compute the `freq` and `bend` parameters to save
// computation by setting `'Keyboard 0 - Send Freq':'0'`. We don't want the
// color of the key to change when it is touched so we deactivate the
// `Piano Keyboard` mode. Fingers should be numbered to be able to use the
// numbered `x` and `y` parameters (`x0`, `y0`, `x1`, etc.), so `Count Fingers`
// is enabled. Finally, by setting `Max Keyboard Polyphony` to 0, we deactivate
// the voice allocation system and we automatically start a voice when the app
// is launched. This means that fingers are no longer associated to specific voices.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] toy.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017:
// https://ccrma.stanford.edu/~rmichon
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

// X/Y interface: one keyboard with one key
// freq and bend are not computed
// fingers are counted
// voice is launched on startup
declare interface "SmartKeyboard{
    'Number of Keyboards':'1',
    'Max Keyboard Polyphony':'0',
    'Keyboard 0 - Number of Keys':'1',
    'Keyboard 0 - Send Freq':'0',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 0 - Send Numbered X':'1',
    'Keyboard 0 - Send Numbered Y':'1'
}";

import("stdfaust.lib");

// parameters
x0 = hslider("x0",0.5,0,1,0.01) : si.smoo;
y0 = hslider("y0",0.5,0,1,0.01) : si.smoo;
y1 = hslider("y1",0,0,1,0.01) : si.smoo;
q = hslider("q[acc: 0 0 -10 0 10]",30,10,50,0.01) : si.smoo;
del = hslider("del[acc: 0 0 -10 0 10]",0.5,0.01,1,0.01) : si.smoo;
fb = hslider("fb[acc: 1 0 -10 0 10]",0.5,0,1,0.01) : si.smoo;

// mapping
impFreq = 2 + x0*20;
resFreq = y0*3000+300;

// simple echo effect
echo = +~(de.delay(65536,del*ma.SR)*fb);

// putting it together
process = os.lf_imptrain(impFreq) : fi.resonlp(resFreq,q,1) : echo : ef.cubicnl(y1,0)*0.95 <: _,_;

trumpet

//################################### trumpet.dsp #####################################
// A simple trumpet app... (for large screens).
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp trumpet.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

import("stdfaust.lib");

declare interface "SmartKeyboard{
    'Number of Keyboards':'5',
    'Max Keyboard Polyphony':'1',
    'Mono Mode':'1',
    'Keyboard 0 - Number of Keys':'13',
    'Keyboard 1 - Number of Keys':'13',
    'Keyboard 2 - Number of Keys':'13',
    'Keyboard 3 - Number of Keys':'13',
    'Keyboard 4 - Number of Keys':'13',
    'Keyboard 0 - Lowest Key':'77',
    'Keyboard 1 - Lowest Key':'72',
    'Keyboard 2 - Lowest Key':'67',
    'Keyboard 3 - Lowest Key':'62',
    'Keyboard 4 - Lowest Key':'57',
    'Rounding Mode':'2',
    'Keyboard 0 - Send Y':'1',
    'Keyboard 1 - Send Y':'1',
    'Keyboard 2 - Send Y':'1',
    'Keyboard 3 - Send Y':'1',
    'Keyboard 4 - Send Y':'1',
}";

// standard parameters
f = hslider("freq",300,50,2000,0.01);
bend = hslider("bend[midi:pitchwheel]",1,0,10,0.01) : si.polySmooth(gate,0.999,1);
gain = hslider("gain",1,0,1,0.01);
s = hslider("sustain[midi:ctrl 64]",0,0,1,1); // for sustain pedal
t = button("gate");
y = hslider("y[midi:ctrl 1]",1,0,1,0.001) : si.smoo;

// fomating parameters
gate = t+s : min(1);
freq = f*bend;
cutoff = y*4000+50;
envelope = gate*gain : si.smoo;

process = os.sawtooth(freq)*envelope : fi.lowpass(3,cutoff) <: _,_;

turenas

//################################### turenas.dsp ########################################
// A simple smart phone percussion based on an additive synthesizer.
//
// ## `SmartKeyboard` Use Strategy
//
// Since the sounds generated by this synth are very short, the strategy here is to take
// advantage of the polyphony capabilities of the iOSKeyboard architecture by creating
// a new voice every time a new key is pressed. Since the `SmartKeyboard` interface has a
// large number of keys here (180), lots of sounds are generated when sliding a
// finger across the keyboard.
//
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] turenas.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

declare name "turenas";

import("stdfaust.lib");

//========================= Smart Keyboard Configuration =================================
// (10 keyboards with 18 keys each configured as a pitch matrix.
//========================================================================================

declare interface "SmartKeyboard{
    'Number of Keyboards':'10',
    'Keyboard 0 - Number of Keys':'18',
    'Keyboard 1 - Number of Keys':'18',
    'Keyboard 2 - Number of Keys':'18',
    'Keyboard 3 - Number of Keys':'18',
    'Keyboard 4 - Number of Keys':'18',
    'Keyboard 5 - Number of Keys':'18',
    'Keyboard 6 - Number of Keys':'18',
    'Keyboard 7 - Number of Keys':'18',
    'Keyboard 8 - Number of Keys':'18',
    'Keyboard 9 - Number of Keys':'18',
    'Keyboard 0 - Lowest Key':'50',
    'Keyboard 1 - Lowest Key':'55',
    'Keyboard 2 - Lowest Key':'60',
    'Keyboard 3 - Lowest Key':'65',
    'Keyboard 4 - Lowest Key':'70',
    'Keyboard 5 - Lowest Key':'75',
    'Keyboard 6 - Lowest Key':'80',
    'Keyboard 7 - Lowest Key':'85',
    'Keyboard 8 - Lowest Key':'90',
    'Keyboard 9 - Lowest Key':'95',
    'Keyboard 0 - Piano Keyboard':'0',
    'Keyboard 1 - Piano Keyboard':'0',
    'Keyboard 2 - Piano Keyboard':'0',
    'Keyboard 3 - Piano Keyboard':'0',
    'Keyboard 4 - Piano Keyboard':'0',
    'Keyboard 5 - Piano Keyboard':'0',
    'Keyboard 6 - Piano Keyboard':'0',
    'Keyboard 7 - Piano Keyboard':'0',
    'Keyboard 8 - Piano Keyboard':'0',
    'Keyboard 9 - Piano Keyboard':'0',
    'Keyboard 0 - Send X':'0',
    'Keyboard 1 - Send X':'0',
    'Keyboard 2 - Send X':'0',
    'Keyboard 3 - Send X':'0',
    'Keyboard 4 - Send X':'0',
    'Keyboard 5 - Send X':'0',
    'Keyboard 6 - Send X':'0',
    'Keyboard 7 - Send X':'0',
    'Keyboard 8 - Send X':'0',
    'Keyboard 9 - Send X':'0'
}";

//================================ Instrument Parameters =================================
// Creates the connection between the synth and the mobile device
//========================================================================================

// SmartKeyboard Y parameter
y = hslider("y",0,0,1,0.01);
// Smart Keyboard frequency parameter
freq = hslider("freq",400,50,2000,0.01);
// SmartKeyboard gate parameter
gate = button("gate");
// mode resonance duration is controlled with the x axis of the accelerometer
res = hslider("res[acc: 0 0 -10 0 10]",2.5,0.01,5,0.01);

//=================================== Parameters Mapping =================================
//========================================================================================

// number of modes
nModes = 6;
// distance between each mode
maxModeSpread = 5;
modeSpread = y*maxModeSpread;
// computing modes frequency ratio
modeFreqRatios = par(i,nModes,1+(i+1)/nModes*modeSpread);
// computing modes gain
minModeGain = 0.3;
modeGains = par(i,nModes,1-(i+1)/(nModes*minModeGain));
// smoothed mode resonance
modeRes = res : si.smoo;

//============================================ DSP =======================================
//========================================================================================

process = sy.additiveDrum(freq,modeFreqRatios,modeGains,0.8,0.001,modeRes,gate)*0.05;

violin2

//############################### violin2.dsp ##################################
// Faust instrument specifically designed for `faust2smartkeyb` where a
// complete violin physical model can be played using the touch sceen
// interface. Bowing is carried out by constantly moving a finger on the
// y axis of a key.
//
// ## `SmartKeyboard` Use Strategy
//
// 4 keyboards are used to control the pitch of the 4 bowed strings. Strings
// are connected to the virtual bow when they are touched.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets.
// However it was specifically designed to be used with `faust2smartkeyb`. For
// best results, we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp violin.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Aug. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//##############################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'4',
    'Max Keyboard Polyphony':'0',
    'Rounding Mode':'2',
    'Send Fingers Count':'1',
    'Keyboard 0 - Number of Keys':'12',
    'Keyboard 1 - Number of Keys':'12',
    'Keyboard 2 - Number of Keys':'12',
    'Keyboard 3 - Number of Keys':'12',
    'Keyboard 0 - Lowest Key':'55',
    'Keyboard 1 - Lowest Key':'62',
    'Keyboard 2 - Lowest Key':'69',
    'Keyboard 3 - Lowest Key':'76',
    'Keyboard 0 - Send Keyboard Freq':'1',
    'Keyboard 1 - Send Keyboard Freq':'1',
    'Keyboard 2 - Send Keyboard Freq':'1',
    'Keyboard 3 - Send Keyboard Freq':'1',
    'Keyboard 0 - Send Y':'1',
    'Keyboard 1 - Send Y':'1',
    'Keyboard 2 - Send Y':'1',
    'Keyboard 3 - Send Y':'1'
}";

import("stdfaust.lib");

// SMARTKEYBOARD PARAMS
kbfreq(0) = hslider("kb0freq",220,20,10000,0.01);
kbbend(0) = hslider("kb0bend",1,0,10,0.01);
kbfreq(1) = hslider("kb1freq",330,20,10000,0.01);
kbbend(1) = hslider("kb1bend",1,0,10,0.01);
kbfreq(2) = hslider("kb2freq",440,20,10000,0.01);
kbbend(2) = hslider("kb2bend",1,0,10,0.01);
kbfreq(3) = hslider("kb3freq",550,20,10000,0.01);
kbbend(3) = hslider("kb3bend",1,0,10,0.01);
kbfingers(0) = hslider("kb0fingers",0,0,10,1) : int;
kbfingers(1) = hslider("kb1fingers",0,0,10,1) : int;
kbfingers(2) = hslider("kb2fingers",0,0,10,1) : int;
kbfingers(3) = hslider("kb3fingers",0,0,10,1) : int;
y = hslider("y",0,0,1,1) : si.smoo;

// MODEL PARAMETERS
// strings lengths
sl(i) = kbfreq(i)*kbbend(i) : pm.f2l : si.smoo;
// string active only if fingers are touching the keyboard
as(i) = kbfingers(i)>0;
// retrieving finger displacement on screen (dirt simple)
bowVel = y-y' : abs : *(3000) : min(1) : si.smoo;
// bow position is constant but could be ontrolled by an external interface
bowPos = 0.7;
bowPress = 0.5;

// ASSEMBLING MODELS
// essentially 4 parallel violin strings
model = par(i,4,pm.violinModel(sl(i),bowPress,bowVel*as(i),bowPos)) :> _;

process = model <: _,_;

violin

//############################### violin.dsp ###################################
// Faust instrument specifically designed for `faust2smartkeyb` where a
// complete violin physical model can be played using the touch sceen
// interface. While the 4 virtual strings can be bowed using a control
// surface on the screen, it could be easily substituted with an external
// interface.
//
// ## `SmartKeyboard` Use Strategy
//
// 4 keyboards are used to control the pitch of the 4 bowed strings. Strings
// are connected to the virtual bow when they are touched. A pad created from
// a keybaord with a single key can be used to control the bow velocity and
// pressure on the selected strings.
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets.
// However it was specifically designed to be used with `faust2smartkeyb`. For
// best results, we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] -effect reverb.dsp violin.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Aug. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//##############################################################################

declare interface "SmartKeyboard{
    'Number of Keyboards':'5',
    'Max Keyboard Polyphony':'0',
    'Rounding Mode':'2',
    'Send Fingers Count':'1',
    'Keyboard 0 - Number of Keys':'19',
    'Keyboard 1 - Number of Keys':'19',
    'Keyboard 2 - Number of Keys':'19',
    'Keyboard 3 - Number of Keys':'19',
    'Keyboard 4 - Number of Keys':'1',
    'Keyboard 0 - Lowest Key':'55',
    'Keyboard 1 - Lowest Key':'62',
    'Keyboard 2 - Lowest Key':'69',
    'Keyboard 3 - Lowest Key':'76',
    'Keyboard 0 - Send Keyboard Freq':'1',
    'Keyboard 1 - Send Keyboard Freq':'1',
    'Keyboard 2 - Send Keyboard Freq':'1',
    'Keyboard 3 - Send Keyboard Freq':'1',
    'Keyboard 4 - Send Freq':'0',
    'Keyboard 4 - Send Key X':'1',
    'Keyboard 4 - Send Key Y':'1',
    'Keyboard 4 - Key 0 - Label':'Bow',
    'Keyboard 4 - Static Mode':'1'
}";

import("stdfaust.lib");

// SMARTKEYBOARD PARAMS
kbfreq(0) = hslider("kb0freq",220,20,10000,0.01);
kbbend(0) = hslider("kb0bend",1,0,10,0.01);
kbfreq(1) = hslider("kb1freq",330,20,10000,0.01);
kbbend(1) = hslider("kb1bend",1,0,10,0.01);
kbfreq(2) = hslider("kb2freq",440,20,10000,0.01);
kbbend(2) = hslider("kb2bend",1,0,10,0.01);
kbfreq(3) = hslider("kb3freq",550,20,10000,0.01);
kbbend(3) = hslider("kb3bend",1,0,10,0.01);
kb4k0x = hslider("kb4k0x",0,0,1,1) : si.smoo;
kb4k0y = hslider("kb4k0y",0,0,1,1) : si.smoo;
kbfingers(0) = hslider("kb0fingers",0,0,10,1) : int;
kbfingers(1) = hslider("kb1fingers",0,0,10,1) : int;
kbfingers(2) = hslider("kb2fingers",0,0,10,1) : int;
kbfingers(3) = hslider("kb3fingers",0,0,10,1) : int;

// MODEL PARAMETERS
// strings lengths
sl(i) = kbfreq(i)*kbbend(i) : pm.f2l : si.smoo;
// string active only if fingers are touching the keyboard
as(i) = kbfingers(i)>0;
// bow pressure could also be controlled by an external parameter
bowPress = kb4k0y;
// retrieving finger displacement on screen (dirt simple)
bowVel = kb4k0x-kb4k0x' : abs : *(8000) : min(1) : si.smoo;
// bow position is constant but could be ontrolled by an external interface
bowPos = 0.7;

// ASSEMBLING MODELS
// essentially 4 parallel violin strings
model = par(i,4,pm.violinModel(sl(i),bowPress,bowVel*as(i),bowPos)) :> _;

process = model <: _,_;

vocal

//######################################## vocal.dsp #####################################
// A funny vocal synth app...
//
// ## Compilation Instructions
//
// This Faust code will compile fine with any of the standard Faust targets. However
// it was specifically designed to be used with `faust2smartkeyb`. For best results,
// we recommend to use the following parameters to compile it:
//
// ```
// faust2smartkeyb [-ios/-android] vocal.dsp
// ```
//
// ## Version/Licence
//
// Version 0.0, Feb. 2017
// Copyright Romain Michon CCRMA (Stanford University)/GRAME 2017
// MIT Licence: https://opensource.org/licenses/MIT
//########################################################################################

import("stdfaust.lib");

declare interface "SmartKeyboard{
    'Number of Keyboards':'1',
    'Max Keyboard Polyphony':'0',
    'Keyboard 0 - Number of Keys':'1',
    'Keyboard 0 - Send Freq':'0',
    'Keyboard 0 - Static Mode':'1',
    'Keyboard 0 - Send X':'1',
    'Keyboard 0 - Piano Keyboard':'0'
}";

// standard parameters
vowel = hslider("vowel[acc: 0 0 -10 0 10]",2,0,4,0.01) : si.smoo;
x = hslider("x",0.5,0,1,0.01) : si.smoo;
vibrato = hslider("vibrato[acc: 1 0 -10 0 10]",0.05,0,0.1,0.01);
gain = hslider("gain",0.25,0,1,0.01);

// fomating parameters
freq = x*200 + 50;
voiceFreq = freq*(os.osc(6)*vibrato+1);

process = pm.SFFormantModelBP(1,vowel,0,voiceFreq,gain) <: _,_;

spat

panpot

declare name        "panpot";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//-------------------------------------------------
// Stereo panpot
//-------------------------------------------------

panpot(x)   = sqrt(c)*x, sqrt(1-c)*x
            with {
                c=(nentry("[1]pan[style:knob]",0,-90,90,1)-90.0)/-180.0;
            };

process     = panpot;

spat

declare name        "spat";
declare version     "1.0";
declare author      "Grame";
declare license     "BSD";
declare copyright   "(c)GRAME 2006";

//==========================================================
//
//                      GMEM SPAT
//  implementation of L. Pottier Spatializer
//
//==========================================================

import("stdfaust.lib");

//------------------------------------------------------
// EXEMPLE : une entree mono spatialisee sur 8 sorties
//------------------------------------------------------

angle           = hslider("angle",    0.0, 0, 1, 0.01);
distance        = hslider("distance", 0.5, 0, 1, 0.01);

process         = vgroup("Spatializer 1x8", sp.spat(8, angle, distance));