Music Visualizer

Dependencies:   mbed SDFileSystem NeoStrip PinDetect

Committer:
spatel465
Date:
Thu Apr 30 02:33:57 2020 +0000
Revision:
6:2f0706de9553
Parent:
5:b6f462ece58f
Child:
8:fa37292cf52c
fixed mic2led

Who changed what in which revision?

UserRevisionLine numberNew contents of line
spatel465 0:adce77867281 1 #include "mbed.h"
spatel465 0:adce77867281 2 #include "PinDetect.h"
spatel465 0:adce77867281 3 #include "NeoStrip.h"
spatel465 0:adce77867281 4 #include "SDFileSystem.h"
spatel465 0:adce77867281 5 #include "wave_player.h"
spatel465 0:adce77867281 6 #include "rtos.h"
spatel465 0:adce77867281 7 #include <string>
spatel465 0:adce77867281 8 #include <vector>
spatel465 0:adce77867281 9
spatel465 0:adce77867281 10 # define MAX_FILE 30
spatel465 0:adce77867281 11
spatel465 0:adce77867281 12 #define N 40
spatel465 0:adce77867281 13 NeoStrip strip(p21, N);
spatel465 0:adce77867281 14
spatel465 0:adce77867281 15 //BusOut myleds(LED1,LED2,LED3,LED4);
spatel465 0:adce77867281 16 DigitalOut myled(LED1);
spatel465 0:adce77867281 17
spatel465 0:adce77867281 18 DigitalIn b2(p29, PullUp);
spatel465 0:adce77867281 19 Serial pc(USBTX, USBRX);
spatel465 0:adce77867281 20 SDFileSystem sd(p5, p6, p7, p8, "sd");
spatel465 0:adce77867281 21 Ticker sampletick;
spatel465 0:adce77867281 22 AnalogOut speaker(p18); // Speaker (pin)
spatel465 0:adce77867281 23 wave_player waver(&speaker);
spatel465 0:adce77867281 24 Serial bt(p28, p27); // Bluetooth
spatel465 0:adce77867281 25 DigitalOut mute(p29); // mute pin (low for shutdown)
spatel465 0:adce77867281 26
spatel465 0:adce77867281 27 PwmOut spk(p24);
spatel465 0:adce77867281 28
spatel465 0:adce77867281 29 Thread thread1;
spatel465 0:adce77867281 30 Thread thread2;
spatel465 0:adce77867281 31 Thread thread3;
spatel465 0:adce77867281 32 Mutex sd_mtx;
makkoli98 4:6fbdec5bc602 33 volatile int src = 1; // 0 for Mic, 1 for SD card
spatel465 0:adce77867281 34
spatel465 0:adce77867281 35 vector<string> filenames; // list of files in sd card
spatel465 0:adce77867281 36 volatile int cur_song = 1;
spatel465 0:adce77867281 37
spatel465 0:adce77867281 38 void read_file_names(char *dir) {
spatel465 0:adce77867281 39 DIR *dp;
spatel465 0:adce77867281 40 struct dirent *dirp;
spatel465 0:adce77867281 41 dp = opendir(dir);
spatel465 0:adce77867281 42 while ((dirp = readdir(dp)) != NULL) {
spatel465 0:adce77867281 43 filenames.push_back(string(dirp->d_name));
spatel465 0:adce77867281 44 }
spatel465 0:adce77867281 45 closedir(dp);
spatel465 0:adce77867281 46 }
spatel465 0:adce77867281 47
spatel465 0:adce77867281 48 class microphone
spatel465 0:adce77867281 49 {
spatel465 0:adce77867281 50 public :
spatel465 0:adce77867281 51 microphone(PinName pin);
spatel465 0:adce77867281 52 float read();
spatel465 0:adce77867281 53 operator float ();
spatel465 0:adce77867281 54 private :
spatel465 0:adce77867281 55 AnalogIn _pin;
spatel465 0:adce77867281 56 };
spatel465 0:adce77867281 57 microphone::microphone (PinName pin):
spatel465 0:adce77867281 58 _pin(pin)
spatel465 0:adce77867281 59 {
spatel465 0:adce77867281 60 }
spatel465 0:adce77867281 61 float microphone::read()
spatel465 0:adce77867281 62 {
spatel465 0:adce77867281 63 return _pin.read();
spatel465 0:adce77867281 64 }
spatel465 0:adce77867281 65 inline microphone::operator float ()
spatel465 0:adce77867281 66 {
spatel465 0:adce77867281 67 return _pin.read();
spatel465 0:adce77867281 68 }
spatel465 0:adce77867281 69
spatel465 0:adce77867281 70 microphone mymicrophone(p16);
spatel465 0:adce77867281 71
spatel465 0:adce77867281 72 uint8_t r = (uint8_t)0;
spatel465 0:adce77867281 73 uint8_t g = (uint8_t)128;
spatel465 0:adce77867281 74 uint8_t b = (uint8_t)0;
spatel465 0:adce77867281 75
spatel465 0:adce77867281 76 int red, green, blue;
spatel465 0:adce77867281 77
spatel465 0:adce77867281 78 // fancy function to make rainbow colors on LEDs
spatel465 0:adce77867281 79 int hueToRGB(float h)
spatel465 0:adce77867281 80 {
spatel465 0:adce77867281 81 float r, g, b;
spatel465 0:adce77867281 82 if (h > 360)
spatel465 0:adce77867281 83 h -= 360;
spatel465 0:adce77867281 84 if (h < 0)
spatel465 0:adce77867281 85 h += 360;
spatel465 0:adce77867281 86 int i = (int)(h / 60.0);
spatel465 0:adce77867281 87 float f = (h / 60.0) - i;
spatel465 0:adce77867281 88 float q = 1 - f;
spatel465 0:adce77867281 89
spatel465 0:adce77867281 90 switch (i % 6)
spatel465 0:adce77867281 91 {
spatel465 0:adce77867281 92 case 0: r = 1; g = f; b = 0; break;
spatel465 0:adce77867281 93 case 1: r = q; g = 1; b = 0; break;
spatel465 0:adce77867281 94 case 2: r = 0; g = 1; b = f; break;
spatel465 0:adce77867281 95 case 3: r = 0; g = q; b = 1; break;
spatel465 0:adce77867281 96 case 4: r = f; g = 0; b = 1; break;
spatel465 0:adce77867281 97 case 5: r = 1; g = 0; b = q; break;
spatel465 0:adce77867281 98 default: r = 0; g = 0; b = 0; break;
spatel465 0:adce77867281 99 }
spatel465 0:adce77867281 100
spatel465 0:adce77867281 101 // scale to integers and return the packed value
spatel465 0:adce77867281 102 uint8_t R = (uint8_t)(r * 255);
spatel465 0:adce77867281 103 uint8_t G = (uint8_t)(g * 255);
spatel465 0:adce77867281 104 uint8_t B = (uint8_t)(b * 255);
spatel465 0:adce77867281 105
spatel465 0:adce77867281 106 return (R << 16) | (G << 8) | B;
spatel465 0:adce77867281 107 }
spatel465 0:adce77867281 108
spatel465 0:adce77867281 109 // convert float values to LED otuput for soundtest array
spatel465 0:adce77867281 110 void float2LED(float value){
spatel465 0:adce77867281 111 float fnumLED = abs((value - 0.5)/3.3)*100; // can mess with this scaling for better LED output
spatel465 0:adce77867281 112 int numLED = (int)fnumLED;
spatel465 0:adce77867281 113 if (numLED > 8) numLED = 8;
spatel465 0:adce77867281 114
spatel465 0:adce77867281 115 static float dh = 360.0 / 5;
spatel465 0:adce77867281 116 static float x = 0;
spatel465 0:adce77867281 117
spatel465 0:adce77867281 118 for(int i = 0; i < numLED; i++){
spatel465 0:adce77867281 119 int c = hueToRGB((dh * i) - x);
spatel465 0:adce77867281 120 strip.setPixel(i, c);
spatel465 0:adce77867281 121 strip.setPixel(i + 8, c);
spatel465 0:adce77867281 122 strip.setPixel(i + 16, c);
spatel465 0:adce77867281 123 strip.setPixel(i + 24, c);
spatel465 0:adce77867281 124 strip.setPixel(i + 32, c);
spatel465 0:adce77867281 125 }
spatel465 0:adce77867281 126 for(int i = numLED; i < 8; i++){
spatel465 0:adce77867281 127 strip.setPixel(i, 0x000000);
spatel465 0:adce77867281 128 strip.setPixel(i + 8, 0x000000);
spatel465 0:adce77867281 129 strip.setPixel(i + 16, 0x000000);
spatel465 0:adce77867281 130 strip.setPixel(i + 24, 0x000000);
spatel465 0:adce77867281 131 strip.setPixel(i + 32, 0x000000);
spatel465 0:adce77867281 132
spatel465 0:adce77867281 133 // old setup for 5 rows of 8 LEDs
spatel465 0:adce77867281 134 //strip.setPixel(i + i * 7, 0x000000);
spatel465 0:adce77867281 135 // strip.setPixel(i + 1 + i * 7, 0x000000);
spatel465 0:adce77867281 136 // strip.setPixel(i + 2 + i * 7, 0x000000);
spatel465 0:adce77867281 137 // strip.setPixel(i + 3 + i * 7, 0x000000);
spatel465 0:adce77867281 138 // strip.setPixel(i + 4 + i * 7, 0x000000);
spatel465 0:adce77867281 139 // strip.setPixel(i + 5 + i * 7, 0x000000);
spatel465 0:adce77867281 140 // strip.setPixel(i + 6 + i * 7, 0x000000);
spatel465 0:adce77867281 141 // strip.setPixel(i + 7 + i * 7, 0x000000);
spatel465 0:adce77867281 142 }
spatel465 0:adce77867281 143 x += 1;
spatel465 0:adce77867281 144 if (x > 360)
spatel465 0:adce77867281 145 x = 0;
spatel465 0:adce77867281 146 }
spatel465 0:adce77867281 147
spatel465 0:adce77867281 148 // same thing but for the mic
spatel465 0:adce77867281 149 void mic2LED(int mic){
spatel465 0:adce77867281 150 static float dh = 360.0 / 5;
spatel465 0:adce77867281 151 static float x = 0;
spatel465 0:adce77867281 152
spatel465 0:adce77867281 153 int numLED = 0;
spatel465 0:adce77867281 154 if(mic == 0) numLED = 0;
spatel465 0:adce77867281 155 else if(mic == 1) numLED = 1;
spatel465 0:adce77867281 156 else if(mic == 2) numLED = 2;
spatel465 0:adce77867281 157 else if(mic == 3) numLED = 3;
spatel465 0:adce77867281 158 else if(mic == 4) numLED = 4;
spatel465 6:2f0706de9553 159 else if(mic == 5) numLED = 5;
spatel465 6:2f0706de9553 160 else if(mic == 6) numLED = 6;
spatel465 6:2f0706de9553 161 else if(mic == 7) numLED = 7;
spatel465 6:2f0706de9553 162 else if(mic == 8) numLED = 8;
spatel465 0:adce77867281 163
spatel465 0:adce77867281 164 for(int i = 0; i < numLED; i++){
spatel465 0:adce77867281 165 int c = hueToRGB((dh * i) - x);
spatel465 0:adce77867281 166 strip.setPixel(i, c);
spatel465 0:adce77867281 167 strip.setPixel(i + 8, c);
spatel465 0:adce77867281 168 strip.setPixel(i + 16, c);
spatel465 0:adce77867281 169 strip.setPixel(i + 24, c);
spatel465 0:adce77867281 170 strip.setPixel(i + 32, c);
spatel465 0:adce77867281 171 }
spatel465 0:adce77867281 172 for(int i = numLED; i < 8; i++){
spatel465 0:adce77867281 173 strip.setPixel(i, 0x000000);
spatel465 0:adce77867281 174 strip.setPixel(i + 8, 0x000000);
spatel465 0:adce77867281 175 strip.setPixel(i + 16, 0x000000);
spatel465 0:adce77867281 176 strip.setPixel(i + 24, 0x000000);
spatel465 0:adce77867281 177 strip.setPixel(i + 32, 0x000000);
spatel465 0:adce77867281 178 }
spatel465 0:adce77867281 179 x += 1;
spatel465 0:adce77867281 180 if (x > 360)
spatel465 0:adce77867281 181 x = 0;
spatel465 0:adce77867281 182 }
spatel465 0:adce77867281 183
spatel465 0:adce77867281 184
spatel465 0:adce77867281 185 void sound_thread() {
spatel465 0:adce77867281 186 FILE *wave_file;
spatel465 0:adce77867281 187 printf("\n\n\nHello, wave world!\n");
spatel465 0:adce77867281 188 string songstr = "/sd/songs/" + filenames[cur_song];
spatel465 0:adce77867281 189 printf("%s", songstr.c_str());
spatel465 0:adce77867281 190 wave_file=fopen(songstr.c_str(),"r");
spatel465 0:adce77867281 191 printf("file opened\n");
spatel465 0:adce77867281 192 waver.play(wave_file);
spatel465 0:adce77867281 193 fclose(wave_file);
spatel465 0:adce77867281 194 Thread::yield();
spatel465 0:adce77867281 195 }
spatel465 0:adce77867281 196
spatel465 0:adce77867281 197
spatel465 0:adce77867281 198
spatel465 0:adce77867281 199 unsigned short max_range = 0xFFFF;
spatel465 0:adce77867281 200 // function that calls above functions
spatel465 0:adce77867281 201 void patternSound(){
spatel465 0:adce77867281 202 //for(int i = 0; i < 60; i++){
spatel465 0:adce77867281 203 float sample;
spatel465 0:adce77867281 204 float average = 0.67/3.3;//initial DC bias level
spatel465 0:adce77867281 205
spatel465 0:adce77867281 206 int buffer[20];
spatel465 0:adce77867281 207
spatel465 0:adce77867281 208 while(1){
spatel465 0:adce77867281 209 if (src) {
spatel465 0:adce77867281 210 // this part works for DAC PCM output //
spatel465 0:adce77867281 211 float test = (float)waver.dac_data/max_range;
spatel465 0:adce77867281 212 pc.printf("--%f", abs((test - 0.5)/3.3));
spatel465 0:adce77867281 213 float2LED(test);
spatel465 0:adce77867281 214 strip.write();
spatel465 0:adce77867281 215 }
spatel465 0:adce77867281 216 //------------------------------------//
spatel465 0:adce77867281 217 else {
spatel465 0:adce77867281 218 //microphone setup //
spatel465 0:adce77867281 219 int centervalue;
spatel465 0:adce77867281 220 for(int i = 0; i < 20; i++){
spatel465 0:adce77867281 221 sample = mymicrophone;
spatel465 0:adce77867281 222 //subtract 0.67V DC bias - but it varies quite a bit after loud or long sounds
spatel465 0:adce77867281 223 average = 0.9999*average + 0.0001*sample;//try to slowly auto adjust the DC bias level
spatel465 0:adce77867281 224 speaker = 0.5 +((sample - average)*33.0);//scale up to 0.0 to 1.0 for speaker output
spatel465 0:adce77867281 225
spatel465 0:adce77867281 226 int micvalue = int(abs((sample - average)*300.0));
spatel465 0:adce77867281 227 //pc.printf("-%d-", micvalue); //scale to around 15 for LEDs
spatel465 0:adce77867281 228
spatel465 0:adce77867281 229 if(i == 1){
spatel465 0:adce77867281 230 centervalue = micvalue;
spatel465 0:adce77867281 231 }
spatel465 0:adce77867281 232 buffer[i] = micvalue;
spatel465 0:adce77867281 233 if(i > 10){
spatel465 0:adce77867281 234 if(micvalue == buffer[1] && micvalue == buffer[2] && micvalue == buffer[3] &&
spatel465 0:adce77867281 235 micvalue == buffer[4] && micvalue == buffer[5] && micvalue == buffer[6] &&
spatel465 0:adce77867281 236 micvalue == buffer[7] && micvalue == buffer[8] && micvalue == buffer[9]){
spatel465 0:adce77867281 237 centervalue = buffer[1];
spatel465 0:adce77867281 238 //pc.printf("-%d-", centervalue);
spatel465 0:adce77867281 239 }
spatel465 0:adce77867281 240 }
spatel465 0:adce77867281 241 int offset = micvalue-centervalue;
spatel465 0:adce77867281 242 //pc.printf(" %d ", offset);
spatel465 0:adce77867281 243 //myleds = micvalue;
spatel465 0:adce77867281 244 mic2LED(2+offset);
spatel465 0:adce77867281 245 wait(1.0/4000.0);
spatel465 0:adce77867281 246 }
spatel465 0:adce77867281 247 ////////////////////////////////////////////////////////
spatel465 0:adce77867281 248 strip.write();
spatel465 0:adce77867281 249 Thread::wait(10);
spatel465 0:adce77867281 250 }
spatel465 0:adce77867281 251 }
spatel465 0:adce77867281 252 }
spatel465 0:adce77867281 253
spatel465 0:adce77867281 254 void bt_thread() {
spatel465 0:adce77867281 255 char bnum = 0;
spatel465 0:adce77867281 256 char bhit = 0;
spatel465 0:adce77867281 257 while(1) {
spatel465 0:adce77867281 258 if (bt.readable()) {
spatel465 0:adce77867281 259 if (bt.getc()=='!') {
spatel465 0:adce77867281 260 if (bt.getc()=='B') { //button data
spatel465 0:adce77867281 261 bnum = bt.getc(); //button number
spatel465 0:adce77867281 262 bhit = bt.getc(); //1 = hit, 0 = release
spatel465 0:adce77867281 263 if (bhit == '1') {
spatel465 0:adce77867281 264 switch (bnum) {
spatel465 0:adce77867281 265 case '1': // Button 1 for play/pause
spatel465 0:adce77867281 266 if (waver.get_play_state() == 1) {
spatel465 0:adce77867281 267 waver.set_play_state(0);
makkoli98 4:6fbdec5bc602 268 thread2.terminate();
makkoli98 4:6fbdec5bc602 269 mute = 0;
spatel465 0:adce77867281 270 } else if (waver.get_play_state() == 0) {
spatel465 0:adce77867281 271 waver.set_play_state(1);
spatel465 0:adce77867281 272 thread2.start(sound_thread);
makkoli98 4:6fbdec5bc602 273 mute = 1;
spatel465 0:adce77867281 274 }
spatel465 0:adce77867281 275 break;
spatel465 0:adce77867281 276 case '2': // Button 2 for mute/unmute
spatel465 0:adce77867281 277 mute = !mute;
spatel465 0:adce77867281 278 break;
spatel465 0:adce77867281 279 case '3': // Button 3 to switch between mic/sd
spatel465 0:adce77867281 280 if (sd_mtx.trylock()) {
spatel465 0:adce77867281 281 sd_mtx.lock();
spatel465 0:adce77867281 282 src = src ? 0 : 1;
spatel465 0:adce77867281 283 if (src) {
makkoli98 5:b6f462ece58f 284 waver.set_play_state(1);
spatel465 0:adce77867281 285 thread2.start(sound_thread);
makkoli98 1:2e32808bfc2b 286 mute = 1;
spatel465 0:adce77867281 287 } else {
spatel465 0:adce77867281 288 waver.set_play_state(0);
spatel465 0:adce77867281 289 while (thread2.get_state() == Thread::Running) {
spatel465 0:adce77867281 290 Thread::yield();
spatel465 0:adce77867281 291 }
spatel465 0:adce77867281 292 thread2.terminate();
makkoli98 1:2e32808bfc2b 293 mute = 0;
spatel465 0:adce77867281 294 }
spatel465 0:adce77867281 295 sd_mtx.unlock();
spatel465 0:adce77867281 296 Thread::wait(100);
spatel465 0:adce77867281 297 }
spatel465 0:adce77867281 298 break;
spatel465 0:adce77867281 299 case '7': // Left arrow for previous
spatel465 0:adce77867281 300 if (sd_mtx.trylock()) {
spatel465 0:adce77867281 301 sd_mtx.lock();
spatel465 0:adce77867281 302 waver.set_play_state(0);
spatel465 0:adce77867281 303 if (cur_song > 0) {
spatel465 0:adce77867281 304 --cur_song;
spatel465 0:adce77867281 305 }
spatel465 0:adce77867281 306 while (thread2.get_state() == Thread::Running) {
spatel465 0:adce77867281 307 Thread::yield();
spatel465 0:adce77867281 308 }
spatel465 0:adce77867281 309 thread2.terminate();
spatel465 0:adce77867281 310 thread2.start(sound_thread);
spatel465 0:adce77867281 311 waver.set_play_state(1);
spatel465 0:adce77867281 312 sd_mtx.unlock();
spatel465 0:adce77867281 313 }
spatel465 0:adce77867281 314 break;
spatel465 0:adce77867281 315 case '8': // Right arrow for skip
spatel465 0:adce77867281 316 if (sd_mtx.trylock()) {
spatel465 0:adce77867281 317 sd_mtx.lock();
spatel465 0:adce77867281 318 waver.set_play_state(0);
spatel465 0:adce77867281 319 if (cur_song < filenames.size() - 1) {
spatel465 0:adce77867281 320 ++cur_song;
spatel465 0:adce77867281 321 }
spatel465 0:adce77867281 322 while (thread2.get_state() == Thread::Running) {
spatel465 0:adce77867281 323 Thread::yield();
spatel465 0:adce77867281 324 }
spatel465 0:adce77867281 325 thread2.terminate();
spatel465 0:adce77867281 326 thread2.start(sound_thread);
spatel465 0:adce77867281 327 waver.set_play_state(1);
spatel465 0:adce77867281 328 sd_mtx.unlock();
spatel465 0:adce77867281 329 }
spatel465 0:adce77867281 330 break;
spatel465 0:adce77867281 331 default:
spatel465 0:adce77867281 332 break;
spatel465 0:adce77867281 333 }
spatel465 0:adce77867281 334 }
spatel465 0:adce77867281 335 }
spatel465 0:adce77867281 336 }
spatel465 0:adce77867281 337 }
spatel465 0:adce77867281 338 Thread::wait(100);
spatel465 0:adce77867281 339 }
spatel465 0:adce77867281 340 }
spatel465 0:adce77867281 341
spatel465 0:adce77867281 342 int main() {
spatel465 0:adce77867281 343 read_file_names("/sd/songs");
spatel465 0:adce77867281 344
spatel465 0:adce77867281 345 strip.setBrightness(0.05);
spatel465 0:adce77867281 346
spatel465 0:adce77867281 347 mute = 1;
spatel465 0:adce77867281 348
spatel465 0:adce77867281 349 thread1.start(bt_thread);
spatel465 0:adce77867281 350 thread2.start(sound_thread);
spatel465 0:adce77867281 351 thread3.start(patternSound);
spatel465 0:adce77867281 352
spatel465 0:adce77867281 353 while(1){
spatel465 0:adce77867281 354 myled = !myled;
spatel465 0:adce77867281 355 Thread::wait(100);
spatel465 0:adce77867281 356 }
spatel465 0:adce77867281 357 }
spatel465 0:adce77867281 358