Hello Stéphane and all,

here is the finalized code.
( Pickup paramter hidden, highpass removed, reverb replaced with
parameterless Dattorro default,
more clear parameter names and description, rearranged order of
convolution tabs and distortion
saves CPU, and a resonant EQ added for weak formants).

From my side it could now be added to the examples, or used and
altered in any way.

Gabriel



[code]

// Modulation synthesis with sparse convolution filter and distortions.
// -------------------------------------------------------------------
//
// A "3D" oscillator oscillating on x,y,z axis, with the radius of x,y
used as waveform,
// very similar and related to FM / AM.
//
// The y axis oscillation is set by MIDI pitch, x and z are detuned by
simple just tuned ratios.
// Feedback acts on the individual sine oscillations (giving a
sawtooth like waveform).
//
// Three weighted copies with time varying shifts are summed in a
lossy integrator
// (sparse convolution), followed by a peak resonance filter and shaped by
// an internal pick-up like distortion and an asymmetric polynomial.
//
// The convolution tabs give a (variyng) triangle impulse response if
integrated twice,
// with a -12 dB/octave rolloff and regular notches.
// Here only one integrator is used.
//
// The envelope is hard wired to the oscillation amplitudes and the
rise time of the filter.
//
// An LFO is wired to pitch.
//
// A resonant EQ and the Dattoro Reverb from the Faust libary are
added as effect on the sum.
//
//
// Inspired by the history of sound synthesis, namely Trautonium, Mini
Moog, Phase Modulation Synthesis,
// Variophon Wind Instrument Synthesizer, Physical Modeling, and the
work of Thomas D. Rossing.
//
// References:
// Kot, Vítězslav. (2006). DIGITAL SOUND EFFECTS ECHO AND REVERB BASED
ON NON EXPONENTIALLY DECAYING COMB FILTER.
// https://en.wikipedia.org/wiki/Variophon
// Parker, Julian & Zavalishin, Vadim & Le Bivic, Efflam. (2016).
Reducing The Aliasing Of Nonlinear Waveshaping Using Continuous-Time
Convolution.
// Nicholas G. Horton, Thomas R. Moore. (2008). Modelling The Magnetic
Pickup Of An Electric Guitar.
// https://www.musicdsp.org/en/latest/Effects/86-waveshaper-gloubi-boulga.html,
see comment from 2005-09-22 01:07:58
// Frei, Beat. Digital Sound Generation I & II, ICST Zurich University
of the Arts
// Smith, J.O. Physical Audio Signal
Processing,http://ccrma.stanford.edu/~jos/pasp/, online book, 2010
edition

declare options "[midi:on][nvoices:8]";
declare options "[-vec]";
declare name "Paradigma_9";
declare version "1.0";
declare author "gabriel";

import("stdfaust.lib");


// Frequency Ratios table
frtonum = waveform{1,16,9,6,5,4,7,3,8,5,7,15};
frtodiv = waveform{1,15,8,5,4,3,5,2,5,3,4, 8};

