mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-02-03 09:44:26 -05:00
OSX crash-on-exit fix, File menu tidying, Confirm bookmark reset
This commit is contained in:
parent
4c6d7ab4d7
commit
7baaca1216
@ -24,6 +24,7 @@
|
||||
#include "ColorTheme.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
#include "ImagePanel.h"
|
||||
#include "ActionDialog.h"
|
||||
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
@ -53,6 +54,22 @@ wxEND_EVENT_TABLE()
|
||||
#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 */
|
||||
std::vector<std::string> str_explode(const std::string &seperator, const std::string &in_str);
|
||||
|
||||
@ -711,18 +728,28 @@ wxMenu *AppFrame::makeFileMenu() {
|
||||
menu->Append(wxID_SDR_START_STOP, "Stop / Start Device");
|
||||
menu->AppendSeparator();
|
||||
|
||||
menu->Append(wxID_OPEN, "&Open Session");
|
||||
menu->Append(wxID_SAVE, "&Save Session");
|
||||
menu->Append(wxID_SAVEAS, "Save Session &As..");
|
||||
menu->AppendSeparator();
|
||||
menu->Append(wxID_RESET, "&Reset Session");
|
||||
menu->AppendSeparator();
|
||||
menu->Append(wxID_OPEN_BOOKMARKS, "Open Bookmarks");
|
||||
menu->Append(wxID_SAVE_BOOKMARKS, "Save Bookmarks");
|
||||
menu->Append(wxID_SAVEAS_BOOKMARKS, "Save Bookmarks As..");
|
||||
menu->AppendSeparator();
|
||||
menu->Append(wxID_RESET_BOOKMARKS, "Reset Bookmarks");
|
||||
wxMenu *sessionMenu = new wxMenu;
|
||||
|
||||
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();
|
||||
|
||||
wxMenu *bookmarkMenu = new wxMenu;
|
||||
|
||||
bookmarkMenu->Append(wxID_OPEN_BOOKMARKS, "Open Bookmarks");
|
||||
bookmarkMenu->Append(wxID_SAVE_BOOKMARKS, "Save Bookmarks");
|
||||
bookmarkMenu->Append(wxID_SAVEAS_BOOKMARKS, "Save Bookmarks As..");
|
||||
bookmarkMenu->AppendSeparator();
|
||||
bookmarkMenu->Append(wxID_RESET_BOOKMARKS, "Reset Bookmarks");
|
||||
|
||||
menu->AppendSubMenu(bookmarkMenu, "Bookmarks");
|
||||
|
||||
#ifndef __APPLE__
|
||||
menu->AppendSeparator();
|
||||
menu->Append(wxID_CLOSE);
|
||||
@ -1570,10 +1597,8 @@ bool AppFrame::actionOnMenuLoadSave(wxCommandEvent& event) {
|
||||
}
|
||||
else if (event.GetId() == wxID_RESET_BOOKMARKS) {
|
||||
|
||||
wxGetApp().getBookmarkMgr().resetBookmarks();
|
||||
wxGetApp().getBookmarkMgr().updateBookmarks();
|
||||
wxGetApp().getBookmarkMgr().updateActiveList();
|
||||
|
||||
ActionDialog::showDialog(new ActionDialogBookmarkReset());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -221,6 +221,7 @@ private:
|
||||
std::vector<RtAudio::DeviceInfo> devices;
|
||||
std::map<int,RtAudio::DeviceInfo> inputDevices;
|
||||
std::map<int,RtAudio::DeviceInfo> outputDevices;
|
||||
|
||||
std::map<int, wxMenuItem *> outputDeviceMenuItems;
|
||||
std::map<int, wxMenuItem *> sampleRateMenuItems;
|
||||
std::map<int, wxMenuItem *> antennaMenuItems;
|
||||
|
@ -21,15 +21,32 @@ public:
|
||||
int channels;
|
||||
float peak;
|
||||
int type;
|
||||
bool is_squelch_active = false;
|
||||
bool is_squelch_active;
|
||||
|
||||
std::vector<float> data;
|
||||
|
||||
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() {
|
||||
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ void DemodulatorInstance::terminate() {
|
||||
demodulatorPreThread->terminate();
|
||||
|
||||
if (audioSinkThread != nullptr) {
|
||||
audioSinkThread->terminate();
|
||||
stopRecording();
|
||||
}
|
||||
|
||||
//that will actually unblock the currently blocked push().
|
||||
|
@ -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:
|
||||
if (audioOutputQueue != nullptr && ati) {
|
||||
|
||||
@ -250,21 +243,6 @@ void DemodulatorThread::run() {
|
||||
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
|
||||
//variable, and works with it with now on until the next while-turn.
|
||||
DemodulatorThreadOutputQueuePtr localAudioVisOutputQueue = nullptr;
|
||||
@ -273,7 +251,7 @@ void DemodulatorThread::run() {
|
||||
localAudioVisOutputQueue = audioVisOutputQueue;
|
||||
}
|
||||
|
||||
if ((ati || modemDigital) && localAudioVisOutputQueue != nullptr && localAudioVisOutputQueue->empty()) {
|
||||
if (!squelched && (ati || modemDigital) && localAudioVisOutputQueue != nullptr && localAudioVisOutputQueue->empty()) {
|
||||
|
||||
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()))) {
|
||||
//non-blocking push needed for audio out
|
||||
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;
|
||||
|
||||
//empty command queue, execute commands
|
||||
|
Loading…
Reference in New Issue
Block a user