OSX crash-on-exit fix, File menu tidying, Confirm bookmark reset

This commit is contained in:
Charles J. Cliffe 2018-01-14 18:56:30 -05:00
parent 4c6d7ab4d7
commit 7baaca1216
5 changed files with 80 additions and 42 deletions

View File

@ -24,6 +24,7 @@
#include "ColorTheme.h" #include "ColorTheme.h"
#include "DemodulatorMgr.h" #include "DemodulatorMgr.h"
#include "ImagePanel.h" #include "ImagePanel.h"
#include "ActionDialog.h"
#include <thread> #include <thread>
#include <iostream> #include <iostream>
@ -53,6 +54,22 @@ wxEND_EVENT_TABLE()
#endif #endif
class ActionDialogBookmarkReset : public ActionDialog {
public:
ActionDialogBookmarkReset() : ActionDialog(wxGetApp().getAppFrame(), wxID_ANY, wxT("Reset Bookmarks?")) {
m_questionText->SetLabelText(wxT("Resetting bookmarks will erase all current bookmarks; are you sure?"));
}
void doClickOK() {
wxGetApp().getBookmarkMgr().resetBookmarks();
wxGetApp().getBookmarkMgr().updateBookmarks();
wxGetApp().getBookmarkMgr().updateActiveList();
}
};
/* split a string by 'seperator' into a vector of string */ /* split a string by 'seperator' into a vector of string */
std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str); std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str);
@ -711,17 +728,27 @@ wxMenu *AppFrame::makeFileMenu() {
menu->Append(wxID_SDR_START_STOP, "Stop / Start Device"); menu->Append(wxID_SDR_START_STOP, "Stop / Start Device");
menu->AppendSeparator(); menu->AppendSeparator();
menu->Append(wxID_OPEN, "&Open Session"); wxMenu *sessionMenu = new wxMenu;
menu->Append(wxID_SAVE, "&Save Session");
menu->Append(wxID_SAVEAS, "Save Session &As.."); sessionMenu->Append(wxID_OPEN, "&Open Session");
sessionMenu->Append(wxID_SAVE, "&Save Session");
sessionMenu->Append(wxID_SAVEAS, "Save Session &As..");
sessionMenu->AppendSeparator();
sessionMenu->Append(wxID_RESET, "&Reset Session");
menu->AppendSubMenu(sessionMenu, "Session");
menu->AppendSeparator(); menu->AppendSeparator();
menu->Append(wxID_RESET, "&Reset Session");
menu->AppendSeparator(); wxMenu *bookmarkMenu = new wxMenu;
menu->Append(wxID_OPEN_BOOKMARKS, "Open Bookmarks");
menu->Append(wxID_SAVE_BOOKMARKS, "Save Bookmarks"); bookmarkMenu->Append(wxID_OPEN_BOOKMARKS, "Open Bookmarks");
menu->Append(wxID_SAVEAS_BOOKMARKS, "Save Bookmarks As.."); bookmarkMenu->Append(wxID_SAVE_BOOKMARKS, "Save Bookmarks");
menu->AppendSeparator(); bookmarkMenu->Append(wxID_SAVEAS_BOOKMARKS, "Save Bookmarks As..");
menu->Append(wxID_RESET_BOOKMARKS, "Reset Bookmarks"); bookmarkMenu->AppendSeparator();
bookmarkMenu->Append(wxID_RESET_BOOKMARKS, "Reset Bookmarks");
menu->AppendSubMenu(bookmarkMenu, "Bookmarks");
#ifndef __APPLE__ #ifndef __APPLE__
menu->AppendSeparator(); menu->AppendSeparator();
@ -1570,9 +1597,7 @@ bool AppFrame::actionOnMenuLoadSave(wxCommandEvent& event) {
} }
else if (event.GetId() == wxID_RESET_BOOKMARKS) { else if (event.GetId() == wxID_RESET_BOOKMARKS) {
wxGetApp().getBookmarkMgr().resetBookmarks(); ActionDialog::showDialog(new ActionDialogBookmarkReset());
wxGetApp().getBookmarkMgr().updateBookmarks();
wxGetApp().getBookmarkMgr().updateActiveList();
return true; return true;
} }

View File

@ -221,6 +221,7 @@ private:
std::vector<RtAudio::DeviceInfo> devices; std::vector<RtAudio::DeviceInfo> devices;
std::map<int,RtAudio::DeviceInfo> inputDevices; std::map<int,RtAudio::DeviceInfo> inputDevices;
std::map<int,RtAudio::DeviceInfo> outputDevices; std::map<int,RtAudio::DeviceInfo> outputDevices;
std::map<int, wxMenuItem *> outputDeviceMenuItems; std::map<int, wxMenuItem *> outputDeviceMenuItems;
std::map<int, wxMenuItem *> sampleRateMenuItems; std::map<int, wxMenuItem *> sampleRateMenuItems;
std::map<int, wxMenuItem *> antennaMenuItems; std::map<int, wxMenuItem *> antennaMenuItems;

