I saw a cool audio synthesizer project on Twitter I wanted to share here. The README has all the details. Enjoy!
Here is the synth generating a 1k saw-tooth wave, displayed on a homemade oscilloscope built from a BlackIce Ice40 FPGA (using icestorm), a Gameduino 3 screen, and an Alinx AN108 AD/DA device.
Sensational! I don’t suppose you have any more details about the scope anywhere? That looks awesome!
… also, thanks Luke for the shout-out, and for all of the amazing work you’ve put into TinyFPGA!
I’m currently in the process of trying to figure out how to get something a little more musical out of the synth, and I’m torn between investing my time in:
- USB UART + computer control (maybe I could borrow from the TinyFPGA bootloader USB serial code here?).
- USB MIDI (seems a bit more open-ended in terms of effort required - involving MIDI standard as well as USB, but this is probably more musically useful?)
- RS-232 UART (seems like this should be relatively straightforward?)
- Plain old non-USB MIDI (again, more hardware including an optoisolator, but perhaps less difficult than USB MIDI)
- a state machine internal to the FPGA for playing tunes and/or drum sequences (easiest, but perhaps least useful).
- exposing the synth to external pins and driving it from another microcontroller.
Does anyone have any thoughts? How would you like to be able to interface with a tiny synth? What would be most useful?
I’m currently leaning towards the USB MIDI angle, but I suspect that I might get out of my depth fairly quickly - the USB standard is huge! as is the MIDI one!
for hints on how I should improve the Arduino code.
Thanks for the links! It looks like you’ve been up to some really interesting stuff
Also, how did I not know about GameDuino until now?!
The USB UART would be generally useful, not just for your project. I have used siimpleuart from the picosoc example for what I think you mean by an RS-232 UART - see https://github.com/lawrie/tinyfpga_examples/tree/master/hello_world.
The state machine sounds worth doing if its easy.
USB Midi is part of the USB HID standard, isn’t it?
Can the synth emulate different musical instruments?
For USB Midi, wouldn’t you want to be able to plug in a USB Midi keyboard? That means that the FPGA would need to be a USB host. That is a much harder task than being a USB device which the bootloader implements (and I am sure that was hard enough). I have looked for USB host FPGA implementations but they seem to be rare and partial. Doing all the USB enumeration stuff without a CPU sounds very hard, and implementing the electrical interface without extra hardware, may not be possible. If you were to use the existing USB connector, it would need to use USB OTG, and I don’t know if it does that. Also if you used that connector for a Midi keyboard, you would probably need a separate power supply.
I may have misunderstood what you want to do with USB Midi.
Good point re: the USB MIDI - I hadn’t really made the connection that a USB host might be substantially harder to implement than a USB slave, but it makes sense now that you mention it. Shame that - I’ll have more of a think about the other options.
As far as instruments go - the synth at the moment should be capable of producing most of the sounds that a 6581 SID chip (ie. Commodore 64) could. That is, apart from the filter effects enabled by the SID’s analog filter section. I’d like to add support for filters, but I’m not sure how much I’ll be able to do in the space/timing constraints available.
Adding extra features like (simple) wavetable synth of different sounds should also be pretty straightforward too. I think it should be possible to create some interesting sounds/instruments with the basic building blocks there
I did notice that @lukevalenty’s Retro Computer board (https://www.tindie.com/products/tinyfpga/tinyfpga-computer-project-board/) has a USB A female connector for connecting USB keyboards and mice, so I don’t know whether he is planning a USB host implementation. Most cheap FPGA boards use the simpler PS/2 interface for keyboards and mice.
I see that David Bank’s Ice40Atom project has an implementation of the 6581 SID -
I have used that on the Blackice II, but I don’t know much about the chip’s capabilities.
That’s awesome! Whoever wrote that was obviously fastidious about accuracy - I see they’ve quoted Bob Yanne’s interview throughout the code!
Mine is more of a loose approximation… you might even say it’s the kind of approximation that someone with no mechanical sympathy for hardware might write as their first verilog project ;-).
That codebase has given me some excellent reading material though! Thanks so much!
What would be useful to me is the serial (uart) interface and/or an SPI interface, for the interface to another microcontroller. (The fpgafun site has a suitable SPI slave implementation).
I am thinking that I could use it on my BlackIce device (which includes an STM32 microcontroller) and give it a Gameduino 3 user interface, like my oscilloscope.
Those interfaces are also suitable to make it controllable from a Raspberry Pi.
Something like this but with your synth replacing the oversized Roland one - https://www.youtube.com/watch?v=7mhZtEOGxIU.
If you implemented midi over uart (RS-232), you could use this device to attach midi controllers:
Or you could just use a breadboard friendly midi jack (https://www.adafruit.com/product/1134) and an optocoupler, It looks like midi is just a uart at 31250 baud, through an optocoupler, so the code on the FPGA is just a uart and simpleuart will do the job - https://github.com/tinyfpga/TinyFPGA-BX/blob/master/examples/picosoc/simpleuart.v.
It is so lovely to see the Tiny Ecosystem grow big.
So I’ve managed to get a simple “song” (in the loosest sense of the word) player example up and running now, which at least proves to me that the concept works, so I’ve ordered some opto-isolators and MIDI connectors and will start work on a MIDI/uart based demo soon
I’ve also started implementing a few effects, such as an exponentially-weighted moving average low-pass filter (because of it’s very simple, single-multiply implementation), and a variable delay-line flanger…
The extra features, combined with the multi-voice song-player has seen me pushing up against a few limits of the 8K chip I think. I had to lower the sample bit-depth from 12 to 8, and, even then, arachne-pnr took about 30 minutes to place and route things! I guess now is probably a good time to learn a little more about the mechanical sympathy aspects of verilog
That simpleuart code looks like a good place to start with MIDI Lawrie. A bonus of the protocol similarity is that it should make it easy to drive from a PC while I wait for the required parts.
There is a version of simpleuart that I used for my Brainfuck project that takes the speed parameter (cfg_divisor) as an input, rather than having to mess around with the current way of setting it, which was designed for the memory-mapped picosoc interface. I also changed the tx and rx data inputs and outputs to 8 bits. Again they were 32-bit because that is the way picosoc works.
I’ll try your latest example. The C chord example worked fine for me.
Cool… I just merged the flanger code across to develop. Be warned - it might take arachne-pnr quite a long time to do it’s thing!
> There is a version of simpleuart that I used for my Brainfuck project that takes the speed parameter > (cfg_divisor) as an input, rather than having to mess around with the current way of setting it, which was > designed for the memory-mapped picosoc interface. I also changed the tx and rx data inputs and outputs to > 8 bits. Again they were 32-bit because that is the way picosoc works.
Yep, nice work - I was just looking at that too, and was thinking about doing something similar.
I should probably just use the code as-is, but I have a bad habit of wanting to “hot-rod” things
This afternoon I started out trying to document what Clifford had written so that I could understand it a little better, but then, once I’d managed to convince myself what was going on, I got a bit distracted, and went down the path of starting to build something a little more elaborate.
I have in mind a UART that:
- has 512-byte TX/RX buffers (using the ICE40 dual-port SBRAM_512x8 blocks)
- uses an accumulator rather than a simple clock divider to allow for more accurate average bit-to-bit timings
- has programmable baud rate (as a parameter to the module)
- has support for different data/parity/stop-bit settings.
It’s a work in progress, but if/when it ends up working, I’ll throw the code up on github somewhere.
There’s a good chance that if the MIDI parts arrive before I finish I’ll just use simpleuart and put this one on the backburner though.
The uart in icodsoc is a bit like that: