1 /*****************************************************************************
2 * volume.c : helper for software audio amplification
3 *****************************************************************************
4 * Copyright (C) 2012 Rémi Denis-Courmont
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <math.h>
26 #include <vlc_common.h>
27 #include <vlc_aout.h>
28
29 #define add_sw_gain() \
30 add_float(MODULE_STRING"-gain", 1., N_("Software gain"), \
31 N_("This linear gain will be applied in software."), true) \
32 change_float_range(0., 8.)
33
aout_SoftVolumeSet(audio_output_t * aout,float volume)34 static int aout_SoftVolumeSet(audio_output_t *aout, float volume)
35 {
36 aout_sys_t *sys = aout->sys;
37 /*
38 * Cubic mapping from software volume to amplification factor.
39 * This provides a good tradeoff between low and high volume ranges.
40 *
41 * This code is only used for the VLC software mixer. If you change this
42 * formula, be sure to update the volume-capable plugins also.
43 */
44 float gain = volume * volume * volume;
45
46 if (!sys->soft_mute && aout_GainRequest(aout, gain))
47 return -1;
48 sys->soft_gain = gain;
49 if (var_InheritBool(aout, "volume-save"))
50 config_PutFloat(aout, MODULE_STRING"-gain", gain);
51
52 aout_VolumeReport(aout, volume);
53 return 0;
54 }
55
aout_SoftMuteSet(audio_output_t * aout,bool mute)56 static int aout_SoftMuteSet (audio_output_t *aout, bool mute)
57 {
58 aout_sys_t *sys = aout->sys;
59
60 if (aout_GainRequest(aout, mute ? 0.f : sys->soft_gain))
61 return -1;
62 sys->soft_mute = mute;
63
64 aout_MuteReport(aout, mute);
65 return 0;
66 }
67
aout_SoftVolumeInit(audio_output_t * aout)68 static void aout_SoftVolumeInit(audio_output_t *aout)
69 {
70 aout_sys_t *sys = aout->sys;
71 float gain = var_InheritFloat(aout, MODULE_STRING"-gain");
72 bool mute = var_InheritBool(aout, "mute");
73
74 aout->volume_set = aout_SoftVolumeSet;
75 aout->mute_set = aout_SoftMuteSet;
76 sys->soft_gain = gain;
77 sys->soft_mute = mute;
78
79 aout_MuteReport(aout, mute);
80 aout_VolumeReport(aout, cbrtf(gain));
81 }
82
aout_SoftVolumeStart(audio_output_t * aout)83 static void aout_SoftVolumeStart (audio_output_t *aout)
84 {
85 aout_sys_t *sys = aout->sys;
86
87 if (aout_GainRequest(aout, sys->soft_mute ? 0.f : sys->soft_gain))
88 {
89 aout_MuteReport(aout, false);
90 aout_VolumeReport(aout, 1.f);
91 }
92 }
93