Sample rate and decimation
frspin opened this issue · 11 comments
I am giving a try to beta version of linhpsdr, now supporting SoapySDR, with my SDRPlay.
Sample rate required by linhpsdr, for WDSP library, is 1536000. WDSP library require input sample rate as a power of 2 and also a power of 2 for internal decimation. So input sample rate is fixed to 1536000 by program, internal DSP sample rate is fixed to 96000 (1536000/16) and audio sample rate is fixed to 48000 (96000/2)
But there is no possibility to obtain this sample rate with SoapySDRPlay in Zero_IF mode.
As I can see in code, sample rate from 200000 to 500000 are obtained using 2000000/8,
sample rate from 500000 to 100000 are obtained using 2000000/4 and sample rate from 1000000 to 2000000 using 2000000/2. Sample rate greater than 2000000 don't use decimation
So, if I set sample rate as 1536000 I obtain a real sample rate of 1000000.
Why I can not define decimation directly? I can define a sample rate of 3072000 and a decimation of 2 but actual SoapySDRPlay return a sample rate of 3072000
Regards
Franco Spinelli
IW2DHW
I have done this mods to Setting.cpp:
`
uint32_t SoapySDRPlay::getInputSampleRateAndDecimation(uint32_t rate, unsigned int *decM,
.........
else if (ifMode == mir_sdr_IF_Zero)
{
//if ((rate >= 200000) && (rate < 500000)) { *decM = 8; *decEnable = 1; return 2000000; }
//else if ((rate >= 500000) && (rate < 1000000)) { *decM = 4; *decEnable = 1; return 2000000; }
//else if ((rate >= 1000000) && (rate < 2000000)) { *decM = 2; *decEnable = 1; return 2000000; }
if ((rate >= 200000) && (rate < 500000)) { *decM = 8; *decEnable = 1; return rate * 8; }
else if ((rate >= 500000) && (rate < 1000000)) { *decM = 4; *decEnable = 1; return rate * 4; }
else if ((rate >= 1000000) && (rate < 2000000)) { *decM = 2; *decEnable = 1; return rate * 2; }
else { *decM = 1; *decEnable = 0; return rate; } }
`
And now I can obtain required sample rate.
Can be a modification in official code?
Regards
Franco Spinelli
IW2DHW
The lowest native sample rate that can be used is 2 MHz in either Low IF or Zero IF mode - I haven't had a chance to check the code, but if the return value is used in the StreamInit call, then this won't work if it's less than 2.0 - have you tested it? If so, please post the debug log.
Yes, I know that hardware sample rate can be 2000000 at minimum.
With original code if you is requiring 1536000 as sample rate you get 2000000 as hardware sample rate, a decimation of 2 and so 1000000 as software sample rate seen by application.
With suggested modification hardware sample rate is set to 2x1536000=3072000, decimation is set to 2 and so software sample rate seen by application is 1536000.
I am using this modification with linhpsdr and all is working
Regards
Franco Spinelli
IW2DHW
min sample rate 200k * 8 = 1.6 MHz - that will not work
if it works for you then that's great, but you can't put that back into the main application when there are cases that will not work.
you would need to change the min to 250k and hope that no one uses it below there - which is a dangerous assumption in my opinion
actually looking at the code, if you specify 200k today you wouldn't actually get 200k, so maybe changing the min to 250k (with a note saying that 200k was never possible in the first place) would be an acceptable change in my view. As long as you test the edge cases I'd be happy with that
You are correct. Required sample rate between 200k and 249k are incorrect, resulting in invalid hardware sample rate of 1600000.
Any other required sample rate give an hardware sample rate equal or greater than 2000000
500000x4=2000000 and 1000000x2=2000000
So the only exception is for 200k
If you think that limiting lower sample rate to 250k can be acceptable, i think that obtaining requested sample rate and not, as now, a fixed value (250k, 500k or 1000k), can be an improvement.
Regards
Franco Spinelli
IW2DHW
now that I've looked at the code, 250k IS currently the lowest sample rate that will work correctly.
Inserting another test and a new decimation factor of 16 we can go down to 125k.
New test become:
if ((rate >= 125000) && (rate < 250000)) { *decM = 16; *decEnable = 1; return rate * 16; } else if ((rate >= 250000) && (rate < 500000)) { *decM = 8; *decEnable = 1; return rate * 8; } else if ((rate >= 500000) && (rate < 1000000)) { *decM = 4; *decEnable = 1; return rate * 4; } else if ((rate >= 1000000) && (rate < 2000000)) { *decM = 2; *decEnable = 1; return rate * 2; } else { *decM = 1; *decEnable = 0; return rate; }
If this code is acceptable, can you insert in Github?
Regards
Franco Spinelli
IW2DHW
Code added to the api3 branch