I’ve built a playable, MIDI capable, polyphonic FM synthesizer using an 32bit ARM Cortex M0 microcontroller and an audio codec. This was a learning experience for me. You can find the finished form of the system in following two images.
Sound samples for the system can be found from the following two links.
- https://soundcloud.com/ihsankehribar/daft-synth-stereo (Midi notes are coming from computer)
Please note that, there is no single tone for this device. Almost every parameter is tunable on the fly. In the future I may build a user interaface with buttons and knobs for this device but at the moment I’m just following change software – recompile – burn path for creating different sounds. Not much effective but works at the moment. 🙂
Couple of months ago, I started this idea of creating a synthesizer with Atmel’s Xmega32E5 8bit microcontroller. You can find the code base for this project from here: https://github.com/kehribar/xmega_fm-synth
I hit some limitations with the Xmega system and wanted to go with an 32bit microcontroller. I ordered / designed couple of breakout boards and before moving on the final PCB form I prototyped the system.
I used an ARM Cortex M0 core STM32F031 for the project. Cortex M0 cores don’t have anything really extra than having a 32×32 hardware multiplier for DSP purposes. Cortex M3 and M4/M4F have specific DSP instructions and they would have been much more helpful for such a computational intensive task, but I just wanted to try what can be done with a low cost, entry level ARM chip. That specific microcontroller also have I2S and DMA module which is essential for this project.
For the system clock, I’m using the internal PLL to generate 48 MHz clock but I left optional XTAL footprint for future possible use.
R1,R2,R3 and R4 is used to slow down the edges of I2S signals to lower the high frequency noise a little bit. I put 49.9 ohms in the real circuit.
This is 2channel, 24bits, 192kHz sampling frequency capable audio DAC from Cirrus Logic (previously Wolfson).
Best thing about this codec is, there is no need for DC blocking caps on the output. That means first of all no need for big bulky capacitors and secondly low frequency response of the output is much better since there will be no need for a high-pass filter to remove the DC level.
Also, this codec generates a negative bias voltage via internal charge pump and I’m tapping that voltage from the codec to power the opamp’s negative supply.
Opamp that I used is MCP6002. It is not a low noise or audio grade opamp but it is rail to rail input/output and have enough bandwith and noise level for a just voltage follower.
This is a second order Sallen Key low pass filter followed by a single order passive low pass filter. Component values should have been properly selected for the best rejection curve, but I used 4.7 k for resistors and 4.7nF for the capacitors which gives roughly 7.3 kHz -3db point.
LDO footprint is compatible with generic 5 pin SOT23 LDOs. Specifically I used Micrel MIC5317. There are two seperate regulators, one for the microcontroller, other for the codec + output filter. There are also ferrite beads at the input stage of the LDOs to filter out some high frequency noise as much as they can.
Optocoupler decouples the instrument ground with the controller board ground and eliminates possible ground loop issues. Also, optocoupler acts as a voltage level conversion between whatever MIDI keyboard sends and 3V3 microcontroller level.
In the v0.1 hardware, I mixed pin#4 and pin#5 of the connector. I patched it with knife + patch wires on the PCB. Easy mistake! 🙂 Schematic is corrected.
I tried to follow Henry Ott’s advice for this layout. You should read his excellent article on the topic. http://www.hottconsultants.com/techtips/split-gnd-plane.html
I partioned the analog and digital portion of the layout seperate and connected two portions over a small bridge and passed every neccessary signal between two portions only on top of that bridge.
Sizewise, I just sticked to 5×5 cm rule of the low cost PCB fab houses though it could have been smaller if needed.
I used http://dirtypcbs.com/ for the PCB manufacturing.
GitHub repository for the firmware is this: https://github.com/kehribar/stm32f031_template/tree/master/_synth This particular firmware is a part of my trial on creating a generic framework for STM32F031 microcontroller. You can check the base repository for other examples.
I used GCC compiler that I downloaded from http://launchpad.net/gcc-arm-embedded. Telling the Makefile where you unzipped the toolchain is enough. For the programmer, I used an STM32F4 Discovery board. After removing two jumper headers, that board acts like a generic ST Link v2 programmer. Calling make iterate on the command line just recompiles everything and flashes the board via OpenOCD under 10 seconds.
For More Details: Polyphonic FM Synthesizer with STM32F031