pothosware / SoapyAirspy

Soapy SDR plugin for the Airspy
https://github.com/pothosware/SoapyAirspy/wiki
MIT License
25 stars 13 forks source link

First readStream contains invalid samples #12

Closed swanepoeljan closed 7 years ago

swanepoeljan commented 7 years ago

Thanks for this very interesting project!

I have been playing with Soapy and an Airspy when I noticed that the FFTs on my first samples did not always came out as expected. Looking closer I noticed that the 1st few complex samples always contained some 0s and from thereon on never again. This seems a bit strange and almost like either the first buffer has some wrong data in it or I am reading it wrong. Hopefully this is something I am doing wrong.

I allocate the buffers as such:

    vector<vector<char>> buffMem(1, vector<char>(SoapySDR::formatToSize("CF32") * mtu));
    vector<void *> buffs(1);
    for (size_t i = 0; i < 1; i++) buffs[i] = buffMem[i].data();
    int flags(0);
    long long timeNs(0);
    vector<vector<float>> sampleBuff(5 * 2048, vector<float>(2));       // Holds the IQ samples

then read a couple of sample with:

    for (int l = 0; l < 4; l++)
    {
        // Read stream
        int elementsRead = device->readStream(st, buffs.data(), mtu, flags, timeNs);

        cout << elementsRead * SoapySDR::formatToSize("CF32") << " bytes have been read. Flags = " << flags << endl;

        for (int i = 0; i < buffMem[0].capacity(); i += SoapySDR::formatToSize("CF32"))
        {
            deciCnt++;

            if (((i + 8) <= buffMem[0].capacity()) && deciCnt == 1)
            {
                // Bytes packed back into floats
                float ival;
                float qval;
                unsigned char ci[] = { buffMem[0][i + 0], buffMem[0][i + 1], buffMem[0][i + 2], buffMem[0][i + 3] };
                unsigned char cq[] = { buffMem[0][i + 4], buffMem[0][i + 5], buffMem[0][i + 6], buffMem[0][i + 7] };
                memcpy(&qval, &cq, sizeof(qval));
                memcpy(&ival, &ci, sizeof(ival));

                // Store the IQ values
                sampleBuff[sampleCount][0] = ival;
                sampleBuff[sampleCount][1] = qval;
                sampleCount++;

                deciCnt = 0;

            }
        }
    }

I am reading 2048 (MTU) elements at a time.

Output of the first few samples

0   9.75201e-007    0
1   -1.63161e-006   0
2   2.91294e-006    0
3   -5.7514e-006    0
4   1.00109e-005    0
5   -1.65721e-005   0
6   2.5934e-005 0
7   -4.02493e-005   0
8   6.21305e-005    0
9   -9.65394e-005   0
10  0.000161523 0
11  -0.000401581    0
12  -0.000173937    -0.000727539
13  -0.000135679    0.000232104
14  0.000481409 -0.000474067
15  -0.00017729 0.000708774`
...

Any idea what could be the cause of this?

As a side question is there some builtin byte packing function or is this pretty much the way everyone else also do it?

touil commented 7 years ago

The IQ conversion routine in libairspy has a delay of 12 samples.

swanepoeljan commented 7 years ago

Ah okay, that is an easy fix for me then. Thanks!