Demo of Embedded Artists LPCXpresso baseboard SD card reader and audio facilities. Updated to put wav file player in a separate library and use the high capacity SD card library provided by Klaus Bu.

Dependencies:   mbed

Committer:
tom_coxon
Date:
Sun Jul 25 17:51:19 2010 +0000
Revision:
2:affcc36a50b4

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tom_coxon 2:affcc36a50b4 1 /*
tom_coxon 2:affcc36a50b4 2 Library wave file player by Tom Coxon
tom_coxon 2:affcc36a50b4 3
tom_coxon 2:affcc36a50b4 4 Based on WAVEplayer by Vlad Cazan/Stephan Rochon modified by Tom Coxon to:
tom_coxon 2:affcc36a50b4 5
tom_coxon 2:affcc36a50b4 6 1. Run correctly on the Embedded Artists LPCXpresso baseboard.
tom_coxon 2:affcc36a50b4 7 2. To play 8 bit sample size in addition to original 16 bit
tom_coxon 2:affcc36a50b4 8 3. To be more fault tolerant when playing wav files.
tom_coxon 2:affcc36a50b4 9 */
tom_coxon 2:affcc36a50b4 10
tom_coxon 2:affcc36a50b4 11 #include "wavplayer.h"
tom_coxon 2:affcc36a50b4 12
tom_coxon 2:affcc36a50b4 13 Ticker tick;
tom_coxon 2:affcc36a50b4 14
tom_coxon 2:affcc36a50b4 15 AnalogOut DACout(p18);
tom_coxon 2:affcc36a50b4 16
tom_coxon 2:affcc36a50b4 17 void WavPlayer::dac_out() {
tom_coxon 2:affcc36a50b4 18 if (DAC_on) {
tom_coxon 2:affcc36a50b4 19 DACout.write_u16(DAC_fifo[DAC_rptr]);
tom_coxon 2:affcc36a50b4 20 DAC_rptr=(DAC_rptr+1) & 0xff;
tom_coxon 2:affcc36a50b4 21 }
tom_coxon 2:affcc36a50b4 22 }
tom_coxon 2:affcc36a50b4 23
tom_coxon 2:affcc36a50b4 24 //void play_wave(char *wavname) {
tom_coxon 2:affcc36a50b4 25 void WavPlayer::play_wave(char *wavname) {
tom_coxon 2:affcc36a50b4 26 unsigned chunk_id,chunk_size,channel;
tom_coxon 2:affcc36a50b4 27 unsigned data,samp_int,i;
tom_coxon 2:affcc36a50b4 28 short dac_data;
tom_coxon 2:affcc36a50b4 29 char *slice_buf;
tom_coxon 2:affcc36a50b4 30 short *data_sptr;
tom_coxon 2:affcc36a50b4 31 FMT_STRUCT wav_format;
tom_coxon 2:affcc36a50b4 32 FILE *wavfile;
tom_coxon 2:affcc36a50b4 33 long slice,num_slices;
tom_coxon 2:affcc36a50b4 34 DAC_wptr=0;
tom_coxon 2:affcc36a50b4 35 DAC_rptr=0;
tom_coxon 2:affcc36a50b4 36
tom_coxon 2:affcc36a50b4 37 size_t result;
tom_coxon 2:affcc36a50b4 38
tom_coxon 2:affcc36a50b4 39 for (i=0;i<256;i+=2) {
tom_coxon 2:affcc36a50b4 40 DAC_fifo[i]=0;
tom_coxon 2:affcc36a50b4 41 DAC_fifo[i+1]=3000;
tom_coxon 2:affcc36a50b4 42 }
tom_coxon 2:affcc36a50b4 43 DAC_wptr=4;
tom_coxon 2:affcc36a50b4 44 DAC_on=0;
tom_coxon 2:affcc36a50b4 45
tom_coxon 2:affcc36a50b4 46 printf("Playing wave file '%s'\r\n",wavname);
tom_coxon 2:affcc36a50b4 47
tom_coxon 2:affcc36a50b4 48 wavfile=fopen(wavname,"rb");
tom_coxon 2:affcc36a50b4 49 if (!wavfile) {
tom_coxon 2:affcc36a50b4 50 printf("Unable to open wav file '%s'\r\n",wavname);
tom_coxon 2:affcc36a50b4 51 exit(1);
tom_coxon 2:affcc36a50b4 52 }
tom_coxon 2:affcc36a50b4 53
tom_coxon 2:affcc36a50b4 54 fread(&chunk_id,4,1,wavfile);
tom_coxon 2:affcc36a50b4 55 fread(&chunk_size,4,1,wavfile);
tom_coxon 2:affcc36a50b4 56 while (!feof(wavfile)) {
tom_coxon 2:affcc36a50b4 57 printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size);
tom_coxon 2:affcc36a50b4 58 switch (chunk_id) {
tom_coxon 2:affcc36a50b4 59 case 0x46464952:
tom_coxon 2:affcc36a50b4 60 fread(&data,4,1,wavfile);
tom_coxon 2:affcc36a50b4 61 printf("RIFF chunk\r\n");
tom_coxon 2:affcc36a50b4 62 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
tom_coxon 2:affcc36a50b4 63 printf(" RIFF type 0x%x\r\n",data);
tom_coxon 2:affcc36a50b4 64 break;
tom_coxon 2:affcc36a50b4 65 case 0x20746d66:
tom_coxon 2:affcc36a50b4 66 fread(&wav_format,sizeof(wav_format),1,wavfile);
tom_coxon 2:affcc36a50b4 67 printf("FORMAT chunk\r\n");
tom_coxon 2:affcc36a50b4 68 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
tom_coxon 2:affcc36a50b4 69 printf(" compression code %d\r\n",wav_format.comp_code);
tom_coxon 2:affcc36a50b4 70 printf(" %d channels\r\n",wav_format.num_channels);
tom_coxon 2:affcc36a50b4 71 printf(" %d samples/sec\r\n",wav_format.sample_rate);
tom_coxon 2:affcc36a50b4 72 printf(" %d bytes/sec\r\n",wav_format.avg_Bps);
tom_coxon 2:affcc36a50b4 73 printf(" block align %d\r\n",wav_format.block_align);
tom_coxon 2:affcc36a50b4 74 printf(" %d bits per sample\r\n",wav_format.sig_bps);
tom_coxon 2:affcc36a50b4 75 if (chunk_size > sizeof(wav_format))
tom_coxon 2:affcc36a50b4 76 fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
tom_coxon 2:affcc36a50b4 77 // create a slice buffer large enough to hold multiple slices
tom_coxon 2:affcc36a50b4 78 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
tom_coxon 2:affcc36a50b4 79 if (!slice_buf) {
tom_coxon 2:affcc36a50b4 80 printf("Unable to malloc slice buffer");
tom_coxon 2:affcc36a50b4 81 exit(1);
tom_coxon 2:affcc36a50b4 82 }
tom_coxon 2:affcc36a50b4 83 break;
tom_coxon 2:affcc36a50b4 84 case 0x61746164:
tom_coxon 2:affcc36a50b4 85 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
tom_coxon 2:affcc36a50b4 86 if (!slice_buf) {
tom_coxon 2:affcc36a50b4 87 printf("Unable to malloc slice buffer");
tom_coxon 2:affcc36a50b4 88 exit(1);
tom_coxon 2:affcc36a50b4 89 }
tom_coxon 2:affcc36a50b4 90 num_slices=chunk_size/wav_format.block_align;
tom_coxon 2:affcc36a50b4 91 printf("DATA chunk\r\n");
tom_coxon 2:affcc36a50b4 92 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
tom_coxon 2:affcc36a50b4 93 printf(" %d slices\r\n",num_slices);
tom_coxon 2:affcc36a50b4 94 printf(" Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate));
tom_coxon 2:affcc36a50b4 95 samp_int=1000000/(wav_format.sample_rate);
tom_coxon 2:affcc36a50b4 96 printf(" programmed interrupt tick interval=%d\r\n",samp_int);
tom_coxon 2:affcc36a50b4 97
tom_coxon 2:affcc36a50b4 98 // starting up ticker to write samples out -- no printfs until tick.detach is called
tom_coxon 2:affcc36a50b4 99 tick.attach_us(this,&WavPlayer::dac_out, samp_int);
tom_coxon 2:affcc36a50b4 100 DAC_on=1;
tom_coxon 2:affcc36a50b4 101 for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
tom_coxon 2:affcc36a50b4 102
tom_coxon 2:affcc36a50b4 103 result = fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
tom_coxon 2:affcc36a50b4 104 if (feof(wavfile)) {
tom_coxon 2:affcc36a50b4 105 printf("Oops -- not enough slices in the wave file\r\n");
tom_coxon 2:affcc36a50b4 106
tom_coxon 2:affcc36a50b4 107 break;
tom_coxon 2:affcc36a50b4 108 }
tom_coxon 2:affcc36a50b4 109
tom_coxon 2:affcc36a50b4 110 data_sptr=(short *)slice_buf;
tom_coxon 2:affcc36a50b4 111 for (i=0;i<SLICE_BUF_SIZE;i++) {
tom_coxon 2:affcc36a50b4 112 dac_data=0;
tom_coxon 2:affcc36a50b4 113
tom_coxon 2:affcc36a50b4 114 // for a stereo wave file average the two channels.
tom_coxon 2:affcc36a50b4 115 for (channel=0;channel<wav_format.num_channels;channel++) {
tom_coxon 2:affcc36a50b4 116 switch (wav_format.sig_bps) {
tom_coxon 2:affcc36a50b4 117 case 16:
tom_coxon 2:affcc36a50b4 118 dac_data+=( ((int)(*data_sptr++)) +32768 );
tom_coxon 2:affcc36a50b4 119 break;
tom_coxon 2:affcc36a50b4 120 case 8:
tom_coxon 2:affcc36a50b4 121 dac_data+=( ((int)(*data_sptr++)) +32768 <<8);
tom_coxon 2:affcc36a50b4 122 break;
tom_coxon 2:affcc36a50b4 123 }
tom_coxon 2:affcc36a50b4 124 }
tom_coxon 2:affcc36a50b4 125 DAC_fifo[DAC_wptr]=dac_data;
tom_coxon 2:affcc36a50b4 126 DAC_wptr=(DAC_wptr+1) & 0xff;
tom_coxon 2:affcc36a50b4 127 while (DAC_wptr==DAC_rptr) {
tom_coxon 2:affcc36a50b4 128 wait_us(10);
tom_coxon 2:affcc36a50b4 129 }
tom_coxon 2:affcc36a50b4 130 }
tom_coxon 2:affcc36a50b4 131 }
tom_coxon 2:affcc36a50b4 132 DAC_on=0;
tom_coxon 2:affcc36a50b4 133 tick.detach();
tom_coxon 2:affcc36a50b4 134 printf("Ticker detached\r\n");
tom_coxon 2:affcc36a50b4 135 free(slice_buf);
tom_coxon 2:affcc36a50b4 136 break;
tom_coxon 2:affcc36a50b4 137 case 0x5453494c:
tom_coxon 2:affcc36a50b4 138 printf("INFO chunk, size %d\r\n",chunk_size);
tom_coxon 2:affcc36a50b4 139 fseek(wavfile,chunk_size,SEEK_CUR);
tom_coxon 2:affcc36a50b4 140 break;
tom_coxon 2:affcc36a50b4 141 default:
tom_coxon 2:affcc36a50b4 142 printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size);
tom_coxon 2:affcc36a50b4 143 data=fseek(wavfile,chunk_size,SEEK_CUR);
tom_coxon 2:affcc36a50b4 144 break;
tom_coxon 2:affcc36a50b4 145 }
tom_coxon 2:affcc36a50b4 146 fread(&chunk_id,4,1,wavfile);
tom_coxon 2:affcc36a50b4 147 fread(&chunk_size,4,1,wavfile);
tom_coxon 2:affcc36a50b4 148 }
tom_coxon 2:affcc36a50b4 149 printf("++++++++++++ Done with wave file ++++++++++\r\n");
tom_coxon 2:affcc36a50b4 150 fclose(wavfile);
tom_coxon 2:affcc36a50b4 151 }
tom_coxon 2:affcc36a50b4 152
tom_coxon 2:affcc36a50b4 153