Urgent.
Dear friends,
I am presently test running the McASP program of Starterware 1.x.x.3 on my OMAPL138 EVM. I need to change the sampling frequency to 8192 Hz from 8000Hz.
Can I get Fs= 8192 Hz instead of 8000Hz using the formula given below
fs = (PLL_IN * [pllJval.pllDval] * pllRval) /(2048 * pllPval). Where PLL_IN = 24576 kHz ..
If possible, how to calculate the values of pllJval, pllDval, pllRval, pllPval to obtain 8192Hz.
Thanks in advance.
Regards,
Mahesh
Mahesh,
Try this combination:
unsigned char fs = 0x44u; unsigned char ref = 0x0Au; unsigned char pllPval = 4u; unsigned char pllRval = 1u; unsigned char pllJval = 8u; unsigned short pllDval = 1920u;
Sujith.
Dear Sujit,
Thanks for the fast response. Need some more help in this. There is no audio output this time with the above settings.
// file : mcaspPlayBk.c
AIC31SampleRateConfig(SOC_I2C_0_REGS, AIC31_MODE_BOTH, (8192u)); // passing 8192 Hz as argument.
// file : aic31.c
void AIC31SampleRateConfig(unsigned int baseAddr, unsigned int mode, unsigned int sampleRate){ /* Original combination by Starterware * unsigned char fs; unsigned char ref = 0x0Au; unsigned char temp; unsigned char pllPval = 4u; unsigned char pllRval = 1u; unsigned char pllJval = 16u; unsigned short pllDval = 0u; */ /* Modified lines for 8192 Hz on 19 April*/ //unsigned char fs = 0x44u; unsigned char fs; unsigned char ref = 0x0Au; unsigned char pllPval = 4u; unsigned char pllRval = 1u; unsigned char pllJval = 8u; unsigned short pllDval = 1920u; unsigned char temp; /* Select the configuration for the given sampling rate */ switch(sampleRate) { case 8000: fs = 0xAAu; break; case 8192: // lines added extra to get 8192 Hz sampling frequency fs = 0x44u; break; case 11025: fs = 0x66u; ref = 0x8Au; pllJval = 14u; pllDval = 7000u; break; case 16000: fs = 0x44u; break; case 22050: fs = 0x22u; ref = 0x8Au; pllJval = 14u; pllDval = 7000u; break; case 24000: fs = 0x22u; break; case 32000: fs = 0x11u; break; case 44100: ref = 0x8Au; fs = 0x00u; pllJval = 14u; pllDval = 7000u; break; case 48000: fs = 0x00u; break; case 96000: ref = 0x6Au; fs = 0x00u; break; default: fs = 0x00u; break; } temp = (mode & fs); /* Set the sample Rate */ CodecRegWrite(baseAddr, AIC31_P0_REG2, temp); CodecRegWrite(baseAddr, AIC31_P0_REG3, 0x80 | pllPval); /* use PLL_CLK_IN as MCLK */ CodecRegWrite(baseAddr, AIC31_P0_REG102, 0x08); /* Use PLL DIV OUT as codec CLK IN */ CodecRegBitClr(baseAddr, AIC31_P0_REG101, 0x01); /* Select GPIO to output the divided PLL IN */ CodecRegWrite(baseAddr, AIC31_P0_REG98, 0x20); temp = (pllJval << 2); CodecRegWrite(baseAddr, AIC31_P0_REG4, temp); /* Configure the PLL divide registers */ CodecRegWrite(baseAddr, AIC31_P0_REG5, (pllDval >> 6) & 0xFF); CodecRegWrite(baseAddr, AIC31_P0_REG6, (pllDval & 0x3F) << 2); temp = pllRval; CodecRegWrite(baseAddr, AIC31_P0_REG11, temp); /* Enable the codec to be master for fs and bclk */ CodecRegWrite(baseAddr, AIC31_P0_REG8, 0xD0); CodecRegWrite(baseAddr, AIC31_P0_REG7, ref);}
There is no audio audio output at all. Could you pls find where exactly I am making mistake guide me to correct them.
regards,
Hi Mahesh,
When I refered to AIC31 data sheet, I could find fsref which can be selected as 48000 or 44100 (register 7). And these values can be divided by some values described for register 2. But 8192 seems cannot be achieved exactly as per the doc.
Anyway, could you please try the below combination so that we can achieve a frequency closer to 8192 and then we may tune the J/D values to make it proper ? You can probe the clock line and see what frequency it comes exactly.
unsigned char fs = 0x99u; // 44100/5.5 unsigned char ref = 0x8Au; unsigned char pllPval = 4u; unsigned char pllRval = 1u; unsigned char pllJval = 8u; unsigned short pllDval = 1920u;
sujith.
Dear Sujitji,
I tried some other few things and got it working for 8192Hz.
//file: mcaspPlayBk.c
#define SAMPLING_RATE (48000u)#define MODIFIED_SAMPLING_RATE (8192u)
AIC31SampleRateConfig(SOC_I2C_0_REGS, AIC31_MODE_BOTH, MODIFIED_SAMPLING_RATE);
// file :aic31.c
void AIC31SampleRateConfig(unsigned int baseAddr, unsigned int mode, unsigned int sampleRate){ unsigned char fs; unsigned char ref = 0x0Au; unsigned char temp; unsigned char pllPval = 4u; unsigned char pllRval = 1u; unsigned char pllJval = 16u; unsigned short pllDval = 0u; /* Select the configuration for the given sampling rate */ switch(sampleRate) { case 8000: fs = 0xAAu; break; case 8192 : fs = 0x44u; pllJval = 8u; pllDval = 1920u; break; case 11025: fs = 0x66u; ref = 0x8Au; pllJval = 14u; pllDval = 7000u; break; case 16000: fs = 0x44u; break; case 22050: fs = 0x22u; ref = 0x8Au; pllJval = 14u; pllDval = 7000u; break; case 24000: fs = 0x22u; break; case 32000: fs = 0x11u; break; case 44100: ref = 0x8Au; fs = 0x00u; pllJval = 14u; pllDval = 7000u; break; case 48000: fs = 0x00u; break; case 96000: ref = 0x6Au; fs = 0x00u; break; default: fs = 0x00u; break; } temp = (mode & fs); /* Set the sample Rate */ CodecRegWrite(baseAddr, AIC31_P0_REG2, temp); CodecRegWrite(baseAddr, AIC31_P0_REG3, 0x80 | pllPval); /* use PLL_CLK_IN as MCLK */ CodecRegWrite(baseAddr, AIC31_P0_REG102, 0x08); /* Use PLL DIV OUT as codec CLK IN */ CodecRegBitClr(baseAddr, AIC31_P0_REG101, 0x01); /* Select GPIO to output the divided PLL IN */ CodecRegWrite(baseAddr, AIC31_P0_REG98, 0x20); temp = (pllJval << 2); CodecRegWrite(baseAddr, AIC31_P0_REG4, temp); /* Configure the PLL divide registers */ CodecRegWrite(baseAddr, AIC31_P0_REG5, (pllDval >> 6) & 0xFF); CodecRegWrite(baseAddr, AIC31_P0_REG6, (pllDval & 0x3F) << 2); temp = pllRval; CodecRegWrite(baseAddr, AIC31_P0_REG11, temp); /* Enable the codec to be master for fs and bclk */ CodecRegWrite(baseAddr, AIC31_P0_REG8, 0xD0); CodecRegWrite(baseAddr, AIC31_P0_REG7, ref);}
Few more questions at last.
1. Can't I use a variable unsigned integer instead of #define macro to change sampling frequency? I need this because the sampling frequency will be coming as result of some data processing algorithm.
2. After getting the sound for 8192Hz, how to verify that it is correctly set to 8192Hz or the nearest possible value.? Is there any chance to see on oscilloscope?
3. Could you please give me exact steps in calculating ref,pllPval, pllRval,pllJval,pllDval value for desired sampling rate?
>>>> Yes you can. Only that, you need to know which all values will come, to put a case in the switch. Otherwise, J, D, P, R values have to be calculated dynamically (hmm.. might be difficult).
>>>>> Yes. The output of the codec fs line can be probed.
>>>>>The calculation is according to the equation given. Say, PLL_IN is 12000, and the output you need is 48000,
you have to tune the values pllPval, pllRval,pllJval,pllDval. May be you can fix P and R values, then find J.D to get the desired output.
Sujith
The aic31 doc give formula for Fsref and the starterware program gives formula for Fs.
aic31.doc:
When the PLL is enabled,FSref = (PLLCLK_IN × K × R) / (2048 × P), whereP = 1, 2, 3,…, 8R = 1, 2, …, 16K = J.DJ = 1, 2, 3, …, 63D = 0000, 0001, 0002, 0003, …, 9998, 9999PLLCLK_IN can be MCLK or BCLK, selected by register 102, bits D5-D4
aic31.c:
fs = (PLL_IN * [pllJval.pllDval] * pllRval) /(2048 * pllPval).
Where PLL_IN = 24576 kHz
I use the later one , with
PLL_IN=24576000; R=1, P=4.
I get K=[J.D]=2.7306.
I am confused a little bit, could pls tell me the significance of setting values for fs and ref in the aic31.c file and relate them to doc.
Sorry, I do not find any pin with name Fs to observe the sampling frequency but there are some ones with names: MCLK, BCLK, WCLK. Which is to be observed?
You can observe WCLK. I hope that is word clock. Anyway, observe BCLK too.
Today it is not possible to observe the signal since the probes are here right now. Mean while could you please help in interpreting the fs = 0x44u; and ref = 0x0Au; in aic31.c . (0x44u = 16*4+4=68, 0x0a=10).
I have a related question. After changing the sampling rate I wanted to see the samples on the Graphs (amplitude vs. sample number, and amplitude vs seconds/microseconds). This may give an idea of sampling frequency.
The following code in the original program copies received buffers in to transmit buffers.
/* Copy the buffer */
memcpy( (void *)txBufPtr[lastSentTxBuf], (void *)rxBufPtr[lastFullRxBuf], AUDIO_BUF_SIZE);
But I want to access the audio data available in rxBufPtr[NUM_BUF] on sample-by-sample basis, from all the received buffers, convert each sample to preferably float/double, copy each float/double sample into an array using for loop. When I get data for 0.25 seconds, I process them to find Ts and display waveform on the time and frequency graphs.
// my declerations
float iSample;
float *psample;
unsigned char pbyte[2];
float arrSample[NUM_SAMPLES_PER_AUDIO_BUF];
//The following code seems not working
for (j=0; j < AUDIO_BUF_SIZE/2; j++){
pbyte[0]= rxBuf0[2*j];
pbyte[1]= rxBuf0[2*j+1];
psample = (float *) pbyte; // convert pointer to unsigned char array (two byte wide) to pointer to float
iSample = *psample; // get float value
printf("%f",iSample);
// todo: store these iSample values in arrSample;
}
In the above code, I assumed that Starterware is taking 16-bit word length.
I get only 0.000 in the iSample when printed onto the console using printf("%f") or printf("%g");
How to get individual samples in to iSample?
Can any body please respond to the above please.
There is no option for probing ?
Anyway, it is possible to read the stored values from the buffer (I couldnt understand the piece of code :(), but how are you going to calculate the sampling frequency from the stored samples ?
Regards
I defer the probe option until I get proper probes back from other lab. This is week end here. Please have re-look at the code. I am not sure this is correct way.
Mean while , I try with code. My idea is to generate a single frequency sine wave in MATLAB and play it with desired sampling frequency using wavplay() function. Connect the Line-out port of my host PC to line-in port of OMAP-L138 evm kit. Acquire the audio using McASP.c project of StarterWare. I know how many samples are going to be there in a single cycle. For this I need to read the stored samples in float/double type array and plot. Optionally, find FFT and store the FFT amplitude and frequency indexes into harddisk using fprintf() for further plotting in MATLAB to verify the spectrum.
I have already written FFT program to do the optioanl part in off-lie using some DSPLIB functions. What I need is to read the audio values stored in rxBuf0, rxBuf1, and rxBuf2.
Please reply soon,.
Is there anybody attending this forum today. Could you please suggest me how to get audio samples into my own float array for manipulation or display.
Are you there . I am still looking for the solution.