MiMi-d - creating a new software synth for Zynthian

36 years ago or so, I built an analog (more or less) polyphonic synthesizer, dubbed the MiMi-a (The MiMi-a page).

It was my main axe for several years, but eventually when virtual analog synths entered the market big time (starting with the Nord Lead) I abandoned the idea of building synths and jumped on the VA bandwagon. I had a Nord Lead 2 for many years, and a couple of years ago I started a voyage through various other virtual analogs, having gotten tired of the Nord Lead 2 sound.

During this time I was constantly longing just to make at least a few changes in what I felt were shortcomings in the architecture. But it would be a lot of work to reverse engineer and subsequently modify a commercial machine, and I also had a look at various DIY projects such as Axoloti but even if I did some experimentation it never really went anywhere.

A couple of years ago, Zynthian arrived on the horizon, and eventually in my studio. Having submitted a couple of patches to ZynAddSubFX, a month ago I turned my eye towards a shortcoming of OB-Xd, namely the filter tracking parameter, which is on/off only, which is an understandable design choice in the original hardware synth, but not really in software - and OB-Xd already has a number of deviations from the real deal not to warrant this limitation.

After having dug out the code for OB-Xd and perused it, it turned out that this was actually just a GUI limitation, resulting in a patch for Zynthian (Add continuous filter keyboard follow in OB-Xd · Issue #902 · zynthian/zynthian-issue-tracking · GitHub).

However, looking at the DSP code for the OB-Xd it dawned on me that this was really a box of synth Lego blocks that could readily be assembled in any way. To start with, the filter and oscillators are really excellent, the filter being one of the best VA filters I’ve heard (and it’s been used by other projects such as preenFM2 I believe too), and the oscillators have no aliasing that I can hear. But I’ve never been pleased with the architecture of Oberheim synths such as the OB-Xa.

Fairly quickly the idea emerged to create a digital rendering of the MiMi-a . Dubbed simply the MiMi-d, the idea is not to create a clone, but instead utilize design concepts from the MiMi-a: 5 stage envelopes (ADSRs with an additional sustain time), bipolar envelope modulation, audio rate filter modulation, full control over voice allocation, and other things.

The idea is not to create a monster synth like the Surge or anything like that, but more of a full-fledged but not overdone polyphonic synthesizer, with two oscillators plus one sub, ladder and multimode filters, three envelopes and two LFOs. The MiMi-a in its time was inspired by the MemoryMoog, even though the final result turned out rather differently in many ways, and one could say that the MiMi-d again picks up this queue. There are some nice features in the OB-Xd that I will reuse too.

Work is still underway, slowly, and what I’m basically doing is starting with the OB-Xd and chiseling away, modifying, adding bits etc until I’m left with the MiMi-a. The plan is first and foremost to create a plugin for the Zynthian native UI, because I really love the way the Zynthian GUI operates. A proper plugin GUI might come later if I have (or anyone else for that matter) enough stamina to get that far.

mimid-oscpage
Prototype MiMi-d parameter page

So far, most of the modules except the sub oscillator are in place, but there are lot of details that are still sketchy, and the parameter pages are in a bit of a haphazard order.

More information including Github links, on the project home page MiMi-d home page

One thing I’d like to know, is how best to add a synth plugin to Zynthian. So far I’ve hacked a description into /zynthian/config/jalv/plugins.json, but I’m assuming this should be done in some structured way, as the file is obviously not intended to be edited manually, having no line breaks; also, I’ve created a .ttl file for Zynthian in /zynthian/zynthian-data/lv2-custom/MiMi-d.lv2/MiMi-d.ttl, and just copy it to the plugin binary directory manually, but I’m sure there’s a better way to do this. I’ve not delved into how to do this properly, having decided to focus on the actual plugin first, so the information is perhaps readily available already.

10 Likes

Hi @ricard

New modules are added via install recepies / scrips. We add one to the scripts for each new device we want to add to the Zynthian library. The script will do what is needed, e.g. fetch the executeable or source and compile plus any configuration. With LV2 that is usually the shared library object (.so), configs (.ttl) and optionally the GUI shared library object (.so) but sometimes the shared libs may need to be compiled specifically for the Zynthian platform (arm32 - soon to migrate to aarch64). Zynthian has a range of locations it looks for LV2 - all the usual places plus the Zynthian specific locations, including lv2-custom. The latter is intended for complementing or overriding upstream configuration that is held in the plugin’s directory so in your case I would expect your plugin to be installed in one of the usual LV2 plugin locations including its own TTL files with no need for custom TTL unless we deem it necessary to customise for Zynthian layout / presenation. (This may include reordering / renaming parameters, changing displayed range / enumerations, etc.) A well defined TTL often does not required such customisation but most benefit from some - to optimise their presentation within the space confined Zynthian UI.

BTW - if you build it as a LV2 plugin for Zynthian it should also work in any DAW that supports LV2.

[Edit] I just looked at your GitHub repro. I would recommend putting MiMi-d in its own dedicated repro and adding DISTRHO or JUCE as a git submodule, i.e. you only have your own code in your repro and the dependancies are pulled from upstream repros. You have done kinda the opposite that you have forked a repro that ports lots of existing modules to JUCE and you are then adding your own that is not ported (as such). It may make use of just your synth more awkward as it is quite tightly integrated with an upstream umberella repro.

3 Likes

Well that gets a like right off the bat . . .!!

Dymo tape? The three D printing of it’s day. . .

Anything you recorded using it?

Just looking randomly at 1987 . . .

Too Clean…?

We need a write up of that. Where best to put it?

1 Like

:slight_smile:

Well, nothing released on any larger scale, but this random improvisation over Pachelbel’s Canon in D is mostly MiMi-a:

The sligthly overdriven character of the beating sawtooths when the oscillator outputs are turned up to max is a hallmark of the MiMi-a sound but I’m not sure I really want to carry that on to the MiMi-d. I’m currently experimenting with various types of soft clipping to emulate the overdriven 3080 OTA used as a VCA, but so far, although pleasing, it’s a bit off the mark.

This piece is an extract from a longer ham-fisted composition called Epos 1 (which originally came about to try out a four channel tape recorder which I’d recently obtained), which is also very MiMi-a-centric (albeit with CS-80 and Minimoog as well - anything after-touch-y is CS-80, and a lot of the bass is the Minimoog. A Korg KPR-77 drum machine rounds off the instrument lineup, but drums that sounds very hand played are done on the MiMi-a in multitimbral mode):
https://soundcloud.com/all-things-electric/epos-1

No, that wasn’t the problem actually. I came to a state where I just thought every sound I made had this nasal character which drove me nuts.

3 Likes

A vague air of mysticism creeps in around these ideas…
Given the joys of the filter miscalculations on the Moog filters it’s a worthy area to examine!
The nosey Swede’s would probably have an interesting view on it…

Funnily enough I happen to have quite a few low voltage Diodes that are passively involved in similar researches. . .

I wonder how long we spend trying to obtain an optimal sound from digital technology because we know it should be possible when previously with analouge circuitry we may have settled for the side effects of the components we had at hand? I am fairly sure that most of the pleasing clipping we hear is the result of happy accidents. The circuit was designed to be as clean and pure as possible then when driven hard just happens to distort in a manner that is not just acceptable but positively beneficial. My Behringer UCM-1820 has input stage that clips quite acceptably to the point that I am known to use it to intentionally distort a guitar or other input rather than rely on an effect processor within Zynthian.

Of course with digital signals you simply must not let the signal clip (unless you are the youth that find digital clipping and aliasing to be an interesting and pleasing effect!!!). You must create some (often complex) algorithm to process the signal to artifically distort it in various ways under various conditions. For it to be comfortably familiar it needs colouration at all levels (not just above a threshold) that affects different frequencies, impulses, etc. in different ways. I decided a long time ago that I haven’t the time in my life to spend trying to replicate something that is so simply and cheaply available in analogue effects but still await for someone else to do so. Please - we look forward to hearing (and hopefully sharing) your efforts.

2 Likes

Yes, I think it’s very true that analog systems sound good of their own accord, because any resulting artifacts are generally well behaved, whereas with digital systems, you really have to be on top of all the maths and not let any signal or control get outside its intended range, or algorithms break down and produce nasty side effects.

I would say tough that I feel there are two classes of analog synths here. Modular systems really are designed to be pushed to and beyond their limits, whereas a pre-packaged digitally controlled polyphonic analog synthesizer like the Prophet-5 needs to have a certain amount of restraint, since there are signal paths which have a limited voltage swing, and when pushed to the limit, the voices start behaving differently, signals start leaking between voices etc, and the instrument as a whole becomes chaotic.

That said, digital algorithms are over time also evolving to be more manageable. The zero delay feedback topology used for the filters in the OB-Xd (and consequently the MiMi-d) can for instance take audio rate modulation in a way which to my ears at least sounds identical to the way an analog filter would behave. That was not the case with early digital filters.

Do you offhand have an example of such a script? I’ve been browsing the Zynthian source, admittedly only in a cursory manner so far, because I’ve been focusing on the synth engine, but I haven’t really figured out where the installation of a plugin actually begins.

That’s a good point, my plan is rearrange the parameters so they are in a logical order in the UI, so that no custom .ttl file is needed, although I would still need to define parameter groups in the .ttl file both to get them properly grouped with proper group names.

Yes, my plan was really speed up development by using Carla or something similar on a PC, however, so far, what I have done in the PC environment is break out single modules and components (like the filter) for more thorough investigation and experimentation, and incorporate them into fairly simple applications that for instance sets the filter to self oscillation, and runs through a number of cutoff frequencies and measures the resulting oscillation amplitude and pitch. But I so much like the Zynthian environment for actual playing that I’ve been content compiling it for Zynthian whenever I want to do real life testing.

Yes, I agree that would be preferable. The reason I’ve done it the other way is that I wanted to start with something that worked, rather than spending a lot of time figuring out how to get a framework to play nicely. I was also thinking that perhaps falkTX would eventually take MiMi-d into the DISTRHO Ports upstream repo, but as you say, MiMi-d is not really a port from somewhere else.

So, at some point, I should really heed your advice though and restructure it all. I see that falkTX has created a plugin framework (DPF) which looks like it would suit my needs - or I may take a closer look at Juce. I’ll need to do that at some point anyway to create a proper UI.

This allows you to build plugins that will compile as naitive LV2, VST, etc. JUCE also supports these platforms now (previously did not support LV2). Both are similar. I feel that JUCE has a larger overhead but both are more bloated than direct low-level LV2 programming which isn’t too difficult. I must admit that I starte to port some of my code to DPF but stopped developing the plugins due to other commitents. I think I found DPF okay but some bits were odd / not yet implemented / broken. It may be better now (a couple of years later).

1 Like

Hi @ricard :slightly_smiling_face:

I am following your both generous and commendable effort, to program an LV2 plugin specifically tailored for the Zynthian platform.

I keenly own myself a Nord Lead 2X rack, which I would struggle to define nasal in sonic character, but which I acknowledge that offers a rather recognisable Prophet-y sound, under a pleasantly Scandinavian ice blanket, and a somewhat restricted gamut of timbral nuances.

This said, I personally believe that in its signature and maybe limited acoustic palette lies the source of its main strength, with the DSP-generated oscillators sounding remarkably crisp and clean even in the higher range, and an unusual thickness for a digital synthesiser.

As of me, I use it hooked to a humble Zoom MS-70CDR multifx pedal: even with such an unassuming digital outboard it garners the erratic imperfections that afford liveliness, and that sonic three-dimensionality that helps sitting it properly in a mix, thus sounding to my ears absolutely fabulous, and - as they say - “organic”.

Just my opinion, of course.

Nasal is perhaps not the correct word I was looking for. Screechy perhaps captures it better.

I had a real love affair with my Nord Lead 2. I remember walking into a music store in 1995 and checking out the orginal Nord Lead. After an hour and a half I was seriously starting to try and figure out how I could afford one. To me it seemed to start firmly in the realm of analog synthesizers and take off from there, with things like FM and morphing. A couple of years later I actually had money in my pocket, but other manufacturers such as Roland and Korg had entered the VA market, and I almost bought myself a JP-8000, but then Clavia launched the Nord Lead 2, fixing the most serious issues (apart from the lack of voices) of the original Nord Lead: Split keyboard capability and filter tracking in steps of thirds rather than just on/off, and that’s the one I got.

I really loved this machine, even went so far as to put weights in the keys to improve the touch sensitivity (Weighting down the Nord).

Fast wind ten years on or so and after being quite content with my instrument lineup I’d started to re-examine the synthesizer market. Somewhere in that process I was using an E-Mu XL-7 primarily as a sequencer but also as a sound source. At some point I was recording a tune with the XL-7 and Nord Lead and it just struck me that the sounds I had on the Nord Lead sounded screechy and unpleasant. Honestly, it was largely just in my head, but at the time I got rid of the Nord Lead 2 which initiated a period of checking out various VA synthesizers.

A few years on, and I got a Nord Lead 2X having reconciled myself with sound, which initially felt like a homecoming, but eventually I sold it again, realizing that the Nord Lead days for me had passed. The Zynthian was actually part of that process, having discovered OB-Xd and ZynAddSubFX, which alone make the Zynthian worth while for me. Not that those instruments replace the sound of the Nord Lead, but they have taken over the ‘exciting and fun to twiddle sounds’ aspect, which is what has always drawn my to synthesizers in the first place.

A couple of months ago I realized I could actually get into instrument design again (always late to the table - OB-Xd has been around for - is it almost ten years now? - and the Zynthian is no baby anymore either), using the OB-Xd as a starting point.

So far things are looking very promising - I’ve got three ADSSR envelopes and two LFO’s, have added audio modulation from one oscillator to the filter, dug out the voice allocation algorithms from the MiMi-a (with some improvements), the filter has been tweaked in various ways and I’m currently looking at some soft clipping to emulate the VCA being driven hard. There’s still a bit to go after that: I want to implement variable sync (not from the MiMi-a but from an earlier fully analog monosynth I built), the mod routings have got to be tweaked, I want to bring in touch and aftertouch sensitivity, and also add a sub oscillator like the MiMi-a has. Plus likely a few other things that I’ve forgotten at this late hour.

5 Likes

Hi,

I surely concur that the Nord Lead, even in its latest incarnations, is not the smoothest of all in terms of synthesiser tone. Heard side by side with my analogue yet structurally similar DSI Rev 2 - which in turn, and despite its relative glory, is not a Matrix 12 or a Prophet 10 - it tends to feel colder, given the same external ambience processing, and definitely less luscious and harmonically rich.

What I do like of the synthesiser firms scene, and which keeps on drawing me towards discovering new machines, is that each company has managed to imprint its catalogue with a more or less recognisable sonic style. In these terms, synths become real instruments as long as they afford a specific timbral flavour, to the compositions in which they are employed.

There certainly are diverse aesthetic philosophies in the various engines and designs. Speaking of classic digital synthesisers from the first wave in the 1980s, I cannot envisage two keyboards more sonically divergent than the Yamaha DX-7 and the Roland D-50. Both were and still are fantastic electronic instruments, but the first was abstract, uncompromising in its architecture, almost clinical in colour and technically challenging to program, while the second was instantly gratifying, sonically charming, colourful in tone and acoustically spacious.

I think that, at times, it is beneficial to be forced to write music proceeding by sonic abstractions, as the organists are well used to do, when they build their fancily-named registrations, which at the end of the day are just slight timbral variations of a mechanical additive synthesiser. Brian Eno was famously capable of achieving extremely fascinating orchestrations, using only its renowned DX-7 custom tones, artfully treated through his signature framework of effects.

The beauty of modern (and relatively affordable) synths is that we can enjoy the luxury of choosing the right instrument for the right desired colour. From this standpoint, we might look at the icy Scandinavian character of the Clavia family as a specific sonic resource, that no wonder they kept consistent across the years. Their instruments are desirable exactly because, in their inherent limitations, they feel like musical tools, which sound organic and real by virtue of their non-limitless timbral gamut.

Best :slightly_smiling_face:

I agree, I think it’s very true that the limitations of an instrument can be very inspirational.

That’s something I like about pre-packaged synths compared to modulars, there is a design philosophy that one can relate to, either doing what can be done inside the box, or sometimes achieving something sonically unexpected given the limitations.

Speaking of sonic character, I’ve been experimenting with subtle overdrive/distortion in the MiMi-d, mostly because the MiMi-a has it, although I’m normally not too fond of overdrive in synths. However, while twiddling I cranked up the audio rate filter modulation and resonance coupled with some overdrive and stood noodling for 4 minutes or so. Something about this sound appeals to me although as I said distorted sounds are normally not my forte. (Straight sound directly from Zynthian with no onboard or outboard processing).

10 Likes

Nice indeed, and very promising :slightly_smiling_face: :+1:

A rich harmonic spectrum, and with an apt wash of spatial ambience (delays + granular/pitch shifted reverb) we are straight in Blade Runner-ish dystopian territories.

Very curious to see what you ultimately come up with, in your synthesizer building endeavour. I look forward to seeing the Mimi listed in the official Zynthian repository.

2 Likes

This is absolutly my bag, baby.

It’s been a while, so I thought I’d offer a small update.

Work is still progressing, but has taken longer than I expected, largely because I’ve spent quite some time tweaking and adjusting the various modules, rather than making minimal changes to the original OB-Xd code.

For instance, the MiMi-a has linear envelope curves, and while I really prefer the more classic exponential curves, I decided to implement an optional linear mode as well to be true to the original. In doing so I discovered a number of inconsistencies with the OB-Xd envelopes; I don’t know if the intention was to emulate a specific Oberheim design, but as far as emulating the CEM 3310 chips used in the OB-Xa there are a couple of errors which I think impacts performance, so I made a number of fixes to better emulate the original analog hardware.

I’ve also combined the LFOs with modulation envelopes to create a couple of general modulation modules which offers flexible modulation capabilities without having a large amount of modules, thus keeping the synthesizer architecture fairly compact.

In some cases I’ve put things on todo lists for future instruments - a MiMi-e one day perhaps …

Anyway, at the moment the state is that I’m basically happy with all the modules and the architecture. Next I need to start thinking about how to package it all up properly, cleaning up the list of parameters, and perhaps put together a rudimentary UI so it can be used outside of Zynthian (or for those that prefer a graphic UI rather than the native Zynthian front panel UI).

This leads me to consider @riban’s comment again:

The way I see it, DISTRHO-Ports is basically a fork of Juce, with patches, among other things to facilitate the generation of LV2 plugins, married with a bunch of plugins, essentially porting them to LV2. Although at the moment I’ve left all the plugins in place, what I’d like to do is remove them all, just leaving the MiMi-d for now, but with the option of adding other instruments in time.

The alternative of creating a MiMi-d repository, using DPF or Juce as a submodule, is of course structurally more correct, but in practical terms would not offer a lot of benefits - when building the MiMi-a, one would still have to check out both MiMi-d and the associated plugin framework, and build it all. It would be different if I were developing a plugin from scratch, but here I’m basing it on existing code, so changing the framework architecture is mostly work with no practical gain. Also, if using Juce I’d miss out on falkTX’s conversion from CMake to the Meson build system which I prefer, as well as other patches that probably facilitate obscure but necessary or at least handy things that would take me a while to discover on my own…

I’ll still be considering it, but at the moment I’m going and try to complete the plugin in its current environment.

Some of the things remaining are:

  • Creating a proper .ttl file from within the plugin, with data points for stepped parameters, rather than having a separate one in /zynthian/zynthian-data, if possible.
  • Shuffling the parameters around to put them in a more logical order and cleaning up the parameter names.
  • Create a rudimentary GUI.
  • Figuring out how to properly install the plugin in the Zynthian environment - for now I’ve hacked it into zynthian/config/jalv/plugins.json manually, but there is obviously a structured way to do this as part of an installation process.
  • I haven’t tried saving MiMi-d patches using the Zynthian lv2 patch storage architecture for quite some time (because I keep changing the parameter definitions during development so any saved patches would become useless pretty quickly), but last time I tried, for some reason they would be saved in /zynthian/zynthian-my-data/presets/lv2/Obxd.presets.lv2 rather than /zynthian/zynthian-my-data/presets/lv2/MiMi-d.presets.lv2, even though they are registered in the MiMi-d manifest file., despite there not being any trace of OB-Xd definitions in the .ttl file.
  • How to distribute the plugin for inclusion in Zynthian.
  • Probably a couple of other things I forgotten about now …

If anyone has any ideas or pointers on the above feel free to just drop a line to point me in the right direction…

4 Likes

The problem with not doing this is when developement of MiMi slows you have a crufty old outdated buggy framework you have to keep deleting and overwriting from upstream. I speak from incompetance.

1 Like

I would advise delaying work on a GUI until you have something you consider sufficiently “complete” to integrate in Zynthian. GUI design (however rudimentary) zaps time!

1 Like

Thanks for the helpful comments and suggestions above!

I’m happy to announce that MiMi-d is now moving from my DISTRHO-Ports fork to a DPF-based repository of its own: GitHub - polluxsynth/audio-plugins: Audio plugins using the Distrho Plugin Framework .

Although a lot of valid points were made above (which I’ve had at the back of my head), the deciding factor is that the .ttl file generation in DISTRHO-Ports does not support scale points and parameter groups (and (in accordance with Juce (at least Juce 5)) the value range for all parameters is always 0…1).

I’ve just spent the better part of every free moment during the weekend implementing the move, and have now run MiMi-d for the first time actually with its own generated .ttl file (i.e. not a patched version of zynthian-data/lv2-custom/Obxd.lv2 ).

Currently the UI is a bit of a shambles though since I have not yet implemented generation of the relevant scale points and port groups, so the parameters are now all in total disarray. I was pleasantly surprised when I finally did get the plugin operational because the first sound powered up was identical to the one that ended up in the current snapshot state when I last had the DISTRO-Ports version running, having kept the parameter symbols intact. However, the parameter definition has been improved in the plugin, so the next step is to properly implement the relevant scale points and port groups, to bring the UI back to its previous state.

There’s also not a top level build file or install target in the repo, so a bit of manual intervention is needed to initialize the build, but I’ll be working on that as well bit by bit.

6 Likes

how to add it to plugins?

Yeah, that’s a good question. So far I’ve hacked it in manually, in two steps:

  1. editing /zynthian/config/jalv/plugins.json in a text editor, adding a MiMi-d entry (this is a bit of a chore, since there are no line breaks (what is this file intended to be edited with anyway?)).
  2. cloning the GitHub - polluxsynth/audio-plugins: Audio plugins using the Distrho Plugin Framework repo into, say,
    /root/src/audio-plugins, and doing make && make install in this directory, which builds the code (checking out the DPF framework as a subdirectory if needed), and installs the resulting lv2 bundle it in /usr/local/lib/lv2 . (So yes, since my previous post the Makefile will now do everything from a simple ‘make’).

The question is however, how to do this properly? I’ve had a look around the software, and one option seems to be:

  1. Add a MiMi-d entry to the file default_jalv_plugins.json in the zynthian-sys repo (which is checked out to /zynthian/zynthian-sys) (again, is there some editor that allows this to be done smoothly?)
  2. Add the (prebuilt) lv2 bundle to the lv2-plugins-prebuilt-rbpi3 repo (which is checked out to /zynthian/zynthian-sw/zynthian-plugins .

I can’t figure out how any new additions to default_jalv_plugins.json get added to the current setup in /zynthian/config/jalv/plugins.json however. The former is copied to the latter if the latter is completely missing (as I suppose it is at first boot), but in the update script (/zynthian-sys/scripts/update_zynthian_sys.sh) I can’t see any form of merge taking place during update.

So, I few pointers here would be appreciated. The plugin is in a state where it might not be ready for its final release, but it would be nice to be able to distribute it for those that want to give it a go.