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
)) {
40 float db_vals
[AF_NCH
];
41 if (!af_control_any_rev(mixer
->afilter
,
42 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_GET
, db_vals
))
43 db_vals
[0] = db_vals
[1] = 1.0;
45 af_from_dB(2, db_vals
, db_vals
, 20.0, -200.0, 60.0);
46 vol
.left
= (db_vals
[0] / (mixer
->softvol_max
/ 100.0)) * 100.0;
47 vol
.right
= (db_vals
[1] / (mixer
->softvol_max
/ 100.0)) * 100.0;
49 float l
= mixer
->vol_l
;
50 float r
= mixer
->vol_r
;
53 /* Try to detect cases where the volume has been changed by some external
54 * action (such as something else changing a shared system-wide volume).
55 * We don't test for exact equality, as some AOs may round the value
56 * we last set to some nearby supported value. 3 has been the default
57 * volume step for increase/decrease keys, and is apparently big enough
58 * to step to the next possible value in most setups.
60 if (FFABS(vol
.left
- l
) >= 3 || FFABS(vol
.right
- r
) >= 3) {
61 mixer
->vol_l
= vol
.left
;
62 mixer
->vol_r
= vol
.right
;
67 void mixer_getvolume(mixer_t
*mixer
, float *l
, float *r
)
74 static void setvolume_internal(mixer_t
*mixer
, float l
, float r
)
76 struct ao_control_vol vol
= {.left
= l
, .right
= r
};
77 if (mixer
->softvol
|| CONTROL_OK
!= ao_control(mixer
->ao
,
78 AOCONTROL_SET_VOLUME
, &vol
)) {
79 // af_volume uses values in dB
80 float db_vals
[AF_NCH
];
82 db_vals
[0] = (l
/ 100.0) * (mixer
->softvol_max
/ 100.0);
83 db_vals
[1] = (r
/ 100.0) * (mixer
->softvol_max
/ 100.0);
84 for (i
= 2; i
< AF_NCH
; i
++)
85 db_vals
[i
] = ((l
+ r
) / 100.0) * (mixer
->softvol_max
/ 100.0) / 2.0;
86 af_to_dB(AF_NCH
, db_vals
, db_vals
, 20.0);
87 if (!af_control_any_rev(mixer
->afilter
,
88 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_SET
, db_vals
)) {
89 mp_tmsg(MSGT_GLOBAL
, MSGL_INFO
,
90 "[Mixer] No hardware mixing, inserting volume filter.\n");
91 if (af_add(mixer
->afilter
, "volume")) {
92 if (!af_control_any_rev(mixer
->afilter
,
93 AF_CONTROL_VOLUME_LEVEL
|AF_CONTROL_SET
, db_vals
)) {
94 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
,
95 "[Mixer] No volume control available.\n");
103 void mixer_setvolume(mixer_t
*mixer
, float l
, float r
)
105 checkvolume(mixer
); // to check mute status
106 mixer
->vol_l
= av_clip(l
, 0, 100);
107 mixer
->vol_r
= av_clip(r
, 0, 100);
108 if (!mixer
->ao
|| mixer
->muted
)
110 setvolume_internal(mixer
, mixer
->vol_l
, mixer
->vol_r
);
113 void mixer_getbothvolume(mixer_t
*mixer
, float *b
)
115 float mixer_l
, mixer_r
;
116 mixer_getvolume(mixer
, &mixer_l
, &mixer_r
);
117 *b
= (mixer_l
+ mixer_r
) / 2;
120 void mixer_setmute(struct mixer
*mixer
, bool mute
)
123 if (mute
!= mixer
->muted
) {
125 setvolume_internal(mixer
, mixer
->vol_l
* !mute
, mixer
->vol_r
* !mute
);
129 bool mixer_getmute(struct mixer
*mixer
)
135 static void addvolume(struct mixer
*mixer
, float d
)
138 mixer_setvolume(mixer
, mixer
->vol_l
+ d
, mixer
->vol_r
+ d
);
140 mixer_setmute(mixer
, false);
143 void mixer_incvolume(mixer_t
*mixer
)
145 addvolume(mixer
, mixer
->volstep
);
148 void mixer_decvolume(mixer_t
*mixer
)
150 addvolume(mixer
, -mixer
->volstep
);
153 void mixer_getbalance(mixer_t
*mixer
, float *val
)
158 af_control_any_rev(mixer
->afilter
, AF_CONTROL_PAN_BALANCE
| AF_CONTROL_GET
,
162 void mixer_setbalance(mixer_t
*mixer
, float val
)
166 af_control_ext_t arg_ext
= { .arg
= level
};
167 af_instance_t
*af_pan_balance
;
172 if (af_control_any_rev(mixer
->afilter
,
173 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
, &val
))
176 if (!(af_pan_balance
= af_add(mixer
->afilter
, "pan"))) {
177 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
,
178 "[Mixer] No balance control available.\n");
182 af_init(mixer
->afilter
);
183 /* make all other channels pass thru since by default pan blocks all */
184 memset(level
, 0, sizeof(level
));
185 for (i
= 2; i
< AF_NCH
; i
++) {
188 af_pan_balance
->control(af_pan_balance
,
189 AF_CONTROL_PAN_LEVEL
| AF_CONTROL_SET
,
194 af_pan_balance
->control(af_pan_balance
,
195 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
, &val
);