aspect.c: use fallback if screen dimensions are not known
[mplayer/glamo.git] / mixer.c
blob4b9d8db1b7b9824636531dfb38d6959a64fa336c
1 /*
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.
19 #include <string.h>
20 #ifndef __MINGW32__
21 #include <sys/ioctl.h>
22 #endif
23 #include <fcntl.h>
24 #include <stdio.h>
25 #include <unistd.h>
27 #include "config.h"
28 #include "libao2/audio_out.h"
29 #include "libaf/af.h"
30 #include "mixer.h"
33 char * mixer_device=NULL;
34 char * mixer_channel=NULL;
35 int soft_vol = 0;
36 float soft_vol_max = 110.0;
38 void mixer_getvolume(mixer_t *mixer, float *l, float *r)
40 ao_control_vol_t vol;
41 *l=0; *r=0;
42 if(mixer->audio_out){
43 if(soft_vol ||
44 CONTROL_OK != mixer->audio_out->control(AOCONTROL_GET_VOLUME,&vol)) {
45 if (!mixer->afilter)
46 return;
47 else {
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;
52 else
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;
58 *r=vol.right;
59 *l=vol.left;
63 void mixer_setvolume(mixer_t *mixer, float l, float r)
65 ao_control_vol_t vol;
66 vol.right=r; vol.left=l;
67 if(mixer->audio_out){
68 if(soft_vol ||
69 CONTROL_OK != mixer->audio_out->control(AOCONTROL_SET_VOLUME,&vol)) {
70 if (!mixer->afilter)
71 return;
72 else {
73 // af_volume uses values in dB
74 float db_vals[AF_NCH];
75 int i;
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");
89 return;
96 mixer->muted=0;
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);
131 else
133 mixer_getvolume(mixer, &mixer->last_l, &mixer->last_r);
134 mixer_setvolume(mixer, 0, 0);
135 mixer->muted=1;
139 void mixer_getbalance(mixer_t *mixer, float *val)
141 *val = 0.f;
142 if(!mixer->afilter)
143 return;
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)
150 float level[AF_NCH];
151 int i;
152 af_control_ext_t arg_ext = { .arg = level };
153 af_instance_t* af_pan_balance;
155 if(!mixer->afilter)
156 return;
157 if (af_control_any_rev(mixer->afilter,
158 AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val))
159 return;
161 if (!(af_pan_balance = af_add(mixer->afilter, "pan"))) {
162 mp_tmsg(MSGT_GLOBAL, MSGL_ERR, "[Mixer] No balance control available.\n");
163 return;
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++) {
170 arg_ext.ch = i;
171 level[i] = 1.f;
172 af_pan_balance->control(af_pan_balance,
173 AF_CONTROL_PAN_LEVEL | AF_CONTROL_SET, &arg_ext);
174 level[i] = 0.f;
177 af_pan_balance->control(af_pan_balance,
178 AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val);