View File

@ -21,15 +21,32 @@ public:
int channels; int channels;
float peak; float peak;
int type; int type;
bool is_squelch_active = false; bool is_squelch_active;
std::vector<float> data; std::vector<float> data;
AudioThreadInput() : AudioThreadInput() :
frequency(0), inputRate(0), sampleRate(0), channels(0), peak(0), type(0) { frequency(0), inputRate(0), sampleRate(0), channels(0), peak(0), type(0), is_squelch_active(false) {
} }
AudioThreadInput(AudioThreadInput *copyFrom) {
copy(copyFrom);
}
void copy(AudioThreadInput *copyFrom) {
frequency = copyFrom->frequency;
inputRate = copyFrom->inputRate;
sampleRate = copyFrom->sampleRate;
channels = copyFrom->channels;
peak = copyFrom->peak;
type = copyFrom->type;
is_squelch_active = copyFrom->is_squelch_active;
data.assign(copyFrom->data.begin(), copyFrom->data.end());
}
virtual ~AudioThreadInput() { virtual ~AudioThreadInput() {
} }

View File

@ -187,7 +187,7 @@ void DemodulatorInstance::terminate() {
demodulatorPreThread->terminate(); demodulatorPreThread->terminate();
if (audioSinkThread != nullptr) { if (audioSinkThread != nullptr) {
audioSinkThread->terminate(); stopRecording();
} }
//that will actually unblock the currently blocked push(). //that will actually unblock the currently blocked push().

View File

@ -225,13 +225,6 @@ void DemodulatorThread::run() {
} }
} }
// Capture audioSinkOutputQueue state in a local variable
DemodulatorThreadOutputQueuePtr localAudioSinkOutputQueue = nullptr;
{
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
localAudioSinkOutputQueue = audioSinkOutputQueue;
}
//compute audio peak: //compute audio peak:
if (audioOutputQueue != nullptr && ati) { if (audioOutputQueue != nullptr && ati) {
@ -250,21 +243,6 @@ void DemodulatorThread::run() {
ati->is_squelch_active = squelched; ati->is_squelch_active = squelched;
} }
//Push to audio sink, if any:
if (ati && localAudioSinkOutputQueue != nullptr) {
if (!localAudioSinkOutputQueue->try_push(ati)) {
std::cout << "DemodulatorThread::run() cannot push ati into audioSinkOutputQueue, is full !" << std::endl;
std::this_thread::yield();
}
}
//now we can nullify ati if squelched, to skip the next processing entirely.
if (ati && squelched) {
ati = nullptr;
}
//At that point, capture the current state of audioVisOutputQueue in a local //At that point, capture the current state of audioVisOutputQueue in a local
//variable, and works with it with now on until the next while-turn. //variable, and works with it with now on until the next while-turn.
DemodulatorThreadOutputQueuePtr localAudioVisOutputQueue = nullptr; DemodulatorThreadOutputQueuePtr localAudioVisOutputQueue = nullptr;
@ -273,7 +251,7 @@ void DemodulatorThread::run() {
localAudioVisOutputQueue = audioVisOutputQueue; localAudioVisOutputQueue = audioVisOutputQueue;
} }
if ((ati || modemDigital) && localAudioVisOutputQueue != nullptr && localAudioVisOutputQueue->empty()) { if (!squelched && (ati || modemDigital) && localAudioVisOutputQueue != nullptr && localAudioVisOutputQueue->empty()) {
AudioThreadInputPtr ati_vis = std::make_shared<AudioThreadInput>(); AudioThreadInputPtr ati_vis = std::make_shared<AudioThreadInput>();
@ -343,7 +321,7 @@ void DemodulatorThread::run() {
} }
} }
if (ati != nullptr) { if (!squelched && ati != nullptr) {
if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance == wxGetApp().getDemodMgr().getLastActiveDemodulator().get()))) { if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance == wxGetApp().getDemodMgr().getLastActiveDemodulator().get()))) {
//non-blocking push needed for audio out //non-blocking push needed for audio out
if (!audioOutputQueue->try_push(ati)) { if (!audioOutputQueue->try_push(ati)) {
@ -354,6 +332,23 @@ void DemodulatorThread::run() {
} }
} }
// Capture audioSinkOutputQueue state in a local variable
DemodulatorThreadOutputQueuePtr localAudioSinkOutputQueue = nullptr;
{
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
localAudioSinkOutputQueue = audioSinkOutputQueue;
}
//Push to audio sink, if any:
if (ati && localAudioSinkOutputQueue != nullptr) {
if (!localAudioSinkOutputQueue->try_push(ati)) {
std::cout << "DemodulatorThread::run() cannot push ati into audioSinkOutputQueue, is full !" << std::endl;
std::this_thread::yield();
}
}
DemodulatorThreadControlCommand command; DemodulatorThreadControlCommand command;
//empty command queue, execute commands //empty command queue, execute commands