Irregularity in the XTRX spectrum

@ipse, @andrewback, @Zack

Hello!

There is a program that should perform a spectrum scan over the entire range of the XTRX SDR receiver (100 kHz - 3.8 GHz). Data is received at samplerate 75 MSPS:

изображение

изображение

The result is an uneven spectrum. It seems that the XTRX receiver is operating with an input filter bandwidth about of 35 MHz, though the filter is set to 75 MHz in the program.

Please tell me what are the nuances of setting the input filter, what do they depend on and can this be the reason of the unevenness?

For example, when scanning with the USRP B200, the result looks like this:
изображение
There are no gaps in the spectrum here.

I wrote a small program for the test. Which continuously receives samples from the XTRX, puts them into memory, and then writes the accumulated data to a PCM file.

When this file is played back, unevenness is again visible on the spectrum. (Figure below)
изображение

Below given the source code of the program that writes samples to a PCM file.
Could you look at the receiver setup. Maybe I’m setting something up wrong?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "xtrx_api.h"

double SAMPLERATE           = 75e6;
double ACTUAL_SAMPLERATE    = 0;
double CENTRAL_FREQ         = 200e6;
double BANDWIDTH            = SAMPLERATE * 1;
double GAIN                 = 20;
int	   LogLevel             = 3;

xtrx_dev* Device;


int main()
{
    const unsigned MAX_DEVS = 4;
    xtrx_device_info_t devices[MAX_DEVS];

    int result = xtrx_discovery(devices, MAX_DEVS);
    if( xtrx_discovery(devices, MAX_DEVS) <= 0 )
    {
        printf("\nDevices not found...");
        return 0;
    }
    printf("\nFound %d device(s)\n", result);


    result = xtrx_open(devices[0].uniqname, LogLevel | XTRX_O_RESET, &Device);
    if( result < 0 )
    {
        printf("\nDevice open error...");
    }
    
	// ============ setting the receiver ============
    result = xtrx_set_ref_clk(Device, 0, XTRX_CLKSRC_INT);
    if( result )
    {
        printf("\n'xtrx_set_ref_clk()' error...");
    }

    result = xtrx_set_samplerate(Device, 0, SAMPLERATE, 0, 0, NULL, NULL, NULL);
    if( result )
    {
        printf("\n'xtrx_set_samplerate()' error...");
    }

    result = xtrx_set_antenna(Device, XTRX_RX_AUTO);
    if( result )
    {
        printf("\n'xtrx_set_antenna()' error...");
    }

    result = xtrx_tune(Device, XTRX_TUNE_RX_FDD, CENTRAL_FREQ, NULL);
    if( result )
    {
        printf("\n'xtrx_tune()' error...");
    }

    result = xtrx_tune_rx_bandwidth(Device, XTRX_CH_AB, BANDWIDTH, NULL);
    if( result )
    {
        printf("\n'xtrx_tune_rx_bandwidth()' error...");
    }

    result = xtrx_set_gain(Device, XTRX_CH_AB, XTRX_RX_LNA_GAIN, 14, NULL);
    if( result )
    {
        printf("\n'xtrx_set_gain()' error...");
    }

    int READS_COUNT       = 70;
    int SAMPLE_SIZE       = 4;
    int SAMPLES_TO_READ   = 7077888;

    uint64_t sz = SAMPLE_SIZE * READS_COUNT;
    sz *= SAMPLES_TO_READ;

    char* samples_buffer = (char*)malloc(sz);
    if (!samples_buffer)
    {
        return 0;
    }

    char* stream_buffers[2];
    stream_buffers[0] = samples_buffer;

    xtrx_run_params_t params;
    params.dir              = XTRX_RX;
    params.nflags           = 0;
    params.rx_stream_start  = 0;
    params.rx.wfmt          = XTRX_WF_16;
    params.rx.hfmt          = XTRX_IQ_INT16;
    params.rx.chs           = XTRX_CH_AB;
    params.rx.paketsize     = 0;
    params.rx.flags         = XTRX_RSP_SISO_MODE;

    result = xtrx_run_ex(Device, &params);
    if( result )
    {
        printf("\n'xtrx_run_ex()' error...");
    }

	// ============ grabbing samples ============
    uint32_t samples_read = 0;
    int curr_read = 0;
    for(curr_read = 0; curr_read < READS_COUNT; curr_read++)
    {
        xtrx_recv_ex_info_t rx_info;
        rx_info.samples         = SAMPLES_TO_READ;
        rx_info.buffer_count    = 1;
        rx_info.buffers         = (void* const*)stream_buffers;
        rx_info.flags           = 0;

        result = xtrx_recv_sync_ex(Device, &rx_info);
        if( result > 0 )
        {
            printf("\n'xtrx_recv_sync_ex()' error...");
            break;
        }

        stream_buffers[0] += (rx_info.samples * SAMPLE_SIZE);
        samples_read += SAMPLES_TO_READ;
    }
	
	xtrx_stop(Device, XTRX_RX);
    xtrx_close(Device);

	// ============ writing samples to file ============
    const char* file_name = "200.000000MHz 75000.000000KHz.pcm";
    FILE *out_file;
    if((out_file = fopen(file_name, "wb+")) == nullptr)
    {
        fprintf(stderr, "File open error.\n");
        free(samples_buffer);
        exit(1);
    }

    size_t samples_written = fwrite(samples_buffer, SAMPLE_SIZE, samples_read, out_file);
    fclose(out_file);
	free(samples_buffer);

    if(samples_written != samples_read)
    {
        fprintf(stderr, "File write error.\n");
    }
    
    printf("\n\nFinished...");
    return 0;
}