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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wolfson_3_wav.cpp Source File

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