Guitar Effects Algorithms

Guitar Effects Algorithms

Postby diydsp » Mon Jul 23, 2012 7:03 pm

This is a dual tremelo that I've been having fun with:
Attachments
RingAndTrem05.zip
Each knob controls one tremelo. Explore the combinations of slow and fast settings.
(1.69 KiB) Downloaded 566 times
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm

Re: Guitar Effects Algorithms

Postby diydsp » Mon Jul 23, 2012 7:08 pm

This one is a digital divide-by-1.5x sound with a noise gate. In goes 999 Hz, out comes 666 Hz.... under a certain set of conditions... usually guitar sounds progress through a sequence of dominant tones and choosing different pickups and tone settings on the guitar leads to different envelopes.

It's kind of like setting up a guitar signal to drive a divide-by-3 counter, except that the counter is clocked on both up-going and down-going transitions of the input waveform. There are some long, drawn-out reasons why you might want to do this and I'll get to them at another time.. For now, just enjoy it as a sound :)
Attachments
DividingDistortion01.zip
frequency divider, divided-by-1.5
(2.26 KiB) Downloaded 576 times
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm

Re: Guitar Effects Algorithms

Postby diydsp » Mon Jul 23, 2012 7:26 pm

Although this one is named "Wah05," it's not actually a wah-wah pedal yet, just the filter part, with a distortion module inline following the filter. Mod 1 = Distortion, Mod 0 = filter frequency...

stick around and we'll modify this code to be a wah pedal with just a few adjustments.

Wah05.zip
Mod1= Distortion Depth, Mod2=Wah/Band-Pass filter center frequency, implemented as a state-variable filter (SVF).
(1.9 KiB) Downloaded 549 times


p.s. I'm developing these programs with a prototype Aristocrat pedal, but all of this will work identically for any audio system built from an Audio Codec Shield and a Maple. Arduino can not handle this type of stuff at full sample rate and 16-bits like Maple can.
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm

Re: Guitar Effects Algorithms

Postby diydsp » Mon Jul 23, 2012 8:03 pm

....and in case anyone wants an audio demo... here's Wah05, hand-controlling mod0 (of "Fc", center frequency) on the Audio Codec Shield:

Wah05.mp3.zip
9 Second loop of two open chords playing through medium-Q bandpass filter sweeping up and down + light clipping distortion.
(217.37 KiB) Downloaded 557 times
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm

Re: Guitar Effects Algorithms

Postby diydsp » Mon Jul 23, 2012 8:15 pm

...all while we're at it, I'd like to include the frequency spectrum of this simple program... you can see how the frequency hops up and down as I twist the knob super fast. you can also see the distortion at the beginning of the second half as a ghost image of overtones, slightly above the fundamentals :)
Attachments
Wah05small.jpg
Frequency Spectrum plot of the 9 second Wah05 demo audio above.
Wah05small.jpg (159.5 KiB) Viewed 8336 times
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm

Re: Guitar Effects Algorithms

Postby clee » Wed Aug 15, 2012 1:18 pm

What fun! Thanks for the code and spectrum.
clee
 
Posts: 7
Joined: Thu Jul 05, 2012 10:18 pm

Re: Guitar Effects Algorithms

Postby diydsp » Mon Aug 27, 2012 5:00 pm

Thanks, clee!

