Closed antonblanchard closed 4 years ago
I haven't found an example of using ConverterRegistry anywhere, but here is an attempt to add it to the AirspyHF driver. Thoughts?
I tested this by dumping various sample formats for a local WBFM station and verifying I could demodulate it in gqrx:
# CF32
rx_sdr -f 105.7M -s 768000 -I CF32 -F CF32 test-cf32.out & sleep 10 && killall rx_sdr
cp test-cf32.out test-cf32-processed.out
# CS16
rx_sdr -f 105.7M -s 768000 -I CS16 -F CS16 test-cs16.out & sleep 10 && killall rx_sdr
sox -t raw -e signed-integer -b 16 -c 2 -r 768000 test-cs16.out -t raw -e floating-point -b 32 -c 2 -r 768000 test-cs16-processed.out
# CS8
rx_sdr -f 105.7M -s 768000 -I CS8 -F CS8 test-cs8.out & sleep 10 && killall rx_sdr
sox -t raw -e signed-integer -b 8 -c 2 -r 768000 test-cs8.out -t raw -e floating-point -b 32 -c 2 -r 768000 test-cs8-processed.out
# CU8
rx_sdr -f 105.7M -s 768000 -I CU8 -F CU8 test-cu8.out & sleep 10 && killall rx_sdr
sox -t raw -e unsigned-integer -b 8 -c 2 -r 768000 test-cu8.out -t raw -e floating-point -b 32 -c 2 -r 768000 test-cu8-processed.out
I'm not sure I follow. The default CF32 to CS16 converter does scale:
const uint16_t S16_FULL_SCALE = uint16_t(1<<15);
...
inline int16_t F32toS16(float from){
return int16_t(from * S16_FULL_SCALE);
}
...
// CF32 <> CS16
static void genericCF32toCS16(const void *srcBuff, void *dstBuff, const size_t numElems, const double scaler)
{
const size_t elemDepth = 2;
auto *src = (float*)srcBuff;
auto *dst = (int16_t*)dstBuff;
for (size_t i = 0; i < numElems*elemDepth; i++)
{
dst[i] = SoapySDR::F32toS16(src[i] * scaler);
}
}
So full scale CF32 (1.0) should map to full scale CS16 (2^15). Actually that makes me wonder if we have a corner case in the converter. If the device can return 1.0 that will map to -32768 for this specific case. Very unlikely I know.
your right, scaling looks good nevermind.
If the device can return 1.0 that will map to -32768 for this specific case. Very unlikely I know.
We made a decision to map floating point and fixed point values with a linear symmetric scaling. Which means the floating point range is just like the fixed point range, so you can have -1.0 inclusive, but you cant have 1.0 (which is exclusive). But you know, its probably one of those debatable trade off things just like rounding modes.
@guruofquality thanks for the explanation, that makes sense.
The SoapyAirspyHF driver only supports CF32 samples. The ConverterRegistry gives us CS16, CS8, CU16 and CU8.