Experiments with variable rate drum sample playback

Or how to get a vintage 1980’s drum machine sound without selling your kidneys!

There was a discussion on the SynthDIY mailing list recently about how the early digital drum machines like the LinnDrum or the Oberheim DMX used to change the pitch of drum sounds by simply changing the sample rate. They literally just played the samples back faster or slower, exactly like speeding up or slowing down a tape recording. At the time, this was relatively easy because each drum sound had its own DAC and its own sample rate clock, and that clock could be a VCO if you wanted. This variable sampling rate was a key feature of a lot of early digital gear – the PPG synths and the Prophet VS used the same trick – and it accounts for a lot of the “crunchy” or “gritty” character of those instruments. The other key element of these early digital drum machines was that they used 8-bit samples, although as I discovered, this is not all it seems.

I was rather inspired by the thought of getting a vintage drum machine sound, and wondered if I could playback original 1980’s drum samples using a PIC.

I headed for one of my recent favourite chips, the 16F1778. This chip has 16K of program memory, but mostly why I like it is that it also has three 10-bit DACs on the chip. That makes it really good fun for generating signals like LFOs or envelopes…or drums!

As well as three DACs, the 16F1778 also has three 16-bit timers, so those could be used to generate the required sample clocks. This was looking good! With a bit of luck and some cunning coding, I might be able to get three variable-rate 8-bit drum samples onto a single chip, assuming the samples were short enough. At least, that was the target to aim at.

My first step was to try and find some of the original 8-bit samples for some of these machines. I found this great site with images for the Oberheim DMX EEPROM chips. Many of the samples were 4K, so I’d be able to fit three of them into my 16K program memory and still have plenty of room (four whole kilobytes!) left for code. So far so good.

It was at this point that I hit my first snag. I discovered the 8-bit samples in the LinnDrum and the Oberheimn DMX aren’t really 8-bit!

When is an 8-bit sample not an 8-bit sample? When it’s µ-Law encoded!

It turns out that saying that early drum machines like the Linn Drum or the Oberheim DMX “used 8-bit samples” isn’t really true. It’s true that they used 8-bit memory, but those samples were played out through an interesting device, the AM6070 µ-Law DAC. You can have a look at the AM6070 µ-Law DAC datasheet if you’re curious. What makes this DAC different from the ones we’re more used to today is that it is not a linear output DAC. Instead, it accepts data in “µ-Law encoded” format, which is a type of simple floating point format, essentially. Human perception of volume is not at all linear (that’s why we invented decibels) in the same way that the human perception of pitch is not at all linear. Similarly to pitch, where we hear “octaves” (e.g. a multiple of two in frequency terms) as “equal”, we hear multiples of two in volume as roughly equal as well (+6dB). The µ-Law takes advantage of this, and distributes the 256 possible 8-bit values across a much wider range by using 16 values for each 6dB range. This gives a much wider range than if the the values were mapped linearly to the output, and we don’t really hear the errors because we’re much less sensitive to loud signals than to quiet ones. Clever stuff. The net result is that the 8-bit data in the LinnDrum and DMX actually has more like a 12 or 13-bit dynamic range.

So what could I do? I can’t really get hold of a AM6070 DAC, and I want to use what I’ve got available, so I decoded the original data into 12-bit format, and then truncated it to 10-bit, since that’s all my DACs can output. So, yes, technically it’s even worse than a 1980’s drum machine. If that frightens you, look away now.

However, that was the only major hurdle. Implementing the variable sample rates using the 16-bit timers worked well, and I used a look-up table to convert from input CV values to 16-bit timer values so that I could give the sample rate controls an “equal octaves” character. Again, as noted before, this feels more “natural” to us poor humans. I assumed I’d need three control voltages per drum voice, but thus far I’ve only used two, one for the sample rate and another for the sample resolution. There’s another available in the code if you get a good idea what to do with it.

So it sounds terrible, right?

You be the judge of that. I like it, but it sure ain’t hifi! Here’s a sound sample, demonstrating the three sounds, and also tweaking the sample rates and the sample resolution for some really crunchy lo-fi chaos. The recording is my usual low standard – just a live laptop mike in the workshop, so not “studio quality” by any stretch of the imagination!

Incidentally, these samples were triggered using an Erica Synths Pico RND module feeding a CD4013 flip-flop on the breadboard, so the Snare and Kick are on alternate beats, and the Tom drops in randomly.

The chip has plenty of unused pins and resources besides CV inputs, in fact. One possible addition would be to use the UART to read MIDI data and allow the drum sounds to be triggered by MIDI. I haven’t done this, but it’s an obvious next step. Here’s what it looks like currently:

The code presented below uses three of the original Oberheim DMX samples, the Kick, the Tom and the Snare. Each of these samples is 4K, so they were obvious ones to go for. I could have included some of the others, but they might have required a whole chip to do it. Nonetheless, it should be possible to provide a full set of DMX or LinnDrum samples in 5 or 6 chips. That’s pretty good when you consider that the 8K sounds like the Ride cymbal on the DMX had to use two EEPROM chips just for the data! We can easily get the whole thing into one chip, and wrap up the clock and the DAC too, saving still more circuitry.

So what is left to do?

As I’ve mentioned, you’d need more chips with different samples in them. This is a question of decoding the original EEPROM images (or finding them decoded somewhere) and then turning the data into a table that can be pasted into the PIC ASM code. I use PHP for jobs like this, but there are lots of tools that would work.

