Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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