Let's Design and Build a (mostly) Digital Theremin!

Posted: 4/10/2020 1:59:25 AM

From: Northern NJ, USA

Joined: 2/17/2012

Improved Envelope Damping & Pitch Correction, Preset Conversion

OK, I gave the Subscope type velocity one last college try and was somewhat successful, but it needed a lot of gain to get an envelope out of it, and to make that playable it seemed to need a really big volume field - without that it was pretty squirrely as the high gain amplified any and all volume hand movements.  Maybe I'm missing something essential, but it doesn't really enthuse me, and isn't a good fit with my knee / envelope generator scheme as it stands.

Instead I took a closer look at envelope damping.  For the extra knob spot I coded up variable VLOC damping location, and now the DAMP knob is scaled identically to the FALL knob, with DAMP timing kicking in when the volume hand is past the point set by the VLOC knob (pre knee, so it corresponds to hand location rather than volume level).  This is quite versatile and working better than I thought it would, and I'll have to make a video soon showing it off.  I did the same volume based rate switching thing for the pitch correction subrate, except in that case I'm using the post knee volume level and a fixed level of -48dB, and that's now working a bit better too.  Never know when you'll stumble on a new basic approach that can generally improve things.

I modified the librarian software to translate my preset files to the various new knobs / ranges / topologies / etc. and got that meat grinder working today.  Some subtleties here and there get a bit lost in translation, but it's mostly just touch-up work, and it never hurts to revisit those sorts of details.

My accordion patch uses maximum pitch correction ("steppy" pitch quantization, actually) and I noticed it was slightly glitching in between notes due to the SPAN function discontinuities and knob value not quite reaching maximum.  It's weird, but even with just 4 hours sleep I was able to analyze it and come up with a better span function in just a few hours (I've previously spent weeks just on this).  Here it is:

The pitch axis number is modulo multiplied to give "fractional" single note cycles.  The MSb is inverted to shift the phase, with the result viewed as a signed value.  This is multiplied by the SPAN value (raised to the 4th power and >> 12, the multiplication is a fixed point operation), saturated, then the MSb is inverted again to make it unsigned.  When the fractional note value is subtracted from this we get a variable pitch correction area in the center, with linear transition regions outside of this between the notes.  Previously, the transition regions were abrupt drops off of a cliff to zero, and quite audible without some low pass processing action afterward.

This new function alone, dialed back and smeared out somewhat with velocity modulation, can pass as another form of pitch correction, which was a rather unexpected pleasure to find.  OK, I'm hitting the hay, night y'all.

Posted: 4/12/2020 2:01:07 AM

From: Northern NJ, USA

Joined: 2/17/2012

Captain's Log, Stardate 2020.04.11

- Fixed envelope fall / damp scaling.
- Fixed quantized PC glitching: velocity now modulates filter cutoff (finesse me?).
- Also: there was a sign error in abs_vel_sq() causing some PC glitching (reworked this function).
- PC pvel & span knobs (PC_P0, PC_P2) now [0:31](48db).
- Envelope knee knob (E_P1) now [0:63](48db).
- Envelope vvel knob (E_P4) now [0:31](48db).
- PV_FMOD pmul & vmul knobs (M_P0, M_P2) now [0:63](48db).
- Almost out of real time on threads 0 & 1!

Literally every knob that is a "continuous" input to the synth is now exponential, most are explicitly so via knob use value pre-processing on thread 7 (which saves real time).  The 48dB range seems to be quite popular.  The last of the squaring and cubing and 4thing of knobs is gone.  Pulled down exponentials (0 in = 0 out) are a great fit for what ails ya.

The pitch correction velocity now lowers the low pass filter cutoff rather than lowering the error amplitude, which got rid of the last of the glitching.  It's fine the way it is, but may get a bit of polish down the road.  It can go from full quantization to so subtle no one on the planet listening could tell that it's doing anything, with a myriad of options in-between - many more or less transparent to even the player, but arguably an improvement to the performance.  I for one can abide by lots, but being substantially off-pitch generally isn't in that category.

So I think I'm finally ready to tweak all of the presets (post auto-conversion via software).  Presets open up all sorts of possibilities and take an instrument to the next level, but are an update pain when your synth / system is at all a moving target.  And the more quality presets you have the more work it is to keep them updated with the system.  But you really want them as soon as possible to preserve any sonic nuggets you dig up when noodling around - like lightning, providence doesn't often strike twice in the same place.

