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
- Committer:
- roryhand
- Date:
- 2018-12-02
- Revision:
- 10:5048aebc394e
- Parent:
- 8:40f37287589a
File content as of revision 10:5048aebc394e:
// 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. //however if i use the write function with 4 arguments (as opposed to just 1 argument) then it doesnt work //only works with the 1 argument version!!! //THIS VERSION WORKED, CHANGED SOME THINGS, THEN CHANGED THEM BACK. NOW IT NO LONGER WORKS!!!! #include "mbed.h" #include "sinelookup.h" #include "I2S.h" #define sample_freq 8000 DigitalOut myled(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); Ticker sampletick; Timer t; Timer t2; #include "SDFileSystem.h" #include "WOLFSON_config.h" Serial pc(USBTX, USBRX); // tx, rx //FOR DEBUGGING PROGRAM USING GNU SCREEN DigitalOut cs(p8); I2S i2s(I2S_TRANSMIT,p5,p6,p7); I2C i2c(p9, p10); SDFileSystem sd(p11, p12, p13, p8, "sd"); // the new pinout that i am using typedef struct uFMT_STRUCT{ short comp_code; short num_channels; unsigned sample_rate; unsigned avg_Bps; short block_align; short sig_bps; } FMT_STRUCT; typedef struct uDATA_STRUCT { unsigned subchunk2_ID; unsigned subchunk2_size; char * data_buf; }DATA_STRUCT; short hello; int i = 0; int h = 0; short bufflen = 1; int buffer[1]; int AudioFormat, NumChannels, SampleRate, BitsPerSample ; char *slice_buf; short *data_sptr; unsigned char *data_bptr; int *data_wptr; unsigned channel; int newvar; long slice, num_slices; int verbosity = 0; int verbosity2 = 0; int interrupt_condition = 1; int sampling_freq = 8000; short Buffer1[8]; short Buffer2[8]; short place_hold1 = 0; short place_hold2 = 0; int flag1 = 1; int flag2 = 0; int flag3 = 1; int flag4 = 0; short value[1]; //long long slice_value; int slice_value[1]; FILE *my_wav; FMT_STRUCT wav_format; DATA_STRUCT wav_data; Ticker flipper; //test void flip() { led2 = !led2; } void isr() { //buffer[0] = (*data_sptr)>>1; //myled = 1; //int bufflen = sizeof(buffer); if(verbosity){ printf("buffer data: %d \n\r",buffer); printf("data_sptr data: %d",data_sptr); short value = Buffer1[0]; printf("value: %d",value); } //t.start(); //t.stop(); //printf("The time taken was %f seconds\n", t.read()); //t.reset(); //myled = 0; led2 = !led2; if(flag1 == 0) { //access double buffer pt1 value[0] = Buffer1[place_hold1]; i2s.write(value,1);//Send next PWM value to amp place_hold1 = place_hold1 + 1; if(place_hold1 == 8) { place_hold1 = 0; place_hold2 = 0; flag1 = 1; flag2 = 0; flag3 = 1; } if(verbosity2 == 1) { printf("value Buffer1: %d\n\r",value[0]); } } else if(flag2 == 0) { //access double buffer pt2 value[0] = Buffer1[place_hold2]; i2s.write(value,1);//Send next PWM value to amp place_hold2 = place_hold2 + 1; if(place_hold2 == 8) { place_hold1 = 0; place_hold2 = 0; flag1 = 0; flag2 = 1; flag3 = 1; } if(verbosity2 == 1) { printf("value Buffer2: %d\n\r",value[0]); } } } void wm8731_setup(int chip_addr, int addr, int cmd){ addr = addr << 1; addr = addr|((cmd >> 8 ))& 0x01;//mess around with order of operations cmd = cmd&0xFF; i2c.start(); i2c.write( chip_addr ); i2c.write( addr ); i2c.write( cmd ); i2c.stop(); } void wm8731_config(void){ wm8731_setup( WM8731_ADDRESS, WM8731_REG_RESET, _WM8731_RESET );//1 wm8731_setup( WM8731_ADDRESS, WM8731_REG_LLINE_IN, _WM8731_LEFT_LINEIN );//2 wm8731_setup( WM8731_ADDRESS, WM8731_REG_RLINE_IN, _WM8731_RIGHT_LINEIN );//3 wm8731_setup( WM8731_ADDRESS, WM8731_REG_LHPHONE_OUT, _WM8731_LEFT_HP );//4 wm8731_setup( WM8731_ADDRESS, WM8731_REG_RHPHONE_OUT, _WM8731_RIGHT_HP );//5 wm8731_setup( WM8731_ADDRESS, WM8731_REG_ANALOG_PATH, _WM8731_ANALOGAUDIO );//6 wm8731_setup( WM8731_ADDRESS, WM8731_REG_DIGITAL_PATH, _WM8731_DIGITALAUDIO );//7 wm8731_setup( WM8731_ADDRESS, WM8731_REG_PDOWN_CTRL, _WM8731_POWER );//8 wm8731_setup( WM8731_ADDRESS, WM8731_REG_DIGITAL_IF, _WM8731_DAIF );//9 wm8731_setup( WM8731_ADDRESS, WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING );//10 } void wm8731_configTEST(void){ int addr = WM8731_REG_RESET; int cmd = _WM8731_RESET; addr = addr << 1; addr = addr|((cmd >> 8 ))& 0x01;//mess around with order of operations cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS ); i2c.write( addr ); i2c.write( cmd ); i2c.stop(); addr = WM8731_REG_LLINE_IN; cmd = _WM8731_LEFT_LINEIN; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//take Fergus' suggestion and declare these to known values EARLIER in program i2c.write( addr ); i2c.write( cmd ); i2c.stop(); addr = WM8731_REG_RLINE_IN; cmd = _WM8731_RIGHT_LINEIN; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//take Fergus' suggestion and declare these to known values EARLIER in program i2c.write( addr ); i2c.write( cmd ); i2c.stop(); //4 addr = WM8731_REG_LHPHONE_OUT; cmd = _WM8731_LEFT_HP; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS ); i2c.write( addr );//WM8731_REG_LHPHONE_OUT, _WM8731_LEFT_HP i2c.write(cmd); i2c.stop(); //5 addr = WM8731_REG_RHPHONE_OUT; cmd = _WM8731_RIGHT_HP; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//WM8731_REG_RHPHONE_OUT, _WM8731_RIGHT_HP i2c.write( addr ); i2c.write( cmd ); i2c.stop(); //6 addr = WM8731_REG_ANALOG_PATH; cmd = _WM8731_ANALOGAUDIO; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//WM8731_REG_ANALOG_PATH, _WM8731_ANALOGAUDIO i2c.write( addr ); i2c.write( cmd ); i2c.stop(); //7 addr = WM8731_REG_DIGITAL_PATH; cmd = _WM8731_DIGITALAUDIO; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//WM8731_REG_DIGITAL_PATH, _WM8731_DIGITALAUDIO i2c.write( addr ); i2c.write( cmd ); i2c.stop(); //8 addr = WM8731_REG_PDOWN_CTRL; cmd = _WM8731_POWER; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//WM8731_REG_PDOWN_CTRL, _WM8731_POWER) i2c.write( addr ); i2c.write( cmd ); i2c.stop(); //9 addr = WM8731_REG_DIGITAL_IF; cmd = _WM8731_DAIF; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS ); i2c.write( addr );//WM8731_REG_DIGITAL_IF, _WM8731_DAIF i2c.write( cmd ); i2c.stop(); //10 addr = WM8731_REG_SAMPLING_CTRL; cmd = _WM8731_SAMPLING; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING i2c.write( addr ); i2c.write( cmd ); i2c.stop(); //11 addr = WM8731_REG_ACTIVE_CTRL; cmd = _WM8731_ACTIVATE; addr = addr << 1; addr = addr|((cmd >> 8 )) & 0x01; cmd = cmd&0xFF; i2c.start(); i2c.write( WM8731_ADDRESS );//WM8731_REG_SAMPLING_CTRL, _WM8731_SAMPLING i2c.write( addr ); i2c.write( cmd );//there is also a deactive version!! i2c.stop(); } int main() { FMT_STRUCT wav_format; char data[2]; pc.printf("Beginning of program\n"); data[0] = 0x0F; data[1] = 0x00; FILE *my_wav; //my_wav = fopen("/sd/mydir/gp40.wav", "rb");//i think that it is "w" for write, "r" for read. //my_wav = fopen("/sd/mydir/gp40_48K.wav", "rb");//i think that it is "w" for write, "r" for read. //my_wav = fopen("/sd/mydir/gp40_48K_quieter.wav", "rb");//i think that it is "w" for write, "r" for read. //my_wav = fopen("/sd/mydir/gp40_8K.wav","rb"); my_wav = fopen("/sd/mydir/gp40_8K_2018.wav","rb"); //my_wav = fopen("/sd/mydir/emd_645.wav", "rb"); fseek(my_wav, 20, SEEK_SET); // set pointer to byte 20 fread(&AudioFormat, 2, 1, my_wav); // check file is PCM if (AudioFormat==0x01) { printf("Wav file is PCM data\n\r"); } else { printf("Wav file is not PCM data\n\r"); } fseek (my_wav,20,SEEK_SET); fread(&wav_format,sizeof(wav_format),1,my_wav); printf("%d block align\n",wav_format.block_align); printf(" %d channels\n",wav_format.num_channels); fseek(my_wav, 36, SEEK_SET); fread(&wav_data.subchunk2_ID,4,1,my_wav); fseek(my_wav, 40, SEEK_SET); fread(&wav_data.subchunk2_size,4,1,my_wav); printf("DATA chunck\n"); printf(" %d subchunk 2 ID\n",wav_data.subchunk2_ID); printf(" %d subchunk 2 size\n",wav_data.subchunk2_size); i2c.frequency(100000); long j = 0; printf("set up the codec\n\r"); while(j <1000){ wm8731_configTEST(); j = j + 1; } //i2s audio data transfer code?? i2s.stereomono(I2S_STEREO); i2s.masterslave(I2S_MASTER);//MASTER definitely works! i2s.frequency(sample_freq); int yes = i2s.setup_ok(); pc.printf("Setup went ok?: %d\n", yes);//0 = ack, 1 = Nack*/ printf("can we get to this point? 1\n\r"); led3 = 1; //myled = 1; led2 = 1; printf("can we get to this point? 2\n\r"); myled = 1; i2s.start(); //while (1) { fread(&wav_format,sizeof(wav_format),1,my_wav); printf("wav_format %d\n\r",wav_format); fseek(my_wav,20,SEEK_SET); fread(&wav_format,sizeof(wav_format),1,my_wav); fseek(my_wav,36,SEEK_SET); fread(&wav_data,sizeof(wav_data),1,my_wav); int num_slices = wav_data.subchunk2_size/wav_format.block_align; printf("wav_data.subchunk2_size: %d\n\r",wav_data.subchunk2_size); printf("wav_format.block_align: %d\n\r",wav_format.block_align); printf("num_slices: %d\n\r",num_slices); printf("num_slices*wav_format.block_align %d\n\r",num_slices*wav_format.block_align); printf("wav_format.num_channels*wav_format.sig_bps/8: %d\n\r",wav_format.num_channels*wav_format.sig_bps/8); printf("chunk_size - sizeof(wav_format) %d\n\r",wav_data.subchunk2_size-sizeof(wav_format)); printf("sizeof(wav_format): %d\n\r",sizeof(wav_format)); printf("do we egt to this point:\n\r"); if (interrupt_condition == 1) { sampletick.attach(&isr,1.0/16000); //1/16000 } slice_buf=(char *)malloc(wav_format.block_align); slice = 0; while(1){ while(flag3 == 1) { //for (slice=0;slice<num_slices;slice+=1) while(slice<num_slices){ //t2.start(); 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 //I do not understand why he is not "seeking" through the file first though... if (feof(my_wav)){ printf("Oops -- not enough slices in the wave file\n"); exit(1); } data_sptr=(short *)slice_buf; // 16 bit samples data_bptr=(unsigned char *)slice_buf; // 8 bit samples data_wptr=(int *)slice_buf; // 32 bit samples slice_value[1]=0; for (channel=0;channel<wav_format.num_channels;channel++) { switch (wav_format.sig_bps) { case 16: //int mybuffer[1]; //mybuffer[0] = data_sptr[channel];// - 32768; if(flag1 == 1) { Buffer1[place_hold1] = data_sptr[channel]; place_hold1 = place_hold1 + 1; if(place_hold1 == 8) { flag4 = 1; break; } } else if(flag2 == 0) { Buffer2[place_hold2] = data_sptr[channel]; place_hold2 = place_hold2 + 1; if(place_hold2 == 8) { flag4 = 1; break; } } if(interrupt_condition==1) { } else { if(verbosity == 1) { t.start(); i2s.write(data_sptr,2); t.stop(); printf("The time taken was %f seconds\n", t.read()); t.reset(); } else { i2s.write(data_sptr,2); } if(sampling_freq == 48000) { wait_us(0.1); } else if(sampling_freq == 8000) { wait_us(2); } } if (verbosity) printf("16 bit channel %d data=%d\n\r ",channel,data_sptr[channel]); slice_value[1]+=data_sptr[channel]; break; case 32: if (verbosity) printf("32 bit channel %d data=%d ",channel,data_wptr[channel]); slice_value[1]+=data_wptr[channel]; break; case 8: if (verbosity) printf("8 bit channel %d data=%d ",channel,(int)data_bptr[channel]); slice_value[1]+=data_bptr[channel]; break; } } if(flag4 == 1) { flag4 = 0; break; } slice_value[1]/=wav_format.num_channels; // slice_value is now averaged. Next it needs to be scaled to an unsigned 16 bit value // with DC offset so it can be written to the DAC. switch (wav_format.sig_bps) { case 8: slice_value[1]<<=8; break; case 16: slice_value[1]+=32768; break; case 32: slice_value[1]>>=16; slice_value[1]+=32768; break; } if (verbosity) { printf("data_sptr data: %d \n\r",data_sptr); printf("slice_value data: %d \n\r",slice_value); } slice = slice + 1; //i2s.write(data_sptr,2); //t2.stop(); //printf("The time taken was %f seconds\n", t2.read()); //t2.reset(); } printf("we must have filled the buffer"); } } /* dac_data=(short unsigned)slice_value; if (verbosity) printf("sample %d wptr %d slice_value %d dac_data %u\n",slice,DAC_wptr,(int)slice_value,dac_data); DAC_fifo[DAC_wptr]=dac_data; DAC_wptr=(DAC_wptr+1) & 0xff; while (DAC_wptr==DAC_rptr) { } }*/ if(interrupt_condition == 1) { sampletick.detach(); } i2s.stop(); fclose(my_wav); printf("File is now closed."); return 0; }