mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2026-08-14 23:43:29 -04:00
Demod instance start/stop recording setup
This commit is contained in:
@@ -2,12 +2,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <memory>
|
||||
#include <ctime>
|
||||
|
||||
#include "DemodulatorInstance.h"
|
||||
#include "CubicSDR.h"
|
||||
|
||||
#include "DemodulatorThread.h"
|
||||
#include "DemodulatorPreThread.h"
|
||||
|
||||
#include "AudioSinkFileThread.h"
|
||||
#include "AudioFileWAV.h"
|
||||
|
||||
#if USE_HAMLIB
|
||||
#include "RigThread.h"
|
||||
@@ -47,6 +50,7 @@ DemodulatorInstance::DemodulatorInstance() {
|
||||
active.store(false);
|
||||
squelch.store(false);
|
||||
muted.store(false);
|
||||
recording.store(false);
|
||||
deltaLock.store(false);
|
||||
deltaLockOfs.store(0);
|
||||
currentOutputDevice.store(-1);
|
||||
@@ -542,6 +546,21 @@ void DemodulatorInstance::setMuted(bool muted) {
|
||||
wxGetApp().getDemodMgr().setLastMuted(muted);
|
||||
}
|
||||
|
||||
bool DemodulatorInstance::isRecording()
|
||||
{
|
||||
return recording.load();
|
||||
}
|
||||
|
||||
void DemodulatorInstance::setRecording(bool recording_in)
|
||||
{
|
||||
if (!recording.load() && recording_in) {
|
||||
startRecording();
|
||||
}
|
||||
else if (recording.load() && !recording_in) {
|
||||
stopRecording();
|
||||
}
|
||||
}
|
||||
|
||||
DemodVisualCue *DemodulatorInstance::getVisualCue() {
|
||||
return &visualCue;
|
||||
}
|
||||
@@ -599,6 +618,50 @@ ModemSettings DemodulatorInstance::getLastModemSettings(std::string demodType) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DemodulatorInstance::startRecording() {
|
||||
if (recording.load()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AudioSinkFileThread *newSinkThread = new AudioSinkFileThread();
|
||||
AudioFileWAV *afHandler = new AudioFileWAV();
|
||||
|
||||
std::stringstream fileName;
|
||||
fileName << getLabel() << "_" << std::time(nullptr);
|
||||
|
||||
afHandler->setOutputFileName(fileName.str());
|
||||
newSinkThread->setAudioFileHandler(afHandler);
|
||||
|
||||
audioSinkThread = newSinkThread;
|
||||
t_AudioSink = new std::thread(&AudioSinkThread::threadMain, audioSinkThread);
|
||||
|
||||
demodulatorThread->setOutputQueue("AudioSink", audioSinkThread->getInputQueue("input"));
|
||||
|
||||
recording.store(true);
|
||||
}
|
||||
|
||||
|
||||
void DemodulatorInstance::stopRecording() {
|
||||
if (!recording.load()) {
|
||||
return;
|
||||
}
|
||||
|
||||
demodulatorThread->setOutputQueue("AudioSink", nullptr);
|
||||
audioSinkThread->terminate();
|
||||
|
||||
t_AudioSink->join();
|
||||
|
||||
delete t_AudioSink;
|
||||
delete audioSinkThread;
|
||||
|
||||
t_AudioSink = nullptr;
|
||||
audioSinkThread = nullptr;
|
||||
|
||||
recording.store(false);
|
||||
}
|
||||
|
||||
|
||||
#if ENABLE_DIGITAL_LAB
|
||||
ModemDigitalOutput *DemodulatorInstance::getOutput() {
|
||||
if (activeOutput == nullptr) {
|
||||
|
||||
@@ -111,6 +111,9 @@ public:
|
||||
bool isMuted();
|
||||
void setMuted(bool muted);
|
||||
|
||||
bool isRecording();
|
||||
void setRecording(bool recording);
|
||||
|
||||
DemodVisualCue *getVisualCue();
|
||||
|
||||
DemodulatorThreadInputQueuePtr getIQInputDataPipe();
|
||||
@@ -132,6 +135,10 @@ public:
|
||||
void closeOutput();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void startRecording();
|
||||
void stopRecording();
|
||||
|
||||
private:
|
||||
DemodulatorThreadInputQueuePtr pipeIQInputData;
|
||||
DemodulatorThreadPostInputQueuePtr pipeIQDemodData;
|
||||
@@ -155,6 +162,8 @@ private:
|
||||
std::atomic_bool squelch;
|
||||
std::atomic_bool muted;
|
||||
std::atomic_bool deltaLock;
|
||||
std::atomic_bool recording;
|
||||
|
||||
std::atomic_int deltaLockOfs;
|
||||
|
||||
std::atomic_int currentOutputDevice;
|
||||
|
||||
@@ -43,6 +43,12 @@ void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBasePtr thread
|
||||
|
||||
audioVisOutputQueue = std::static_pointer_cast<DemodulatorThreadOutputQueue>(threadQueue);
|
||||
}
|
||||
|
||||
if (name == "AudioSinkOutput") {
|
||||
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
|
||||
|
||||
audioSinkOutputQueue = std::static_pointer_cast<AudioThreadInputQueue>(threadQueue);
|
||||
}
|
||||
}
|
||||
|
||||
double DemodulatorThread::abMagnitude(float inphase, float quadrature) {
|
||||
@@ -310,6 +316,13 @@ void DemodulatorThread::run() {
|
||||
}
|
||||
}
|
||||
|
||||
// Capture audioSinkOutputQueue state in a local
|
||||
DemodulatorThreadOutputQueuePtr localAudioSinkOutputQueue = nullptr;
|
||||
{
|
||||
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
|
||||
localAudioSinkOutputQueue = audioSinkOutputQueue;
|
||||
}
|
||||
|
||||
if (ati != nullptr) {
|
||||
if (!muted.load() && (!wxGetApp().getSoloMode() || (demodInstance == wxGetApp().getDemodMgr().getLastActiveDemodulator().get()))) {
|
||||
//non-blocking push needed for audio out
|
||||
@@ -318,6 +331,13 @@ void DemodulatorThread::run() {
|
||||
std::cout << "DemodulatorThread::run() cannot push ati into audioOutputQueue, is full !" << std::endl;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
if (localAudioSinkOutputQueue != nullptr) {
|
||||
if (!audioSinkOutputQueue->try_push(ati)) {
|
||||
std::cout << "DemodulatorThread::run() cannot push ati into audioSinkOutputQueue, is full !" << std::endl;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ protected:
|
||||
DemodulatorThreadOutputQueuePtr audioVisOutputQueue = nullptr;
|
||||
DemodulatorThreadControlCommandQueuePtr threadQueueControl = nullptr;
|
||||
|
||||
DemodulatorThreadOutputQueuePtr audioSinkOutputQueue = nullptr;
|
||||
|
||||
//protects the audioVisOutputQueue dynamic binding change at runtime (in DemodulatorMgr)
|
||||
std::mutex m_mutexAudioVisOutputQueue;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user