0
|
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
20 */
|
|
21
|
|
22 #include <stdio.h>
|
|
23 #include <stdlib.h>
|
|
24 #include <string.h>
|
|
25 #include <esd.h>
|
|
26
|
|
27 #include <unistd.h>
|
|
28 #include <fcntl.h>
|
|
29 #include <sys/types.h>
|
|
30 #include <sys/ioctl.h>
|
|
31 #include <sys/stat.h>
|
|
32
|
|
33 #include "esdout.h"
|
|
34
|
|
35 #ifdef HAVE_OSS
|
|
36 # include <Output/OSS/soundcard.h>
|
|
37 # define OSS_AVAILABLE TRUE
|
|
38 #else
|
|
39 # define OSS_AVAILABLE FALSE
|
|
40 #endif
|
|
41
|
|
42 #include <libaudacious/util.h>
|
|
43
|
|
44
|
|
45
|
|
46 static void esdout_get_oss_volume(int *l, int *r);
|
|
47 static void esdout_set_oss_volume(int l, int r);
|
|
48
|
|
49
|
|
50 static int player = -1;
|
|
51 static int lp = 100, rp = 100;
|
|
52
|
|
53 /*
|
|
54 * Find the stream id, and set stream volume to 'persistent' value.
|
|
55 */
|
|
56 void
|
|
57 esdout_mixer_init(void)
|
|
58 {
|
|
59 esdout_fetch_volume(NULL, NULL);
|
|
60 if (!(OSS_AVAILABLE && esd_cfg.use_oss_mixer && !esd_cfg.use_remote))
|
|
61 esdout_set_volume(lp, rp);
|
|
62 }
|
|
63
|
|
64 /*
|
|
65 * Grab the stream volume from the server. The problem here is that
|
|
66 * ESD does not have a built-in function for finding the player ID of
|
|
67 * a specific player - nor does it let us know what the player ID is
|
|
68 * when the player is created! So, we grab 'allinfo' and scan the
|
|
69 * returned player list for the string which we know is our player
|
|
70 * name (esd_cfg.playername) This function seems to take a long time
|
|
71 * to run... I'm not sure where to start optimizing, however...
|
|
72 */
|
|
73 void
|
|
74 esdout_fetch_volume(int *l, int *r)
|
|
75 {
|
|
76 int fd;
|
|
77 esd_info_t *all_info = NULL;
|
|
78 esd_player_info_t *info;
|
|
79
|
|
80 fd = esd_open_sound(esd_cfg.hostname);
|
|
81 all_info = esd_get_all_info(fd);
|
|
82
|
|
83 /* scan linked list for our playername */
|
|
84 for (info = all_info->player_list; info != NULL; info = info->next)
|
|
85 if (!strcmp(esd_cfg.playername, info->name))
|
|
86 break;
|
|
87
|
|
88 if (info) {
|
|
89 player = info->source_id;
|
|
90 if (l && r) {
|
|
91 /*
|
|
92 * Sometimes we call with NULL
|
|
93 * args to fetch the player num
|
|
94 */
|
|
95 *l = (info->left_vol_scale * 100) / 256;
|
|
96 *r = (info->right_vol_scale * 100) / 256;
|
|
97 }
|
|
98 }
|
|
99 else
|
|
100 g_warning("xmms: Couldn't find our player "
|
|
101 "(was looking for %s) at the server", esd_cfg.playername);
|
|
102
|
|
103 if (all_info)
|
|
104 esd_free_all_info(all_info);
|
|
105 esd_close(fd);
|
|
106 }
|
|
107
|
|
108 void
|
|
109 esdout_get_volume(int *l, int *r)
|
|
110 {
|
|
111 if (OSS_AVAILABLE && esd_cfg.use_oss_mixer && !esd_cfg.use_remote) {
|
|
112 esdout_get_oss_volume(l, r);
|
|
113 lp = *l;
|
|
114 rp = *r;
|
|
115 }
|
|
116 else {
|
|
117 /*
|
|
118 * We assume that the volume hasn't changed from the
|
|
119 * 'persistant' value. Constantly polling takes too
|
|
120 * much time/resources. Commenting this section out
|
|
121 * will consistently check the ESD server to see if
|
|
122 * someone else changed our stream volume.
|
|
123 */
|
|
124 *l = lp;
|
|
125 *r = rp;
|
|
126 /* esdout_fetch_volume(l, r); */
|
|
127 }
|
|
128 }
|
|
129
|
|
130 void
|
|
131 esdout_set_volume(int l, int r)
|
|
132 {
|
|
133 lp = l;
|
|
134 rp = r;
|
|
135
|
|
136 if (OSS_AVAILABLE && esd_cfg.use_oss_mixer && !esd_cfg.use_remote) {
|
|
137 esdout_set_oss_volume(l, r);
|
|
138 }
|
|
139 else if (player != -1 && esd_cfg.playername != NULL) {
|
|
140 int fd = esd_open_sound(esd_cfg.hostname);
|
|
141 if (fd >= 0) {
|
|
142 esd_set_stream_pan(fd, player, (l * 256) / 100, (r * 256) / 100);
|
|
143 esd_close(fd);
|
|
144 }
|
|
145 }
|
|
146 }
|
|
147
|
|
148 #ifdef HAVE_OSS
|
|
149
|
|
150 static void
|
|
151 esdout_get_oss_volume(int *l, int *r)
|
|
152 {
|
|
153 int fd, v, devs;
|
|
154 long cmd;
|
|
155
|
|
156 if (esd_cfg.use_remote)
|
|
157 return;
|
|
158
|
|
159 fd = open(DEV_MIXER, O_RDONLY);
|
|
160 if (fd != -1) {
|
|
161 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs);
|
|
162 if (devs & SOUND_MASK_PCM)
|
|
163 cmd = SOUND_MIXER_READ_PCM;
|
|
164 else if (devs & SOUND_MASK_VOLUME)
|
|
165 cmd = SOUND_MIXER_READ_VOLUME;
|
|
166 else {
|
|
167 close(fd);
|
|
168 return;
|
|
169 }
|
|
170 ioctl(fd, cmd, &v);
|
|
171 *r = (v & 0xFF00) >> 8;
|
|
172 *l = (v & 0x00FF);
|
|
173 close(fd);
|
|
174 }
|
|
175 }
|
|
176
|
|
177 static void
|
|
178 esdout_set_oss_volume(int l, int r)
|
|
179 {
|
|
180 int fd, v, devs;
|
|
181 long cmd;
|
|
182
|
|
183 if (esd_cfg.use_remote)
|
|
184 return;
|
|
185
|
|
186 fd = open(DEV_MIXER, O_RDONLY);
|
|
187
|
|
188 if (fd != -1) {
|
|
189 ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs);
|
|
190 if (devs & SOUND_MASK_PCM)
|
|
191 cmd = SOUND_MIXER_WRITE_PCM;
|
|
192 else if (devs & SOUND_MASK_VOLUME)
|
|
193 cmd = SOUND_MIXER_WRITE_VOLUME;
|
|
194 else {
|
|
195 close(fd);
|
|
196 return;
|
|
197 }
|
|
198 v = (r << 8) | l;
|
|
199 ioctl(fd, cmd, &v);
|
|
200 close(fd);
|
|
201 }
|
|
202 }
|
|
203
|
|
204 #else
|
|
205
|
|
206 static void
|
|
207 esdout_get_oss_volume(int *l, int *r)
|
|
208 {
|
|
209 }
|
|
210
|
|
211 static void
|
|
212 esdout_set_oss_volume(int l, int r)
|
|
213 {
|
|
214 }
|
|
215
|
|
216 #endif
|