Eduardo Vitela / Mbed 2 deprecated RepWAV

Dependencies:   SDFileSystem mbed-src mbed

Fork of SDFileSystem_HelloWorld by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wavplayer.cpp Source File

wavplayer.cpp

00001 /*
00002  Library wave file player by Tom Coxon
00003 
00004  Based on WAVEplayer by Vlad Cazan/Stephan Rochon modified by Tom Coxon to:
00005 
00006  1. Run correctly on the Embedded Artists LPCXpresso baseboard.
00007  2. To play 8 bit sample size in addition to original 16 bit
00008  3. To be more fault tolerant when playing wav files.
00009 */
00010 
00011 #include "wavplayer.h"
00012 
00013 Ticker tick;
00014 Serial pc(USBTX,USBRX);
00015 DigitalIn p1(SW1);
00016 AnalogOut DACout(PTE30);
00017 
00018 void WavPlayer::dac_out() {
00019     if (DAC_on) {
00020         DACout.write_u16(DAC_fifo[DAC_rptr]);
00021         DAC_rptr=(DAC_rptr+1) & 0xff;
00022     }
00023 }
00024 
00025 void WavPlayer::play_wave(char *wavname) {
00026     unsigned chunk_id,chunk_size,channel;
00027     unsigned data,samp_int,i;
00028     short dac_data;
00029     char *slice_buf;
00030     short *data_sptr;
00031     FMT_STRUCT wav_format;
00032     FILE *wavfile;
00033     long slice,num_slices;
00034     DAC_wptr=0;
00035     DAC_rptr=0;
00036 
00037     size_t result;
00038 
00039     for (i=0;i<256;i+=2) {
00040         DAC_fifo[i]=0;
00041         DAC_fifo[i+1]=3000;
00042     }
00043     DAC_wptr=4;
00044     DAC_on=0;
00045 
00046     pc.printf("Reproduciendo arcivo '%s'\r\n",wavname);
00047 
00048     wavfile=fopen(wavname,"rb");
00049     if (!wavfile) {
00050         pc.printf("Incapas de abrir archivo '%s'\r\n",wavname);
00051         exit(1);
00052     }
00053 
00054     fread(&chunk_id,4,1,wavfile);
00055     fread(&chunk_size,4,1,wavfile);
00056     while (!feof(wavfile)) {
00057         pc.printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size);
00058         switch (chunk_id) {
00059             case 0x46464952:
00060                 fread(&data,4,1,wavfile);
00061                 pc.printf("RIFF chunk\r\n");
00062                 pc.printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
00063                 pc.printf("  RIFF type 0x%x\r\n",data);
00064                 break;
00065             case 0x20746d66:
00066                 fread(&wav_format,sizeof(wav_format),1,wavfile);
00067                 pc.printf("FORMAT chunk\r\n");
00068                 pc.printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
00069                 pc.printf("  compression code %d\r\n",wav_format.comp_code);
00070                 pc.printf("  %d channels\r\n",wav_format.num_channels);
00071                 pc.printf("  %d samples/sec\r\n",wav_format.sample_rate);
00072                 pc.printf("  %d bytes/sec\r\n",wav_format.avg_Bps);
00073                 pc.printf("  block align %d\r\n",wav_format.block_align);
00074                 pc.printf("  %d bits per sample\r\n",wav_format.sig_bps);
00075                 if (chunk_size > sizeof(wav_format))
00076                     fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
00077 // create a slice buffer large enough to hold multiple slices
00078                 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
00079                 if (!slice_buf) {
00080                     pc.printf("Unable to malloc slice buffer");
00081                     exit(1);
00082                 }
00083                 break;
00084             case 0x61746164:
00085                 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
00086                 if (!slice_buf) {
00087                     pc.printf("Unable to malloc slice buffer");
00088                     exit(1);
00089                 }
00090                 num_slices=chunk_size/wav_format.block_align;
00091                 pc.printf("DATA chunk\r\n");
00092                 pc.printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
00093                 pc.printf("  %d slices\r\n",num_slices);
00094                 pc.printf("  Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate));
00095                 samp_int=1000000/(wav_format.sample_rate);
00096                 pc.printf("  programmed interrupt tick interval=%d\r\n",samp_int);
00097 
00098 // starting up ticker to write samples out -- no printfs until tick.detach is called
00099                 tick.attach_us(this,&WavPlayer::dac_out, samp_int);
00100                 DAC_on=1;
00101                 for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
00102 
00103                     result = fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
00104                     if (feof(wavfile)) {
00105                         pc.printf("Oops -- not enough slices in the wave file\r\n");
00106 
00107                         break;
00108                     }
00109 
00110                     data_sptr=(short *)slice_buf;
00111                     for (i=0;i<SLICE_BUF_SIZE;i++) {
00112                         dac_data=0;
00113 
00114 // for a stereo wave file average the two channels.
00115                         for (channel=0;channel<wav_format.num_channels;channel++) {
00116                             switch (wav_format.sig_bps) {
00117                                 case 16:
00118                                     dac_data+=(  ((int)(*data_sptr++)) +32768 );
00119                                     break;
00120                                 case 8:
00121                                     dac_data+=(  ((int)(*data_sptr++)) +32768 <<8);
00122                                     break;
00123                             }
00124                         }
00125                         DAC_fifo[DAC_wptr]=dac_data;
00126                         DAC_wptr=(DAC_wptr+1) & 0xff;
00127                         while (DAC_wptr==DAC_rptr) {
00128                             wait_us(10);
00129                         }
00130                     }
00131                     if(p1==0){
00132                         break;    
00133                     }
00134                 }
00135                 DAC_on=0;
00136                 tick.detach();
00137                 pc.printf("Ticker detached\r\n");
00138                 free(slice_buf);
00139                 break;
00140             case 0x5453494c:
00141                 pc.printf("INFO chunk, size %d\r\n",chunk_size);
00142                 fseek(wavfile,chunk_size,SEEK_CUR);
00143                 break;
00144             default:
00145                 pc.printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size);
00146                 data=fseek(wavfile,chunk_size,SEEK_CUR);
00147                 break;
00148         }
00149         fread(&chunk_id,4,1,wavfile);
00150         fread(&chunk_size,4,1,wavfile);
00151     }
00152     pc.printf("++++++++++++ Fin de reproducion del archivo ++++++++++\r\n");
00153     fclose(wavfile);
00154 }
00155 
00156