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#include <QDebug>
4#include <qaudioformat.h>
5#include <qalgorithms.h>
6
7QT_BEGIN_NAMESPACE
8
9/*!
10 \class QAudioFormat
11 \brief The QAudioFormat class stores audio stream parameter information.
12
13 \inmodule QtMultimedia
14 \ingroup multimedia
15 \ingroup multimedia_audio
16
17 An audio format specifies how data in a raw audio stream is arranged. For
18 example, how the stream is to be interpreted.
19
20 QAudioFormat contains parameters that specify how the audio sample data
21 is arranged. These are the frequency, the number of channels, and the
22 sample format. The following table describes these in more detail.
23
24 \table
25 \header
26 \li Parameter
27 \li Description
28 \row
29 \li Sample Rate
30 \li Samples per second of audio data in Hertz.
31 \row
32 \li Number of channels
33 \li The number of audio channels (typically one for mono
34 or two for stereo). These are the amount of consecutive
35 samples that together form one frame in the stream
36 \row
37 \li Sample format
38 \li The format of the audio samples in the stream
39 \endtable
40
41 This class is used in conjunction with QAudioSource or
42 QAudioSink to allow you to specify the parameters of the audio
43 stream being read or written, or with QAudioBuffer when dealing with
44 samples in memory.
45
46 You can obtain audio formats compatible with the audio device used
47 through functions in QAudioDevice. This class also lets you
48 query available parameter values for a device, so that you can set
49 the parameters yourself. See the \l QAudioDevice class
50 description for details. You need to know the format of the audio
51 streams you wish to play or record.
52
53 Samples for all channels will be interleaved.
54 One sample for each channel for the same instant in time is referred
55 to as a frame in Qt Multimedia (and other places).
56*/
57
58/*!
59 \fn QAudioFormat::QAudioFormat()
60
61 Constructs a new audio format.
62
63 Values are initialized as follows:
64 \list
65 \li sampleRate() = 0
66 \li channelCount() = 0
67 \li sampleFormat() = QAudioFormat::Unknown
68 \endlist
69*/
70
71/*!
72 \fn QAudioFormat::QAudioFormat(const QAudioFormat &other)
73
74 Construct a new audio format using \a other.
75*/
76
77/*!
78 \fn QAudioFormat::~QAudioFormat()
79
80 Destroy this audio format.
81*/
82
83/*!
84 \fn bool QAudioFormat::operator==(const QAudioFormat &a, const QAudioFormat &b)
85
86 Returns \c true if audio format \a a is equal to \a b, otherwise returns \c false.
87*/
88
89/*!
90 \fn bool QAudioFormat::operator!=(const QAudioFormat &a, const QAudioFormat &b)
91
92 Returns \c true if audio format \a a is not equal to \a b, otherwise returns \c false.
93*/
94
95/*!
96 \fn bool QAudioFormat::isValid() const
97
98 Returns \c true if all of the parameters are valid.
99*/
100
101/*!
102 \fn void QAudioFormat::setSampleRate(int samplerate)
103
104 Sets the sample rate to \a samplerate in Hertz.
105*/
106
107/*!
108 \fn int QAudioFormat::sampleRate() const
109
110 Returns the current sample rate in Hertz.
111*/
112
113/*!
114 \enum QAudioFormat::AudioChannelPosition
115
116 Describes the possible audio channel positions. These follow the standard
117 definition used in the 22.2 surround sound configuration.
118
119 \value UnknownPosition Unknown position
120 \value FrontLeft
121 \value FrontRight
122 \value FrontCenter
123 \value LFE Low Frequency Effect channel (Subwoofer)
124 \value BackLeft
125 \value BackRight
126 \value FrontLeftOfCenter
127 \value FrontRightOfCenter
128 \value BackCenter
129 \value LFE2
130 \value SideLeft
131 \value SideRight
132 \value TopFrontLeft
133 \value TopFrontRight
134 \value TopFrontCenter
135 \value TopCenter
136 \value TopBackLeft
137 \value TopBackRight
138 \value TopSideLeft
139 \value TopSideRight
140 \value TopBackCenter
141 \value BottomFrontCenter
142 \value BottomFrontLeft
143 \value BottomFrontRight
144*/
145/*!
146 \variable QAudioFormat::NChannelPositions
147 \internal
148*/
149
150/*!
151 \enum QAudioFormat::ChannelConfig
152
153 This enum describes a standardized audio channel layout. The most common
154 configurations are Mono, Stereo, 2.1 (stereo plus low frequency), 5.1 surround,
155 and 7.1 surround configurations.
156
157 \value ChannelConfigUnknown The channel configuration is not known.
158 \value ChannelConfigMono The audio has one Center channel.
159 \value ChannelConfigStereo The audio has two channels, Left and Right.
160 \value ChannelConfig2Dot1 The audio has three channels, Left, Right and
161 LFE (low frequency effect).
162 \value ChannelConfig3Dot0 The audio has three channels, Left, Right, and
163 Center.
164 \value ChannelConfig3Dot1 The audio has four channels, Left, Right, Center,
165 and LFE (low frequency effect).
166 \value ChannelConfigSurround5Dot0 The audio has five channels, Left, Right,
167 Center, BackLeft, and BackRight.
168 \value ChannelConfigSurround5Dot1 The audio has 6 channels, Left, Right,
169 Center, LFE, BackLeft, and BackRight.
170 \value ChannelConfigSurround7Dot0 The audio has 7 channels, Left, Right,
171 Center, BackLeft, BackRight, SideLeft, and SideRight.
172 \value ChannelConfigSurround7Dot1 The audio has 8 channels, Left, Right,
173 Center, LFE, BackLeft, BackRight, SideLeft, and SideRight.
174*/
175
176/*!
177 Sets the channel configuration to \a config.
178
179 Sets the channel configuration of the audio format to one of the standard
180 audio channel configurations.
181
182 \note that this will also modify the channel count.
183*/
184void QAudioFormat::setChannelConfig(ChannelConfig config) noexcept
185{
186 m_channelConfig = config;
187 if (config != ChannelConfigUnknown)
188 m_channelCount = qPopulationCount(v: config);
189}
190
191/*!
192 Returns the position of a certain audio \a channel inside an audio frame
193 for the given format.
194 Returns -1 if the channel does not exist for this format or the channel
195 configuration is unknown.
196*/
197int QAudioFormat::channelOffset(AudioChannelPosition channel) const noexcept
198{
199 if (!(m_channelConfig & (1u << channel)))
200 return -1;
201
202 uint maskedChannels = m_channelConfig & ((1u << channel) - 1);
203 return qPopulationCount(v: maskedChannels);
204}
205
206/*!
207 \fn void QAudioFormat::setChannelCount(int channels)
208
209 Sets the channel count to \a channels. Setting this also sets the channel
210 config to ChannelConfigUnknown.
211*/
212
213/*!
214 \fn template <typename... Args> QAudioFormat::ChannelConfig QAudioFormat::channelConfig(Args... channels)
215
216 Returns the current channel configuration for the given \a channels.
217*/
218/*!
219 \fn QAudioFormat::ChannelConfig QAudioFormat::channelConfig() const noexcept
220
221 Returns the current channel configuration.
222*/
223
224/*!
225 \fn int QAudioFormat::channelCount() const
226
227 Returns the current channel count value.
228
229*/
230
231/*!
232 \fn void QAudioFormat::setSampleFormat(SampleFormat format)
233
234 Sets the sample format to \a format.
235
236 \sa QAudioFormat::SampleFormat
237*/
238
239/*!
240 \fn QAudioFormat::SampleFormat QAudioFormat::sampleFormat() const
241 Returns the current sample format.
242
243 \sa setSampleFormat()
244*/
245
246/*!
247 Returns the number of bytes required for this audio format for \a microseconds.
248
249 Returns 0 if this format is not valid.
250
251 Note that some rounding may occur if \a microseconds is not an exact fraction of the
252 sampleRate().
253
254 \sa durationForBytes()
255 */
256qint32 QAudioFormat::bytesForDuration(qint64 microseconds) const
257{
258 return bytesPerFrame() * framesForDuration(microseconds);
259}
260
261/*!
262 Returns the number of microseconds represented by \a bytes in this format.
263
264 Returns 0 if this format is not valid.
265
266 Note that some rounding may occur if \a bytes is not an exact multiple
267 of the number of bytes per frame.
268
269 \sa bytesForDuration()
270*/
271qint64 QAudioFormat::durationForBytes(qint32 bytes) const
272{
273 // avoid compiler warnings about unused variables. [[maybe_unused]] in the header
274 // gives compiler errors on older gcc versions
275 Q_UNUSED(reserved);
276
277 if (!isValid() || bytes <= 0)
278 return 0;
279
280 // We round the byte count to ensure whole frames
281 return qint64(1000000LL * (bytes / bytesPerFrame())) / sampleRate();
282}
283
284/*!
285 Returns the number of bytes required for \a frameCount frames of this format.
286
287 Returns 0 if this format is not valid.
288
289 \sa bytesForDuration()
290*/
291qint32 QAudioFormat::bytesForFrames(qint32 frameCount) const
292{
293 return frameCount * bytesPerFrame();
294}
295
296/*!
297 Returns the number of frames represented by \a byteCount in this format.
298
299 Note that some rounding may occur if \a byteCount is not an exact multiple
300 of the number of bytes per frame.
301
302 Each frame has one sample per channel.
303
304 \sa framesForDuration()
305*/
306qint32 QAudioFormat::framesForBytes(qint32 byteCount) const
307{
308 int size = bytesPerFrame();
309 if (size > 0)
310 return byteCount / size;
311 return 0;
312}
313
314/*!
315 Returns the number of frames required to represent \a microseconds in this format.
316
317 Note that some rounding may occur if \a microseconds is not an exact fraction of the
318 \l sampleRate().
319*/
320qint32 QAudioFormat::framesForDuration(qint64 microseconds) const
321{
322 if (!isValid())
323 return 0;
324
325 return qint32((microseconds * sampleRate()) / 1000000LL);
326}
327
328/*!
329 Return the number of microseconds represented by \a frameCount frames in this format.
330*/
331qint64 QAudioFormat::durationForFrames(qint32 frameCount) const
332{
333 if (!isValid() || frameCount <= 0)
334 return 0;
335
336 return (frameCount * 1000000LL) / sampleRate();
337}
338
339/*!
340 \fn int QAudioFormat::bytesPerFrame() const
341
342 Returns the number of bytes required to represent one frame
343 (a sample in each channel) in this format.
344
345 Returns 0 if this format is invalid.
346*/
347
348/*!
349 \fn int QAudioFormat::bytesPerSample() const
350 Returns the number of bytes required to represent one sample in this format.
351
352 Returns 0 if this format is invalid.
353*/
354
355/*!
356 Normalizes the \a sample value to a number between -1 and 1.
357 The method depends on the QaudioFormat.
358*/
359float QAudioFormat::normalizedSampleValue(const void *sample) const
360{
361 switch (m_sampleFormat) {
362 case UInt8:
363 return ((float)*reinterpret_cast<const quint8 *>(sample))
364 / (float)std::numeric_limits<qint8>::max()
365 - 1.;
366 case Int16:
367 return ((float)*reinterpret_cast<const qint16 *>(sample))
368 / (float)std::numeric_limits<qint16>::max();
369 case Int32:
370 return ((float)*reinterpret_cast<const qint32 *>(sample))
371 / (float)std::numeric_limits<qint32>::max();
372 case Float:
373 return *reinterpret_cast<const float *>(sample);
374 case Unknown:
375 case NSampleFormats:
376 break;
377 }
378
379 return 0.;
380}
381
382/*!
383 Returns a default channel configuration for \a channelCount.
384
385 Default configurations are defined for up to 8 channels, and correspond to
386 standard Mono, Stereo and Surround configurations. For higher channel counts,
387 this simply uses the first \a channelCount audio channels defined in
388 \l QAudioFormat::AudioChannelPosition.
389*/
390QAudioFormat::ChannelConfig QAudioFormat::defaultChannelConfigForChannelCount(int channelCount)
391{
392 QAudioFormat::ChannelConfig config;
393 switch (channelCount) {
394 case 0:
395 config = QAudioFormat::ChannelConfigUnknown;
396 break;
397 case 1:
398 config = QAudioFormat::ChannelConfigMono;
399 break;
400 case 2:
401 config = QAudioFormat::ChannelConfigStereo;
402 break;
403 case 3:
404 config = QAudioFormat::ChannelConfig2Dot1;
405 break;
406 case 4:
407 config = QAudioFormat::channelConfig(channels: QAudioFormat::FrontLeft, channels: QAudioFormat::FrontRight,
408 channels: QAudioFormat::BackLeft, channels: QAudioFormat::BackRight);
409 break;
410 case 5:
411 config = QAudioFormat::ChannelConfigSurround5Dot0;
412 break;
413 case 6:
414 config = QAudioFormat::ChannelConfigSurround5Dot1;
415 break;
416 case 7:
417 config = QAudioFormat::ChannelConfigSurround7Dot0;
418 break;
419 case 8:
420 config = QAudioFormat::ChannelConfigSurround7Dot1;
421 break;
422 default:
423 // give up, simply use the first n channels
424 config = QAudioFormat::ChannelConfig((1 << (channelCount + 1)) - 1);
425 }
426 return config;
427}
428
429/*!
430 \enum QAudioFormat::SampleFormat
431
432 Qt will always expect and use samples in the endianness of the host platform.
433 When processing audio data from external sources yourself, ensure you convert
434 them to the correct endianness before writing them to a QAudioSink or
435 QAudioBuffer.
436
437 \value Unknown Not Set
438 \value UInt8 Samples are unsigned 8 bit signed integers
439 \value Int16 Samples are 16 bit signed integers
440 \value Int32 Samples are 32 bit signed integers
441 \value Float Samples are floats
442 \omitvalue NSampleFormats
443*/
444
445#ifndef QT_NO_DEBUG_STREAM
446QDebug operator<<(QDebug dbg, QAudioFormat::SampleFormat type)
447{
448 QDebugStateSaver saver(dbg);
449 dbg.nospace();
450 switch (type) {
451 case QAudioFormat::UInt8:
452 dbg << "UInt8";
453 break;
454 case QAudioFormat::Int16:
455 dbg << "Int16";
456 break;
457 case QAudioFormat::Int32:
458 dbg << "Int32";
459 break;
460 case QAudioFormat::Float:
461 dbg << "Float";
462 break;
463 default:
464 dbg << "Unknown";
465 break;
466 }
467 return dbg;
468}
469
470QDebug operator<<(QDebug dbg, const QAudioFormat &f)
471{
472 dbg << "QAudioFormat(" << f.sampleRate() << "Hz, " << f.channelCount() << "Channels, "
473 << f.sampleFormat() << "Format )";
474 return dbg;
475}
476#endif
477
478QT_END_NAMESPACE
479

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