
Music Visualizer
Dependencies: mbed SDFileSystem NeoStrip PinDetect
main.cpp
- Committer:
- spatel465
- Date:
- 2020-04-30
- Revision:
- 6:2f0706de9553
- Parent:
- 5:b6f462ece58f
- Child:
- 8:fa37292cf52c
File content as of revision 6:2f0706de9553:
#include "mbed.h" #include "PinDetect.h" #include "NeoStrip.h" #include "SDFileSystem.h" #include "wave_player.h" #include "rtos.h" #include <string> #include <vector> # define MAX_FILE 30 #define N 40 NeoStrip strip(p21, N); //BusOut myleds(LED1,LED2,LED3,LED4); DigitalOut myled(LED1); DigitalIn b2(p29, PullUp); Serial pc(USBTX, USBRX); SDFileSystem sd(p5, p6, p7, p8, "sd"); Ticker sampletick; AnalogOut speaker(p18); // Speaker (pin) wave_player waver(&speaker); Serial bt(p28, p27); // Bluetooth DigitalOut mute(p29); // mute pin (low for shutdown) PwmOut spk(p24); Thread thread1; Thread thread2; Thread thread3; Mutex sd_mtx; volatile int src = 1; // 0 for Mic, 1 for SD card vector<string> filenames; // list of files in sd card volatile int cur_song = 1; void read_file_names(char *dir) { DIR *dp; struct dirent *dirp; dp = opendir(dir); while ((dirp = readdir(dp)) != NULL) { filenames.push_back(string(dirp->d_name)); } closedir(dp); } class microphone { public : microphone(PinName pin); float read(); operator float (); private : AnalogIn _pin; }; microphone::microphone (PinName pin): _pin(pin) { } float microphone::read() { return _pin.read(); } inline microphone::operator float () { return _pin.read(); } microphone mymicrophone(p16); uint8_t r = (uint8_t)0; uint8_t g = (uint8_t)128; uint8_t b = (uint8_t)0; int red, green, blue; // fancy function to make rainbow colors on LEDs int hueToRGB(float h) { float r, g, b; if (h > 360) h -= 360; if (h < 0) h += 360; int i = (int)(h / 60.0); float f = (h / 60.0) - i; float q = 1 - f; switch (i % 6) { case 0: r = 1; g = f; b = 0; break; case 1: r = q; g = 1; b = 0; break; case 2: r = 0; g = 1; b = f; break; case 3: r = 0; g = q; b = 1; break; case 4: r = f; g = 0; b = 1; break; case 5: r = 1; g = 0; b = q; break; default: r = 0; g = 0; b = 0; break; } // scale to integers and return the packed value uint8_t R = (uint8_t)(r * 255); uint8_t G = (uint8_t)(g * 255); uint8_t B = (uint8_t)(b * 255); return (R << 16) | (G << 8) | B; } // convert float values to LED otuput for soundtest array void float2LED(float value){ float fnumLED = abs((value - 0.5)/3.3)*100; // can mess with this scaling for better LED output int numLED = (int)fnumLED; if (numLED > 8) numLED = 8; static float dh = 360.0 / 5; static float x = 0; for(int i = 0; i < numLED; i++){ int c = hueToRGB((dh * i) - x); strip.setPixel(i, c); strip.setPixel(i + 8, c); strip.setPixel(i + 16, c); strip.setPixel(i + 24, c); strip.setPixel(i + 32, c); } for(int i = numLED; i < 8; i++){ strip.setPixel(i, 0x000000); strip.setPixel(i + 8, 0x000000); strip.setPixel(i + 16, 0x000000); strip.setPixel(i + 24, 0x000000); strip.setPixel(i + 32, 0x000000); // old setup for 5 rows of 8 LEDs //strip.setPixel(i + i * 7, 0x000000); // strip.setPixel(i + 1 + i * 7, 0x000000); // strip.setPixel(i + 2 + i * 7, 0x000000); // strip.setPixel(i + 3 + i * 7, 0x000000); // strip.setPixel(i + 4 + i * 7, 0x000000); // strip.setPixel(i + 5 + i * 7, 0x000000); // strip.setPixel(i + 6 + i * 7, 0x000000); // strip.setPixel(i + 7 + i * 7, 0x000000); } x += 1; if (x > 360) x = 0; } // same thing but for the mic void mic2LED(int mic){ static float dh = 360.0 / 5; static float x = 0; int numLED = 0; if(mic == 0) numLED = 0; else if(mic == 1) numLED = 1; else if(mic == 2) numLED = 2; else if(mic == 3) numLED = 3; else if(mic == 4) numLED = 4; else if(mic == 5) numLED = 5; else if(mic == 6) numLED = 6; else if(mic == 7) numLED = 7; else if(mic == 8) numLED = 8; for(int i = 0; i < numLED; i++){ int c = hueToRGB((dh * i) - x); strip.setPixel(i, c); strip.setPixel(i + 8, c); strip.setPixel(i + 16, c); strip.setPixel(i + 24, c); strip.setPixel(i + 32, c); } for(int i = numLED; i < 8; i++){ strip.setPixel(i, 0x000000); strip.setPixel(i + 8, 0x000000); strip.setPixel(i + 16, 0x000000); strip.setPixel(i + 24, 0x000000); strip.setPixel(i + 32, 0x000000); } x += 1; if (x > 360) x = 0; } void sound_thread() { FILE *wave_file; printf("\n\n\nHello, wave world!\n"); string songstr = "/sd/songs/" + filenames[cur_song]; printf("%s", songstr.c_str()); wave_file=fopen(songstr.c_str(),"r"); printf("file opened\n"); waver.play(wave_file); fclose(wave_file); Thread::yield(); } unsigned short max_range = 0xFFFF; // function that calls above functions void patternSound(){ //for(int i = 0; i < 60; i++){ float sample; float average = 0.67/3.3;//initial DC bias level int buffer[20]; while(1){ if (src) { // this part works for DAC PCM output // float test = (float)waver.dac_data/max_range; pc.printf("--%f", abs((test - 0.5)/3.3)); float2LED(test); strip.write(); } //------------------------------------// else { //microphone setup // int centervalue; for(int i = 0; i < 20; i++){ sample = mymicrophone; //subtract 0.67V DC bias - but it varies quite a bit after loud or long sounds average = 0.9999*average + 0.0001*sample;//try to slowly auto adjust the DC bias level speaker = 0.5 +((sample - average)*33.0);//scale up to 0.0 to 1.0 for speaker output int micvalue = int(abs((sample - average)*300.0)); //pc.printf("-%d-", micvalue); //scale to around 15 for LEDs if(i == 1){ centervalue = micvalue; } buffer[i] = micvalue; if(i > 10){ if(micvalue == buffer[1] && micvalue == buffer[2] && micvalue == buffer[3] && micvalue == buffer[4] && micvalue == buffer[5] && micvalue == buffer[6] && micvalue == buffer[7] && micvalue == buffer[8] && micvalue == buffer[9]){ centervalue = buffer[1]; //pc.printf("-%d-", centervalue); } } int offset = micvalue-centervalue; //pc.printf(" %d ", offset); //myleds = micvalue; mic2LED(2+offset); wait(1.0/4000.0); } //////////////////////////////////////////////////////// strip.write(); Thread::wait(10); } } } void bt_thread() { char bnum = 0; char bhit = 0; while(1) { if (bt.readable()) { if (bt.getc()=='!') { if (bt.getc()=='B') { //button data bnum = bt.getc(); //button number bhit = bt.getc(); //1 = hit, 0 = release if (bhit == '1') { switch (bnum) { case '1': // Button 1 for play/pause if (waver.get_play_state() == 1) { waver.set_play_state(0); thread2.terminate(); mute = 0; } else if (waver.get_play_state() == 0) { waver.set_play_state(1); thread2.start(sound_thread); mute = 1; } break; case '2': // Button 2 for mute/unmute mute = !mute; break; case '3': // Button 3 to switch between mic/sd if (sd_mtx.trylock()) { sd_mtx.lock(); src = src ? 0 : 1; if (src) { waver.set_play_state(1); thread2.start(sound_thread); mute = 1; } else { waver.set_play_state(0); while (thread2.get_state() == Thread::Running) { Thread::yield(); } thread2.terminate(); mute = 0; } sd_mtx.unlock(); Thread::wait(100); } break; case '7': // Left arrow for previous if (sd_mtx.trylock()) { sd_mtx.lock(); waver.set_play_state(0); if (cur_song > 0) { --cur_song; } while (thread2.get_state() == Thread::Running) { Thread::yield(); } thread2.terminate(); thread2.start(sound_thread); waver.set_play_state(1); sd_mtx.unlock(); } break; case '8': // Right arrow for skip if (sd_mtx.trylock()) { sd_mtx.lock(); waver.set_play_state(0); if (cur_song < filenames.size() - 1) { ++cur_song; } while (thread2.get_state() == Thread::Running) { Thread::yield(); } thread2.terminate(); thread2.start(sound_thread); waver.set_play_state(1); sd_mtx.unlock(); } break; default: break; } } } } } Thread::wait(100); } } int main() { read_file_names("/sd/songs"); strip.setBrightness(0.05); mute = 1; thread1.start(bt_thread); thread2.start(sound_thread); thread3.start(patternSound); while(1){ myled = !myled; Thread::wait(100); } }