Demod instance start/stop recording setup

This commit is contained in:
Charles J. Cliffe 2017-10-09 20:07:40 -04:00
parent c202d99a2a
commit f8e51df8cd
8 changed files with 108 additions and 24 deletions

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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) {

View File

@ -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;

View File

@ -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();
}
}
}
}

View File

@ -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;
};