Here's another effect I've been playing with lately. It's guest's pitch-shifter with a sequencer driving the pitch change. The pitch-sequence is stored inside the patch. You'll see have I have about 5 different ones in there; they're easy to change.
mod1 = sequencer speed
mod0 = general pitch range (same as guest's pitch-shifter!)

demo audio: http://soundcloud.com/diydsp/spaceyloops-with-the

SpectralShot02.jpg
Spectral representation of the what the sequenced pitch-shifter does do a guitar signal
SpectralShot02.jpg (237.31 KiB) Viewed 8262 times


Note: this program was modified to include the sequencer at the Providence Maker Faire 2012 while at a booth next to a whole bunch of gameboy street performers who played inside with a portable amp. They were rocking the whole time, providing a great, inspiring atmosphere and taught me some of the nuances of the root-minor third-tonic sequence!

Code: Select all
// ArpeggPitch02 -
// mod0 = overall pitch
// mod1 =
//based on Open Music Lab's GuestPitch01
/* Pitch Shifter loosely based on Open Music Lab's miCrODEC pitch shifter */
// -no interpolation between points yet
// -two taps move through the buffer at the same rate
// -tap amplitudes have triangle overlap windows
// -MOD1 controls amount of pitch shift

#define SAMPLE_RATE 44 // 44.1kHz sample rate
#define ADCS 2 // only 1 ADC used here -> MOD0
#include <AudioCodec_Maple.h>

// -MOD0 is divided into 21 regions that are each a different pitch multiplier
// -step size 320 is 1/1 ratio, 160 is 1/2 or octave-down
// -the step array represents a series of intervals that are from just intonation tuning
uint32 step[] = {120,135,150,160,180,200,225,
                 240,270,300,320,360,400,450,
                 480,540,600,640,720,800,900};
/*
uint32 step[39]={
  80,  85,  90,  95, 101, 107, 113, 120,
 127, 135, 143, 151, 160, 170, 180, 190,
 202, 214, 227, 240, 254, 269, 285, 302,
 320, 339, 360, 381, 404, 428, 453, 480,
 509, 539, 571, 605, 641, 679, 719
};
*/

int16 left_in, right_in, left_out, right_out;
uint16 mod0_value = 0,mod1_value=0;

#define SIZE 2048 // buffer size is limited by microcontroller SRAM size
int16 buffer[SIZE];
uint32 location = 0; // buffer location to read/write from
uint32 tap_count = 0;
uint32 tap0_pos,tap1_pos;
int32 tap0_amp,tap1_amp;
int16 pitch_shifted;

// arpeggiator code
// bigger numbers are slower
//uint16 countDownMax=5000;int16 sequence[] = {0,2,4,2,0,2,4,7};int16 sequenceLen = 8;
//uint16 countDownMax=1000;int16 sequence[] = {0,4,0,5};int16 sequenceLen = 4;

uint16 countDownMax=1000;int16 sequence[] = {5,5,5,2,2,2,0,0};int16 sequenceLen = 8;

//uint16 countDownMax=1000;int16 sequence[] = {1,0,1,0, 2,0,2,0, 4,0,4,0, 7,0,6,0};int16 sequenceLen = 16;


//uint16 countDownMax=1300;int16 sequence[] = {7,0,0,7, 0,0, 7,-1};int16 sequenceLen = 8;

uint16 countDownVal=100,sequenceStep=0;
int sequenceVal=0;


void setup() {
  SerialUSB.end();
  AudioCodec_init();
  //nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
}

void loop() {  while (1);  }   // reduce clock jitter

// timer4_ch1 interrupt routine - all data processed here
void AudioCodec_interrupt() {
  AudioCodec_data(&left_in, &right_in, left_out, right_out);
  left_in = left_in * 8;   // scale input volume up by 18dB
  AudioCodec_ADC(&mod0_value,&mod1_value);
 
  // Arpeggiator Sequencer ------------------------
  countDownVal     = countDownVal - 1;
  if(countDownVal == 0){
    countDownVal   = countDownMax;
   
    // advance sequencer
    sequenceStep     = sequenceStep + 1;
    if(sequenceStep >= sequenceLen){
      sequenceStep   = 0;
    }
 
    // Mod1 controls speed of arpeggiation
    countDownMax = 10 + ( (0xffff^mod1_value) >> 4);
    sequenceVal  = sequence[sequenceStep];
  }
 
 
  // Pitch-Scaler ----------------------------------
  // Knob 0 selects pitch steps
  int n = 0;
  while (mod0_value > n) {
    n = n + 0x10000/21;      // 21 is the size of the step[] array
  }
  n = n*21/0x10000;
 
  n = n + sequenceVal;  // add arpeggiator's pitch sequencer value
 
  if (n > 20) {
    //n = 20;     // option 1. Peak at max pitch
    n = n - 7;    // option 2. Roll back one octave from target
  }
 
  tap_count = tap_count + step[n];
  int frac = tap_count%320;
  tap0_pos = (tap_count/320)%SIZE;
  tap1_pos = (tap0_pos + SIZE/2)%SIZE;
 
  // make the tap_amp's zero at the location and count up to SIZE on both sides
  // this for overlapping to hide the discontinuity the taps move across at the buffer's head location
  if (tap0_pos >= location) {
    if ((tap0_pos - location) <= SIZE/2) {
      tap0_amp = (tap0_pos - location);
    } else {
      tap0_amp = (SIZE - tap0_pos + location);
    }
  } else {
    if ((location - tap0_pos) <= SIZE/2) {
      tap0_amp = (location - tap0_pos);
    } else {
      tap0_amp = (SIZE - location + tap0_pos);
    }
  }
  tap1_amp = SIZE/2 - tap0_amp;
 
  pitch_shifted = (tap0_amp*buffer[tap0_pos] + tap0_amp*buffer[(tap0_pos+1)%SIZE]
                 + tap1_amp*buffer[tap1_pos] + tap1_amp*buffer[(tap1_pos+1)%SIZE])/SIZE/2;

  pitch_shifted *= 2;  // scale volume to hear a little more easily

  // bit crush
  //uint16 numberOfBits = mod1_value>>12;
  //uint16 mask = 0xffff<< numberOfBits;
  //pitch_shifted = pitch_shifted & (0x8000|mask);
 
  left_out = pitch_shifted;  // send wet val to left
  right_out = left_in;       // send dry val to right
 
  // store value for next time
  buffer[location++] = left_in;
  if (location >= SIZE)    location = 0;
}
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm

Sample and Hold and Bit Crusher

Postby diydsp » Thu Oct 11, 2012 7:56 pm

Here's a little program I've been working on. It does two Lo-Fi effects: A BitCrusher and a Sample and Hold. One reduces information in the time domain and the other lessens dynamic range by creating an increased noise floor. If you twirl the knobs, you get some nice timbres... this would be good with an LFO :) or envelope follower :)


