// Copyright (c) Charles J. Cliffe // SPDX-License-Identifier: GPL-2.0+ #pragma once #include #include #include #include #include #include #include "ThreadBlockingQueue.h" #include "RtAudio.h" #include "DemodDefs.h" class AudioThreadInput { public: long long frequency; int inputRate; int sampleRate; int channels; float peak; int type; std::vector data; AudioThreadInput() : frequency(0), sampleRate(0), channels(0), peak(0) { } virtual ~AudioThreadInput() { } }; typedef std::shared_ptr AudioThreadInputPtr; class AudioThreadCommand { public: enum AudioThreadCommandEnum { AUDIO_THREAD_CMD_NULL, AUDIO_THREAD_CMD_SET_DEVICE, AUDIO_THREAD_CMD_SET_SAMPLE_RATE }; AudioThreadCommand() : cmd(AUDIO_THREAD_CMD_NULL), int_value(0) { } AudioThreadCommandEnum cmd; int int_value; }; typedef ThreadBlockingQueue AudioThreadInputQueue; typedef ThreadBlockingQueue AudioThreadCommandQueue; typedef std::shared_ptr AudioThreadInputQueuePtr; typedef std::shared_ptr AudioThreadCommandQueuePtr; class AudioThread : public IOThread { public: AudioThreadInputPtr currentInput; AudioThreadInputQueuePtr inputQueue; std::atomic_uint audioQueuePtr; std::atomic_uint underflowCount; std::atomic_bool initialized; std::atomic_bool active; std::atomic_int outputDevice; float gain; AudioThread(); ~AudioThread(); static void enumerateDevices(std::vector &devs); void setupDevice(int deviceId); void setInitOutputDevice(int deviceId, int sampleRate=-1); int getOutputDevice(); void setSampleRate(int sampleRate); int getSampleRate(); virtual void run(); virtual void terminate(); bool isActive(); void setActive(bool state); void setGain(float gain_in); float getGain(); AudioThreadCommandQueue *getCommandQueue(); private: RtAudio dac; unsigned int nBufferFrames; RtAudio::StreamOptions opts; RtAudio::StreamParameters parameters; AudioThreadCommandQueue cmdQueue; int sampleRate; //The own m_mutex protecting this AudioThread, in particular boundThreads std::recursive_mutex m_mutex; public: //give access to the this AudioThread lock std::recursive_mutex& getMutex(); void bindThread(AudioThread *other); void removeThread(AudioThread *other); static std::map deviceController; static std::map deviceSampleRate; static std::map deviceThread; static void deviceCleanup(); static void setDeviceSampleRate(int deviceId, int sampleRate); //protected by m_mutex std::vector boundThreads; };