From 9f497c1b6004e9d00ad5abc8399f77b163f656a4 Mon Sep 17 00:00:00 2001 From: Roland Rossgotterer Date: Wed, 25 Sep 2019 21:37:48 +0200 Subject: [PATCH] [AFV] Handle stereo in- and output devices --- src/blackcore/afv/audio/input.cpp | 36 +++++++++++++++++------------- src/blackcore/afv/audio/input.h | 1 + src/blackcore/afv/audio/output.cpp | 12 +++++----- src/blacksound/audioutilities.cpp | 25 ++++++++++++++++++++- src/blacksound/audioutilities.h | 2 ++ 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/blackcore/afv/audio/input.cpp b/src/blackcore/afv/audio/input.cpp index be7829794..aa75e976b 100644 --- a/src/blackcore/afv/audio/input.cpp +++ b/src/blackcore/afv/audio/input.cpp @@ -93,29 +93,28 @@ namespace BlackCore { if (m_started) { return; } - QAudioFormat inputFormat; - inputFormat.setSampleRate(m_sampleRate); - inputFormat.setChannelCount(1); - inputFormat.setSampleSize(16); - inputFormat.setSampleType(QAudioFormat::SignedInt); - inputFormat.setByteOrder(QAudioFormat::LittleEndian); - inputFormat.setCodec("audio/pcm"); - if (!inputDevice.isFormatSupported(inputFormat)) + m_inputFormat.setSampleRate(m_sampleRate); + m_inputFormat.setChannelCount(1); + m_inputFormat.setSampleSize(16); + m_inputFormat.setSampleType(QAudioFormat::SignedInt); + m_inputFormat.setByteOrder(QAudioFormat::LittleEndian); + m_inputFormat.setCodec("audio/pcm"); + if (!inputDevice.isFormatSupported(m_inputFormat)) { - inputFormat = inputDevice.nearestFormat(inputFormat); + m_inputFormat = inputDevice.nearestFormat(m_inputFormat); const QString w = inputDevice.deviceName() % ": Default INPUT format not supported - trying to use nearest" % - " Sample rate: " % QString::number(inputFormat.sampleRate()) % - " Sample size: " % QString::number(inputFormat.sampleSize()) % - " Sample type: " % QString::number(inputFormat.sampleType()) % - " Byte order: " % QString::number(inputFormat.byteOrder()) % - " Codec: " % inputFormat.codec() % - " Channel count: " % QString::number(inputFormat.channelCount()); + " Sample rate: " % QString::number(m_inputFormat.sampleRate()) % + " Sample size: " % QString::number(m_inputFormat.sampleSize()) % + " Sample type: " % QString::number(m_inputFormat.sampleType()) % + " Byte order: " % QString::number(m_inputFormat.byteOrder()) % + " Codec: " % m_inputFormat.codec() % + " Channel count: " % QString::number(m_inputFormat.channelCount()); CLogMessage(this).warning(w); } - m_audioInput.reset(new QAudioInput(inputDevice, inputFormat)); + m_audioInput.reset(new QAudioInput(inputDevice, m_inputFormat)); m_audioInputBuffer.start(); m_audioInput->start(&m_audioInputBuffer); @@ -138,6 +137,11 @@ namespace BlackCore { QVector samples = convertBytesTo16BitPCM(frame); + if (m_inputFormat.channelCount() == 2) + { + samples = convertFromStereoToMono(samples); + } + int value = 0; for (qint16 &sample : samples) { diff --git a/src/blackcore/afv/audio/input.h b/src/blackcore/afv/audio/input.h index 2286649b4..4778ad68a 100644 --- a/src/blackcore/afv/audio/input.h +++ b/src/blackcore/afv/audio/input.h @@ -119,6 +119,7 @@ namespace BlackCore BlackSound::Codecs::COpusEncoder m_encoder; QScopedPointer m_audioInput; QAudioDeviceInfo m_device; + QAudioFormat m_inputFormat; bool m_started = false; int m_opusBytesEncoded = 0; diff --git a/src/blackcore/afv/audio/output.cpp b/src/blackcore/afv/audio/output.cpp index c84888f33..93b9b13f5 100644 --- a/src/blackcore/afv/audio/output.cpp +++ b/src/blackcore/afv/audio/output.cpp @@ -10,6 +10,7 @@ #include "output.h" #include "blackmisc/logmessage.h" +#include "blacksound/audioutilities.h" #include #include @@ -61,16 +62,13 @@ namespace BlackCore m_maxSampleOutput = 0; } - // if (maxlen > buffer.size()) { maxlen = buffer.size(); } - // memcpy(data, buffer.constData(), maxlen > buffer.size() ? buffer.size() : maxlen); - qint16 *p = reinterpret_cast(data); - int index = 0; - for (int n = 0; n < count; n++) + if (channelCount == 2) { - p[index++] = buffer[n]; - if (channelCount == 2) p[index++] = buffer[n]; + buffer = convertFromMonoToStereo(buffer); } + memcpy(data, buffer.constData(), maxlen); + return maxlen; } diff --git a/src/blacksound/audioutilities.cpp b/src/blacksound/audioutilities.cpp index f1df2bdfd..52e30c53b 100644 --- a/src/blacksound/audioutilities.cpp +++ b/src/blacksound/audioutilities.cpp @@ -8,7 +8,7 @@ QVector convertBytesTo16BitPCM(const QByteArray input) for (int n = 0; n < inputSamples; n++) { - output[n] = *reinterpret_cast(input.data() + n * 2); + output[n] = *reinterpret_cast(input.data() + n * 2); } return output; } @@ -19,3 +19,26 @@ QVector convertFloatBytesTo16BitPCM(const QByteArray input) qFatal("Not implemented"); return {}; } + +QVector convertFromMonoToStereo(const QVector &mono) +{ + QVector stereo; + stereo.reserve(mono.size() * 2); + for (qint16 sample : mono) + { + stereo << sample; + stereo << sample; + } + return stereo; +} + +QVector convertFromStereoToMono(const QVector &stereo) +{ + QVector mono; + mono.reserve(stereo.size() / 2); + for (int i = 0; i < stereo.size(); i = i + 2) + { + mono.append(stereo.at(i)); + } + return mono; +} diff --git a/src/blacksound/audioutilities.h b/src/blacksound/audioutilities.h index 9cc2d8612..b28ea434c 100644 --- a/src/blacksound/audioutilities.h +++ b/src/blacksound/audioutilities.h @@ -7,5 +7,7 @@ BLACKSOUND_EXPORT QVector convertBytesTo16BitPCM(const QByteArray input); BLACKSOUND_EXPORT QVector convertFloatBytesTo16BitPCM(const QByteArray input); +BLACKSOUND_EXPORT QVector convertFromMonoToStereo(const QVector &mono); +BLACKSOUND_EXPORT QVector convertFromStereoToMono(const QVector &stereo); #endif // guard