My problem is I'm new to ALL of this, so there's a lot of dust to settle, and anything changing anywhere in the project can kick it back up all over the place.  But experience gives quicker and quicker solutions, often utilizing constructs / outright code theft developed for other problems in / sections of the overall design.  It might not seem like anything is going anywhere, but to me this project feels very much like a crossword puzzle, where the last 50% of the blanks take the last 5% of the time to fill (minus cabinetry and all that other physical stuff!).  Reach a critical mass of solutions and a reaction can happen quickly, and with very little extra input (compared to the slog at the beginning, anyway).  Ludicrous speed!

[EDIT] Wanted to add that there are some parameters you can surprisingly change quite quickly and sharply without audible telltales.  The volume knee is quite sharp, but that fact is inaudible until you approach an on-off type transition.  The non-rounded pitch quantization function I discussed in the previous post has sharp corners that aren't "clicky" or anything until they approach hard quantization, and even then they're just "steppy" as you would expect.  The pitch axis number drastically alters the (low Q) axis filtering cutoff frequency, and the pitch axis velocity can now drastically lower the 4th order LPF of the pitch correction function, but you won't hear either.  I wasted a certain amount of time thinking certain abrupt slope changes and such in the processing control signals would be objectionably audible, and hence formulated complex schemes to round them off, but it turns out much of that worry was unfounded / unwarranted.  Live and learn.  The one place you have to really worry about fidelity is the output waveform itself - the ear can hear all sorts of distortion (e.g. harmonics) that the eye just can't see.  A second order polynomial - even minus the first order term! - can give you something that looks for all the world like a sine wave, but unfortunately won't sound like one.  Soft clipping looks like it could be done via squaring, but you need higher order polynomials to avoid aliasing.

Posted: 4/12/2020 4:45:08 PM

From: Northern NJ, USA

Joined: 2/17/2012

iPitch Correction!

Ah, here it is finally, the best pitch correction scheme to-date and one I can easily live with:

The top path is the note correction function I showed graphically two posts back.  This is multiplied by (2^27)/(12*(2^32)) to make the full scale note "fit" the real note range.

The bottom path takes a one delay difference to find velocity, squares it (absolute value & gain & shaping), multiplies this by PVEL, filters it via 2Hz low pass first order, inverts the result to change direction, and uses this to modulate CORR, or the strength of correction.

The modulated CORR is then used to set the note correction strength, with the result sent to a 4th order low pass filter where the cutoff frequency is set by either the RATE or SUBR knobs, depending on whether the volume level is above or below -48dB, respectively.  The correction is then added back into the input pitch number to correct it.

I previously had a second order 16Hz low pass filter before the velocity sensor.  This was a replication of the volume velocity code, but it's unnecessary here as I can't hear any velocity noise in the pitch processing.  Low pass filtering after sensing the velocity completely gets rid of clicks and stuttering and such when modulating CORR.

This is working fantastically, all the knobs make sense, have good ranges, and don't interact.

[EDIT] Other than listening to what the pitch corrector is doing while fiddling with the knobs, one thing that really helps when setting things up is watching the LED tuner note display with it's input tap point set to post correction.  I replicated the tuner POST knob on the pitch correction UI page for just this purpose.

[EDIT2] Investigating the useful frequency range of LP4 (rate & subr), 0.24Hz is a useful low end, 1Hz a useful nominal, and 120Hz useful high end.  This is a range of 120Hz / 0.24Hz = 500, which is approximately 9 bits, and 9bits * 6dB/bit = 54dB.  I made a special encoder type for this with reversed 60dB range over the encoder values of [0:31], which puts the nominal rather high at knob setting of maybe 20 or so, but otherwise gives a good range.

[EDIT3] Renamed "rate" to "filt" and "subr" to "subf" - increasing the encoder value lowers the filter cutoff frequency.  Range is now 48dB (256:1), and when the knob is zeroed the cutoff is set to ~1kHz.

Posted: 4/15/2020 3:46:52 PM

From: Northern NJ, USA

Joined: 2/17/2012

Deep In The Cups

Time to synthesize more "bells"!  This time the natural sort found in the cupboard:

Preset names and order of recording, clockwise from left: martini_0, martini_1, wine_0, wine_1.

Here's my results: [MP3].

The first sound is the real martini_0, followed by the synthesized version, then martini_1, etc.  Audacity was doing it's little "snick" thing during recording, so I updated it, but in the end had to increase the recording buffer to get rid of it.  You'll unfortunately hear this in the real / synth recordings.  So, at the end of the MP3 I put just the four synthesized glasses, without the audio issue.  For the real recordings I'm tapping the glass rims with the body of a plastic pen.

