pothosware / SoapyPlutoSDR

Soapy SDR plugin for PlutoSDR
https://github.com/pothosware/SoapyPlutoSDR/wiki
GNU Lesser General Public License v2.1
53 stars 22 forks source link

Add CS12 support #19

Closed zuckschwerdt closed 5 years ago

zuckschwerdt commented 5 years ago

Adds support for CS12. Only available with direct copy. Intended for 8 Msps (and lower) over SoapyRemote. Use CS8 with SoapyRemote for 10 Msps.

zuckschwerdt commented 5 years ago

This still needs some evaluation as the scale seems off.

vsonnier commented 5 years ago

Tested on localhost: Works similar, and using my own derivative from your work in the branch feat-cs12-nothread. How suprising. You original version though was sttuturing all the time, constantly giving return -1 for readStream on Cubic side.

For that samplerate of 6Msps, SoapySDRServer is steaming at 17Mbytes / s on output, while processing 25 MB / s on input. Good work !

The scale is off though. When using a signal generator (moRFeus) on a 147MHz signal, using a direct Pluto connection shows a signal in [-130 .. -33] dB on Cubic waterfall, whille the same signal is giving [-104 .. -7.2] db through SoapyRemote CS12. On the other hand, using CS16 the same way seems consistent with the direct connection. The scale you can input on the remote settings of Cubic doesn't seem to change much trying 2048 or 32768.

zuckschwerdt commented 5 years ago

I have now hacked rx_tools to support CS12 input and output and hardwired PlutoSDR (no fancy signal generators here, sadly) on the Pluto to: I: 0x0123 Q:0x0ABC (matching the 2048 hardware scale). This gives me a byte stream (capture file) on the client side of SoapyRemote of:

00000000  23 c1 ab 23 c1 ab 23 c1  ab 23 c1 ab 23 c1 ab 23

That seems to work to spec. Could it be that CubicSDR applies some scaling or swap endianess?

vsonnier commented 5 years ago

Cubic just requests CF32. SoapyRemote code shows that CONVERT_CF32_CS12 is basically CONVERT_CS16_CS12 with an applied scale. What scale is that ?

Maybe Clubic is not transmitting correctly the "Remote Scale" setting to the SoapySDRServer. I'll have a look.

zuckschwerdt commented 5 years ago

If the scale was off by 4 bit (32768 instead of 2048) we'd see 24dB – that matches your findings pretty well.

zuckschwerdt commented 5 years ago

Pushed the hack of rx_sdr here: https://github.com/zuckschwerdt/rx_tools/tree/feat-inputfmt if you need that for testing. Need to clean that up another day…

vsonnier commented 5 years ago

Mmm. Well I forgot how verbose the reading and writing of SoapySDR settings was in Cubic because of it's generality. I won't have time to look at this today (tonight), unfortunately.

vsonnier commented 5 years ago

If the scale was off by 4 bit (32768 instead of 2048) we'd see 24dB – that matches your findings pretty well.

By the way, the CS12 format being MSBit aligned, the right remote scale (when working) would be 32768, no ?

zuckschwerdt commented 5 years ago

My understanding is that all formats, except the native format should be at maximum scale. So CS12 (packed) is scale 2048, if you process that further to CS16 or get that auto-converted somehow(?) it should be scale 32768. If you think in fixed-point arithmetic then CS16 -> Q0.15 and CS8 -> Q0.7 are neatly normalized. But CS12 (unpacked) -> Q0.15 and not normalized to 1 but to 1/16 – better to scale (MSB align) that while unpacking.

vsonnier commented 5 years ago

My understanding is that all formats, except the native format should be at maximum scale. So CS12 (packed) is scale 2048...

From a user perspective you are right, but in practice the scale is 32768 for CS12 (see next §) because converting to CF32 is just implemented like CONVERT_CS16_CS12 plus the application of the scale.

@guruofquality Would it be better to re-align on LSBit ( >> 4) before applying the scale, so it would be more consistent to have indeed 2048 for CS12 at full scale ?

The scale you can input on the remote settings of Cubic doesn't seem to change much trying 2048 or 32768.

Turns out I was right, but the bug is not in CubicSDR but in SoapyRemote itself: Indeed SoapySDR::ArgInfoList SoapyRemoteDevice::getStreamArgsInfo(const int direction, const size_t channel) advertises the key remote:scale: https://github.com/pothosware/SoapyRemote/blob/0a7cb585d3325d8211f2c82705c8783c4129a421/client/Streaming.cpp#L89 but expects remote:scalar: https://github.com/pothosware/SoapyRemote/blob/0a7cb585d3325d8211f2c82705c8783c4129a421/client/Streaming.cpp#L191

Since it cannot find the key, the applied scale is a default computed one.

Testing a quick fix in SoapySDR::ArgInfoList SoapyRemoteDevice::getStreamArgsInfo I made the scale indeed work. The right one is indeed 32758, because:

zuckschwerdt commented 5 years ago

I actually found the bug. https://github.com/pothosware/SoapyRemote/blob/master/client/ClientStreamData.cpp#L63 uses the scaleFactor from the remote stream, which is 2048. But the CS12 is converted to CS16 at full scale (32768) then converted to CF32. The float now are not [-1; 1] but rather [-16; 16] PR coming shortly.

zuckschwerdt commented 5 years ago

Oh :) We had the same conclusion there ;)

guruofquality commented 5 years ago

@guruofquality Would it be better to re-align on LSBit ( >> 4) before applying the scale, so it would be more consistent to have indeed 2048 for CS12 at full scale ?

I agree that this is confusing and I'm not sure what the intent was. This converter has more gain. I think its best to adjust he scale factor, and eventually soapyremote and others will be switched over to the converter functions in SoapySDR itself (so these things stop getting duplicated everywhere). Thats a good time to switch it back i guess.

zuckschwerdt commented 5 years ago

We would still need to put the 12 bits at MSB, then shift them down to get a sign extend. That seemed a bit too much bit-twiddeling, so I propose to account for the extra scale factor of 16 in the already existing scale multiplication. The PR also has a note of warning to what is happening there ;)

zuckschwerdt commented 5 years ago

@vsonnier can you reset/rebase #14 and put the feat-cs12-nothread changes there? Then we can test that last step and finalize it.