Dan Allegre / 401_reverb

Dependencies:   mbed

Committer:
dallegre
Date:
Sat Jul 30 02:21:09 2016 +0000
Revision:
1:a4ce08417c60
Parent:
0:c12e968e5b60
made it into an allpass delay program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dallegre 0:c12e968e5b60 1 //Header including the saturating math functions. Also includes signed to unsigned and unsigned to signed integer conversion
dallegre 0:c12e968e5b60 2 //functions.
dallegre 0:c12e968e5b60 3
dallegre 0:c12e968e5b60 4 #define MIN -15000.0f //so you don't get negative vlaues because the stuff is in unsigned format
dallegre 0:c12e968e5b60 5 #define MAX 15000.0f //limit at maximum 16 bit value so it doesn't wrap around
dallegre 0:c12e968e5b60 6
dallegre 0:c12e968e5b60 7 //saturation addition
dallegre 0:c12e968e5b60 8 float satSubtract(float x, float y){ //x - y
dallegre 0:c12e968e5b60 9 if(x < (MIN + y)) //if((x - y) < MIN), add y to both sides to yields if(x < (MIN + y))
dallegre 0:c12e968e5b60 10 return MIN;
dallegre 0:c12e968e5b60 11 if(-y > (MAX - x)) //if((x - y) > MAX), subtract x from both sides to yield if(-y > (MAX - x))
dallegre 0:c12e968e5b60 12 return MAX;
dallegre 0:c12e968e5b60 13 return (x - y); //if it's not limiting then just return x - y
dallegre 0:c12e968e5b60 14 }
dallegre 0:c12e968e5b60 15
dallegre 0:c12e968e5b60 16 //saturation subtraction
dallegre 0:c12e968e5b60 17 float satAdd(float x, float y){ //x + y
dallegre 0:c12e968e5b60 18 if(x < (MIN - y)) //if((x + y) < MIN)
dallegre 0:c12e968e5b60 19 return MIN;
dallegre 0:c12e968e5b60 20 if(x > (MAX - y)) //if((x + y) > MAX)
dallegre 0:c12e968e5b60 21 return MAX;
dallegre 0:c12e968e5b60 22 return (x + y); //if it's not limiting then just return x + y
dallegre 0:c12e968e5b60 23 }
dallegre 0:c12e968e5b60 24
dallegre 0:c12e968e5b60 25 //signed to unsigned integer conversion
dallegre 0:c12e968e5b60 26 float intToFloat(int input){
dallegre 0:c12e968e5b60 27 uint16_t output = 0;
dallegre 0:c12e968e5b60 28 float output_f = 0;
dallegre 0:c12e968e5b60 29 if(0x8000 && input){
dallegre 0:c12e968e5b60 30 output = input - 0x8000; //then it's a negative number
dallegre 0:c12e968e5b60 31 }else{
dallegre 0:c12e968e5b60 32 output = input + 0x8000; //then it's a postive number
dallegre 0:c12e968e5b60 33 }
dallegre 0:c12e968e5b60 34 output_f = output/2.0;
dallegre 0:c12e968e5b60 35 output_f -= 32768.0/2.0; //remove DC offsset from signed to unsigned conversion.
dallegre 0:c12e968e5b60 36 output_f *= float(2.0); //amplify a little.
dallegre 0:c12e968e5b60 37 return output_f;
dallegre 0:c12e968e5b60 38 }
dallegre 0:c12e968e5b60 39
dallegre 0:c12e968e5b60 40 //unsigned to signed integer conversion
dallegre 0:c12e968e5b60 41 int unsignedToSigned(int input){
dallegre 0:c12e968e5b60 42 int output = 0;
dallegre 0:c12e968e5b60 43 if(input >= 0x8000) //then convert it to a positive signed numbber
dallegre 0:c12e968e5b60 44 output = ((input >> 1) & 0x7FFF);
dallegre 0:c12e968e5b60 45 if(input < 0x8000)
dallegre 0:c12e968e5b60 46 output = input + 0x8000;
dallegre 0:c12e968e5b60 47 return output + 32768/2;
dallegre 0:c12e968e5b60 48 }
dallegre 0:c12e968e5b60 49
dallegre 0:c12e968e5b60 50 //these ideas taken from paulbourke.net/miscellaneous/interpolation/
dallegre 0:c12e968e5b60 51 //linear
dallegre 0:c12e968e5b60 52 float linterp(float y1, float y2, float frac){
dallegre 0:c12e968e5b60 53 return(y1*(1-frac) + y2*frac);
dallegre 0:c12e968e5b60 54 }
dallegre 0:c12e968e5b60 55 //cosine
dallegre 0:c12e968e5b60 56 float cosinterp(float y1, float y2, float frac){
dallegre 0:c12e968e5b60 57 float frac2;
dallegre 0:c12e968e5b60 58 frac2 = (1 - cos(frac*float(3.14159)))/2;
dallegre 0:c12e968e5b60 59 return(y1*(1-frac2) + y2*frac2);
dallegre 0:c12e968e5b60 60 }
dallegre 0:c12e968e5b60 61
dallegre 0:c12e968e5b60 62 //1 pole lowpass filter from ear level engineering's website
dallegre 0:c12e968e5b60 63 #include <math.h>
dallegre 0:c12e968e5b60 64 class OnePoleLp {
dallegre 0:c12e968e5b60 65 public:
dallegre 0:c12e968e5b60 66 OnePoleLp() {a0 = 1.0; b1 = 0.0; z1 = 0.0;};
dallegre 0:c12e968e5b60 67 OnePoleLp(float Fc) {z1 = 0.0; setFc(Fc);};
dallegre 0:c12e968e5b60 68 //~OnePole();
dallegre 0:c12e968e5b60 69 void setFc(float Fc);
dallegre 0:c12e968e5b60 70 float process(float in);
dallegre 0:c12e968e5b60 71 protected:
dallegre 0:c12e968e5b60 72 float a0, b1, z1;
dallegre 0:c12e968e5b60 73 };
dallegre 0:c12e968e5b60 74 inline void OnePoleLp::setFc(float Fc) {
dallegre 0:c12e968e5b60 75 b1 = exp(-2.0 * 3.14159 * Fc);
dallegre 0:c12e968e5b60 76 a0 = float(1.0) - b1;
dallegre 0:c12e968e5b60 77 }
dallegre 0:c12e968e5b60 78 inline float OnePoleLp::process(float in) {
dallegre 0:c12e968e5b60 79 return z1 = in * a0 + z1 * b1;
dallegre 0:c12e968e5b60 80 }
dallegre 0:c12e968e5b60 81 //1 pole highpass filter
dallegre 0:c12e968e5b60 82 class OnePoleHp {
dallegre 0:c12e968e5b60 83 public:
dallegre 0:c12e968e5b60 84 OnePoleHp() {a0 = 1.0; b1 = 0.0; z1 = 0.0;};
dallegre 0:c12e968e5b60 85 OnePoleHp(float Fc) {z1 = 0.0; setFc(Fc);};
dallegre 0:c12e968e5b60 86 //~OnePole();
dallegre 0:c12e968e5b60 87 void setFc(float Fc);
dallegre 0:c12e968e5b60 88 float process(float in);
dallegre 0:c12e968e5b60 89 protected:
dallegre 0:c12e968e5b60 90 float a0, b1, z1;
dallegre 0:c12e968e5b60 91 };
dallegre 0:c12e968e5b60 92 inline void OnePoleHp::setFc(float Fc) {
dallegre 0:c12e968e5b60 93 b1 = -exp(-2.0 * 3.14159 * (float(0.5) - Fc));
dallegre 0:c12e968e5b60 94 a0 = float(1.0) + b1;
dallegre 0:c12e968e5b60 95 }
dallegre 0:c12e968e5b60 96 inline float OnePoleHp::process(float in) {
dallegre 0:c12e968e5b60 97 return z1 = in * a0 + z1 * b1;
dallegre 0:c12e968e5b60 98 }
dallegre 0:c12e968e5b60 99
dallegre 0:c12e968e5b60 100 //make a delay class
dallegre 0:c12e968e5b60 101 class Delay {
dallegre 0:c12e968e5b60 102 public:
dallegre 0:c12e968e5b60 103 Delay() {
dallegre 0:c12e968e5b60 104 index1 = 0;
dallegre 0:c12e968e5b60 105 index2 = DELAYLEN*.99;
dallegre 0:c12e968e5b60 106 for(int i = 0; i <= DELAYLEN; i++){
dallegre 0:c12e968e5b60 107 buffer[i] = 0;
dallegre 0:c12e968e5b60 108 }
dallegre 0:c12e968e5b60 109 };
dallegre 0:c12e968e5b60 110 void setLength(float length);
dallegre 0:c12e968e5b60 111 float process(float in, float fbin, float length);
dallegre 0:c12e968e5b60 112 protected:
dallegre 0:c12e968e5b60 113 float buffer[DELAYLEN];
dallegre 0:c12e968e5b60 114 int index1, index2, intlength;
dallegre 0:c12e968e5b60 115 float fraclength, out;
dallegre 0:c12e968e5b60 116 };
dallegre 0:c12e968e5b60 117 inline float Delay::process(float in, float fbin, float length){
dallegre 0:c12e968e5b60 118 //update index values
dallegre 0:c12e968e5b60 119 index1++;
dallegre 0:c12e968e5b60 120 index2++;
dallegre 0:c12e968e5b60 121 if(index1 >= (DELAYLEN))
dallegre 0:c12e968e5b60 122 index1 = 0;
dallegre 0:c12e968e5b60 123 if(index2 >= (DELAYLEN))
dallegre 0:c12e968e5b60 124 index2 = 0;
dallegre 0:c12e968e5b60 125
dallegre 0:c12e968e5b60 126 //separate length into integer and fractional parts for interpolation
dallegre 0:c12e968e5b60 127 intlength = length;
dallegre 0:c12e968e5b60 128 fraclength = length - intlength;
dallegre 0:c12e968e5b60 129
dallegre 0:c12e968e5b60 130 //update indices based on delay length
dallegre 0:c12e968e5b60 131 index2 = index1 + intlength;
dallegre 0:c12e968e5b60 132 if(index2 >= DELAYLEN)
dallegre 0:c12e968e5b60 133 index2 = index1 + intlength - DELAYLEN;
dallegre 0:c12e968e5b60 134
dallegre 0:c12e968e5b60 135 //write to delay buffer
dallegre 1:a4ce08417c60 136 buffer[index1] = satAdd(in,fbin);
dallegre 0:c12e968e5b60 137
dallegre 0:c12e968e5b60 138 //read the delays out of the delay array. do some crazy interpolation stuff.
dallegre 0:c12e968e5b60 139 if(index2+1 < DELAYLEN){
dallegre 0:c12e968e5b60 140 out = linterp(buffer[index2],buffer[index2+1],fraclength); //worry about the converion from float to uint outside of this.
dallegre 0:c12e968e5b60 141 }else{
dallegre 0:c12e968e5b60 142 out = buffer[index2]; //probably just want to take the output of the delay and not the dry.
dallegre 0:c12e968e5b60 143 }
dallegre 0:c12e968e5b60 144 return out;
dallegre 1:a4ce08417c60 145 }