The Delta Flyer

A "clean room" implementation FM synth using the mbed libraries.

Similar projects worth following
In this project we built a prototype board and firmware that turned an STM32F446RE Nucleo board into a working FM synth keyboard.
This implementation used no pre-existing synth chips or anything like that, just a Nucleo board some pots and switches and the Mbed library (there wasn't time to code up tuned assembly and the digital IOs weren't performance critical). This is a hell of a chip

The concept of this device is to be a tool for experimentation with FM synthesis. While a normal professional FM synth can be programmed it is not usually on the fly. By putting the scalar parameters of the envelopes onto slider potentiometers, and the ratio and any other future integer options onto dedicated switches a retro-enmodulator enables real-time tuning of the sound of the instrument.

Unfortunately I can't embed a video here apparently so check the links for the youtube playlist.

The main source code repository and the youtube playlist of demo videos are in the link

Further work:

The "Delta Flyer", the prototype was built with solder-assisted wire wrap and required a keyset from a "donor" keyboard to work.  It's repeatable but it more or less exchanges a working, well-designed (if kinda lame) instrument for an experimental music device.

The next version is going to have an opto-isolated (that's what the reference design calls for) MIDI interface.  It's also going to be called something different (current idea retro-enmodulator) so it can be sold, even if not by me.  Construction will be on actual PCB (very very sparse with the pots dominating the surface area) still mostly through hole and leveraging the Nucleo through the connectors.  I'm also planning to make use of so-called rotary "DIP switches" instead of the current true dip switches so the digital parameters (e.g. FM ratio, and probably pseudo-waveform choices if added) are legible on the fly to people who haven't started to memorize hex by osmosis.  The form factor will be a tabletop synth (as opposed to a keyboard or rack mount), an unusual form factor but I really like the precision the huge pots give.

To that effect I've started teaching myself to make KiCAD footprints.  Although James has Eagle I don't expect he'll continue adding to the project.  No matter what it'll be slow going, in off time with job searches going on.


KiCAD footprint for those max-size slider pots.

kicad_mod - 1.28 kB - 12/28/2017 at 06:53



Octave script generates carrier phase increments array C++ code declaration from sample depth and frequency.

m - 417.00 bytes - 12/16/2017 at 21:36



Octave script generates C++ header and implementation file for a 4097 entry 16-bit LUT of the first quadrant of a sine wave.

m - 470.00 bytes - 12/16/2017 at 21:36


  • 6 × 4.7kohm through hole resistors 1/8 watt
  • 9 × 10k ohm through hole resistors 1/4 watt
  • 1 × 6-position double sided 0.1" header
  • 1 × 8x2 position double sided 0.1" header
  • 1 × 3.5mm stereo jack

View all 15 components

  • Keeping better tune

    Steven Clark10/03/2018 at 02:03 0 comments

    So the original Delta Flyer has a 20khz sampling rate driven by being an integer number of microseconds for the MBED API's timer interrupt.  I'm a little worried how much jitter that has, and maybe the problems that kept 40khz from being stable relate to limits of the API.  For example MBED can't record ultrasound with basic analog input because every time you ask for a sample it take 3 samples at I-think-it-was 5 microseconds each and sends you the mode.  I don't really have plans to pursue CD audio but both a faster sampling rate and operation with less jitter are desirable.  Fortunately ST provides.  The very-definitely sold at a loss Nucleos include all the bells and whistles, among them a 32.768khz RTC crystal.  It might not be suitable for a board-nonspecific design but for myself and anyone who wants to work form one of these it should be great.

  • Shrinking the BoM to something almost reasonable

    Steven Clark10/03/2018 at 01:54 0 comments

    Part of the justification for the giant juicy slider pots on the Delta Flyer (and Delta Flyer 2 when I can scrounge the time to assemble it and move the keyboard up for testing) is that when you' go looking for potentiometers with physical controls on Digikey or the like they're all about a buck anyway so you might as well get nice ones.  Also the other parts like the DIP switch bank and the DIN jack aren't cheap either.

    This isn't the case if you buy from overseas.  I'm seeing 10 packs of knob or volume-wheel pots for 70 cents and 4-packs of rotary DIP switches for 5 bucks from the usual places.  Combine this with newly-standardized 3.5mm MIDI (and the assumption that adapter cables will be built) and we're looking at vastly less board space used.

    Suddenly a board run for kits is an actual semi-reasonable idea.  They won't be as gloriously physical as the DFs, but a retroenmodulator board could fit within the footprint of the Nucleo connectors and probably have room to spare for a badly needed audio amp, so it works with something other than powered computer speakers.  Think something on the order of $20, probably with a margin.  Assuming I ever find the time.

  • Possible alternative algorithms

    Steven Clark06/12/2018 at 19:50 0 comments

    Since this synth is fully software it will be possible to re-program for other algorithms, someone just needs to make the firmware.

    An easy one would be subtractive synthesis from a square wave.  FIR filters would allow pulling harmonics out of a square wave to make other sounds.  Pretty standard stuff.

    A more modern technique would be "simulation" techniques involving "digital waveguide synthesis" where a digital delay line and some filtering shape an initial impulse into a note.

  • Better IO pin choice

    Steven Clark06/04/2018 at 01:54 0 comments

    When we made the first prototype I didn't find the PDF schematics for the Nucleo 64 boards.  We found that several of our pins didn't work for the desired purposes and we needed to rearrange busses using non-continuous pins. Fortunately this is easy with mbed, just probably bad for performance.  Well I have the PDF schematic now so here's some pointers:

    Today I learned a schematic symbol for jumpers or at least solder bridges, that's what all the arc symbols are.

    ADC pins:

    PA_2 and PA_3 are used for the UART to the ST-Link(we already knew that, and the bridge is closed by default obviously, bridge SB_61 to connect the ADC Vref to AVDD on PA_3, closing SB_62 and 63 would connect these pins to the PA_2 and PA_3 pins on the header)

    PA_4 and PA_5 are the DACS (we knew that too)

    PB_1  connects to its pin by SB64 or alternatively to AVDD by SB65, to the pin is the default

    That leaves PA_0, PA_1, PA_6, PA_7, PB_0, PC_0-PC_5

    Digital Pins:

    PA_13 is TMS (I guess JTAG Test Mode Select)

    PA_14 is TCK (I guess JTAG test clock)

    PB_3 is SWO (I guess JTAG Single Wire Output) 

    PB_11 is connected to ground by a 4.7uf cap and apparently has no header pin

    PB_12 is connected to the header by SB37 instead of AVDD by SB34

    PB_13 14 and 15 are different pins on the F373 chip and there's a set of solder bridges that could be used to rewire this board for that chip

    PC_13 is connected by SB17 to a pullup to VDD and Button USER to ground, which appears to have an RC circuit in parallel, probably to debounce.

    PC_14 and PC_15 are connected to the 32768hz crystal

    PH_0 and PH_1 can be connected to an 8mhz crystal across unpopulated R35 and R37 to achieve independence from the ST link which is usually providing it's own clock over PH_0, I don't know if PH_1 can be used for anything in the current config.

    PD_2 seems to be an available pin somehow

    PF_5 does not exist in this chip instead there is a VDD hookup through SB43, SB47 would connect it to a pin for chips that have it

    PF_7 does not exist in this chip instead there is a VDD hookup SB31, SB30 would connect it to a pin for chips that have it.

    So I know which pins not to use.

  • Building a better sine function

    Steven Clark05/03/2018 at 22:10 0 comments

    FM synthesis requires a lot of calculation of sine values, so speed is of the essence.  My worry was that a normal sine function from a math library might concentrate on accuracy over speed and would take an unknown amount of time.  To counter this I made my own, mostly by cheating.  The original fast integer sine function for the Delta Flyer was lookup table based.  An array of 4097 16-bit sine values was calculated with Octave and written to a source file.  Mirroring allowed us to store only a quarter wave with the most significant 2 bits of the angle being the quadrant determining which way to proceed into the table and what sign to give the output.  To deal with the missing 2 bits of entry precision 2 entries were pulled from the table and the bitshift constant multiplication of the last 2 entries used to create a linear interpolation for values between them.  This worked, worked well, and was in line with what I remember of how the Yamaha chips were supposed to work.

    I never did actually check if a calculated sine was slower than my LUT method.  I did, however know that the method we used wasn't fast enough to allow a 40khz sampling rate with an arbitrary number of notes simulated with at least an earlier version of the synthesis function.  If the synthesis interrupt routine ran over it would be called again before completion, the DAC would never be updated with the new volume, and the input routines would be starved turning the synthesizer silent and freezing it.  The simple solution with only some days to work with was just to ignore the upper half of the human hearing range and set the sampling rate to 20khz.  This was good enough to allow full sit-on-the-keyboard polyphony and cover the dominant tones of all the notes in our 49-key set anyway.

    So, as a thing to do to keep myself technical while concentrating on trying to land my new-grad job I decided to actually benchmark and confirm that assumption.  To do that I needed a calculated sine to test against, unfortunately I wasn't able to get the ARM DSP sine implementation out of my libraries (I'm assuming MBed doesn't keep it to ensure a platform-neutral library), so I just had to make my own.

    The gold standard of calculating the sine wave with basic arithmetic is what's called a Taylor series: an infinitely long polynomial in the form of an infinite summation that fits a pattern. 

    In the case of sine.  There's a few problems with this, first of which is that it takes literally all of eternity to calculate.  The second is the number format: we want to pass in integers or, thought of a different way, fixed-point values between -1 and 1 while the above polynomial takes in radians, from -pi to pi.  A few scaling constants could fix that, I guess.

    A nice helpful thing is that the above infinite polynomial is accurate for a sine wave of infinite length.  With a little bitmasking all we really care about is the first cycle, as said above from -1 to 1.  And our application is audio so the estimate doesn't need to be perfect in shape, just very good.  If we stop the summation at n=4, the x^7 term of the polynomial we get a graph that's the right shape.  The only problem is it crosses the X-axis at 0.98 instead of 1, about 2% early.

    The source of this error is that the Taylor series is only maximally accurate with all it's terms.  if you cut it off early it's not meant to give you an estimate of the same order.  But we know an estimate of this order will work and give us about the right shape.  So let's make our own, besides, multiplying everything by pi is getting old.

    We know from the Taylor series, and from the basic fact that our desired graph flips when x goes negative that the polynomial we desire will consist only of odd-order terms.  Now what are the desired features of...

    Read more »

View all 5 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates