comparison src/esd/mixer.c @ 12:3da1b8942b8b trunk

[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author nenolod
date Mon, 18 Sep 2006 03:14:20 -0700
parents src/Output/esd/mixer.c@0ad4849f6219
children b8da6a0b0da2
comparison
equal deleted inserted replaced
11:cff1d04026ae 12:3da1b8942b8b
1 /* BMP - Cross-platform multimedia player
2 * Copyright (C) 2003-2004 BMP development team.
3 *
4 * Based on XMMS:
5 * Copyright (C) 1998-2003 XMMS development team.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <esd.h>
26
27 #include <audacious/configdb.h>
28
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <sys/types.h>
32 #include <sys/ioctl.h>
33 #include <sys/stat.h>
34
35 #include "esdout.h"
36
37 #ifdef HAVE_OSS
38 # ifdef HAVE_SYS_SOUNDCARD_H
39 # include <sys/soundcard.h>
40 # else
41 # include <soundcard.h>
42 # endif
43 # define OSS_AVAILABLE TRUE
44 #else
45 # define OSS_AVAILABLE FALSE
46 #endif
47
48 #include <audacious/util.h>
49
50 #define QUERY_PLAYER_ID_ATTEMPTS 5
51
52 static void esdout_get_oss_volume(int *l, int *r);
53 static void esdout_set_oss_volume(int l, int r);
54
55
56 static int player = -1;
57 static int lp = 100, rp = 100;
58
59 /*
60 * Find the stream id, and set stream volume to 'persistent' value.
61 */
62 void
63 esdout_mixer_init(void)
64 {
65 int i;
66
67 /* reset player id */
68 player = -1;
69
70 /* query n-time for player id */
71 for(i=0; (i<QUERY_PLAYER_ID_ATTEMPTS) && (player == (-1)) ; i++)
72 esdout_fetch_volume(NULL, NULL);
73
74 if (!(OSS_AVAILABLE && esd_cfg.use_oss_mixer && !esd_cfg.use_remote))
75 esdout_set_volume(lp, rp);
76 }
77
78 /*
79 * Grab the stream volume from the server. The problem here is that
80 * ESD does not have a built-in function for finding the player ID of
81 * a specific player - nor does it let us know what the player ID is
82 * when the player is created! So, we grab 'allinfo' and scan the
83 * returned player list for the string which we know is our player
84 * name (esd_cfg.playername) This function seems to take a long time
85 * to run... I'm not sure where to start optimizing, however...
86 */
87 void
88 esdout_fetch_volume(int *l, int *r)
89 {
90 int fd;
91 esd_info_t *all_info = NULL;
92 esd_player_info_t *info;
93
94 fd = esd_open_sound(esd_cfg.hostname);
95 all_info = esd_get_all_info(fd);
96
97 /* scan linked list for our playername */
98 for (info = all_info->player_list; info != NULL; info = info->next)
99 if (!strcmp(esd_cfg.playername, info->name))
100 break;
101
102 if (info) {
103 player = info->source_id;
104 if (l && r) {
105 /*
106 * Sometimes we call with NULL
107 * args to fetch the player num
108 */
109 *l = (info->left_vol_scale * 100) / 256;
110 *r = (info->right_vol_scale * 100) / 256;
111 }
112 }
113 else
114 g_warning("xmms: Couldn't find our player "
115 "(was looking for %s) at the server", esd_cfg.playername);
116
117 if (all_info)
118 esd_free_all_info(all_info);
119 esd_close(fd);
120 }
121
122 void
123 esdout_get_volume(int *l, int *r)
124 {
125 if (OSS_AVAILABLE && esd_cfg.use_oss_mixer && !esd_cfg.use_remote) {
126 esdout_get_oss_volume(l, r);
127 lp = *l;
128 rp = *r;
129 }
130 else {
131 /*
132 * We assume that the volume hasn't changed from the
133 * 'persistant' value. Constantly polling takes too
134 * much time/resources. Commenting this section out
135 * will consistently check the ESD server to see if
136 * someone else changed our stream volume.
137 */
138 *l = lp;
139 *r = rp;
140 /* esdout_fetch_volume(l, r); */
141 }
142 }
143
144 void
145 esdout_set_volume(int l, int r)
146 {
147 ConfigDb *db;
148 lp = l;
149 rp = r;
150
151 if (OSS_AVAILABLE && esd_cfg.use_oss_mixer && !esd_cfg.use_remote) {
152 esdout_set_oss_volume(l, r);
153 }
154 else if (player != -1 && esd_cfg.playername != NULL) {
155 int fd = esd_open_sound(esd_cfg.hostname);
156 if (fd >= 0) {
157 esd_set_stream_pan(fd, player, (l * 256) / 100, (r * 256) / 100);
158 esd_close(fd);
159 }
160 }
161
162 /* save volume values in db */
163 db = bmp_cfg_db_open();
164 bmp_cfg_db_set_int(db, "ESD", "volume_left", lp);
165 bmp_cfg_db_set_int(db, "ESD", "volume_right", rp);
166 bmp_cfg_db_close(db);
167 }
168
169 #ifdef HAVE_OSS
170
171 static void
172 esdout_get_oss_volume(int *l, int *r)
173 {
174 int fd, v, devs;
175 long cmd;
176
177 if (esd_cfg.use_remote)
178 return;
179
180 fd = open(DEV_MIXER, O_RDONLY);
181 if (fd != -1) {
182 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs);
183 if (devs & SOUND_MASK_PCM)
184 cmd = SOUND_MIXER_READ_PCM;
185 else if (devs & SOUND_MASK_VOLUME)
186 cmd = SOUND_MIXER_READ_VOLUME;
187 else {
188 close(fd);
189 return;
190 }
191 ioctl(fd, cmd, &v);
192 *r = (v & 0xFF00) >> 8;
193 *l = (v & 0x00FF);
194 close(fd);
195 }
196 }
197
198 static void
199 esdout_set_oss_volume(int l, int r)
200 {
201 int fd, v, devs;
202 long cmd;
203
204 if (esd_cfg.use_remote)
205 return;
206
207 fd = open(DEV_MIXER, O_RDONLY);
208
209 if (fd != -1) {
210 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs);
211 if (devs & SOUND_MASK_PCM)
212 cmd = SOUND_MIXER_WRITE_PCM;
213 else if (devs & SOUND_MASK_VOLUME)
214 cmd = SOUND_MIXER_WRITE_VOLUME;
215 else {
216 close(fd);
217 return;
218 }
219 v = (r << 8) | l;
220 ioctl(fd, cmd, &v);
221 close(fd);
222 }
223 }
224
225 #else
226
227 static void
228 esdout_get_oss_volume(int *l, int *r)
229 {
230 }
231
232 static void
233 esdout_set_oss_volume(int l, int r)
234 {
235 }
236
237 #endif