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.
main.cpp
- Committer:
- tom_coxon
- Date:
- 2010-07-09
- Revision:
- 1:22c43c468a2f
- Parent:
- 0:1f4b7aa80ab3
- Child:
- 2:affcc36a50b4
File content as of revision 1:22c43c468a2f:
/* Demo of Embedded Artists LPCXpresso baseboard SD card reader and audio facilities. Based on WAVEplayer by Vlad Cazan/Stephan Rochon modified by Tom Coxon to run correctly on the Embedded Artists LPCXpresso baseboard. Also modified to play 8 bit sample size in addition to original 16 bit and to be more fault tolerant when playing wav files. Place suitable uncompressed wav files with 8 or 16 bit sample sizes on the SD card and ensure the file names are 8.3 format. Then change the main method below to the relevant file paths. Please set all jumpers on board to the default case except for the following: Audio setup: 1. Insert a jumper in J31 to connect signal PIO1_2 to the low pass filer as described in section 4.7.2. of base board users guide. 2. Insert three jumpers in J33 to connect PIO3_0, PIO3_1 and PIO3_2 to control the amplifier as described in section 4.8 of base board users guide. 3. Insert a jumper in J32 and remove any from J34 to use the internal speaker as described in section 4.8 of base board users guide. SD Card setup: 4. Insert all five jumpers in J39 as described in section 4.3.3 of base board users guide. 5. Remove jumper marked "A" in J55 In order to connect PIO1_11 to CS signal of J40 (the SPI-SSEL signal) as described in section 4.3.3 of base board users guide. */ #include "mbed.h" #include "SDFileSystem.h" AnalogOut DACout(p18); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); Ticker tick; SDFileSystem sd(p5, p6, p7, p24, "sd"); #define SAMPLE_FREQ 40000 #define BUF_SIZE (SAMPLE_FREQ/10) #define SLICE_BUF_SIZE 1 void dac_out(void); void play_wave(char *); void cleanup(char *); void fill_adc_buf(short *, unsigned); void swapword(unsigned *); // a FIFO for the DAC short DAC_fifo[256]; short DAC_wptr; short DAC_rptr; short DAC_on; typedef struct uFMT_STRUCT { short comp_code; short num_channels; unsigned sample_rate; unsigned avg_Bps; short block_align; short sig_bps; } FMT_STRUCT; int main() { led1=0; wait(.5); led1=1; wait(.5); led1=0; printf("\r\n--------------- Starting -----------------\r\n"); play_wave("/sd/startup.wav"); // 8 bit sample size play_wave("/sd/baddonut.wav"); // 16 bit sample size play_wave("/sd/dduck.wav"); // 8 bit sample size play_wave("/sd/bbunny.wav"); // 8 bit sample size play_wave("/sd/clint16.wav"); // 16 bit sample size printf("<<<<<<<<<<<<<<<< All done >>>>>>>>>>>>>>>>\r\n"); led1=1; wait(.5); led1=0; wait(.5); led1=1; } void play_wave(char *wavname) { unsigned chunk_id,chunk_size,channel; unsigned data,samp_int,i; short dac_data; char *slice_buf; short *data_sptr; FMT_STRUCT wav_format; FILE *wavfile; long slice,num_slices; DAC_wptr=0; DAC_rptr=0; size_t result; for (i=0;i<256;i+=2) { DAC_fifo[i]=0; DAC_fifo[i+1]=3000; } DAC_wptr=4; DAC_on=0; led1=led2=led3=led4=0; printf("Playing wave file '%s'\r\n",wavname); wavfile=fopen(wavname,"rb"); if (!wavfile) { printf("Unable to open wav file '%s'\r\n",wavname); exit(1); } fread(&chunk_id,4,1,wavfile); fread(&chunk_size,4,1,wavfile); while (!feof(wavfile)) { printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size); switch (chunk_id) { case 0x46464952: fread(&data,4,1,wavfile); printf("RIFF chunk\r\n"); printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); printf(" RIFF type 0x%x\r\n",data); break; case 0x20746d66: fread(&wav_format,sizeof(wav_format),1,wavfile); printf("FORMAT chunk\r\n"); printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); printf(" compression code %d\r\n",wav_format.comp_code); printf(" %d channels\r\n",wav_format.num_channels); printf(" %d samples/sec\r\n",wav_format.sample_rate); printf(" %d bytes/sec\r\n",wav_format.avg_Bps); printf(" block align %d\r\n",wav_format.block_align); printf(" %d bits per sample\r\n",wav_format.sig_bps); if (chunk_size > sizeof(wav_format)) fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR); // create a slice buffer large enough to hold multiple slices slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE); if (!slice_buf) { printf("Unable to malloc slice buffer"); exit(1); } break; case 0x61746164: slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE); if (!slice_buf) { printf("Unable to malloc slice buffer"); exit(1); } num_slices=chunk_size/wav_format.block_align; printf("DATA chunk\r\n"); printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size); printf(" %d slices\r\n",num_slices); printf(" Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate)); samp_int=1000000/(wav_format.sample_rate); printf(" programmed interrupt tick interval=%d\r\n",samp_int); // starting up ticker to write samples out -- no printfs until tick.detach is called tick.attach_us(&dac_out, samp_int); DAC_on=1; led2=1; for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) { result = fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile); if (feof(wavfile)) { printf("Oops -- not enough slices in the wave file\r\n"); break; } data_sptr=(short *)slice_buf; for (i=0;i<SLICE_BUF_SIZE;i++) { dac_data=0; // for a stereo wave file average the two channels. for (channel=0;channel<wav_format.num_channels;channel++) { switch (wav_format.sig_bps) { case 16: dac_data+=( ((int)(*data_sptr++)) +32768 ); break; case 8: dac_data+=( ((int)(*data_sptr++)) +32768 <<8); break; } } DAC_fifo[DAC_wptr]=dac_data; DAC_wptr=(DAC_wptr+1) & 0xff; while (DAC_wptr==DAC_rptr) { led1=1; wait_us(10); } led1=0; } } DAC_on=0; led2=0; tick.detach(); printf("Ticker detached\r\n"); led3=1; free(slice_buf); break; case 0x5453494c: printf("INFO chunk, size %d\r\n",chunk_size); fseek(wavfile,chunk_size,SEEK_CUR); break; default: printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size); data=fseek(wavfile,chunk_size,SEEK_CUR); break; } fread(&chunk_id,4,1,wavfile); fread(&chunk_size,4,1,wavfile); } printf("++++++++++++ Done with wave file ++++++++++\r\n"); fclose(wavfile); led1=0; } void dac_out() { if (DAC_on) { led4=1; DACout.write_u16(DAC_fifo[DAC_rptr]); DAC_rptr=(DAC_rptr+1) & 0xff; led4=0; } }