Audacity has a very nice FFT view where the cursor sticks at the high points, making resonance frequencies and amplitudes quite easy to read, particularly with a linear frequency axis.  For all of the voices I doubled up the lowest strongest resonance, and slightly offset one via the PV_FMOD system, to give a low frequency beating sound which really adds to the realism (if you listen to the very last sample in the MP3, I vary the beat a little near the end of the decay with my pitch hand).  As before, the higher resonances are very roughly synthesized via the inharmonic resonator, and I made almost no attempt here to make that part of it high fidelity.  The real recordings are in mono, I've got the resonator providing a bit of pseudo stereo for the synthesized version.


I'm hearing noise leakage due to the level being PV modulated with limited dynamic range, the last major thing that needs to be addressed in the SW. 

Yesterday I revamped the type system a bit, the exponentially scaled knob offerings went from 24dB, 48dB, 72dB, 96dB to 48dB, 60dB, 72dB, 84dB - so 12dB steps rather than 24dB steps.  24dB wasn't being used for anything, and 84dB is now used for all resonance knobs, which seems to be a better fit than 96dB, which was over-representing the high Q end of things IMO.  I also made two exponential type groups (normal and reversed sense) that aren't pulled to zero (purely exponential).  For reference, 48dB is 8 bits, or 256:1; 60dB is 10 bits, or 1k:1; 72dB is 12 bits, or 4k:1; 84dB is 14 bits, or 16k:1.  If I really need 96dB (16 bits, or 65k:1) I can just square a 48dB knob (though this only works well for the non-floored sort).

The floored 48dB knob type gets used a lot in the design, and 48dB corresponds to the useful volume and pitch ranges.

Posted: 4/15/2020 6:39:08 PM

From: Germany

Joined: 8/30/2014

Time to synthesize more "bells"!

