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:
Sat Jul 03 10:07:07 2010 +0000
Revision:
0:1f4b7aa80ab3
Child:
1:22c43c468a2f

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tom_coxon 0:1f4b7aa80ab3 1 /*
tom_coxon 0:1f4b7aa80ab3 2 Demo of Embedded Artists LPCXpresso baseboard SD card
tom_coxon 0:1f4b7aa80ab3 3 reader and audio facilities.
tom_coxon 0:1f4b7aa80ab3 4
tom_coxon 0:1f4b7aa80ab3 5 WAVEplayer by Vlad Cazan/Stephan Rochon modified by Tom Coxon
tom_coxon 0:1f4b7aa80ab3 6 to run correctly on the Embedded Artists LPCXpresso baseboard.
tom_coxon 0:1f4b7aa80ab3 7
tom_coxon 0:1f4b7aa80ab3 8 Also modified to play 8 bit sample size in addition to
tom_coxon 0:1f4b7aa80ab3 9 original 16 bit.
tom_coxon 0:1f4b7aa80ab3 10
tom_coxon 0:1f4b7aa80ab3 11 Place suitable wav files with 8 or 16 bit sample sizes on the
tom_coxon 0:1f4b7aa80ab3 12 SD card and ensure the file names are 8.3 format. Then change
tom_coxon 0:1f4b7aa80ab3 13 the main method below to the relevant file paths.
tom_coxon 0:1f4b7aa80ab3 14
tom_coxon 0:1f4b7aa80ab3 15 Please set all jumpers on board to the default case except for
tom_coxon 0:1f4b7aa80ab3 16 the following:
tom_coxon 0:1f4b7aa80ab3 17
tom_coxon 0:1f4b7aa80ab3 18 Audio setup:
tom_coxon 0:1f4b7aa80ab3 19
tom_coxon 0:1f4b7aa80ab3 20 1. Insert a jumper in J31 to connect signal PIO1_2 to the low
tom_coxon 0:1f4b7aa80ab3 21 pass filer as described in section 4.7.2. of base board users
tom_coxon 0:1f4b7aa80ab3 22 guide.
tom_coxon 0:1f4b7aa80ab3 23
tom_coxon 0:1f4b7aa80ab3 24 2. Insert three jumpers in J33 to connect PIO3_0, PIO3_1 and
tom_coxon 0:1f4b7aa80ab3 25 PIO3_2 to control the amplifier as described in section 4.8
tom_coxon 0:1f4b7aa80ab3 26 of base board users guide.
tom_coxon 0:1f4b7aa80ab3 27
tom_coxon 0:1f4b7aa80ab3 28 3. Insert a jumper in J32 and remove any from J34 to use the
tom_coxon 0:1f4b7aa80ab3 29 internal speaker as described in section 4.8
tom_coxon 0:1f4b7aa80ab3 30 of base board users guide.
tom_coxon 0:1f4b7aa80ab3 31
tom_coxon 0:1f4b7aa80ab3 32 SD Card setup:
tom_coxon 0:1f4b7aa80ab3 33
tom_coxon 0:1f4b7aa80ab3 34 4. Insert all five jumpers in J39 as described in section 4.3.3
tom_coxon 0:1f4b7aa80ab3 35 of base board users guide.
tom_coxon 0:1f4b7aa80ab3 36
tom_coxon 0:1f4b7aa80ab3 37 5. Remove jumper marked "A" in J55 In order to connect PIO1_11
tom_coxon 0:1f4b7aa80ab3 38 to CS signal of J40 (the SPI-SSEL signal) as described in section 4.3.3
tom_coxon 0:1f4b7aa80ab3 39 of base board users guide.
tom_coxon 0:1f4b7aa80ab3 40 */
tom_coxon 0:1f4b7aa80ab3 41
tom_coxon 0:1f4b7aa80ab3 42 #include "mbed.h"
tom_coxon 0:1f4b7aa80ab3 43 #include "SDFileSystem.h"
tom_coxon 0:1f4b7aa80ab3 44
tom_coxon 0:1f4b7aa80ab3 45 AnalogOut DACout(p18);
tom_coxon 0:1f4b7aa80ab3 46 DigitalOut led1(LED1);
tom_coxon 0:1f4b7aa80ab3 47 DigitalOut led2(LED2);
tom_coxon 0:1f4b7aa80ab3 48 DigitalOut led3(LED3);
tom_coxon 0:1f4b7aa80ab3 49 DigitalOut led4(LED4);
tom_coxon 0:1f4b7aa80ab3 50 Ticker tick;
tom_coxon 0:1f4b7aa80ab3 51 SDFileSystem sd(p5, p6, p7, p24, "sd");
tom_coxon 0:1f4b7aa80ab3 52
tom_coxon 0:1f4b7aa80ab3 53 #define SAMPLE_FREQ 40000
tom_coxon 0:1f4b7aa80ab3 54 #define BUF_SIZE (SAMPLE_FREQ/10)
tom_coxon 0:1f4b7aa80ab3 55 #define SLICE_BUF_SIZE 1
tom_coxon 0:1f4b7aa80ab3 56
tom_coxon 0:1f4b7aa80ab3 57 void dac_out(void);
tom_coxon 0:1f4b7aa80ab3 58 void play_wave(char *);
tom_coxon 0:1f4b7aa80ab3 59 void cleanup(char *);
tom_coxon 0:1f4b7aa80ab3 60 void fill_adc_buf(short *, unsigned);
tom_coxon 0:1f4b7aa80ab3 61 void swapword(unsigned *);
tom_coxon 0:1f4b7aa80ab3 62
tom_coxon 0:1f4b7aa80ab3 63 // a FIFO for the DAC
tom_coxon 0:1f4b7aa80ab3 64 short DAC_fifo[256];
tom_coxon 0:1f4b7aa80ab3 65 short DAC_wptr;
tom_coxon 0:1f4b7aa80ab3 66 short DAC_rptr;
tom_coxon 0:1f4b7aa80ab3 67 short DAC_on;
tom_coxon 0:1f4b7aa80ab3 68
tom_coxon 0:1f4b7aa80ab3 69 typedef struct uFMT_STRUCT {
tom_coxon 0:1f4b7aa80ab3 70 short comp_code;
tom_coxon 0:1f4b7aa80ab3 71 short num_channels;
tom_coxon 0:1f4b7aa80ab3 72 unsigned sample_rate;
tom_coxon 0:1f4b7aa80ab3 73 unsigned avg_Bps;
tom_coxon 0:1f4b7aa80ab3 74 short block_align;
tom_coxon 0:1f4b7aa80ab3 75 short sig_bps;
tom_coxon 0:1f4b7aa80ab3 76 } FMT_STRUCT;
tom_coxon 0:1f4b7aa80ab3 77
tom_coxon 0:1f4b7aa80ab3 78
tom_coxon 0:1f4b7aa80ab3 79 int main() {
tom_coxon 0:1f4b7aa80ab3 80 led1=0;
tom_coxon 0:1f4b7aa80ab3 81 wait(.5);
tom_coxon 0:1f4b7aa80ab3 82 led1=1;
tom_coxon 0:1f4b7aa80ab3 83 wait(.5);
tom_coxon 0:1f4b7aa80ab3 84 led1=0;
tom_coxon 0:1f4b7aa80ab3 85 printf("\r\n--------------- Starting -----------------\r\n");
tom_coxon 0:1f4b7aa80ab3 86
tom_coxon 0:1f4b7aa80ab3 87 play_wave("/sd/startup.wav"); // 8 bit sample size
tom_coxon 0:1f4b7aa80ab3 88
tom_coxon 0:1f4b7aa80ab3 89 play_wave("/sd/baddonut.wav"); // 16 bit sample size
tom_coxon 0:1f4b7aa80ab3 90
tom_coxon 0:1f4b7aa80ab3 91 play_wave("/sd/dduck.wav"); // 8 bit sample size
tom_coxon 0:1f4b7aa80ab3 92
tom_coxon 0:1f4b7aa80ab3 93 play_wave("/sd/bbunny.wav"); // 8 bit sample size
tom_coxon 0:1f4b7aa80ab3 94
tom_coxon 0:1f4b7aa80ab3 95 play_wave("/sd/clint16.wav"); // 16 bit sample size
tom_coxon 0:1f4b7aa80ab3 96
tom_coxon 0:1f4b7aa80ab3 97 printf("<<<<<<<<<<<<<<<< All done >>>>>>>>>>>>>>>>\r\n");
tom_coxon 0:1f4b7aa80ab3 98 led1=1;
tom_coxon 0:1f4b7aa80ab3 99 wait(.5);
tom_coxon 0:1f4b7aa80ab3 100 led1=0;
tom_coxon 0:1f4b7aa80ab3 101 wait(.5);
tom_coxon 0:1f4b7aa80ab3 102 led1=1;
tom_coxon 0:1f4b7aa80ab3 103 }
tom_coxon 0:1f4b7aa80ab3 104
tom_coxon 0:1f4b7aa80ab3 105 void play_wave(char *wavname) {
tom_coxon 0:1f4b7aa80ab3 106 unsigned chunk_id,chunk_size,channel;
tom_coxon 0:1f4b7aa80ab3 107 unsigned data,samp_int,i;
tom_coxon 0:1f4b7aa80ab3 108 short dac_data;
tom_coxon 0:1f4b7aa80ab3 109 char *slice_buf;
tom_coxon 0:1f4b7aa80ab3 110 short *data_sptr;
tom_coxon 0:1f4b7aa80ab3 111 FMT_STRUCT wav_format;
tom_coxon 0:1f4b7aa80ab3 112 FILE *wavfile;
tom_coxon 0:1f4b7aa80ab3 113 long slice,num_slices;
tom_coxon 0:1f4b7aa80ab3 114 DAC_wptr=0;
tom_coxon 0:1f4b7aa80ab3 115 DAC_rptr=0;
tom_coxon 0:1f4b7aa80ab3 116 for (i=0;i<256;i+=2) {
tom_coxon 0:1f4b7aa80ab3 117 DAC_fifo[i]=0;
tom_coxon 0:1f4b7aa80ab3 118 DAC_fifo[i+1]=3000;
tom_coxon 0:1f4b7aa80ab3 119 }
tom_coxon 0:1f4b7aa80ab3 120 DAC_wptr=4;
tom_coxon 0:1f4b7aa80ab3 121 DAC_on=0;
tom_coxon 0:1f4b7aa80ab3 122
tom_coxon 0:1f4b7aa80ab3 123 led1=led2=led3=led4=0;
tom_coxon 0:1f4b7aa80ab3 124
tom_coxon 0:1f4b7aa80ab3 125 printf("Playing wave file '%s'\r\n",wavname);
tom_coxon 0:1f4b7aa80ab3 126
tom_coxon 0:1f4b7aa80ab3 127 wavfile=fopen(wavname,"rb");
tom_coxon 0:1f4b7aa80ab3 128 if (!wavfile) {
tom_coxon 0:1f4b7aa80ab3 129 printf("Unable to open wav file '%s'\r\n",wavname);
tom_coxon 0:1f4b7aa80ab3 130 exit(1);
tom_coxon 0:1f4b7aa80ab3 131 }
tom_coxon 0:1f4b7aa80ab3 132
tom_coxon 0:1f4b7aa80ab3 133 fread(&chunk_id,4,1,wavfile);
tom_coxon 0:1f4b7aa80ab3 134 fread(&chunk_size,4,1,wavfile);
tom_coxon 0:1f4b7aa80ab3 135 while (!feof(wavfile)) {
tom_coxon 0:1f4b7aa80ab3 136 printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size);
tom_coxon 0:1f4b7aa80ab3 137 switch (chunk_id) {
tom_coxon 0:1f4b7aa80ab3 138 case 0x46464952:
tom_coxon 0:1f4b7aa80ab3 139 fread(&data,4,1,wavfile);
tom_coxon 0:1f4b7aa80ab3 140 printf("RIFF chunk\r\n");
tom_coxon 0:1f4b7aa80ab3 141 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
tom_coxon 0:1f4b7aa80ab3 142 printf(" RIFF type 0x%x\r\n",data);
tom_coxon 0:1f4b7aa80ab3 143 break;
tom_coxon 0:1f4b7aa80ab3 144 case 0x20746d66:
tom_coxon 0:1f4b7aa80ab3 145 fread(&wav_format,sizeof(wav_format),1,wavfile);
tom_coxon 0:1f4b7aa80ab3 146 printf("FORMAT chunk\r\n");
tom_coxon 0:1f4b7aa80ab3 147 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
tom_coxon 0:1f4b7aa80ab3 148 printf(" compression code %d\r\n",wav_format.comp_code);
tom_coxon 0:1f4b7aa80ab3 149 printf(" %d channels\r\n",wav_format.num_channels);
tom_coxon 0:1f4b7aa80ab3 150 printf(" %d samples/sec\r\n",wav_format.sample_rate);
tom_coxon 0:1f4b7aa80ab3 151 printf(" %d bytes/sec\r\n",wav_format.avg_Bps);
tom_coxon 0:1f4b7aa80ab3 152 printf(" block align %d\r\n",wav_format.block_align);
tom_coxon 0:1f4b7aa80ab3 153 printf(" %d bits per sample\r\n",wav_format.sig_bps);
tom_coxon 0:1f4b7aa80ab3 154 if (chunk_size > sizeof(wav_format))
tom_coxon 0:1f4b7aa80ab3 155 fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
tom_coxon 0:1f4b7aa80ab3 156 // create a slice buffer large enough to hold multiple slices
tom_coxon 0:1f4b7aa80ab3 157 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
tom_coxon 0:1f4b7aa80ab3 158 if (!slice_buf) {
tom_coxon 0:1f4b7aa80ab3 159 printf("Unable to malloc slice buffer");
tom_coxon 0:1f4b7aa80ab3 160 exit(1);
tom_coxon 0:1f4b7aa80ab3 161 }
tom_coxon 0:1f4b7aa80ab3 162 break;
tom_coxon 0:1f4b7aa80ab3 163 case 0x61746164:
tom_coxon 0:1f4b7aa80ab3 164 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
tom_coxon 0:1f4b7aa80ab3 165 if (!slice_buf) {
tom_coxon 0:1f4b7aa80ab3 166 printf("Unable to malloc slice buffer");
tom_coxon 0:1f4b7aa80ab3 167 exit(1);
tom_coxon 0:1f4b7aa80ab3 168 }
tom_coxon 0:1f4b7aa80ab3 169 num_slices=chunk_size/wav_format.block_align;
tom_coxon 0:1f4b7aa80ab3 170 printf("DATA chunk\r\n");
tom_coxon 0:1f4b7aa80ab3 171 printf(" chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
tom_coxon 0:1f4b7aa80ab3 172 printf(" %d slices\r\n",num_slices);
tom_coxon 0:1f4b7aa80ab3 173 printf(" Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate));
tom_coxon 0:1f4b7aa80ab3 174 samp_int=1000000/(wav_format.sample_rate);
tom_coxon 0:1f4b7aa80ab3 175 printf(" programmed interrupt tick interval=%d\r\n",samp_int);
tom_coxon 0:1f4b7aa80ab3 176
tom_coxon 0:1f4b7aa80ab3 177 // starting up ticker to write samples out -- no printfs until tick.detach is called
tom_coxon 0:1f4b7aa80ab3 178 tick.attach_us(&dac_out, samp_int);
tom_coxon 0:1f4b7aa80ab3 179 DAC_on=1;
tom_coxon 0:1f4b7aa80ab3 180 led2=1;
tom_coxon 0:1f4b7aa80ab3 181 for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
tom_coxon 0:1f4b7aa80ab3 182 fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
tom_coxon 0:1f4b7aa80ab3 183 if (feof(wavfile)) {
tom_coxon 0:1f4b7aa80ab3 184 printf("Oops -- not enough slices in the wave file\r\n");
tom_coxon 0:1f4b7aa80ab3 185 exit(1);
tom_coxon 0:1f4b7aa80ab3 186 }
tom_coxon 0:1f4b7aa80ab3 187 data_sptr=(short *)slice_buf;
tom_coxon 0:1f4b7aa80ab3 188 for (i=0;i<SLICE_BUF_SIZE;i++) {
tom_coxon 0:1f4b7aa80ab3 189 dac_data=0;
tom_coxon 0:1f4b7aa80ab3 190
tom_coxon 0:1f4b7aa80ab3 191 // for a stereo wave file average the two channels.
tom_coxon 0:1f4b7aa80ab3 192 for (channel=0;channel<wav_format.num_channels;channel++) {
tom_coxon 0:1f4b7aa80ab3 193 switch (wav_format.sig_bps) {
tom_coxon 0:1f4b7aa80ab3 194 case 16:
tom_coxon 0:1f4b7aa80ab3 195 dac_data+=( ((int)(*data_sptr++)) +32768 );
tom_coxon 0:1f4b7aa80ab3 196 break;
tom_coxon 0:1f4b7aa80ab3 197 case 8:
tom_coxon 0:1f4b7aa80ab3 198 dac_data+=( ((int)(*data_sptr++)) +32768 <<8);
tom_coxon 0:1f4b7aa80ab3 199 break;
tom_coxon 0:1f4b7aa80ab3 200 }
tom_coxon 0:1f4b7aa80ab3 201 }
tom_coxon 0:1f4b7aa80ab3 202 DAC_fifo[DAC_wptr]=dac_data;
tom_coxon 0:1f4b7aa80ab3 203 DAC_wptr=(DAC_wptr+1) & 0xff;
tom_coxon 0:1f4b7aa80ab3 204 while (DAC_wptr==DAC_rptr) {
tom_coxon 0:1f4b7aa80ab3 205 led1=1;
tom_coxon 0:1f4b7aa80ab3 206 wait_us(10);
tom_coxon 0:1f4b7aa80ab3 207 }
tom_coxon 0:1f4b7aa80ab3 208 led1=0;
tom_coxon 0:1f4b7aa80ab3 209 }
tom_coxon 0:1f4b7aa80ab3 210 }
tom_coxon 0:1f4b7aa80ab3 211 DAC_on=0;
tom_coxon 0:1f4b7aa80ab3 212 led2=0;
tom_coxon 0:1f4b7aa80ab3 213 tick.detach();
tom_coxon 0:1f4b7aa80ab3 214 printf("Ticker detached\r\n");
tom_coxon 0:1f4b7aa80ab3 215 led3=1;
tom_coxon 0:1f4b7aa80ab3 216 free(slice_buf);
tom_coxon 0:1f4b7aa80ab3 217 break;
tom_coxon 0:1f4b7aa80ab3 218 case 0x5453494c:
tom_coxon 0:1f4b7aa80ab3 219 printf("INFO chunk, size %d\r\n",chunk_size);
tom_coxon 0:1f4b7aa80ab3 220 fseek(wavfile,chunk_size,SEEK_CUR);
tom_coxon 0:1f4b7aa80ab3 221 break;
tom_coxon 0:1f4b7aa80ab3 222 default:
tom_coxon 0:1f4b7aa80ab3 223 printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size);
tom_coxon 0:1f4b7aa80ab3 224 data=fseek(wavfile,chunk_size,SEEK_CUR);
tom_coxon 0:1f4b7aa80ab3 225 break;
tom_coxon 0:1f4b7aa80ab3 226 }
tom_coxon 0:1f4b7aa80ab3 227 fread(&chunk_id,4,1,wavfile);
tom_coxon 0:1f4b7aa80ab3 228 fread(&chunk_size,4,1,wavfile);
tom_coxon 0:1f4b7aa80ab3 229 }
tom_coxon 0:1f4b7aa80ab3 230 printf("++++++++++++ Done with wave file ++++++++++\r\n");
tom_coxon 0:1f4b7aa80ab3 231 fclose(wavfile);
tom_coxon 0:1f4b7aa80ab3 232 led1=0;
tom_coxon 0:1f4b7aa80ab3 233 }
tom_coxon 0:1f4b7aa80ab3 234
tom_coxon 0:1f4b7aa80ab3 235
tom_coxon 0:1f4b7aa80ab3 236 void dac_out() {
tom_coxon 0:1f4b7aa80ab3 237 if (DAC_on) {
tom_coxon 0:1f4b7aa80ab3 238 led4=1;
tom_coxon 0:1f4b7aa80ab3 239 DACout.write_u16(DAC_fifo[DAC_rptr]);
tom_coxon 0:1f4b7aa80ab3 240 DAC_rptr=(DAC_rptr+1) & 0xff;
tom_coxon 0:1f4b7aa80ab3 241 led4=0;
tom_coxon 0:1f4b7aa80ab3 242 }
tom_coxon 0:1f4b7aa80ab3 243 }
tom_coxon 0:1f4b7aa80ab3 244
tom_coxon 0:1f4b7aa80ab3 245