![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Simple mbed amplifier for quarter-inch audio input with volume, delay, and distortion control from smartphone app via bluetooth.
main.cpp@0:a487ac94eb85, 2017-05-02 (annotated)
- Committer:
- lindseysix
- Date:
- Tue May 02 00:28:13 2017 +0000
- Revision:
- 0:a487ac94eb85
Prototype amplifier with effects and smartphone control via bluetooth
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lindseysix | 0:a487ac94eb85 | 1 | //Library includes |
lindseysix | 0:a487ac94eb85 | 2 | #include "mbed.h" |
lindseysix | 0:a487ac94eb85 | 3 | #include "rtos.h" |
lindseysix | 0:a487ac94eb85 | 4 | |
lindseysix | 0:a487ac94eb85 | 5 | #define MAX_DELAY 10000 //Max size of delay effect sample buffer(too large can crash on compile from memory limit) |
lindseysix | 0:a487ac94eb85 | 6 | |
lindseysix | 0:a487ac94eb85 | 7 | //mbed pin declarations |
lindseysix | 0:a487ac94eb85 | 8 | |
lindseysix | 0:a487ac94eb85 | 9 | AnalogIn pot(p20); |
lindseysix | 0:a487ac94eb85 | 10 | DigitalOut led(LED1); |
lindseysix | 0:a487ac94eb85 | 11 | DigitalOut led2(LED2); |
lindseysix | 0:a487ac94eb85 | 12 | AnalogIn input(p15); |
lindseysix | 0:a487ac94eb85 | 13 | AnalogOut output(p18); |
lindseysix | 0:a487ac94eb85 | 14 | Serial pc(USBTX, USBRX); |
lindseysix | 0:a487ac94eb85 | 15 | Serial blue(p13,p14); |
lindseysix | 0:a487ac94eb85 | 16 | |
lindseysix | 0:a487ac94eb85 | 17 | //global variable declarations |
lindseysix | 0:a487ac94eb85 | 18 | |
lindseysix | 0:a487ac94eb85 | 19 | int inv_gain = 3; //scale factor for decreasing delay volume |
lindseysix | 0:a487ac94eb85 | 20 | int delay = 0; //store value for delay from smartphone app |
lindseysix | 0:a487ac94eb85 | 21 | float volume = .5; //store value for volume from smartphone app |
lindseysix | 0:a487ac94eb85 | 22 | float distortion = 1.0; //store value for distortion from smartphone app |
lindseysix | 0:a487ac94eb85 | 23 | unsigned short buffer[MAX_DELAY]; //declare array for storing samples for delay effect |
lindseysix | 0:a487ac94eb85 | 24 | int scaleFactor = 30; //global to convert int values from smartphone app sliders |
lindseysix | 0:a487ac94eb85 | 25 | |
lindseysix | 0:a487ac94eb85 | 26 | /******************************************************* |
lindseysix | 0:a487ac94eb85 | 27 | Bluetooth thread for reading input from smartphone app |
lindseysix | 0:a487ac94eb85 | 28 | ********************************************************/ |
lindseysix | 0:a487ac94eb85 | 29 | void threadBluetooth(void const *args) |
lindseysix | 0:a487ac94eb85 | 30 | { |
lindseysix | 0:a487ac94eb85 | 31 | while(1) |
lindseysix | 0:a487ac94eb85 | 32 | { |
lindseysix | 0:a487ac94eb85 | 33 | if(blue.readable()) //check if new value is available |
lindseysix | 0:a487ac94eb85 | 34 | { |
lindseysix | 0:a487ac94eb85 | 35 | int changeVal; //variable to hold value from smartphone app |
lindseysix | 0:a487ac94eb85 | 36 | changeVal = blue.getc(); //get new value from app via bluetooth |
lindseysix | 0:a487ac94eb85 | 37 | |
lindseysix | 0:a487ac94eb85 | 38 | if(changeVal <= scaleFactor) //check if new value falls in volume slider range |
lindseysix | 0:a487ac94eb85 | 39 | { |
lindseysix | 0:a487ac94eb85 | 40 | //convert volume to float value in range [0.0-1.0] |
lindseysix | 0:a487ac94eb85 | 41 | volume = (float)changeVal/((float)scaleFactor+3); |
lindseysix | 0:a487ac94eb85 | 42 | } |
lindseysix | 0:a487ac94eb85 | 43 | else if(changeVal <= scaleFactor*2) //check if value is in delay range |
lindseysix | 0:a487ac94eb85 | 44 | { |
lindseysix | 0:a487ac94eb85 | 45 | //convert delay to float in range (0.0 - 1.0] |
lindseysix | 0:a487ac94eb85 | 46 | delay = ((float)changeVal-((float)scaleFactor+1))/((float)scaleFactor)*MAX_DELAY; |
lindseysix | 0:a487ac94eb85 | 47 | |
lindseysix | 0:a487ac94eb85 | 48 | if(changeVal == 31) //if new value is bottom of delay slider |
lindseysix | 0:a487ac94eb85 | 49 | { |
lindseysix | 0:a487ac94eb85 | 50 | delay = 0; //set delay to zero (disable effect) |
lindseysix | 0:a487ac94eb85 | 51 | } |
lindseysix | 0:a487ac94eb85 | 52 | } |
lindseysix | 0:a487ac94eb85 | 53 | else if(changeVal <= scaleFactor*3) //check if value is in distortion range |
lindseysix | 0:a487ac94eb85 | 54 | { |
lindseysix | 0:a487ac94eb85 | 55 | //convert distortion to float in range (3.0 - 4.0) |
lindseysix | 0:a487ac94eb85 | 56 | distortion = 3.0 + ((float)changeVal-(2*(float)scaleFactor+1))/((float)scaleFactor); |
lindseysix | 0:a487ac94eb85 | 57 | |
lindseysix | 0:a487ac94eb85 | 58 | if(changeVal == 61) //if new value is bottom of distortion slider |
lindseysix | 0:a487ac94eb85 | 59 | { |
lindseysix | 0:a487ac94eb85 | 60 | distortion = 1; //set distortion to one (disable effect) |
lindseysix | 0:a487ac94eb85 | 61 | } |
lindseysix | 0:a487ac94eb85 | 62 | } |
lindseysix | 0:a487ac94eb85 | 63 | } |
lindseysix | 0:a487ac94eb85 | 64 | Thread::wait(100); |
lindseysix | 0:a487ac94eb85 | 65 | } //end bluetooth thread |
lindseysix | 0:a487ac94eb85 | 66 | |
lindseysix | 0:a487ac94eb85 | 67 | /***** |
lindseysix | 0:a487ac94eb85 | 68 | Main |
lindseysix | 0:a487ac94eb85 | 69 | *****/ |
lindseysix | 0:a487ac94eb85 | 70 | |
lindseysix | 0:a487ac94eb85 | 71 | int main(void) |
lindseysix | 0:a487ac94eb85 | 72 | { |
lindseysix | 0:a487ac94eb85 | 73 | Thread threadBlue(threadBluetooth); //startup Bluetooth thread for smartphone app |
lindseysix | 0:a487ac94eb85 | 74 | int oldDelay; //global for delay comparison |
lindseysix | 0:a487ac94eb85 | 75 | |
lindseysix | 0:a487ac94eb85 | 76 | while(1) |
lindseysix | 0:a487ac94eb85 | 77 | { |
lindseysix | 0:a487ac94eb85 | 78 | int i; //for loop count variable |
lindseysix | 0:a487ac94eb85 | 79 | |
lindseysix | 0:a487ac94eb85 | 80 | if(delay > 0) //check if delay effect is on |
lindseysix | 0:a487ac94eb85 | 81 | { |
lindseysix | 0:a487ac94eb85 | 82 | if(delay != oldDelay) //if delay value has changed re-buffer |
lindseysix | 0:a487ac94eb85 | 83 | { |
lindseysix | 0:a487ac94eb85 | 84 | for (i = 0; i < delay; i++) //buffer loop |
lindseysix | 0:a487ac94eb85 | 85 | { |
lindseysix | 0:a487ac94eb85 | 86 | buffer[i] += input.read_u16(); |
lindseysix | 0:a487ac94eb85 | 87 | oldDelay = delay; |
lindseysix | 0:a487ac94eb85 | 88 | } |
lindseysix | 0:a487ac94eb85 | 89 | } |
lindseysix | 0:a487ac94eb85 | 90 | while(delay > 0) //while delay is on |
lindseysix | 0:a487ac94eb85 | 91 | { |
lindseysix | 0:a487ac94eb85 | 92 | buffer[i] = buffer[i]/inv_gain + input.read_u16(); //scale buffer value and add to input |
lindseysix | 0:a487ac94eb85 | 93 | output.write_u16(distortion * volume * buffer[i]); //write to output |
lindseysix | 0:a487ac94eb85 | 94 | i = (i+1) % delay; //traverse buffer array(use delay number of values) |
lindseysix | 0:a487ac94eb85 | 95 | } |
lindseysix | 0:a487ac94eb85 | 96 | } |
lindseysix | 0:a487ac94eb85 | 97 | else |
lindseysix | 0:a487ac94eb85 | 98 | { |
lindseysix | 0:a487ac94eb85 | 99 | //with no delay write input value scaled by volume and distortion |
lindseysix | 0:a487ac94eb85 | 100 | output.write_u16(distortion * volume * input.read_u16()); |
lindseysix | 0:a487ac94eb85 | 101 | wait_us(23); //wait time based on sample rate |
lindseysix | 0:a487ac94eb85 | 102 | } |
lindseysix | 0:a487ac94eb85 | 103 | } |
lindseysix | 0:a487ac94eb85 | 104 | } //end main |