summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-06-11 20:50:44 +0200
committerLars Knoll <lars.knoll@qt.io>2021-06-19 22:57:55 +0200
commit83e9c2d8c3b278bae81a6060cc1657a95250f1ee (patch)
treedd469ebd3fa73a3b2b16eeec04eff6f90da2d47e
parent00cedc5107aecbe66619eef8baf18241ef3fc390 (diff)
Add positioning information for channels to QAudioFormat
Just having a list of x channels without knowing where they are spatially positioned is missing the most important part. Reworked the QAudioBuffer access API to allow accessing data with a specified frame layout. Change-Id: I2aba20e62e97d80ca8873c97aa00f234ea210cd2 Reviewed-by: André de la Rocha <andre.rocha@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--examples/multimedia/audiodecoder/audiodecoder.cpp2
-rw-r--r--src/multimedia/audio/qaudiobuffer.h152
-rw-r--r--src/multimedia/audio/qaudioformat.cpp72
-rw-r--r--src/multimedia/audio/qaudioformat.h66
-rw-r--r--tests/auto/unit/multimedia/qaudiobuffer/tst_qaudiobuffer.cpp165
-rw-r--r--tests/auto/unit/multimedia/qaudioformat/tst_qaudioformat.cpp39
6 files changed, 358 insertions, 138 deletions
diff --git a/examples/multimedia/audiodecoder/audiodecoder.cpp b/examples/multimedia/audiodecoder/audiodecoder.cpp
index f3492a52a..c65a3838c 100644
--- a/examples/multimedia/audiodecoder/audiodecoder.cpp
+++ b/examples/multimedia/audiodecoder/audiodecoder.cpp
@@ -133,7 +133,7 @@ void AudioDecoder::bufferReady()
return;
}
- m_waveDecoder->write((const char *)buffer.constData(), buffer.byteCount());
+ m_waveDecoder->write(buffer.constData<char>(), buffer.byteCount());
}
void AudioDecoder::error(QAudioDecoder::Error error)
diff --git a/src/multimedia/audio/qaudiobuffer.h b/src/multimedia/audio/qaudiobuffer.h
index c7ac45a48..b4c58fe10 100644
--- a/src/multimedia/audio/qaudiobuffer.h
+++ b/src/multimedia/audio/qaudiobuffer.h
@@ -49,6 +49,101 @@
QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+template <QAudioFormat::SampleFormat> struct AudioSampleFormatHelper
+{
+};
+
+template <> struct AudioSampleFormatHelper<QAudioFormat::UInt8>
+{
+ using value_type = unsigned char;
+ static constexpr value_type Default = 128;
+};
+
+template <> struct AudioSampleFormatHelper<QAudioFormat::Int16>
+{
+ using value_type = short;
+ static constexpr value_type Default = 0;
+};
+
+template <> struct AudioSampleFormatHelper<QAudioFormat::Int32>
+{
+ using value_type = int;
+ static constexpr value_type Default = 0;
+};
+
+template <> struct AudioSampleFormatHelper<QAudioFormat::Float>
+{
+ using value_type = float;
+ static constexpr value_type Default = 0.;
+};
+
+}
+
+template <QAudioFormat::ChannelConfig config, QAudioFormat::SampleFormat format>
+struct QAudioFrame
+{
+private:
+ // popcount in qalgorithms.h is unfortunately not constexpr on MSVC.
+ // Use this here as a fallback
+ static constexpr int constexprPopcount(quint32 i)
+ {
+ i = i - ((i >> 1) & 0x55555555); // add pairs of bits
+ i = (i & 0x33333333) + ((i >> 2) & 0x33333333); // quads
+ i = (i + (i >> 4)) & 0x0F0F0F0F; // groups of 8
+ return (i * 0x01010101) >> 24; // horizontal sum of bytes
+ }
+ static constexpr int nChannels = constexprPopcount(config);
+public:
+ using value_type = typename QtPrivate::AudioSampleFormatHelper<format>::value_type;
+ value_type channels[nChannels];
+ static constexpr int positionToIndex(QAudioFormat::AudioChannelPosition pos)
+ {
+ if (!(config & (1u << pos)))
+ return -1;
+
+ uint maskedChannels = config & ((1u << pos) - 1);
+ return qPopulationCount(maskedChannels);
+ }
+
+
+ value_type value(QAudioFormat::AudioChannelPosition pos) const {
+ int idx = positionToIndex(pos);
+ if (idx < 0)
+ return QtPrivate::AudioSampleFormatHelper<format>::Default;
+ return channels[idx];
+ }
+ void setValue(QAudioFormat::AudioChannelPosition pos, value_type val) const {
+ int idx = positionToIndex(pos);
+ if (idx < 0)
+ return;
+ channels[idx] = val;
+ }
+ value_type operator[](QAudioFormat::AudioChannelPosition pos) const {
+ return value(pos);
+ }
+ constexpr void clear() {
+ for (int i = 0; i < nChannels; ++i)
+ channels[i] = QtPrivate::AudioSampleFormatHelper<format>::Default;
+ }
+};
+
+template <QAudioFormat::SampleFormat Format>
+using QAudioFrameMono = QAudioFrame<QAudioFormat::ChannelConfigMono, Format>;
+
+template <QAudioFormat::SampleFormat Format>
+using QAudioFrameStereo = QAudioFrame<QAudioFormat::ChannelConfigStereo, Format>;
+
+template <QAudioFormat::SampleFormat Format>
+using QAudioFrame2Dot1 = QAudioFrame<QAudioFormat::ChannelConfig2Dot1, Format>;
+
+template <QAudioFormat::SampleFormat Format>
+using QAudioFrameSurround5Dot1 = QAudioFrame<QAudioFormat::ChannelConfigSurround5Dot1, Format>;
+
+template <QAudioFormat::SampleFormat Format>
+using QAudioFrameSurround7Dot1 = QAudioFrame<QAudioFormat::ChannelConfigSurround7Dot1, Format>;
+
+
class QAudioBufferPrivate;
QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QAudioBufferPrivate, Q_MULTIMEDIA_EXPORT)
@@ -81,48 +176,16 @@ public:
qint64 duration() const noexcept;
qint64 startTime() const noexcept;
- // Data access
- const void* constData() const noexcept;
- const void* data() const noexcept;
- void *data();
+ // Structures for easier access to data
+ typedef QAudioFrameMono<QAudioFormat::UInt8> U8M;
+ typedef QAudioFrameMono<QAudioFormat::Int16> S16M;
+ typedef QAudioFrameMono<QAudioFormat::Int32> S32M;
+ typedef QAudioFrameMono<QAudioFormat::Float> F32M;
- // Structures for easier access to stereo data
- template <typename T> struct StereoFrameDefault { enum { Default = 0 }; };
-
- template <typename T> struct StereoFrame {
-
- StereoFrame()
- : left(T(StereoFrameDefault<T>::Default))
- , right(T(StereoFrameDefault<T>::Default))
- {
- }
-
- StereoFrame(T leftSample, T rightSample)
- : left(leftSample)
- , right(rightSample)
- {
- }
-
- StereoFrame& operator=(const StereoFrame &other)
- {
- // Two straight assigns is probably
- // cheaper than a conditional check on
- // self assignment
- left = other.left;
- right = other.right;
- return *this;
- }
-
- T left;
- T right;
-
- T average() const {return (left + right) / 2;}
- void clear() {left = right = T(StereoFrameDefault<T>::Default);}
- };
-
- typedef StereoFrame<unsigned char> S8U;
- typedef StereoFrame<signed short> S16S;
- typedef StereoFrame<float> S32F;
+ typedef QAudioFrameStereo<QAudioFormat::UInt8> U8S;
+ typedef QAudioFrameStereo<QAudioFormat::Int16> S16S;
+ typedef QAudioFrameStereo<QAudioFormat::Int32> S32S;
+ typedef QAudioFrameStereo<QAudioFormat::Float> F32S;
template <typename T> const T* constData() const {
return static_cast<const T*>(constData());
@@ -134,12 +197,13 @@ public:
return static_cast<T*>(data());
}
private:
+ const void* constData() const noexcept;
+ const void* data() const noexcept;
+ void *data();
+
QExplicitlySharedDataPointer<QAudioBufferPrivate> d;
};
-template <> struct QAudioBuffer::StereoFrameDefault<unsigned char> { enum { Default = 128 }; };
-template <> struct QAudioBuffer::StereoFrameDefault<unsigned short> { enum { Default = 32768 }; };
-
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QAudioBuffer)
diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp
index c29c82914..c9217372b 100644
--- a/src/multimedia/audio/qaudioformat.cpp
+++ b/src/multimedia/audio/qaudioformat.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <QDebug>
#include <qaudioformat.h>
+#include <qalgorithms.h>
QT_BEGIN_NAMESPACE
@@ -141,10 +142,78 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum AudioChannel
+
+ The audio channels follow the standard definition used in
+
+ \value Mono
+ \value Left
+ \value Right
+ \value Center
+ \value LFE Low Frequence Effect channel (Subwoofer)
+ \value RearLeft
+ \value RearRight,
+ \value SideLeft,
+ \value SideRight
+ \value RearCenter
+*/
+
+
+/*!
+ \enum ChannelConfig
+
+ This enum describes a standardized audio channel layout. The most common configurations are Mono, Stereo, 2.1
+ (stereo plus low frequency) , 5.1 surround and 7.1 surround configurations.
+
+ \value ChannelConfigUnknown The channel configuration is not known.
+ \value ChannelConfigMono The audio has one Center channel
+ \value ChannelConfigStereo The audio has two channels, Left and Right
+ \value ChannelConfig2Dot1 The audio has three channels, Left, Right and LFE (low frequency effect)
+ \value ChannelConfigSurround5Dot0 The audio has five channels, Left, Right, Center, BackLeft, BackRight
+ \value ChannelConfigSurround5Dot1 The audio has 6 channels, Left, Right, Center, LFE, BackLeft and BackRight
+ \value ChannelConfigSurround7Dot0 The audio has 7 channels, Left, Right, Center, BackLeft, BackRight, SideLeft and SideRight
+ \value ChannelConfigSurround7Dot1 The audio has 8 channels, Left, Right, Center, LFE, BackLeft, BackRight, SideLeft and SideRight
+*/
+
+/*!
+ Sets the channel configuration to \a config.
+
+ Sets the channel configuration of the audio format to one of the standard
+ audio channel configurations.
+
+ \note that this will also modify the channel count.
+*/
+void QAudioFormat::setChannelConfig(ChannelConfig config) noexcept
+{
+ m_channelConfig = config;
+ if (config != ChannelConfigUnknown)
+ m_channelCount = qPopulationCount(config);
+}
+
+/*!
+ Returns the position of a certain audio channel inside an audio frame for the given format.
+ Returns -1 if the channel does not exist for this format or the channel configuration is unknown.
+*/
+int QAudioFormat::channelOffset(AudioChannelPosition channel) const noexcept
+{
+ if (!(m_channelConfig & (1u << channel)))
+ return -1;
+
+ uint maskedChannels = m_channelConfig & ((1u << channel) - 1);
+ return qPopulationCount(maskedChannels);
+}
+
+/*!
\fn void QAudioFormat::setChannelCount(int channels)
- Sets the channel count to \a channels.
+ Sets the channel count to \a channels. Setting this also sets the channel config to ChannelConfigUnknown.
+*/
+
+
+/*!
+ \fn QAudioFormat::ChannelConfig QAudioFormat::channelConfig() const noexcept
+ Returns the current channel configuration.
*/
/*!
@@ -198,7 +267,6 @@ qint64 QAudioFormat::durationForBytes(qint32 bytes) const
{
// avoid compiler warnings about unused variables. [[maybe_unused]] in the header
// gives compiler errors on older gcc versions
- Q_UNUSED(bitfields);
Q_UNUSED(reserved);
if (!isValid() || bytes <= 0)
diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h
index c5580e7f2..40e8ed8eb 100644
--- a/src/multimedia/audio/qaudioformat.h
+++ b/src/multimedia/audio/qaudioformat.h
@@ -50,10 +50,17 @@ QT_BEGIN_NAMESPACE
class QAudioFormatPrivate;
+namespace QtPrivate {
+template <typename... Args>
+constexpr int channelConfig(Args... values) {
+ return (0 | ... | (1u << values));
+}
+}
+
class QAudioFormat
{
public:
- enum SampleFormat {
+ enum SampleFormat : quint16 {
Unknown,
UInt8,
Int16,
@@ -62,6 +69,52 @@ public:
NSampleFormats
};
+ // This matches the speaker positions of a 22.2 audio layout. Stereo, Surround 5.1 and Surround 7.1 are subsets of these
+ enum AudioChannelPosition {
+ UnknownPosition,
+ FrontLeft,
+ FrontRight,
+ FrontCenter,
+ LFE,
+ BackLeft,
+ BackRight,
+ FrontLeftOfCenter,
+ FrontRightOfCenter,
+ BackCenter,
+ LFE2,
+ SideLeft,
+ SideRight,
+ TopFrontLeft,
+ TopFrontRight,
+ TopFrontCenter,
+ TopCenter,
+ TopBackLeft,
+ TopBackRight,
+ TopSideLeft,
+ TopSideRight,
+ TopBackCenter,
+ BottomFrontCenter,
+ BottomFrontLeft,
+ BottomFrontRight
+ };
+
+ enum ChannelConfig : quint32 {
+ ChannelConfigUnknown = 0,
+ ChannelConfigMono = QtPrivate::channelConfig(FrontCenter),
+ ChannelConfigStereo = QtPrivate::channelConfig(FrontLeft, FrontRight),
+ ChannelConfig2Dot1 = QtPrivate::channelConfig(FrontLeft, FrontRight, LFE),
+ ChannelConfigSurround5Dot0 = QtPrivate::channelConfig(FrontLeft, FrontRight, FrontCenter, BackLeft, BackRight),
+ ChannelConfigSurround5Dot1 = QtPrivate::channelConfig(FrontLeft, FrontRight, FrontCenter, LFE, BackLeft, BackRight),
+ ChannelConfigSurround7Dot0 = QtPrivate::channelConfig(FrontLeft, FrontRight, FrontCenter, BackLeft, BackRight, SideLeft, SideRight),
+ ChannelConfigSurround7Dot1 = QtPrivate::channelConfig(FrontLeft, FrontRight, FrontCenter, LFE, BackLeft, BackRight, SideLeft, SideRight),
+ };
+
+ template <typename... Args>
+ static ChannelConfig channelConfig(Args... channels)
+ {
+ return ChannelConfig(QtPrivate::channelConfig(channels...));
+ }
+
constexpr bool isValid() const noexcept
{
return m_sampleRate > 0 && m_channelCount > 0 && m_sampleFormat != Unknown;
@@ -70,9 +123,14 @@ public:
constexpr void setSampleRate(int sampleRate) noexcept { m_sampleRate = sampleRate; }
constexpr int sampleRate() const noexcept { return m_sampleRate; }
- constexpr void setChannelCount(int channelCount) noexcept { m_channelCount = channelCount; }
+ Q_MULTIMEDIA_EXPORT void setChannelConfig(ChannelConfig config) noexcept;
+ constexpr ChannelConfig channelConfig() const noexcept { return m_channelConfig; }
+
+ constexpr void setChannelCount(int channelCount) noexcept { m_channelConfig = ChannelConfigUnknown; m_channelCount = channelCount; }
constexpr int channelCount() const noexcept { return m_channelCount; }
+ Q_MULTIMEDIA_EXPORT int channelOffset(AudioChannelPosition channel) const noexcept;
+
constexpr void setSampleFormat(SampleFormat f) noexcept { m_sampleFormat = f; }
constexpr SampleFormat sampleFormat() const noexcept { return m_sampleFormat; }
@@ -115,9 +173,9 @@ public:
private:
SampleFormat m_sampleFormat = SampleFormat::Unknown;
- int m_sampleRate = 0;
short m_channelCount = 0;
- short bitfields = 0;
+ ChannelConfig m_channelConfig = ChannelConfigUnknown;
+ int m_sampleRate = 0;
quint64 reserved = 0;
};
diff --git a/tests/auto/unit/multimedia/qaudiobuffer/tst_qaudiobuffer.cpp b/tests/auto/unit/multimedia/qaudiobuffer/tst_qaudiobuffer.cpp
index 2fab63a1a..875025559 100644
--- a/tests/auto/unit/multimedia/qaudiobuffer/tst_qaudiobuffer.cpp
+++ b/tests/auto/unit/multimedia/qaudiobuffer/tst_qaudiobuffer.cpp
@@ -81,9 +81,9 @@ void tst_QAudioBuffer::ctors()
{
// Null buffer
QVERIFY(!mNull->isValid());
- QVERIFY(mNull->constData() == nullptr);
- QVERIFY(mNull->data() == nullptr);
- QVERIFY(((const QAudioBuffer*)mNull)->data() == nullptr);
+ QVERIFY(mNull->constData<char>() == nullptr);
+ QVERIFY(mNull->data<char>() == nullptr);
+ QVERIFY(((const QAudioBuffer*)mNull)->data<char>() == nullptr);
QCOMPARE(mNull->duration(), 0LL);
QCOMPARE(mNull->byteCount(), 0);
QCOMPARE(mNull->sampleCount(), 0);
@@ -92,9 +92,9 @@ void tst_QAudioBuffer::ctors()
// Empty buffer
QVERIFY(mEmpty->isValid());
- QVERIFY(mEmpty->constData() != nullptr);
- QVERIFY(mEmpty->data() != nullptr);
- QVERIFY(((const QAudioBuffer*)mEmpty)->data() != nullptr);
+ QVERIFY(mEmpty->constData<char>() != nullptr);
+ QVERIFY(mEmpty->data<char>() != nullptr);
+ QVERIFY(((const QAudioBuffer*)mEmpty)->data<char>() != nullptr);
QCOMPARE(mEmpty->sampleCount(), 1000);
QCOMPARE(mEmpty->frameCount(), 500);
QCOMPARE(mEmpty->duration(), 50000LL);
@@ -103,9 +103,9 @@ void tst_QAudioBuffer::ctors()
// bytearray buffer
QVERIFY(mFromArray->isValid());
- QVERIFY(mFromArray->constData() != nullptr);
- QVERIFY(mFromArray->data() != nullptr);
- QVERIFY(((const QAudioBuffer*)mFromArray)->data() != nullptr);
+ QVERIFY(mFromArray->constData<char>() != nullptr);
+ QVERIFY(mFromArray->data<char>() != nullptr);
+ QVERIFY(((const QAudioBuffer*)mFromArray)->data<char>() != nullptr);
/// 4000 bytes at 10KHz, 2ch, 16bit = 40kBps -> 0.1s
QCOMPARE(mFromArray->duration(), 100000LL);
QCOMPARE(mFromArray->byteCount(), 4000);
@@ -117,9 +117,9 @@ void tst_QAudioBuffer::ctors()
// Now some invalid buffers
QAudioBuffer badFormat(1000, QAudioFormat());
QVERIFY(!badFormat.isValid());
- QVERIFY(badFormat.constData() == nullptr);
- QVERIFY(badFormat.data() == nullptr);
- QVERIFY(((const QAudioBuffer*)&badFormat)->data() == nullptr);
+ QVERIFY(badFormat.constData<char>() == nullptr);
+ QVERIFY(badFormat.data<char>() == nullptr);
+ QVERIFY(((const QAudioBuffer*)&badFormat)->data<char>() == nullptr);
QCOMPARE(badFormat.duration(), 0LL);
QCOMPARE(badFormat.byteCount(), 0);
QCOMPARE(badFormat.sampleCount(), 0);
@@ -128,9 +128,9 @@ void tst_QAudioBuffer::ctors()
QAudioBuffer badArray(QByteArray(), mFormat);
QVERIFY(!badArray.isValid());
- QVERIFY(badArray.constData() == nullptr);
- QVERIFY(badArray.data() == nullptr);
- QVERIFY(((const QAudioBuffer*)&badArray)->data() == nullptr);
+ QVERIFY(badArray.constData<char>() == nullptr);
+ QVERIFY(badArray.data<char>() == nullptr);
+ QVERIFY(((const QAudioBuffer*)&badArray)->data<char>() == nullptr);
QCOMPARE(badArray.duration(), 0LL);
QCOMPARE(badArray.byteCount(), 0);
QCOMPARE(badArray.sampleCount(), 0);
@@ -139,9 +139,9 @@ void tst_QAudioBuffer::ctors()
QAudioBuffer badBoth = QAudioBuffer(QByteArray(), QAudioFormat());
QVERIFY(!badBoth.isValid());
- QVERIFY(badBoth.constData() == nullptr);
- QVERIFY(badBoth.data() == nullptr);
- QVERIFY(((const QAudioBuffer*)&badBoth)->data() == nullptr);
+ QVERIFY(badBoth.constData<char>() == nullptr);
+ QVERIFY(badBoth.data<char>() == nullptr);
+ QVERIFY(((const QAudioBuffer*)&badBoth)->data<char>() == nullptr);
QCOMPARE(badBoth.duration(), 0LL);
QCOMPARE(badBoth.byteCount(), 0);
QCOMPARE(badBoth.sampleCount(), 0);
@@ -156,77 +156,77 @@ void tst_QAudioBuffer::assign()
void tst_QAudioBuffer::constData() const
{
- const void *data = mEmpty->constData();
+ const void *data = mEmpty->constData<void *>();
QVERIFY(data != nullptr);
const unsigned int *idata = reinterpret_cast<const unsigned int*>(data);
QCOMPARE(*idata, 0U);
- const QAudioBuffer::S8U *sdata = mEmpty->constData<QAudioBuffer::S8U>();
+ const QAudioBuffer::U8S *sdata = mEmpty->constData<QAudioBuffer::U8S>();
QVERIFY(sdata);
- QCOMPARE(sdata->left, (unsigned char)0);
- QCOMPARE(sdata->right, (unsigned char)0);
+ QCOMPARE(sdata->value(QAudioFormat::FrontLeft), (unsigned char)0);
+ QCOMPARE(sdata->value(QAudioFormat::FrontRight), (unsigned char)0);
// The bytearray one should be 0x80
- data = mFromArray->constData();
+ data = mFromArray->constData<void *>();
QVERIFY(data != nullptr);
idata = reinterpret_cast<const unsigned int *>(data);
QCOMPARE(*idata, 0x80808080);
- sdata = mFromArray->constData<QAudioBuffer::S8U>();
- QCOMPARE(sdata->left, (unsigned char)0x80);
- QCOMPARE(sdata->right, (unsigned char)0x80);
+ sdata = mFromArray->constData<QAudioBuffer::U8S>();
+ QCOMPARE(sdata->value(QAudioFormat::FrontLeft), (unsigned char)0x80);
+ QCOMPARE(sdata->value(QAudioFormat::FrontRight), (unsigned char)0x80);
}
void tst_QAudioBuffer::data_const() const
{
- const void *data = ((const QAudioBuffer*)mEmpty)->data();
+ const void *data = ((const QAudioBuffer*)mEmpty)->data<void *>();
QVERIFY(data != nullptr);
const unsigned int *idata = reinterpret_cast<const unsigned int*>(data);
QCOMPARE(*idata, 0U);
- const QAudioBuffer::S8U *sdata = ((const QAudioBuffer*)mEmpty)->constData<QAudioBuffer::S8U>();
+ const QAudioBuffer::U8S *sdata = ((const QAudioBuffer*)mEmpty)->constData<QAudioBuffer::U8S>();
QVERIFY(sdata);
- QCOMPARE(sdata->left, (unsigned char)0);
- QCOMPARE(sdata->right, (unsigned char)0);
+ QCOMPARE(sdata->value(QAudioFormat::FrontLeft), (unsigned char)0);
+ QCOMPARE(sdata->value(QAudioFormat::FrontRight), (unsigned char)0);
// The bytearray one should be 0x80
- data = ((const QAudioBuffer*)mFromArray)->data();
+ data = ((const QAudioBuffer*)mFromArray)->data<void *>();
QVERIFY(data != nullptr);
idata = reinterpret_cast<const unsigned int *>(data);
QCOMPARE(*idata, 0x80808080);
- sdata = ((const QAudioBuffer*)mFromArray)->constData<QAudioBuffer::S8U>();
- QCOMPARE(sdata->left, (unsigned char)0x80);
- QCOMPARE(sdata->right, (unsigned char)0x80);
+ sdata = ((const QAudioBuffer*)mFromArray)->constData<QAudioBuffer::U8S>();
+ QCOMPARE(sdata->value(QAudioFormat::FrontLeft), (unsigned char)0x80);
+ QCOMPARE(sdata->value(QAudioFormat::FrontRight), (unsigned char)0x80);
}
void tst_QAudioBuffer::data()
{
- void *data = mEmpty->data();
+ void *data = mEmpty->data<void *>();
QVERIFY(data != nullptr);
unsigned int *idata = reinterpret_cast<unsigned int*>(data);
QCOMPARE(*idata, 0U);
- QAudioBuffer::S8U *sdata = mEmpty->data<QAudioBuffer::S8U>();
+ QAudioBuffer::U8S *sdata = mEmpty->data<QAudioBuffer::U8S>();
QVERIFY(sdata);
- QCOMPARE(sdata->left, (unsigned char)0);
- QCOMPARE(sdata->right, (unsigned char)0);
+ QCOMPARE(sdata->value(QAudioFormat::FrontLeft), (unsigned char)0);
+ QCOMPARE(sdata->value(QAudioFormat::FrontRight), (unsigned char)0);
// The bytearray one should be 0x80
- data = mFromArray->data();
+ data = mFromArray->data<void *>();
QVERIFY(data != nullptr);
idata = reinterpret_cast<unsigned int *>(data);
QCOMPARE(*idata, 0x80808080);
- sdata = mFromArray->data<QAudioBuffer::S8U>();
- QCOMPARE(sdata->left, (unsigned char)0x80);
- QCOMPARE(sdata->right, (unsigned char)0x80);
+ sdata = mFromArray->data<QAudioBuffer::U8S>();
+ QCOMPARE(sdata->value(QAudioFormat::FrontLeft), (unsigned char)0x80);
+ QCOMPARE(sdata->value(QAudioFormat::FrontRight), (unsigned char)0x80);
}
void tst_QAudioBuffer::durations()
@@ -274,72 +274,63 @@ void tst_QAudioBuffer::durations_data()
void tst_QAudioBuffer::stereoSample()
{
// Uninitialized (should default to zero level for type)
- QAudioBuffer::S8U s8u;
+ QAudioBuffer::U8S u8s;
QAudioBuffer::S16S s16s;
- QAudioBuffer::S32F s32f;
+ QAudioBuffer::F32S f32s;
+ u8s.clear();
+ s16s.clear();
+ f32s.clear();
- QCOMPARE(s8u.left, (unsigned char) 0x80);
- QCOMPARE(s8u.right, (unsigned char) 0x80);
- QCOMPARE(s8u.average(), (unsigned char) 0x80);
+ QCOMPARE(u8s[QAudioFormat::FrontLeft], (unsigned char) 0x80);
+ QCOMPARE(u8s[QAudioFormat::FrontRight], (unsigned char) 0x80);
- QCOMPARE(s16s.left, (signed short) 0x0);
- QCOMPARE(s16s.right, (signed short) 0x0);
- QCOMPARE(s16s.average(), (signed short) 0x0);
+ QCOMPARE(s16s[QAudioFormat::FrontLeft], (signed short) 0x0);
+ QCOMPARE(s16s[QAudioFormat::FrontRight], (signed short) 0x0);
- QCOMPARE(s32f.left, 0.0f);
- QCOMPARE(s32f.right, 0.0f);
- QCOMPARE(s32f.average(), 0.0f);
+ QCOMPARE(f32s[QAudioFormat::FrontLeft], 0.0f);
+ QCOMPARE(f32s[QAudioFormat::FrontRight], 0.0f);
// Initialized
- QAudioBuffer::S8U s8u2(34, 145);
- QAudioBuffer::S16S s16s2(-10000, 346);
- QAudioBuffer::S32F s32f2(500.7f, -123.1f);
+ QAudioBuffer::U8S u8s2{34, 145};
+ QAudioBuffer::S16S s16s2{-10000, 346};
+ QAudioBuffer::F32S f32s2{500.7f, -123.1f};
- QCOMPARE(s8u2.left, (unsigned char) 34);
- QCOMPARE(s8u2.right, (unsigned char) 145);
- QCOMPARE(s8u2.average(), (unsigned char) 89);
+ QCOMPARE(u8s2[QAudioFormat::FrontLeft], (unsigned char) 34);
+ QCOMPARE(u8s2[QAudioFormat::FrontRight], (unsigned char) 145);
- QCOMPARE(s16s2.left, (signed short) -10000);
- QCOMPARE(s16s2.right, (signed short) 346);
- QCOMPARE(s16s2.average(), (signed short) (-5000 + 173));
+ QCOMPARE(s16s2[QAudioFormat::FrontLeft], (signed short) -10000);
+ QCOMPARE(s16s2[QAudioFormat::FrontRight], (signed short) 346);
- QCOMPARE(s32f2.left, 500.7f);
- QCOMPARE(s32f2.right, -123.1f);
- QCOMPARE(s32f2.average(), (500.7f - 123.1f)/2);
+ QCOMPARE(f32s2[QAudioFormat::FrontLeft], 500.7f);
+ QCOMPARE(f32s2[QAudioFormat::FrontRight], -123.1f);
// Assigned
- s8u = s8u2;
+ u8s = u8s2;
s16s = s16s2;
- s32f = s32f2;
+ f32s = f32s2;
- QCOMPARE(s8u.left, (unsigned char) 34);
- QCOMPARE(s8u.right, (unsigned char) 145);
- QCOMPARE(s8u.average(), (unsigned char) 89);
+ QCOMPARE(u8s[QAudioFormat::FrontLeft], (unsigned char) 34);
+ QCOMPARE(u8s[QAudioFormat::FrontRight], (unsigned char) 145);
- QCOMPARE(s16s.left, (signed short) -10000);
- QCOMPARE(s16s.right, (signed short) 346);
- QCOMPARE(s16s.average(), (signed short) (-5000 + 173));
+ QCOMPARE(s16s[QAudioFormat::FrontLeft], (signed short) -10000);
+ QCOMPARE(s16s[QAudioFormat::FrontRight], (signed short) 346);
- QCOMPARE(s32f.left, 500.7f);
- QCOMPARE(s32f.right, -123.1f);
- QCOMPARE(s32f.average(), (500.7f - 123.1f)/2);
+ QCOMPARE(f32s[QAudioFormat::FrontLeft], 500.7f);
+ QCOMPARE(f32s[QAudioFormat::FrontRight], -123.1f);
// Cleared
- s8u.clear();
+ u8s.clear();
s16s.clear();
- s32f.clear();
+ f32s.clear();
- QCOMPARE(s8u.left, (unsigned char) 0x80);
- QCOMPARE(s8u.right, (unsigned char) 0x80);
- QCOMPARE(s8u.average(), (unsigned char) 0x80);
+ QCOMPARE(u8s[QAudioFormat::FrontLeft], (unsigned char) 0x80);
+ QCOMPARE(u8s[QAudioFormat::FrontRight], (unsigned char) 0x80);
- QCOMPARE(s16s.left, (signed short) 0x0);
- QCOMPARE(s16s.right, (signed short) 0x0);
- QCOMPARE(s16s.average(), (signed short) 0x0);
+ QCOMPARE(s16s[QAudioFormat::FrontLeft], (signed short) 0x0);
+ QCOMPARE(s16s[QAudioFormat::FrontRight], (signed short) 0x0);
- QCOMPARE(s32f.left, 0.0f);
- QCOMPARE(s32f.right, 0.0f);
- QCOMPARE(s32f.average(), 0.0f);
+ QCOMPARE(f32s[QAudioFormat::FrontLeft], 0.0f);
+ QCOMPARE(f32s[QAudioFormat::FrontRight], 0.0f);
}
diff --git a/tests/auto/unit/multimedia/qaudioformat/tst_qaudioformat.cpp b/tests/auto/unit/multimedia/qaudioformat/tst_qaudioformat.cpp
index cdfedea1e..b2ee24808 100644
--- a/tests/auto/unit/multimedia/qaudioformat/tst_qaudioformat.cpp
+++ b/tests/auto/unit/multimedia/qaudioformat/tst_qaudioformat.cpp
@@ -51,6 +51,8 @@ private slots:
void checkSampleRate();
void checkChannelCount();
+ void channelConfig();
+
void checkSizes();
void checkSizes_data();
};
@@ -162,6 +164,43 @@ void tst_QAudioFormat::checkChannelCount()
QVERIFY(audioFormat.channelCount() == 5);
}
+void tst_QAudioFormat::channelConfig()
+{
+ QAudioFormat format;
+ format.setChannelConfig(QAudioFormat::ChannelConfig2Dot1);
+ QVERIFY(format.channelConfig() == QAudioFormat::ChannelConfig2Dot1);
+ QVERIFY(format.channelCount() == 3);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontLeft) == 0);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontRight) == 1);
+ QVERIFY(format.channelOffset(QAudioFormat::BackCenter) == -1);
+
+ format.setChannelConfig(QAudioFormat::ChannelConfigSurround5Dot1);
+ QVERIFY(format.channelConfig() == QAudioFormat::ChannelConfigSurround5Dot1);
+ QVERIFY(format.channelCount() == 6);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontLeft) == 0);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontRight) == 1);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontCenter) == 2);
+ QVERIFY(format.channelOffset(QAudioFormat::LFE) == 3);
+ QVERIFY(format.channelOffset(QAudioFormat::BackLeft) == 4);
+ QVERIFY(format.channelOffset(QAudioFormat::BackRight) == 5);
+ QVERIFY(format.channelOffset(QAudioFormat::BackCenter) == -1);
+
+ auto config = QAudioFormat::channelConfig(QAudioFormat::FrontCenter, QAudioFormat::BackCenter, QAudioFormat::LFE);
+ format.setChannelConfig(config);
+ QVERIFY(format.channelConfig() == config);
+ QVERIFY(format.channelCount() == 3);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontLeft) == -1);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontRight) == -1);
+ QVERIFY(format.channelOffset(QAudioFormat::FrontCenter) == 0);
+ QVERIFY(format.channelOffset(QAudioFormat::LFE) == 1);
+ QVERIFY(format.channelOffset(QAudioFormat::BackLeft) == -1);
+ QVERIFY(format.channelOffset(QAudioFormat::BackRight) == -1);
+ QVERIFY(format.channelOffset(QAudioFormat::BackCenter) == 2);
+
+ format.setChannelCount(2);
+ QVERIFY(format.channelConfig() == QAudioFormat::ChannelConfigUnknown);
+}
+
void tst_QAudioFormat::checkSizes()
{
QFETCH(QAudioFormat, format);