Dependencies:   mbed

Committer:
vcazan
Date:
Sun Dec 06 17:08:31 2009 +0000
Revision:
0:143457f10e26

        

Who changed what in which revision?

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