mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 13:48:38 -05:00
AM, USB and LSB somewhat working
This commit is contained in:
parent
8b89b27b40
commit
4f43f65065
@ -38,35 +38,35 @@ AppFrame::AppFrame() :
|
|||||||
wxBoxSizer *demodTray = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer *demodTray = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
demodTray->AddSpacer(5);
|
demodTray->AddSpacer(5);
|
||||||
demodOpts->AddSpacer(5);
|
demodOpts->AddSpacer(5);
|
||||||
|
|
||||||
wxStaticText *audioDeviceLabel = new wxStaticText(this, wxID_ANY, wxString("Audio Device:"));
|
wxStaticText *audioDeviceLabel = new wxStaticText(this, wxID_ANY, wxString("Audio Device:"));
|
||||||
demodOpts->Add(audioDeviceLabel, 1, wxFIXED_MINSIZE | wxALL, 0);
|
demodOpts->Add(audioDeviceLabel, 1, wxFIXED_MINSIZE | wxALL, 0);
|
||||||
|
|
||||||
wxArrayString str;
|
wxArrayString str;
|
||||||
str.Add("Primary Device");
|
str.Add("Primary Device");
|
||||||
wxChoice *wxCh = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, str);
|
wxChoice *wxCh = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, str);
|
||||||
demodOpts->Add(wxCh, 1, wxFIXED_MINSIZE | wxALL, 0);
|
demodOpts->Add(wxCh, 1, wxFIXED_MINSIZE | wxALL, 0);
|
||||||
|
|
||||||
demodOpts->AddSpacer(2);
|
demodOpts->AddSpacer(2);
|
||||||
|
|
||||||
wxStaticText *demodTypeLabel = new wxStaticText(this, wxID_ANY, wxString("Demodulation:"));
|
wxStaticText *demodTypeLabel = new wxStaticText(this, wxID_ANY, wxString("Demodulation:"));
|
||||||
demodOpts->Add(demodTypeLabel, 1, wxFIXED_MINSIZE | wxALL, 0);
|
demodOpts->Add(demodTypeLabel, 1, wxFIXED_MINSIZE | wxALL, 0);
|
||||||
|
|
||||||
str.Clear();
|
str.Clear();
|
||||||
str.Add("FM");
|
str.Add("FM");
|
||||||
str.Add("FM Stereo");
|
str.Add("FM Stereo");
|
||||||
str.Add("AM");
|
str.Add("AM");
|
||||||
str.Add("LSB");
|
str.Add("LSB");
|
||||||
str.Add("USB");
|
str.Add("USB");
|
||||||
wxChoice *wxDemodChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, str);
|
wxChoice *wxDemodChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, str);
|
||||||
demodOpts->Add(wxDemodChoice, 1, wxFIXED_MINSIZE | wxALL, 0);
|
demodOpts->Add(wxDemodChoice, 1, wxFIXED_MINSIZE | wxALL, 0);
|
||||||
|
|
||||||
demodOpts->AddSpacer(5);
|
demodOpts->AddSpacer(5);
|
||||||
demodTray->AddSpacer(5);
|
demodTray->AddSpacer(5);
|
||||||
|
|
||||||
demodTray->Add(demodOpts, 1, wxEXPAND | wxALL, 0); */
|
demodTray->Add(demodOpts, 1, wxEXPAND | wxALL, 0); */
|
||||||
|
|
||||||
demodSpectrumCanvas = new SpectrumCanvas(this, NULL);
|
demodSpectrumCanvas = new SpectrumCanvas(this, NULL);
|
||||||
demodSpectrumCanvas->Setup(1024);
|
demodSpectrumCanvas->Setup(1024);
|
||||||
@ -123,7 +123,7 @@ AppFrame::AppFrame() :
|
|||||||
wxMenu *menu = new wxMenu;
|
wxMenu *menu = new wxMenu;
|
||||||
|
|
||||||
std::vector<RtAudio::DeviceInfo>::iterator devices_i;
|
std::vector<RtAudio::DeviceInfo>::iterator devices_i;
|
||||||
std::map<int,RtAudio::DeviceInfo>::iterator mdevices_i;
|
std::map<int, RtAudio::DeviceInfo>::iterator mdevices_i;
|
||||||
AudioThread::enumerateDevices(devices);
|
AudioThread::enumerateDevices(devices);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -141,8 +141,8 @@ AppFrame::AppFrame() :
|
|||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
for (mdevices_i = output_devices.begin(); mdevices_i != output_devices.end(); mdevices_i++) {
|
for (mdevices_i = output_devices.begin(); mdevices_i != output_devices.end(); mdevices_i++) {
|
||||||
wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE+mdevices_i->first,mdevices_i->second.name,wxT("Description?"));
|
wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE + mdevices_i->first, mdevices_i->second.name, wxT("Description?"));
|
||||||
itm->SetId(wxID_RT_AUDIO_DEVICE+mdevices_i->first);
|
itm->SetId(wxID_RT_AUDIO_DEVICE + mdevices_i->first);
|
||||||
if (mdevices_i->second.isDefaultOutput) {
|
if (mdevices_i->second.isDefaultOutput) {
|
||||||
itm->Check(true);
|
itm->Check(true);
|
||||||
}
|
}
|
||||||
@ -153,14 +153,13 @@ AppFrame::AppFrame() :
|
|||||||
menuBar->Append(menu, wxT("Output &Device"));
|
menuBar->Append(menu, wxT("Output &Device"));
|
||||||
|
|
||||||
wxMenu *demodMenu = new wxMenu;
|
wxMenu *demodMenu = new wxMenu;
|
||||||
demod_menuitems[DemodulatorType::DEMOD_TYPE_FM] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_FM,wxT("FM"),wxT("Description?"));
|
demod_menuitems[DEMOD_TYPE_FM] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_FM, wxT("FM"), wxT("Description?"));
|
||||||
demod_menuitems[DemodulatorType::DEMOD_TYPE_AM] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_AM,wxT("AM"),wxT("Description?"));
|
demod_menuitems[DEMOD_TYPE_AM] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_AM, wxT("AM"), wxT("Description?"));
|
||||||
demod_menuitems[DemodulatorType::DEMOD_TYPE_LSB] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_LSB,wxT("LSB"),wxT("Description?"));
|
demod_menuitems[DEMOD_TYPE_LSB] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_LSB, wxT("LSB"), wxT("Description?"));
|
||||||
demod_menuitems[DemodulatorType::DEMOD_TYPE_USB] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_USB,wxT("USB"),wxT("Description?"));
|
demod_menuitems[DEMOD_TYPE_USB] = demodMenu->AppendRadioItem(wxID_DEMOD_TYPE_USB, wxT("USB"), wxT("Description?"));
|
||||||
|
|
||||||
menuBar->Append(demodMenu, wxT("Demodulaton &Type"));
|
menuBar->Append(demodMenu, wxT("Demodulaton &Type"));
|
||||||
|
|
||||||
|
|
||||||
SetMenuBar(menuBar);
|
SetMenuBar(menuBar);
|
||||||
|
|
||||||
CreateStatusBar();
|
CreateStatusBar();
|
||||||
@ -180,25 +179,25 @@ AppFrame::~AppFrame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AppFrame::OnMenu(wxCommandEvent& event) {
|
void AppFrame::OnMenu(wxCommandEvent& event) {
|
||||||
if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE+devices.size()) {
|
if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + devices.size()) {
|
||||||
if (activeDemodulator) {
|
if (activeDemodulator) {
|
||||||
activeDemodulator->setOutputDevice(event.GetId()-wxID_RT_AUDIO_DEVICE);
|
activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE);
|
||||||
activeDemodulator = NULL;
|
activeDemodulator = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeDemodulator) {
|
if (activeDemodulator) {
|
||||||
if (event.GetId() == wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_FM) {
|
if (event.GetId() == wxID_DEMOD_TYPE_FM) {
|
||||||
activeDemodulator->setDemodulatorType(DemodulatorType::DEMOD_TYPE_FM);
|
activeDemodulator->setDemodulatorType(DEMOD_TYPE_FM);
|
||||||
activeDemodulator = NULL;
|
activeDemodulator = NULL;
|
||||||
} else if (event.GetId() == wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_AM) {
|
} else if (event.GetId() == wxID_DEMOD_TYPE_AM) {
|
||||||
activeDemodulator->setDemodulatorType(DemodulatorType::DEMOD_TYPE_AM);
|
activeDemodulator->setDemodulatorType(DEMOD_TYPE_AM);
|
||||||
activeDemodulator = NULL;
|
activeDemodulator = NULL;
|
||||||
} else if (event.GetId() == wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_LSB) {
|
} else if (event.GetId() == wxID_DEMOD_TYPE_LSB) {
|
||||||
activeDemodulator->setDemodulatorType(DemodulatorType::DEMOD_TYPE_LSB);
|
activeDemodulator->setDemodulatorType(DEMOD_TYPE_LSB);
|
||||||
activeDemodulator = NULL;
|
activeDemodulator = NULL;
|
||||||
} else if (event.GetId() == wxID_DEMOD_TYPE+DemodulatorType::DEMOD_TYPE_USB) {
|
} else if (event.GetId() == wxID_DEMOD_TYPE_USB) {
|
||||||
activeDemodulator->setDemodulatorType(DemodulatorType::DEMOD_TYPE_USB);
|
activeDemodulator->setDemodulatorType(DEMOD_TYPE_USB);
|
||||||
activeDemodulator = NULL;
|
activeDemodulator = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,7 +231,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
|||||||
int outputDevice = demod->getOutputDevice();
|
int outputDevice = demod->getOutputDevice();
|
||||||
scopeCanvas->setDeviceName(output_devices[outputDevice].name);
|
scopeCanvas->setDeviceName(output_devices[outputDevice].name);
|
||||||
output_device_menuitems[outputDevice]->Check(true);
|
output_device_menuitems[outputDevice]->Check(true);
|
||||||
DemodulatorType dType = demod->getDemodulatorType();
|
int dType = demod->getDemodulatorType();
|
||||||
demod_menuitems[dType]->Check(true);
|
demod_menuitems[dType]->Check(true);
|
||||||
}
|
}
|
||||||
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
|
||||||
@ -244,10 +243,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
|||||||
if (demodBw > SRATE / 2) {
|
if (demodBw > SRATE / 2) {
|
||||||
demodBw = SRATE / 2;
|
demodBw = SRATE / 2;
|
||||||
}
|
}
|
||||||
if (demodBw != demodWaterfallCanvas->GetBandwidth()) {
|
if (demodBw < 80000) {
|
||||||
demodWaterfallCanvas->SetBandwidth(demodBw);
|
demodBw = 80000;
|
||||||
demodSpectrumCanvas->SetBandwidth(demodBw);
|
|
||||||
}
|
}
|
||||||
|
demodWaterfallCanvas->SetBandwidth(demodBw);
|
||||||
|
demodSpectrumCanvas->SetBandwidth(demodBw);
|
||||||
}
|
}
|
||||||
demodSignalMeter->setLevel(demod->getSignalLevel());
|
demodSignalMeter->setLevel(demod->getSignalLevel());
|
||||||
if (demodSignalMeter->inputChanged()) {
|
if (demodSignalMeter->inputChanged()) {
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#define wxID_RT_AUDIO_DEVICE 1000
|
#define wxID_RT_AUDIO_DEVICE 1000
|
||||||
#define wxID_DEMOD_TYPE 1500
|
#define wxID_DEMOD_TYPE_FM 2000
|
||||||
|
#define wxID_DEMOD_TYPE_AM 2001
|
||||||
|
#define wxID_DEMOD_TYPE_LSB 2002
|
||||||
|
#define wxID_DEMOD_TYPE_USB 2003
|
||||||
|
|
||||||
// Define a new frame type
|
// Define a new frame type
|
||||||
class AppFrame: public wxFrame {
|
class AppFrame: public wxFrame {
|
||||||
@ -42,7 +45,7 @@ private:
|
|||||||
std::map<int,RtAudio::DeviceInfo> output_devices;
|
std::map<int,RtAudio::DeviceInfo> output_devices;
|
||||||
std::map<int,wxMenuItem *> output_device_menuitems;
|
std::map<int,wxMenuItem *> output_device_menuitems;
|
||||||
|
|
||||||
std::map<DemodulatorType,wxMenuItem *> demod_menuitems;
|
std::map<int,wxMenuItem *> demod_menuitems;
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#define DEFAULT_FFT_SIZE 2048
|
#define DEFAULT_FFT_SIZE 2048
|
||||||
|
|
||||||
#define DEFAULT_FREQ 98900000
|
//#define DEFAULT_FREQ 98900000
|
||||||
|
#define DEFAULT_FREQ 132000000
|
||||||
#define AUDIO_FREQUENCY 44100
|
#define AUDIO_FREQUENCY 44100
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
enum DemodulatorType {
|
#define DEMOD_TYPE_NULL 0
|
||||||
DEMOD_TYPE_NULL, DEMOD_TYPE_AM, DEMOD_TYPE_FM, DEMOD_TYPE_LSB, DEMOD_TYPE_USB
|
#define DEMOD_TYPE_FM 1
|
||||||
};
|
#define DEMOD_TYPE_AM 2
|
||||||
|
#define DEMOD_TYPE_LSB 3
|
||||||
|
#define DEMOD_TYPE_USB 4
|
||||||
|
|
||||||
|
|
||||||
class DemodulatorThread;
|
class DemodulatorThread;
|
||||||
class DemodulatorThreadCommand {
|
class DemodulatorThreadCommand {
|
||||||
@ -41,14 +44,15 @@ public:
|
|||||||
class DemodulatorThreadControlCommand {
|
class DemodulatorThreadControlCommand {
|
||||||
public:
|
public:
|
||||||
enum DemodulatorThreadControlCommandEnum {
|
enum DemodulatorThreadControlCommandEnum {
|
||||||
DEMOD_THREAD_CMD_CTL_NULL, DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO, DEMOD_THREAD_CMD_CTL_SQUELCH_OFF
|
DEMOD_THREAD_CMD_CTL_NULL, DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO, DEMOD_THREAD_CMD_CTL_SQUELCH_OFF, DEMOD_THREAD_CMD_CTL_TYPE
|
||||||
};
|
};
|
||||||
|
|
||||||
DemodulatorThreadControlCommand() :
|
DemodulatorThreadControlCommand() :
|
||||||
cmd(DEMOD_THREAD_CMD_CTL_NULL) {
|
cmd(DEMOD_THREAD_CMD_CTL_NULL), demodType(DEMOD_TYPE_NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorThreadControlCommandEnum cmd;
|
DemodulatorThreadControlCommandEnum cmd;
|
||||||
|
int demodType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DemodulatorThreadIQData: public ReferenceCounter {
|
class DemodulatorThreadIQData: public ReferenceCounter {
|
||||||
@ -122,7 +126,7 @@ public:
|
|||||||
unsigned int bandwidth; // set equal to disable second stage re-sampling?
|
unsigned int bandwidth; // set equal to disable second stage re-sampling?
|
||||||
unsigned int audioSampleRate;
|
unsigned int audioSampleRate;
|
||||||
|
|
||||||
DemodulatorType demodType;
|
int demodType;
|
||||||
|
|
||||||
DemodulatorThreadParameters() :
|
DemodulatorThreadParameters() :
|
||||||
frequency(0), inputRate(SRATE), bandwidth(200000), audioSampleRate(
|
frequency(0), inputRate(SRATE), bandwidth(200000), audioSampleRate(
|
||||||
|
@ -19,6 +19,8 @@ DemodulatorInstance::DemodulatorInstance() :
|
|||||||
audioThread = new AudioThread(audioInputQueue, threadQueueNotify);
|
audioThread = new AudioThread(audioInputQueue, threadQueueNotify);
|
||||||
|
|
||||||
demodulatorThread->setAudioInputQueue(audioInputQueue);
|
demodulatorThread->setAudioInputQueue(audioInputQueue);
|
||||||
|
|
||||||
|
currentDemodType = demodulatorThread->getDemodulatorType();
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorInstance::~DemodulatorInstance() {
|
DemodulatorInstance::~DemodulatorInstance() {
|
||||||
@ -208,11 +210,17 @@ int DemodulatorInstance::getOutputDevice() {
|
|||||||
return audioThread->getOutputDevice();
|
return audioThread->getOutputDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorInstance::setDemodulatorType(DemodulatorType demod_type_in) {
|
void DemodulatorInstance::setDemodulatorType(int demod_type_in) {
|
||||||
demodulatorThread->setDemodulatorType(demod_type_in);
|
if (demodulatorThread && threadQueueControl) {
|
||||||
|
DemodulatorThreadControlCommand command;
|
||||||
|
command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_TYPE;
|
||||||
|
currentDemodType = demod_type_in;
|
||||||
|
command.demodType = demod_type_in;
|
||||||
|
threadQueueControl->push(command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorType DemodulatorInstance::getDemodulatorType() {
|
int DemodulatorInstance::getDemodulatorType() {
|
||||||
return demodulatorThread->getDemodulatorType();
|
return currentDemodType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ public:
|
|||||||
void setOutputDevice(int device_id);
|
void setOutputDevice(int device_id);
|
||||||
int getOutputDevice();
|
int getOutputDevice();
|
||||||
|
|
||||||
void setDemodulatorType(DemodulatorType demod_type_in);
|
void setDemodulatorType(int demod_type_in);
|
||||||
DemodulatorType getDemodulatorType();
|
int getDemodulatorType();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<std::string *> label; //
|
std::atomic<std::string *> label; //
|
||||||
@ -75,5 +75,7 @@ private:
|
|||||||
std::atomic<bool> active;
|
std::atomic<bool> active;
|
||||||
std::atomic<bool> squelch;
|
std::atomic<bool> squelch;
|
||||||
std::atomic<bool> stereo;
|
std::atomic<bool> stereo;
|
||||||
|
|
||||||
|
int currentDemodType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,8 +88,8 @@ void DemodulatorPreThread::threadMain() {
|
|||||||
commandQueue->pop(command);
|
commandQueue->pop(command);
|
||||||
switch (command.cmd) {
|
switch (command.cmd) {
|
||||||
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH:
|
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH:
|
||||||
if (command.int_value < 3000) {
|
if (command.int_value < 1500) {
|
||||||
command.int_value = 3000;
|
command.int_value = 1500;
|
||||||
}
|
}
|
||||||
if (command.int_value > SRATE) {
|
if (command.int_value > SRATE) {
|
||||||
command.int_value = SRATE;
|
command.int_value = SRATE;
|
||||||
|
@ -9,16 +9,14 @@
|
|||||||
DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
|
DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify) :
|
DemodulatorThreadCommandQueue* threadQueueNotify) :
|
||||||
postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), am_max(1), am_max_ma(1), am_max_maa(1), stereo(false), terminated(
|
postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), am_max(1), am_max_ma(1), am_max_maa(1), stereo(false), terminated(
|
||||||
false), demodulatorType(DemodulatorType::DEMOD_TYPE_FM), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelch_level(
|
false), demodulatorType(DEMOD_TYPE_FM), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelch_level(0), squelch_tolerance(
|
||||||
0), squelch_tolerance(0), signal_level(0), squelch_enabled(false) {
|
0), signal_level(0), squelch_enabled(false) {
|
||||||
|
|
||||||
fdem = freqdem_create(0.5);
|
fdem = freqdem_create(0.5);
|
||||||
liquid_ampmodem_type type_lsb = LIQUID_AMPMODEM_LSB;
|
ampdem_lsb = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_LSB, 1);
|
||||||
ampdem_lsb = ampmodem_create(1.0, 0.5, type_lsb, 1);
|
ampdem_usb = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_USB, 1);
|
||||||
liquid_ampmodem_type type_usb = LIQUID_AMPMODEM_USB;
|
ampdem = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 0);
|
||||||
ampdem_usb = ampmodem_create(1.0, -0.5, type_usb, 1);
|
ampdem_active = ampdem;
|
||||||
liquid_ampmodem_type type_dsb = LIQUID_AMPMODEM_DSB;
|
|
||||||
ampdem = ampmodem_create(0.5, 0.0, type_dsb, 0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
DemodulatorThread::~DemodulatorThread() {
|
DemodulatorThread::~DemodulatorThread() {
|
||||||
@ -66,8 +64,23 @@ void DemodulatorThread::threadMain() {
|
|||||||
firhilbf firR2C = firhilbf_create(m, slsl);
|
firhilbf firR2C = firhilbf_create(m, slsl);
|
||||||
firhilbf firC2R = firhilbf_create(m, slsl);
|
firhilbf firC2R = firhilbf_create(m, slsl);
|
||||||
|
|
||||||
nco_crcf nco_shift = nco_crcf_create(LIQUID_NCO);
|
nco_crcf nco_stereo_shift = nco_crcf_create(LIQUID_NCO);
|
||||||
double shift_freq = 0;
|
double nco_stereo_shift_freq = 0;
|
||||||
|
|
||||||
|
nco_crcf nco_ssb_shift_up = nco_crcf_create(LIQUID_NCO);
|
||||||
|
nco_crcf_set_frequency(nco_ssb_shift_up, (2.0 * M_PI) * 0.25);
|
||||||
|
|
||||||
|
|
||||||
|
nco_crcf nco_ssb_shift_down = nco_crcf_create(LIQUID_NCO);
|
||||||
|
nco_crcf_set_frequency(nco_ssb_shift_down, (2.0 * M_PI) * 0.25);
|
||||||
|
|
||||||
|
// estimate required filter length and generate filter
|
||||||
|
h_len = estimate_req_filter_len(ft,100.0);
|
||||||
|
float h2[h_len];
|
||||||
|
liquid_firdes_kaiser(h_len,0.25,As,0.0,h2);
|
||||||
|
|
||||||
|
firfilt_crcf ssb_fir_filter = firfilt_crcf_create(h2, h_len);
|
||||||
|
|
||||||
|
|
||||||
agc = agc_crcf_create();
|
agc = agc_crcf_create();
|
||||||
agc_crcf_set_bandwidth(agc, 0.9);
|
agc_crcf_set_bandwidth(agc, 0.9);
|
||||||
@ -106,7 +119,7 @@ void DemodulatorThread::threadMain() {
|
|||||||
freqdem_reset(fdem);
|
freqdem_reset(fdem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_size = ceil((double) (bufSize) * inp->resample_ratio);
|
int out_size = ceil((double) (bufSize) * inp->resample_ratio) + 32;
|
||||||
|
|
||||||
if (agc_data.size() != out_size) {
|
if (agc_data.size() != out_size) {
|
||||||
if (agc_data.capacity() < out_size) {
|
if (agc_data.capacity() < out_size) {
|
||||||
@ -131,7 +144,7 @@ void DemodulatorThread::threadMain() {
|
|||||||
demod_output.resize(num_written);
|
demod_output.resize(num_written);
|
||||||
}
|
}
|
||||||
|
|
||||||
int audio_out_size = ceil((double) (num_written) * audio_resample_ratio);
|
int audio_out_size = ceil((double) (num_written) * audio_resample_ratio) + 32;
|
||||||
|
|
||||||
agc_crcf_execute_block(agc, &resampled_data[0], num_written, &agc_data[0]);
|
agc_crcf_execute_block(agc, &resampled_data[0], num_written, &agc_data[0]);
|
||||||
|
|
||||||
@ -143,40 +156,51 @@ void DemodulatorThread::threadMain() {
|
|||||||
current_level = agc_crcf_get_signal_level(agc);
|
current_level = agc_crcf_get_signal_level(agc);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (demodulatorType) {
|
if (demodulatorType == DEMOD_TYPE_FM) {
|
||||||
case DemodulatorType::DEMOD_TYPE_FM:
|
|
||||||
freqdem_demodulate_block(fdem, &agc_data[0], num_written, &demod_output[0]);
|
freqdem_demodulate_block(fdem, &agc_data[0], num_written, &demod_output[0]);
|
||||||
break;
|
} else {
|
||||||
case DemodulatorType::DEMOD_TYPE_LSB:
|
float p;
|
||||||
for (int i = 0; i < num_written; i++) {
|
switch (demodulatorType) {
|
||||||
ampmodem_demodulate(ampdem_lsb, resampled_data[i], &demod_output[i]);
|
case DEMOD_TYPE_LSB:
|
||||||
|
for (int i = 0; i < num_written; i++) { // Reject upper band
|
||||||
|
nco_crcf_mix_up(nco_ssb_shift_up, resampled_data[i], &x);
|
||||||
|
nco_crcf_step(nco_ssb_shift_up);
|
||||||
|
firfilt_crcf_push(ssb_fir_filter, x);
|
||||||
|
firfilt_crcf_execute(ssb_fir_filter, &x);
|
||||||
|
nco_crcf_mix_down(nco_ssb_shift_down, x, &resampled_data[i]);
|
||||||
|
nco_crcf_step(nco_ssb_shift_down);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEMOD_TYPE_USB:
|
||||||
|
for (int i = 0; i < num_written; i++) { // Reject lower band
|
||||||
|
nco_crcf_mix_down(nco_ssb_shift_down, resampled_data[i], &x);
|
||||||
|
nco_crcf_step(nco_ssb_shift_down);
|
||||||
|
firfilt_crcf_push(ssb_fir_filter, x);
|
||||||
|
firfilt_crcf_execute(ssb_fir_filter, &x);
|
||||||
|
nco_crcf_mix_up(nco_ssb_shift_up, x, &resampled_data[i]);
|
||||||
|
nco_crcf_step(nco_ssb_shift_up);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEMOD_TYPE_AM:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
case DemodulatorType::DEMOD_TYPE_USB:
|
|
||||||
for (int i = 0; i < num_written; i++) {
|
|
||||||
ampmodem_demodulate(ampdem_usb, resampled_data[i], &demod_output[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case DemodulatorType::DEMOD_TYPE_AM:
|
|
||||||
am_max = 0;
|
am_max = 0;
|
||||||
|
|
||||||
for (int i = 0; i < num_written; i++) {
|
for (int i = 0; i < num_written; i++) {
|
||||||
ampmodem_demodulate(ampdem, resampled_data[i], &demod_output[i]);
|
ampmodem_demodulate(ampdem_active, resampled_data[i], &demod_output[i]);
|
||||||
if (demod_output[i] > am_max) {
|
if (demod_output[i] > am_max) {
|
||||||
am_max = demod_output[i];
|
am_max = demod_output[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
am_max_ma = am_max_ma + (am_max - am_max_ma) * 0.03;
|
am_max_ma = am_max_ma + (am_max - am_max_ma) * 0.05;
|
||||||
am_max_maa = am_max_maa + (am_max_ma - am_max_maa) * 0.03;
|
am_max_maa = am_max_maa + (am_max_ma - am_max_maa) * 0.05;
|
||||||
|
|
||||||
float gain = 0.95/am_max_maa;
|
float gain = 0.95 / am_max_maa;
|
||||||
|
|
||||||
for (int i = 0; i < num_written; i++) {
|
for (int i = 0; i < num_written; i++) {
|
||||||
demod_output[i] *= gain;
|
demod_output[i] *= gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_out_size != resampled_audio_output.size()) {
|
if (audio_out_size != resampled_audio_output.size()) {
|
||||||
@ -199,15 +223,15 @@ void DemodulatorThread::threadMain() {
|
|||||||
|
|
||||||
double freq = (2.0 * M_PI) * (((double) abs(38000)) / ((double) inp->bandwidth));
|
double freq = (2.0 * M_PI) * (((double) abs(38000)) / ((double) inp->bandwidth));
|
||||||
|
|
||||||
if (shift_freq != freq) {
|
if (nco_stereo_shift_freq != freq) {
|
||||||
nco_crcf_set_frequency(nco_shift, freq);
|
nco_crcf_set_frequency(nco_stereo_shift, freq);
|
||||||
shift_freq = freq;
|
nco_stereo_shift_freq = freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_written; i++) {
|
for (int i = 0; i < num_written; i++) {
|
||||||
firhilbf_r2c_execute(firR2C, demod_output[i], &x);
|
firhilbf_r2c_execute(firR2C, demod_output[i], &x);
|
||||||
nco_crcf_mix_down(nco_shift, x, &y);
|
nco_crcf_mix_down(nco_stereo_shift, x, &y);
|
||||||
nco_crcf_step(nco_shift);
|
nco_crcf_step(nco_stereo_shift);
|
||||||
firhilbf_c2r_execute(firC2R, y, &demod_output_stereo[i]);
|
firhilbf_c2r_execute(firC2R, y, &demod_output_stereo[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +334,8 @@ void DemodulatorThread::threadMain() {
|
|||||||
visOutQueue->push(ati_vis);
|
visOutQueue->push(ati_vis);
|
||||||
}
|
}
|
||||||
if (!threadQueueControl->empty()) {
|
if (!threadQueueControl->empty()) {
|
||||||
|
int newDemodType = DEMOD_TYPE_NULL;
|
||||||
|
|
||||||
while (!threadQueueControl->empty()) {
|
while (!threadQueueControl->empty()) {
|
||||||
DemodulatorThreadControlCommand command;
|
DemodulatorThreadControlCommand command;
|
||||||
threadQueueControl->pop(command);
|
threadQueueControl->pop(command);
|
||||||
@ -325,10 +351,30 @@ void DemodulatorThread::threadMain() {
|
|||||||
squelch_tolerance = 1;
|
squelch_tolerance = 1;
|
||||||
squelch_enabled = false;
|
squelch_enabled = false;
|
||||||
break;
|
break;
|
||||||
|
case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_TYPE:
|
||||||
|
newDemodType = command.demodType;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newDemodType != DEMOD_TYPE_NULL) {
|
||||||
|
switch (newDemodType) {
|
||||||
|
case DEMOD_TYPE_FM:
|
||||||
|
break;
|
||||||
|
case DEMOD_TYPE_LSB:
|
||||||
|
ampdem_active = ampdem_lsb;
|
||||||
|
break;
|
||||||
|
case DEMOD_TYPE_USB:
|
||||||
|
ampdem_active = ampdem_usb;
|
||||||
|
break;
|
||||||
|
case DEMOD_TYPE_AM:
|
||||||
|
ampdem_active = ampdem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
demodulatorType = newDemodType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inp->decRefCount();
|
inp->decRefCount();
|
||||||
@ -353,7 +399,11 @@ void DemodulatorThread::threadMain() {
|
|||||||
agc_crcf_destroy(agc);
|
agc_crcf_destroy(agc);
|
||||||
firhilbf_destroy(firR2C);
|
firhilbf_destroy(firR2C);
|
||||||
firhilbf_destroy(firC2R);
|
firhilbf_destroy(firC2R);
|
||||||
nco_crcf_destroy(nco_shift);
|
// firhilbf_destroy(firR2Cssb);
|
||||||
|
// firhilbf_destroy(firC2Rssb);
|
||||||
|
nco_crcf_destroy(nco_stereo_shift);
|
||||||
|
nco_crcf_destroy(nco_ssb_shift_up);
|
||||||
|
nco_crcf_destroy(nco_ssb_shift_down);
|
||||||
|
|
||||||
while (!buffers.empty()) {
|
while (!buffers.empty()) {
|
||||||
AudioThreadInput *audioDataDel = buffers.front();
|
AudioThreadInput *audioDataDel = buffers.front();
|
||||||
@ -397,10 +447,11 @@ float DemodulatorThread::getSquelchLevel() {
|
|||||||
return squelch_level;
|
return squelch_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorThread::setDemodulatorType(DemodulatorType demod_type_in) {
|
void DemodulatorThread::setDemodulatorType(int demod_type_in) {
|
||||||
demodulatorType = demod_type_in;
|
demodulatorType = demod_type_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
DemodulatorType DemodulatorThread::getDemodulatorType() {
|
int DemodulatorThread::getDemodulatorType() {
|
||||||
return demodulatorType;
|
return demodulatorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,14 +34,15 @@ public:
|
|||||||
void initialize();
|
void initialize();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
void setStereo(bool state);bool isStereo();
|
void setStereo(bool state);
|
||||||
|
bool isStereo();
|
||||||
|
|
||||||
float getSignalLevel();
|
float getSignalLevel();
|
||||||
void setSquelchLevel(float signal_level_in);
|
void setSquelchLevel(float signal_level_in);
|
||||||
float getSquelchLevel();
|
float getSquelchLevel();
|
||||||
|
|
||||||
void setDemodulatorType(DemodulatorType demod_type_in);
|
void setDemodulatorType(int demod_type_in);
|
||||||
DemodulatorType getDemodulatorType();
|
int getDemodulatorType();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static void *pthread_helper(void *context) {
|
static void *pthread_helper(void *context) {
|
||||||
@ -66,6 +67,7 @@ protected:
|
|||||||
AudioThreadInputQueue *audioInputQueue;
|
AudioThreadInputQueue *audioInputQueue;
|
||||||
|
|
||||||
freqdem fdem;
|
freqdem fdem;
|
||||||
|
ampmodem ampdem_active;
|
||||||
ampmodem ampdem;
|
ampmodem ampdem;
|
||||||
ampmodem ampdem_usb;
|
ampmodem ampdem_usb;
|
||||||
ampmodem ampdem_lsb;
|
ampmodem ampdem_lsb;
|
||||||
@ -78,11 +80,12 @@ protected:
|
|||||||
|
|
||||||
std::atomic<bool> stereo;
|
std::atomic<bool> stereo;
|
||||||
std::atomic<bool> terminated;
|
std::atomic<bool> terminated;
|
||||||
std::atomic<DemodulatorType> demodulatorType;
|
std::atomic<int> demodulatorType;
|
||||||
|
|
||||||
DemodulatorThreadCommandQueue* threadQueueNotify;
|
DemodulatorThreadCommandQueue* threadQueueNotify;
|
||||||
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
DemodulatorThreadControlCommandQueue *threadQueueControl;
|
||||||
std::atomic<float> squelch_level;
|
std::atomic<float> squelch_level;
|
||||||
float squelch_tolerance;
|
float squelch_tolerance;
|
||||||
std::atomic<float> signal_level;bool squelch_enabled;
|
std::atomic<float> signal_level;
|
||||||
|
bool squelch_enabled;
|
||||||
};
|
};
|
||||||
|
@ -47,7 +47,6 @@ void DemodulatorWorkerThread::threadMain() {
|
|||||||
result.bandwidth = filterCommand.bandwidth;
|
result.bandwidth = filterCommand.bandwidth;
|
||||||
result.inputRate = filterCommand.inputRate;
|
result.inputRate = filterCommand.inputRate;
|
||||||
resultQueue->push(result);
|
resultQueue->push(result);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,12 +48,12 @@ private:
|
|||||||
fftw_complex *in, *out;
|
fftw_complex *in, *out;
|
||||||
fftw_plan plan;
|
fftw_plan plan;
|
||||||
|
|
||||||
float fft_ceil_ma, fft_ceil_maa;
|
double fft_ceil_ma, fft_ceil_maa;
|
||||||
float fft_floor_ma, fft_floor_maa;
|
double fft_floor_ma, fft_floor_maa;
|
||||||
|
|
||||||
std::vector<float> fft_result;
|
std::vector<double> fft_result;
|
||||||
std::vector<float> fft_result_ma;
|
std::vector<double> fft_result_ma;
|
||||||
std::vector<float> fft_result_maa;
|
std::vector<double> fft_result_maa;
|
||||||
|
|
||||||
SpectrumContext *glContext;
|
SpectrumContext *glContext;
|
||||||
int fft_size;
|
int fft_size;
|
||||||
|
@ -17,9 +17,7 @@
|
|||||||
|
|
||||||
#include <wx/numformatter.h>
|
#include <wx/numformatter.h>
|
||||||
|
|
||||||
#define MIN_FM_BANDWIDTH 2000
|
#define MIN_BANDWIDTH 1500
|
||||||
#define MIN_AM_BANDWIDTH 2000
|
|
||||||
|
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint)
|
wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint)
|
||||||
EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown)
|
EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown)
|
||||||
@ -36,7 +34,7 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
|
|||||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
||||||
wxFULL_REPAINT_ON_RESIZE), parent(parent), spectrumCanvas(NULL), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(
|
wxFULL_REPAINT_ON_RESIZE), parent(parent), spectrumCanvas(NULL), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(
|
||||||
WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false), fft_size(0), waterfall_lines(0), plan(
|
WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false), fft_size(0), waterfall_lines(0), plan(
|
||||||
NULL), in(NULL), out(NULL), center_freq(0), bandwidth(0), isView(false), resampler(NULL), resample_ratio(0), last_bandwidth(0), last_input_bandwidth(
|
NULL), in(NULL), out(NULL), center_freq(0), bandwidth(0), isView(false), resampler(NULL), resample_ratio(0), last_bandwidth(0), last_input_bandwidth(
|
||||||
0) {
|
0) {
|
||||||
|
|
||||||
glContext = new WaterfallContext(this, &wxGetApp().GetContext(this));
|
glContext = new WaterfallContext(this, &wxGetApp().GetContext(this));
|
||||||
@ -84,7 +82,7 @@ void WaterfallCanvas::Setup(int fft_size_in, int waterfall_lines_in) {
|
|||||||
if (plan) {
|
if (plan) {
|
||||||
fftw_destroy_plan(plan);
|
fftw_destroy_plan(plan);
|
||||||
}
|
}
|
||||||
plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_MEASURE);
|
plan = fftw_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
|
||||||
|
|
||||||
glContext->Setup(fft_size, waterfall_lines);
|
glContext->Setup(fft_size, waterfall_lines);
|
||||||
}
|
}
|
||||||
@ -133,7 +131,6 @@ void WaterfallCanvas::attachSpectrumCanvas(SpectrumCanvas *canvas_in) {
|
|||||||
spectrumCanvas = canvas_in;
|
spectrumCanvas = canvas_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
const wxSize ClientSize = GetClientSize();
|
const wxSize ClientSize = GetClientSize();
|
||||||
@ -346,7 +343,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!resampler || bandwidth != last_bandwidth || last_input_bandwidth != input->bandwidth) {
|
if (!resampler || bandwidth != last_bandwidth || last_input_bandwidth != input->bandwidth) {
|
||||||
resample_ratio = (float) (bandwidth) / (float) input->bandwidth;
|
resample_ratio = (double) (bandwidth) / (double) input->bandwidth;
|
||||||
|
|
||||||
float As = 60.0f;
|
float As = 60.0f;
|
||||||
|
|
||||||
@ -359,7 +356,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
|||||||
last_input_bandwidth = input->bandwidth;
|
last_input_bandwidth = input->bandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_size = ceil((float) (input->data.size()) * resample_ratio);
|
int out_size = ceil((double) (input->data.size()) * resample_ratio) + 32;
|
||||||
|
|
||||||
if (resampler_buffer.size() != out_size) {
|
if (resampler_buffer.size() != out_size) {
|
||||||
if (resampler_buffer.capacity() < out_size) {
|
if (resampler_buffer.capacity() < out_size) {
|
||||||
@ -373,14 +370,37 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
|||||||
|
|
||||||
resampler_buffer.resize(fft_size);
|
resampler_buffer.resize(fft_size);
|
||||||
|
|
||||||
for (int i = 0; i < fft_size; i++) {
|
if (num_written < fft_size) {
|
||||||
in[i][0] = resampler_buffer[i].real;
|
for (int i = 0; i < num_written; i++) {
|
||||||
in[i][1] = resampler_buffer[i].imag;
|
in[i][0] = resampler_buffer[i].real;
|
||||||
|
in[i][1] = resampler_buffer[i].imag;
|
||||||
|
}
|
||||||
|
for (int i = num_written; i < fft_size; i++) {
|
||||||
|
in[i][0] = 0;
|
||||||
|
in[i][1] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < fft_size; i++) {
|
||||||
|
in[i][0] = resampler_buffer[i].real;
|
||||||
|
in[i][1] = resampler_buffer[i].imag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < fft_size; i++) {
|
|
||||||
in[i][0] = (*data)[i].real;
|
if (data->size() < fft_size) {
|
||||||
in[i][1] = (*data)[i].imag;
|
for (int i = 0, iMax = data->size(); i < iMax; i++) {
|
||||||
|
in[i][0] = (*data)[i].real;
|
||||||
|
in[i][1] = (*data)[i].imag;
|
||||||
|
}
|
||||||
|
for (int i = data->size(); i < fft_size; i++) {
|
||||||
|
in[i][0] = 0;
|
||||||
|
in[i][1] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < fft_size; i++) {
|
||||||
|
in[i][0] = (*data)[i].real;
|
||||||
|
in[i][1] = (*data)[i].imag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,19 +450,19 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) {
|
|||||||
fft_floor -= 1;
|
fft_floor -= 1;
|
||||||
|
|
||||||
fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05;
|
fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05;
|
||||||
fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.01;
|
fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05;
|
||||||
|
|
||||||
fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01;
|
fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05;
|
||||||
fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01;
|
fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05;
|
||||||
|
|
||||||
for (int i = 0, iMax = fft_size; i < iMax; i++) {
|
for (int i = 0, iMax = fft_size; i < iMax; i++) {
|
||||||
float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
|
double v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa));
|
||||||
spectrum_points[i * 2] = ((float) i / (float) iMax);
|
spectrum_points[i * 2] = ((float) i / (float) iMax);
|
||||||
spectrum_points[i * 2 + 1] = v;
|
spectrum_points[i * 2 + 1] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spectrumCanvas) {
|
if (spectrumCanvas) {
|
||||||
spectrumCanvas->spectrum_points.assign(spectrum_points.begin(),spectrum_points.end());
|
spectrumCanvas->spectrum_points.assign(spectrum_points.begin(), spectrum_points.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,8 +502,8 @@ void WaterfallCanvas::mouseMoved(wxMouseEvent& event) {
|
|||||||
if (activeDemodulatorBandwidth > SRATE) {
|
if (activeDemodulatorBandwidth > SRATE) {
|
||||||
activeDemodulatorBandwidth = SRATE;
|
activeDemodulatorBandwidth = SRATE;
|
||||||
}
|
}
|
||||||
if (activeDemodulatorBandwidth < MIN_FM_BANDWIDTH) {
|
if (activeDemodulatorBandwidth < MIN_BANDWIDTH) {
|
||||||
activeDemodulatorBandwidth = MIN_FM_BANDWIDTH;
|
activeDemodulatorBandwidth = MIN_BANDWIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
command.int_value = activeDemodulatorBandwidth;
|
command.int_value = activeDemodulatorBandwidth;
|
||||||
@ -673,8 +693,8 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
|
|||||||
unsigned int freq = input_center_freq - (int) (0.5 * (float) GetBandwidth()) + (int) ((float) pos * (float) GetBandwidth());
|
unsigned int freq = input_center_freq - (int) (0.5 * (float) GetBandwidth()) + (int) ((float) pos * (float) GetBandwidth());
|
||||||
unsigned int bw = (unsigned int) (fabs(width) * (float) GetBandwidth());
|
unsigned int bw = (unsigned int) (fabs(width) * (float) GetBandwidth());
|
||||||
|
|
||||||
if (bw < MIN_FM_BANDWIDTH) {
|
if (bw < MIN_BANDWIDTH) {
|
||||||
bw = MIN_FM_BANDWIDTH;
|
bw = MIN_BANDWIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bw) {
|
if (!bw) {
|
||||||
|
@ -60,12 +60,12 @@ private:
|
|||||||
fftw_complex *in, *out;
|
fftw_complex *in, *out;
|
||||||
fftw_plan plan;
|
fftw_plan plan;
|
||||||
|
|
||||||
float fft_ceil_ma, fft_ceil_maa;
|
double fft_ceil_ma, fft_ceil_maa;
|
||||||
float fft_floor_ma, fft_floor_maa;
|
double fft_floor_ma, fft_floor_maa;
|
||||||
|
|
||||||
std::vector<float> fft_result;
|
std::vector<double> fft_result;
|
||||||
std::vector<float> fft_result_ma;
|
std::vector<double> fft_result_ma;
|
||||||
std::vector<float> fft_result_maa;
|
std::vector<double> fft_result_maa;
|
||||||
|
|
||||||
WaterfallContext *glContext;
|
WaterfallContext *glContext;
|
||||||
MouseTracker mTracker;
|
MouseTracker mTracker;
|
||||||
@ -88,7 +88,7 @@ private:
|
|||||||
|
|
||||||
bool isView;
|
bool isView;
|
||||||
msresamp_crcf resampler;
|
msresamp_crcf resampler;
|
||||||
float resample_ratio;
|
double resample_ratio;
|
||||||
nco_crcf nco_shift;
|
nco_crcf nco_shift;
|
||||||
int shift_freq;
|
int shift_freq;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user