mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-04-08 04:29:50 -04:00
Demod instance start/stop recording setup
This commit is contained in:
parent
c202d99a2a
commit
f8e51df8cd
@ -8,27 +8,28 @@ AudioSinkFileThread::AudioSinkFileThread() : AudioSinkThread() {
|
||||
}
|
||||
|
||||
AudioSinkFileThread::~AudioSinkFileThread() {
|
||||
if (outputFileHandler != nullptr) {
|
||||
outputFileHandler->closeFile();
|
||||
if (audioFileHandler != nullptr) {
|
||||
audioFileHandler->closeFile();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSinkFileThread::sink(AudioThreadInputPtr input) {
|
||||
if (!outputFileHandler) {
|
||||
if (!audioFileHandler) {
|
||||
return;
|
||||
}
|
||||
// forward to output file handler
|
||||
outputFileHandler->writeToFile(input);
|
||||
audioFileHandler->writeToFile(input);
|
||||
}
|
||||
|
||||
void AudioSinkFileThread::inputChanged(AudioThreadInput oldProps, AudioThreadInputPtr newProps) {
|
||||
// close, set new parameters, adjust file name sequence and re-open?
|
||||
if (!outputFileHandler) {
|
||||
if (!audioFileHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
audioFileHandler->closeFile();
|
||||
}
|
||||
|
||||
void AudioSinkFileThread::setOutput(AudioFile * output) {
|
||||
outputFileHandler = output;
|
||||
outputFileHandler->setOutputFileName(sinkName);
|
||||
void AudioSinkFileThread::setAudioFileHandler(AudioFile * output) {
|
||||
audioFileHandler = output;
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ public:
|
||||
void sink(AudioThreadInputPtr input);
|
||||
void inputChanged(AudioThreadInput oldProps, AudioThreadInputPtr newProps);
|
||||
|
||||
void setOutput(AudioFile *output);
|
||||
void setAudioFileHandler(AudioFile *output);
|
||||
|
||||
protected:
|
||||
AudioFile *outputFileHandler = nullptr;
|
||||
AudioFile *audioFileHandler = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
@ -42,6 +42,8 @@ void AudioSinkThread::run() {
|
||||
inputRef.inputRate = inp->inputRate;
|
||||
inputRef.sampleRate = inp->sampleRate;
|
||||
}
|
||||
|
||||
sink(inp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,12 +51,3 @@ void AudioSinkThread::terminate() {
|
||||
IOThread::terminate();
|
||||
inputQueuePtr->flush();
|
||||
}
|
||||
|
||||
void AudioSinkThread::setSinkName(std::string sinkName_in) {
|
||||
sinkName = sinkName_in;
|
||||
}
|
||||
|
||||
std::string AudioSinkThread::getSinkName() {
|
||||
return sinkName;
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,8 @@ public:
|
||||
virtual void sink(AudioThreadInputPtr input) = 0;
|
||||
virtual void inputChanged(AudioThreadInput oldProps, AudioThreadInputPtr newProps) = 0;
|
||||
|
||||
virtual void setSinkName(std::string sinkName_in);
|
||||
virtual std::string getSinkName();
|
||||
|
||||
protected:
|
||||
std::recursive_mutex m_mutex;
|
||||
AudioThreadInputQueuePtr inputQueuePtr;
|
||||
std::string sinkName;
|
||||
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user