bladeRF xA9 - receiving IQ samples in <double,double> format
Posted: Tue Jul 11, 2023 2:07 am
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:
inside:
When
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.
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?
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;
}
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));
}
}
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.