4/03/2013

Anushri development SSM2164




The Anushri project actually has three roots. One of them was a concept for a synth “celebrating” the SSM2164, using one of these chips for each voltage-controlled element (dual VCO, VCF, and VCA), which I started simulating in september 2011 and abandoned given the complexity of the resulting machine which would be unsuitable for a kit. The second was a concept for an “analog control board” for the Shruthi-1, replacing the digital oscillators by a single VCO – a kind of upgrade to the Sidekick. Given the increasing complexity of Shruthi-1 filter boards – which relied on digital switching, and the difficulty of cramming a full VCO circuit and LFOs/envelopes in the small board space, not to mention a MIDI->CV converter to make it useful, this project did not go very far. The last project came from a small synth manufacturer who asked me a quote for designing the digital logic of an analogue synth (MIDI>CV, arpeggiator and digital LFOs). This intrigued me and I sort of worked my way through half of the code for this to see how easy it would be given that all the functional blocks were available from existing projects. All these were “scratch an itch” side projects, rather than something I really believed in as a product.

In february I gave an interview for a modular synth blog, and talking about the Shruthi, I said that I found VCOs uninteresting. I started thinking that maybe I was fooling myself about that just because I never went through the process of getting one to work, and started looking again into the topic – using the SSM2164 saw-core I had been playing with in simulation previously. Around march, the Ambika project was approaching completion and I was getting very frustrated about it – the development seemed never-ending, with many bad surprises on the road, and just like the Shruthi-1 I was a bit scared at the thought that users would never, ever, get enough of the project – and that it would be feature request after feature request for the months (years?) following the release. I thought about the analog minisynth concept again, and was seduced by the fact that it would be a pleasant change from Ambika – the “one knob per function” interface people expect from a monosynth would keep the project away from feature creep (and hardware is much harder to upgrade than software!); and it seemed like a relatively small and easy thing to build compared to Ambika. I breadboarded my 2164 VCO + a SVF using the remaining half of the chip, a LM13700 VCA (I did not want to use another half SSM2164 for that), and it was indeed fun to play with!



One thing still bothered me: there were already many one-VCO synths on the market (Minibrute, Dark energy, Domino, Nanozwerg), and I wanted to go a bit further sonically. Adding a second VCO? No, too much circuitry. Adding a digital oscillator à la Shruthi-1? Not an option indeed. I had committed myself to use a high resolution/refresh rate for the CVs (to make it as smooth as possible), and there wasn’t enough CPU left on the ATMega328. The bit of inspiration came from reading Tom Wiltshire’s page about the Juno DCO. I realized that a DCO is really just a VCO with sync signals coming from a digital source. So I decided to route a sync signal into the VCO to achieve a hardsync sound – the sync signal source being the 16-bit hardware timer from the 328p. This worked great and allowed both DCO-like operation (something I did not really bother with) and buzzing hardsync sounds. It did not take long before I decided to route this digital sync signal to other places – the VCO current source, to get linear FM, and the mixer, where it could be used to widen the VCO sound. Another idea that came to me for enriching the sound was to find a use for the unused half of the LM13700. When overdriven, OTAs add a characteristic “tanh” saturation to the signal. Furthermore, I had already observed on the Ambika SMR4 board how their built-in Darlington buffer yields clipped/asymmetric signals when incorrectly used. This gave a straightforward but very useful distortion/fuzz circuit. At this stage the design looked good to me. I decided to add a bunch of modular-style connectors, given the number of requests I had received in the past regarding interfacing the Shruthi-1 with modular gear. I came up with a first layout which used two rows of pots, one for the synthesis functions (directly wired into the analog signal processing chain), the other software-defined, serving as ADSR/LFO controls, general system settings, and 8 steps + length control for an analog-style step sequencer. Writing the firmware was a very, very quick affair, given that I already had the basic code tree for a monosynth ready (If you’re wondering, the very first piece of code I write on a new project is voice.h and parameter.cc). I got a proto made and as usual: the firmware was running flawlessly on first boot minus all buttons and pots operating backwards, but the whole thing felt broken.



The analog-style 8-step sequencer left me unimpressed. I still don’t understand how people can be comfortable with the idea of programming 2 or 4 bar note patterns with *knobs*. I decided to bet all my money on the 101-style sequencer instead, even if it made it impossible (for the moment) to use the unit without external MIDI input.
Once 15mm knobs were fitted on the pots, the layout was not very usable.
The long row of controls made it hard to remember which pot does what.
In a case, it would have looked fugly. Especially since it would expose A LOT of solder joints, and there would be a lot of white space.
The VCO tracking really sucked.
To solve the layout problem, I bit the bullet and re-laid out everything on two boards – something I originally wanted to avoid to make for a slimmer case and bring the cost down. It took two whole days, but the readability of the layout greatly improved. Bonus: the boards were now small enough to be mounted behind a Eurorack panel – this mattered to me since I was starting building my little modular setup at that time.