// SampleAndHoldAndBitCrush03 (diydsp)
// mod0 = BitCrusher amount
// mod1 = Sample and Hold frequency
//
//based on Open Music Lab's GuestPitch01
/* Pitch Shifter loosely based on Open Music Lab's miCrODEC pitch shifter */
// -no interpolation between points yet
// -two taps move through the buffer at the same rate
// -tap amplitudes have triangle overlap windows
// -MOD1 controls amount of pitch shift

#define SAMPLE_RATE 44 // 44.1kHz sample rate
#define ADCS 2
#include <AudioCodec_Maple.h>


int16 left_in, right_in, left_out, right_out;
uint16 prev_left_in_mag=0;
uint16 mod0_value = 0,mod1_value=0;

uint16 countDownMax=1000;
int16 countDownVal=100;

int16 BitCrush(int16 inVal);
int16 SampleAndHold(int16 inVal);


void setup() {
SerialUSB.end();
AudioCodec_init();

//nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
}

void loop() {
while (1);
} // reduce clock jitter

int32 inputFilt=0;

uint16 SampHoldOut=0;

// timer4_ch1 interrupt routine - all data processed here
void AudioCodec_interrupt()
{

AudioCodec_data(&left_in, &right_in, left_out, right_out);
AudioCodec_ADC(&mod0_value,&mod1_value);

// Main Processing Chain
SampHoldOut = SampleAndHold(left_in);

left_out = BitCrush(SampHoldOut);
}

int16 SampleAndHold(int16 inVal)
{
static int16 outVal = 0; // keep local to this function

countDownVal = countDownVal - 1;
if(countDownVal <= 0){

// Mod1 controls interval
countDownMax = 1 + ( (0xffff^mod1_value) >> 8);
countDownVal = countDownMax;

outVal = inVal;
}
return outVal;
}

int16 BitCrush(int16 inVal)
{
// bit crush
uint16 numberOfBits = mod0_value>>12;
uint16 mask = 0xffff<< numberOfBits;
uint16 andVal = (0x8000|mask);
int16 outVal = inVal & andVal;

return outVal;
}
http://diydsp.com is where I teach people Do-It-Yourself Digital Signal Processing for music instruments and other applications.
diydsp
 
Posts: 21
Joined: Mon Dec 19, 2011 10:44 pm


Return to Audio Codec Shield

Who is online

Users browsing this forum: No registered users and 1 guest


cron