An floppy drive audio generator using dsp on live audio

Dependencies:   Terminal asyncADC mbed-dsp mbed

Committer:
Condo2k4
Date:
Wed May 24 11:59:27 2017 +0000
Revision:
1:02553973d9cf
Parent:
0:84c336a81482
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Condo2k4 0:84c336a81482 1 //#include "mbed.h"
Condo2k4 0:84c336a81482 2 //#include <algorithm>
Condo2k4 0:84c336a81482 3 //#include "asyncADC.h"
Condo2k4 0:84c336a81482 4 //#include "arm_math.h"
Condo2k4 0:84c336a81482 5 //#include "arm_common_tables.h"
Condo2k4 0:84c336a81482 6 //#include "moppy.h"
Condo2k4 0:84c336a81482 7 //#include "Terminal.h"
Condo2k4 0:84c336a81482 8 //
Condo2k4 0:84c336a81482 9 //#define AUDIO_PIN (A0)
Condo2k4 0:84c336a81482 10 //
Condo2k4 0:84c336a81482 11 //Terminal pc(USBTX, USBRX, 115200);
Condo2k4 0:84c336a81482 12 //DigitalOut process_led(LED3); // Blue
Condo2k4 0:84c336a81482 13 //Timer timer;
Condo2k4 0:84c336a81482 14 //
Condo2k4 0:84c336a81482 15 //#define FFT_SIZE 2048
Condo2k4 0:84c336a81482 16 //#define SAMPLE_RATE_HZ 10000 // Sample rate in Hertz
Condo2k4 0:84c336a81482 17 //#include "fft.h"
Condo2k4 0:84c336a81482 18 //
Condo2k4 0:84c336a81482 19 //#define BIN_TO_FREQ(bin) ((bin*(long)SAMPLE_RATE_HZ)/FFT_SIZE)
Condo2k4 0:84c336a81482 20 //
Condo2k4 0:84c336a81482 21 //
Condo2k4 0:84c336a81482 22 //#define FREQ_ANALYSER_SCALAR (3)
Condo2k4 0:84c336a81482 23 //#define FREQ_ANALYSER_WIDTH (FFT_SIZE>>(FREQ_ANALYSER_SCALAR+1))
Condo2k4 0:84c336a81482 24 //#define FREQ_ANALYSER_HEIGHT (10)
Condo2k4 0:84c336a81482 25 //
Condo2k4 0:84c336a81482 26 ////BUFFERS
Condo2k4 0:84c336a81482 27 //
Condo2k4 0:84c336a81482 28 //uint16_t adcBuffer[FFT_SIZE*2];
Condo2k4 0:84c336a81482 29 //float fftBuffer[FFT_SIZE*2];
Condo2k4 0:84c336a81482 30 //float magnitudes[FFT_SIZE];
Condo2k4 0:84c336a81482 31 //char pcBuffer1[FREQ_ANALYSER_WIDTH+3];
Condo2k4 0:84c336a81482 32 //char pcBuffer2[FREQ_ANALYSER_WIDTH+3];
Condo2k4 0:84c336a81482 33 //
Condo2k4 0:84c336a81482 34 //
Condo2k4 0:84c336a81482 35 //// INTERRUPTS
Condo2k4 0:84c336a81482 36 //
Condo2k4 0:84c336a81482 37 //volatile int sectionCounter = 0;
Condo2k4 0:84c336a81482 38 //volatile bool sectionFilled = false;
Condo2k4 0:84c336a81482 39 //volatile uint32_t sectionStart, sectionEnd;
Condo2k4 0:84c336a81482 40 //
Condo2k4 0:84c336a81482 41 //void callback(uint32_t start, uint32_t end) {
Condo2k4 0:84c336a81482 42 // sectionFilled = true;
Condo2k4 0:84c336a81482 43 // sectionCounter++;
Condo2k4 0:84c336a81482 44 // sectionStart = start;
Condo2k4 0:84c336a81482 45 // sectionEnd = end;
Condo2k4 0:84c336a81482 46 //}
Condo2k4 0:84c336a81482 47 //
Condo2k4 0:84c336a81482 48 //// UTILS
Condo2k4 0:84c336a81482 49 //
Condo2k4 0:84c336a81482 50 //uint32_t ceilToPowerOf2(uint32_t i) {
Condo2k4 0:84c336a81482 51 // i--;
Condo2k4 0:84c336a81482 52 // i|=(i>>1);
Condo2k4 0:84c336a81482 53 // i|=(i>>2);
Condo2k4 0:84c336a81482 54 // i|=(i>>4);
Condo2k4 0:84c336a81482 55 // i|=(i>>8);
Condo2k4 0:84c336a81482 56 // i|=(i>>16);
Condo2k4 0:84c336a81482 57 // return i+1;
Condo2k4 0:84c336a81482 58 //}
Condo2k4 0:84c336a81482 59 //
Condo2k4 0:84c336a81482 60 //void trySwp(int16_t *indices, float *magnitudes, int a, int b) {
Condo2k4 0:84c336a81482 61 // if(magnitudes[indices[a]]>magnitudes[indices[b]]) {
Condo2k4 0:84c336a81482 62 // int x = indices[a];
Condo2k4 0:84c336a81482 63 // indices[a] = indices[b];
Condo2k4 0:84c336a81482 64 // indices[b] = x;
Condo2k4 0:84c336a81482 65 // }
Condo2k4 0:84c336a81482 66 //}
Condo2k4 0:84c336a81482 67 //
Condo2k4 0:84c336a81482 68 //void sort(int16_t *indices, float *magnitudes, int size) {
Condo2k4 0:84c336a81482 69 // indices[0] = 0;
Condo2k4 0:84c336a81482 70 // for(int i=1; i<size; i++) {
Condo2k4 0:84c336a81482 71 // indices[i]=i;
Condo2k4 0:84c336a81482 72 // for(int j=i; j-->0;) {
Condo2k4 0:84c336a81482 73 // trySwp(indices, magnitudes, j, j+1);
Condo2k4 0:84c336a81482 74 // }
Condo2k4 0:84c336a81482 75 // }
Condo2k4 0:84c336a81482 76 //}
Condo2k4 0:84c336a81482 77 //
Condo2k4 0:84c336a81482 78 //bool magComparator(int const & a, int const & b) {
Condo2k4 0:84c336a81482 79 // return magnitudes[a] > magnitudes[b];
Condo2k4 0:84c336a81482 80 //}
Condo2k4 0:84c336a81482 81 //
Condo2k4 0:84c336a81482 82 //// MAIN
Condo2k4 0:84c336a81482 83 //
Condo2k4 0:84c336a81482 84 //int main()
Condo2k4 0:84c336a81482 85 //{
Condo2k4 0:84c336a81482 86 //
Condo2k4 0:84c336a81482 87 // pcBuffer1[0] = '|';
Condo2k4 0:84c336a81482 88 // pcBuffer1[FREQ_ANALYSER_WIDTH+1] = '|';
Condo2k4 0:84c336a81482 89 // pcBuffer1[FREQ_ANALYSER_WIDTH+2] = 0;
Condo2k4 0:84c336a81482 90 // memset(pcBuffer2+1, '-', FREQ_ANALYSER_WIDTH);
Condo2k4 0:84c336a81482 91 // pcBuffer2[0] = '+';
Condo2k4 0:84c336a81482 92 // pcBuffer2[FREQ_ANALYSER_WIDTH+1] = '+';
Condo2k4 0:84c336a81482 93 // pcBuffer2[FREQ_ANALYSER_WIDTH+2] = 0;
Condo2k4 0:84c336a81482 94 //
Condo2k4 0:84c336a81482 95 // process_led = 1;
Condo2k4 0:84c336a81482 96 //
Condo2k4 0:84c336a81482 97 // pc.cls();
Condo2k4 0:84c336a81482 98 // pc.cursor(false);
Condo2k4 0:84c336a81482 99 // pc.locate(0,0);
Condo2k4 0:84c336a81482 100 // pc.printf("Synchronising Floppy Drives\r\n");
Condo2k4 0:84c336a81482 101 //
Condo2k4 0:84c336a81482 102 // Moppy moppy(D1, D0, 38400); // tx, rx, baud
Condo2k4 0:84c336a81482 103 //
Condo2k4 0:84c336a81482 104 // pc.printf("Setup Complete\r\n");
Condo2k4 0:84c336a81482 105 //
Condo2k4 0:84c336a81482 106 // switch(asyncAnalogToCircularBuffer(AUDIO_PIN, adcBuffer, 2*FFT_SIZE, SAMPLE_RATE_HZ, callback)) {
Condo2k4 0:84c336a81482 107 // case E_ASYNC_ADC_ACTIVE:
Condo2k4 0:84c336a81482 108 // error("AsyncADC already in use");
Condo2k4 0:84c336a81482 109 // case E_DMA_IN_USE:
Condo2k4 0:84c336a81482 110 // error("DMA already in use");
Condo2k4 0:84c336a81482 111 // case E_INVALID_BUFFER_SIZE:
Condo2k4 0:84c336a81482 112 // error("Invalid destination buffer size");
Condo2k4 0:84c336a81482 113 // }
Condo2k4 0:84c336a81482 114 //
Condo2k4 0:84c336a81482 115 // int16_t indices[FFT_SIZE*2];
Condo2k4 0:84c336a81482 116 //
Condo2k4 0:84c336a81482 117 // timer.start();
Condo2k4 0:84c336a81482 118 //
Condo2k4 0:84c336a81482 119 // pc.locate(0,16);
Condo2k4 0:84c336a81482 120 // pc.printf("%dHz", BIN_TO_FREQ(1));
Condo2k4 0:84c336a81482 121 // pc.locate(FREQ_ANALYSER_WIDTH-20,16);
Condo2k4 0:84c336a81482 122 // pc.printf("%20dHz", BIN_TO_FREQ(FFT_SIZE/2));
Condo2k4 0:84c336a81482 123 //
Condo2k4 0:84c336a81482 124 // while(1) {
Condo2k4 0:84c336a81482 125 // if(sectionFilled) {
Condo2k4 0:84c336a81482 126 // process_led = 0;
Condo2k4 0:84c336a81482 127 //
Condo2k4 0:84c336a81482 128 // timer.reset();
Condo2k4 0:84c336a81482 129 //
Condo2k4 0:84c336a81482 130 // //convert to floating point
Condo2k4 0:84c336a81482 131 // for(int i=sectionStart, j=0; i<=sectionEnd; i++, j+=2) {
Condo2k4 0:84c336a81482 132 // fftBuffer[j] = (float)adcBuffer[i];
Condo2k4 0:84c336a81482 133 // fftBuffer[j+1] = 0.0f;
Condo2k4 0:84c336a81482 134 // }
Condo2k4 0:84c336a81482 135 //
Condo2k4 0:84c336a81482 136 // // Calculate FFT if a full sample is available.
Condo2k4 0:84c336a81482 137 // // Run FFT on sample data.
Condo2k4 0:84c336a81482 138 // arm_cfft_f32(FFT_BUFFER, fftBuffer, 0, 1);
Condo2k4 0:84c336a81482 139 // // Calculate magnitude of complex numbers output by the FFT.
Condo2k4 0:84c336a81482 140 // arm_cmplx_mag_f32(fftBuffer, magnitudes, FFT_SIZE);
Condo2k4 0:84c336a81482 141 //
Condo2k4 0:84c336a81482 142 // for(int i=1; i<FFT_SIZE; i++)
Condo2k4 0:84c336a81482 143 // indices[i]=i;
Condo2k4 0:84c336a81482 144 // std::sort(indices + 1, indices + (FFT_SIZE/2), magComparator);
Condo2k4 0:84c336a81482 145 //
Condo2k4 0:84c336a81482 146 // //REMEMBER: Ignore Indicies[0]!!!!
Condo2k4 0:84c336a81482 147 // moppy.setFrequency(0, BIN_TO_FREQ(indices[1]));
Condo2k4 0:84c336a81482 148 // moppy.setFrequency(1, BIN_TO_FREQ(indices[2]));
Condo2k4 0:84c336a81482 149 // moppy.setFrequency(2, BIN_TO_FREQ(indices[3]));
Condo2k4 0:84c336a81482 150 // moppy.setFrequency(3, BIN_TO_FREQ(indices[4]));
Condo2k4 0:84c336a81482 151 // moppy.flush();
Condo2k4 0:84c336a81482 152 //
Condo2k4 0:84c336a81482 153 // pc.locate(0, 4);
Condo2k4 0:84c336a81482 154 // pc.puts(pcBuffer2);
Condo2k4 0:84c336a81482 155 // memset(pcBuffer1+1, ' ', FREQ_ANALYSER_WIDTH);
Condo2k4 0:84c336a81482 156 // float max = magnitudes[indices[1]];
Condo2k4 0:84c336a81482 157 // if(max<1000000) max = 1000000;
Condo2k4 0:84c336a81482 158 // for(int i=2; i<FFT_SIZE/2; i++) {
Condo2k4 0:84c336a81482 159 // int j = (i>>FREQ_ANALYSER_SCALAR)+1;
Condo2k4 0:84c336a81482 160 // if(magnitudes[i] > magnitudes[j])
Condo2k4 0:84c336a81482 161 // magnitudes[j] = magnitudes[i];
Condo2k4 0:84c336a81482 162 // }
Condo2k4 0:84c336a81482 163 // for(int y=0; y<FREQ_ANALYSER_HEIGHT; y++) {
Condo2k4 0:84c336a81482 164 // float thresh = max*(FREQ_ANALYSER_HEIGHT-y)/(FREQ_ANALYSER_HEIGHT+1.0f);//((FREQ_ANALYSER_HEIGHT-1)-y)*max/(FREQ_ANALYSER_HEIGHT+1);
Condo2k4 0:84c336a81482 165 // for(int x=1; x<=FREQ_ANALYSER_WIDTH; x++)
Condo2k4 0:84c336a81482 166 // if(pcBuffer1[x]!='#' && magnitudes[x]>thresh)
Condo2k4 0:84c336a81482 167 // pcBuffer1[x]='#';
Condo2k4 0:84c336a81482 168 // pc.locate(0, y+5);
Condo2k4 0:84c336a81482 169 // pc.puts(pcBuffer1);
Condo2k4 0:84c336a81482 170 // }
Condo2k4 0:84c336a81482 171 // pc.locate(0, FREQ_ANALYSER_HEIGHT+5);
Condo2k4 0:84c336a81482 172 // pc.puts(pcBuffer2);
Condo2k4 0:84c336a81482 173 //
Condo2k4 0:84c336a81482 174 //
Condo2k4 0:84c336a81482 175 // long process_time = timer.read_us();
Condo2k4 0:84c336a81482 176 //
Condo2k4 0:84c336a81482 177 //
Condo2k4 0:84c336a81482 178 // long x = (process_time)/(100*FFT_SIZE/SAMPLE_RATE_HZ);
Condo2k4 0:84c336a81482 179 //
Condo2k4 0:84c336a81482 180 // pc.locate(0,2);
Condo2k4 0:84c336a81482 181 // pc.printf("Process Time:%3d.%02dms ~%d.%02d%%", process_time/1000, ((process_time+5)/10)%100, x/100, x%100);
Condo2k4 0:84c336a81482 182 //// pc.printf("\r\n%f", magnitudes[indices[1]]);
Condo2k4 0:84c336a81482 183 //
Condo2k4 0:84c336a81482 184 // process_led = 1;
Condo2k4 0:84c336a81482 185 //
Condo2k4 0:84c336a81482 186 // sectionFilled = false;
Condo2k4 0:84c336a81482 187 // }
Condo2k4 0:84c336a81482 188 // sleep();
Condo2k4 0:84c336a81482 189 // }
Condo2k4 0:84c336a81482 190 //}