The VCO problem was a tough one, because I spent a lot of energy trying to solve the wrong problem. My original focus was on the integrator reset time in the saw-core, but even by faking Spice models of the crappiest JFETs, or of op-amps with the most horrible offsets, or of comparators slow as molasses, I could not get in simulation something as bad as what I was measuring. That’s when I decided to pimp my measuring equipment and get something more serious to probe the integrator current source…



After a few days blocked on the problem, everything pointed to the exponential converter – something confirmed after rapidly breadboarding a standard transistor-pair expo converter in place of the 2164 and getting 5 octaves of tracking minus temperature stability. It took me a while to figure out what was wrong… It turned out that the SSM2164 input is not the ideal virtual ground I thought it was! The problem was solved by increasing the value of the resistor at the 2164 input (from 15k to 100k) – less current, less non-linearities affecting scaling.

With that problem fixed, I got a second proto made. The interface was much better, and the VCO tracked well over 5 octaves (the remaining error was due to the integrator reset time and some errors in the 2164 expo response – would have required more circuitry for compensation…).

What remained to be solved was what to put in place of the analog-style step sequencer. I quickly toyed with the idea of an 8 steps waveform editor for the LFO (a kind of sequencer but at modulation rates) – wasn’t good. I had 9 knobs, roughly 40% of the CPU after some optimizations, and 2 days left before a demo at Modular Square. And this is when I decided to ressucitate… eigendrums. This was a quite old drum machine concept inspired by an ISMIR paper by Ellis and Arroyo. Let’s do it!

First problem was how to get audio out of the MCU. Solved by hacking the board to hook up the MCU PWM pin to the output op-amp (I also tried hooking it into the VCF->VCA, but then it sucked because a synth note had to be played for the drums to be heard). I had to swap the functions of two MCUs pins for that. Damn, the Shruthi-1 made me sick of PWM and I was at it again…



Second problem was to code a drumsynth with a very low CPU requirement. Simplest approach that could work: a digital sine oscillator with AD envelope for pitch and amplitude + noise + ringmod. Since I decided to dedicate only one knob for adjusting the tone, the knob worked as a morphing control through various combination of parameters that I programmed into the unit through CC with a MIDIpal, writing down parameter values on paper. Later I ditched the ringmod and used a sample for the HH.



Third problem was the drum pattern generation. I wanted something fun to play with, that could generate musically interesting patterns, and that could allow the classic “build-ups” found in electronic music. My first try, the straightforward eigenrhythm implementation worked well, but it was not fun to play. At this stage, I had 6 knobs controlling the 6 principal components + 3 for tone control. The problem was that the last knobs had decreasing impact (PCA “sorts” dimensions by decreasing variance), and that there was no way of getting dense or sparse patterns – the PCA learned the “average” density of a pattern and I wanted a way of bringing in outliers too! What I wanted was something more like an euclidean sequencer, in which it is possible to control sparsity/density. So let us work backwards… With 3 knobs dedicated to a sparsity/density control for each instrument (how would it work? TBD…), this would leave me with only 2 knobs for controlling the base structure of the drum pattern. How to map the space of drum patterns into a 2D space? My first approach was to get a bank of presets, lay them out in 2D using the first 2 axes of the PCA, and use the 2 knobs as X/Y coordinates in this space (did it before, see figure 4). Problem: the map has gaps, and I don’t want to store many patterns in flash. Same problem with LLE. I want hmmm… something like a topology-aware VQ that would give me a grid-like codebook? How is that called? Kohonen map! That’s how I decided to use self-organizing maps to build a 2D grid of patterns. Last open problem was the sparsity/density control – once you have a pattern, how to progressively remove notes to turn it into an empty pattern, and how to progressively add notes to turn it into a grid of sixteenth notes. If, like me, your past job involved counting n-grams and solving combinatorial optimization problems, the solution gets very obvious: select the sequence of note addition/removals that visits the rhythmic patterns with the highest frequency in a corpus of drum loops. The library is the grammar. Nice side-effect: randomly walking through this Hamming neighborhood creates musically interesting variations for free! I made it in time for the Modular Square demo – though the whole thing was trained in a small corpus of rhythms (larger model on its way – it did not make it into the first version of the Anushri firmware).

After the Modular Square demo, I noticed something odd about my proto… When switching from the single board layout to the 2 boards layout, I blindly rearranged the available controls without realizing there was room for more! I added two knobs, changing the number of software knobs from 9 to 10 (functions: VCO detune, velocity destination control, and a bitcrusher for the drum section which is the FX maximizing the wow/CPU cycles ratio – leaving all competitors in the dust); and adding a knob for sub-oscillator level. And more room for 2 modular I/O jacks! This is how we got to the present third revision of the board.

The final touches to the firmware included a secret way of overriding the drum sequencer with a x0x pattern input on the keyboard, a way of sequencing the drum section from an external source, and bringing back the CC drum sounds editing I used during development.

All in all, the project took 1 month of hardcore development to get the basics done, 3 months to feel “right”, and 4 months of polishing – which are the ratios I am getting used to!

No comments:

Post a Comment