Music Visualizer / Mbed 2 deprecated 4180FinalProject

Dependencies:   mbed SDFileSystem NeoStrip PinDetect

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "PinDetect.h"
00003 #include "NeoStrip.h"
00004 #include "SDFileSystem.h"
00005 #include "wave_player.h"
00006 #include "rtos.h"
00007 #include <string>
00008 #include <vector>
00009 
00010 # define MAX_FILE 30
00011 
00012 #define N 40
00013 NeoStrip strip(p21, N);
00014 
00015 DigitalOut myled(LED1);
00016 
00017 DigitalIn b2(p29, PullUp);
00018 Serial pc(USBTX, USBRX);
00019 SDFileSystem sd(p5, p6, p7, p8, "sd");
00020 Ticker sampletick;
00021 AnalogOut speaker(p18);                  // Speaker (pin)
00022 wave_player waver(&speaker);
00023 Serial bt(p28, p27);      // Bluetooth
00024 DigitalOut mute(p29);          // mute pin (low for shutdown)
00025 
00026 PwmOut spk(p24);
00027 
00028 Thread thread1;
00029 Thread thread2;
00030 Thread thread3;
00031 Mutex sd_mtx;
00032 volatile int src = 1;  // 0 for Mic, 1 for SD card
00033 
00034 vector<string> filenames;               // list of files in sd card
00035 volatile int cur_song = 1;
00036 
00037 void read_file_names(char *dir) {
00038     DIR *dp;
00039     struct dirent *dirp;
00040     dp = opendir(dir);
00041     while ((dirp = readdir(dp)) != NULL) {
00042         filenames.push_back(string(dirp->d_name));
00043     }
00044     closedir(dp);
00045 }
00046 
00047 class microphone
00048 {
00049 public :
00050     microphone(PinName pin);
00051     float read();
00052     operator float ();
00053 private :
00054     AnalogIn _pin;
00055 };
00056 microphone::microphone (PinName pin):
00057     _pin(pin)
00058 {
00059 }
00060 float microphone::read()
00061 {
00062     return _pin.read();
00063 }
00064 inline microphone::operator float ()
00065 {
00066     return _pin.read();
00067 }
00068  
00069 microphone mymicrophone(p16);
00070 
00071 uint8_t r = (uint8_t)0;
00072 uint8_t g = (uint8_t)128;
00073 uint8_t b = (uint8_t)0;
00074 
00075 int red, green, blue;
00076  
00077 // fancy function to make rainbow colors on LEDs
00078 int hueToRGB(float h)
00079 {
00080     float r, g, b;
00081     if (h > 360)
00082         h -= 360;
00083     if (h < 0)
00084         h += 360;
00085     int i = (int)(h / 60.0);
00086     float f = (h / 60.0) - i;
00087     float q = 1 - f;
00088     
00089     switch (i % 6)
00090     {
00091         case 0: r = 1; g = f; b = 0; break;
00092         case 1: r = q; g = 1; b = 0; break;
00093         case 2: r = 0; g = 1; b = f; break;
00094         case 3: r = 0; g = q; b = 1; break;
00095         case 4: r = f; g = 0; b = 1; break;
00096         case 5: r = 1; g = 0; b = q; break;
00097         default: r = 0; g = 0; b = 0; break;
00098     }
00099     
00100     // scale to integers and return the packed value
00101     uint8_t R = (uint8_t)(r * 255);
00102     uint8_t G = (uint8_t)(g * 255);
00103     uint8_t B = (uint8_t)(b * 255);
00104 
00105     return (R << 16) | (G << 8) | B;
00106 }
00107 
00108 // convert float values to LED otuput for soundtest array
00109 void float2LED(float value){
00110     float fnumLED = abs((value - 0.5)/3.3)*100; // can mess with this scaling for better LED output
00111     int numLED = (int)fnumLED;
00112     if (numLED > 8) numLED = 8;
00113     
00114     static float dh = 360.0 / 5;
00115     static float x = 0;
00116     
00117     for(int i = 0; i < numLED; i++){
00118         int c = hueToRGB((dh * i) - x);
00119         strip.setPixel(i, c);
00120         strip.setPixel(i + 8, c);
00121         strip.setPixel(i + 16, c);
00122         strip.setPixel(i + 24, c);
00123         strip.setPixel(i + 32, c);
00124         }
00125     for(int i = numLED; i < 8; i++){
00126         strip.setPixel(i, 0x000000);
00127         strip.setPixel(i + 8, 0x000000);
00128         strip.setPixel(i + 16, 0x000000);
00129         strip.setPixel(i + 24, 0x000000);
00130         strip.setPixel(i + 32, 0x000000);
00131         }
00132     x += 1;
00133     if (x > 360)
00134         x = 0;
00135 }
00136 
00137 // same thing but for the mic
00138 void mic2LED(int mic){
00139     static float dh = 360.0 / 5;
00140     static float x = 0;
00141     
00142     int numLED = 0;
00143     if(mic == 0) numLED = 0;
00144     else if(mic == 1) numLED = 1;
00145     else if(mic == 2) numLED = 2;
00146     else if(mic == 3) numLED = 3;
00147     else if(mic == 4) numLED = 4;
00148     else if(mic == 5) numLED = 5;
00149     else if(mic == 6) numLED = 6;
00150     else if(mic == 7) numLED = 7;
00151     else if(mic == 8) numLED = 8;
00152     
00153     for(int i = 0; i < numLED; i++){
00154         int c = hueToRGB((dh * i) - x);
00155         strip.setPixel(i, c);
00156         strip.setPixel(i + 8, c);
00157         strip.setPixel(i + 16, c);
00158         strip.setPixel(i + 24, c);
00159         strip.setPixel(i + 32, c);
00160         }
00161     for(int i = numLED; i < 8; i++){
00162         strip.setPixel(i, 0x000000);
00163         strip.setPixel(i + 8, 0x000000);
00164         strip.setPixel(i + 16, 0x000000);
00165         strip.setPixel(i + 24, 0x000000);
00166         strip.setPixel(i + 32, 0x000000);
00167         }
00168     x += 1;
00169     if (x > 360)
00170         x = 0; 
00171 }
00172 
00173  
00174 void sound_thread() {
00175     FILE *wave_file;
00176     printf("\n\n\nHello, wave world!\n");
00177     string songstr = "/sd/songs/" + filenames[cur_song];
00178     printf("%s", songstr.c_str());
00179     wave_file=fopen(songstr.c_str(),"r");
00180     printf("file opened\n");
00181     waver.play(wave_file);
00182     fclose(wave_file);
00183     Thread::yield();
00184 }
00185     
00186 unsigned short max_range = 0xFFFF;
00187 // function that calls above functions
00188 void patternSound(){
00189     //for(int i = 0; i < 60; i++){
00190         float sample;
00191         float average = 0.67/3.3;//initial DC bias level
00192         
00193         int buffer[20];
00194         
00195         while(1){
00196             if (src) {
00197             // this part works for DAC PCM output //
00198             float test = (float)waver.dac_data/max_range;
00199             pc.printf("--%f", abs((test - 0.5)/3.3));
00200             float2LED(test);
00201             strip.write();
00202             }
00203             //------------------------------------//
00204             else {
00205             //microphone setup //
00206             int centervalue;
00207             for(int i = 0; i < 20; i++){
00208                 sample = mymicrophone;
00209                 //subtract 0.67V DC bias - but it varies quite a bit after loud or long sounds
00210                 average = 0.9999*average + 0.0001*sample;//try to slowly auto adjust the DC bias level
00211                 speaker = 0.5 +((sample - average)*33.0);//scale up to 0.0 to 1.0 for speaker output
00212                 
00213                 int micvalue = int(abs((sample - average)*300.0));
00214                 //pc.printf("-%d-", micvalue); //scale to around 15 for LEDs
00215                 
00216                 if(i == 1){
00217                     centervalue = micvalue;
00218                 }
00219                 buffer[i] = micvalue;
00220                 if(i > 10){
00221                     if(micvalue == buffer[1] && micvalue == buffer[2] && micvalue == buffer[3] &&
00222                         micvalue == buffer[4] && micvalue == buffer[5] && micvalue == buffer[6] && 
00223                         micvalue == buffer[7] && micvalue == buffer[8] && micvalue == buffer[9]){
00224                               centervalue = buffer[1];
00225                               }
00226                     }
00227                 int offset = micvalue-centervalue;
00228                 mic2LED(2+offset);
00229                 wait(1.0/4000.0);
00230                 }
00231             strip.write();
00232             Thread::wait(10);
00233             }
00234         }
00235 }
00236 
00237 void bt_thread() {
00238     char bnum = 0;
00239     char bhit = 0;
00240     while(1) {
00241         if (bt.readable()) {
00242             if (bt.getc()=='!') {
00243                 if (bt.getc()=='B') { //button data
00244                     bnum = bt.getc(); //button number
00245                     bhit = bt.getc(); //1 = hit, 0 = release
00246                     if (bhit == '1') {
00247                         switch (bnum) {
00248                             case '1':   // Button 1 for play/pause
00249                                 if (src) {
00250                                     if (waver.get_play_state() == 1) {
00251                                         waver.set_play_state(0);
00252                                         thread2.terminate();
00253                                         mute = 0;
00254                                     } else if (waver.get_play_state() == 0) {
00255                                         waver.set_play_state(1);
00256                                         thread2.start(sound_thread);
00257                                         mute = 1;
00258                                     }
00259                                 }
00260                                 break;
00261                             case '2':   // Button 2 for mute/unmute
00262                                 mute = !mute;
00263                                 break;
00264                             case '3':   // Button 3 to switch between mic/sd
00265                                 if (sd_mtx.trylock()) {
00266                                     sd_mtx.lock();
00267                                     src = src ? 0 : 1;
00268                                     if (src) {
00269                                         waver.set_play_state(1);
00270                                         thread2.start(sound_thread);
00271                                         mute = 1;
00272                                     } else {
00273                                         waver.set_play_state(0);
00274                                         while (thread2.get_state() == Thread::Running) {
00275                                             Thread::yield();
00276                                         }
00277                                         thread2.terminate();
00278                                         mute = 0;
00279                                     }
00280                                     sd_mtx.unlock();
00281                                     Thread::wait(100);
00282                                 }
00283                                 break;
00284                             case '7':   // Left arrow for previous
00285                                 if (sd_mtx.trylock() && src) {
00286                                     sd_mtx.lock();
00287                                     waver.set_play_state(0);
00288                                     if (cur_song > 0) {
00289                                         --cur_song;
00290                                     }
00291                                     while (thread2.get_state() == Thread::Running) {
00292                                         Thread::yield();
00293                                     }
00294                                     thread2.terminate();
00295                                     thread2.start(sound_thread);
00296                                     waver.set_play_state(1);
00297                                     sd_mtx.unlock();
00298                                 }
00299                                 break;
00300                             case '8':   // Right arrow for skip
00301                                 if (sd_mtx.trylock() && src) {
00302                                     sd_mtx.lock();
00303                                     waver.set_play_state(0);
00304                                     if (cur_song < filenames.size() - 1) {
00305                                         ++cur_song;
00306                                     }
00307                                     while (thread2.get_state() == Thread::Running) {
00308                                         Thread::yield();
00309                                     }
00310                                     thread2.terminate();
00311                                     thread2.start(sound_thread);
00312                                     waver.set_play_state(1);
00313                                     sd_mtx.unlock();
00314                                 }
00315                                 break;
00316                             default:
00317                                 break;
00318                         }
00319                     }
00320                 }
00321             }
00322         }
00323         Thread::wait(100);
00324     }
00325 }
00326 
00327 int main() {
00328     read_file_names("/sd/songs");
00329 
00330     strip.setBrightness(0.05);
00331     
00332     mute = 1;
00333         
00334     thread1.start(bt_thread);
00335     thread2.start(sound_thread);
00336     thread3.start(patternSound);
00337     
00338     while(1){
00339         myled = !myled;
00340         Thread::wait(100);
00341     }
00342 }
00343