music main

Dependencies:   USBHost mbed

Fork of AppBoard_Waveplayer by jim hamblen

Files at this revision

API Documentation at this revision

Comitter:
niv17
Date:
Tue Apr 14 03:46:33 2015 +0000
Parent:
10:6eefc37bfa23
Commit message:
Version that needs to be fixed

Changed in this revision

CircularBuffer.h Show annotated file Show diff for this revision Revisions of this file
MMA7660.lib Show diff for this revision Revisions of this file
WaveFileReader.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
wave_player_appbd.lib Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CircularBuffer.h	Tue Apr 14 03:46:33 2015 +0000
@@ -0,0 +1,107 @@
+
+#ifndef _CircularBuffer_h
+#define _CircularBuffer_h
+
+#define INITIAL 3000
+
+template <class T>
+class CircularBuffer{
+    /* If wptr == rptr, it is empty */
+    /* Remember: capacity-1 is all you can store */
+private:
+    size_t rptr,wptr,capacity;
+    T *data;
+    
+public:
+    CircularBuffer(size_t cap){
+        rptr = 0;
+        wptr = cap-1;
+        //printf("\r\n%u  %u",rptr,wptr);
+        //fflush(stdout);
+        capacity = cap;
+        data = new T[cap];
+        clear();
+    }
+    
+    ~CircularBuffer(){
+        delete[] data;
+    }
+    
+    size_t writeSizeRemaining();
+    void write(T *dataPtr, size_t samples);
+    size_t readSizeRemaining();
+    void read(T *dataPtr, size_t samples);
+    T readOneSample();
+    void clear();
+    
+};
+
+template <class T>
+size_t CircularBuffer<T>::writeSizeRemaining() {
+    return capacity-readSizeRemaining()-1;
+}
+
+template <class T>
+void CircularBuffer<T>::write(T *dataPtr, size_t samples) 
+{
+    /* Assumes enough space is avilable in data */    
+    //Condition 1 if wptr+samples<capacity
+    //Condition 2 else two for loops
+    
+    size_t sizeRemaining = capacity - wptr;
+    if(sizeRemaining <= samples){
+        size_t i=0;
+        for(; wptr<capacity; i++) 
+            data[wptr++] = dataPtr[i];
+        for(wptr = 0; i < samples; i++)
+            data[wptr++] = dataPtr[i];
+            
+    } else {
+        for(size_t i=0; i<samples; i++)
+            data[wptr++] = dataPtr[i];
+    } 
+}
+
+template <class T>
+size_t CircularBuffer<T>::readSizeRemaining(){ 
+    return (wptr >= rptr) ? wptr - rptr : (capacity-rptr+wptr);
+}
+
+template <class T>
+void CircularBuffer<T>::read(T *buf, size_t samples) 
+{
+    /* Assumes enough space is avilable in data */
+    
+    //Condition 1 if wptr+samples<capacity
+    //Condition 2 else two for loops
+
+    size_t sizeRemaining = capacity - rptr;
+    if(sizeRemaining <= samples){
+        size_t i=0;
+        for(; rptr < capacity; rptr++) {
+           buf[i++] = data[rptr];
+         }
+        for(rptr = 0; i<samples; i++)
+           buf[i] = data[rptr++];
+    } else {
+        for(size_t i=0; i < samples ; i++)
+           buf[i] = data[rptr++];
+    }
+}
+
+template <class T>
+T CircularBuffer<T>::readOneSample() {
+    return data[rptr++];  
+}
+
+template <class T>
+void CircularBuffer<T>::clear() {
+    wptr = capacity-1;
+    rptr = 0;
+    for(size_t i = 0; i-1<capacity; i=i+2){
+        data[i] = INITIAL;
+        data[i+1] = 0;
+    }
+}
+
+#endif
--- a/MMA7660.lib	Thu Apr 09 20:24:22 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/Sissors/code/MMA7660/#36a163511e34
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WaveFileReader.h	Tue Apr 14 03:46:33 2015 +0000
@@ -0,0 +1,132 @@
+/* Read the wavefile */
+
+typedef struct uFMT_STRUCT {
+  short comp_code;
+  short num_channels;
+  unsigned sample_rate;
+  unsigned avg_Bps;
+  short block_align;
+  short sig_bps;
+} FMT_STRUCT;
+
+class WaveFileReader {
+
+private:
+    FILE * wavefile;
+    bool isRepeat;
+    unsigned dataChunkSize;
+    long int startofdata;
+    void readHeader();
+    FMT_STRUCT wav_format;
+
+public:
+    WaveFileReader( FILE *, bool);
+    float readSamplePeriod();
+    size_t read(unsigned short *buf, size_t size);
+};
+
+WaveFileReader::WaveFileReader(FILE *wavefile, bool isRepeat){
+    this->wavefile = wavefile;
+    this->isRepeat = isRepeat;
+    readHeader();
+}
+
+float WaveFileReader::readSamplePeriod(){
+    return 1000000/(wav_format.sample_rate);
+}
+
+void WaveFileReader::readHeader(){
+    unsigned chunk_id, data, chunk_size;
+    fread(&chunk_id,4,1,wavefile);
+    fread(&chunk_size,4,1,wavefile);
+    
+    while (!feof(wavefile)){
+        switch (chunk_id) {
+            case 0x46464952:
+                fread(&data,4,1,wavefile);
+                break;
+            case 0x20746d66:
+                fread(&wav_format,sizeof(wav_format),1,wavefile); 
+                if (chunk_size > sizeof(wav_format))
+                    fseek(wavefile,chunk_size-sizeof(wav_format),SEEK_CUR);
+                break;
+            case 0x5453494c:
+                fseek(wavefile,chunk_size,SEEK_CUR);
+                break;
+            case 0x61746164:
+              startofdata = ftell(wavefile);
+              dataChunkSize = chunk_size;
+              fseek(wavefile,chunk_size,SEEK_CUR);
+              break;
+          default:
+            data=fseek(wavefile,chunk_size,SEEK_CUR);
+            break;
+        }
+        fread(&chunk_id,4,1,wavefile);
+        fread(&chunk_size,4,1,wavefile);
+    }
+    fseek(wavefile,startofdata,SEEK_SET);
+}
+
+size_t WaveFileReader::read(unsigned short *DAC_fifo, size_t size){
+    unsigned channel;
+    short unsigned dac_data;
+    long long slice_value;
+    char *slice_buf;
+    short *data_sptr;
+    unsigned char *data_bptr;
+    int *data_wptr;
+    
+    slice_buf=(char *)malloc(wav_format.block_align);
+    if (!slice_buf) {
+      printf("Unable to malloc slice buffer");
+      exit(1);
+    }
+
+    for (size_t i=0; i<size; i++){
+        fread(slice_buf,wav_format.block_align,1,wavefile);
+        if (feof(wavefile)) {
+            if(isRepeat){
+                fseek(wavefile,startofdata,SEEK_SET);
+                printf("Reached end of file, reapeat is on");
+            }else{  
+                printf("Reached end of file, reapeat is off");
+                return i;
+            }
+        }
+        data_sptr=(short *)slice_buf;     // 16 bit samples
+        data_bptr=(unsigned char *)slice_buf;     // 8 bit samples
+        data_wptr=(int *)slice_buf;     // 32 bit samples
+        slice_value=0;
+        for (channel=0;channel<wav_format.num_channels;channel++) {
+            switch (wav_format.sig_bps) {
+                case 16:
+                    slice_value+=data_sptr[channel];
+                    break;
+                case 32:
+                    slice_value+=data_wptr[channel];
+                    break;
+                case 8:
+                  slice_value+=data_bptr[channel];
+                  break;
+            }
+        }
+        slice_value/=wav_format.num_channels;
+        switch (wav_format.sig_bps) {
+            case 8:     
+                slice_value<<=8;
+                break;
+            case 16:
+                slice_value+=32768;
+                break;
+            case 32: 
+                slice_value>>=16;
+                slice_value+=32768;
+                break;
+        }
+        dac_data=(short unsigned)slice_value;
+        DAC_fifo[i]=dac_data;
+    }
+    free(slice_buf);
+    return size;
+}
\ No newline at end of file
--- a/main.cpp	Thu Apr 09 20:24:22 2015 +0000
+++ b/main.cpp	Tue Apr 14 03:46:33 2015 +0000
@@ -1,84 +1,65 @@
-#include "mbed.h"
-#include "USBHostMSD.h"
-#include "wave_player.h"
-#include "MMA7660.h"
-#include "rtos.h"
-
-//mbed Application board waveplayer demo
-//Plays the wave file "sample.wav" on the USB flash drive
-//Outputs to onboard speaker (but at very low volume)
-//and the Audio Out jack for connection to a set of amplified PC speakers (at higher volume)
-//Needs a USB flash drive inserted with the wav file on it to run
-
-//Analog Out Jack
-AnalogOut DACout(p18);
-//On Board Speaker
-PwmOut PWMout(p26);
-int music = 0;
-void readbuf();
-Serial pc(USBTX,USBRX);
-MMA7660 MMA(p28, p27);
-AnalogIn sound(p17);
-PwmOut r (p23);
-PwmOut g (p24);
-PwmOut b (p25);
- FILE *wave_file;
- void readbuf(void const *args);
- unsigned short * waveArray;
- DigitalIn fire(p14);
- void changemusic(void const *args);
- void changecolor(void const *args);
- int randomval = 0;
- int start = 0;
- Ticker fillbuf;
-unsigned short * buf;
- wave_player waver(&DACout,&PWMout, &waveArray[0]);
-int main()
-{
-    USBHostMSD msd("usb");
-   // for(int i = 0; i<256; i++)
-//        { 
-//       waveArray[i] = 0;
-//        }
-    
-    r.period(0.001);
-    //setup PWM hardware for a Class D style audio output
-    PWMout.period(1.0/400000.0);
-    printf("\r\n\nHello, wave world!\n");
-    // wait until connected to a USB device
-    while(!msd.connect()) {
-        Thread::wait(500);
-    }
-    //open wav file and play it
-
-     
-      pc.printf("\r\nenter wavefile\n\n"); 
-      wave_file =  fopen("/usb/sample.wav","r");
-      
-     // waver.set_verbosity(1);
-    Thread thread(readbuf);
-      waver.play(wave_file);
-      
-    fclose(wave_file);
-       
-       pc.printf("\r\n END OF FILE\n");
-        pc.printf("\r\n\n BUFFER:::\n");
-       
-         
-    
-   while(1);
-   
-}
-void readbuf(void const * args){
-   
-    while(1){
-         wait_ms(11.0);
-   
-    waver.getFIFO(buf);
-    
-    //for(int i = 0; i<256; i++) {
-//       printf("%hu\r\n",buf[i]); 
-//       }
-   }
-    
-}
+#include "mbed.h"
+#include "WaveFileReader.h"
+#include "USBHostMSD.h"
+#include "CircularBuffer.h"
+
+#define MAXSIZE 4096
+#define EXTRASIZE 0
+
+Serial pc(USBTX,USBRX);
+
+unsigned short buffer[MAXSIZE];
+AnalogOut DACout(p18);
+Ticker ticker;
+//CircularBuffer<unsigned short> circularBuffer(MAXSIZE+EXTRASIZE);  
+
+void writeAnalog(){
+    static int i=0;
+    if(i>=1024)i = 0;
+    //DACout.write_u16(circularBuffer.readOneSample());
+    DACout.write_u16(buffer[i]);
+    i++;
+    
+}
+
+int main() {
+         
+    pc.printf("\r\n Detecting USB...");
+    fflush(stdout);
+    
+    USBHostMSD msd("usb");
+    while(!msd.connect()) {
+        Thread::wait(500);
+        pc.printf("\r\nwaiting..");
+    }
+    pc.printf("\r\n USD Detected");
+    fflush(stdout);
+     
+    FILE *file;
+    file = fopen("/usb/sample.wav","r");
+    WaveFileReader waveReader(file,false);
+    pc.printf("\r\n File opened");
+    fflush(stdout);
+    
+    float samplePeriod = waveReader.readSamplePeriod();
+    waveReader.read(buffer,MAXSIZE);   
+    ticker.attach_us(&writeAnalog,samplePeriod);
+    //pc.printf("\r\n Ticker attached");
+    
+ //   while(1){
+//        while(circularBuffer.writeSizeRemaining() < MAXSIZE){}
+//        //pc.printf("\r\n Reading next MAXSIZE");
+//        //fflush(stdout);
+//        int length = waveReader.read(buffer,MAXSIZE);  
+//        if(length<MAXSIZE){
+//            circularBuffer.write(buffer,MAXSIZE); 
+//            break;
+//        }
+//        //Mixer.mix(buf);
+//        circularBuffer.write(buffer,MAXSIZE); 
+//    }
+    fclose(file);
+    while(1) {
+         
+    }
+}
\ No newline at end of file
--- a/wave_player_appbd.lib	Thu Apr 09 20:24:22 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://developer.mbed.org/users/niv17/code/wave_player_appbd/#b10ea1b38f08