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 <sys/ioctl.h>
28 #include "libao2/audio_out.h"
33 char * mixer_device
=NULL
;
34 char * mixer_channel
=NULL
;
36 float soft_vol_max
= 110.0;
38 void mixer_getvolume(mixer_t
*mixer
, float *l
, float *r
)
44 CONTROL_OK
!= mixer
->audio_out
->control(AOCONTROL_GET_VOLUME
,&vol
)) {
48 float db_vals
[AF_NCH
];
49 if (!af_control_any_rev(mixer
->afilter
,
50 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_GET
, db_vals
))
51 db_vals
[0] = db_vals
[1] = 1.0;
53 af_from_dB (2, db_vals
, db_vals
, 20.0, -200.0, 60.0);
54 vol
.left
= (db_vals
[0] / (soft_vol_max
/ 100.0)) * 100.0;
55 vol
.right
= (db_vals
[1] / (soft_vol_max
/ 100.0)) * 100.0;
63 void mixer_setvolume(mixer_t
*mixer
, float l
, float r
)
66 vol
.right
=r
; vol
.left
=l
;
69 CONTROL_OK
!= mixer
->audio_out
->control(AOCONTROL_SET_VOLUME
,&vol
)) {
73 // af_volume uses values in dB
74 float db_vals
[AF_NCH
];
76 db_vals
[0] = (l
/ 100.0) * (soft_vol_max
/ 100.0);
77 db_vals
[1] = (r
/ 100.0) * (soft_vol_max
/ 100.0);
78 for (i
= 2; i
< AF_NCH
; i
++) {
79 db_vals
[i
] = ((l
+ r
) / 100.0) * (soft_vol_max
/ 100.0) / 2.0;
81 af_to_dB (AF_NCH
, db_vals
, db_vals
, 20.0);
82 if (!af_control_any_rev(mixer
->afilter
,
83 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_SET
, db_vals
)) {
84 mp_tmsg(MSGT_GLOBAL
, MSGL_INFO
, "[Mixer] No hardware mixing, inserting volume filter.\n");
85 if (af_add(mixer
->afilter
, "volume")) {
86 if (!af_control_any_rev(mixer
->afilter
,
87 AF_CONTROL_VOLUME_LEVEL
| AF_CONTROL_SET
, db_vals
)) {
88 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
, "[Mixer] No volume control available.\n");
99 void mixer_incvolume(mixer_t
*mixer
)
101 float mixer_l
, mixer_r
;
102 mixer_getvolume(mixer
, &mixer_l
, &mixer_r
);
103 mixer_l
+= mixer
->volstep
;
104 if ( mixer_l
> 100 ) mixer_l
= 100;
105 mixer_r
+= mixer
->volstep
;
106 if ( mixer_r
> 100 ) mixer_r
= 100;
107 mixer_setvolume(mixer
, mixer_l
, mixer_r
);
110 void mixer_decvolume(mixer_t
*mixer
)
112 float mixer_l
, mixer_r
;
113 mixer_getvolume(mixer
, &mixer_l
, &mixer_r
);
114 mixer_l
-= mixer
->volstep
;
115 if ( mixer_l
< 0 ) mixer_l
= 0;
116 mixer_r
-= mixer
->volstep
;
117 if ( mixer_r
< 0 ) mixer_r
= 0;
118 mixer_setvolume(mixer
, mixer_l
, mixer_r
);
121 void mixer_getbothvolume(mixer_t
*mixer
, float *b
)
123 float mixer_l
, mixer_r
;
124 mixer_getvolume(mixer
, &mixer_l
, &mixer_r
);
125 *b
= ( mixer_l
+ mixer_r
) / 2;
128 void mixer_mute(mixer_t
*mixer
)
130 if (mixer
->muted
) mixer_setvolume(mixer
, mixer
->last_l
, mixer
->last_r
);
133 mixer_getvolume(mixer
, &mixer
->last_l
, &mixer
->last_r
);
134 mixer_setvolume(mixer
, 0, 0);
139 void mixer_getbalance(mixer_t
*mixer
, float *val
)
144 af_control_any_rev(mixer
->afilter
,
145 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_GET
, val
);
148 void mixer_setbalance(mixer_t
*mixer
, float val
)
152 af_control_ext_t arg_ext
= { .arg
= level
};
153 af_instance_t
* af_pan_balance
;
157 if (af_control_any_rev(mixer
->afilter
,
158 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
, &val
))
161 if (!(af_pan_balance
= af_add(mixer
->afilter
, "pan"))) {
162 mp_tmsg(MSGT_GLOBAL
, MSGL_ERR
, "[Mixer] No balance control available.\n");
166 af_init(mixer
->afilter
);
167 /* make all other channels pass thru since by default pan blocks all */
168 memset(level
, 0, sizeof(level
));
169 for (i
= 2; i
< AF_NCH
; i
++) {
172 af_pan_balance
->control(af_pan_balance
,
173 AF_CONTROL_PAN_LEVEL
| AF_CONTROL_SET
, &arg_ext
);
177 af_pan_balance
->control(af_pan_balance
,
178 AF_CONTROL_PAN_BALANCE
| AF_CONTROL_SET
, &val
);