#ifndef _AUDIO_PROCESSOR_H_ #define _AUDIO_PROCESSOR_H_ #include "AudioEffect.h" #include "WavFileWriter.h" #include #include #include #include #include #include #include class QAudioBuffer; namespace SpeexWebRTCTest { enum class Backend { Speex, WebRTC }; class AudioProcessor final : public QIODevice { Q_OBJECT public: explicit AudioProcessor(const QAudioFormat& format, const QAudioFormat& monitorFormat, QBuffer& monitorDevice, QObject* parent = nullptr); ~AudioProcessor() override; bool open(OpenMode mode) override; void close() override; qint64 bytesAvailable() const override; bool isSequential() const override; bool canReadLine() const override; Backend getCurrentBackend() const; void switchBackend(Backend); void setEffectParam(const QString& param, const QVariant& value); signals: void voiceActivityChanged(bool); void inputLevelsChanged(const QVector&); void outputLevelsChanged(const QVector&); protected: qint64 readData(char* data, qint64 maxlen) override; qint64 writeData(const char* data, qint64 len) override; private: void process(); void processBuffer(QAudioBuffer& inputBuffer, const QAudioBuffer& monitorBuffer); void clearBuffers(); mutable std::mutex inputMutex_; mutable std::mutex outputMutex_; mutable std::mutex monitorMutex_; std::mutex processMutex_; std::size_t bufferSize_; const QAudioFormat format_; const QAudioFormat monitorFormat_; QBuffer& monitorDevice_; QByteArray inputBuffer_; QByteArray monitorBuffer_; QByteArray outputBuffer_; QScopedPointer dsp_; std::thread worker_; bool doWork_ = false; std::condition_variable inputEvent_; std::mutex inputEventMutex_; QScopedPointer sourceEncoder_; QScopedPointer processedEncoder_; }; } // namespace SpeexWebRTCTest Q_DECLARE_METATYPE(QVector) #endif // _AUDIO_PROCESSOR_H_