Test of Embedded Artists LPCXpresso baseboard ethernet, SD card, audio and OLED display facilities. The program displays the day, date and time on the baseboard OLED and sounds the Big Ben chimes on the hour and quarter hour. On initial startup the program checks that the mbed clock is set and that the chime wav files can be accessed on the SD card. If not it asks to be connected to the internet to obtain the current time and to download the wav files to the SD card.

Dependencies:   EthernetNetIf NTPClient_NetServices mbed EAOLED

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 
00015 AnalogOut DACout(p18);
00016 
00017 void WavPlayer::dac_out() {
00018     if (DAC_on) {
00019         DACout.write_u16(DAC_fifo[DAC_rptr]);
00020         DAC_rptr=(DAC_rptr+1) & 0xff;
00021     }
00022 }
00023 
00024 //void play_wave(char *wavname) {
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     printf("Playing wave file '%s'\r\n",wavname);
00047 
00048     wavfile=fopen(wavname,"rb");
00049     if (!wavfile) {
00050         printf("Unable to open wav file '%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         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                 printf("RIFF chunk\r\n");
00062                 printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
00063                 printf("  RIFF type 0x%x\r\n",data);
00064                 break;
00065             case 0x20746d66:
00066                 fread(&wav_format,sizeof(wav_format),1,wavfile);
00067                 printf("FORMAT chunk\r\n");
00068                 printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
00069                 printf("  compression code %d\r\n",wav_format.comp_code);
00070                 printf("  %d channels\r\n",wav_format.num_channels);
00071                 printf("  %d samples/sec\r\n",wav_format.sample_rate);
00072                 printf("  %d bytes/sec\r\n",wav_format.avg_Bps);
00073                 printf("  block align %d\r\n",wav_format.block_align);
00074                 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                     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                     printf("Unable to malloc slice buffer");
00088                     exit(1);
00089                 }
00090                 num_slices=chunk_size/wav_format.block_align;
00091                 printf("DATA chunk\r\n");
00092                 printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
00093                 printf("  %d slices\r\n",num_slices);
00094                 printf("  Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate));
00095                 samp_int=1000000/(wav_format.sample_rate);
00096                 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                         printf("Oops -- not enough slices in the wave file\r\n");
00106                         if (result) ;//just to stop compiler complaining that we have not used result
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                 }
00132                 DAC_on=0;
00133                 tick.detach();
00134                 printf("Ticker detached\r\n");
00135                 free(slice_buf);
00136                 break;
00137             case 0x5453494c:
00138                 printf("INFO chunk, size %d\r\n",chunk_size);
00139                 fseek(wavfile,chunk_size,SEEK_CUR);
00140                 break;
00141             default:
00142                 printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size);
00143                 data=fseek(wavfile,chunk_size,SEEK_CUR);
00144                 break;
00145         }
00146         fread(&chunk_id,4,1,wavfile);
00147         fread(&chunk_size,4,1,wavfile);
00148     }
00149     printf("++++++++++++ Done with wave file ++++++++++\r\n");
00150     fclose(wavfile);
00151 }
00152