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