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

Revision:
0:1f4b7aa80ab3
Child:
1:22c43c468a2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Jul 03 10:07:07 2010 +0000
@@ -0,0 +1,245 @@
+/*
+ Demo of Embedded Artists LPCXpresso baseboard SD card
+ reader and audio facilities.
+
+ 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.
+ 
+ Place suitable 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;
+    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) {
+                    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");
+                        exit(1);
+                    }
+                    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;
+    }
+}
+
+