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
qtaudio.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 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#include <qtaudio.h>
6#include <qmath.h>
7#include <QDebug>
8
10
11#define LOG100 4.60517018599
12
13/*!
14 \namespace QtAudio
15 \ingroup multimedia-namespaces
16 \brief The QtAudio namespace contains enums used by the audio classes.
17 \inmodule QtMultimedia
18 \ingroup multimedia
19 \ingroup multimedia_audio
20*/
21
22/*!
23 \enum QtAudio::Error
24
25 \value NoError No errors have occurred
26 \value OpenError An error occurred opening the audio device
27 \value IOError An error occurred during read/write of audio device. This can happen when
28 e.g. an external audio interface is disconnected.
29 \value UnderrunError \e{This value has been deprecated in Qt-6.11 and is not emitted from Qt. Observe
30 QtAudio::State::IdleState instead.}.
31 Audio data is not being fed to the audio device at a fast enough rate.
32 \value FatalError A non-recoverable error has occurred, the audio device is not usable at this time.
33*/
34
35/*!
36 \enum QtAudio::State
37
38 \value ActiveState Audio data is being processed, this state is set after start() is called
39 and while audio data is available to be processed.
40 \value SuspendedState The audio stream is in a suspended state. Entered after suspend() is called
41 or when another stream takes control of the audio device. In the later case,
42 a call to resume will return control of the audio device to this stream. This
43 should usually only be done upon user request.
44 \value StoppedState The audio device is closed, and is not processing any audio data
45 \value IdleState This state indicates that the audio system is temporarily idle due to
46 a buffering condition.
47 For a QAudioSink, IdleState means there isn’t enough data available
48 from the QIODevice to read.
49 For a QAudioSource, IdleState is entered when the ring buffer that
50 feeds the QIODevice becomes full. In that case, any new audio data
51 arriving from the audio interface is discarded until the application
52 reads from the QIODevice, which frees up space in the buffer.
53*/
54
55/*!
56 \enum QtAudio::VolumeScale
57
58 This enum defines the different audio volume scales.
59
60 \value LinearVolumeScale Linear scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full
61 volume. All Qt Multimedia classes that have an audio volume use
62 a linear scale.
63 \value CubicVolumeScale Cubic scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full
64 volume.
65 \value LogarithmicVolumeScale Logarithmic Scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is
66 full volume. UI volume controls should usually use a logarithmic
67 scale.
68 \value DecibelVolumeScale Decibel (dB, amplitude) logarithmic scale. \c -200 is silence
69 and \c 0 is full volume.
70
71 \sa QtAudio::convertVolume()
72*/
73
74namespace QtAudio
75{
76
77/*!
78 Converts an audio \a volume \a from a volume scale \a to another, and returns the result.
79
80 Depending on the context, different scales are used to represent audio volume. All Qt Multimedia
81 classes that have an audio volume use a linear scale, the reason is that the loudness of a
82 speaker is controlled by modulating its voltage on a linear scale. The human ear on the other
83 hand, perceives loudness in a logarithmic way. Using a logarithmic scale for volume controls
84 is therefore appropriate in most applications. The decibel scale is logarithmic by nature and
85 is commonly used to define sound levels, it is usually used for UI volume controls in
86 professional audio applications. The cubic scale is a computationally cheap approximation of a
87 logarithmic scale, it provides more control over lower volume levels.
88
89 The following example shows how to convert the volume value from a slider control before passing
90 it to a QMediaPlayer. As a result, the perceived increase in volume is the same when increasing
91 the volume slider from 20 to 30 as it is from 50 to 60:
92
93 \snippet multimedia-snippets/audio.cpp Volume conversion
94
95 \sa VolumeScale, QAudioSink::setVolume(), QAudioSource::setVolume(),
96 QSoundEffect::setVolume()
97*/
98float convertVolume(float volume, VolumeScale from, VolumeScale to)
99{
100 switch (from) {
101 case LinearVolumeScale:
102 volume = qMax(float(0), volume);
103 switch (to) {
104 case LinearVolumeScale:
105 return volume;
106 case CubicVolumeScale:
107 return qPow(volume, float(1 / 3.0));
108 case LogarithmicVolumeScale:
109 return 1 - std::exp(-volume * LOG100);
110 case DecibelVolumeScale:
111 if (volume < 0.001)
112 return float(-200);
113 else
114 return float(20.0) * std::log10(volume);
115 }
116 break;
117 case CubicVolumeScale:
118 volume = qMax(float(0), volume);
119 switch (to) {
120 case LinearVolumeScale:
121 return volume * volume * volume;
122 case CubicVolumeScale:
123 return volume;
124 case LogarithmicVolumeScale:
125 return 1 - std::exp(-volume * volume * volume * LOG100);
126 case DecibelVolumeScale:
127 if (volume < 0.001)
128 return float(-200);
129 else
130 return float(3.0 * 20.0) * std::log10(volume);
131 }
132 break;
133 case LogarithmicVolumeScale:
134 volume = qMax(float(0), volume);
135 switch (to) {
136 case LinearVolumeScale:
137 if (volume > 0.99)
138 return 1;
139 else
140 return -std::log(1 - volume) / LOG100;
141 case CubicVolumeScale:
142 if (volume > 0.99)
143 return 1;
144 else
145 return qPow(-std::log(1 - volume) / LOG100, float(1 / 3.0));
146 case LogarithmicVolumeScale:
147 return volume;
148 case DecibelVolumeScale:
149 if (volume < 0.001)
150 return float(-200);
151 else if (volume > 0.99)
152 return 0;
153 else
154 return float(20.0) * std::log10(-std::log(1 - volume) / LOG100);
155 }
156 break;
157 case DecibelVolumeScale:
158 switch (to) {
159 case LinearVolumeScale:
160 return qPow(float(10.0), volume / float(20.0));
161 case CubicVolumeScale:
162 return qPow(float(10.0), volume / float(3.0 * 20.0));
163 case LogarithmicVolumeScale:
164 if (qFuzzyIsNull(volume))
165 return 1;
166 else
167 return 1 - std::exp(-qPow(float(10.0), volume / float(20.0)) * LOG100);
168 case DecibelVolumeScale:
169 return volume;
170 }
171 break;
172 }
173
174 return volume;
175}
176
177} // namespace QtAudio
178
179#ifndef QT_NO_DEBUG_STREAM
180QDebug operator<<(QDebug dbg, QAudio::Error error)
181{
182 QDebugStateSaver saver(dbg);
183 dbg.nospace();
184 switch (error) {
185 case QAudio::NoError:
186 dbg << "NoError";
187 break;
188 case QAudio::OpenError:
189 dbg << "OpenError";
190 break;
191 case QAudio::IOError:
192 dbg << "IOError";
193 break;
194 QT_WARNING_PUSH;
195 QT_WARNING_DISABLE_DEPRECATED;
196 case QAudio::UnderrunError:
197 dbg << "UnderrunError";
198 break;
199 QT_WARNING_POP;
200 case QAudio::FatalError:
201 dbg << "FatalError";
202 break;
203 }
204 return dbg;
205}
206
207QDebug operator<<(QDebug dbg, QAudio::State state)
208{
209 QDebugStateSaver saver(dbg);
210 dbg.nospace();
211 switch (state) {
212 case QAudio::ActiveState:
213 dbg << "ActiveState";
214 break;
215 case QAudio::SuspendedState:
216 dbg << "SuspendedState";
217 break;
218 case QAudio::StoppedState:
219 dbg << "StoppedState";
220 break;
221 case QAudio::IdleState:
222 dbg << "IdleState";
223 break;
224 }
225 return dbg;
226}
227
228QDebug operator<<(QDebug dbg, QAudio::VolumeScale scale)
229{
230 QDebugStateSaver saver(dbg);
231 dbg.nospace();
232 switch (scale) {
233 case QAudio::LinearVolumeScale:
234 dbg << "LinearVolumeScale";
235 break;
236 case QAudio::CubicVolumeScale:
237 dbg << "CubicVolumeScale";
238 break;
239 case QAudio::LogarithmicVolumeScale:
240 dbg << "LogarithmicVolumeScale";
241 break;
242 case QAudio::DecibelVolumeScale:
243 dbg << "DecibelVolumeScale";
244 break;
245 }
246 return dbg;
247}
248
249#endif
250
251
252QT_END_NAMESPACE
Combined button and popup list for selecting options.
std::enable_if_t< isAudioSourceCallback< Callback >, bool > if_audio_source_callback
Definition qtaudio.h:118
float convertVolume(float volume, VolumeScale from, VolumeScale to)
Converts an audio volume from a volume scale to another, and returns the result.
Definition qtaudio.cpp:98
QDebug operator<<(QDebug debug, QIODevice::OpenMode modes)
#define LOG100
Definition qtaudio.cpp:11