mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-27 14:09:11 -05:00
commit
88c1bb5d51
@ -114,7 +114,7 @@ void DeviceConfig::load(DataNode *node) {
|
||||
busy_lock.unlock();
|
||||
}
|
||||
|
||||
AppConfig::AppConfig() {
|
||||
AppConfig::AppConfig() : configName("") {
|
||||
winX.store(0);
|
||||
winY.store(0);
|
||||
winW.store(0);
|
||||
@ -122,6 +122,7 @@ AppConfig::AppConfig() {
|
||||
winMax.store(false);
|
||||
themeId.store(0);
|
||||
snap.store(1);
|
||||
centerFreq.store(100000000);
|
||||
}
|
||||
|
||||
|
||||
@ -195,6 +196,35 @@ long long AppConfig::getSnap() {
|
||||
return snap.load();
|
||||
}
|
||||
|
||||
void AppConfig::setCenterFreq(long long freqVal) {
|
||||
centerFreq.store(freqVal);
|
||||
}
|
||||
|
||||
long long AppConfig::getCenterFreq() {
|
||||
return centerFreq.load();
|
||||
}
|
||||
|
||||
void AppConfig::setConfigName(std::string configName) {
|
||||
this->configName = configName;
|
||||
}
|
||||
|
||||
std::string AppConfig::getConfigFileName(bool ignoreName) {
|
||||
std::string cfgFileDir = getConfigDir();
|
||||
|
||||
wxFileName cfgFile;
|
||||
if (configName.length() && !ignoreName) {
|
||||
std::string tempFn("config-");
|
||||
tempFn.append(configName);
|
||||
tempFn.append(".xml");
|
||||
cfgFile = wxFileName(cfgFileDir, tempFn);
|
||||
} else {
|
||||
cfgFile = wxFileName(cfgFileDir, "config.xml");
|
||||
}
|
||||
|
||||
std::string cfgFileName = cfgFile.GetFullPath(wxPATH_NATIVE).ToStdString();
|
||||
|
||||
return cfgFileName;
|
||||
}
|
||||
|
||||
bool AppConfig::save() {
|
||||
DataTree cfg;
|
||||
@ -212,6 +242,7 @@ bool AppConfig::save() {
|
||||
*window_node->newChild("max") = winMax.load();
|
||||
*window_node->newChild("theme") = themeId.load();
|
||||
*window_node->newChild("snap") = snap.load();
|
||||
*window_node->newChild("center_freq") = centerFreq.load();
|
||||
}
|
||||
|
||||
DataNode *devices_node = cfg.rootNode()->newChild("devices");
|
||||
@ -222,11 +253,7 @@ bool AppConfig::save() {
|
||||
device_config_i->second->save(device_node);
|
||||
}
|
||||
|
||||
|
||||
std::string cfgFileDir = getConfigDir();
|
||||
|
||||
wxFileName cfgFile = wxFileName(cfgFileDir, "config.xml");
|
||||
std::string cfgFileName = cfgFile.GetFullPath(wxPATH_NATIVE).ToStdString();
|
||||
std::string cfgFileName = getConfigFileName();
|
||||
|
||||
if (!cfg.SaveToFileXML(cfgFileName)) {
|
||||
std::cout << "Error saving :: configuration file '" << cfgFileName << "' is not writable!" << std::endl;
|
||||
@ -240,11 +267,27 @@ bool AppConfig::load() {
|
||||
DataTree cfg;
|
||||
std::string cfgFileDir = getConfigDir();
|
||||
|
||||
wxFileName cfgFile = wxFileName(cfgFileDir, "config.xml");
|
||||
std::string cfgFileName = cfgFile.GetFullPath(wxPATH_NATIVE).ToStdString();
|
||||
std::string cfgFileName = getConfigFileName();
|
||||
wxFileName cfgFile = wxFileName(cfgFileName);
|
||||
|
||||
if (!cfgFile.Exists()) {
|
||||
return true;
|
||||
if (configName.length()) {
|
||||
wxFileName baseConfig = wxFileName(getConfigFileName(true));
|
||||
if (baseConfig.Exists()) {
|
||||
std::string baseConfigFileName = baseConfig.GetFullPath(wxPATH_NATIVE).ToStdString();
|
||||
std::cout << "Creating new configuration file '" << cfgFileName << "' by copying '" << baseConfigFileName << "'..";
|
||||
wxCopyFile(baseConfigFileName, cfgFileName);
|
||||
if (!cfgFile.Exists()) {
|
||||
std::cout << "failed." << std::endl;
|
||||
return true;
|
||||
}
|
||||
std::cout << "ok." << std::endl;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfgFile.IsFileReadable()) {
|
||||
@ -290,7 +333,13 @@ bool AppConfig::load() {
|
||||
win_node->getNext("snap")->element()->get(snapVal);
|
||||
snap.store(snapVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (win_node->hasAnother("center_freq")) {
|
||||
long long freqVal;
|
||||
win_node->getNext("center_freq")->element()->get(freqVal);
|
||||
centerFreq.store(freqVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.rootNode()->hasAnother("devices")) {
|
||||
DataNode *devices_node = cfg.rootNode()->getNext("devices");
|
||||
|
@ -59,14 +59,21 @@ public:
|
||||
void setSnap(long long snapVal);
|
||||
long long getSnap();
|
||||
|
||||
void setCenterFreq(long long freqVal);
|
||||
long long getCenterFreq();
|
||||
|
||||
void setConfigName(std::string configName);
|
||||
std::string getConfigFileName(bool ignoreName=false);
|
||||
bool save();
|
||||
bool load();
|
||||
bool reset();
|
||||
|
||||
private:
|
||||
std::string configName;
|
||||
std::map<std::string, DeviceConfig *> deviceConfig;
|
||||
std::atomic_int winX,winY,winW,winH;
|
||||
std::atomic_bool winMax;
|
||||
std::atomic_int themeId;
|
||||
std::atomic_llong snap;
|
||||
std::atomic_llong centerFreq;
|
||||
};
|
||||
|
@ -93,14 +93,14 @@ AppFrame::AppFrame() :
|
||||
|
||||
demodSpectrumCanvas = new SpectrumCanvas(this, attribList);
|
||||
demodSpectrumCanvas->setup(1024);
|
||||
demodSpectrumCanvas->setView(DEFAULT_FREQ, 300000);
|
||||
demodSpectrumCanvas->setView(wxGetApp().getConfig()->getCenterFreq(), 300000);
|
||||
demodVisuals->Add(demodSpectrumCanvas, 3, wxEXPAND | wxALL, 0);
|
||||
|
||||
demodVisuals->AddSpacer(1);
|
||||
|
||||
demodWaterfallCanvas = new WaterfallCanvas(this, attribList);
|
||||
demodWaterfallCanvas->setup(1024, 128);
|
||||
demodWaterfallCanvas->setView(DEFAULT_FREQ, 300000);
|
||||
demodWaterfallCanvas->setView(wxGetApp().getConfig()->getCenterFreq(), 300000);
|
||||
demodWaterfallCanvas->attachSpectrumCanvas(demodSpectrumCanvas);
|
||||
demodSpectrumCanvas->attachWaterfallCanvas(demodWaterfallCanvas);
|
||||
demodVisuals->Add(demodWaterfallCanvas, 6, wxEXPAND | wxALL, 0);
|
||||
@ -357,7 +357,6 @@ AppFrame::AppFrame() :
|
||||
#ifdef _WIN32
|
||||
SetIcon(wxICON(frame_icon));
|
||||
#endif
|
||||
GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), DEFAULT_FREQ));
|
||||
|
||||
wxAcceleratorEntry entries[3];
|
||||
entries[0].Set(wxACCEL_CTRL, (int) 'O', wxID_OPEN);
|
||||
@ -447,7 +446,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||
saveSession(saveFileDialog.GetPath().ToStdString());
|
||||
} else if (event.GetId() == wxID_RESET) {
|
||||
wxGetApp().getDemodMgr().terminateAll();
|
||||
wxGetApp().setFrequency(DEFAULT_FREQ);
|
||||
wxGetApp().setFrequency(100000000);
|
||||
wxGetApp().setOffset(0);
|
||||
SetTitle(CUBICSDR_TITLE);
|
||||
currentSessionFile = "";
|
||||
@ -563,6 +562,7 @@ void AppFrame::OnClose(wxCloseEvent& event) {
|
||||
wxGetApp().getConfig()->setWindowMaximized(this->IsMaximized());
|
||||
wxGetApp().getConfig()->setTheme(ThemeMgr::mgr.getTheme());
|
||||
wxGetApp().getConfig()->setSnap(wxGetApp().getFrequencySnap());
|
||||
wxGetApp().getConfig()->setCenterFreq(wxGetApp().getFrequency());
|
||||
wxGetApp().getConfig()->save();
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -63,9 +63,7 @@ bool CubicSDR::OnInit() {
|
||||
|
||||
wxApp::SetAppName("CubicSDR");
|
||||
|
||||
config.load();
|
||||
|
||||
frequency = DEFAULT_FREQ;
|
||||
frequency = wxGetApp().getConfig()->getCenterFreq();
|
||||
offset = 0;
|
||||
ppm = 0;
|
||||
directSamplingMode = 0;
|
||||
@ -194,6 +192,24 @@ PrimaryGLContext& CubicSDR::GetContext(wxGLCanvas *canvas) {
|
||||
return *glContext;
|
||||
}
|
||||
|
||||
void CubicSDR::OnInitCmdLine(wxCmdLineParser& parser) {
|
||||
parser.SetDesc (commandLineInfo);
|
||||
parser.SetSwitchChars (wxT("-"));
|
||||
}
|
||||
|
||||
bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) {
|
||||
wxString *confName = new wxString;
|
||||
if (parser.Found("c",confName)) {
|
||||
if (confName) {
|
||||
config.setConfigName(confName->ToStdString());
|
||||
}
|
||||
}
|
||||
|
||||
config.load();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CubicSDR::setFrequency(long long freq) {
|
||||
if (freq < sampleRate / 2) {
|
||||
freq = sampleRate / 2;
|
||||
|
@ -17,12 +17,14 @@
|
||||
#include "AppConfig.h"
|
||||
#include "AppFrame.h"
|
||||
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
#define NUM_DEMODULATORS 1
|
||||
|
||||
class CubicSDR: public wxApp {
|
||||
public:
|
||||
CubicSDR() :
|
||||
appframe(NULL), m_glContext(NULL), frequency(DEFAULT_FREQ), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL), sampleRate(DEFAULT_SAMPLE_RATE), offset(0), snap(1), directSamplingMode(0), ppm(0) {
|
||||
appframe(NULL), m_glContext(NULL), frequency(0), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL), sampleRate(DEFAULT_SAMPLE_RATE), offset(0), snap(1), directSamplingMode(0), ppm(0) {
|
||||
|
||||
}
|
||||
|
||||
@ -31,6 +33,9 @@ public:
|
||||
virtual bool OnInit();
|
||||
virtual int OnExit();
|
||||
|
||||
virtual void OnInitCmdLine(wxCmdLineParser& parser);
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
|
||||
|
||||
void setFrequency(long long freq);
|
||||
long long getFrequency();
|
||||
|
||||
@ -94,4 +99,11 @@ private:
|
||||
std::thread *t_PostSDR;
|
||||
};
|
||||
|
||||
static const wxCmdLineEntryDesc commandLineInfo [] =
|
||||
{
|
||||
{ wxCMD_LINE_SWITCH, "h", "help", "Command line parameter help", wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
|
||||
{ wxCMD_LINE_OPTION, "c", "config", "Specify a named configuration to use, i.e. '-c ham'" },
|
||||
{ wxCMD_LINE_NONE }
|
||||
};
|
||||
|
||||
DECLARE_APP(CubicSDR)
|
||||
|
@ -30,7 +30,6 @@ const char filePathSeparator =
|
||||
#define DEFAULT_SAMPLE_RATE 2400000
|
||||
#define DEFAULT_FFT_SIZE 2048
|
||||
|
||||
#define DEFAULT_FREQ 100000000
|
||||
#define DEFAULT_DEMOD_TYPE 1
|
||||
#define DEFAULT_DEMOD_BW 200000
|
||||
|
||||
|
@ -12,8 +12,15 @@ std::map<int, int> AudioThread::deviceSampleRate;
|
||||
std::map<int, std::thread *> AudioThread::deviceThread;
|
||||
|
||||
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) :
|
||||
currentInput(NULL), inputQueue(inputQueue), audioQueuePtr(0), underflowCount(0), terminated(false), active(false), outputDevice(-1), gain(
|
||||
currentInput(NULL), inputQueue(inputQueue), gain(
|
||||
1.0), threadQueueNotify(threadQueueNotify), sampleRate(0), nBufferFrames(1024) {
|
||||
|
||||
audioQueuePtr.store(0);
|
||||
underflowCount.store(0);
|
||||
terminated.store(false);
|
||||
active.store(false);
|
||||
outputDevice.store(-1);
|
||||
|
||||
boundThreads = new std::vector<AudioThread *>;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,22 @@
|
||||
#include "DemodulatorInstance.h"
|
||||
|
||||
DemodulatorInstance::DemodulatorInstance() :
|
||||
t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), terminated(true), audioTerminated(true), demodTerminated(
|
||||
true), preDemodTerminated(true), active(false), squelch(false), stereo(false), tracking(false), follow(false), currentAudioSampleRate(0), currentFrequency(0), currentBandwidth(0), currentOutputDevice(-1), currentAudioGain(1.0) {
|
||||
t_Demod(NULL), t_PreDemod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), currentAudioGain(1.0) {
|
||||
|
||||
terminated.store(true);
|
||||
audioTerminated.store(true);
|
||||
demodTerminated.store(true);
|
||||
preDemodTerminated.store(true);
|
||||
active.store(false);
|
||||
squelch.store(false);
|
||||
stereo.store(false);
|
||||
tracking.store(false);
|
||||
follow.store(false);
|
||||
currentAudioSampleRate.store(0);
|
||||
currentFrequency.store(0);
|
||||
currentBandwidth.store(0);
|
||||
currentOutputDevice.store(-1);
|
||||
|
||||
|
||||
label = new std::string("Unnamed");
|
||||
threadQueueDemod = new DemodulatorThreadInputQueue;
|
||||
|
@ -10,9 +10,11 @@
|
||||
|
||||
DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* iqInputQueue, DemodulatorThreadPostInputQueue* iqOutputQueue,
|
||||
DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) :
|
||||
iqInputQueue(iqInputQueue), iqOutputQueue(iqOutputQueue), terminated(false), initialized(false), audioResampler(NULL), stereoResampler(NULL), iqResampleRatio(
|
||||
iqInputQueue(iqInputQueue), iqOutputQueue(iqOutputQueue), audioResampler(NULL), stereoResampler(NULL), iqResampleRatio(
|
||||
1), audioResampleRatio(1), firStereoRight(NULL), firStereoLeft(NULL), iirStereoPilot(NULL), iqResampler(NULL), commandQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl(
|
||||
threadQueueControl) {
|
||||
terminated.store(false);
|
||||
initialized.store(false);
|
||||
|
||||
freqShifter = nco_crcf_create(LIQUID_VCO);
|
||||
shiftFrequency = 0;
|
||||
|
@ -14,10 +14,14 @@
|
||||
DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* iqInputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
|
||||
DemodulatorThreadCommandQueue* threadQueueNotify) :
|
||||
iqInputQueue(iqInputQueue), audioVisOutputQueue(NULL), audioOutputQueue(NULL), iqAutoGain(NULL), amOutputCeil(1), amOutputCeilMA(1), amOutputCeilMAA(
|
||||
1), stereo(false), agcEnabled(true), terminated(
|
||||
false), demodulatorType(DEMOD_TYPE_FM), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelchLevel(0), signalLevel(
|
||||
1), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelchLevel(0), signalLevel(
|
||||
0), squelchEnabled(false), audioSampleRate(0) {
|
||||
|
||||
stereo.store(false);
|
||||
agcEnabled.store(false);
|
||||
terminated.store(false);
|
||||
demodulatorType.store(DEMOD_TYPE_FM);
|
||||
|
||||
demodFM = freqdem_create(0.5);
|
||||
demodAM_USB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_USB, 1);
|
||||
demodAM_LSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_LSB, 1);
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include <vector>
|
||||
|
||||
DemodulatorWorkerThread::DemodulatorWorkerThread(DemodulatorThreadWorkerCommandQueue* in, DemodulatorThreadWorkerResultQueue* out) :
|
||||
terminated(false), commandQueue(in), resultQueue(out) {
|
||||
|
||||
commandQueue(in), resultQueue(out) {
|
||||
terminated.store(false);
|
||||
}
|
||||
|
||||
DemodulatorWorkerThread::~DemodulatorWorkerThread() {
|
||||
|
@ -6,7 +6,10 @@
|
||||
#include <deque>
|
||||
|
||||
SDRPostThread::SDRPostThread() :
|
||||
iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL), num_vis_samples(16384*2), swapIQ(false) {
|
||||
iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), dcFilter(NULL), num_vis_samples(16384*2) {
|
||||
|
||||
terminated.store(false);
|
||||
swapIQ.store(false);
|
||||
|
||||
// create a lookup table
|
||||
for (unsigned int i = 0; i <= 0xffff; i++) {
|
||||
|
@ -4,7 +4,10 @@
|
||||
#include "CubicSDR.h"
|
||||
|
||||
SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) :
|
||||
commandQueue(pQueue), iqDataOutQueue(NULL), terminated(false), offset(0), deviceId(-1) {
|
||||
commandQueue(pQueue), iqDataOutQueue(NULL) {
|
||||
terminated.store(false);
|
||||
offset.store(0);
|
||||
deviceId.store(-1);
|
||||
dev = NULL;
|
||||
sampleRate.store(DEFAULT_SAMPLE_RATE);
|
||||
}
|
||||
@ -141,7 +144,7 @@ void SDRThread::threadMain() {
|
||||
|
||||
signed char buf[BUF_SIZE];
|
||||
|
||||
long long frequency = DEFAULT_FREQ;
|
||||
long long frequency = wxGetApp().getConfig()->getCenterFreq();
|
||||
int ppm = devConfig->getPPM();
|
||||
int direct_sampling_mode = devConfig->getDirectSampling();;
|
||||
int buf_size = BUF_SIZE;
|
||||
|
Loading…
Reference in New Issue
Block a user