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

Posted: 5/16/2019 2:36:05 AM

From: Northern NJ, USA

Joined: 2/17/2012

2nd Order Bass & Treble EQ

It takes more real-time, and a bit more code, but second order is definitely the way to go for bass and treble EQ, even if the goal is a first order roll-off:

As seen above, even with both controls maxed out there is relatively little midrange interaction with second order filters.  The real-time and code spent linearizing the control for the first order case can be spent on the extra filtering of the second order case, as two first order filters in a row tuned the same way don't need any special treatment in that department.  Here's the updated spreadsheet: [LINK].

[EDIT] I was able to refactor the gray filter, so that it and the bass and treble tone controls now employ the same base subroutines.  I'm getting near the end of available processor memory (>93% utilized), so it's a lucky thing that the SW side of this feels like it's near to wrapping up.

[EDIT2] These kinds of EQ controls on something like a home stereo can be rather mild, so you could probably get away with first order filters there.  On a synth they're more of an effect, and second order gives you more "oomph".

Posted: 5/17/2019 5:35:09 PM

From: Northern NJ, USA

Joined: 2/17/2012

Two Knob Preset Load / Store Considered Harmful

Up until now the D-Lev prototype UI (user interface) has employed two knobs for loading and storing presets.  Preset slot 0 was for system, or global, presets, while slots [1:127] were for user presets.  To copy one slot to the other was as simple as setting the "Load" and "Stor" knobs to the desired slots and initiating a write (by pressing the auto-calibrate knob).  To save only the system parameters, one would set the "Stor" knob to 0 and do a write.  This would also set the power-on slot to whatever slot the "Load" knob was set to when saving the system parameters.

Roger prompted me to consider implementing a two step store to make things safer, and a short while ago I did so.  A couple of days ago I accidentally overwrote my violin preset (waa!) because I forgot to set the Stor knob correctly during a write.  This made me feel that the two step store was perhaps not all that fundamentally safe with two knobs, and that the two knobs were the root of the problem.  There's too much going on during a write for my poor brain to pay full attention to all the important details.

After some thought I've implemented the following:

There is only a single "Load" knob now, and it functions thusly:
- Preset store also stores system parameters, there is no special system slot visible to the user.
- System parameters load only at power-up.
- User slots are [1:127].
- The slot that was last written to is the power-up default.

So the way to, say, copy slot 3 to slot 7:
1. Set "Load" knob to slot 3.
2. Press "C/wr".  "?WR?" appears on the LCD and an LED lights.
3. Set "Load" knob to slot 7.
4. Press "C/wr".  The write happens and "?WR?" goes away and the LED extinguishes.

Doing anything other than twiddling or pressing "Load" while "?WR?" is on the screen blows out of the write.  If you changed "Load" to a different slot before the blow-out, that slot will load after the blow-out.

During the write arm, I can see the FPGA board LED light up through the translucent enclosure, and think it is a good addition as it draws your attention to something very important going on.  On a production model this would be a panel LED.

The final implementation will likely have negative ROM preset slots (once I work out a way to save and restore presets via the serial port - probably via TTL script).  The plan is to have slot -128 be the invisible system preset, slots [-127:-1] be ROM "factory" presets, and slots [0:127] be R/W user presets.  A "factory reset" would then overwrite the user presets with the factory presets.  I'm on the fence regarding preset 0, not sure whether to force it to be the power-on default, or keep the last slot written as the power-on default.  The last slot written method is sort of a superset, as one could always write the desired default voice to slot 0.

Since this code is executed on thread 7 it was kind of a bear to get it working correctly.  And the logic paths are surprisingly deep and broad.

Getting rid of the "Stor" knob on the main page opened up some prime real estate for development, and I stuck the global volume there.

Posted: 5/19/2019 5:56:49 PM

From: Northern NJ, USA

Joined: 2/17/2012

Everyone Loves Raymond Presets!

Tera Term is an open source terminal emulator that I've been using to communicate with my Hive processor on the D-Lev prototype.  Tera Term has a TTL macro language that is feature rich enough to easily automate many tasks and, coupled with my HCL command line interface, I'm able to upload code to the EEPROM, peek and poke memory locations and registers, etc. 

The SPI commands I implemented in HCL allow me to read and write the EEPROM directly, and since the presets are stored in there (along with the SW image), one should be able to manage presets off-line.  Indeed, this is what I just accomplished.  Took maybe a day total, and a lot of that was coming up to speed on various TTL commands that I've never used.

I wrote a TTL macro that reads the info contained in a specified D-Lev preset slot and writes it to a specified file.  And I wrote another that reads data from a specified file and writes it to a specified the preset slot on the D-Lev.  TTL has a "filenamebox" command that conveniently lists the files in a directory, which came in quite handy.  And I put in a global loop to automate multiple slot operations.

Works like a champ!  I should have done this ages ago, it would have made tinkering with the preset code much less nerve wracking.  Now users (currently just Roger and me) can exchange presets!

The macros accept as valid input the preset slot range of [-128:127].  This signed range maps to the unsigned EEPROM address range in the usual modulo fashion:
  preset slot [0:127] => EEPROM addr slot [0:127]
  preset slot [-128:-1] => EEPROM addr slot [128:255]

The preset knob on the D-Lev will be changed from [1:127] to [-127:127], with slot -128 (128 unsigned) being the (inaccessible directly) system parameter slot.  The negative presets will be read-only via the D-Lev parameter management system, but will obviously be readable & writeable via the TTL macros.  This, along with a simple factory reset, will be, AFAICT, among the last major SW edits / additions.

[EDIT] Just finished the D-Lev SW edits to enable the preset range [-127:127], uploaded the system params to slot -128, and BAM! factory presets are a thing.  Now to code a factory reset...

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