SDRPlusPlus
SDRPlusPlus copied to clipboard
u8 IQ file playback
(SDR++ v1.0.4) When I load a SDRSharp IQ recording (8 bit unsigned), the file plays with double speed. 20180516_233225Z_405300000Hz_IQ.wav.gz
Channels : 2
Sample Rate : 250000
Precision : 8-bit
Duration : 00:00:10.00 = 2500000 samples ~ 750 CDDA sectors
File Size : 5.00M
Bit Rate : 4.00M
Sample Encoding: 8-bit Unsigned Integer PCM
00000000: 5249 4646 644b 4c00 5741 5645 666d 7420 RIFFdKL.WAVEfmt
00000010: 1000 0000 0100 0200 90d0 0300 20a1 0700 ............ ...
00000020: 0200 0800 6461 7461 404b 4c00 7f80 7f80 ....data@KL.....
00000030: 7e7f 807f 8080 7f7f 807f 8080 8080 7f7f ~...............
...
Another SDRSharp (8 bit unsigned) recording with sample rate 1024000 shows the same and the signal is all over the place.
However if I convert to 16 bit signed samples, everything is fine.
Hello, Yes, only 16bit wav is currently supported
Is this the i16 to f32 conversion?
https://github.com/AlexandreRouma/SDRPlusPlus/blob/312c80b3557be29ef3d9f2d82f712a10ce762890/source_modules/file_source/src/main.cpp#L152
I could not find something like volk_8u_s32f_convert_32f(). Is there no 8 bit unsigned conversion in the volk library? What about rtl_sdr?
If I check the bits-per-sample and do (just a workaround for testing)
uint16_t bitDepth = _this->reader->getBitDepth();
if (bitDepth == 8) {
uint8_t* inBuf = new uint8_t[blockSize * 2];
while (true) {
_this->reader->readSamples(inBuf, blockSize * 2 * sizeof(uint8_t));
for (uint32_t n = 0; n < blockSize; n++) {
_this->stream.writeBuf[n].re = (inBuf[2*n] - 128) / 128.0f;
_this->stream.writeBuf[n].im = (inBuf[2*n+1] - 128) / 128.0f;
}
if (!_this->stream.swap(blockSize)) { break; };
}
delete[] inBuf;
}
else {
int16_t* inBuf = new int16_t[blockSize * 2];
while (true) {
_this->reader->readSamples(inBuf, blockSize * 2 * sizeof(int16_t));
volk_16i_s32f_convert_32f((float*)_this->stream.writeBuf, inBuf, 32768.0f, blockSize * 2);
if (!_this->stream.swap(blockSize)) { break; };
}
delete[] inBuf;
}
It works, but you have to stop and start again if you load a file with different bits/sample.
Also I don't really know the code, maybe I got the buffer sizes wrong.
As long as 8 bit unsigned is not supported, maybe a getBitDepth() check would prevent playing these files.
There is also floatWorker(), is this for reading float32 IQ files directly?
I tried the "float32 Mode" checkbox, stop and start the f32-IQ-file, 10 seconds nothing, then 10 seconds the signal. Then if it runs in a loop, the signal is sometimes inverted and sometime not. Perhaps it does not start at the right offset and I/Q are sometimes swapped? (There is also a mirror image.)
The "data" in the f32 file does not start at 0x24, it does not have chunk size 16 and WAVE_FORMAT_PCM=1, but chunk size 18 and WAVE_FORMAT_IEEE_FLOAT=3 and then there is additional non-PCM data.
If I cut it back, it works, but maybe sdrpp could just read until it finds "data" after the bits/sample, would be more flexible.
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
float32-example: 20180516_233225Z_405300000Hz_IQ_f32.wav.gz
00000000: 5249 4646 322d 3101 5741 5645 666d 7420 RIFF2-1.WAVEfmt
00000010: 1200 0000 0300 0200 90d0 0300 8084 1e00 ................
00000020: 0800 2000 0000 6661 6374 0400 0000 a025 .. ...fact.....%
00000030: 2600 6461 7461 002d 3101 0000 00bc 0000 &.data.-1.......
...
@AlexandreRouma I observed the following playback issue (v1.0.4): If I grab the filter window in order to change the filter size in FM, the playback speeds up until I release the left mouse button. (It does not happen if I have another VFO audio active.)
this is normal, the file source is not throttled, when the DSP worker is repeatedly stopped and started to change the taps of the filter, some data dropped thus causing the apparent "speed up"
grouping with #129, follow that issue instead