Merge pull request #410 from cjcliffe/modem_factory_funcs

Modem factory funcs
This commit is contained in:
Charles J. Cliffe 2016-07-24 16:28:30 -05:00 committed by GitHub
commit 8558292417
48 changed files with 148 additions and 94 deletions

View File

@ -190,30 +190,30 @@ bool CubicSDR::OnInit() {
RigThread::enumerate();
#endif
Modem::addModemFactory(new ModemFM);
Modem::addModemFactory(new ModemNBFM);
Modem::addModemFactory(new ModemFMStereo);
Modem::addModemFactory(new ModemAM);
Modem::addModemFactory(new ModemLSB);
Modem::addModemFactory(new ModemUSB);
Modem::addModemFactory(new ModemDSB);
Modem::addModemFactory(new ModemIQ);
Modem::addModemFactory(ModemFM::factory, "FM", 200000);
Modem::addModemFactory(ModemNBFM::factory, "NBFM", 12500);
Modem::addModemFactory(ModemFMStereo::factory, "FMS", 200000);
Modem::addModemFactory(ModemAM::factory, "AM", 6000);
Modem::addModemFactory(ModemLSB::factory, "LSB", 5400);
Modem::addModemFactory(ModemUSB::factory, "USB", 5400);
Modem::addModemFactory(ModemDSB::factory, "DSB", 5400);
Modem::addModemFactory(ModemIQ::factory, "I/Q", 48000);
#ifdef ENABLE_DIGITAL_LAB
Modem::addModemFactory(new ModemAPSK);
Modem::addModemFactory(new ModemASK);
Modem::addModemFactory(new ModemBPSK);
Modem::addModemFactory(new ModemDPSK);
Modem::addModemFactory(ModemAPSK::factory, "APSK", 200000);
Modem::addModemFactory(ModemASK::factory, "ASK", 200000);
Modem::addModemFactory(ModemBPSK::factory, "BPSK", 200000);
Modem::addModemFactory(ModemDPSK::factory, "DPSK", 200000);
#if ENABLE_LIQUID_EXPERIMENTAL
Modem::addModemFactory(new ModemFSK);
Modem::addModemFactory(ModemFSK::factory, "FSK", 19200);
#endif
Modem::addModemFactory(new ModemGMSK);
Modem::addModemFactory(new ModemOOK);
Modem::addModemFactory(new ModemPSK);
Modem::addModemFactory(new ModemQAM);
Modem::addModemFactory(new ModemQPSK);
Modem::addModemFactory(new ModemSQAM);
Modem::addModemFactory(new ModemST);
Modem::addModemFactory(ModemGMSK::factory, "GMSK", 19200);
Modem::addModemFactory(ModemOOK::factory, "OOK", 200000);
Modem::addModemFactory(ModemPSK::factory, "PSK", 200000);
Modem::addModemFactory(ModemQAM::factory, "QAM", 200000);
Modem::addModemFactory(ModemQPSK::factory, "QPSK", 200000);
Modem::addModemFactory(ModemSQAM::factory, "SQAM", 200000);
Modem::addModemFactory(ModemST::factory, "ST", 200000);
#endif
frequency = wxGetApp().getConfig()->getCenterFreq();

View File

@ -128,6 +128,13 @@ void DemodulatorInstance::updateLabel(long long freq) {
}
void DemodulatorInstance::terminate() {
#if ENABLE_DIGITAL_LAB
if (activeOutput) {
closeOutput();
}
#endif
// std::cout << "Terminating demodulator audio thread.." << std::endl;
audioThread->terminate();
// std::cout << "Terminating demodulator thread.." << std::endl;
@ -156,7 +163,6 @@ bool DemodulatorInstance::isTerminated() {
if (audioTerminated) {
if (t_Audio) {
t_Audio->join();
delete t_Audio;
@ -175,11 +181,6 @@ bool DemodulatorInstance::isTerminated() {
#endif
t_Demod = nullptr;
}
#if ENABLE_DIGITAL_LAB
if (activeOutput) {
closeOutput();
}
#endif
}
if (preDemodTerminated) {
@ -208,7 +209,7 @@ bool DemodulatorInstance::isActive() {
void DemodulatorInstance::setActive(bool state) {
if (active && !state) {
#if ENABLE_DIGITAL_LAB
if (activeOutput && !isTerminated()) {
if (activeOutput) {
activeOutput->Hide();
}
#endif
@ -314,7 +315,14 @@ void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) {
if (lastbw) {
setBandwidth(lastbw);
}
}
#if ENABLE_DIGITAL_LAB
if (isModemInitialized() && getModemType() == "digital") {
ModemDigitalOutputConsole *outp = (ModemDigitalOutputConsole *)getOutput();
outp->setTitle(getDemodulatorType() + ": " + frequencyToStr(getFrequency()));
}
#endif
}
}
std::string DemodulatorInstance::getDemodulatorType() {

View File

@ -136,6 +136,7 @@ void DemodulatorThread::run() {
ati->sampleRate = cModemKit->sampleRate;
ati->inputRate = inp->sampleRate;
ati->data.resize(0);
}
cModem->demodulate(cModemKit, &modemData, ati);
@ -160,7 +161,7 @@ void DemodulatorThread::run() {
}
}
if (audioOutputQueue != nullptr && ati && !squelched) {
if (audioOutputQueue != nullptr && ati && ati->data.size() && !squelched) {
std::vector<float>::iterator data_i;
ati->peak = 0;
for (data_i = ati->data.begin(); data_i != ati->data.end(); data_i++) {
@ -182,7 +183,7 @@ void DemodulatorThread::run() {
localAudioVisOutputQueue = audioVisOutputQueue;
}
if (ati && localAudioVisOutputQueue != nullptr && localAudioVisOutputQueue->empty()) {
if ((ati || modemDigital) && localAudioVisOutputQueue != nullptr && localAudioVisOutputQueue->empty()) {
AudioThreadInput *ati_vis = new AudioThreadInput;
ati_vis->sampleRate = inp->sampleRate;
@ -190,6 +191,10 @@ void DemodulatorThread::run() {
size_t num_vis = DEMOD_VIS_SIZE;
if (modemDigital) {
if (ati) { // TODO: handle digital modems with audio output
ati->setRefCount(0);
ati = nullptr;
}
ati_vis->data.resize(inputData->size());
ati_vis->channels = 2;
for (int i = 0, iMax = inputData->size() / 2; i < iMax; i++) {

View File

@ -3,6 +3,7 @@
ModemFactoryList Modem::modemFactories;
DefaultRatesList Modem::modemDefaultRates;
//! Create an empty range (0.0, 0.0)
ModemRange::ModemRange(void) {
@ -38,8 +39,9 @@ Modem::~Modem() {
}
void Modem::addModemFactory(Modem *factorySingle) {
modemFactories[factorySingle->getName()] = factorySingle;
void Modem::addModemFactory(ModemFactoryFn factoryFunc, std::string modemName, int defaultRate) {
modemFactories[modemName] = factoryFunc;
modemDefaultRates[modemName] = defaultRate;
}
ModemFactoryList Modem::getFactories() {
@ -48,15 +50,15 @@ ModemFactoryList Modem::getFactories() {
Modem *Modem::makeModem(std::string modemName) {
if (modemFactories.find(modemName) != modemFactories.end()) {
return modemFactories[modemName]->factory();
return (Modem *)modemFactories[modemName]();
}
return nullptr;
}
int Modem::getModemDefaultSampleRate(std::string modemName) {
if (modemFactories.find(modemName) != modemFactories.end()) {
return modemFactories[modemName]->getDefaultSampleRate();
if (modemDefaultRates.find(modemName) != modemDefaultRates.end()) {
return modemDefaultRates[modemName];
}
return 0;

View File

@ -108,14 +108,21 @@ public:
typedef std::vector<ModemArgInfo> ModemArgInfoList;
class Modem;
typedef std::map<std::string,Modem *> ModemFactoryList;
class ModemBase {
};
typedef ModemBase *(*ModemFactoryFn)();
typedef std::map<std::string, ModemFactoryFn> ModemFactoryList;
typedef std::map<std::string, int> DefaultRatesList;
typedef std::map<std::string, std::string> ModemSettings;
class Modem {
class Modem : public ModemBase {
public:
static void addModemFactory(Modem *factorySingle);
static void addModemFactory(ModemFactoryFn, std::string modemName, int defaultRate);
static ModemFactoryList getFactories();
static Modem *makeModem(std::string modemName);
@ -124,8 +131,6 @@ public:
virtual std::string getType() = 0;
virtual std::string getName() = 0;
virtual Modem *factory() = 0;
Modem();
virtual ~Modem();
@ -149,5 +154,6 @@ public:
private:
static ModemFactoryList modemFactories;
static DefaultRatesList modemDefaultRates;
std::atomic_bool refreshKit;
};

View File

@ -8,7 +8,7 @@ ModemAM::~ModemAM() {
ampmodem_destroy(demodAM);
}
Modem *ModemAM::factory() {
ModemBase *ModemAM::factory() {
return new ModemAM;
}

View File

@ -9,7 +9,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int getDefaultSampleRate();

View File

@ -8,7 +8,7 @@ ModemDSB::~ModemDSB() {
ampmodem_destroy(demodAM_DSB);
}
Modem *ModemDSB::factory() {
ModemBase *ModemDSB::factory() {
return new ModemDSB;
}

View File

@ -9,7 +9,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int getDefaultSampleRate();

View File

@ -8,7 +8,7 @@ ModemFM::~ModemFM() {
freqdem_destroy(demodFM);
}
Modem *ModemFM::factory() {
ModemBase *ModemFM::factory() {
return new ModemFM;
}

View File

@ -9,7 +9,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int getDefaultSampleRate();

View File

@ -16,7 +16,7 @@ std::string ModemFMStereo::getName() {
return "FMS";
}
Modem *ModemFMStereo::factory() {
ModemBase *ModemFMStereo::factory() {
return new ModemFMStereo;
}

View File

@ -29,7 +29,7 @@ public:
std::string getType();
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);
int getDefaultSampleRate();

View File

@ -12,7 +12,7 @@ std::string ModemIQ::getName() {
return "I/Q";
}
Modem *ModemIQ::factory() {
ModemBase *ModemIQ::factory() {
return new ModemIQ;
}

View File

@ -8,7 +8,7 @@ public:
std::string getType();
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);
int getDefaultSampleRate();

View File

@ -13,7 +13,7 @@ ModemLSB::ModemLSB() : ModemAnalog() {
c2rFilt = firhilbf_create(5, 90.0);
}
Modem *ModemLSB::factory() {
ModemBase *ModemLSB::factory() {
return new ModemLSB;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);
int getDefaultSampleRate();

View File

@ -8,7 +8,7 @@ ModemNBFM::~ModemNBFM() {
freqdem_destroy(demodFM);
}
Modem *ModemNBFM::factory() {
ModemBase *ModemNBFM::factory() {
return new ModemNBFM;
}

View File

@ -9,7 +9,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int getDefaultSampleRate();

View File

@ -13,7 +13,7 @@ ModemUSB::ModemUSB() : ModemAnalog() {
c2rFilt = firhilbf_create(5, 90.0);
}
Modem *ModemUSB::factory() {
ModemBase *ModemUSB::factory() {
return new ModemUSB;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);
int getDefaultSampleRate();

View File

@ -12,7 +12,7 @@ ModemAPSK::ModemAPSK() : ModemDigital() {
cons = 4;
}
Modem *ModemAPSK::factory() {
ModemBase *ModemAPSK::factory() {
return new ModemAPSK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
ModemArgInfoList getSettings();
void writeSetting(std::string setting, std::string value);

View File

@ -13,7 +13,7 @@ ModemASK::ModemASK() : ModemDigital() {
cons = 2;
}
Modem *ModemASK::factory() {
ModemBase *ModemASK::factory() {
return new ModemASK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
ModemArgInfoList getSettings();
void writeSetting(std::string setting, std::string value);

View File

@ -4,7 +4,7 @@ ModemBPSK::ModemBPSK() : ModemDigital() {
demodBPSK = modem_create(LIQUID_MODEM_BPSK);
}
Modem *ModemBPSK::factory() {
ModemBase *ModemBPSK::factory() {
return new ModemBPSK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);

View File

@ -13,7 +13,7 @@ ModemDPSK::ModemDPSK() : ModemDigital() {
cons = 2;
}
Modem *ModemDPSK::factory() {
ModemBase *ModemDPSK::factory() {
return new ModemDPSK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
ModemArgInfoList getSettings();
void writeSetting(std::string setting, std::string value);

View File

@ -9,7 +9,7 @@ ModemFSK::ModemFSK() : ModemDigital() {
outStream << std::hex;
}
Modem *ModemFSK::factory() {
ModemBase *ModemFSK::factory() {
return new ModemFSK;
}

View File

@ -19,7 +19,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);
int getDefaultSampleRate();

View File

@ -16,7 +16,7 @@ std::string ModemGMSK::getName() {
return "GMSK";
}
Modem *ModemGMSK::factory() {
ModemBase *ModemGMSK::factory() {
return new ModemGMSK;
}

View File

@ -19,7 +19,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);
int getDefaultSampleRate();

View File

@ -12,7 +12,7 @@ std::string ModemOOK::getName() {
return "OOK";
}
Modem *ModemOOK::factory() {
ModemBase *ModemOOK::factory() {
return new ModemOOK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
int checkSampleRate(long long sampleRate, int audioSampleRate);

View File

@ -13,7 +13,7 @@ ModemPSK::ModemPSK() : ModemDigital() {
cons = 2;
}
Modem *ModemPSK::factory() {
ModemBase *ModemPSK::factory() {
return new ModemPSK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
ModemArgInfoList getSettings();
void writeSetting(std::string setting, std::string value);

View File

@ -12,7 +12,7 @@ ModemQAM::ModemQAM() : ModemDigital() {
cons = 4;
}
Modem *ModemQAM::factory() {
ModemBase *ModemQAM::factory() {
return new ModemQAM;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
ModemArgInfoList getSettings();
void writeSetting(std::string setting, std::string value);

View File

@ -4,7 +4,7 @@ ModemQPSK::ModemQPSK() : ModemDigital() {
demodQPSK = modem_create(LIQUID_MODEM_QPSK);
}
Modem *ModemQPSK::factory() {
ModemBase *ModemQPSK::factory() {
return new ModemQPSK;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);

View File

@ -7,7 +7,7 @@ ModemSQAM::ModemSQAM() : ModemDigital() {
cons = 32;
}
Modem *ModemSQAM::factory() {
ModemBase *ModemSQAM::factory() {
return new ModemSQAM;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
ModemArgInfoList getSettings();
void writeSetting(std::string setting, std::string value);

View File

@ -4,7 +4,7 @@ ModemST::ModemST() : ModemDigital() {
demodST = modem_create(LIQUID_MODEM_V29);
}
Modem *ModemST::factory() {
ModemBase *ModemST::factory() {
return new ModemST;
}

View File

@ -8,7 +8,7 @@ public:
std::string getName();
Modem *factory();
static ModemBase *factory();
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);

View File

@ -55,7 +55,7 @@ SoapySDR::Kwargs SDRThread::combineArgs(SoapySDR::Kwargs a, SoapySDR::Kwargs b)
return c;
}
void SDRThread::init() {
bool SDRThread::init() {
//#warning Debug On
// SoapySDR_setLogLevel(SOAPY_SDR_DEBUG);
@ -77,7 +77,20 @@ void SDRThread::init() {
device = devInfo->getSoapyDevice();
SoapySDR::Kwargs currentStreamArgs = combineArgs(devInfo->getStreamArgs(),streamArgs);
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), currentStreamArgs);
std::string streamExceptionStr("");
try {
stream = device->setupStream(SOAPY_SDR_RX,"CF32", std::vector<size_t>(), currentStreamArgs);
} catch(exception e) {
streamExceptionStr = e.what();
}
if (!stream) {
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_FAILED, std::string("Stream setup failed, stream is null. ") + streamExceptionStr);
std::cout << "Stream setup failed, stream is null. " << streamExceptionStr << std::endl;
return false;
}
int streamMTU = device->getStreamMTU(stream);
mtuElems.store(streamMTU);
@ -89,6 +102,12 @@ void SDRThread::init() {
wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Activating stream."));
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->activateStream(stream);
if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) {
@ -146,6 +165,8 @@ void SDRThread::init() {
updateSettings();
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_INITIALIZED, std::string("Device Initialized."));
return true;
}
void SDRThread::deinit() {
@ -270,6 +291,10 @@ void SDRThread::updateGains() {
void SDRThread::updateSettings() {
bool doUpdate = false;
if (!stream) {
return;
}
if (offset_changed.load()) {
if (!freq_changed.load()) {
frequency.store(frequency.load());
@ -280,6 +305,10 @@ void SDRThread::updateSettings() {
if (rate_changed.load()) {
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());
}
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
numChannels.store(getOptimalChannelCount(sampleRate.load()));
numElems.store(getOptimalElementCount(sampleRate.load(), 60));
@ -384,7 +413,10 @@ void SDRThread::run() {
if (activeDev != NULL) {
std::cout << "device init()" << std::endl;
init();
if (!init()) {
std::cout << "SDR Thread stream init error." << std::endl;
return;
}
std::cout << "starting readLoop()" << std::endl;
activeDev->setActive(true);
readLoop();

View File

@ -40,7 +40,7 @@ typedef ThreadQueue<SDRThreadIQData *> SDRThreadIQDataQueue;
class SDRThread : public IOThread {
private:
void init();
bool init();
void deinit();
void readStream(SDRThreadIQDataQueue* iqDataOutQueue);
void readLoop();

View File

@ -128,17 +128,18 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glViewport(0, 0, ClientSize.x, ClientSize.y);
if (scopePanel.getMode() == ScopePanel::SCOPE_MODE_XY && !spectrumVisible()) {
glDrawBuffer(GL_FRONT);
glContext->DrawBegin(false);
} else {
glDrawBuffer(GL_BACK);
// TODO: find out why frontbuffer drawing has stopped working in wx 3.1.0?
// if (scopePanel.getMode() == ScopePanel::SCOPE_MODE_XY && !spectrumVisible()) {
// glDrawBuffer(GL_FRONT);
// glContext->DrawBegin(false);
// } else {
// glDrawBuffer(GL_BACK);
glContext->DrawBegin();
bgPanel.setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground * 3.0, RGBA4f(0,0,0,1));
bgPanel.calcTransform(CubicVR::mat4::identity());
bgPanel.draw();
}
// }
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -216,9 +217,9 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->DrawTunerTitles(ppmMode);
glContext->DrawEnd();
if (scopePanel.getMode() != ScopePanel::SCOPE_MODE_XY || spectrumVisible()) {
// if (scopePanel.getMode() != ScopePanel::SCOPE_MODE_XY || spectrumVisible()) {
SwapBuffers();
}
// }
}