-
Notifications
You must be signed in to change notification settings - Fork 192
Sample rate not ok? #3
Comments
Theory why the formula can be correct: Would be so cool if the IP blocks would be publicly documented, rather than having only an API available. An API does not fully respect the capabilities. |
Can confirm that the code in that section and the comments are completely wrong. There does seem to be a 160 MHz clock source, that gets divided twice by the BCK_DIV and CLKM_DIV values. And there should be no -1 when setting the register, either. The values are used directly by the hardware. (No idea what happens if you try to divide by zero!) The original code works only by pure chance. It seems the correct way to set the rate is indeed to find two divisors that divide 160 MHz down to 32 times your preferred sample rate. |
Any proper code would have to try and calculate (160000000+samplerate16)/(samplerate32), and then try to find two numbers, 1..63 and 2..63, whose product is as close as possible to this number. For instance, 8*13=104 works fairly well to get 48 kHz. Alternatively, make a table of dividers for common sample rates, and only allow those. |
For a more precies samplerate it would be possible to use an I2S codec or I2S DAC, that acts as i2s master. This would require an i2c communication to setup the codec properly each time i2sSetRate() is called. As there is no asynchronous sample rate conversion done in the current setup ("only" skipping/doubling of samples) this would give better quality audio, as skipping/doubling occurs less often. |
According to our engineers: It will be added into the documentation, and I'll change the code accordingly. |
Fixed in 75cd867 |
What actually happens if you set I2S_BITS_MOD to something other than 0? How does that look on the actual bus? |
From what I remember, the hardware will output extra low bits on the bus after the 16 bits for each channel have been sent out. Don't have a scope here so I can't check. |
In that case, your PWM and sigma-delta code will not work as expected with this update. |
I would say it will. The delta-sigma samples will be pushed together a bit and the average volume will be slightly lower, but because the changes will be above the sample rate anyway it shouldn't impact any signal below the nyquist frequency, apart from the decrease in volume. |
The function i2sSetRate in i2s_freertos.c did not work properly. When measuring the i2s wordselect frequency with then one, the function actually calculated (variable bestfreq), there was quite a deviation.
The accoustic effect was a change of sound-pitch.
The divider "calculation" in the below fix is not the most elegant one, but at least I think I identified the real formula for the word select formula (see code, line that begins with tstfreq=). The Base frequency is also 160 MHz (Independent on CPU speed setting).
Cannot commit the fix myself. So here the solution, which works for me.
Have also a second order sigma delta converter with over sampling ration of 64 working, delivering better sound quality (effectively 13.3 bit resolution, compared to 10 bits). E.g. speach does not sound that metallic anymore as before. Of course the noise on the IO pin itself will decrease the ENOB with respect to the ideal one.
So... here the sample rate fix code:
The text was updated successfully, but these errors were encountered: