Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //todo red button and light sensor
00002 
00003 
00004 #include "mbed.h"
00005 #include "SDFileSystem.h"
00006 
00007 AnalogOut DACout(p18);
00008 DigitalOut led1(LED1);
00009 DigitalOut led2(LED2);
00010 DigitalOut led3(LED3);
00011 DigitalOut led4(LED4);
00012 DigitalOut digout(p8);
00013 Ticker tick;
00014 SDFileSystem sd(p5, p6, p7, p13, "sd");
00015 
00016 #define SAMPLE_FREQ 40000
00017 #define BUF_SIZE (SAMPLE_FREQ/10)
00018 #define SLICE_BUF_SIZE 1
00019 
00020 void dac_out(void);
00021 void play_wave(char *);
00022 void cleanup(char *);
00023 void fill_adc_buf(short *, unsigned);
00024 void swapword(unsigned *);
00025 
00026 // a FIFO for the DAC
00027 short DAC_fifo[256];
00028 short DAC_wptr;
00029 short DAC_rptr;
00030 short DAC_on;
00031 
00032 typedef struct uFMT_STRUCT {
00033   short comp_code;
00034   short num_channels;
00035   unsigned sample_rate;
00036   unsigned avg_Bps;
00037   short block_align;
00038   short sig_bps;
00039 } FMT_STRUCT;
00040 
00041 
00042 int main() {
00043   led1=0; wait(.5); led1=1; wait(.5); led1=0;
00044   printf("Hello, world!\n");
00045   play_wave("/sd/baddonut.wav");
00046   printf("Back from play_wave()\n");
00047   play_wave("/sd/clint16.wav");
00048   printf("Back from play_wave()\n");
00049   printf("Goodbye, world!\n");
00050 }
00051   
00052 void play_wave(char *wavname)
00053 {
00054         unsigned chunk_id,chunk_size,channel;
00055         unsigned *data_wptr,data,samp_int,i;
00056         short dac_data;
00057         char *slice_buf;
00058         short *data_sptr;
00059         char *data_bptr;
00060         FMT_STRUCT wav_format;
00061         FILE *wavfile;
00062         long slice,num_slices;
00063   DAC_wptr=0;
00064   DAC_rptr=0;
00065   for (i=0;i<256;i+=2) {
00066     DAC_fifo[i]=0;
00067     DAC_fifo[i+1]=3000;
00068   }
00069   DAC_wptr=4;
00070   DAC_on=0;
00071 
00072   led1=led2=led3=led4=0;
00073   
00074   printf("Playing wave file '%s'\n",wavname);
00075 
00076   wavfile=fopen(wavname,"rb");
00077   if (!wavfile) {
00078     printf("Unable to open wav file '%s'\n",wavname);
00079     exit(1);
00080   }
00081 
00082   fread(&chunk_id,4,1,wavfile);
00083   fread(&chunk_size,4,1,wavfile);
00084   while (!feof(wavfile)) {
00085     printf("Read chunk ID 0x%x, size 0x%x\n",chunk_id,chunk_size);
00086     switch (chunk_id) {
00087       case 0x46464952:
00088         fread(&data,4,1,wavfile);
00089         printf("RIFF chunk\n");
00090         printf("  chunk size %d (0x%x)\n",chunk_size,chunk_size);
00091         printf("  RIFF type 0x%x\n",data);
00092         break;
00093       case 0x20746d66:
00094         fread(&wav_format,sizeof(wav_format),1,wavfile);
00095         printf("FORMAT chunk\n");
00096         printf("  chunk size %d (0x%x)\n",chunk_size,chunk_size);
00097         printf("  compression code %d\n",wav_format.comp_code);
00098         printf("  %d channels\n",wav_format.num_channels);
00099         printf("  %d samples/sec\n",wav_format.sample_rate);
00100         printf("  %d bytes/sec\n",wav_format.avg_Bps);
00101         printf("  block align %d\n",wav_format.block_align);
00102         printf("  %d bits per sample\n",wav_format.sig_bps);
00103         if (chunk_size > sizeof(wav_format))
00104           fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
00105 // create a slice buffer large enough to hold multiple slices
00106         slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
00107         if (!slice_buf) {
00108           printf("Unable to malloc slice buffer");
00109           exit(1);
00110         }
00111         break;
00112       case 0x61746164:
00113         slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
00114         if (!slice_buf) {
00115           printf("Unable to malloc slice buffer");
00116           exit(1);
00117         }        num_slices=chunk_size/wav_format.block_align;
00118         printf("DATA chunk\n");
00119         printf("  chunk size %d (0x%x)\n",chunk_size,chunk_size);
00120         printf("  %d slices\n",num_slices);
00121         printf("  Ideal sample interval=%d\n",(unsigned)(1000000.0/wav_format.sample_rate));
00122         samp_int=1000000/(wav_format.sample_rate);
00123         printf("  programmed interrupt tick interval=%d\n",samp_int);
00124 
00125 // starting up ticker to write samples out -- no printfs until tick.detach is called
00126         tick.attach_us(&dac_out, samp_int); 
00127         DAC_on=1; 
00128         led2=1;
00129         for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {
00130           fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
00131           if (feof(wavfile)) {
00132             printf("Oops -- not enough slices in the wave file\n");
00133             exit(1);
00134           }
00135           data_sptr=(short *)slice_buf;
00136           for (i=0;i<SLICE_BUF_SIZE;i++) {
00137             dac_data=0;
00138 
00139 // for a stereo wave file average the two channels.
00140             for (channel=0;channel<wav_format.num_channels;channel++) {
00141               switch (wav_format.sig_bps) {
00142                 case 16:
00143                   dac_data+=(  ((int)(*data_sptr++)) +32768)>>5;
00144                   break;
00145               }
00146             }
00147             dac_data>>=1;
00148             DAC_fifo[DAC_wptr]=dac_data;
00149             DAC_wptr=(DAC_wptr+1) & 0xff;
00150             while (DAC_wptr==DAC_rptr) {
00151               led1=1;
00152             }
00153             led1=0;
00154           }
00155         }
00156         DAC_on=0;
00157         led2=0;
00158         tick.detach();
00159         printf("Ticker detached\n");
00160         led3=1;
00161         free(slice_buf);
00162         break;
00163       case 0x5453494c:
00164         printf("INFO chunk, size %d\n",chunk_size);
00165         fseek(wavfile,chunk_size,SEEK_CUR);
00166         break;
00167       default:
00168         printf("unknown chunk type 0x%x, size %d\n",chunk_id,chunk_size);
00169         data=fseek(wavfile,chunk_size,SEEK_CUR);
00170         break;
00171     }
00172     fread(&chunk_id,4,1,wavfile);
00173     fread(&chunk_size,4,1,wavfile);
00174   }
00175   printf("Done with wave file\n");
00176   fclose(wavfile);
00177   led1=0;
00178 }
00179 
00180 
00181 void dac_out()
00182 {
00183   if (DAC_on) {
00184     digout=1;
00185     DACout.write(DAC_fifo[DAC_rptr]);
00186     DAC_rptr=(DAC_rptr+1) & 0xff;
00187     digout=0;
00188   }
00189 }
00190 
00191