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