[sharing] synthcore gen~ library

    Jan 02 2017 | 8:34 pm
    Beta attached, contents:
    FUNCTION LIBRARY * pans & ramps - pan1(), pan2(), rampgate(), ramptrig(). * smoothers- smoother(), smoother2(), smoother3(). * Saturators - parabol1(), parabol2(), paraboln(), hyperbol(). * Biquads - biquadlow(), biquadband(), biquadhigh(), biquadnotch(), biquadval(), biquad(). * Ramp Oscs - ramp(), ramptrg(), rampgate(), rampphase(), rampsoft(). * Oscs - sine2sine(), pulse1(), pulse2(), eptr(), eptrpulse(), eptrpulse3x(), sawdown(), sawup(), tri(), tri2(), sawtri(), karplus(), waveset(), noiselpf(), noisebpf(), noisehpf(), noisenotch(). * IIR - comb(). * SVFs - svf(), svfCoeffs3x(), filt(), gainComp(), svfMixer(). * LFOs - lfo(), lfopoly(). * Envs - adsr(), adsrloop(), padsrloop(), adbdsrloop(), padbdsrloop().
    Some of the functions require external buffer data, and I am preparing a demo download to show how it all works. This week I focused on commenting the work I'd done so far, and I appreciate any feedback on making it more understandable. Being gen~ codebox, I am assuming quite a bit of aduio knowledge, so I tried to keep the comments succinct. What do you think?

    • Jan 02 2017 | 9:54 pm
      " I am preparing a demo download to show how it all works. This week I focused on commenting the work I’d done so far, and I appreciate any feedback on making it more understandable."
      The lazy boy in me says "comprehensive and detailed comments please", but the auto-didact says "minimal and succinct only please".
      'Preciate the hard work Ernest, looking forward to the demo.
    • Jan 02 2017 | 10:29 pm
      Damn Ernest, this is awesome. I've been doing a ton of my recent work within codebox, and this is sure to provide me with some solid techniques.
      Thanks for the work!
    • Jan 03 2017 | 1:11 am
      It just keeps getting better and better! Thanks so much, Ernest!
      Also, even as someone who's fairly new to audio, DSP, and coding, I think your use of comments is fairly reasonable. For me, personally, it takes a some effort to fully wrap my head around concepts, but I think your code aids more than hinders in that regard. In fact, a lot of this could make a great companion piece when reading papers on things like filters and bandlimiting- subjects that normally use equations rather than algorithms to demonstrate concepts, which has been a giant wall for me to climb.
    • Jan 03 2017 | 9:11 am
      Dear Ernest
      This is, definitely, a great stuff. Thank you very much.
    • Jan 03 2017 | 2:46 pm
      Thanks Ernest! Great work.
    • Jan 03 2017 | 11:21 pm
      Thanks for the comments. You may notice I some comments that gen~ crashed when returning values from inside conditional statements. It appears to be more frequent when there is more than one variable returned. Today I found something else, which might account for it, while writing the following stereo delay function:
      ping(input1, input2, delayL, delayR, mix, cross, inpan, feedback){// stereo delay
      	Delay ping1(384000, feedback=1);// allows 2 secs at 192khz
      	Delay ping2(384000, feedback=1);
      	u, v, x, y, z = 0;
      	if(mix > 0){ // this part can be bypassed when not used. 
      		x = ping1.read(delayL, interp="spline");
      		y = ping2.read(delayR, interp="spline");
      		z = 1 - cross;
      		u = input1 * (1 - inpan);
      		v = input2 * inpan;
      		ping1.write((x * z + y * cross) * feedback + u * z + v * cross);
      		ping2.write((y * z + x * cross) * feedback + v * z + u * cross);
      			mix(input1, x, mix),
      			mix(input2, y, mix);
      	} else {
      		return input1, input2;
      Param dl1 (24000), dr1 (20400), d1m (.75), d1w(.5), d1p(.5), d1z(.75);
      left = in1; right = in2;
      out1, out2 = ping(left, right, dl1, dr1, d1m, d1w, d1p, d1z);
      The above works fine, but if I try calling the function with:
      out1 = in1;
      out2 = in2;
      out1, out2 = ping(out1, out2, dl1, dr1, d1m, d1w, d1p, d1z);
      It fails to compile, and sometimes crashes, saying "read-onlys can't be written." Strangely, this works:
      out1 = in1;
      right = in2;
      out1, out2 = ping(out1, right, dl1, dr1, d1m, d1w, d1p, d1z);
      So it appears the first argument in a function is read/write, but the others are read only. According to conventional programming, which should it be? Is the first argument meant to be read-only too, or are all the arguments meant to be read only? I never really thought about it before, I don't know the answer.
    • Jan 06 2017 | 3:49 am
    • Jan 06 2017 | 2:32 pm
      all cool. congrats.
      can i just point out that this is crying out the be in max package format. or at least a single '.genexpr' file for using 'require'.
      easier for you to maintain and push and users to update.
    • Jan 06 2017 | 7:27 pm
      Well,. it is not easier to maintain *for me*, lol. It might be easier for you. But I have some questions about inexplicable behaviors which rather impact performance in a separate thread to resolve first, before I submit a package.
    • Jan 07 2017 | 8:34 pm
      Meanwhile, I have added static 1-pole low pass, high pass, low shelf, and high shelf filters. Here is the test patch.
    • Jan 09 2017 | 11:34 pm
      This is drop two of the synthcore library, with about a dozen new functions.
      I thought some more about making a .gendsp file. The issue is, all the docementation or the function calls is in the library.. So what I am planning to do is assemble a bunch of little patches that demo each section:
        * MATHS - qsin, qcos, db2a.
        * PANS & RAMPS - pan1(), pan2(), rampgate(), ramptrig().
        * SMOOTHERS - smoother(), smoother2(), smoother3().
        * SATURATORS- parabol1(), parabol2(), paraboln(), hyperbol().
        * 1-POLE FILTERS - static(), staticlo(), statichi(), shelflo(), shelfhi(). 
        * BIQUADS - biquad(), biquad0(), biquadlow(), biquadlo2(), biguadlo3(), biquadband(), biquadband2(), biquadband3(), biquadhi(), biquadhi2(),
      	biquadhi3(), biquadnotch(), biquadamp().
        * RAMP OSCS - ramp(), ramptrg(), rampgate(), rampphase(), rampsoft().
        * OSCS  -	sine(), pulse1(), pulse2(), eptr(), eptrpulse(), eptrpulse3x(), sawdown(), sawup(), tri(), tri2(), sawtri(), karplus(), waveset(), 
      	noiselpf(), noisebpf(), noisehpf(), noisenotch().
        * IIR - comb().
        * SVFs - svf(), svfCoeffs3x(), filt(), gainComp(), svfMixer().
        * LFOs - lfo(), lfopoly().
        * ENVS- adsr(), adsrloop(), padsrloop(), adbdsrloop(), padbdsrloop().
        * DISPLAY -  biquadplot(), biquadplot2(), displayfilter().
      - DECLARATIONS - constants; for above functions. 
      These are optimized functions. Input ranges are not clipped or normalized. Inputs are in range 0~1, and outputs are bipolar, unless otherwise noted. Samplerate constants are passed in, as they are not compiled out of functions.
    • Jan 10 2017 | 7:00 pm
      Have you considered maybe putting these on Github? I imagine in the beginning it'd be a pain to put each part of the library into individual files, but after that it'd probably be a lot easier to update, as well as get a bit more attention and feedback. Just a thought, of course.
    • Jan 12 2017 | 2:55 pm
      From experience, when someone even suggests github, then either the discussion is over, or the third Reich is taking over.
    • Jan 15 2017 | 3:23 am
      pardon my ignance but how do i use this lovely library? I am learning GenExpr and am proficient in regular Gen
    • Jan 15 2017 | 7:02 pm
      i am writing: out1=eptr(in1);
      at the bottom of the codebox with the synthcore gen library in it
    • Jan 15 2017 | 8:14 pm
      nevermind i got it
    • Jan 16 2017 | 6:17 am
      Ah well you need the buffer data for that to work. I am surprised if you figured it out! The waveset and svf gain compensation tables are very large, so I hadn't included them in this drop. But here are the others, with the new library which adds an effects section: glide, two delays, two choruses, and a reverb. The constants are now put into inputs on the codebox for optimization purposes. When I finish the functions themselves, I will add some demo calls in main().
    • Jan 17 2017 | 2:07 pm
      This is great ernest thanks, I'll let you know (and credit!) when I use it. I think there's an omission on your last post; next to line 1509 (limit), there should be an "hR2 = 0;"? Btw, it works fine as a genexpr with "require".
    • Jan 20 2017 | 6:30 am
      Thanks for sharing this - very interesting work, and very helpful as a learning tool - greatly appreciated.
    • Jan 25 2017 | 5:03 pm
      The synthcore2 synthesizer, based on this library, is now available for download. It currently only contains a few presets which I used for stress testing, and I will be adding a preset library next. The download is 6MB, here: http://www.yofiel.com/software/mac-and-pc-apps/synthcore2
    • Jan 25 2017 | 5:58 pm
      Wow! Thank you.
    • Feb 05 2017 | 10:19 am
      The Synthcore library with help demo and a full package is now available here:
      It also includes two demo synths: the Synthcore synth, and 'Synthcore lite,' which simply removes the dynamic graphics which reduces cpu load from 25% to
      I am hoping to submit the library as a package, which will require Cycling74 approval, so I welcome any suggestions and opinions.
    • Feb 06 2017 | 3:44 am
      Well, there's been 200 downloads in the last 12 hours and no one has said it doesn't work. So I think it's finally done after 6 months of work. I really had no idea how little of this had been done before. I had thought it was only going to take a few weeks, but I had to make most of it from scratch. Going for arthritis medication and a very long bath )
    • Feb 07 2017 | 9:18 am
      BIG THANKS for your tremendous work, Ernest!
    • Feb 08 2017 | 12:52 am
      You're most welcome. One user reported an apparent bug that the synth keyboard doesn't work. This is because, on the initial preset, the envelope is in loop mode (if you adjust the sustain and durations, it will reproduce the terrifying sound of the monster's spell in Magicians episode 1). In loop mode, the pitch is resampled when the loop restarts. Changing env1 to multi mode causes it to behave as typically expected in contemporary synth designs.
    • Feb 11 2017 | 2:36 am
      1,041 synthcore downloads now, no reported problems.
    • Feb 25 2017 | 10:28 am
      checked on 7.3.2, all appears to work, 1,300 downloads. Submitted as project.
    • Apr 24 2017 | 12:09 am
      I've been using the oscillators from the synthcore library a lot. Do you think it's worth it to upsample these in a poly~ to remove aliasing?
    • Jun 20 2017 | 10:32 pm
      Hi Dario, sorry for the delay in response. What I do is just run the whole thing at 96khz, because everything is in one gen~ object, there is no need for poly~ for upsampling. Glad you like the oscillators )
    • Jun 20 2017 | 10:39 pm
      You will also find a technical description of the anti-aliasing in the library here: http://www.yofiel.com/software/cycling-74-patches/antialiased-oscillators
      doubling the sampling frequency gives you an extra octave of headroom.