Vlad Cazan
/
WavePlayer
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Sun Jul 31 2022 22:49:05 by 1.7.2