mbed variation drum machine

Product

This project implements a variation drum machine based on the original project found here. Essentially, a drum machine is developed that can automatically generate new drum patterns from an initial seed pattern using XOR.

The variation algrorithm used here is developed [by me] for this project. All drum sounds are original and are generated by replication of recorded drum soundwaves using Additive Synthesis.

Features

16 note measures of three sounds

mbed variation drum measure

//                            1   +    2   +    3   +    4   +             
    unsigned int high[16] = { 2,0,1,0, 2,0,1,0, 2,0,1,0, 2,0,1,0};
    unsigned int mid [16] = { 0,0,0,0, 2,0,0,0, 0,0,0,0, 2,0,0,0};
    unsigned int low [16] = { 2,0,0,0, 0,0,0,0, 0,0,2,0, 0,0,0,0};
  • 16 note measure
  • 4 beats per note
  • 3 drum pattern

8 synthesized drum set sounds

Bass drumMid tomSnareHight hat
Low tomHigh tomCymbalRim shot

4 selectable velocities per sound

0off1soft
2medium3loud

adjustable note variation

Each note velocity of each beat is XORd with a random variation value from zero to a maximum determined by potentiometer input. For example: 2 XOR 3 becomes 1, 2 XOR 2 becomes 0, 2 XOR 0 remains 2.

Potentiometer down sets the maximum variation of all beats to zero. Increasing from zero gradually increases the maximum variation of each note of each beat beginning with the last note first. Potentiometer middle sets the variation of all beats to the maximum variation of three. Continuing from the middle decreases the maximum variation of each note of each beat beginning with the last note first. The resulting variation algorithm randomly adds and subtracts notes of varying velocities from the original pattern.

/media/uploads/subtask/drumvariation.png

adjustable bpm

  • By potentiometer.

Design

system

/media/uploads/subtask/drum_diagram.png

  • One potentiometer for BPM adjustment
  • One potentiometer for note variation adjustment
  • One analog out for drum sounds
  • Four LEDs to indicate BPM rate
  • One 22.05KHz timer interrupt for audio out
  • One 3Hz timer interrupt for reading potentiometers

additive synthesis

The recorded wav file of each drum sound was written to a text file to acquire each wave form.

/media/uploads/subtask/bassaudio2.png /media/uploads/subtask/basssynthesis.png

mbed bass drum

static inline float bass_drum(void) 
{
    // Vb = velocity; Kb = gain
    const float e3=-60.0f, f1=324.0f*pi, f2=122.0f*pi, f3=100.0f*pi,
                p1=0.15f*pi, p2=-0.69f*pi, p3=-0.2f*pi;
    float t=0.0000453515f*b++; 
    if (t <= 0.00570988f) 
        return Vb*Kb*fastsin(f1*t + p1);
    else if (t <= 0.02210332f)
        return Vb*0.73f*Kb*fastersin(f2*t + p2);
    else        
        return Vb*1.46f*Kb*fastexp(e3*t)*fastersin(f3*t + p3);              
}

/media/uploads/subtask/tomaudio.png /media/uploads/subtask/tomsynth.png

mbed mid tom

static inline float mid_tom(void) 
{
    const float e1=-18.0f, f1=254.0f*pi,p1=0.5f*pi;
    float t=0.0000453515f*m++; 
    return Vm*Km*fastexp(e1*t)*fastsin(f1*t + p1);  
}

/media/uploads/subtask/cymbaudio.png /media/uploads/subtask/cymbsynth.png

mbed cymbal

static inline float cymbal(void) 
{  
    // Vc = velocity; Kc = gain
    const float e1=-10.0f, e2=-400.0f, f1=600.0f*pi, f2=16000.0f*pi,
                f3=32000.0f*pi, p2=0.5f*pi, p3=0.25f*pi;
    float t=0.0000453515f*c++;    
    return Vc*Kc*fastexp(e1*t)*fastsin(f1*t) * Vc*fastsin(f2*t+p2) - 
        Vc*Kc*fastexp(e2*t) * fastsin(f3*t+p3);     
}

output

Add drums with DC offset.

audio out

void play(void) 
{
    audio = cymbal() + bass_drum() + rim_shot() + offset;
}

Challenges

  • Processing speed is important to synthesize clear sounds as each sound is produced by a combination of precise frequencies
  • Initially one sound sounded okay when played by itself
  • Initially sounds played together produced clicks, delays, buzzing, etc
  • Problem determined to be the speed of the standard sin and exp functions required for Additive Synthesis
  • sin and exp were replaced with fastsin and fastexp algorithms found online [and altered for this project] that produce significantly faster approximations for sine and exponent

fast sine!

static inline float fastsin(float x)
{
    const float B = 4/pi;
    const float C = -4/(pi*pi);
    const float P = 0.225f;
    float y, xppi;
    x = fmod(x,2.0f*pi);        
    if (x<=pi) 
        y = B * x + C * x * x;
    else {
        xppi = x - pi;   
        y = -1.0f * (B * xppi + C * xppi * xppi); 
    }      
    y = P * (y * abs(y) - y) + y;   
    return y;
}
  • Made most functions static inline to insert code in place at assembly
  • Minimized multiplication and division
  • Minimized interrupts for best sound

Results

  • Sound ok
  • BPM ok
  • Variation ok
  • sin takes 28 microseconds
  • fastsin takes 9 microseconds
  • Demonstration here...

Future Plans

  • Joystick buttons to select drum sound, input drum rhythm and playback rhythm
  • Tilting the MBED will change the tempo of playback by use of the accelerometer
  • Use base 4 value to store variation from 0 to 3333 [0 to 255 decimal]


Please log in to post comments.