volume: guarantee dB/linear conversion is reversible

This commit is contained in:
Lennart Poettering 2009-08-14 20:03:30 +02:00
parent 72d2540e8d
commit 0f2a4ed422
2 changed files with 40 additions and 1 deletions

View file

@ -205,9 +205,12 @@ pa_volume_t pa_sw_volume_from_linear(double v) {
*
* http://www.robotplanet.dk/audio/audio_gui_design/
* http://lists.linuxaudio.org/pipermail/linux-audio-dev/2009-May/thread.html#23151
*
* We make sure that the conversion to linear and back yields the
* same volume value! That's why we need the lround() below!
*/
return (pa_volume_t) (cbrt(v) * PA_VOLUME_NORM);
return (pa_volume_t) lround(cbrt(v) * PA_VOLUME_NORM);
}
double pa_sw_volume_to_linear(pa_volume_t v) {

View file

@ -1,8 +1,33 @@
/***
This file is part of PulseAudio.
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <pulse/volume.h>
#include <pulse/gccmacro.h>
#include <pulsecore/macro.h>
int main(int argc, char *argv[]) {
pa_volume_t v;
pa_cvolume cv;
@ -60,5 +85,16 @@ int main(int argc, char *argv[]) {
printf("After: volume: [%s]; balance: %2.1f (intended: %2.1f) %s\n", pa_cvolume_snprint(s, sizeof(s), &r), k, b, k < b-.05 || k > b+.5 ? "MISMATCH" : "");
}
for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 1) {
double l = pa_sw_volume_to_linear(v);
pa_volume_t k = pa_sw_volume_from_linear(l);
double db = pa_sw_volume_to_dB(v);
pa_volume_t r = pa_sw_volume_from_dB(db);
pa_assert(k == v);
pa_assert(r == v);
}
return 0;
}