print a more detailed and more useful description of each stream with lavf
[mplayer.git] / mixer.c
blobe58c8a6713106441d629e70f5c0735397b6d65e6
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"
32 #include "help_mp.h"
34 char * mixer_device=NULL;
35 char * mixer_channel=NULL;
36 int soft_vol = 0;
37 float soft_vol_max = 110.0;
39 void mixer_getvolume(mixer_t *mixer, float *l, float *r)
41 ao_control_vol_t vol;
42 *l=0; *r=0;
43 if(mixer->audio_out){
44 if(soft_vol ||
45 CONTROL_OK != mixer->audio_out->control(AOCONTROL_GET_VOLUME,&vol)) {
46 if (!mixer->afilter)
47 return;
48 else {
49 float db_vals[AF_NCH];
50 if (!af_control_any_rev(mixer->afilter,
51 AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, db_vals))
52 db_vals[0] = db_vals[1] = 1.0;
53 else
54 af_from_dB (2, db_vals, db_vals, 20.0, -200.0, 60.0);
55 vol.left = (db_vals[0] / (soft_vol_max / 100.0)) * 100.0;
56 vol.right = (db_vals[1] / (soft_vol_max / 100.0)) * 100.0;
59 *r=vol.right;
60 *l=vol.left;
64 void mixer_setvolume(mixer_t *mixer, float l, float r)
66 ao_control_vol_t vol;
67 vol.right=r; vol.left=l;
68 if(mixer->audio_out){
69 if(soft_vol ||
70 CONTROL_OK != mixer->audio_out->control(AOCONTROL_SET_VOLUME,&vol)) {
71 if (!mixer->afilter)
72 return;
73 else {
74 // af_volume uses values in dB
75 float db_vals[AF_NCH];
76 int i;
77 db_vals[0] = (l / 100.0) * (soft_vol_max / 100.0);
78 db_vals[1] = (r / 100.0) * (soft_vol_max / 100.0);
79 for (i = 2; i < AF_NCH; i++) {
80 db_vals[i] = ((l + r) / 100.0) * (soft_vol_max / 100.0) / 2.0;
82 af_to_dB (AF_NCH, db_vals, db_vals, 20.0);
83 if (!af_control_any_rev(mixer->afilter,
84 AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, db_vals)) {
85 mp_msg(MSGT_GLOBAL, MSGL_INFO, MSGTR_InsertingAfVolume);
86 if (af_add(mixer->afilter, "volume")) {
87 if (!af_control_any_rev(mixer->afilter,
88 AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, db_vals)) {
89 mp_msg(MSGT_GLOBAL, MSGL_ERR, MSGTR_NoVolume);
90 return;
97 mixer->muted=0;
100 void mixer_incvolume(mixer_t *mixer)
102 float mixer_l, mixer_r;
103 mixer_getvolume(mixer, &mixer_l, &mixer_r);
104 mixer_l += mixer->volstep;
105 if ( mixer_l > 100 ) mixer_l = 100;
106 mixer_r += mixer->volstep;
107 if ( mixer_r > 100 ) mixer_r = 100;
108 mixer_setvolume(mixer, mixer_l, mixer_r);
111 void mixer_decvolume(mixer_t *mixer)
113 float mixer_l, mixer_r;
114 mixer_getvolume(mixer, &mixer_l, &mixer_r);
115 mixer_l -= mixer->volstep;
116 if ( mixer_l < 0 ) mixer_l = 0;
117 mixer_r -= mixer->volstep;
118 if ( mixer_r < 0 ) mixer_r = 0;
119 mixer_setvolume(mixer, mixer_l, mixer_r);
122 void mixer_getbothvolume(mixer_t *mixer, float *b)
124 float mixer_l, mixer_r;
125 mixer_getvolume(mixer, &mixer_l, &mixer_r);
126 *b = ( mixer_l + mixer_r ) / 2;
129 void mixer_mute(mixer_t *mixer)
131 if (mixer->muted) mixer_setvolume(mixer, mixer->last_l, mixer->last_r);
132 else
134 mixer_getvolume(mixer, &mixer->last_l, &mixer->last_r);
135 mixer_setvolume(mixer, 0, 0);
136 mixer->muted=1;
140 void mixer_getbalance(mixer_t *mixer, float *val)
142 *val = 0.f;
143 if(!mixer->afilter)
144 return;
145 af_control_any_rev(mixer->afilter,
146 AF_CONTROL_PAN_BALANCE | AF_CONTROL_GET, val);
149 void mixer_setbalance(mixer_t *mixer, float val)
151 float level[AF_NCH];
152 int i;
153 af_control_ext_t arg_ext = { .arg = level };
154 af_instance_t* af_pan_balance;
156 if(!mixer->afilter)
157 return;
158 if (af_control_any_rev(mixer->afilter,
159 AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val))
160 return;
162 if (!(af_pan_balance = af_add(mixer->afilter, "pan"))) {
163 mp_msg(MSGT_GLOBAL, MSGL_ERR, MSGTR_NoBalance);
164 return;
167 af_init(mixer->afilter);
168 /* make all other channels pass thru since by default pan blocks all */
169 memset(level, 0, sizeof(level));
170 for (i = 2; i < AF_NCH; i++) {
171 arg_ext.ch = i;
172 level[i] = 1.f;
173 af_pan_balance->control(af_pan_balance,
174 AF_CONTROL_PAN_LEVEL | AF_CONTROL_SET, &arg_ext);
175 level[i] = 0.f;
178 af_pan_balance->control(af_pan_balance,
179 AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val);