mx.synths
project name: mx.synths
project url: https://github.com/schollz/mx.synths
author: infinitedigits
description: like mr.radar or mr.coffee but for synths
discussion url: https://llllllll.co/t/mx-synths/49535
tags: synth midi

mx.synths

mx.samples: like mr.coffee or mr.radar, but for instrument synths. (companion to mx.samples).

https://vimeo.com/631313246

Requirements

Documentation

mx.synths is a collection of eclectic polyphonic synths.

each synth has a specific style that can be tweakable via “mod” parameters. their are four mod parameters and they are synth-specific (though usually mods 2 and 3 are frequency and resonance respectively and usually mod 4 is detuning). all other parameters - found in the MX.SYNTHS PSET menu - are shared for each synth. most the parameters are evident (delay send, adsr, etc.). one special parameter is called “sub”. sub is synth specific (and not implemented in every synth) which activates some sound with low-note priority. many of the parameters have lfos.

since all synths share the parameters menu, you should save your settings if you find a patch you like (PSET > SAVE), so it is easier to come back to.

the synths

piano

piano: this is an ‘acoustic piano’-like synth from @zebra’s DreadMoon engine. it is essentialy noise being filtered through a comb filter. the mod parameters can make it sound more like a drum than a piano sometimes. mods:

  1. decay
  2. noise freq
  3. resonance
  4. detuning


epiano

epiano: this is an electric piano based on FM rhodes type sounds. it is taken with minimal adjustments from snappizz’s FM Rhodes SynthDef. mods:

  1. lfo depth
  2. mix
  3. modulator index
  4. lfo speed

casio

casio: this is an emulation of the phase distortion synthesis from the 1984 Casio CZ-101. I implemented it purely based on their patent and has all sorts of weird artifacts. mods:

  1. artfiacts
  2. phasing
  3. resonance
  4. detuning


malone

malone: malone comes from designing an organ sound for a drone. it is a heavily modified version of Svdk Vedeka’s port of Coloscope’s pure-data organ. mods:

  1. detuning speed
  2. filter
  3. resonance
  4. detuning


toshiya

toshiya: this is a another from sound designing for making drones. I wrote about it here. it has a klank sound that can be modulated. mods:

  1. pitch spread
  2. klank volume
  3. filter oscillator
  4. detuning


synthy

synthy: this is the basis of a couple of synths - starlids and synthy, this is yet another iteration. mods:

  1. stereo spread
  2. filter spread
  3. resonance
  4. detuning


polyperc

PolyPerc: this is the classic PolyPerc engine from @tehn, with some adjustments. mods:

  1. pulse width
  2. filter
  3. resonance
  4. detuning


icarus2

icarus: this a slight modification of the icarus script. mods:

  1. feedback
  2. delay time
  3. PWM width
  4. detuning


mdapiano: simply based off the SuperCollider MdaPiano. mods:

  1. stereoness
  2. vibrato rate
  3. vibrato depth
  4. detuning


kalimba:based off the p.dupuiskalimba, which is a fork from @nathan’s kalimba.. mods:

  1. stereoness
  2. vibrato rate
  3. vibrato depth
  4. click mix


triangles

triangles:based off the triangles engine. mods:

  1. bellow
  2. noise
  3. semitone detune
  4. vibrato


usage as library

mx.synths can be included in other libraries. its probably easiest to change the engine and import the menu library:

engine.name="MxSynths"
local mxsynths_=include("mx.synths/lib/mx.synths")
mxsynths=mxsynths_:new()

now you can edit the current sound by directly editing the parameters, as all the parameters will update the engine. to then play a note you can use

engine.mx_note_on(<midi>,<amp>,<duration>)

the <duration> is the number of seconds to automatically release. it effectively lets you choose whether it will play as a “one-shot” synth. if you want it to be “one-shot” then set the duration to the duration you want and it will be released after. if you want to instead use it with note off signals, then you should set <duration> to a large number (like 600 seconds). then you can tell it when you want to do the release by sending a subsequent command:

engine.mx_note_off(<midi>)

there is a helper function to do one-shot playback, you can simply do mxsynths:play({...}) with all the parameters you want, e.g.:

mxsynths:play({synth="malone",note=60,velocity=80,attack=0.1,release=2})

limitations

there are a couple limitations that may become obvious when you spend time with mx.synths.

first - while you can play multiple synth voices simultaneously, the way I wrote the engine is such that only all synth voices will voice-steal from each other if they are playing the same note. (also currently there isn’t a engine command to send all the parameters, rather the parameters are gathered from the PSET menu, but that can be added soon).

second - polyphony is not limited in the engine, but it will be limited by the norns cpu. probably 6-10 polyphony is the max for most synths. setting a quick release if you can will help with this. the synths could also be better optimized I’m sure.

making your own synth

any and all contributions are welcome and accepted.

making your own synth is a simple process. there are three basic steps.

  1. make your SynthDef. start with a basic SynthDef like this:
SynthDef("yoursynth",{
    arg out=0,hz=220,amp=1.0,gate=1,sub=0,portamento=1,
    attack=0.01,decay=0.2,sustain=0.9,release=5,
    mod1=0,mod2=0,mod3=0,mod4=0,pan=0,duration=600;
    var snd,env,pw;
    mod1=Lag.kr(mod1);mod2=Lag.kr(mod2);mod3=Lag.kr(mod3);mod4=Lag.kr(mod4);
    hz=Lag.kr(hz,portamento).cpsmidi;
    env=EnvGen.ar(Env.adsr(attack,decay,sustain,release),(gate-EnvGen.kr(Env.new([0,0,1],[duration,0]))),doneAction:2);

    // <yoursynth>
    
    // (optional but recommended) map the mods to something/
    // mods always sent as [-1,1] so they need to be mapped:
    pw=LinLin.kr(mod1,-1,1,0.2,0.8);

    // make some sound
    snd = Pulse.ar(hz,width:pw);
    
    // </yoursynth>

    snd = Pan2.ar(snd,Lag.kr(pan,0.1));
    Out.ar(out,snd*env*amp/8);
}).add;

once you finish, you can paste it into the Engine_MxSynths.sc, like around here.

  1. add “your synth” to the registry. edit l.synths in the lib/mx.synths.lua script to include the name of your synth. make sure it matches exactly what you named your SynthDef is step #1.

  2. (optional) add some graphics for your synth. simply write a function that draws something to the screen and update redraw() in mx.synths.lua to run your function when it is selected.

Thanks

this script wouldn’t exist without @zebra, who gave me lots of guidance in SuperCollider in general and also the “piano” is from their DreadMoon engine. thanks also to @tehn, a version of PolyPerc is in this engine. and thanks to @snappiz which the “epiano” is adapted.

Ideas/Roadmap

Install

install with

;install https://github.com/schollz/mx.synths