From 0b97bd360a491564afa260ba87c740885bf708e8 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Sun, 4 Apr 2021 22:13:31 -0400 Subject: [PATCH] Cleanup: audio file, audio threads --- src/audio/AudioFile.cpp | 8 +--- src/audio/AudioFileWAV.cpp | 14 +++---- src/audio/AudioFileWAV.h | 18 ++++----- src/audio/AudioSinkFileThread.h | 6 +-- src/audio/AudioSinkThread.cpp | 4 +- src/audio/AudioSinkThread.h | 6 +-- src/audio/AudioThread.cpp | 66 ++++++++++++++++----------------- src/audio/AudioThread.h | 30 +++++++-------- 8 files changed, 70 insertions(+), 82 deletions(-) diff --git a/src/audio/AudioFile.cpp b/src/audio/AudioFile.cpp index 6b15db7..7eaeedb 100644 --- a/src/audio/AudioFile.cpp +++ b/src/audio/AudioFile.cpp @@ -5,13 +5,9 @@ #include "CubicSDR.h" #include -AudioFile::AudioFile() { +AudioFile::AudioFile() = default; -} - -AudioFile::~AudioFile() { - -} +AudioFile::~AudioFile() = default; void AudioFile::setOutputFileName(std::string filename) { filenameBase = filename; diff --git a/src/audio/AudioFileWAV.cpp b/src/audio/AudioFileWAV.cpp index 374fbf3..a58b778 100644 --- a/src/audio/AudioFileWAV.cpp +++ b/src/audio/AudioFileWAV.cpp @@ -22,7 +22,8 @@ namespace little_endian_io template std::istream& read_word(std::istream& ins, Word& value, unsigned size = sizeof(Word)) { - for (unsigned n = 0, value = 0; n < size; ++n) { + value = 0; + for (unsigned n = 0; n < size; ++n) { value |= ins.get() << (8 * n); } return ins; @@ -50,11 +51,10 @@ namespace big_endian_io using namespace little_endian_io; -AudioFileWAV::AudioFileWAV() : AudioFile() { +AudioFileWAV::AudioFileWAV() : AudioFile(), dataChunkPos(0) { } -AudioFileWAV::~AudioFileWAV() { -} +AudioFileWAV::~AudioFileWAV() = default; std::string AudioFileWAV::getExtension() @@ -119,7 +119,7 @@ bool AudioFileWAV::closeFile() return true; } -void AudioFileWAV::writeHeaderToFileStream(AudioThreadInputPtr input) { +void AudioFileWAV::writeHeaderToFileStream(const AudioThreadInputPtr& input) { // Based on simple wav file output code from // http://www.cplusplus.com/forum/beginner/166954/ @@ -140,7 +140,7 @@ void AudioFileWAV::writeHeaderToFileStream(AudioThreadInputPtr input) { outputFileStream << "data----"; // (chunk size to be filled in later) } -void AudioFileWAV::writePayloadToFileStream(AudioThreadInputPtr input, size_t startInputPosition, size_t endInputPosition) { +void AudioFileWAV::writePayloadToFileStream(const AudioThreadInputPtr& input, size_t startInputPosition, size_t endInputPosition) { // Prevent clipping float intScale = (input->peak < 1.0) ? 32767.0f : (32767.0f / input->peak); @@ -164,7 +164,7 @@ void AudioFileWAV::writePayloadToFileStream(AudioThreadInputPtr input, size_t st } } -size_t AudioFileWAV::getMaxWritableNumberOfSamples(AudioThreadInputPtr input) { +size_t AudioFileWAV::getMaxWritableNumberOfSamples(const AudioThreadInputPtr& input) const { long long remainingBytesInFile = (long long)(MAX_WAV_FILE_SIZE) - currentFileSize; diff --git a/src/audio/AudioFileWAV.h b/src/audio/AudioFileWAV.h index 1dc9672..2f3b385 100644 --- a/src/audio/AudioFileWAV.h +++ b/src/audio/AudioFileWAV.h @@ -11,19 +11,19 @@ class AudioFileWAV : public AudioFile { public: AudioFileWAV(); - ~AudioFileWAV(); + ~AudioFileWAV() override; //override to manage name change with multi-part WAV. - virtual void setOutputFileName(std::string filename); + void setOutputFileName(std::string filename) override; //override of the base method to generate multi-part //WAV to overcome the WAV format size limit. - virtual std::string getOutputFileName(); + std::string getOutputFileName() override; - virtual std::string getExtension(); + std::string getExtension() override; - virtual bool writeToFile(AudioThreadInputPtr input); - virtual bool closeFile(); + bool writeToFile(AudioThreadInputPtr input) override; + bool closeFile() override; protected: std::ofstream outputFileStream; @@ -33,10 +33,10 @@ protected: private: - size_t getMaxWritableNumberOfSamples(AudioThreadInputPtr input); + size_t getMaxWritableNumberOfSamples(const AudioThreadInputPtr& input) const; - void writeHeaderToFileStream(AudioThreadInputPtr input); + void writeHeaderToFileStream(const AudioThreadInputPtr& input); //write [startInputPosition; endInputPosition[ samples from input into the file. - void writePayloadToFileStream(AudioThreadInputPtr input, size_t startInputPosition, size_t endInputPosition); + void writePayloadToFileStream(const AudioThreadInputPtr& input, size_t startInputPosition, size_t endInputPosition); }; \ No newline at end of file diff --git a/src/audio/AudioSinkFileThread.h b/src/audio/AudioSinkFileThread.h index f0bdb73..03a52a2 100644 --- a/src/audio/AudioSinkFileThread.h +++ b/src/audio/AudioSinkFileThread.h @@ -11,7 +11,7 @@ class AudioSinkFileThread : public AudioSinkThread { public: AudioSinkFileThread(); - ~AudioSinkFileThread(); + ~AudioSinkFileThread() override; enum SquelchOption { SQUELCH_RECORD_SILENCE = 0, // default value, record as a user would hear it. @@ -20,8 +20,8 @@ public: SQUELCH_RECORD_MAX }; - virtual void sink(AudioThreadInputPtr input); - virtual void inputChanged(AudioThreadInput oldProps, AudioThreadInputPtr newProps); + void sink(AudioThreadInputPtr input) override; + void inputChanged(AudioThreadInput oldProps, AudioThreadInputPtr newProps) override; void setAudioFileHandler(AudioFile *output); diff --git a/src/audio/AudioSinkThread.cpp b/src/audio/AudioSinkThread.cpp index edf3152..bdfd43c 100644 --- a/src/audio/AudioSinkThread.cpp +++ b/src/audio/AudioSinkThread.cpp @@ -11,9 +11,7 @@ AudioSinkThread::AudioSinkThread() { setInputQueue("input", inputQueuePtr); } -AudioSinkThread::~AudioSinkThread() { - -} +AudioSinkThread::~AudioSinkThread() = default; void AudioSinkThread::run() { #ifdef __APPLE__ diff --git a/src/audio/AudioSinkThread.h b/src/audio/AudioSinkThread.h index 754c75d..db5f13b 100644 --- a/src/audio/AudioSinkThread.h +++ b/src/audio/AudioSinkThread.h @@ -10,10 +10,10 @@ class AudioSinkThread : public IOThread { public: AudioSinkThread(); - virtual ~AudioSinkThread(); + ~AudioSinkThread() override; - virtual void run(); - virtual void terminate(); + void run() override; + void terminate() override; virtual void sink(AudioThreadInputPtr input) = 0; virtual void inputChanged(AudioThreadInput oldProps, AudioThreadInputPtr newProps) = 0; diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 312b5a2..751455f 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -2,13 +2,10 @@ // SPDX-License-Identifier: GPL-2.0+ #include "AudioThread.h" -#include "CubicSDRDefs.h" #include #include #include "CubicSDR.h" -#include "DemodulatorThread.h" #include "DemodulatorInstance.h" -#include #include //50 ms @@ -80,9 +77,9 @@ void AudioThread::deviceCleanup() { //NOT PROTECTED by m_device_mutex on purpose, to prevent deadlocks with i->second->controllerThread // it doesn't matter, it is only called when all "normal" audio threads are detached from the controller. // - for (auto i = deviceController.begin(); i != deviceController.end(); i++) { + for (auto & i : deviceController) { - delete i->second; + delete i.second; } deviceController.clear(); @@ -98,7 +95,7 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned ::memset(out, 0, nBufferFrames * 2 * sizeof(float)); //src in the controller thread: - AudioThread *src = (AudioThread *)userData; + auto *src = (AudioThread *)userData; //by construction, src is a controller thread, from deviceController: std::lock_guard lock(src->getMutex()); @@ -157,7 +154,7 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned } - if (srcmix->currentInput->channels == 0 || !srcmix->currentInput->data.size()) { + if (srcmix->currentInput->channels == 0 || srcmix->currentInput->data.empty()) { if (!srcmix->inputQueue->empty()) { srcmix->audioQueuePtr = 0; if (srcmix->currentInput) { @@ -195,7 +192,7 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned mixPeak = srcPeak; } } - if (srcmix->currentInput && srcmix->currentInput->data.size()) { + if (srcmix->currentInput && !srcmix->currentInput->data.empty()) { float v = srcmix->currentInput->data[srcmix->audioQueuePtr] * srcmix->gain; out[i * 2] += v; out[i * 2 + 1] += v; @@ -204,7 +201,7 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned } } else { - for (int i = 0, iMax = srcmix->currentInput->channels * nBufferFrames; i < iMax; i++) { + for (unsigned int i = 0, iMax = srcmix->currentInput->channels * nBufferFrames; i < iMax; i++) { if (srcmix->audioQueuePtr >= srcmix->currentInput->data.size()) { srcmix->audioQueuePtr = 0; @@ -222,7 +219,7 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned mixPeak = srcPeak; } } - if (srcmix->currentInput && srcmix->currentInput->data.size()) { + if (srcmix->currentInput && !srcmix->currentInput->data.empty()) { out[i] = out[i] + srcmix->currentInput->data[srcmix->audioQueuePtr] * srcmix->gain; } @@ -248,9 +245,9 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned void AudioThread::enumerateDevices(std::vector &devs) { RtAudio endac; - int numDevices = endac.getDeviceCount(); + unsigned int numDevices = endac.getDeviceCount(); - for (int i = 0; i < numDevices; i++) { + for (unsigned int i = 0; i < numDevices; i++) { RtAudio::DeviceInfo info = endac.getDeviceInfo(i); devs.push_back(info); @@ -322,7 +319,7 @@ void AudioThread::setDeviceSampleRate(int deviceId, int sampleRate) { } } -void AudioThread::setSampleRate(int sampleRate) { +void AudioThread::setSampleRate(int sampleRate_in) { bool thisIsAController = false; @@ -332,7 +329,7 @@ void AudioThread::setSampleRate(int sampleRate) { if (deviceController[outputDevice.load()] == this) { thisIsAController = true; - deviceSampleRate[outputDevice.load()] = sampleRate; + deviceSampleRate[outputDevice.load()] = sampleRate_in; } } @@ -344,31 +341,30 @@ void AudioThread::setSampleRate(int sampleRate) { dac.closeStream(); //Set bounded sample rate: - for (size_t j = 0; j < boundThreads.size(); j++) { - AudioThread *srcmix = boundThreads[j]; - srcmix->setSampleRate(sampleRate); + for (auto srcmix : boundThreads) { + srcmix->setSampleRate(sampleRate_in); } //make a local copy, snapshot of the list of demodulators std::vector demodulators = wxGetApp().getDemodMgr().getDemodulators(); - for (auto demod : demodulators) { + for (const auto& demod : demodulators) { if (demod->getOutputDevice() == outputDevice.load()) { - demod->setAudioSampleRate(sampleRate); + demod->setAudioSampleRate(sampleRate_in); } } - dac.openStream(¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, &nBufferFrames, &audioCallback, (void *)this, &opts); + dac.openStream(¶meters, nullptr, RTAUDIO_FLOAT32, sampleRate_in, &nBufferFrames, &audioCallback, (void *)this, &opts); dac.startStream(); } - this->sampleRate = sampleRate; + sampleRate = sampleRate_in; } int AudioThread::getSampleRate() { std::lock_guard lock(m_mutex); - return this->sampleRate; + return sampleRate; } void AudioThread::setupDevice(int deviceId) { @@ -411,7 +407,7 @@ void AudioThread::setupDevice(int deviceId) { if (deviceController.find(parameters.deviceId) == deviceController.end()) { //Create a new controller thread for parameters.deviceId: - AudioThread* newController = new AudioThread(); + auto* newController = new AudioThread(); newController->setInitOutputDevice(parameters.deviceId, sampleRate); newController->bindThread(this); @@ -422,7 +418,7 @@ void AudioThread::setupDevice(int deviceId) { else if (deviceController[parameters.deviceId] == this) { //Attach callback - dac.openStream(¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, &nBufferFrames, &audioCallback, (void *)this, &opts); + dac.openStream(¶meters, nullptr, RTAUDIO_FLOAT32, sampleRate, &nBufferFrames, &audioCallback, (void *)this, &opts); dac.startStream(); } else { @@ -455,21 +451,21 @@ int AudioThread::getOutputDevice() { return outputDevice; } -void AudioThread::setInitOutputDevice(int deviceId, int sampleRate) { +void AudioThread::setInitOutputDevice(int deviceId, int sampleRate_in) { //global lock std::lock_guard lock(m_device_mutex); outputDevice = deviceId; - if (sampleRate == -1) { + if (sampleRate_in == -1) { if (deviceSampleRate.find(parameters.deviceId) != deviceSampleRate.end()) { - sampleRate = deviceSampleRate[deviceId]; + sampleRate_in = deviceSampleRate[deviceId]; } } else { - deviceSampleRate[deviceId] = sampleRate; + deviceSampleRate[deviceId] = sampleRate_in; } - this->sampleRate = sampleRate; + sampleRate = sampleRate_in; } void AudioThread::run() { @@ -517,20 +513,20 @@ void AudioThread::run() { //Nullify currentInput... currentInput = nullptr; - //Stop : Retreive the matching controling thread in a scope lock: - AudioThread* controllerThread = nullptr; + //Stop : Retrieve the matching controlling thread in a scope lock: + AudioThread* controllerMatchingThread; { std::lock_guard global_lock(m_device_mutex); - controllerThread = deviceController[parameters.deviceId]; + controllerMatchingThread = deviceController[parameters.deviceId]; } - if (controllerThread != this) { + if (controllerMatchingThread != this) { //'this' is not the controller, so remove it from the bounded list: //beware, we must take the controller mutex, because the audio callback may use the list of bounded //threads at that moment: - std::lock_guard lock(controllerThread->getMutex()); + std::lock_guard lock(controllerMatchingThread->getMutex()); - controllerThread->removeThread(this); + controllerMatchingThread->removeThread(this); } else { // 'this' is a controller thread: diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 98b5983..52d473e 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -15,13 +15,13 @@ class AudioThreadInput { public: - long long frequency; - int inputRate; - int sampleRate; - int channels; - float peak; - int type; - bool is_squelch_active; + long long frequency{}; + int inputRate{}; + int sampleRate{}; + int channels{}; + float peak{}; + int type{}; + bool is_squelch_active{}; std::vector data; @@ -31,7 +31,7 @@ public: } - AudioThreadInput(AudioThreadInput *copyFrom) { + explicit AudioThreadInput(AudioThreadInput *copyFrom) { copy(copyFrom); } @@ -47,9 +47,7 @@ public: } - virtual ~AudioThreadInput() { - - } + virtual ~AudioThreadInput() = default; }; typedef std::shared_ptr AudioThreadInputPtr; @@ -83,17 +81,17 @@ class AudioThread : public IOThread { public: AudioThread(); - virtual ~AudioThread(); + ~AudioThread() override; static void enumerateDevices(std::vector &devs); - void setInitOutputDevice(int deviceId, int sampleRate = -1); + void setInitOutputDevice(int deviceId, int sampleRate_in = -1); int getOutputDevice(); int getSampleRate(); - virtual void run(); - virtual void terminate(); + void run() override; + void terminate() override; bool isActive(); void setActive(bool state); @@ -141,7 +139,7 @@ private: std::recursive_mutex m_mutex; void setupDevice(int deviceId); - void setSampleRate(int sampleRate); + void setSampleRate(int sampleRate_in); void bindThread(AudioThread *other); void removeThread(AudioThread *other);