diff --git a/app/app.pro b/app/app.pro index 1ad56018..16124c14 100644 --- a/app/app.pro +++ b/app/app.pro @@ -89,6 +89,7 @@ SOURCES += \ streaming/session.cpp \ streaming/audio/audio.cpp \ streaming/audio/renderers/sdlaud.cpp \ + streaming/audio/renderers/qtaud.cpp \ gui/computermodel.cpp \ gui/appmodel.cpp \ streaming/streamutils.cpp \ @@ -107,6 +108,7 @@ HEADERS += \ streaming/session.hpp \ streaming/audio/renderers/renderer.h \ streaming/audio/renderers/sdl.h \ + streaming/audio/renderers/qtaud.h \ gui/computermodel.h \ gui/appmodel.h \ streaming/video/decoder.h \ diff --git a/app/streaming/audio/audio.cpp b/app/streaming/audio/audio.cpp index ba6c2f59..8f5566cf 100644 --- a/app/streaming/audio/audio.cpp +++ b/app/streaming/audio/audio.cpp @@ -1,6 +1,7 @@ #include "../session.hpp" #include "renderers/renderer.h" #include "renderers/sdl.h" +#include "renderers/qtaud.h" #include diff --git a/app/streaming/audio/renderers/qtaud.cpp b/app/streaming/audio/renderers/qtaud.cpp new file mode 100644 index 00000000..e83133f0 --- /dev/null +++ b/app/streaming/audio/renderers/qtaud.cpp @@ -0,0 +1,94 @@ +#include "qtaud.h" + +#include + +QtAudioRenderer::QtAudioRenderer() + : m_AudioOutput(nullptr), + m_OutputDevice(nullptr) +{ + +} + +QtAudioRenderer::~QtAudioRenderer() +{ + delete m_AudioOutput; +} + +bool QtAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* opusConfig) +{ + QAudioFormat format; + + // testAudio() assumes this sample rate + Q_ASSERT(opusConfig->sampleRate == 48000); + + format.setSampleRate(opusConfig->sampleRate); + format.setChannelCount(opusConfig->channelCount); + format.setSampleSize(16); + format.setSampleType(QAudioFormat::SignedInt); + format.setCodec("audio/pcm"); + + m_AudioOutput = new QAudioOutput(format); + + m_AudioOutput->setBufferSize(SAMPLES_PER_FRAME * 2); + + qInfo() << "Audio stream buffer:" << m_AudioOutput->bufferSize() << "bytes"; + + m_OutputDevice = m_AudioOutput->start(); + if (m_OutputDevice == nullptr) { + qWarning() << "Audio start failed:" << m_AudioOutput->error(); + return false; + } + + return true; +} + +void QtAudioRenderer::submitAudio(short* audioBuffer, int audioSize) +{ + m_OutputDevice->write((const char *)audioBuffer, audioSize); +} + +bool QtAudioRenderer::testAudio(int audioConfiguration) +{ + QAudioFormat format; + + format.setSampleRate(48000); + format.setSampleSize(16); + format.setSampleType(QAudioFormat::SignedInt); + format.setCodec("audio/pcm"); + + switch (audioConfiguration) { + case AUDIO_CONFIGURATION_STEREO: + format.setChannelCount(2); + break; + case AUDIO_CONFIGURATION_51_SURROUND: + format.setChannelCount(6); + break; + default: + Q_ASSERT(false); + return false; + } + + if (QAudioDeviceInfo::defaultOutputDevice().isFormatSupported(format)) { + qInfo() << "Audio test successful with" << format.channelCount() << "channels"; + return true; + } + else { + qWarning() << "Audio test failed with" << format.channelCount() << "channels"; + return false; + } +} + +int QtAudioRenderer::detectAudioConfiguration() +{ + int preferredChannelCount = QAudioDeviceInfo::defaultOutputDevice().preferredFormat().channelCount(); + + qInfo() << "Audio output device prefers" << preferredChannelCount << "channel configuration"; + + // We can better downmix 5.1 to quad than we can upmix stereo + if (preferredChannelCount > 2) { + return AUDIO_CONFIGURATION_51_SURROUND; + } + else { + return AUDIO_CONFIGURATION_STEREO; + } +} diff --git a/app/streaming/audio/renderers/qtaud.h b/app/streaming/audio/renderers/qtaud.h new file mode 100644 index 00000000..fc664dfa --- /dev/null +++ b/app/streaming/audio/renderers/qtaud.h @@ -0,0 +1,24 @@ +#pragma once + +#include "renderer.h" +#include + +class QtAudioRenderer : public IAudioRenderer +{ +public: + QtAudioRenderer(); + + virtual ~QtAudioRenderer(); + + virtual bool prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* opusConfig); + + virtual void submitAudio(short* audioBuffer, int audioSize); + + virtual bool testAudio(int audioConfiguration); + + virtual int detectAudioConfiguration(); + +private: + QAudioOutput* m_AudioOutput; + QIODevice* m_OutputDevice; +};