// MIDI
// minimum velocity
minvelo = 1 / 32;
midigrp(x) = hgroup("[1]MIDI",x);
f = nentry("freq[hidden:1]",200,40,2000,0.1);
kmidi = nentry("key[hidden:1]",69,0,127,1);
bend =  ba.semi2ratio(hslider("bend[hidden:1][midi:pitchwheel][style:
knob]",0,-2,2,0.01));
gain =   nentry("gain[hidden:1]",0.6,0,1,0.01)<:* : _*(1-minvelo):_+ minvelo;
master =  hslider("volume[midi:ctrl 7]",0.6,0,1,0.01);
gate =  button("gate[hidden:1]") ;

// Oscillator Parameter
rtogrp(x) = hgroup("[2]Oscillator",x);
rto1sel = rtogrp(hslider("[1]x[style:knob]",-12,-36,36,1));
rto2sel = rtogrp(hslider("[2]z[style:knob]",19,-36,36,1));
fbka = rtogrp(hslider("[3]Feedback[style:knob]",0.15,0,1,0.01)<:*:*(1/ma.PI));
detune = rtogrp(hslider("[4]Detune[style:knob]",0.125,0,0.5,0.005)/ma.SR);

// LFO and Envelope Parameter
lfogrp(x) = hgroup("[3]Envelope & LFO",x);
enva = (lfogrp(ba.db2linear(hslider("[1]A[style:knob]",20,15,66,1) )/1000));
envd = (lfogrp(ba.db2linear(hslider("[2]D[style:knob]",74,26,100,1)
)/1000)*envpscal);
envs = (lfogrp(hslider("[3]S[style:knob]",0,0,1,0.01) ));
envr = (lfogrp(ba.db2linear(hslider("[4]R[style:knob]",50,26,100,1)
)/1000)*envpscal);
lfof = lfogrp(hslider("[5]LFO Hz[style:knob]",3,0.1,12,0.1));
lfvibra = lfogrp(hslider("[6]Vibrato[style:knob]",0.125,0,1,0.01))<:*;

env = en.adsre(enva,envd*envpscal,envs,envr*envpscal,gate);
envg = env:_* gain;

lfosn = qsin(mphasor(lfof/ma.SR));

// Triangular Filter Parameter
fltgrp(x) = hgroup("[4]Filter",x);
wid = fltgrp(hslider("[1]Rise[style:knob]",3,1,9,0.001)):2^_:1/_;
edge = fltgrp(hslider("[2]Fall[style:knob]",6,1,9,0.001)):2^_:1/_;
fiq = fltgrp(hslider("[3]Q[style:knob]",1,0.5,3.87,0.01))<:*;
drive = fltgrp(hslider("[4]Drive[style:knob]",-12,-12,30,0.1)):_/20.0:10^_;

// Modulation Frequency Ratios
rto1oct = rto1sel / 12 : floor;
rto1semi = rto1sel + 36 : _% 12;
rto1a = frtonum, rto1semi : rdtable;
rto1b = frtodiv, rto1semi : rdtable;
rto1 = (rto1a/rto1b)*(2^rto1oct);
rto1r = min((1/ rto1),1);

rto2oct = rto2sel / 12 : floor;
rto2semi = rto2sel + 36 : _% 12;
rto2a = frtonum, rto2semi : rdtable;
rto2b = frtodiv, rto2semi : rdtable;
rto2 = rto1*(rto2a/rto2b)*(2^rto2oct);
rto2r  = min((1 / rto2),1);

// Pitch
lg2f = ma.log2(f/440);
stretch = 0.0333*lg2f;
envpscal = ( - 3 * lg2f ):ba.db2linear;
fplus = f*bend + lfosn* lfvibra*f * 0.5/12*envg + stretch;

w = f/ma.SR;
w2 = rto1 * w;
w3 = rto2 * w;
wplus = fplus/ma.SR;

fbk1 = fbka*(0.5 -w)^4;
fbk2 = fbka*(0.5 - w2)^4*rto1r;
fbk3 = fbka*(0.5 - w3)^4*rto2r;

// Modulation Reduction Per Frequency
redux1 = ((3.3 -((rto1+1)*w) )/3.3),0: max:_^3;
redux2 = ((3.3 -((rto2+1)*w) )/3.3),0: max:_^3;
modep = envg;
modep1 =  envg * redux1 *rto1r * gain ;
modep2 =  envg * redux2 *rto2r * gain ;

// Sine Oscillator
wrap(n) = n-( floor( n +0.5)) ;
// Bhaskara I based approximate sine curve
qsincurve(x) = 1 - ( (x*x)<: *(1.2253517*16),(_<:*:* (-3.60562732*16)):>_ );
qsin(x) = x+(0.5): wrap <: (abs:-(0.25):qsincurve),_:ma.copysign;
// Feedback Depth Reduction Curve
fbcurve (x)= x:abs:-(1) <:^(3):_,(x):ma.copysign;

// Oscillator
mphasor(fw) = (+(fw) ~ (wrap));
oscsn(fw, off) = mphasor(fw) + off:qsin:+~*(0.5);
osc1(fw, off) = ((fw),+(off):(oscsn)) ~ (*(fbk2):fi.pole(0.5):_*fbcurve(fw));

// 3D to 2D radius
oscy(fw, off) = (osc1(fw, off )*osc1(fw*rto2+2*detune,0.75 + off)*modep2)*modep;
oscx(fw, off) = (osc1(fw*rto1+detune,0.25 +
off)*osc1(fw*rto2+2*detune,0.25 + off)*modep2)*modep1;
oscxy(fw, off) = (oscy(fw, off)<:*),(oscx(fw, off)<:*):+:sqrt;

// Pick-Up like Distortion
// distance :
pickd = 0.25;
pickup(x, pickd) = x,
                // normal for in < 1.2e-4
                ( x,(x^2:_+pickd:_^(3/2)):/ ),
                // ILO:
                ( pickd^(3/2) / ( sqrt(x*x + 1)):ma.neg:_+ pickd^(3/2) ):
                // select
                ba.if( (_:abs:_<= 1.2e-4), _, _ ):_*(pickd^(4/3));

// Basic Synthvoice, modulated Oscillations
synthvox(fw, ph2, ph3, g1, g2, g3) = (oscxy(fw, 0):_*g1), (oscxy(fw,
ph2):_*g2),(oscxy(fw, ph3):_*g3):>_ : fi.zero(1.0)<:_,(pickd):pickup;


// Triangle
// reduce width with frequency
widredux = w <:+:_^3:1.0-_;
// diff to max f in octaves, reduced for higher octaves
dwo =  (  0.25 / wid  ):max(_, 1): ma.log2: ma.inv: _*widredux: ma.inv;
// falling edge
egderto = edge / wid;
wid2 =  wid * (2^(dwo * (1-envg ))):
        _* (2^(dwo * (1- gain ) )):
        min( _,  0.25): max( _, 4 / (ma.SR/fplus));
wid2e = edge: min( _, 0.25): max( _, 4 /(ma.SR/fplus));

fiw = wplus/wid2;
fiwtail = wplus/wid2e;
// triangle coefficients
apg0 = fiw;
apg1 = - apg0 - fiwtail;
apg2 = fiwtail;
// integration freq
igpole = 1.0-5.0/ma.SR;
resf = (fplus /( wid2 +wid2e) ): min( _, (0.249 * ma.SR));

// Asymmetric Shaper x - 0.15x²-0.15x³
tubicclip = _:min(_, (1.19419)):max(_,(-1.86086));
tubicilo(x) = x,
                // normal for in < 1.2e-4
                ( x - 0.15*(x^2)-0.15*(x^3) ),
                // ILO:
                (( 0.5*(x^2) - 0.05*(x^3) - 0.0375*(x^4) ),(x <:_,_':-
:_<:(abs:max(_,1.2e-4)),(ma.signum):ma.copysign):/):
                // select
                ba.if( (_:abs:_<= 1.2e-4), _, _ ):fi.dcblockerat(10.0);


// Sound
process = synthvox(wplus, wid2, wid2e, apg0, apg1, apg2):
fi.dcblockerat(10.0): fi.pole(igpole) : fi.svf.peak( resf, fiq) :
            _*drive: tubicclip: tubicilo:_*(1/drive);
effect = _ * master:preeq( lsf,lsgain, b1f, eqq2, eqg2, b2f, eqq3,
eqg3, hsf, hsgain) <:_,_:re.dattorro_rev_default;



// 
---------------------------------------------------------------------------------------------------------------
// Resonant EQ for instrument corpus, based on SVF
eqgrp(x) = hgroup("[5]EQ",x);
lsgain = eqgrp(hslider("[1]Low Gain[style:knob]",3,-18,18,0.25));
b1f = eqgrp(hslider("[2]Split F Low[style:knob]",-0.5,-1,1,0.05))
:(2.0)^_:_*360;
b1gain = eqgrp(hslider("[3]Band 1 Gain[style:knob]",4.5,-18,18,0.25));
b2f = eqgrp(hslider("[4]Split F Hi[style:knob]",-0.5,-1,1,0.05)):(2.0)^_:_*720;
b2gain = eqgrp(hslider("[5]Band 2 Gain[style:knob]",4.5,-18,18,0.25));
hsgain = eqgrp(hslider("[6]Hi Gain[style:knob]",-3,-18,18,0.25));

// Q and gain of middle bands are scaled simultanously, with
saturation curve on gain,
// max gain is reduced from the output. Bands are spaced in octaves by default.
lsf = b1f *0.5;
hsf = b2f * 2;
gcurve( gain, gainrange) = abs(gain/gainrange) <:*:1-_:_+1:_*0.5;
qscal( gain, gainrange) = 1.414 * ( abs(gain/ gainrange)) :_+ 1.414;
eqq2 = qscal( b1gain, 18.0);
eqg2 = b1gain * gcurve( b1gain, 18.0);
eqq3 = qscal( b2gain, 18.0);
eqg3 = b2gain * gcurve( b2gain, 18.0);
eqredux = max( lsgain, eqg2):max(_, eqg3):max(_,hsgain):ba.db2linear: ma.inv;

preeq( f1,g1,f2,q2,g2,f3,q3,g3,f4,g4) = _*eqredux:fi.svf.bell( f1,
1.414, g1):fi.svf.bell( f2, q2, g2): fi.svf.bell( f3, q3,
g3):fi.svf.hs( f4, 1.414, g4);

[/code]


On Thu, Sep 11, 2025 at 3:25 PM ga <gvoxangel...@gmail.com> wrote:
>
> Thanks, this would be a great solution.
>
> Meanwhile I collected the references for the relevant parts (below, if 
> someone is interested ).
> The unfinished reverb will be omitted for simplicity and clarity, pickup 
> replaced.
> I will take some time for the changes, if someone finds a part in the code 
> the should be either more concise or
> more verbose, or a msitake, let me know.
> I also realized that I rewrote some things that seem to have equivalents in 
> the library, I will most likely replace them.
>
> Gabriel
>
> // Modulation synthesis with sparse convolution filter and distortions.
> // ====================================================================
> //
> // A "3D" oscillator oscillating on x,y,z axis, with the radius of x,y going
> // into a hyperbolic distortion.
> //
> // The y axis oscillation is set by MIDI pitch, x and z are detuned by simple 
> just tuned ratios.
> // Feedback acts on the individual sine oscillations.
> //
> //
> // Three weighted copies with time varying shifts are summed in a lossy 
> integrator
> // ( sparse convolution ), followed by a peak filter and shaped by an 
> asymmetric polynomial.
> //
> // The convolution tabs would give a (variyng) triangle impulse response if 
> integrated twice,
> // with a -12 dB/octave rolloff and varying regular notches.
> // Here only one integrator is used.
> //
> //
> // The envelope is hard wired to the oscillation amplitudes and the rise time 
> of the filter.
> //
> // An LFO is wired to pitch.
> //
> //
> // Inspired by the history of sound synthesis, namely Trautonium, Mini Moog, 
> Phase Modulation Synthesis,
> // Variophon Wind Instrument Synthesizer, Physical Modeling, and the work of 
> Thams D. Rossing.
> //
> // References:
> // Kot, Vítězslav. (2006). DIGITAL SOUND EFFECTS ECHO AND REVERB BASED ON NON 
> EXPONENTIALLY DECAYING COMB FILTER.
> // https://en.wikipedia.org/wiki/Variophon
> // Parker, Julian & Zavalishin, Vadim & Le Bivic, Efflam. (2016). Reducing 
> The Aliasing Of Nonlinear Waveshaping Using Continuous-Time Convolution.
> // Nicholas G. Horton, Thomas R. Moore. (2008). Modelling The Magnetic Pickup 
> Of An Electric Guitar.
> // 
> https://www.musicdsp.org/en/latest/Effects/86-waveshaper-gloubi-boulga.html, 
> see comment from 2005-09-22 01:07:58
> // Frei, Beat. Digital Sound Generation I & II, ICST Zurich University of the 
> Arts
> // Smith, J.O. Physical Audio Signal 
> Processing,http://ccrma.stanford.edu/~jos/pasp/, online book, 2010 edition
>
> On Thu, Sep 11, 2025 at 10:57 AM Stéphane Letz <l...@grame.fr> wrote:
>>
>> Hi Gabriel,
>>
>> I suggest we do it simple for now. If you can cleanup and document the DSP 
>> code, then I can put in the examples/misc section: 
>> https://faustdoc.grame.fr/examples/#misc
>>
>> Thanks.
>>
>> Stéphane
>>
>>
>> > Le 10 sept. 2025 à 18:43, ga <gvoxangel...@gmail.com> a écrit :
>> >
>> > Thanks
>> >
>> > I will look into installing Faust locally, I am bit deterred by the vast 
>> > amount of dependencies
>> > and my little experience with installing such projects.
>> >
>> > I also don't have much experience with make and compiling and C,
>> > but I think faust2rpialsaconsole might be onther option I have to look into
>> > as running it on a Pi seems a reasonable solution for hardware.
>> > I do have a Pi 400, on which unfortunately the Patch OS which might be a
>> > good choice for OS does not run (or I didnt get it to run ).
>> >
>> > to 4)
>> > The code and concept is public and libre from my side, but maybe licenses 
>> > of third parties have to be considered.
>> >
>> > So I reused and altered code from the Faust library ( by Julius Smith I 
>> > think ) for the allpass delay,
>> > and the idea for the triangular filter was originally inspired by the 
>> > historic Variophon triangular oscillator, etc.
>> > so at least a proper note with history and references would be desireable.
>> > Since the concept has a really long history with many sources and 
>> > variants, and is floating on my desk since years,
>> > it's a bit difficult to be accurate in this regards, and to do this 
>> > justice.
>> >
>> > The code also still needs some minor tweaks and cosmetic changes before it 
>> > is released in a 'final' version.
>> > For instance it uses two SVFs in series at the moment with very similar 
>> > corner frequencies,
>> > which could probably be replaced by a single SVF with a 'morphing' output.
>> >
>> > A previous version had roughly antialiased synched noise (windowed with a 
>> > quarter sine wave) in a addition to the osciallator,
>> > to mimick a corpus impulse response, and to enhance piano and string 
>> > reminiscent sounds.
>> >
>> > I now tried to replace this with short allpass delays but it sounds less 
>> > convincing and "boxed", and setting
>> > the length of the allpass chain is also too arbitrary att the moment.
>> >
>> > Also noise has the interesting property that it has fluctuations, so a 
>> > seed could be matched
>> > to produce a sequence that resembles the derivative (or 2nd derivative) of 
>> > a real corpus impulse response.
>> >
>> > I would like to keep the paramter set to 4 though, as the idea for a 
>> > hardware interface is to have
>> > two rows with 4 push and turn encoders each, one row for synth and one for 
>> > EQ and other effects,
>> > with each encoder serving also as a button to select a set of 4 parameters 
>> > that belong together, like ADSR.
>> > ( sketch : 
>> > https://assets.steadyhq.com/production/post/c0d7b8ae-4d1f-4afa-afe8-8bcce17883ac/uploads/images/5prochhxdb/UI.jpg?auto=compress&w=800&fit=max&dpr=2&fm=webp)
>> >
>> > (Pressing two encoders in the corners simultanously could be used for 
>> > saveing and laoding presets.)
>> >
>> > This is one reason why the noise was omitted in this version.
>> >
>> > Such a controller should be seperate from the computing hardware and be 
>> > useful for many things,
>> > and could be easy to build from two I²C breakout boards from Adafruit,
>> > but I do not have the tools and funds for this at the moment, and it 
>> > requires
>> > additional code for interfacing, which I do not have experience with.
>> >
>> > The idea defintively is to make it an all open source and somewhat 
>> > flexible synth concept.
>> >
>> > An interesting aspect for me is that it touches and fuses many aspects of 
>> > the history of synthesis,
>> > and synthesis approaches, starting with the Trautonium, modulation 
>> > synthesis, subtractive,
>> > aspects and findings of physical modeling, etc, in a very compact but 
>> > meaningful parameter set and combination.
>> > ( less paramter than a Mini Moog I think, from which it also borroughs of 
>> > course).
>> >
>> > By this it is also a good simplified model to learn and teach I think, for 
>> > instance you could
>> > examine what makes a sound "pianoide" and then expand on this with real 
>> > pianos and real accurate modeling
>> > of real phyiscal forces etc., and then again examine their perceptual 
>> > significance and compare to this "cartoon"
>> > version, and many similar things.
>> >
>> > I dont know whats the best way to publish this so others can contribute 
>> > and expand on this.
>> > Maintaining and ovreseeing a project on Sourceforge or similar requires a 
>> > lot of work and energy and experience
>> > which I do not have.
>> > So I am also looking for interested people I can hand this idea over,
>> > Including it with Faust examples would be interesting in this regards,  
>> > but I am not sure it is fundamental and also simple enough for this, etc.
>> >
>> > Gabriel
>> >
>> >
>> >
>> >
>> > On Wed, Sep 10, 2025 at 3:14 PM Stéphane Letz <l...@grame.fr> wrote:
>> > Hi,
>> >
>> > Thanks for this interesting code. For exporting the code, you have several 
>> > options:
>> >
>> > 1) exporting the DSP for a standard plugin format.
>> >
>> >         - you can possibly use the JUCE export for that, as an 
>> > intermediate step: 
>> > https://github.com/grame-cncm/faust/tree/master-dev/architecture/juce. For 
>> > maximal flexibility the best would be to compile and install a local Faust 
>> > version.
>> >
>> >         - another option is to use the Fadeli project 
>> > https://github.com/DISTRHO/Fadeli
>> >
>> > 2) you may find more info on this page 
>> > https://faust.grame.fr/community/powered-by-faust
>> >
>> > 3) you can connect to the Faust developer/user community on Discord 
>> > channel, see https://faust.grame.fr/community/help/
>> >
>> > 4) You wrote « I am proposing the attached synthesis engine. » : Is the 
>> > code public ? Are you interested to contribute it in the Faust examples: 
>> > https://faustdoc.grame.fr/examples/
>> >
>> > Thanks.
>> >
>> > Stéphane
>> >
>> >
>> > > Le 4 sept. 2025 à 11:53, ga <gvoxangel...@gmail.com> a écrit :
>> > >
>> > > Hello
>> > > I am proposing the attached synthesis engine.
>> > > It uses a "3D" oscillator that oscillates in x,y, z ( similar to FM / AM)
>> > > The radius of x,y is fed into a pickup distortion, which goes into a 
>> > > triangular filter ( 3 phase offset copies going into an integrator) an 
>> > > asymmetric distortion.
>> > > It has only 4× 4 parameter, including classic ADSR and LFO, envelope 
>> > > hardwired to oscillation amplitudes.
>> > > Its capable of a variety of semi- realistic sounds.
>> > > Sound demo is here:
>> > > https://youtu.be/7CBhMcYDWac?feature=shared
>> > >
>> > >
>> > > I would need some help to streamline the code mor Faustian,
>> > > to export including GUI, and to export including the effect,
>> > > and maybe ideas how to port this to some small hardware, Pi or Daisy Pod 
>> > > ( though I doubt it will run there ). as well as opinion on the method 
>> > > and ideas.
>> > >
>> > > Code:
>> > >
>> > > declare options "[midi:on][nvoices:8]";
>> > > declare options "[-vec]";
>> > > declare name "Paradigma_9 v007";
>> > > declare version "0.0.7";
>> > > declare author "gabriel";
>> > > declare copyright "https://steady.page/en/voxangelica/";;
>> > > declare license "DWTW";
>> > > // a synthesizer with "philonic" 3D spin oscillator and triangular filter
>> > > import("stdfaust.lib");
>> > > import("maths.lib");
>> > >
>> > > // frequency ratios table
>> > > frtonum = waveform{1,16,9,6,5,4,7,3,8,5,7,15};
>> > > frtodiv = waveform{1,15,8,5,4,3,5,2,5,3,4, 8};
>> > >
>> > > // MIDI
>> > > midigrp(x) = hgroup("[1]MIDI",x);
>> > > f = nentry("freq",200,40,2000,0.1) ;
>> > > kmidi = nentry("key",69,0,127,1) ;
>> > > bend = ba.semi2ratio(hslider("bend[midi:pitchwheel][style: 
>> > > knob]",0,-2,2,0.01)) ;
>> > > gain = nentry("gain",0.6,0,1,0.01)<:* ;
>> > > master = hslider("volume[midi:ctrl 7]",1,0,2,0.01) ;
>> > > gate = button("gate") ;
>> > >
>> > > // spin oscill params
>> > > rtogrp(x) = hgroup("[2]philonic",x);
>> > > rto1sel = rtogrp(hslider("[1]x[style:knob]",-12,-24,24,1));
>> > > rto2sel = rtogrp(hslider("[2]z[style:knob]",19,-24,24,1));
>> > > fbka = 
>> > > rtogrp(hslider("[3]excentric[style:knob]",0.4,0,1,0.01)<:*:*(1/ma.PI));
>> > > detune = 
>> > > rtogrp(hslider("[4]warble[style:knob]",0.125,0,0.5,0.005)/ma.SR);
>> > > pickd = 
>> > > rtogrp(hslider("[5]distance[style:knob]",0.7,0.25,1,0.0625))<:*:si.smoo;
>> > >
>> > > // LFO and Envelope Parameter
>> > > lfogrp(x) = hgroup("[3]envelope & lfo",x);
>> > > enva = (lfogrp(ba.db2linear(hslider("[1]A[style:knob]",20,15,66,1) 
>> > > )/1000));
>> > > envd = (lfogrp(ba.db2linear(hslider("[2]D[style:knob]",74,26,100,1) 
>> > > )/1000)*envpscal);
>> > > envs = (lfogrp(hslider("[3]S[style:knob]",0,0,1,0.01) ));
>> > > envr = (lfogrp(ba.db2linear(hslider("[4]R[style:knob]",50,26,100,1) 
>> > > )/1000)*envpscal);
>> > > lfof = lfogrp(hslider("[5]LFO Hz[style:knob]",3,0.1,12,0.1));
>> > > lfvibra = lfogrp(hslider("[6]Vibrato[style:knob]",0.125,0,2,0.01))<:*;
>> > >
>> > > env = en.adsre(enva,envd*envpscal,envs,envr*envpscal,gate);
>> > > envg = env:_* gain;
>> > >
>> > > lfosn = qsin(mphasor(lfof/ma.SR));
>> > >
>> > > // Triangular Filter Parameter
>> > > fltgrp(x) = hgroup("[4]triangulation",x);
>> > > wid = fltgrp(hslider("[1]rise[style:knob]",4.89,1,9,0.001)):2^_:1/_;
>> > > edge = fltgrp(hslider("[2]fall[style:knob]",6,1,9,0.001)):2^_:1/_;
>> > > fiq = fltgrp(hslider("[3]q[style:knob]",1.18,0.5,3.87,0.01))<:*;
>> > > hpon = fltgrp(checkbox("[4]highpass"));
>> > > drive = fltgrp(hslider("[5]drive[style:knob]",0,-6,36,0.1)):_/20.0:10^_;
>> > >
>> > > rto1oct = rto1sel / 12 : floor;
>> > > rto1semi = rto1sel + 24 : _% 12;
>> > > rto1a = frtonum, rto1semi : rdtable;
>> > > rto1b = frtodiv, rto1semi : rdtable;
>> > > rto1 = (rto1a/rto1b)*(2^rto1oct);
>> > > rto1r = min((1/ rto1),1);
>> > >
>> > > rto2oct = rto2sel / 12 : floor;
>> > > rto2semi = rto2sel + 24 : _% 12;
>> > > rto2a = frtonum, rto2semi : rdtable;
>> > > rto2b = frtodiv, rto2semi : rdtable;
>> > > rto2 = rto1*(rto2a/rto2b)*(2^rto2oct);
>> > > rto2r = min((1 / rto2),1);
>> > >
>> > > // fve
>> > > lg2f = ma.log2(f/440);
>> > > stretch = 0.0333*lg2f;
>> > > envpscal = ( - 3 * lg2f ):ba.db2linear;
>> > > fplus = f*bend + lfosn* lfvibra*f * 0.5/12*envg + stretch;
>> > >
>> > > w = f/ma.SR;
>> > > w2 = rto1 * w;
>> > > w3 = rto2 * w;
>> > > wplus = fplus/ma.SR;
>> > >
>> > > fbk1 = fbka*(0.5 -w)^4;
>> > > fbk2 = fbka*(0.5 - w2)^4*rto1r;
>> > > fbk3 = fbka*(0.5 - w3)^4*rto2r;
>> > >
>> > > // modulation reduction per frequency
>> > > redux1 = ((3.3 -((rto1+1)*w) )/3.3),0: max:_^3;
>> > > redux2 = ((3.3 -((rto2+1)*w) )/3.3),0: max:_^3;
>> > > modep = envg;
>> > > modep1 = envg * redux1 *rto1r * gain ;
>> > > modep2 = envg * redux2 *rto2r * gain ;
>> > >
>> > > // sine oscillator
>> > > wrap(n) = n-( floor( n +0.5)) ;
>> > > qsincurve(x) = 1 - ( (x*x)<: *(1.2253517*16),(_<:*:* 
>> > > (-3.60562732*16)):>_ );
>> > > qsin(x) = x+(0.5): wrap <: (abs:-(0.25):qsincurve),_:ma.copysign;
>> > > // feedback depth reduction curve
>> > > fbcurve (x)= x:abs:-(1) <:^(3):_,(x):ma.copysign;
>> > >
>> > > // oscillator
>> > > mphasor(fw) = (+(fw) ~ (wrap));
>> > > oscsn(fw, off) = mphasor(fw) + off:qsin:+~*(0.5);
>> > > osc1(fw, off) = ((fw),+(off):(oscsn)) ~ 
>> > > (*(fbk2):fi.pole(0.5):_*fbcurve(fw));
>> > > dcrem(x) = x <:_,_': -: +~*(0.999773243);
>> > >
>> > > // 3D
>> > > oscy(fw, off) = (osc1(fw, off )*osc1(fw*rto2+2*detune,0.75 + 
>> > > off)*modep2)*modep;
>> > > oscx(fw, off) = (osc1(fw*rto1+detune,0.25 + 
>> > > off)*osc1(fw*rto2+2*detune,0.25 + off)*modep2)*modep1;
>> > > oscxy(fw, off) = (oscy(fw, off)<:*),(oscx(fw, off)<:*):+:sqrt: 
>> > > fi.zero(1.0);//dcrem; //
>> > > //oscxyb(fw, off) = (oscy(fw, off):fi.zero(1)) <:_,(_^2),((oscx(fw, 
>> > > off):fi.zero(1):_^2)): _, (_+_):_,(_+0.1:_^(3/2)):_/_;
>> > > // with pickup
>> > > oscxyc(fw, off) = oscxy(fw, off) <:_,(_^2:_+pickd:_^(3/2)):/;
>> > > //
>> > > //synthvox(fw, ph2, ph3, g1, g2, g3) = (oscxy(fw, 0):_*g1), (oscxy(fw, 
>> > > ph2):_*g2),(oscxy(fw, ph3):_*g3):>_ ;
>> > > synthvox(fw, ph2, ph3, g1, g2, g3) = (oscxyc(fw, 0):_*g1), (oscxyc(fw, 
>> > > ph2):_*g2),(oscxyc(fw, ph3):_*g3):>_ ;
>> > > // triangulation
>> > > widredux = w <:+:_^3:1.0-_;
>> > > // diff to max f in octaves, reduced for higher octaves
>> > > dwo = ( 0.25 / wid ):max(_, 1): ma.log2: ma.inv: _*widredux: ma.inv;
>> > > //edge = 1/7; // falling triangle edge,
>> > > egderto = edge / wid;
>> > > wid2 = wid * (2^(dwo * (1-envg ))):
>> > >         _* (2^(dwo * (1- gain ) )):
>> > >         min( _, 0.25): max( _, 4 / (ma.SR/fplus));
>> > > wid2e = edge: min( _, 0.25): max( _, 4 /(ma.SR/fplus));
>> > >
>> > > fiw = wplus/wid2;
>> > > fiwtail = wplus/wid2e;
>> > > // triangle coefficients
>> > > apg0 = fiw;
>> > > apg1 = - apg0 - fiwtail;
>> > > apg2 = fiwtail;
>> > > // integration freq
>> > > igpole = 1.0-5.0/ma.SR;
>> > > resf = (fplus /( wid2 +wid2e) ): min( _, (0.249 * ma.SR));
>> > >
>> > > // shaper
>> > > // x - 0.15x²-0.15x³
>> > > tubicclip = _:min(_, (1.19419)):max(_,(-1.86086));
>> > > //tubic(x) = x - 0.15*(x^2)-0.15*(x^3);
>> > > tubicilo(x) = x,
>> > >                 // normal for in < 1.2e-4
>> > >                 ( x - 0.15*(x^2)-0.15*(x^3) ),
>> > >                 // ILO:
>> > >                 (( 0.5*(x^2) - 0.05*(x^3) - 0.0375*(x^4) ),(x <:_,_':- 
>> > > :_<:(abs:max(_,1.2e-4)),(ma.signum):ma.copysign):/):
>> > >                 // select
>> > >                 ba.if( (_:abs:_<= 1.2e-4), _, _ ):dcrem;
>> > > //
>> > > superfbp = 1 - sin( 2 * ma.PI * w );
>> > >
>> > > // make sound
>> > > process = synthvox(wplus, wid2, wid2e, apg0, apg1, apg2): 
>> > > fi.dcblockerat(10.0): fi.pole(igpole) : fi.svf.peak( resf, fiq) <:
>> > >             ba.if( hpon, fi.svf.hp( fplus/(wid+wid):min(_, ma.SR*0.249), 
>> > > 0.707 ),_):
>> > >             _*drive: tubicclip: tubicilo:_*(1/drive);
>> > > effect = _ * master:rev;
>> > >
>> > > // 
>> > > ###############################################################################################
>> > > // CIELverb 
>> > > ######################################################################################
>> > > // minimalist reverb
>> > > //
>> > > // UI
>> > > revgrp(x) = hgroup("[5]reverb",x);
>> > > sizem = 
>> > > revgrp(hslider("[1]size[style:knob]",0,-1.5,1.5,0.02)):(2.0)^_:_*16.7:si.smoo;
>> > > revt = revgrp(hslider("[2]revTime[style:knob]",60,40,80,0.1)): 
>> > > ba.db2linear:_*0.001;
>> > > bright = revgrp(hslider("[4]brightness[style:knob]",90,52,112,0.1)): 
>> > > ba.midikey2hz;
>> > > earlyl = revgrp(hslider("[5]early/late[style:knob]",0,0,1,0.01));
>> > > drywet = revgrp(hslider("[6]dry/wet[style:knob]",0.5,0,1,0.01)) <:*;
>> > >
>> > > // reverb settings
>> > > // change revt with size
>> > > revtadapt = revt * ( 0.161*(sizem^3)/(6*sizem^2 ));
>> > > // diffusion delay times
>> > > revd0 = ma.SR * (sizem / 334);
>> > > revd1 = revd0 * 1 / ( 2 - log(2));
>> > > revd2 = revd0 * 1 / ( 3 - log(2));
>> > > revd3 = revd0 * 1 / ( 4 - log(2));
>> > > revgn = 10^(-3*(( sizem/ 334 )/revtadapt));
>> > > // diffusion allpass coeficients
>> > > revc = 0.707;//0.61803; //
>> > > revc1 = -revc * 10^(-3*(( revd1/ ma.SR )/revtadapt));
>> > > revc2 = -revc * 10^(-3*(( revd2/ ma.SR )/revtadapt));
>> > > revc3 = -revc * 10^(-3*(( revd3/ ma.SR )/revtadapt));
>> > > // post (early)
>> > > revdp = revd3 * 1 / ( 4 - log(2));
>> > > postd1 = revdp * 1 / ( 2 - log(2));
>> > > postd2 = postd1 * 1 / ( 3 - log(2));
>> > > postd3 = postd2 * 1 / ( 4 - log(2));
>> > > postc = 0.382;//1/3;//0.61803; //
>> > > postc1 = -postc * 10^(-3*(( postd1/ ma.SR )/(revtadapt * 1 / ( 4 - 
>> > > log(2)))));
>> > > postc2 = -postc * 10^(-3*(( postd2/ ma.SR )/(revtadapt * 1 / ( 4 - 
>> > > log(2)))));
>> > > postc3 = -postc * 10^(-3*(( postd2/ ma.SR )/(revtadapt * 1 / ( 4 - 
>> > > log(2)))));
>> > >
>> > > // left right delay time offsets
>> > > postdlroff = ma.SR * 0.15 /334 ;
>> > >
>> > > lfo1 = os.oscsin(0.13)*8.0;
>> > > apcomblp(maxdel,N,g) = (+ <: 
>> > > (de.fdelay1a(maxdel,N-1.5)<:_,_':+:_*0.5),*(g)) ~ *(-g) : mem,_ : +;
>> > > // post diffusion (early reflections, placed after reverb loop)
>> > > postdiff( in ) = in <:
>> > >                 (apcomblp( 4096, postd1, postc1): apcomblp( 4096, postd2 
>> > > + postdlroff, postc2): apcomblp( 4096, postd3 - postdlroff*0.382, 
>> > > postc3)),
>> > >                 (apcomblp( 4096, postd1 + postdlroff, postc1) :apcomblp( 
>> > > 4096, postd2 - postdlroff*0.382, postc2): apcomblp( 4096, postd3, 
>> > > postc3));
>> > >
>> > > // feedback filter
>> > > dampp = sin( 2 * ma.PI * bright/ma.SR);
>> > > fidamp = _*(dampp) : +~*(1-dampp) <:_,_':+:_*0.5: *(revgn);
>> > >
>> > >
>> > > // reverb
>> > > rev = _<: +~ (apcomblp( 4096, revd1 - lfo1, revc1):apcomblp( 4096, revd2 
>> > > + lfo1, revc2): apcomblp( 4096, revd3,revc3): de.fdelay1a( 4096, revd0 
>> > > ):fidamp ),_:(_*drywet:postdiff),((_*(1-drywet))<:_,_):route(4, 4, 
>> > > (1,1),(2,3),(3,2),(4,4)):>(_+_),(_+_);
>> > >
>> > > // END REVERB 
>> > > ############################################################################
>> > >
>> > > _______________________________________________
>> > > Faudiostream-users mailing list
>> > > Faudiostream-users@lists.sourceforge.net
>> > > https://lists.sourceforge.net/lists/listinfo/faudiostream-users
>> >
>>


_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to