Having individual outputs is handy, but a mixed output would be good too. The typical drum machine of this era lets you set the level for each drum, and we could add a pan pot to position each sound in the stereo field too. This is just a basic multiple-mono-sources-in/stereo-out stereo mixer application.

Finally, there’s nothing to trigger the drums with. You can use 0-5V trigger pulses from somewhere else (an LFO, for example) but it’ll be hard to program patterns like that! Writing a bit of code to convert MIDI information to triggers would be a simple way to allow the drums to be sequenced, or you could go the whole hog and build a standalone drum machine with its own onboard sequencer modelled on the originals, complete with chunky keyboard switches and lots of LEDs!

Druid DRUMS details

Currently, there are no plans to offer the DRUMS chip in the shop, so I’m afraid you’ll have to program your own chip, or find a friend to program one for you. If you’d like to see programmed chips in the shop, send us an email, and if there’s enough interest, we’ll do it!

Creative Commons License
Drums by Tom Wiltshire for Electric Druid is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Here’s the legal stuff.

23 thoughts on “Experiments with variable rate drum sample playback

  1. Brilliant work Tom! That looks like the basis of some fantastic DIY drum machines, especially in two or maybe three chip format for more sounds. Trigger interface could be anything from a really simple piezo pad to an MCU based sequencer! Plus free pins to boot!! Keep up the cool work bud!

  2. good job as usual!
    However I encounter a little problem with the CV inputs of the drum 2, no problem with the input 1 and 3.
    Maybe in the code ?
    Another small error on the schema, trig 2 and 3 seem reversed.
    thank you for your answer, I really appreciate your projects.

    FG (pardon my french)

  3. I took a Korg Volca sample apart, and as far as I could tell it was a single ARM Cortex M3 microcontroller and a few megabytes of SPI Flash that I assume was for the samples, so I’m quite sure it’s possible.

    1. I’d go as far to say that with a 32-bit processor like the M3 and a few MB of Flash, it’d be not just possible but easy! I was trying it with a 8-bit processor and no external memory, so it’s necessarily a lot more limited.

  4. Hi Tom,

    Interesting project! I’m working on something similar for FC. 🙂

    I wanted to point out that you could store an additional sample in there using the upper 4 bits of the 14bit words of the three existing samples. eg, for each word, the lower 10 bits are the actual sample, the upper 4 bits are part of another sample. The 4th sample is split across the 3 other samples with 2 bits to spare.

    You’d have to do some special converting to read the fourth sound, but it’d let you push things further and squeeze in more sounds.

    You’re then limited by only having 3 16-bit timers and 3 DACs, but you could give this bonus sound an 8-bit timer and a PWM output.

    Or, you could convert your unused CVs into a sound-select, allowing the user to trigger whichever sound they wanted from an output.

    Just some thoughts!

  5. Hi, It seems you are missing env and filter after the dac output, depending on which kind of sound you play. Also you are better of with an exponential amplifier and an 8 bit dac, that would make it more natural. Not sure though, Cheers

  6. Hi Tom, nice experiment.. Looks some like the Dtronics Digidrum i made 6-7years ago.
    however, i used a dsPIC and did the uLaw decoding on the fly with a lookup table..
    It amazed me how good it sounds, using original rom data and decode the uLaw yourself.. instead of using a standard sampled drumsound in a sampler.

    Keep up the good work, love reading about your experiments / projects..

    Cheers,
    Django

    1. I searched for Digidrum, well, kind of page is there, but not much else. Is that dsPIC project not available in any form, open or otherwise? Thank you.

  7. Hello, I really like this module, but the output signal is a little weak for a modular, I had the idea to put an additional op amp to boost the audio signal. But a not very nice frequency has appeared (as if we heard the clock of the chip or something that looks like) do you have an idea to reduce this frequency and at the same time boost the signal?
    thank you so much

  8. Maybe this will be know to most enthusiasts, but I will post just in case. There is an open sourced code for Atmega328 that gives 6 drum instruments. Each has separate output, separate trigger, and also each has pitch control. Code is provided in Arduino .INO file form, read my comments there at the end how to “free” pins that are normally occupied by quartz (xtal).
    Article, design files, code and comments:
    https://www.hackster.io/janost/xr10-open-source-drum-module-6b2b3f

  9. I need nothing more in my life than to have a single channel of a Linn LM-1 where i can load my own samples.
    I cannot get this particular punch anywhere else !
    What you have done here is really close ! The pitching sounds fantastic too. I just need the rest of the channel’s audio path components and this is it !
    The Linn LM-1 also has a nice fat juicy transformer which helps to beef up the sound.
    I remember some guy set up a crowd funded project to build such a beast, where we could load our own samples too, but the guy ran away with the money AND the donated chips ! What a disaster. What the world needs is some hero to build this machine. I remember some guy said he could build me a channel on Arduino, but i lost his contact details !
    I wonder if there is anyone out there who can help me 🙂

  10. Fun read, but I think it’s worth suggesting that, if the timing isn’t so tight that you can’t spare a few extra operations per sample, it’d be more space-efficient to store the samples in 8-bit u-law form and convert on the fly – u-law conversion isn’t difficult (you could even do it with a lookup table, if time is tight,) and it doubles the available sample space with no (additional) loss in quality (since the Linn/DMX samples were stored in this format to begin with.)

    1. Yeah, this is a nice idea. When I was doing it, I made the assumption that time would be very tight, so I decoded the samples first so the code would have the minimum to do. Having got it working like that, I then never went back to see exactly how tight the time was exactly! It’s possible you could do it on the fly – as you say, a look-up would be pretty fast, and it would save program memory.

Leave a Reply to rvense Cancel reply

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