pothosware / SoapySDRPlay2

Soapy SDR plugin for SDRPlay
MIT License
51 stars 11 forks source link

Sample rate and decimation #49

Closed frspin closed 4 years ago

frspin commented 5 years ago

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

frspin commented 5 years ago

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

SDRplay commented 5 years ago

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.

frspin commented 5 years ago

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

SDRplay commented 5 years ago

min sample rate 200k * 8 = 1.6 MHz - that will not work

SDRplay commented 5 years ago

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.

SDRplay commented 5 years ago

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

SDRplay commented 5 years ago

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

frspin commented 5 years ago

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

SDRplay commented 5 years ago

now that I've looked at the code, 250k IS currently the lowest sample rate that will work correctly.

frspin commented 5 years ago

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

SDRplay commented 4 years ago

Code added to the api3 branch