AVR cheap bass drum synthesis

April 29

The idea with the drum synth is to get a wide range of sounds out of the smallest, simplest possible circuit. There are 4 drum modes, bass, snare, hat and something more glitchy. I’m using an AtTiny45 as it’s got analogue inputs, fast PWM for output and enough memory for a few lookup tables of data. Here’s the test circuit:

The AtTiny chip is computing each sample at roughly 31kHz so I need to avoid any CPU-hungry operations like multiplication (8Mhz clock/31.25kHz = 256 instructions max). The bass drum gets around this by using two 8 bit lookup tables, each 256 bytes in size. The first is an ‘impact’ table which is a sort of exponential drop off curve and the second is a sine wave scaled to a 0-255 range. Source code is here (Compiled in g++, fuses L = 0xE2, H = 0xDF, E = 0xFF) and here’s the bit that does the important work:

impactPos += speed;
sinePos += pgm_read_byte(&impact_tbl[(impactPos >> 8) & 0xff]);
sample = pgm_read_byte(&sine_tbl[(sinePos >> 4) & 0xff]);

The sine table is being modulated by the ever-decreasing impact table so the frequency drops over time. The speed of the playback determines the pitch of the drum and the initial impactPos determines the type of sound. For a cheesy 70’s disco tom you set it to zero to go from a really high tone down to a low one. For a tech bass you start further down the curve to get a more muted and constrained sound.

This is a lazy approach as there is no decay on the volume – instead it depends on the drum playing out until the frequency of the sine wave is too low to hear. This avoids any multiplications but has some 8 bit artefacts as a consequence (I kind of like them).  Here’s some example output:

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.



4 Responses to “AVR cheap bass drum synthesis”

  1. 1 kim

    hey Ive tried to use the source for this about ten times and I keep getting “selection attribute cannot be specified for local variables” and it stops uploading/compiling at beginning of Sine Lookup Table.

    Any idea why this would be happening? Im not well versed in code so Im not really able to figure it out myself

    thanks for any help id really like to make this project

  2. 2 kim

    ps-am using arduino uno to program attiny45 via breadboard.

  3. 3 admin

    Hi Kim,

    What tools do you use to program the attiny with an arduino? I use the AVRISP2 unit with avrdude, is it similar to that?

    My initial guess is that the compiler you are using does not support the PROGMEM macro as it is or that it differs slightly when running it through the arduino.

    I’ll find the makefile and upload that too, perhaps there’s something relevant in there.

    Thanks,
    Alex

  4. 4 admin

    Hi Kim,

    It’ll be a week or so until I can get into this but I’ve included some links that might help below.

    The problem is that PROGMEM was not working with g++, but maybe that has been fixed on your compiler… try deleting the lines ‘#ifdef’ down to the ‘#endif’ at the top of the file. What happens then?

    Thanks,
    Alex

    http://www.arduino.cc/en/Reference/PROGMEM
    http://playground.arduino.cc/Learning/Memory
    http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003&start=all&postdays=0&postorder=asc


Leave a Reply

Your email address will not be published. Required fields are marked *