bladeRF xA9 - receiving IQ samples in <double,double> format

Having issues with the site, hardware, source code, or any other issues?
Post Reply
waffle
Posts: 1
Joined: Tue Jul 11, 2023 1:56 am

bladeRF xA9 - receiving IQ samples in <double,double> format

Post by waffle »

Hello, I am using bladeRF 2.0 micro xA9 with libbladeRF C API.

Let's say I want to record two seconds at 8Mhz sample rate.
That means I am interested in receiving 2*8M = 16M IQ samples.

I divide the desired buffer into:
__nbuffers = 7813 // number of buffers
__bufsize = 2048 // number of samples in each buffer (number of complex samples, so each sample consist of both I and Q)

Hence, I expect to read a total of 16001024 IQ samples (32b), which means 16001024 * 2 = 32002048 int16_t (16b).

I use the function: bladerf_sync_rx
in the format: BLADERF_FORMAT_SC16_Q11
for channel: BLADERF_CHANNEL_RX(0) -- means RX1

With each call to the function, I receive an array of the size __bufsize*2.

I would like to convert the units from int16_t to double for I and double for Q.
That is, I would like to have an array in which each cell is an IQ sample of size 128bits.

1. I searched online and concluded that I have to divide each int16_t by a number that is derived by the max resolution of the ADC/DAC - which means divide by 2048. Is that the correct number to divide in order for convert the ints to doubles?

Secondly, when using:

Code: Select all

       status = bladerf_sync_rx(__dev, __16icbuf + i * __bufsize * 2, __bufsize, &meta, timeout_ms); // sample len or * 2?
inside:

Code: Select all

/* Receive samples and do work on them */
    for (i = 0; i < __nbuffers && status == 0; i++) {
        status = bladerf_sync_rx(__dev, __16icbuf + i * __bufsize * 2, __bufsize, &meta, timeout_ms); // sample len or * 2?
        if (status != 0) {
            fprintf(stderr, "RX \"now\" failed: %s\n\n",
                    bladerf_strerror(status));
        } else if (meta.status & BLADERF_META_STATUS_OVERRUN) {
            fprintf(stderr, "Overrun detected. %u valid samples were read.\n",
                    meta.actual_count);
        } else {
            // printf("RX'd %u samples at t=0x%016" PRIx64 "\n", meta.actual_count,
            //        meta.timestamp);

            fflush(stdout);
        }
    }

    // convert from int16_t to sample_t
    // output_items is complex (2x sample_t), so __bufsize is 2*(iq_samples length)
    if (__fmt == BLADERF_FORMAT_SC8_Q7 || __fmt == BLADERF_FORMAT_SC8_Q7_META) {
        volk_8i_s32f_convert_iqsamp_t(iq_samples, (int8_t*)__16icbuf, __bufsize * __nbuffers * 2);
    } else {
        volk_16i_s32f_convert_iqsamp_t(iq_samples, __16icbuf, __bufsize * __nbuffers * 2);
        std::cout << "Buffer converted" << std::endl;
    }
When

Code: Select all

    __16icbuf = (int16_t*)malloc(__bufsize * __nbuffers * 2 * sizeof(int16_t));

    std::vector<iqsamp_t> iq_samples_vec(__bufsize * __nbuffers);
    iqsamp_t *iq_samples = &iq_samples_vec->front();

void BLADERF_XA9_SDR::volk_16i_s32f_convert_iqsamp_t(iqsamp_t* output, const int16_t* input, size_t num_elements) {
    for (size_t i = 0; i < num_elements-1; i+=2) {
        output[i/2] = iqsamp_t(static_cast<sample_t>((input[i]) / 2048.0), static_cast<sample_t>((input[i+1]) / 2048.0));
    }
}
I get samples in form:
sample=(0.152418,-0.051783)
sample=(0.070835,0.062042)
sample=(-0.159257,-0.011724)
sample=(-0.173425,-0.033708)
sample=(-0.092819,0.132877)
sample=(-0.191988,-0.272106)

2. Does the third parameter in bladerf_sync_rx should be __bufsize or __bufsize * 2 ? which means should it be number of IQ samples or number of int16_t numbers?

Thanks in advance.
Post Reply