EA BaseBoard, playing wav, PC see\'s SD-card through USB port.

Dependencies:   mbed

Committer:
Lerche
Date:
Tue Nov 22 05:45:58 2011 +0000
Revision:
0:fef366d2ed20
Thanks to those who provided EA_WavPlayer and USB_MSC

Who changed what in which revision?

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