Now, if you add some whistles, nobody could claim anymore your device could still lack anything, right?
(well, I don't know whether those are all the bells...)

A few of them sound more like triangle or metallic bell than glass. If that wasn't your goal, I'd still not "improve" them (towards glass, discarding their current versions), those are nice sounds on their own.

Posted: 4/16/2020 5:22:24 PM

From: Northern NJ, USA

Joined: 2/17/2012

"Now, if you add some whistles, nobody could claim anymore your device could still lack anything, right?
(well, I don't know whether those are all the bells...)"   - tinkeringdude

Ha ha!  I actually do have a human whistle...  Might make a nice joke marketing blurb ("with all the bells and whistles!").

"A few of them sound more like triangle or metallic bell than glass. If that wasn't your goal, I'd still not "improve" them (towards glass, discarding their current versions), those are nice sounds on their own."

My only goal was to replicate the real thing (and of course to gain more experience in doing so).  Some do sound like triangles, I'll have to try that next (though I suppose I've got too many of these bell-like presets already).

Posted: 4/19/2020 8:55:12 PM

From: Northern NJ, USA

Joined: 2/17/2012

Dropping In

It's been an intense couple of weeks of polishing the D-Lev software.  I made a dual vmod hinge for the pitch preview: when vmod is positive the hinge point is at the 0dB point, and hen vmod is negative it's at the -48dB point, with both hinging downwards.  This makes the "prev" knob setting the maximum that will occur (sans any pmod addition / subtraction, which itself hinges at 440Hz).  To implement this I needed a new type, linear but dropping to zero the low end, much like my offset exp2 types:

Mathematically, this is a simple sloped line combined with the 16th power, so it's a trivial 16th order polynomial.  The one shown above gives nominal 48dB control slope until the knob is around 1/4, then it drops to -96dB with the knob set to zero, and this is a good fit for volume type functions in the linear domain.

I also re-introduced the noise volume drop, which is a variable drop in gain above (in a dB sense, not necessarily a physical hand sense) the knee vloc point.  For a day or so this was a +/- control, with positive values dropping the noise amplitude the closer one gets to 0dB volume, and negative values dropping the oscillator level instead, but that felt too gimmicky.  For a bit longer before that it was a +/- slope for the noise above the knee point, but there don't seem to be many natural scenarios where you want the noise level to increase faster than the oscillator level, and it made the hinge point more difficult to deal with.  Noise higher at the knee and then not increasing as fast as the oscillator towards 0dB gives an OK breathy voice type sound.

So I'm maybe actually, really, genuinely, literally at the point where going though all my presets and aligning them with the current synth makes sense.  I like getting new synth ideas, and coming up with new ways to scale the knob values, but at some point it has to stop for anything else to move forward.  All of this may seem like minor dithering, but one crappy feature can hobble the whole thing.


Did someone mention triangles?  Here is my attempt to synthesize 6" and 8" triangles: [MP3].

As usual, the real 6" is first, then the synth 6", then the real 8", then the synth 8".  The 8" has something going on that isn't obvious from the FFT spectra, I had to really mess with it to even get this close.  The 6" sounds pretty good.  I think the inharmonic resonator could be used to better advantage here, but I couldn't be arsed to.

Posted: 4/20/2020 3:27:58 AM

From: Northern NJ, USA

Joined: 2/17/2012

The Wind Cries Mary - [MP3]

(sorry about the Audacity clicking)

[EDIT] I downloaded a simple Gnome audio recorder, which recorded clicking too, so I figured it probably wasn't Audacity.  Tried several settings in the Pulse Audio config files but those only made it worse.  At one point Audacity started playing back really weird, so I uninstalled it and installed the older version in the package system.  Finally, I examined alsamixer, it seems setting the line-in volume too high creates the clicking, so (for now at least) I can record cleanly.  I don't know why recording audio on a PC has to be this difficult, it's literally just grabbing samples from an ADC and sticking them in RAM.  I'm amazed video works at all.

Posted: 4/22/2020 3:48:00 PM

From: Northern NJ, USA

Joined: 2/17/2012

A Bridge Too Far

I find myself humming a old popular melody ("Dream A Little Dream Of Me" in this case), so I run over to the D-Lev and find I can play it OK, so look it up on YouTube to see what keys people played / sang it in - only to find the bridge (or intro, or some other significant portion) isn't in my head and almost completely alien to me.  Kinda puts a damper on things!  Though it is an opportunity to get to know these tunes better.

PV_MOD Plateaus

If anyone told me I'd develop the D-Lev musical filters almost immediately, the oscillators over a period of time, but the modulation and knob scaling would never go to bed, I would have thought them crazy - as I naively assumed more the opposite - but here we are.  Knob scaling in particular is really nuanced.  How do you spread the minimum number of detents over the maximally useful range?  Often there is some zero point that you want more resolution around, with some nominal range used most, with the max doing something weird but possibly useful as an effect.  Offset exponentials did this for a ton of settings, but I'm finding the pitch and volume modulation knob curves more useful when they aren't strictly linear.  So yesterday I played around with a squared plateau for these knobs (pmod & vmod):

The signed knob value is XORed with the full MSb, multiplied by 2 to restore full range, squared, shifted right once to divide by 2, then XORed again to restore signedness, for a total of 6 opcodes.  You could instead save the sign, square, multiply by 2, and restore the sign, but the first process is more generic and can be used to generate multiple plateaus of any order.  Indeed, I use a cubed triple plateau for the oscillator offset and harmonic multipliers.

Anyway, it's working quite well and I've got all the weights in useful ranges.  What made me think of doing this was the squaring of the new noise volume drop knob, which is a vmod function.  The only mod knob I haven't squared or plateaued is the noise PWM pmod, as large values don't seem all that useful (you generally either want noise PWM proportional to the period or constant with frequency, or something in between).

Wacky Tobaccy

All the oscillator work on PV modulating the harmonic multiplier (it now all happens in the linear domain followed by EXP2) makes me wonder if there is a more useful combination that would fit on two UI pages (14 knobs).  Harmonic content (and PV modulation of it) is now global.  The harmonic multipliers are separate (though PV modulated commonly).  There seem to be a lot of "weird" non-harmonic harmonics type settings available, but they aren't all that fundamentally different from each other.  Maybe have more oscillators (there is plenty of real time left on the thread) or have them intermodulate each other ala FM (PM actually)?  Feels like I'm missing some basic opportunity to do something more different and/or useful.

Posted: 4/23/2020 2:41:20 AM

From: Northern NJ, USA

Joined: 2/17/2012

Whither FM?

Outside of EPs, bells, and other metallic sounds, how useful - really - is FM synthesis?  Particularly as it applies to a digital Theremin?  A handful of formants plus a delay based resonator will do more bells than you can shake a stick at.  UFO woo-woo stuff is sorta fun, but you're probably not going to play a melody or anything with it.  I'm having a hard time coming up with reasons to have more than three or so oscillators doing anything.  I think FM in the first place was an early way to somewhat get around the need for filters, as various timbres could be created without them.  But, again, once you have those filters, is there a huge point anymore?  For some perverse reason I'd like to have gobs oscillators in there, droning away and earning their keep somehow, but can't imagine any realistic scenario where they would.

You must be logged in to post a reply. Please log in or register for a new account.