1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
5#ifndef QAUDIOFORMAT_H
6#define QAUDIOFORMAT_H
7
8#include <QtCore/qobject.h>
9#include <QtCore/qshareddata.h>
10
11#include <QtMultimedia/qtmultimediaglobal.h>
12
13QT_BEGIN_NAMESPACE
14
15namespace QtPrivate {
16template <typename... Args>
17constexpr int channelConfig(Args... values) {
18 return (0 | ... | (1u << values));
19}
20}
21
22class QAudioFormat
23{
24public:
25 enum SampleFormat : quint16 {
26 Unknown,
27 UInt8,
28 Int16,
29 Int32,
30 Float,
31 NSampleFormats
32 };
33
34 // This matches the speaker positions of a 22.2 audio layout. Stereo, Surround 5.1 and Surround 7.1 are subsets of these
35 enum AudioChannelPosition {
36 UnknownPosition,
37 FrontLeft,
38 FrontRight,
39 FrontCenter,
40 LFE,
41 BackLeft,
42 BackRight,
43 FrontLeftOfCenter,
44 FrontRightOfCenter,
45 BackCenter,
46 SideLeft,
47 SideRight,
48 TopCenter,
49 TopFrontLeft,
50 TopFrontCenter,
51 TopFrontRight,
52 TopBackLeft,
53 TopBackCenter,
54 TopBackRight,
55 LFE2,
56 TopSideLeft,
57 TopSideRight,
58 BottomFrontCenter,
59 BottomFrontLeft,
60 BottomFrontRight
61 };
62 static constexpr int NChannelPositions = BottomFrontRight + 1;
63
64 enum ChannelConfig : quint32 {
65 ChannelConfigUnknown = 0,
66 ChannelConfigMono = QtPrivate::channelConfig(values: FrontCenter),
67 ChannelConfigStereo = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight),
68 ChannelConfig2Dot1 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: LFE),
69 ChannelConfig3Dot0 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: FrontCenter),
70 ChannelConfig3Dot1 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: FrontCenter, values: LFE),
71 ChannelConfigSurround5Dot0 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: FrontCenter, values: BackLeft, values: BackRight),
72 ChannelConfigSurround5Dot1 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: FrontCenter, values: LFE, values: BackLeft, values: BackRight),
73 ChannelConfigSurround7Dot0 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: FrontCenter, values: BackLeft, values: BackRight, values: SideLeft, values: SideRight),
74 ChannelConfigSurround7Dot1 = QtPrivate::channelConfig(values: FrontLeft, values: FrontRight, values: FrontCenter, values: LFE, values: BackLeft, values: BackRight, values: SideLeft, values: SideRight),
75 };
76
77 template <typename... Args>
78 static constexpr ChannelConfig channelConfig(Args... channels)
79 {
80 return ChannelConfig(QtPrivate::channelConfig(channels...));
81 }
82
83 constexpr bool isValid() const noexcept
84 {
85 return m_sampleRate > 0 && m_channelCount > 0 && m_sampleFormat != Unknown;
86 }
87
88 constexpr void setSampleRate(int sampleRate) noexcept { m_sampleRate = sampleRate; }
89 constexpr int sampleRate() const noexcept { return m_sampleRate; }
90
91 Q_MULTIMEDIA_EXPORT void setChannelConfig(ChannelConfig config) noexcept;
92 constexpr ChannelConfig channelConfig() const noexcept { return m_channelConfig; }
93
94 constexpr void setChannelCount(int channelCount) noexcept
95 {
96 m_channelConfig = ChannelConfigUnknown;
97 m_channelCount = short(channelCount);
98 }
99 constexpr int channelCount() const noexcept { return m_channelCount; }
100
101 Q_MULTIMEDIA_EXPORT int channelOffset(AudioChannelPosition channel) const noexcept;
102
103 constexpr void setSampleFormat(SampleFormat f) noexcept { m_sampleFormat = f; }
104 constexpr SampleFormat sampleFormat() const noexcept { return m_sampleFormat; }
105
106 // Helper functions
107 Q_MULTIMEDIA_EXPORT qint32 bytesForDuration(qint64 microseconds) const;
108 Q_MULTIMEDIA_EXPORT qint64 durationForBytes(qint32 byteCount) const;
109
110 Q_MULTIMEDIA_EXPORT qint32 bytesForFrames(qint32 frameCount) const;
111 Q_MULTIMEDIA_EXPORT qint32 framesForBytes(qint32 byteCount) const;
112
113 Q_MULTIMEDIA_EXPORT qint32 framesForDuration(qint64 microseconds) const;
114 Q_MULTIMEDIA_EXPORT qint64 durationForFrames(qint32 frameCount) const;
115
116 constexpr int bytesPerFrame() const { return bytesPerSample()*channelCount(); }
117 constexpr int bytesPerSample() const noexcept
118 {
119 switch (m_sampleFormat) {
120 case Unknown:
121 case NSampleFormats: return 0;
122 case UInt8: return 1;
123 case Int16: return 2;
124 case Int32:
125 case Float: return 4;
126 }
127 return 0;
128 }
129
130 Q_MULTIMEDIA_EXPORT float normalizedSampleValue(const void *sample) const;
131
132 friend bool operator==(const QAudioFormat &a, const QAudioFormat &b)
133 {
134 return a.m_sampleRate == b.m_sampleRate &&
135 a.m_channelCount == b.m_channelCount &&
136 a.m_sampleFormat == b.m_sampleFormat;
137 }
138 friend bool operator!=(const QAudioFormat &a, const QAudioFormat &b)
139 {
140 return !(a == b);
141 }
142
143 static Q_MULTIMEDIA_EXPORT ChannelConfig defaultChannelConfigForChannelCount(int channelCount);
144
145private:
146 SampleFormat m_sampleFormat = SampleFormat::Unknown;
147 short m_channelCount = 0;
148 ChannelConfig m_channelConfig = ChannelConfigUnknown;
149 int m_sampleRate = 0;
150 Q_DECL_UNUSED_MEMBER quint64 reserved = 0;
151};
152
153#ifndef QT_NO_DEBUG_STREAM
154Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QAudioFormat &);
155Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAudioFormat::SampleFormat);
156#endif
157
158QT_END_NAMESPACE
159
160Q_DECLARE_METATYPE(QAudioFormat)
161
162#endif // QAUDIOFORMAT_H
163

source code of qtmultimedia/src/multimedia/audio/qaudioformat.h