Stephane ROCHON
/
WAVEplayer
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Mon Jul 18 2022 01:23:33 by 1.7.2