From ef467807ee19cee8a041a79a4fb191a9fd781a72 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 13 Jun 2016 13:58:26 +0200 Subject: Add LogarithmicVolumeScale to VolumeScale enum. Change-Id: I0b556b5f705825fc8c8135305bda4bc860ffbf14 Reviewed-by: Christian Stromme --- .../multimedia/qdeclarativemultimediaglobal.cpp | 16 +++--- .../multimedia/qdeclarativemultimediaglobal_p.h | 1 + src/multimedia/audio/qaudio.cpp | 65 ++++++++++++++++++---- src/multimedia/audio/qaudio.h | 1 + .../doc/snippets/multimedia-snippets/audio.cpp | 2 +- 5 files changed, 65 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp index bb1b9c9d8..999f086d5 100644 --- a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp +++ b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp @@ -191,18 +191,20 @@ QJSValue QDeclarativeMultimediaGlobal::availableCameras() const Depending on the context, different scales are used to represent audio volume. All Qt Multimedia classes that have an audio volume use a linear scale, the reason is that the loudness of a speaker is controlled by modulating its voltage on a linear scale. The human ear on the other - hand, perceives loudness in a logarithmic way. That is why the decibel scale, being a logarithmic - scale, is typically used to define sound levels. UI volume controls in professional audio - applications usually use a decibel scale. The cubic scale is a computationally cheap - approximation of a logarithmic scale, most applications should use a cubic scale for their UI - volume controls. + hand, perceives loudness in a logarithmic way. Using a logarithmic scale for volume controls + is therefore appropriate in most applications. The decibel scale is logarithmic by nature and + is commonly used to define sound levels, it is usually used for UI volume controls in + professional audio applications. The cubic scale is a computationally cheap approximation of a + logarithmic scale, it provides more control over lower volume levels. Valid values for \a from and \a to are: \list \li QtMultimedia.LinearVolumeScale - Linear scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full volume. All Qt Multimedia types that have an audio volume use a linear scale. \li QtMultimedia.CubicVolumeScale - Cubic scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full - volume. UI volume controls should usually use a cubic scale. + volume. + \li QtMultimedia.LogarithmicVolumeScale - Logarithmic scale. \c 0.0 (0%) is silence and \c 1.0 + (100%) is full volume. UI volume controls should usually use a logarithmic scale. \li QtMultimedia.DecibelVolumeScale - Decibel (dB, amplitude) logarithmic scale. \c -200 is silence and \c 0 is full volume. \endlist @@ -216,7 +218,7 @@ QJSValue QDeclarativeMultimediaGlobal::availableCameras() const id: volumeSlider property real volume: QtMultimedia.convertVolume(volumeSlider.value, - QtMultimedia.CubicVolumeScale, + QtMultimedia.LogarithmicVolumeScale, QtMultimedia.LinearVolumeScale) } diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal_p.h b/src/imports/multimedia/qdeclarativemultimediaglobal_p.h index a8413cc09..101bd899a 100644 --- a/src/imports/multimedia/qdeclarativemultimediaglobal_p.h +++ b/src/imports/multimedia/qdeclarativemultimediaglobal_p.h @@ -70,6 +70,7 @@ public: enum VolumeScale { LinearVolumeScale = QAudio::LinearVolumeScale, CubicVolumeScale = QAudio::CubicVolumeScale, + LogarithmicVolumeScale = QAudio::LogarithmicVolumeScale, DecibelVolumeScale = QAudio::DecibelVolumeScale }; diff --git a/src/multimedia/audio/qaudio.cpp b/src/multimedia/audio/qaudio.cpp index 426c984df..d4f89e898 100644 --- a/src/multimedia/audio/qaudio.cpp +++ b/src/multimedia/audio/qaudio.cpp @@ -44,6 +44,8 @@ QT_BEGIN_NAMESPACE +#define LOG100 4.60517018599 + static void qRegisterAudioMetaTypes() { qRegisterMetaType(); @@ -118,13 +120,16 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterAudioMetaTypes) This enum defines the different audio volume scales. - \value LinearVolumeScale Linear scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full - volume. All Qt Multimedia classes that have an audio volume use a - linear scale. - \value CubicVolumeScale Cubic scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full - volume. UI volume controls should usually use a cubic scale. - \value DecibelVolumeScale Decibel (dB, amplitude) logarithmic scale. \c -200 is silence and - \c 0 is full volume. + \value LinearVolumeScale Linear scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full + volume. All Qt Multimedia classes that have an audio volume use + a linear scale. + \value CubicVolumeScale Cubic scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full + volume. + \value LogarithmicVolumeScale Logarithmic Scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is + full volume. UI volume controls should usually use a logarithmic + scale. + \value DecibelVolumeScale Decibel (dB, amplitude) logarithmic scale. \c -200 is silence + and \c 0 is full volume. \since 5.8 \sa QAudio::convertVolume() @@ -141,11 +146,11 @@ namespace QAudio Depending on the context, different scales are used to represent audio volume. All Qt Multimedia classes that have an audio volume use a linear scale, the reason is that the loudness of a speaker is controlled by modulating its voltage on a linear scale. The human ear on the other - hand, perceives loudness in a logarithmic way. That is why the decibel scale, being a logarithmic - scale, is typically used to define sound levels. UI volume controls in professional audio - applications usually use a decibel scale. The cubic scale is a computationally cheap - approximation of a logarithmic scale, most applications should use a cubic scale for their UI - volume controls. + hand, perceives loudness in a logarithmic way. Using a logarithmic scale for volume controls + is therefore appropriate in most applications. The decibel scale is logarithmic by nature and + is commonly used to define sound levels, it is usually used for UI volume controls in + professional audio applications. The cubic scale is a computationally cheap approximation of a + logarithmic scale, it provides more control over lower volume levels. The following example shows how to convert the volume value from a slider control before passing it to a QMediaPlayer. As a result, the perceived increase in volume is the same when increasing @@ -167,6 +172,8 @@ qreal convertVolume(qreal volume, VolumeScale from, VolumeScale to) return volume; case CubicVolumeScale: return qPow(volume, qreal(1 / 3.0)); + case LogarithmicVolumeScale: + return 1 - std::exp(-volume * LOG100); case DecibelVolumeScale: if (volume < 0.001) return qreal(-200); @@ -181,6 +188,8 @@ qreal convertVolume(qreal volume, VolumeScale from, VolumeScale to) return volume * volume * volume; case CubicVolumeScale: return volume; + case LogarithmicVolumeScale: + return 1 - std::exp(-volume * volume * volume * LOG100); case DecibelVolumeScale: if (volume < 0.001) return qreal(-200); @@ -188,12 +197,41 @@ qreal convertVolume(qreal volume, VolumeScale from, VolumeScale to) return qreal(3.0 * 20.0) * std::log10(volume); } break; + case LogarithmicVolumeScale: + volume = qMax(qreal(0), volume); + switch (to) { + case LinearVolumeScale: + if (volume > 0.99) + return 1; + else + return -std::log(1 - volume) / LOG100; + case CubicVolumeScale: + if (volume > 0.99) + return 1; + else + return qPow(-std::log(1 - volume) / LOG100, qreal(1 / 3.0)); + case LogarithmicVolumeScale: + return volume; + case DecibelVolumeScale: + if (volume < 0.001) + return qreal(-200); + else if (volume > 0.99) + return 0; + else + return qreal(20.0) * std::log10(-std::log(1 - volume) / LOG100); + } + break; case DecibelVolumeScale: switch (to) { case LinearVolumeScale: return qPow(qreal(10.0), volume / qreal(20.0)); case CubicVolumeScale: return qPow(qreal(10.0), volume / qreal(3.0 * 20.0)); + case LogarithmicVolumeScale: + if (qFuzzyIsNull(volume)) + return 1; + else + return 1 - std::exp(-qPow(qreal(10.0), volume / qreal(20.0)) * LOG100); case DecibelVolumeScale: return volume; } @@ -316,6 +354,9 @@ QDebug operator<<(QDebug dbg, QAudio::VolumeScale scale) case QAudio::CubicVolumeScale: dbg << "CubicVolumeScale"; break; + case QAudio::LogarithmicVolumeScale: + dbg << "LogarithmicVolumeScale"; + break; case QAudio::DecibelVolumeScale: dbg << "DecibelVolumeScale"; break; diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h index 9bbc6cf22..457a3b621 100644 --- a/src/multimedia/audio/qaudio.h +++ b/src/multimedia/audio/qaudio.h @@ -74,6 +74,7 @@ namespace QAudio enum VolumeScale { LinearVolumeScale, CubicVolumeScale, + LogarithmicVolumeScale, DecibelVolumeScale }; diff --git a/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp b/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp index 736d1b306..9646b708e 100644 --- a/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp +++ b/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp @@ -257,7 +257,7 @@ void applyVolume(int volumeSliderValue) // volumeSliderValue is in the range [0..100] qreal linearVolume = QAudio::convertVolume(volumeSliderValue / qreal(100.0), - QAudio::CubicVolumeScale, + QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale); player.setVolume(qRound(linearVolume * 100)); -- cgit v1.2.1