|
|
|
@ -14,9 +14,6 @@
|
|
|
|
|
// class static constants
|
|
|
|
|
const double RspDuo::MAX_FREQUENCY_NR = 2000000000;
|
|
|
|
|
const uint8_t RspDuo::DEF_DECIMATION_NR = 1;
|
|
|
|
|
const int RspDuo::DEF_WAIT_TIME_NR = 0; // default wait time before recording
|
|
|
|
|
const int RspDuo::DEF_CHUNK_TIME_NR = 0; // default chunk time of recording
|
|
|
|
|
const int RspDuo::MAX_RUN_TIME_NR = 86400; // max run time of recording
|
|
|
|
|
const int RspDuo::DEF_AGC_BANDWIDTH_NR = 50; // default agc bandwidth
|
|
|
|
|
const int RspDuo::MIN_AGC_SET_POINT_NR = -72; // min agc set point
|
|
|
|
|
const int RspDuo::DEF_AGC_SET_POINT_NR = -60; // default agc set point
|
|
|
|
@ -25,7 +22,6 @@ const int RspDuo::DEF_GAIN_REDUCTION_NR = 40; // default gain reduction
|
|
|
|
|
const int RspDuo::MAX_GAIN_REDUCTION_NR = 60; // max gain reduction
|
|
|
|
|
const int RspDuo::DEF_LNA_STATE_NR = 4; // default lna state
|
|
|
|
|
const int RspDuo::MAX_LNA_STATE_NR = 9; // max lna state
|
|
|
|
|
const int RspDuo::DEF_SAMPLE_FREQUENCY_NR = 6000000; // default sample frequency
|
|
|
|
|
const int RspDuo::DEF_SAMPLE_RATE_NR = 2000000; // default sample rate
|
|
|
|
|
|
|
|
|
|
// global variables (SDRPlay)
|
|
|
|
@ -37,23 +33,16 @@ sdrplay_api_CallbackFnsT cbFns;
|
|
|
|
|
sdrplay_api_RxChannelParamsT *chParams;
|
|
|
|
|
|
|
|
|
|
// global variables
|
|
|
|
|
//FILE *out_file_fp = NULL;
|
|
|
|
|
FILE *file_replay = NULL;
|
|
|
|
|
short *buffer_16_ar = NULL;
|
|
|
|
|
struct timeval current_tm = {0, 0};
|
|
|
|
|
struct timeval start_tm = {0, 0};
|
|
|
|
|
struct timeval chunk_tm = {0, 0};
|
|
|
|
|
struct timeval finish_tm = {0, 0};
|
|
|
|
|
uint32_t frames_nr = 0;
|
|
|
|
|
std::string file;
|
|
|
|
|
short max_a_nr = 0;
|
|
|
|
|
short max_b_nr = 0;
|
|
|
|
|
bool run_fg = true;
|
|
|
|
|
bool stats_fg = true;
|
|
|
|
|
bool write_fg = true;
|
|
|
|
|
bool *capture_fg;
|
|
|
|
|
std::ofstream* saveIqFileLocal;
|
|
|
|
|
int wait_time_nr = 2;
|
|
|
|
|
IqData *buffer1;
|
|
|
|
|
IqData *buffer2;
|
|
|
|
|
|
|
|
|
@ -64,17 +53,12 @@ RspDuo::RspDuo(std::string _type, uint32_t _fc, uint32_t _fs,
|
|
|
|
|
{
|
|
|
|
|
nDecimation = DEF_DECIMATION_NR;
|
|
|
|
|
usb_bulk_fg = false;
|
|
|
|
|
small_verbose_fg = false;
|
|
|
|
|
more_verbose_fg = false;
|
|
|
|
|
agc_bandwidth_nr = DEF_AGC_BANDWIDTH_NR;
|
|
|
|
|
agc_set_point_nr = DEF_AGC_SET_POINT_NR;
|
|
|
|
|
gain_reduction_nr = DEF_GAIN_REDUCTION_NR;
|
|
|
|
|
lna_state_nr = DEF_LNA_STATE_NR;
|
|
|
|
|
rf_notch_fg = false;
|
|
|
|
|
dab_notch_fg = false;
|
|
|
|
|
chunk_time_nr = DEF_CHUNK_TIME_NR;
|
|
|
|
|
|
|
|
|
|
//out_file_fp = saveIqFile;
|
|
|
|
|
capture_fg = saveIq;
|
|
|
|
|
saveIqFileLocal = &saveIqFile;
|
|
|
|
|
}
|
|
|
|
@ -90,7 +74,6 @@ void RspDuo::start()
|
|
|
|
|
void RspDuo::stop()
|
|
|
|
|
{
|
|
|
|
|
uninitialise_device();
|
|
|
|
|
finish();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RspDuo::process(IqData *_buffer1, IqData *_buffer2)
|
|
|
|
@ -103,13 +86,13 @@ void RspDuo::process(IqData *_buffer1, IqData *_buffer2)
|
|
|
|
|
// control loop
|
|
|
|
|
while (run_fg)
|
|
|
|
|
{
|
|
|
|
|
if (write_fg)
|
|
|
|
|
if (stats_fg)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Info - control_loop - frames_nr: %d max_a_nr: %d max_b_nr: %d\n", frames_nr, max_a_nr, max_b_nr);
|
|
|
|
|
std::cerr << "[RspDuo] frames_nr: " << frames_nr <<
|
|
|
|
|
" max_a_nr: " << max_a_nr << " max_b_nr: " << max_b_nr << std::endl;
|
|
|
|
|
max_a_nr = 0;
|
|
|
|
|
max_b_nr = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -129,141 +112,100 @@ void RspDuo::replay(IqData *_buffer1, IqData *_buffer2, std::string _file, bool
|
|
|
|
|
rv = fread(&q1, 1, sizeof(short), file_replay);
|
|
|
|
|
rv = fread(&i2, 1, sizeof(short), file_replay);
|
|
|
|
|
rv = fread(&q2, 1, sizeof(short), file_replay);
|
|
|
|
|
|
|
|
|
|
buffer1->lock();
|
|
|
|
|
buffer2->lock();
|
|
|
|
|
|
|
|
|
|
if (buffer1->get_length() < buffer1->get_n())
|
|
|
|
|
{
|
|
|
|
|
buffer1->push_back({(double)i1, (double)q1});
|
|
|
|
|
buffer2->push_back({(double)i2, (double)q2});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer1->unlock();
|
|
|
|
|
buffer2->unlock();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RspDuo::validate()
|
|
|
|
|
{
|
|
|
|
|
// validate decimation
|
|
|
|
|
if (this->nDecimation != 1 && this->nDecimation != 2 && this->nDecimation != 4 &&
|
|
|
|
|
this->nDecimation != 8 && this->nDecimation != 16 && this->nDecimation != 32)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - decimation must be in 1, 2, 4, 8, 16, 32\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
void RspDuo::validate() {
|
|
|
|
|
// validate decimation
|
|
|
|
|
if (nDecimation != 1 && nDecimation != 2 && nDecimation != 4 &&
|
|
|
|
|
nDecimation != 8 && nDecimation != 16 && nDecimation != 32) {
|
|
|
|
|
std::cerr << "Error: Decimation must be in 1, 2, 4, 8, 16, 32" << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// validate fc
|
|
|
|
|
if (this->fc < 1 || this->fc > MAX_FREQUENCY_NR)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - frequency must be between 1 and %.1f\n", MAX_FREQUENCY_NR);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
// validate fc
|
|
|
|
|
if (fc < 1 || fc > MAX_FREQUENCY_NR) {
|
|
|
|
|
std::cerr << "Error: Frequency must be between 1 and " << MAX_FREQUENCY_NR << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// validate agc
|
|
|
|
|
if (agc_bandwidth_nr != 0 && agc_bandwidth_nr != 5 && agc_bandwidth_nr != 50 && agc_bandwidth_nr != 100)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - agc bandwidth must be in 0, 5, 50, 100\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (agc_set_point_nr > 0 || agc_set_point_nr < MIN_AGC_SET_POINT_NR)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - agc set point must be between %d and 0\n", MIN_AGC_SET_POINT_NR);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
// validate agc
|
|
|
|
|
if (agc_bandwidth_nr != 0 && agc_bandwidth_nr != 5 && agc_bandwidth_nr != 50 && agc_bandwidth_nr != 100) {
|
|
|
|
|
std::cerr << "Error: AGC bandwidth must be in 0, 5, 50, 100" << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (agc_set_point_nr > 0 || agc_set_point_nr < MIN_AGC_SET_POINT_NR) {
|
|
|
|
|
std::cerr << "Error: AGC set point must be between " << MIN_AGC_SET_POINT_NR << " and 0" << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// validate LNA
|
|
|
|
|
if (gain_reduction_nr < MIN_GAIN_REDUCTION_NR || gain_reduction_nr > MAX_GAIN_REDUCTION_NR)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - gain reduction must be between %d and %d\n", MIN_GAIN_REDUCTION_NR, MAX_GAIN_REDUCTION_NR);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (lna_state_nr < 1 || lna_state_nr > MAX_LNA_STATE_NR)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - lna state must be between 1 and %d\n", MAX_LNA_STATE_NR);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
// validate LNA
|
|
|
|
|
if (gain_reduction_nr < MIN_GAIN_REDUCTION_NR || gain_reduction_nr > MAX_GAIN_REDUCTION_NR) {
|
|
|
|
|
std::cerr << "Error: Gain reduction must be between " << MIN_GAIN_REDUCTION_NR << " and " << MAX_GAIN_REDUCTION_NR << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (lna_state_nr < 1 || lna_state_nr > MAX_LNA_STATE_NR) {
|
|
|
|
|
std::cerr << "Error: LNA state must be between 1 and " << MAX_LNA_STATE_NR << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// validate notch filters
|
|
|
|
|
// validate notch filters
|
|
|
|
|
|
|
|
|
|
// validate wait/chunk
|
|
|
|
|
if (wait_time_nr < 0 || wait_time_nr > MAX_RUN_TIME_NR)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - wait time must be between 0 and %d\n", MAX_RUN_TIME_NR);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
if (chunk_time_nr < 0 || chunk_time_nr > MAX_RUN_TIME_NR)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - chunk time must be between 0 and %d\n", MAX_RUN_TIME_NR);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// validate the command line options - other
|
|
|
|
|
if (small_verbose_fg && more_verbose_fg)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - read_command_line - use only one of -v/-V\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// print them out
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
fprintf(stderr, "fc (Hz) : %d\n", this->fc);
|
|
|
|
|
fprintf(stderr, "file : %s\n", file.c_str());
|
|
|
|
|
fprintf(stderr, "wait_time_nr (s) : %d\n", wait_time_nr);
|
|
|
|
|
fprintf(stderr, "chunk_time_nr (s) : %d\n", chunk_time_nr);
|
|
|
|
|
fprintf(stderr, "agc_bandwidth_nr (Hz) : %d\n", agc_bandwidth_nr);
|
|
|
|
|
fprintf(stderr, "agc_set_point_nr (dBfs) : %d\n", agc_set_point_nr);
|
|
|
|
|
fprintf(stderr, "gain_reduction_nr (dB) : %d\n", gain_reduction_nr);
|
|
|
|
|
fprintf(stderr, "lna_state_nr : %d\n", lna_state_nr);
|
|
|
|
|
fprintf(stderr, "N_DECIMATION : %d\n", this->nDecimation);
|
|
|
|
|
fprintf(stderr, "rf_notch_fg : %s\n", rf_notch_fg ? "true" : "false");
|
|
|
|
|
fprintf(stderr, "dab_notch_fg : %s\n", dab_notch_fg ? "true" : "false");
|
|
|
|
|
fprintf(stderr, "usb_bulk_fg : %s\n", usb_bulk_fg ? "true" : "false");
|
|
|
|
|
fprintf(stderr, "stats_fg : %s\n", stats_fg ? "true" : "false");
|
|
|
|
|
fprintf(stderr, "small_verbose_fg : %s\n", small_verbose_fg ? "true" : "false");
|
|
|
|
|
fprintf(stderr, "more_verbose_fg : %s\n", more_verbose_fg ? "true" : "false");
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
// print them out
|
|
|
|
|
std::cerr << "[RspDuo] Print config" << std::endl;
|
|
|
|
|
std::cerr << "fc (Hz) : " << fc << std::endl;
|
|
|
|
|
std::cerr << "fs (Hz) : " << fs << std::endl;
|
|
|
|
|
std::cerr << "file : " << file.c_str() << std::endl;
|
|
|
|
|
std::cerr << "agc_bandwidth_nr (Hz) : " << agc_bandwidth_nr << std::endl;
|
|
|
|
|
std::cerr << "agc_set_point_nr (dBfs) : " << agc_set_point_nr << std::endl;
|
|
|
|
|
std::cerr << "gain_reduction_nr (dB) : " << gain_reduction_nr << std::endl;
|
|
|
|
|
std::cerr << "lna_state_nr : " << lna_state_nr << std::endl;
|
|
|
|
|
std::cerr << "N_DECIMATION : " << nDecimation << std::endl;
|
|
|
|
|
std::cerr << "rf_notch_fg : " << (rf_notch_fg ? "true" : "false") << std::endl;
|
|
|
|
|
std::cerr << "dab_notch_fg : " << (dab_notch_fg ? "true" : "false") << std::endl;
|
|
|
|
|
std::cerr << "usb_bulk_fg : " << (usb_bulk_fg ? "true" : "false") << std::endl;
|
|
|
|
|
std::cerr << "stats_fg : " << (stats_fg ? "true" : "false") << std::endl;
|
|
|
|
|
std::cerr << "\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RspDuo::open_api()
|
|
|
|
|
{
|
|
|
|
|
float ver = 0.0;
|
|
|
|
|
|
|
|
|
|
// open the sdrplay api
|
|
|
|
|
if ((err = sdrplay_api_Open()) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_Open failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: API open failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
// enable debug logging output
|
|
|
|
|
if ((err = sdrplay_api_DebugEnable(NULL, sdrplay_api_DbgLvl_Verbose)) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_DebugEnable failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: Debug enable failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check api versions match
|
|
|
|
|
if ((err = sdrplay_api_ApiVersion(&ver)) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_ApiVersion failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: Set API version failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ver != SDRPLAY_API_VERSION)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - open_api - API versions do not match (local=%.2f dll=%.2f)\n", SDRPLAY_API_VERSION, ver);
|
|
|
|
|
std::cerr << "Error: API versions do not match, local= " << SDRPLAY_API_VERSION << "API= " << ver << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RspDuo::get_device()
|
|
|
|
@ -275,7 +217,7 @@ void RspDuo::get_device()
|
|
|
|
|
// lock api while device selection is performed
|
|
|
|
|
if ((err = sdrplay_api_LockDeviceApi()) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_LockDeviceApi failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: Lock API during device selection failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
@ -283,17 +225,17 @@ void RspDuo::get_device()
|
|
|
|
|
// fetch list of available devices
|
|
|
|
|
if ((err = sdrplay_api_GetDevices(devs, &ndev, sizeof(devs) / sizeof(sdrplay_api_DeviceT))) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_GetDevices failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: sdrplay_api_GetDevices failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_UnlockDeviceApi();
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "Info - get_device - MaxDevs=%ld NumDevs=%d\n", sizeof(devs) / sizeof(sdrplay_api_DeviceT), ndev);
|
|
|
|
|
std::cerr << "[RspDuo] MaxDevs=" << sizeof(devs) / sizeof(sdrplay_api_DeviceT) << " NumDevs=" << ndev << std::endl;
|
|
|
|
|
|
|
|
|
|
if (ndev == 0)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - get_device - no devices found\n");
|
|
|
|
|
std::cerr << "Error: No devices found" << std::endl;
|
|
|
|
|
sdrplay_api_UnlockDeviceApi();
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
@ -305,15 +247,13 @@ void RspDuo::get_device()
|
|
|
|
|
if (devs[i].hwVer == SDRPLAY_RSPduo_ID)
|
|
|
|
|
{
|
|
|
|
|
chosenIdx = i;
|
|
|
|
|
fprintf(stderr, "Info - get_device - Dev%d: SerNo=%s hwVer=%d tuner=0x%.2x rspDuoMode=0x%.2x\n",
|
|
|
|
|
i, devs[i].SerNo, devs[i].hwVer, devs[i].tuner, devs[i].rspDuoMode);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i == ndev)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - get_device - could not find a suitable RSPduo device to open\n");
|
|
|
|
|
std::cerr << "Error: Could not find a suitable RSPduo device to open" << std::endl;
|
|
|
|
|
sdrplay_api_UnlockDeviceApi();
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
@ -321,20 +261,20 @@ void RspDuo::get_device()
|
|
|
|
|
|
|
|
|
|
chosenDevice = &devs[chosenIdx];
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "Info - get_device - chosenDevice=%d\n", chosenIdx);
|
|
|
|
|
|
|
|
|
|
// set operating mode
|
|
|
|
|
chosenDevice->tuner = sdrplay_api_Tuner_Both;
|
|
|
|
|
chosenDevice->rspDuoMode = sdrplay_api_RspDuoMode_Dual_Tuner;
|
|
|
|
|
chosenDevice->rspDuoSampleFreq = DEF_SAMPLE_FREQUENCY_NR;
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "Info - get_device - Dev%d: selected rspDuoMode=0x%.2x tuner=0x%.2x rspDuoSampleFreq=%.1f\n",
|
|
|
|
|
chosenIdx, chosenDevice->rspDuoMode, chosenDevice->tuner, chosenDevice->rspDuoSampleFreq);
|
|
|
|
|
std::cerr << "[RspDuo] Device ID " << chosenIdx << std::endl;
|
|
|
|
|
std::cerr << "[RspDuo] Serial Number " << devs[i].SerNo << std::endl;
|
|
|
|
|
std::cerr << "[RspDuo] Hardware Version " << std::to_string(devs[i].hwVer) << std::endl;
|
|
|
|
|
std::cerr << "[RspDuo] Tuner " << std::hex << chosenDevice->tuner << std::dec << std::endl;
|
|
|
|
|
std::cerr << "[RspDuo] RspDuoMode " << std::hex << chosenDevice->rspDuoMode << std::dec << std::endl;
|
|
|
|
|
|
|
|
|
|
// select chosen device
|
|
|
|
|
if ((err = sdrplay_api_SelectDevice(chosenDevice)) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_SelectDevice failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: Select device failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_UnlockDeviceApi();
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
@ -343,7 +283,7 @@ void RspDuo::get_device()
|
|
|
|
|
// unlock api now that device is selected
|
|
|
|
|
if ((err = sdrplay_api_UnlockDeviceApi()) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_UnlockDeviceApi failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: Unlock device API failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
@ -356,7 +296,7 @@ void RspDuo::set_device_parameters()
|
|
|
|
|
// retrieve device parameters so they can be changed if wanted
|
|
|
|
|
if ((err = sdrplay_api_GetDeviceParams(chosenDevice->dev, &deviceParams)) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Error - sdrplay_api_GetDeviceParams failed " + std::string(sdrplay_api_GetErrorString(err)) << std::endl;
|
|
|
|
|
std::cout << "Error: sdrplay_api_GetDeviceParams failed " + std::string(sdrplay_api_GetErrorString(err)) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
@ -364,7 +304,7 @@ void RspDuo::set_device_parameters()
|
|
|
|
|
// check for NULL pointer before changing settings
|
|
|
|
|
if (deviceParams == NULL)
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Error - sdrplay_api_GetDeviceParams returned NULL deviceParams pointer" << std::endl;
|
|
|
|
|
std::cout << "Error: Device parameters pointer is null" << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
@ -385,13 +325,13 @@ void RspDuo::set_device_parameters()
|
|
|
|
|
// check for NULL pointer before changing settings
|
|
|
|
|
if (chParams == NULL)
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Error - sdrplay_api_GetDeviceParams returned NULL chParams pointer" << std::endl;
|
|
|
|
|
std::cerr << "Error: Channel parameters pointer is null" << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set center frequency
|
|
|
|
|
chParams->tunerParams.rfFreq.rfHz = this->fc;
|
|
|
|
|
chParams->tunerParams.rfFreq.rfHz = fc;
|
|
|
|
|
|
|
|
|
|
// set AGC
|
|
|
|
|
chParams->ctrlParams.agc.enable = sdrplay_api_AGC_DISABLE;
|
|
|
|
@ -418,21 +358,21 @@ void RspDuo::set_device_parameters()
|
|
|
|
|
|
|
|
|
|
// set decimation and IF frequency and analog bandwidth
|
|
|
|
|
chParams->ctrlParams.decimation.enable = 1;
|
|
|
|
|
chParams->ctrlParams.decimation.decimationFactor = this->nDecimation;
|
|
|
|
|
chParams->ctrlParams.decimation.decimationFactor = nDecimation;
|
|
|
|
|
chParams->tunerParams.ifType = sdrplay_api_IF_1_620;
|
|
|
|
|
chParams->tunerParams.bwType = sdrplay_api_BW_1_536;
|
|
|
|
|
|
|
|
|
|
if (this->nDecimation == 4)
|
|
|
|
|
if (nDecimation == 4)
|
|
|
|
|
{
|
|
|
|
|
// 2 MSa/s / 4 = 500 kHz
|
|
|
|
|
chParams->tunerParams.bwType = sdrplay_api_BW_0_600;
|
|
|
|
|
}
|
|
|
|
|
else if (this->nDecimation == 8)
|
|
|
|
|
else if (nDecimation == 8)
|
|
|
|
|
{
|
|
|
|
|
// 2 MSa/s / 8 = 250 kHz
|
|
|
|
|
chParams->tunerParams.bwType = sdrplay_api_BW_0_300;
|
|
|
|
|
}
|
|
|
|
|
else if (this->nDecimation == 16 || this->nDecimation == 32)
|
|
|
|
|
else if (nDecimation == 16 || nDecimation == 32)
|
|
|
|
|
{
|
|
|
|
|
// 2 MSa/s / 16 = 125 kHz
|
|
|
|
|
// 2 MSa/s / 32 = 62.5 kHz
|
|
|
|
@ -462,7 +402,7 @@ void RspDuo::stream_a_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT
|
|
|
|
|
|
|
|
|
|
if (buffer_16_ar == NULL)
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Error - stream_a_callback - malloc failed" << std::endl;
|
|
|
|
|
std::cout << "Error: stream_a_callback, malloc failed" << std::endl;
|
|
|
|
|
run_fg = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -479,7 +419,7 @@ void RspDuo::stream_a_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find max for stats
|
|
|
|
|
if (stats_fg && write_fg)
|
|
|
|
|
if (stats_fg)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < numSamples; i++)
|
|
|
|
|
{
|
|
|
|
@ -520,24 +460,15 @@ void RspDuo::stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT
|
|
|
|
|
buffer1->unlock();
|
|
|
|
|
buffer2->unlock();
|
|
|
|
|
|
|
|
|
|
// decide if to write data
|
|
|
|
|
gettimeofday(¤t_tm, NULL);
|
|
|
|
|
|
|
|
|
|
// write if over start time
|
|
|
|
|
if (start_tm.tv_sec + wait_time_nr <= current_tm.tv_sec)
|
|
|
|
|
{
|
|
|
|
|
write_fg = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// write data to file
|
|
|
|
|
if (*capture_fg && write_fg)
|
|
|
|
|
if (*capture_fg)
|
|
|
|
|
{
|
|
|
|
|
saveIqFileLocal->write(reinterpret_cast<char*>(buffer_16_ar),
|
|
|
|
|
sizeof(short) * numSamples * 4);
|
|
|
|
|
|
|
|
|
|
if (!(*saveIqFileLocal))
|
|
|
|
|
{
|
|
|
|
|
std::cerr << "Error - stream_b_callback - not enough samples received" << std::endl;
|
|
|
|
|
std::cout << "Error: stream_b_callback, not enough samples received" << std::endl;
|
|
|
|
|
free(buffer_16_ar);
|
|
|
|
|
run_fg = false;
|
|
|
|
|
return;
|
|
|
|
@ -549,7 +480,7 @@ void RspDuo::stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT
|
|
|
|
|
free(buffer_16_ar);
|
|
|
|
|
|
|
|
|
|
// find max for stats
|
|
|
|
|
if (stats_fg && write_fg)
|
|
|
|
|
if (stats_fg)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < numSamples; i++)
|
|
|
|
|
{
|
|
|
|
@ -565,29 +496,32 @@ void RspDuo::stream_b_callback(short *xi, short *xq, sdrplay_api_StreamCbParamsT
|
|
|
|
|
|
|
|
|
|
void RspDuo::event_callback(sdrplay_api_EventT eventId, sdrplay_api_TunerSelectT tuner, sdrplay_api_EventParamsT *params, void *cbContext)
|
|
|
|
|
{
|
|
|
|
|
std::string tuner_str = (tuner == sdrplay_api_Tuner_A) ? "sdrplay_api_Tuner_A" : "sdrplay_api_Tuner_B";
|
|
|
|
|
switch (eventId)
|
|
|
|
|
{
|
|
|
|
|
case sdrplay_api_GainChange:
|
|
|
|
|
fprintf(stderr, "Info - event_callback - GainChange tuner=%s gRdB=%d lnaGRdB=%d systemGain=%.2f\n",
|
|
|
|
|
(tuner == sdrplay_api_Tuner_A) ? "sdrplay_api_Tuner_A" : "sdrplay_api_Tuner_B",
|
|
|
|
|
params->gainParams.gRdB, params->gainParams.lnaGRdB, params->gainParams.currGain);
|
|
|
|
|
std::cerr << "[RspDuo] Gain change, tuner=" << tuner_str << " ";
|
|
|
|
|
std::cerr << "gRdB=" << params->gainParams.gRdB << " ";
|
|
|
|
|
std::cerr << "lnaGRdB=" << params->gainParams.lnaGRdB << " ";
|
|
|
|
|
std::cerr << "systemGain=" << params->gainParams.currGain << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case sdrplay_api_PowerOverloadChange:
|
|
|
|
|
fprintf(stderr, "Info - event_callback - PowerOverloadChange tuner=%s powerOverloadChangeType=%s\n",
|
|
|
|
|
(tuner == sdrplay_api_Tuner_A) ? "sdrplay_api_Tuner_A" : "sdrplay_api_Tuner_B",
|
|
|
|
|
(params->powerOverloadParams.powerOverloadChangeType == sdrplay_api_Overload_Detected) ? "sdrplay_api_Overload_Detected" : "sdrplay_api_Overload_Corrected");
|
|
|
|
|
|
|
|
|
|
std::cerr << "[RspDuo] PowerOverloadChange, tuner=" << tuner_str << " ";
|
|
|
|
|
std::cerr << "powerOverloadChangeType=" <<
|
|
|
|
|
((params->powerOverloadParams.powerOverloadChangeType
|
|
|
|
|
== sdrplay_api_Overload_Detected) ? "sdrplay_api_Overload_Detected" :
|
|
|
|
|
"sdrplay_api_Overload_Corrected") << std::endl;
|
|
|
|
|
// send update message to acknowledge power overload message received
|
|
|
|
|
sdrplay_api_Update(chosenDevice->dev, tuner, sdrplay_api_Update_Ctrl_OverloadMsgAck, sdrplay_api_Update_Ext1_None);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case sdrplay_api_DeviceRemoved:
|
|
|
|
|
fprintf(stderr, "Info - event_callback - device removed\n");
|
|
|
|
|
std::cerr << "[RspDuo] Device removed" << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
fprintf(stderr, "Info - event_callback - unknown event %d\n", eventId);
|
|
|
|
|
std::cerr << "[RspDuo] Unknown event " << eventId << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -596,7 +530,7 @@ void RspDuo::initialise_device()
|
|
|
|
|
{
|
|
|
|
|
if ((err = sdrplay_api_Init(chosenDevice->dev, &cbFns, NULL)) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_Init failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: sdrplay_api_Init failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
@ -606,7 +540,7 @@ void RspDuo::uninitialise_device()
|
|
|
|
|
{
|
|
|
|
|
if ((err = sdrplay_api_Uninit(chosenDevice->dev)) != sdrplay_api_Success)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Error - sdrplay_api_Uninit failed %s\n", sdrplay_api_GetErrorString(err));
|
|
|
|
|
std::cerr << "Error: sdrplay_api_Uninit failed " << sdrplay_api_GetErrorString(err) << std::endl;
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
@ -615,22 +549,3 @@ void RspDuo::uninitialise_device()
|
|
|
|
|
sdrplay_api_UnlockDeviceApi();
|
|
|
|
|
sdrplay_api_Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RspDuo::finish()
|
|
|
|
|
{
|
|
|
|
|
char time_tx[BUFFER_SIZE_NR];
|
|
|
|
|
|
|
|
|
|
// close files
|
|
|
|
|
close_file();
|
|
|
|
|
|
|
|
|
|
// get finish date and time
|
|
|
|
|
gettimeofday(&finish_tm, NULL);
|
|
|
|
|
|
|
|
|
|
strftime(time_tx, sizeof(time_tx), "%d %b %Y %H:%M:%S", localtime(&finish_tm.tv_sec));
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
fprintf(stderr, "Info - finish - finish_tm: %s.%03ld\n", time_tx, finish_tm.tv_usec / 1000);
|
|
|
|
|
fprintf(stderr, "Info - finish - frames_nr: %d\n", frames_nr);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|