Arduino 8 note polyphony MIDI Synth

So I decided to actually make some documentation, and so I thought I'd make a new topic.

Anyway, here it is, my Arduino synth!

It has a MIDI input, output, and thruput; 6 buttons and 6 pots for input; an 8*16 RG LED matrix; a 9-bit audio output, so far capable of synthsizing 8 note polyphony wavetable synthesis, including a variable pulse width square wave, with volume control on each note.

Here are all the insides of the synth:

Click on the photo to go to the Flickr page, where there are mouseover notes on the parts of the synth.

Here's a photo of the front face:

The code of the synth has a few main parts: the MIDI handling code, written by me using the MIDI library; the LED matrix and button input code, which both use hardware SPI; and the synthesis interrupt routine, which is called at 32500KHz. This was written in assembler for optimal speed, since the interrupt is called every 512 clock cycles. Major thanks to joemarshall, his synth is here, and the meeblip project, here, for help coding the assembly code. (I had never before written in assembly)
I designed the sketch to be easily expanded; the MIDI input handling can handle 8 notes at once on each of 4 channels, even though only 1 channel is currently used. There are other things that aren't optimal for the current capabilities, but will be useful once I add new features.

Code in the next post!

Nevermind, it'll be much easier to just attach the files. I used a bunch of tabs to make things more organized in my eyes, so I made a zip file of the sketch folder, with all the neccessary files. The MIDI library is the one here, and the SPI library is the standard one included with the IDE.

Here's a video!

MIDI_synth_test_assembler.zip (8.05 KB)

I realized that the code I posted doesn't actually work!

It compiles and all, but it seems like the arduino is running out of SRAM: commenting out the triangle waveform fixes it, otherwise the arduino doesn't do anything.
The problem is, I'm using a 328-based arduino, and as far as I can tell, I shouldn't be running out of memory!
A count of the main memory-taking up parts of the program:
2x 256 byte wavetables, including the problem waveform - 512 bytes
These wavetables are aligned at 256 byte multiples in SRAM, so I guess the aligning costs some memory, since the Arduino specific variables are allocated first, and they don't take up a multiple of 256 bytes. I'll say the aligning costs an extra 512 bytes. - 512 bytes
2x 8 int arrays to store the display state - 32 bytes
10 int array for the character sprites to display - 20 bytes
8x the oscillator struct, which is 7 bytes each - 56 bytes
12 int array for note frequencies - 24 bytes
4x8 byte array to store currently playing MIDI notes - 32 bytes
4x8 byte array to keep track of which notes are new - 32 bytes
Let's overestimate and say that all the other assorted variables used amounts to 100 bytes - 100 bytes

512+512+32+20+56+24+32+32+100= only 1320 bytes.
I can't see a reason why the extra wavetable should be a problem!
I didn't account for the MIDI or SPI libraries, but I can't imagine they would take up the ~700 bytes needed to fill the available 2Kbytes of SRAM.

Can anyone else see any issues? Like I said, the code works perfectly fine without the triangle waveform, so the problem is somehow related to that.

Still haven't figured out the extra wavetable problem, but here's a song I made using the synth, my mpc, and my kp3 last night, in like an hour and a half.

did u died

A bit of a dark and minimalist song. Which is a bit of an odd mood considering that christmas break just began. :stuck_out_tongue:

sciguy:
I realized that the code I posted doesn't actually work!

It compiles and all, but it seems like the arduino is running out of SRAM: commenting out the triangle waveform fixes it, otherwise the arduino doesn't do anything.
The problem is, I'm using a 328-based arduino, and as far as I can tell, I shouldn't be running out of memory!
...
Can anyone else see any issues? Like I said, the code works perfectly fine without the triangle waveform, so the problem is somehow related to that.

Alright, I've been fiddling with the code for hours trying to figure this out. I eventually settled upon the conclusion that it was a memory issue. So as one solution, I decided to try modifying the MIDI library, it seemed to be using up a bunch of RAM, and trimming it down. I duplicated the library, and edited the names of the files to MIDI_trimmed, adjusting #includes where appropriate. Before making any actual changes, I compiled the sketch, just to make sure I didn't make any stupid errors duplicating and renaming the library files. I hadn't changed the code meaningfully at all. But whoop, now my sketch if 2000 bytes shorter, and everything works.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHWHAT-THE-HECK-DID-I-DO-THAT-MADE-IT-WORK-IN-2-SECONDS-WITH-ZERO-EFFORT-AFTER-I-HAD-FAILED-FOR-HOURS-ACTUALLY-TRYING-TO-FIX-IT!!!!!!!!!!!!!!!!!!!!11111!!!!1!1!ONE
:0 :0 :0 :0 :0 :0 :0 :0 :0 :0 :0 :0 :0 :0 :0 :0
sigh

Oh well. At least it all works now.

Anyway, now the synth has 3 waveforms: variable width pulse, sawtooth, and now triangle. I also implemented attack and decay envelopes on the notes! The waveforms sound a bit distorted on lower volumes, but that's understandable since the resolution just decreases as volume decreases. The distortion is most noticable on the triangle waveform (but not too much), a bit audible on the sawtooth, and never noticable on the pulse.

Edit:
Progress today! Now that I've got the audio generating code running, I'm moving on to other parts. I started today on an interface that will allow for customizing settings of midi channel, waveforms, etc, on the device. There's now a menu system navigable using the buttons. There's also an input lock feature that makes it so the knobs only change settings when an edit mode is on; one button turns on the edit mode, another button locks it in edit mode for live tweaking.

amazing work, keep posting about your progress! i'm planning to build something like this myself, with a lcd display instead of led-matrix, with eproms it should be possible to save presets...

Thanks, there might not be much progress for a while since school has started again after winter break.
But anyway, I'll be sure to post progress here!

I was planning on definitely having some preset saving system on this thing. Probably also sequence saving once I get a sequencer running on this thing. (a long ways away from that... :slight_smile: )
Grrrh, ending parentheticals with smileys is annoying

The arduino already has 1Kbytes of internal EEPROM, that should be enough for a bunch of stuff. One synth settings preset would only be maybe 20 bytes max, I would guess. I could easily fit a couple sequences in there as well, maybe a custom wavetable as well.

Have u tried the new avr tollchain? i read somewhere that there was an issue with the version 1.0 in that sense. Was discovered during some contest on a shield code development or summat...