SoapySDR Read Stream - Samples Lost

So we use Soapy APIs to implement basic radar. Specifically, we separate Transmitting and Receiving.

Followings are codes of them:

#define CONTIGUOUS_BUFF_TX_LENGTH (int) 2e5
#define BUFF_TX_LENGTH (size_t) 1e3
#define BUFF_RX_LENGTH (size_t) 1e3
#define STREAM_TIMEOUT_TX 3e6
#define STREAM_TIMEOUT_RX 3e6
#define ZERO_DELAY_SAMPLES 96

//Begin transmitting
    int txStreamStatus = 0, rxStreamStatus = 0;
    for(int i = 0; i < CONTIGUOUS_BUFF_TX_LENGTH / BUFF_TX_LENGTH; i++)
    {
        buffsTx[0] = bufferTx;
        txStreamStatus = SoapySDRDevice_writeStream(sdr, txStream, buffsTx, BUFF_TX_LENGTH, &flags, transmitTime, STREAM_TIMEOUT_TX);
        transmitTime += BUFF_TX_LENGTH / SAMPLE_RATE_TX * 1e9; //Begin next transmission immediately after this one finishes.
        bufferTx += BUFF_TX_LENGTH; //Move buffer pointer to the next section of the contiguous buffer to be transmitted.

        if(txStreamStatus != BUFF_TX_LENGTH)
        {
            printf("[TransmitReceive] Write stream failed: %d\n", txStreamStatus);
        }
    }
// //Begin receiving

    for(int i = 0; i < CONTIGUOUS_BUFF_RX_LENGTH / BUFF_RX_LENGTH; i++)

    {

        buffsRx[0] = bufferRx;

        rxStreamStatus = SoapySDRDevice_readStream(sdr, rxStream, buffsRx, BUFF_RX_LENGTH, &flags, &timestampRx, STREAM_TIMEOUT_RX);

        bufferRx += BUFF_RX_LENGTH; //Move buffer pointer to the next section of the contiguous buffer to be received.

       

        if(rxStreamStatus != BUFF_RX_LENGTH)

        {

            printf("[TransmitReceive] Samples captured: %d\n", rxStreamStatus);

            if(rxStreamStatus < 0)

            {

                printf("[TransmitReceive] Read stream failed. Error Code: %d\n", rxStreamStatus);

            }

           

            *firstSampleIndex = BUFF_RX_LENGTH - rxStreamStatus + ZERO_DELAY_SAMPLES;

        }

        if(rxStreamStatus < 0)  // Detect a failed chirp

        {

            printf("[TransmitReceive] Detected failed chirp! Filling buffer with zeros.\n");

            for(int j = 0; j < CONTIGUOUS_BUFF_RX_LENGTH; j++)

            {

                // contBufferRx[j] = 0*(1+I);

                contBufferRx[j].real = 0;

                contBufferRx[j].imag = 0;

            }

            break;  // Skip this chirp, move on to the next one.

        }

    }

So the flow is:

  • We set up stream first => SoapySDRStream* stream = SoapySDRDevice_setupStream(sdr, direction, SOAPY_SDR_CS16, NULL, 0, &args)
  • Once RX and TX stream are set, we put the samples in the buffer.
  • We then activate both the streams. => SoapySDRDevice_activateStream(sdr, txStream, 0, 0, 0) and SoapySDRDevice_activateStream(sdr, rxStream, flags, receiveTime, 0)

A part of the outputs is like this:

Started chirp code at time 8.742012 s
[TransmitReceive] Scheduled to transmit/receive a chirp at 9.025904 s
[TransmitReceive] Samples captured: 420
[SaveData] Saving data to file...
Finished chirp code at time 9.045836 s

The return value of SoapySDRDevice_readStream() is the number of elements read per buffer or error code. What I’m confused about, from receiving part of code:
if(rxStreamStatus != BUFF_RX_LENGTH)
why are some Samples lost?
Is this a bug where I could solve or just improve the lost rate?

What you are seeing depends upon the device and the system that you are using. With both the transmit and the receive, when you call writeStream/readStream it returns the number actually processed - if it is less than the number requested, you shift the buffers appropriately and do the read/write until all of the data has been processed. In universalSend, that is what the test -

       while(num2 > 0){
             ....

is about.

In universalReceive, the test -

	while(rec > 0){
                  ....

Is doing the same thing - making sure that all of the data has been progressed.

universalSend.cpp and universalReceive are found at -

It is not an error - that is how the routines work !