does not work yet. Sound starts but then stops after a few seconds, whole thing hangs. Published so as I can import through mbed CLI.
Dependencies: mbed sinelookup SDFileSystem_Copy_of_mbed_version I2S
wolfson_3_wav.cpp
00001 00002 // 24/03/2018 update - I appear to be able to address the device and write something, as I am getting an ACK returned from the i2c write() function. 00003 //however if i use the write function with 4 arguments (as opposed to just 1 argument) then it doesnt work 00004 //only works with the 1 argument version!!! 00005 00006 00007 //THIS VERSION WORKED, CHANGED SOME THINGS, THEN CHANGED THEM BACK. NOW IT NO LONGER WORKS!!!! 00008 #include "mbed.h" 00009 #include "sinelookup.h" 00010 #include "I2S.h" 00011 #define sample_freq 8000 00012 DigitalOut myled(LED1); 00013 DigitalOut led2(LED2); 00014 DigitalOut led3(LED3); 00015 Ticker sampletick; 00016 Timer t; 00017 Timer t2; 00018 #include "SDFileSystem.h" 00019 #include "WOLFSON_config.h" 00020 Serial pc(USBTX, USBRX); // tx, rx //FOR DEBUGGING PROGRAM USING GNU SCREEN 00021 DigitalOut cs(p8); 00022 I2S i2s(I2S_TRANSMIT,p5,p6,p7); 00023 I2C i2c(p9, p10); 00024 00025 SDFileSystem sd(p11, p12, p13, p8, "sd"); // the new pinout that i am using 00026 00027 typedef struct uFMT_STRUCT{ 00028 short comp_code; 00029 short num_channels; 00030 unsigned sample_rate; 00031 unsigned avg_Bps; 00032 short block_align; 00033 short sig_bps; 00034 } FMT_STRUCT; 00035 00036 typedef struct uDATA_STRUCT { 00037 unsigned subchunk2_ID; 00038 unsigned subchunk2_size; 00039 char * data_buf; 00040 }DATA_STRUCT; 00041 short hello; 00042 int i = 0; 00043 int h = 0; 00044 short bufflen = 1; 00045 int buffer[1]; 00046 int AudioFormat, NumChannels, SampleRate, BitsPerSample ; 00047 char *slice_buf; 00048 short *data_sptr; 00049 unsigned char *data_bptr; 00050 int *data_wptr; 00051 unsigned channel; 00052 int newvar; 00053 long slice, num_slices; 00054 int verbosity = 0; 00055 int verbosity2 = 0; 00056 int interrupt_condition = 1; 00057 int sampling_freq = 8000; 00058 short Buffer1[8]; 00059 short Buffer2[8]; 00060 short place_hold1 = 0; 00061 short place_hold2 = 0; 00062 int flag1 = 1; 00063 int flag2 = 0; 00064 int flag3 = 1; 00065 int flag4 = 0; 00066 short value[1]; 00067 //long long slice_value; 00068 int slice_value[1]; 00069 FILE *my_wav; 00070 FMT_STRUCT wav_format; 00071 DATA_STRUCT wav_data; 00072 00073 Ticker flipper; 00074 //test 00075 void flip() { 00076 led2 = !led2; 00077 } 00078 00079 00080 void isr() 00081 { 00082 //buffer[0] = (*data_sptr)>>1; 00083 //myled = 1; 00084 //int bufflen = sizeof(buffer); 00085 if(verbosity){ 00086 printf("buffer data: %d \n\r",buffer); 00087 printf("data_sptr data: %d",data_sptr); 00088 short value = Buffer1[0]; 00089 printf("value: %d",value); 00090 } 00091 //t.start(); 00092 00093 //t.stop(); 00094 //printf("The time taken was %f seconds\n", t.read()); 00095 //t.reset(); 00096 //myled = 0; 00097 led2 = !led2; 00098 if(flag1 == 0) 00099 { 00100 //access double buffer pt1 00101 value[0] = Buffer1[place_hold1]; 00102 i2s.write(value,1);//Send next PWM value to amp 00103 place_hold1 = place_hold1 + 1; 00104 if(place_hold1 == 8) 00105 { 00106 place_hold1 = 0; 00107 place_hold2 = 0; 00108 flag1 = 1; 00109 flag2 = 0; 00110 flag3 = 1; 00111 } 00112 if(verbosity2 == 1) 00113 { 00114 printf("value Buffer1: %d\n\r",value[0]); 00115 } 00116 } 00117 else if(flag2 == 0) 00118 { 00119 //access double buffer pt2 00120 value[0] = Buffer1[place_hold2]; 00121 i2s.write(value,1);//Send next PWM value to amp 00122 place_hold2 = place_hold2 + 1; 00123 if(place_hold2 == 8) 00124 { 00125 place_hold1 = 0; 00126 place_hold2 = 0; 00127 flag1 = 0; 00128 flag2 = 1; 00129 flag3 = 1; 00130 } 00131 if(verbosity2 == 1) 00132 { 00133 printf("value Buffer2: %d\n\r",value[0]); 00134 } 00135 } 00136 00137 } 00138 00139 00140 00141 void wm8731_setup(int chip_addr, int addr, int cmd){ 00142 addr = addr << 1; 00143 addr = addr|((cmd >> 8 ))& 0x01;//mess around with order of operations 00144 cmd = cmd&0xFF; 00145 i2c.start(); 00146 i2c.write( chip_addr ); 00147 i2c.write( addr ); 00148 i2c.write( cmd ); 00149 i2c.stop(); 00150 } 00151 00152 00153 void wm8731_config(void){ 00154 wm8731_setup( WM8731_ADDRESS, WM8731_REG_RESET, _WM8731_RESET );//1 00155 wm8731_setup( WM8731_ADDRESS, WM8731_REG_LLINE_IN, _WM8731_LEFT_LINEIN );//2 00156 wm8731_setup( WM8731_ADDRESS, WM8731_REG_RLINE_IN, _WM8731_RIGHT_LINEIN );//3 00157 wm8731_setup( WM8731_ADDRESS, WM8731_REG_LHPHONE_OUT, _WM8731_LEFT_HP );//4 00158 wm8731_setup( WM8731_ADDRESS, WM8731_REG_RHPHONE_OUT, _WM8731_RIGHT_HP );//5 00159 wm8731_setup( WM8731_ADDRESS, WM8731_REG_ANALOG_PATH, _WM8731_ANALOGAUDIO );//6 00160 wm8731_setup( WM8731_ADDRESS, WM8731_REG_DIGITAL_PATH, _WM8731_DIGITALAUDIO );//7 00161 wm8731_setup( WM8731_ADDRESS, WM8731_REG_PDOWN_CTRL, _WM8731_POWER );//8 00162 wm8731_setup( WM8731_ADDRESS, WM8731_REG_DIGITAL_IF, _WM8731_DAIF );//9 00163 wm8731_setup( WM8731_ADDRESS, WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING );//10 00164 } 00165 00166 void wm8731_configTEST(void){ 00167 int addr = WM8731_REG_RESET; 00168 int cmd = _WM8731_RESET; 00169 addr = addr << 1; 00170 addr = addr|((cmd >> 8 ))& 0x01;//mess around with order of operations 00171 cmd = cmd&0xFF; 00172 i2c.start(); 00173 i2c.write( WM8731_ADDRESS ); 00174 i2c.write( addr ); 00175 i2c.write( cmd ); 00176 i2c.stop(); 00177 00178 addr = WM8731_REG_LLINE_IN; 00179 cmd = _WM8731_LEFT_LINEIN; 00180 addr = addr << 1; 00181 addr = addr|((cmd >> 8 )) & 0x01; 00182 cmd = cmd&0xFF; 00183 i2c.start(); 00184 i2c.write( WM8731_ADDRESS );//take Fergus' suggestion and declare these to known values EARLIER in program 00185 i2c.write( addr ); 00186 i2c.write( cmd ); 00187 i2c.stop(); 00188 00189 00190 addr = WM8731_REG_RLINE_IN; 00191 cmd = _WM8731_RIGHT_LINEIN; 00192 addr = addr << 1; 00193 addr = addr|((cmd >> 8 )) & 0x01; 00194 cmd = cmd&0xFF; 00195 i2c.start(); 00196 i2c.write( WM8731_ADDRESS );//take Fergus' suggestion and declare these to known values EARLIER in program 00197 i2c.write( addr ); 00198 i2c.write( cmd ); 00199 i2c.stop(); 00200 00201 00202 //4 00203 addr = WM8731_REG_LHPHONE_OUT; 00204 cmd = _WM8731_LEFT_HP; 00205 addr = addr << 1; 00206 addr = addr|((cmd >> 8 )) & 0x01; 00207 cmd = cmd&0xFF; 00208 i2c.start(); 00209 i2c.write( WM8731_ADDRESS ); 00210 i2c.write( addr );//WM8731_REG_LHPHONE_OUT, _WM8731_LEFT_HP 00211 i2c.write(cmd); 00212 i2c.stop(); 00213 00214 //5 00215 addr = WM8731_REG_RHPHONE_OUT; 00216 cmd = _WM8731_RIGHT_HP; 00217 addr = addr << 1; 00218 addr = addr|((cmd >> 8 )) & 0x01; 00219 cmd = cmd&0xFF; 00220 i2c.start(); 00221 i2c.write( WM8731_ADDRESS );//WM8731_REG_RHPHONE_OUT, _WM8731_RIGHT_HP 00222 i2c.write( addr ); 00223 i2c.write( cmd ); 00224 i2c.stop(); 00225 00226 00227 //6 00228 addr = WM8731_REG_ANALOG_PATH; 00229 cmd = _WM8731_ANALOGAUDIO; 00230 addr = addr << 1; 00231 addr = addr|((cmd >> 8 )) & 0x01; 00232 cmd = cmd&0xFF; 00233 i2c.start(); 00234 i2c.write( WM8731_ADDRESS );//WM8731_REG_ANALOG_PATH, _WM8731_ANALOGAUDIO 00235 i2c.write( addr ); 00236 i2c.write( cmd ); 00237 i2c.stop(); 00238 00239 //7 00240 addr = WM8731_REG_DIGITAL_PATH; 00241 cmd = _WM8731_DIGITALAUDIO; 00242 addr = addr << 1; 00243 addr = addr|((cmd >> 8 )) & 0x01; 00244 cmd = cmd&0xFF; 00245 i2c.start(); 00246 i2c.write( WM8731_ADDRESS );//WM8731_REG_DIGITAL_PATH, _WM8731_DIGITALAUDIO 00247 i2c.write( addr ); 00248 i2c.write( cmd ); 00249 i2c.stop(); 00250 00251 //8 00252 addr = WM8731_REG_PDOWN_CTRL; 00253 cmd = _WM8731_POWER; 00254 addr = addr << 1; 00255 addr = addr|((cmd >> 8 )) & 0x01; 00256 cmd = cmd&0xFF; 00257 i2c.start(); 00258 i2c.write( WM8731_ADDRESS );//WM8731_REG_PDOWN_CTRL, _WM8731_POWER) 00259 i2c.write( addr ); 00260 i2c.write( cmd ); 00261 i2c.stop(); 00262 00263 00264 //9 00265 addr = WM8731_REG_DIGITAL_IF; 00266 cmd = _WM8731_DAIF; 00267 addr = addr << 1; 00268 addr = addr|((cmd >> 8 )) & 0x01; 00269 cmd = cmd&0xFF; 00270 i2c.start(); 00271 i2c.write( WM8731_ADDRESS ); 00272 i2c.write( addr );//WM8731_REG_DIGITAL_IF, _WM8731_DAIF 00273 i2c.write( cmd ); 00274 i2c.stop(); 00275 00276 00277 //10 00278 addr = WM8731_REG_SAMPLING_CTRL; 00279 cmd = _WM8731_SAMPLING; 00280 addr = addr << 1; 00281 addr = addr|((cmd >> 8 )) & 0x01; 00282 cmd = cmd&0xFF; 00283 i2c.start(); 00284 i2c.write( WM8731_ADDRESS );//WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING 00285 i2c.write( addr ); 00286 i2c.write( cmd ); 00287 i2c.stop(); 00288 00289 00290 00291 00292 //11 00293 addr = WM8731_REG_ACTIVE_CTRL; 00294 cmd = _WM8731_ACTIVATE; 00295 addr = addr << 1; 00296 addr = addr|((cmd >> 8 )) & 0x01; 00297 cmd = cmd&0xFF; 00298 i2c.start(); 00299 i2c.write( WM8731_ADDRESS );//WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING 00300 i2c.write( addr ); 00301 i2c.write( cmd );//there is also a deactive version!! 00302 i2c.stop(); 00303 00304 00305 00306 } 00307 00308 int main() { 00309 FMT_STRUCT wav_format; 00310 char data[2]; 00311 pc.printf("Beginning of program\n"); 00312 data[0] = 0x0F; 00313 data[1] = 0x00; 00314 FILE *my_wav; 00315 //my_wav = fopen("/sd/mydir/gp40.wav", "rb");//i think that it is "w" for write, "r" for read. 00316 //my_wav = fopen("/sd/mydir/gp40_48K.wav", "rb");//i think that it is "w" for write, "r" for read. 00317 //my_wav = fopen("/sd/mydir/gp40_48K_quieter.wav", "rb");//i think that it is "w" for write, "r" for read. 00318 //my_wav = fopen("/sd/mydir/gp40_8K.wav","rb"); 00319 my_wav = fopen("/sd/mydir/gp40_8K_2018.wav","rb"); 00320 //my_wav = fopen("/sd/mydir/emd_645.wav", "rb"); 00321 fseek(my_wav, 20, SEEK_SET); // set pointer to byte 20 00322 fread(&AudioFormat, 2, 1, my_wav); // check file is PCM 00323 if (AudioFormat==0x01) { 00324 printf("Wav file is PCM data\n\r"); 00325 } 00326 else { 00327 printf("Wav file is not PCM data\n\r"); 00328 } 00329 00330 fseek (my_wav,20,SEEK_SET); 00331 fread(&wav_format,sizeof(wav_format),1,my_wav); 00332 printf("%d block align\n",wav_format.block_align); 00333 printf(" %d channels\n",wav_format.num_channels); 00334 00335 00336 fseek(my_wav, 36, SEEK_SET); 00337 fread(&wav_data.subchunk2_ID,4,1,my_wav); 00338 fseek(my_wav, 40, SEEK_SET); 00339 fread(&wav_data.subchunk2_size,4,1,my_wav); 00340 printf("DATA chunck\n"); 00341 printf(" %d subchunk 2 ID\n",wav_data.subchunk2_ID); 00342 printf(" %d subchunk 2 size\n",wav_data.subchunk2_size); 00343 i2c.frequency(100000); 00344 long j = 0; 00345 printf("set up the codec\n\r"); 00346 while(j <1000){ 00347 wm8731_configTEST(); 00348 j = j + 1; 00349 } 00350 //i2s audio data transfer code?? 00351 i2s.stereomono(I2S_STEREO); 00352 i2s.masterslave(I2S_MASTER);//MASTER definitely works! 00353 i2s.frequency(sample_freq); 00354 int yes = i2s.setup_ok(); 00355 pc.printf("Setup went ok?: %d\n", yes);//0 = ack, 1 = Nack*/ 00356 printf("can we get to this point? 1\n\r"); 00357 led3 = 1; 00358 //myled = 1; 00359 led2 = 1; 00360 printf("can we get to this point? 2\n\r"); 00361 00362 myled = 1; 00363 i2s.start(); 00364 //while (1) { 00365 fread(&wav_format,sizeof(wav_format),1,my_wav); 00366 printf("wav_format %d\n\r",wav_format); 00367 00368 fseek(my_wav,20,SEEK_SET); 00369 fread(&wav_format,sizeof(wav_format),1,my_wav); 00370 fseek(my_wav,36,SEEK_SET); 00371 fread(&wav_data,sizeof(wav_data),1,my_wav); 00372 int num_slices = wav_data.subchunk2_size/wav_format.block_align; 00373 printf("wav_data.subchunk2_size: %d\n\r",wav_data.subchunk2_size); 00374 printf("wav_format.block_align: %d\n\r",wav_format.block_align); 00375 printf("num_slices: %d\n\r",num_slices); 00376 printf("num_slices*wav_format.block_align %d\n\r",num_slices*wav_format.block_align); 00377 printf("wav_format.num_channels*wav_format.sig_bps/8: %d\n\r",wav_format.num_channels*wav_format.sig_bps/8); 00378 printf("chunk_size - sizeof(wav_format) %d\n\r",wav_data.subchunk2_size-sizeof(wav_format)); 00379 printf("sizeof(wav_format): %d\n\r",sizeof(wav_format)); 00380 printf("do we egt to this point:\n\r"); 00381 if (interrupt_condition == 1) 00382 { 00383 sampletick.attach(&isr,1.0/16000); //1/16000 00384 } 00385 slice_buf=(char *)malloc(wav_format.block_align); 00386 slice = 0; 00387 while(1){ 00388 00389 while(flag3 == 1) 00390 { 00391 //for (slice=0;slice<num_slices;slice+=1) 00392 while(slice<num_slices){ 00393 //t2.start(); 00394 fread(slice_buf,wav_format.block_align,1,my_wav);//THIS IS WHERE HE READS IN THE DATA, TO SLICE_BUF. BUT USES WAV_FORMAT.BLOCKALIGN AS HIS SIZE GUIDE 00395 //I do not understand why he is not "seeking" through the file first though... 00396 if (feof(my_wav)){ 00397 printf("Oops -- not enough slices in the wave file\n"); 00398 exit(1); 00399 } 00400 data_sptr=(short *)slice_buf; // 16 bit samples 00401 data_bptr=(unsigned char *)slice_buf; // 8 bit samples 00402 data_wptr=(int *)slice_buf; // 32 bit samples 00403 slice_value[1]=0; 00404 for (channel=0;channel<wav_format.num_channels;channel++) { 00405 switch (wav_format.sig_bps) { 00406 case 16: 00407 //int mybuffer[1]; 00408 //mybuffer[0] = data_sptr[channel];// - 32768; 00409 if(flag1 == 1) 00410 { 00411 Buffer1[place_hold1] = data_sptr[channel]; 00412 place_hold1 = place_hold1 + 1; 00413 if(place_hold1 == 8) 00414 { 00415 flag4 = 1; 00416 break; 00417 } 00418 00419 } 00420 else if(flag2 == 0) 00421 { 00422 Buffer2[place_hold2] = data_sptr[channel]; 00423 place_hold2 = place_hold2 + 1; 00424 if(place_hold2 == 8) 00425 { 00426 flag4 = 1; 00427 break; 00428 } 00429 00430 } 00431 00432 if(interrupt_condition==1) 00433 { 00434 00435 00436 } 00437 else 00438 { 00439 if(verbosity == 1) 00440 { 00441 t.start(); 00442 i2s.write(data_sptr,2); 00443 t.stop(); 00444 printf("The time taken was %f seconds\n", t.read()); 00445 t.reset(); 00446 } 00447 00448 else 00449 { 00450 00451 i2s.write(data_sptr,2); 00452 00453 } 00454 00455 if(sampling_freq == 48000) 00456 { 00457 wait_us(0.1); 00458 } 00459 else if(sampling_freq == 8000) 00460 { 00461 wait_us(2); 00462 } 00463 } 00464 00465 00466 00467 00468 00469 if (verbosity) 00470 printf("16 bit channel %d data=%d\n\r ",channel,data_sptr[channel]); 00471 slice_value[1]+=data_sptr[channel]; 00472 break; 00473 case 32: 00474 if (verbosity) 00475 printf("32 bit channel %d data=%d ",channel,data_wptr[channel]); 00476 slice_value[1]+=data_wptr[channel]; 00477 break; 00478 case 8: 00479 if (verbosity) 00480 printf("8 bit channel %d data=%d ",channel,(int)data_bptr[channel]); 00481 slice_value[1]+=data_bptr[channel]; 00482 break; 00483 } 00484 } 00485 if(flag4 == 1) 00486 { 00487 flag4 = 0; 00488 break; 00489 } 00490 slice_value[1]/=wav_format.num_channels; 00491 00492 // slice_value is now averaged. Next it needs to be scaled to an unsigned 16 bit value 00493 // with DC offset so it can be written to the DAC. 00494 switch (wav_format.sig_bps) { 00495 case 8: slice_value[1]<<=8; 00496 break; 00497 case 16: slice_value[1]+=32768; 00498 break; 00499 case 32: slice_value[1]>>=16; 00500 slice_value[1]+=32768; 00501 break; 00502 } 00503 if (verbosity) 00504 { 00505 printf("data_sptr data: %d \n\r",data_sptr); 00506 printf("slice_value data: %d \n\r",slice_value); 00507 } 00508 slice = slice + 1; 00509 //i2s.write(data_sptr,2); 00510 //t2.stop(); 00511 //printf("The time taken was %f seconds\n", t2.read()); 00512 //t2.reset(); 00513 } 00514 printf("we must have filled the buffer"); 00515 } 00516 } 00517 00518 00519 /* dac_data=(short unsigned)slice_value; 00520 if (verbosity) 00521 printf("sample %d wptr %d slice_value %d dac_data %u\n",slice,DAC_wptr,(int)slice_value,dac_data); 00522 DAC_fifo[DAC_wptr]=dac_data; 00523 DAC_wptr=(DAC_wptr+1) & 0xff; 00524 while (DAC_wptr==DAC_rptr) { 00525 } 00526 }*/ 00527 00528 00529 if(interrupt_condition == 1) 00530 { 00531 00532 sampletick.detach(); 00533 } 00534 00535 i2s.stop(); 00536 00537 fclose(my_wav); 00538 printf("File is now closed."); 00539 return 0; 00540 } 00541
Generated on Sun Jul 24 2022 02:28:00 by 1.7.2