2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <libavutil/common.h>
24 #include "libao2/audio_out.h"
30 static void checkvolume(struct mixer
*mixer
)
36 if (mixer
->softvol
|| CONTROL_OK
!= ao_control(mixer
->ao
,
37 AOCONTROL_GET_VOLUME
, &vol
)) {
38 mixer
->softvol
= true;
41 float db_vals
[AF_NCH
];
42 if (!af_control_any_rev(mixer
->afilter
,
43 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_GET
, db_vals
))
44 db_vals
[0] = db_vals
[1] = 1.0;
46 af_from_dB(2, db_vals
, db_vals
, 20.0, -200.0, 60.0);
47 vol
.left
= (db_vals
[0] / (mixer
->softvol_max
/ 100.0)) * 100.0;
48 vol
.right
= (db_vals
[1] / (mixer
->softvol_max
/ 100.0)) * 100.0;
50 float l
= mixer
->vol_l
;
51 float r
= mixer
->vol_r
;
52 if (mixer
->muted_using_volume
)
54 /* Try to detect cases where the volume has been changed by some external
55 * action (such as something else changing a shared system-wide volume).
56 * We don't test for exact equality, as some AOs may round the value
57 * we last set to some nearby supported value. 3 has been the default
58 * volume step for increase/decrease keys, and is apparently big enough
59 * to step to the next possible value in most setups.
61 if (FFABS(vol
.left
- l
) >= 3 || FFABS(vol
.right
- r
) >= 3) {
62 mixer
->vol_l
= vol
.left
;
63 mixer
->vol_r
= vol
.right
;
64 if (mixer
->muted_using_volume
)
68 // Rely on the value not changing if the query is not supported
69 ao_control(mixer
->ao
, AOCONTROL_GET_MUTE
, &mixer
->muted
);
70 mixer
->muted_by_us
&= mixer
->muted
;
71 mixer
->muted_using_volume
&= mixer
->muted
;
74 void mixer_getvolume(mixer_t
*mixer
, float *l
, float *r
)
81 static void setvolume_internal(mixer_t
*mixer
, float l
, float r
)
83 struct ao_control_vol vol
= {.left
= l
, .right
= r
};
84 if (!mixer
->softvol
) {
85 // relies on the driver data being permanent (so ptr stays valid)
86 mixer
->restore_volume
= mixer
->ao
->no_persistent_volume
?
87 mixer
->ao
->driver
->info
->short_name
: NULL
;
88 if (ao_control(mixer
->ao
, AOCONTROL_SET_VOLUME
, &vol
) != CONTROL_OK
)
89 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
,
90 "[Mixer] Failed to change audio output volume.\n");
93 mixer
->restore_volume
= "softvol";
96 // af_volume uses values in dB
97 float db_vals
[AF_NCH
];
99 db_vals
[0] = (l
/ 100.0) * (mixer
->softvol_max
/ 100.0);
100 db_vals
[1] = (r
/ 100.0) * (mixer
->softvol_max
/ 100.0);
101 for (i
= 2; i
< AF_NCH
; i
++)
102 db_vals
[i
] = ((l
+ r
) / 100.0) * (mixer
->softvol_max
/ 100.0) / 2.0;
103 af_to_dB(AF_NCH
, db_vals
, db_vals
, 20.0);
104 if (!af_control_any_rev(mixer
->afilter
,
105 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_SET
,
107 mp_tmsg(MSGT_GLOBAL
, MSGL_INFO
,
108 "[Mixer] No hardware mixing, inserting volume filter.\n");
109 if (!(af_add(mixer
->afilter
, "volume")
110 && af_control_any_rev(mixer
->afilter
,
111 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_SET
,
113 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
,
114 "[Mixer] No volume control available.\n");
118 void mixer_setvolume(mixer_t
*mixer
, float l
, float r
)
120 checkvolume(mixer
); // to check mute status and AO support for volume
121 mixer
->vol_l
= av_clip(l
, 0, 100);
122 mixer
->vol_r
= av_clip(r
, 0, 100);
123 if (!mixer
->ao
|| mixer
->muted
)
125 setvolume_internal(mixer
, mixer
->vol_l
, mixer
->vol_r
);
128 void mixer_getbothvolume(mixer_t
*mixer
, float *b
)
130 float mixer_l
, mixer_r
;
131 mixer_getvolume(mixer
, &mixer_l
, &mixer_r
);
132 *b
= (mixer_l
+ mixer_r
) / 2;
135 void mixer_setmute(struct mixer
*mixer
, bool mute
)
138 if (mute
!= mixer
->muted
) {
139 if (!mixer
->softvol
&& !mixer
->muted_using_volume
&& ao_control(
140 mixer
->ao
, AOCONTROL_SET_MUTE
, &mute
) == CONTROL_OK
) {
141 mixer
->muted_using_volume
= false;
143 setvolume_internal(mixer
, mixer
->vol_l
*!mute
, mixer
->vol_r
*!mute
);
144 mixer
->muted_using_volume
= mute
;
147 mixer
->muted_by_us
= mute
;
151 bool mixer_getmute(struct mixer
*mixer
)
157 static void addvolume(struct mixer
*mixer
, float d
)
160 mixer_setvolume(mixer
, mixer
->vol_l
+ d
, mixer
->vol_r
+ d
);
162 mixer_setmute(mixer
, false);
165 void mixer_incvolume(mixer_t
*mixer
)
167 addvolume(mixer
, mixer
->volstep
);
170 void mixer_decvolume(mixer_t
*mixer
)
172 addvolume(mixer
, -mixer
->volstep
);
175 void mixer_getbalance(mixer_t
*mixer
, float *val
)
178 af_control_any_rev(mixer
->afilter
,
179 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_GET
,
181 *val
= mixer
->balance
;
184 /* NOTE: Currently the balance code is seriously buggy: it always changes
185 * the af_pan mapping between the first two input channels and first two
186 * output channels to particular values. These values make sense for an
187 * af_pan instance that was automatically inserted for balance control
188 * only and is otherwise an identity transform, but if the filter was
189 * there for another reason, then ignoring and overriding the original
190 * values is completely wrong. In particular, this will break
191 * automatically inserted downmix filters; the original coefficients that
192 * are significantly below 1 will be overwritten with much higher values.
195 void mixer_setbalance(mixer_t
*mixer
, float val
)
199 af_control_ext_t arg_ext
= { .arg
= level
};
200 af_instance_t
*af_pan_balance
;
202 mixer
->balance
= val
;
207 if (af_control_any_rev(mixer
->afilter
,
208 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
, &val
))
211 if (val
== 0 || mixer
->ao
->channels
< 2)
214 if (!(af_pan_balance
= af_add(mixer
->afilter
, "pan"))) {
215 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
,
216 "[Mixer] No balance control available.\n");
220 af_init(mixer
->afilter
);
221 /* make all other channels pass thru since by default pan blocks all */
222 memset(level
, 0, sizeof(level
));
223 for (i
= 2; i
< AF_NCH
; i
++) {
226 af_pan_balance
->control(af_pan_balance
,
227 AF_CONTROL_PAN_LEVEL
| AF_CONTROL_SET
,
232 af_pan_balance
->control(af_pan_balance
,
233 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
, &val
);
236 // Called after the audio filter chain is built or rebuilt.
237 void mixer_reinit(struct mixer
*mixer
, struct ao
*ao
)
240 /* Use checkvolume() to see if softvol needs to be enabled because of
241 * lacking AO support, but first store values it could overwrite. */
242 float left
= mixer
->vol_l
, right
= mixer
->vol_r
;
243 bool muted
= mixer
->muted_by_us
;
245 /* Try to avoid restoring volume stored from one control method with
246 * another. Especially, restoring softvol volume (typically high) on
247 * system mixer could have very nasty effects. */
248 const char *restore_reason
= mixer
->softvol
? "softvol" :
249 mixer
->ao
->driver
->info
->short_name
;
250 if (mixer
->restore_volume
&& !strcmp(mixer
->restore_volume
,
252 mixer_setvolume(mixer
, left
, right
);
253 /* We turn mute off at AO uninit, so it has to be restored (unless
254 * we're reinitializing filter chain while keeping AO); but we only
255 * enable mute, not turn external mute off. */
257 mixer_setmute(mixer
, true);
258 if (mixer
->balance
!= 0)
259 mixer_setbalance(mixer
, mixer
->balance
);
262 /* Called before uninitializing the audio output. The main purpose is to
263 * turn off mute, in case it's a global/persistent setting which might
264 * otherwise be left enabled even after this player instance exits.
266 void mixer_uninit(struct mixer
*mixer
)
269 if (mixer
->muted_by_us
) {
270 /* Current audio output API combines playing the remaining buffered
271 * audio and uninitializing the AO into one operation, even though
272 * ideally unmute would happen between those two steps. We can't do
273 * volume changes after uninitialization, but we don't want the
274 * remaining audio to play at full volume either. Thus this
275 * workaround to drop remaining audio first. */
277 mixer_setmute(mixer
, false);
278 /* We remember mute status and re-enable it if we play more audio
279 * in the same process. */
280 mixer
->muted_by_us
= true;