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