mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 13:48:38 -05:00
Make stream deactivated before a sample-rate change and reactivated afterwards (#718)
* Make stream deactivated before a sample-rate chnage and reactivated afterwards * Re-read sample rate and MTU AFTER stream activation to recompute CubicSDR buffers
This commit is contained in:
parent
0f098e3cbb
commit
c27e1e6514
@ -87,6 +87,7 @@ bool SDRThread::init() {
|
|||||||
|
|
||||||
std::string streamExceptionStr("");
|
std::string streamExceptionStr("");
|
||||||
|
|
||||||
|
//1. setup stream for CF32:
|
||||||
try {
|
try {
|
||||||
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), currentStreamArgs);
|
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), currentStreamArgs);
|
||||||
} catch(exception e) {
|
} catch(exception e) {
|
||||||
@ -98,23 +99,17 @@ bool SDRThread::init() {
|
|||||||
std::cout << "Stream setup failed, stream is null. " << streamExceptionStr << std::endl;
|
std::cout << "Stream setup failed, stream is null. " << streamExceptionStr << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int streamMTU = device->getStreamMTU(stream);
|
//2. Set sample rate:
|
||||||
mtuElems.store(streamMTU);
|
device->setSampleRate(SOAPY_SDR_RX, 0, sampleRate.load());
|
||||||
|
|
||||||
|
//3. Store Stream-specific parameters to current Device
|
||||||
deviceInfo.load()->setStreamArgs(currentStreamArgs);
|
deviceInfo.load()->setStreamArgs(currentStreamArgs);
|
||||||
deviceConfig.load()->setStreamOpts(currentStreamArgs);
|
deviceConfig.load()->setStreamOpts(currentStreamArgs);
|
||||||
|
|
||||||
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Activating stream."));
|
//4. Apply other settings: Frequency, PPM correction, Gains, Device-specific settings:
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
|
||||||
|
|
||||||
// TODO: explore bandwidth setting option to see if this is necessary for others
|
|
||||||
if (device->getDriverKey() == "bladeRF") {
|
|
||||||
device->setBandwidth(SOAPY_SDR_RX, 0, sampleRate.load());
|
|
||||||
}
|
|
||||||
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency - offset.load());
|
||||||
device->activateStream(stream);
|
|
||||||
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
|
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
|
||||||
hasPPM.store(true);
|
hasPPM.store(true);
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load());
|
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load());
|
||||||
@ -133,28 +128,12 @@ bool SDRThread::init() {
|
|||||||
device->setGainMode(SOAPY_SDR_RX, 0, agc_mode.load());
|
device->setGainMode(SOAPY_SDR_RX, 0, agc_mode.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
numChannels.store(getOptimalChannelCount(sampleRate.load()));
|
|
||||||
numElems.store(getOptimalElementCount(sampleRate.load(), TARGET_DISPLAY_FPS));
|
|
||||||
|
|
||||||
//fallback if mtuElems was wrong
|
|
||||||
if (!mtuElems.load()) {
|
|
||||||
mtuElems.store(numElems.load());
|
|
||||||
std::cout << "SDRThread::init(): Device Stream MTU is broken, use " << mtuElems.load() << "instead..." << std::endl << std::flush;
|
|
||||||
} else {
|
|
||||||
std::cout << "SDRThread::init(): Device Stream set to MTU: " << mtuElems.load() << std::endl << std::flush;
|
|
||||||
}
|
|
||||||
|
|
||||||
overflowBuffer.data.resize(mtuElems.load());
|
|
||||||
|
|
||||||
buffs[0] = malloc(mtuElems.load() * 4 * sizeof(float));
|
|
||||||
numOverflow = 0;
|
|
||||||
|
|
||||||
SoapySDR::ArgInfoList settingsInfo = device->getSettingInfo();
|
SoapySDR::ArgInfoList settingsInfo = device->getSettingInfo();
|
||||||
SoapySDR::ArgInfoList::const_iterator settings_i;
|
SoapySDR::ArgInfoList::const_iterator settings_i;
|
||||||
|
|
||||||
if (!setting_value_changed.load()) {
|
if (!setting_value_changed.load()) {
|
||||||
settings.erase(settings.begin(), settings.end());
|
settings.clear();
|
||||||
settingChanged.erase(settingChanged.begin(), settingChanged.end());
|
settingChanged.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//apply settings.
|
//apply settings.
|
||||||
@ -174,11 +153,15 @@ bool SDRThread::init() {
|
|||||||
setting_value_changed.store(false);
|
setting_value_changed.store(false);
|
||||||
|
|
||||||
} //leave lock guard scope
|
} //leave lock guard scope
|
||||||
|
|
||||||
updateSettings();
|
|
||||||
|
|
||||||
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_INITIALIZED, std::string("Device Initialized."));
|
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_INITIALIZED, std::string("Device Initialized."));
|
||||||
|
|
||||||
|
//5. Activate stream: (through update settings)
|
||||||
|
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Activating stream."));
|
||||||
|
|
||||||
|
rate_changed.store(true);
|
||||||
|
updateSettings();
|
||||||
|
|
||||||
//rebuild menu now that settings are really been applied.
|
//rebuild menu now that settings are really been applied.
|
||||||
wxGetApp().notifyMainUIOfDeviceChange(true);
|
wxGetApp().notifyMainUIOfDeviceChange(true);
|
||||||
|
|
||||||
@ -188,7 +171,13 @@ bool SDRThread::init() {
|
|||||||
void SDRThread::deinit() {
|
void SDRThread::deinit() {
|
||||||
device->deactivateStream(stream);
|
device->deactivateStream(stream);
|
||||||
device->closeStream(stream);
|
device->closeStream(stream);
|
||||||
free(buffs[0]);
|
|
||||||
|
if (buffs[0] != nullptr) {
|
||||||
|
::free(buffs[0]);
|
||||||
|
buffs[0] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRThread::assureBufferMinSize(SDRThreadIQData * dataOut, size_t minSize) {
|
void SDRThread::assureBufferMinSize(SDRThreadIQData * dataOut, size_t minSize) {
|
||||||
@ -413,11 +402,12 @@ void SDRThread::readLoop() {
|
|||||||
void SDRThread::updateGains() {
|
void SDRThread::updateGains() {
|
||||||
SDRDeviceInfo *devInfo = deviceInfo.load();
|
SDRDeviceInfo *devInfo = deviceInfo.load();
|
||||||
|
|
||||||
gainValues.erase(gainValues.begin(),gainValues.end());
|
gainValues.clear();
|
||||||
gainChanged.erase(gainChanged.begin(),gainChanged.end());
|
gainChanged.clear();
|
||||||
|
|
||||||
SDRRangeMap gains = devInfo->getGains(SOAPY_SDR_RX, 0);
|
SDRRangeMap gains = devInfo->getGains(SOAPY_SDR_RX, 0);
|
||||||
for (SDRRangeMap::iterator gi = gains.begin(); gi != gains.end(); gi++) {
|
for (SDRRangeMap::iterator gi = gains.begin(); gi != gains.end(); gi++) {
|
||||||
|
|
||||||
gainValues[gi->first] = device->getGain(SOAPY_SDR_RX, 0, gi->first);
|
gainValues[gi->first] = device->getGain(SOAPY_SDR_RX, 0, gi->first);
|
||||||
gainChanged[gi->first] = false;
|
gainChanged[gi->first] = false;
|
||||||
}
|
}
|
||||||
@ -448,39 +438,49 @@ void SDRThread::updateSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rate_changed.load()) {
|
if (rate_changed.load()) {
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
|
||||||
|
//1. Silence the device:
|
||||||
|
device->deactivateStream(stream);
|
||||||
|
|
||||||
|
//2. Set the (new) sample rate
|
||||||
|
device->setSampleRate(SOAPY_SDR_RX, 0, sampleRate.load());
|
||||||
|
|
||||||
|
//2.2 Device-specific workarounds:
|
||||||
// TODO: explore bandwidth setting option to see if this is necessary for others
|
// TODO: explore bandwidth setting option to see if this is necessary for others
|
||||||
if (device->getDriverKey() == "bladeRF") {
|
if (device->getDriverKey() == "bladeRF") {
|
||||||
device->setBandwidth(SOAPY_SDR_RX, 0, sampleRate.load());
|
device->setBandwidth(SOAPY_SDR_RX, 0, sampleRate.load());
|
||||||
}
|
}
|
||||||
// Fix for LimeSDR-USB not properly handling samplerate changes while device is
|
|
||||||
// active.
|
//3. Re-activate stream:
|
||||||
else if (device->getHardwareKey() == "LimeSDR-USB") {
|
device->activateStream(stream);
|
||||||
std::cout << "SDRThread::updateSettings(): Force deactivate / activate limeSDR stream" << std::endl << std::flush;
|
|
||||||
device->deactivateStream(stream);
|
//4. Re-do Cubic buffers :
|
||||||
device->activateStream(stream);
|
//re-read current sample rate and MTU:
|
||||||
}
|
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX, 0));
|
||||||
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
|
|
||||||
numChannels.store(getOptimalChannelCount(sampleRate.load()));
|
numChannels.store(getOptimalChannelCount(sampleRate.load()));
|
||||||
numElems.store(getOptimalElementCount(sampleRate.load(), TARGET_DISPLAY_FPS));
|
numElems.store(getOptimalElementCount(sampleRate.load(), TARGET_DISPLAY_FPS));
|
||||||
|
//read (new) MTU size:
|
||||||
int streamMTU = device->getStreamMTU(stream);
|
int streamMTU = device->getStreamMTU(stream);
|
||||||
|
|
||||||
mtuElems.store(streamMTU);
|
mtuElems.store(streamMTU);
|
||||||
|
|
||||||
//fallback if mtuElems was wrong
|
//fallback if mtuElems was wrong
|
||||||
if (!mtuElems.load()) {
|
if (!mtuElems.load()) {
|
||||||
mtuElems.store(numElems.load());
|
mtuElems.store(numElems.load());
|
||||||
std::cout << "SDRThread::updateSettings(): Device Stream MTU is broken, use " << mtuElems.load() << "instead..." << std::endl << std::flush;
|
std::cout << "SDRThread: Device Stream MTU is broken, use " << mtuElems.load() << " instead..." << std::endl << std::flush;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "SDRThread::updateSettings(): Device Stream changing to MTU: " << mtuElems.load() << std::endl << std::flush;
|
std::cout << "SDRThread : Device Stream set to MTU: " << mtuElems.load() << std::endl << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
overflowBuffer.data.resize(mtuElems.load());
|
overflowBuffer.data.resize(mtuElems.load());
|
||||||
free(buffs[0]);
|
if (buffs[0] != nullptr) {
|
||||||
buffs[0] = malloc(mtuElems.load() * 4 * sizeof(float));
|
::free(buffs[0]);
|
||||||
|
}
|
||||||
|
buffs[0] = ::malloc(mtuElems.load() * 4 * sizeof(float));
|
||||||
//clear overflow buffer
|
//clear overflow buffer
|
||||||
numOverflow = 0;
|
numOverflow = 0;
|
||||||
|
|
||||||
|
//
|
||||||
rate_changed.store(false);
|
rate_changed.store(false);
|
||||||
doUpdate = true;
|
doUpdate = true;
|
||||||
}
|
}
|
||||||
@ -499,11 +499,7 @@ void SDRThread::updateSettings() {
|
|||||||
}
|
}
|
||||||
freq_changed.store(false);
|
freq_changed.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// double devFreq = device->getFrequency(SOAPY_SDR_RX,0);
|
|
||||||
// if (((long long)devFreq + offset.load()) != frequency.load()) {
|
|
||||||
// wxGetApp().setFrequency((long long)devFreq + offset.load());
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (agc_mode_changed.load()) {
|
if (agc_mode_changed.load()) {
|
||||||
if (device->hasGainMode(SOAPY_SDR_RX, 0)) {
|
if (device->hasGainMode(SOAPY_SDR_RX, 0)) {
|
||||||
|
@ -106,9 +106,9 @@ protected:
|
|||||||
void updateSettings();
|
void updateSettings();
|
||||||
SoapySDR::Kwargs combineArgs(SoapySDR::Kwargs a, SoapySDR::Kwargs b);
|
SoapySDR::Kwargs combineArgs(SoapySDR::Kwargs a, SoapySDR::Kwargs b);
|
||||||
|
|
||||||
SoapySDR::Stream *stream;
|
SoapySDR::Stream *stream = nullptr;
|
||||||
SoapySDR::Device *device;
|
SoapySDR::Device *device;
|
||||||
void *buffs[1];
|
void *buffs[1] = { nullptr };
|
||||||
ReBuffer<SDRThreadIQData> buffers;
|
ReBuffer<SDRThreadIQData> buffers;
|
||||||
SDRThreadIQData overflowBuffer;
|
SDRThreadIQData overflowBuffer;
|
||||||
int numOverflow;
|
int numOverflow;
|
||||||
|
Loading…
Reference in New Issue
Block a user