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

Files at this revision

API Documentation at this revision

Comitter:
tom_coxon
Date:
Sat Jul 03 10:07:07 2010 +0000
Child:
1:22c43c468a2f
Commit message:

Changed in this revision

FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FATFileSystem.lib	Sat Jul 03 10:07:07 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_unsupported/code/fatfilesystem/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Sat Jul 03 10:07:07 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/SDFileSystem/#b1ddfc9a9b25
--- /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;
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Jul 03 10:07:07 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/3944f1e2fa4f