Dependencies:   mbed

Committer:
Kerpower
Date:
Sat Jan 02 17:07:38 2010 +0000
Revision:
0:4cda52c0c66e

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kerpower 0:4cda52c0c66e 1 #include "mbed.h"
Kerpower 0:4cda52c0c66e 2 #include "SDFileSystem.h"
Kerpower 0:4cda52c0c66e 3
Kerpower 0:4cda52c0c66e 4 AnalogOut DACout(p18);
Kerpower 0:4cda52c0c66e 5 DigitalOut led1(LED1);
Kerpower 0:4cda52c0c66e 6 DigitalOut led2(LED2);
Kerpower 0:4cda52c0c66e 7 DigitalOut led3(LED3);
Kerpower 0:4cda52c0c66e 8 DigitalOut led4(p8);
Kerpower 0:4cda52c0c66e 9 DigitalOut digout(LED4);
Kerpower 0:4cda52c0c66e 10 Ticker tick;
Kerpower 0:4cda52c0c66e 11 SDFileSystem sd(p11, p12, p13, p14, "sd");
Kerpower 0:4cda52c0c66e 12
Kerpower 0:4cda52c0c66e 13 #define SAMPLE_FREQ 40000
Kerpower 0:4cda52c0c66e 14 #define BUF_SIZE (SAMPLE_FREQ/10)
Kerpower 0:4cda52c0c66e 15 #define SLICE_BUF_SIZE 1
Kerpower 0:4cda52c0c66e 16
Kerpower 0:4cda52c0c66e 17 void dac_out(void);
Kerpower 0:4cda52c0c66e 18 void play_wave(char *);
Kerpower 0:4cda52c0c66e 19 void cleanup(char *);
Kerpower 0:4cda52c0c66e 20 void fill_adc_buf(short *, unsigned);
Kerpower 0:4cda52c0c66e 21 void swapword(unsigned *);
Kerpower 0:4cda52c0c66e 22
Kerpower 0:4cda52c0c66e 23 // a FIFO for the DAC
Kerpower 0:4cda52c0c66e 24 short DAC_fifo[256];
Kerpower 0:4cda52c0c66e 25 short DAC_wptr;
Kerpower 0:4cda52c0c66e 26 short DAC_rptr;
Kerpower 0:4cda52c0c66e 27 short DAC_on;
Kerpower 0:4cda52c0c66e 28
Kerpower 0:4cda52c0c66e 29 typedef struct uFMT_STRUCT {
Kerpower 0:4cda52c0c66e 30 short comp_code;
Kerpower 0:4cda52c0c66e 31 short num_channels;
Kerpower 0:4cda52c0c66e 32 unsigned sample_rate;
Kerpower 0:4cda52c0c66e 33 unsigned avg_Bps;
Kerpower 0:4cda52c0c66e 34 short block_align;
Kerpower 0:4cda52c0c66e 35 short sig_bps;
Kerpower 0:4cda52c0c66e 36 } FMT_STRUCT;
Kerpower 0:4cda52c0c66e 37
Kerpower 0:4cda52c0c66e 38
Kerpower 0:4cda52c0c66e 39 int main() {
Kerpower 0:4cda52c0c66e 40 led1=0; wait(.5); led1=1; wait(.5); led1=0;
Kerpower 0:4cda52c0c66e 41 printf("Hello, world!\n");
Kerpower 0:4cda52c0c66e 42 play_wave("/sd/baddonut.wav");
Kerpower 0:4cda52c0c66e 43 printf("Back from play_wave()\n");
Kerpower 0:4cda52c0c66e 44 play_wave("/sd/clint16.wav");
Kerpower 0:4cda52c0c66e 45 printf("Back from play_wave()\n");
Kerpower 0:4cda52c0c66e 46 printf("Goodbye, world!\n");
Kerpower 0:4cda52c0c66e 47 led1=1; wait(.5); led1=0; wait(.5); led1=1;
Kerpower 0:4cda52c0c66e 48 }
Kerpower 0:4cda52c0c66e 49
Kerpower 0:4cda52c0c66e 50 void play_wave(char *wavname)
Kerpower 0:4cda52c0c66e 51 {
Kerpower 0:4cda52c0c66e 52 unsigned chunk_id,chunk_size,channel;
Kerpower 0:4cda52c0c66e 53 // unsigned *data_wptr,data,samp_int,i;
Kerpower 0:4cda52c0c66e 54 unsigned data,samp_int,i;
Kerpower 0:4cda52c0c66e 55 short dac_data;
Kerpower 0:4cda52c0c66e 56 char *slice_buf;
Kerpower 0:4cda52c0c66e 57 short *data_sptr;
Kerpower 0:4cda52c0c66e 58 // char *data_bptr;
Kerpower 0:4cda52c0c66e 59 FMT_STRUCT wav_format;
Kerpower 0:4cda52c0c66e 60 FILE *wavfile;
Kerpower 0:4cda52c0c66e 61 long slice,num_slices;
Kerpower 0:4cda52c0c66e 62 DAC_wptr=0;
Kerpower 0:4cda52c0c66e 63 DAC_rptr=0;
Kerpower 0:4cda52c0c66e 64 for (i=0;i<256;i+=2) {
Kerpower 0:4cda52c0c66e 65 DAC_fifo[i]=0;
Kerpower 0:4cda52c0c66e 66 DAC_fifo[i+1]=3000;
Kerpower 0:4cda52c0c66e 67 }
Kerpower 0:4cda52c0c66e 68 DAC_wptr=4;
Kerpower 0:4cda52c0c66e 69 DAC_on=0;
Kerpower 0:4cda52c0c66e 70
Kerpower 0:4cda52c0c66e 71 led1=led2=led3=led4=0;
Kerpower 0:4cda52c0c66e 72
Kerpower 0:4cda52c0c66e 73 printf("Playing wave file '%s'\n",wavname);
Kerpower 0:4cda52c0c66e 74
Kerpower 0:4cda52c0c66e 75 wavfile=fopen(wavname,"rb");
Kerpower 0:4cda52c0c66e 76 if (!wavfile) {
Kerpower 0:4cda52c0c66e 77 printf("Unable to open wav file '%s'\n",wavname);
Kerpower 0:4cda52c0c66e 78 exit(1);
Kerpower 0:4cda52c0c66e 79 }
Kerpower 0:4cda52c0c66e 80
Kerpower 0:4cda52c0c66e 81 fread(&chunk_id,4,1,wavfile);
Kerpower 0:4cda52c0c66e 82 fread(&chunk_size,4,1,wavfile);
Kerpower 0:4cda52c0c66e 83 while (!feof(wavfile)) {
Kerpower 0:4cda52c0c66e 84 printf("Read chunk ID 0x%x, size 0x%x\n",chunk_id,chunk_size);
Kerpower 0:4cda52c0c66e 85 switch (chunk_id) {
Kerpower 0:4cda52c0c66e 86 case 0x46464952:
Kerpower 0:4cda52c0c66e 87 fread(&data,4,1,wavfile);
Kerpower 0:4cda52c0c66e 88 printf("RIFF chunk\n");
Kerpower 0:4cda52c0c66e 89 printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
Kerpower 0:4cda52c0c66e 90 printf(" RIFF type 0x%x\n",data);
Kerpower 0:4cda52c0c66e 91 break;
Kerpower 0:4cda52c0c66e 92 case 0x20746d66:
Kerpower 0:4cda52c0c66e 93 fread(&wav_format,sizeof(wav_format),1,wavfile);
Kerpower 0:4cda52c0c66e 94 printf("FORMAT chunk\n");
Kerpower 0:4cda52c0c66e 95 printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
Kerpower 0:4cda52c0c66e 96 printf(" compression code %d\n",wav_format.comp_code);
Kerpower 0:4cda52c0c66e 97 printf(" %d channels\n",wav_format.num_channels);
Kerpower 0:4cda52c0c66e 98 printf(" %d samples/sec\n",wav_format.sample_rate);
Kerpower 0:4cda52c0c66e 99 printf(" %d bytes/sec\n",wav_format.avg_Bps);
Kerpower 0:4cda52c0c66e 100 printf(" block align %d\n",wav_format.block_align);
Kerpower 0:4cda52c0c66e 101 printf(" %d bits per sample\n",wav_format.sig_bps);
Kerpower 0:4cda52c0c66e 102 if (chunk_size > sizeof(wav_format))
Kerpower 0:4cda52c0c66e 103 fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
Kerpower 0:4cda52c0c66e 104 // create a slice buffer large enough to hold multiple slices
Kerpower 0:4cda52c0c66e 105 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
Kerpower 0:4cda52c0c66e 106 if (!slice_buf) {
Kerpower 0:4cda52c0c66e 107 printf("Unable to malloc slice buffer");
Kerpower 0:4cda52c0c66e 108 exit(1);
Kerpower 0:4cda52c0c66e 109 }
Kerpower 0:4cda52c0c66e 110 break;
Kerpower 0:4cda52c0c66e 111 case 0x61746164:
Kerpower 0:4cda52c0c66e 112 slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
Kerpower 0:4cda52c0c66e 113 if (!slice_buf) {
Kerpower 0:4cda52c0c66e 114 printf("Unable to malloc slice buffer");
Kerpower 0:4cda52c0c66e 115 exit(1);
Kerpower 0:4cda52c0c66e 116 } num_slices=chunk_size/wav_format.block_align;
Kerpower 0:4cda52c0c66e 117 printf("DATA chunk\n");
Kerpower 0:4cda52c0c66e 118 printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size);
Kerpower 0:4cda52c0c66e 119 printf(" %d slices\n",num_slices);
Kerpower 0:4cda52c0c66e 120 printf(" Ideal sample interval=%d\n",(unsigned)(1000000.0/wav_format.sample_rate));
Kerpower 0:4cda52c0c66e 121 samp_int=1000000/(wav_format.sample_rate);
Kerpower 0:4cda52c0c66e 122 printf(" programmed interrupt tick interval=%d\n",samp_int);
Kerpower 0:4cda52c0c66e 123
Kerpower 0:4cda52c0c66e 124 // starting up ticker to write samples out -- no printfs until tick.detach is called
Kerpower 0:4cda52c0c66e 125 tick.attach_us(&dac_out, samp_int);
Kerpower 0:4cda52c0c66e 126 DAC_on=1;
Kerpower 0:4cda52c0c66e 127 led2=1;
Kerpower 0:4cda52c0c66e 128 for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
Kerpower 0:4cda52c0c66e 129 fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
Kerpower 0:4cda52c0c66e 130 if (feof(wavfile)) {
Kerpower 0:4cda52c0c66e 131 printf("Oops -- not enough slices in the wave file\n");
Kerpower 0:4cda52c0c66e 132 exit(1);
Kerpower 0:4cda52c0c66e 133 }
Kerpower 0:4cda52c0c66e 134 data_sptr=(short *)slice_buf;
Kerpower 0:4cda52c0c66e 135 for (i=0;i<SLICE_BUF_SIZE;i++) {
Kerpower 0:4cda52c0c66e 136 dac_data=0;
Kerpower 0:4cda52c0c66e 137
Kerpower 0:4cda52c0c66e 138 // for a stereo wave file average the two channels.
Kerpower 0:4cda52c0c66e 139 for (channel=0;channel<wav_format.num_channels;channel++) {
Kerpower 0:4cda52c0c66e 140 switch (wav_format.sig_bps) {
Kerpower 0:4cda52c0c66e 141 case 16:
Kerpower 0:4cda52c0c66e 142 dac_data+=( ((int)(*data_sptr++)) +32768)>>5;
Kerpower 0:4cda52c0c66e 143 break;
Kerpower 0:4cda52c0c66e 144 }
Kerpower 0:4cda52c0c66e 145 }
Kerpower 0:4cda52c0c66e 146 dac_data>>=1;
Kerpower 0:4cda52c0c66e 147 DAC_fifo[DAC_wptr]=dac_data;
Kerpower 0:4cda52c0c66e 148 DAC_wptr=(DAC_wptr+1) & 0xff;
Kerpower 0:4cda52c0c66e 149 while (DAC_wptr==DAC_rptr) {
Kerpower 0:4cda52c0c66e 150 led1=1;
Kerpower 0:4cda52c0c66e 151 }
Kerpower 0:4cda52c0c66e 152 led1=0;
Kerpower 0:4cda52c0c66e 153 }
Kerpower 0:4cda52c0c66e 154 }
Kerpower 0:4cda52c0c66e 155 DAC_on=0;
Kerpower 0:4cda52c0c66e 156 led2=0;
Kerpower 0:4cda52c0c66e 157 tick.detach();
Kerpower 0:4cda52c0c66e 158 printf("Ticker detached\n");
Kerpower 0:4cda52c0c66e 159 led3=1;
Kerpower 0:4cda52c0c66e 160 free(slice_buf);
Kerpower 0:4cda52c0c66e 161 break;
Kerpower 0:4cda52c0c66e 162 case 0x5453494c:
Kerpower 0:4cda52c0c66e 163 printf("INFO chunk, size %d\n",chunk_size);
Kerpower 0:4cda52c0c66e 164 fseek(wavfile,chunk_size,SEEK_CUR);
Kerpower 0:4cda52c0c66e 165 break;
Kerpower 0:4cda52c0c66e 166 default:
Kerpower 0:4cda52c0c66e 167 printf("unknown chunk type 0x%x, size %d\n",chunk_id,chunk_size);
Kerpower 0:4cda52c0c66e 168 data=fseek(wavfile,chunk_size,SEEK_CUR);
Kerpower 0:4cda52c0c66e 169 break;
Kerpower 0:4cda52c0c66e 170 }
Kerpower 0:4cda52c0c66e 171 fread(&chunk_id,4,1,wavfile);
Kerpower 0:4cda52c0c66e 172 fread(&chunk_size,4,1,wavfile);
Kerpower 0:4cda52c0c66e 173 }
Kerpower 0:4cda52c0c66e 174 printf("Done with wave file\n");
Kerpower 0:4cda52c0c66e 175 fclose(wavfile);
Kerpower 0:4cda52c0c66e 176 led1=0;
Kerpower 0:4cda52c0c66e 177 }
Kerpower 0:4cda52c0c66e 178
Kerpower 0:4cda52c0c66e 179
Kerpower 0:4cda52c0c66e 180 void dac_out()
Kerpower 0:4cda52c0c66e 181 {
Kerpower 0:4cda52c0c66e 182 if (DAC_on) {
Kerpower 0:4cda52c0c66e 183 digout=1;
Kerpower 0:4cda52c0c66e 184 DACout.write_u16(DAC_fifo[DAC_rptr]);
Kerpower 0:4cda52c0c66e 185 DAC_rptr=(DAC_rptr+1) & 0xff;
Kerpower 0:4cda52c0c66e 186 digout=0;
Kerpower 0:4cda52c0c66e 187 }
Kerpower 0:4cda52c0c66e 188 }
Kerpower 0:4cda52c0c66e 189
Kerpower 0:4cda52c0c66e 190