[AFV] Handle stereo in- and output devices

This commit is contained in:
Roland Rossgotterer
2019-09-25 21:37:48 +02:00
committed by Mat Sutcliffe
parent a06205efbd
commit 9f497c1b60
5 changed files with 52 additions and 24 deletions

View File

@@ -93,29 +93,28 @@ namespace BlackCore
{ {
if (m_started) { return; } if (m_started) { return; }
QAudioFormat inputFormat; m_inputFormat.setSampleRate(m_sampleRate);
inputFormat.setSampleRate(m_sampleRate); m_inputFormat.setChannelCount(1);
inputFormat.setChannelCount(1); m_inputFormat.setSampleSize(16);
inputFormat.setSampleSize(16); m_inputFormat.setSampleType(QAudioFormat::SignedInt);
inputFormat.setSampleType(QAudioFormat::SignedInt); m_inputFormat.setByteOrder(QAudioFormat::LittleEndian);
inputFormat.setByteOrder(QAudioFormat::LittleEndian); m_inputFormat.setCodec("audio/pcm");
inputFormat.setCodec("audio/pcm"); if (!inputDevice.isFormatSupported(m_inputFormat))
if (!inputDevice.isFormatSupported(inputFormat))
{ {
inputFormat = inputDevice.nearestFormat(inputFormat); m_inputFormat = inputDevice.nearestFormat(m_inputFormat);
const QString w = const QString w =
inputDevice.deviceName() % inputDevice.deviceName() %
": Default INPUT format not supported - trying to use nearest" % ": Default INPUT format not supported - trying to use nearest" %
" Sample rate: " % QString::number(inputFormat.sampleRate()) % " Sample rate: " % QString::number(m_inputFormat.sampleRate()) %
" Sample size: " % QString::number(inputFormat.sampleSize()) % " Sample size: " % QString::number(m_inputFormat.sampleSize()) %
" Sample type: " % QString::number(inputFormat.sampleType()) % " Sample type: " % QString::number(m_inputFormat.sampleType()) %
" Byte order: " % QString::number(inputFormat.byteOrder()) % " Byte order: " % QString::number(m_inputFormat.byteOrder()) %
" Codec: " % inputFormat.codec() % " Codec: " % m_inputFormat.codec() %
" Channel count: " % QString::number(inputFormat.channelCount()); " Channel count: " % QString::number(m_inputFormat.channelCount());
CLogMessage(this).warning(w); CLogMessage(this).warning(w);
} }
m_audioInput.reset(new QAudioInput(inputDevice, inputFormat)); m_audioInput.reset(new QAudioInput(inputDevice, m_inputFormat));
m_audioInputBuffer.start(); m_audioInputBuffer.start();
m_audioInput->start(&m_audioInputBuffer); m_audioInput->start(&m_audioInputBuffer);
@@ -138,6 +137,11 @@ namespace BlackCore
{ {
QVector<qint16> samples = convertBytesTo16BitPCM(frame); QVector<qint16> samples = convertBytesTo16BitPCM(frame);
if (m_inputFormat.channelCount() == 2)
{
samples = convertFromStereoToMono(samples);
}
int value = 0; int value = 0;
for (qint16 &sample : samples) for (qint16 &sample : samples)
{ {

View File

@@ -119,6 +119,7 @@ namespace BlackCore
BlackSound::Codecs::COpusEncoder m_encoder; BlackSound::Codecs::COpusEncoder m_encoder;
QScopedPointer<QAudioInput> m_audioInput; QScopedPointer<QAudioInput> m_audioInput;
QAudioDeviceInfo m_device; QAudioDeviceInfo m_device;
QAudioFormat m_inputFormat;
bool m_started = false; bool m_started = false;
int m_opusBytesEncoded = 0; int m_opusBytesEncoded = 0;

View File

@@ -10,6 +10,7 @@
#include "output.h" #include "output.h"
#include "blackmisc/logmessage.h" #include "blackmisc/logmessage.h"
#include "blacksound/audioutilities.h"
#include <QDebug> #include <QDebug>
#include <QStringBuilder> #include <QStringBuilder>
@@ -61,16 +62,13 @@ namespace BlackCore
m_maxSampleOutput = 0; m_maxSampleOutput = 0;
} }
// if (maxlen > buffer.size()) { maxlen = buffer.size(); } if (channelCount == 2)
// memcpy(data, buffer.constData(), maxlen > buffer.size() ? buffer.size() : maxlen);
qint16 *p = reinterpret_cast<qint16 *>(data);
int index = 0;
for (int n = 0; n < count; n++)
{ {
p[index++] = buffer[n]; buffer = convertFromMonoToStereo(buffer);
if (channelCount == 2) p[index++] = buffer[n];
} }
memcpy(data, buffer.constData(), maxlen);
return maxlen; return maxlen;
} }

View File

@@ -19,3 +19,26 @@ QVector<qint16> convertFloatBytesTo16BitPCM(const QByteArray input)
qFatal("Not implemented"); qFatal("Not implemented");
return {}; return {};
} }
QVector<qint16> convertFromMonoToStereo(const QVector<qint16> &mono)
{
QVector<qint16> stereo;
stereo.reserve(mono.size() * 2);
for (qint16 sample : mono)
{
stereo << sample;
stereo << sample;
}
return stereo;
}
QVector<qint16> convertFromStereoToMono(const QVector<qint16> &stereo)
{
QVector<qint16> mono;
mono.reserve(stereo.size() / 2);
for (int i = 0; i < stereo.size(); i = i + 2)
{
mono.append(stereo.at(i));
}
return mono;
}

View File

@@ -7,5 +7,7 @@
BLACKSOUND_EXPORT QVector<qint16> convertBytesTo16BitPCM(const QByteArray input); BLACKSOUND_EXPORT QVector<qint16> convertBytesTo16BitPCM(const QByteArray input);
BLACKSOUND_EXPORT QVector<qint16> convertFloatBytesTo16BitPCM(const QByteArray input); BLACKSOUND_EXPORT QVector<qint16> convertFloatBytesTo16BitPCM(const QByteArray input);
BLACKSOUND_EXPORT QVector<qint16> convertFromMonoToStereo(const QVector<qint16> &mono);
BLACKSOUND_EXPORT QVector<qint16> convertFromStereoToMono(const QVector<qint16> &stereo);
#endif // guard #endif // guard