source: roaraudio/libroaresd/esdctl.c @ 3517:1a3218a3fc5b

Last change on this file since 3517:1a3218a3fc5b was 3517:1a3218a3fc5b, checked in by phi, 14 years ago

updated license headers, FSF moved office

File size: 9.4 KB
Line 
1//esdctl.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *  The code (may) include prototypes and comments (and maybe
6 *  other code fragements) from EsounD.
7 *  They are mostly copyrighted by Eric B. Mitchell (aka 'Ricdude)
8 *  <ericmit@ix.netcom.com>. For more information see AUTHORS.esd.
9 *
10 *  This file is part of libroaresd a part of RoarAudio,
11 *  a cross-platform sound system for both, home and professional use.
12 *  See README for details.
13 *
14 *  This file is free software; you can redistribute it and/or modify
15 *  it under the terms of the GNU General Public License version 3
16 *  as published by the Free Software Foundation.
17 *
18 *  RoarAudio is distributed in the hope that it will be useful,
19 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *  GNU General Public License for more details.
22 *
23 *  You should have received a copy of the GNU General Public License
24 *  along with this software; see the file COPYING.  If not, write to
25 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
26 *  Boston, MA 02110-1301, USA.
27 *
28 *  NOTE for everyone want's to change something and send patches:
29 *  read README and HACKING! There a addition information on
30 *  the license of this document you need to read before you send
31 *  any patches.
32 *
33 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
34 *  or libpulse*:
35 *  The libs libroaresd, libroararts and libroarpulse link this libroar
36 *  and are therefore GPL. Because of this it may be illigal to use
37 *  them with any software that uses libesd, libartsc or libpulse*.
38 */
39
40#include "libroaresd.h"
41
42/* lock/unlock will disable/enable foreign clients from connecting */
43
44// we do not have such a thing at the moment...
45// so always return -1
46int esd_lock( int esd ) {
47 return -1;
48}
49int esd_unlock( int esd ) {
50 return -1;
51}
52
53/* standby/resume will free/reclaim audio device so others may use it */
54int esd_standby( int esd ) {
55 struct roar_connection con;
56
57 roar_connect_fh(&con, esd);
58
59 return roar_set_standby(&con, ROAR_STANDBY_ACTIVE);
60}
61
62int esd_resume( int esd ) {
63 struct roar_connection con;
64
65 roar_connect_fh(&con, esd);
66
67 return roar_set_standby(&con, ROAR_STANDBY_INACTIVE);
68}
69
70/* print server into to stdout */
71void esd_print_server_info( esd_server_info_t *server_info ) {
72 char buf[80] = "";
73
74 if ( server_info->format & ESD_BITS16 )
75  strcat(buf, "16 bit ");
76 else
77  strcat(buf, "8 bit ");
78
79 if ( server_info->format & ESD_STEREO )
80  strcat(buf, "stereo ");
81 else
82  strcat(buf, "mono ");
83
84 printf("server version   = %i\n",        server_info->version);
85 printf("server format    = 0x%08x %s\n", server_info->format, buf);
86 printf("server rate      = %i\n",        server_info->rate);
87}
88
89
90void esd_print_player_info( esd_player_info_t *player_info ) {
91 char buf[80] = "";
92
93 if ( (player_info->format & ESD_BITS16) == ESD_BITS16 )
94  strcat(buf, "16 bit ");
95 else
96  strcat(buf, "8 bit ");
97
98 if ( (player_info->format & ESD_STEREO) == ESD_STEREO )
99  strcat(buf, "stereo ");
100 else
101  strcat(buf, "mono ");
102
103 printf("player %i name    = %s\n",        player_info->source_id, player_info->name);
104 printf("player %i format  = 0x%08x %s\n", player_info->source_id, player_info->format, buf);
105 printf("player %i rate    = %i\n",        player_info->source_id, player_info->rate);
106 printf("player %i left    = %i\n",        player_info->source_id, player_info->left_vol_scale );
107 printf("player %i right   = %i\n",        player_info->source_id, player_info->right_vol_scale );
108}
109
110void esd_print_sample_info( esd_sample_info_t *sample_info ) {
111}
112
113/* print all info to stdout */
114void esd_print_all_info( esd_info_t *all_info ) {
115 esd_player_info_t *player;
116 esd_sample_info_t *sample;
117
118
119 esd_print_server_info(all_info->server);
120
121 player = all_info->player_list;
122
123 while (player) {
124  esd_print_player_info(player);
125  player = player->next;
126 }
127
128 sample = all_info->sample_list;
129
130 while (sample) {
131  esd_print_sample_info(sample);
132  sample = sample->next;
133 }
134
135}
136
137/* retrieve server properties (sample rate, format, version number) */
138esd_server_info_t *esd_get_server_info( int esd ) {
139 esd_server_info_t * r;
140 struct roar_stream     s;
141 struct roar_connection con;
142 struct roar_message    m;
143
144 r = malloc(sizeof(esd_server_info_t));
145
146 if ( r == NULL )
147  return NULL;
148
149 r->version = 0; // seems to be static
150
151 roar_connect_fh(&con, esd);
152 m.cmd     = ROAR_CMD_SERVER_OINFO;
153 m.datalen = 0;
154
155 if ( roar_req(&con, &m, NULL) == -1 ) {
156  free(r);
157  return NULL;
158 }
159
160 if ( m.cmd != ROAR_CMD_OK ) {
161  free(r);
162  return NULL;
163 }
164
165 if ( roar_stream_m2s(&s, &m) == -1 ) {
166  free(r);
167  return NULL;
168 }
169
170 r->rate   = s.info.rate;
171 r->format = 0;
172
173 if ( s.info.channels  == 1 )
174  r->format |= ESD_MONO;
175 else
176  r->format |= ESD_STEREO;
177
178 if ( s.info.bits == 8 )
179  r->format |= ESD_BITS8;
180 else
181  r->format |= ESD_BITS16;
182
183 return r;
184}
185/* release all memory allocated for the server properties structure */
186void esd_free_server_info( esd_server_info_t *server_info ) {
187 if (server_info)
188  free(server_info);
189}
190
191/* retrieve all information from server */
192esd_info_t *esd_get_all_info( int esd ) {
193 esd_info_t * r;
194 int i;
195 int num;
196 int clients[ROAR_CLIENTS_MAX];
197 struct roar_client c;
198 struct roar_stream s;
199 struct roar_connection con[1];
200 struct roar_mixer_settings mixer;
201 int channels;
202 esd_player_info_t * new_player, * cur = NULL; // = NULL to avoid gcc warning
203
204 roar_connect_fh(con, esd);
205
206 r = malloc(sizeof(esd_info_t));
207
208 if ( r == NULL )
209  return NULL;
210
211 r->server      = esd_get_server_info(esd);
212 r->player_list = NULL;
213 r->sample_list = NULL;
214
215 if ( (num = roar_list_clients(con, clients, ROAR_CLIENTS_MAX)) == -1 ) {
216  ROAR_ERR("esd_get_all_info(*): can not get client list");
217  num = 0;
218 }
219
220 for (i = 0; i < num; i++) {
221  if ( roar_get_client(con, &c, clients[i]) == -1 ) {
222   ROAR_ERR("esd_get_all_info(*): can not get client info");
223   continue;
224  }
225
226  if ( c.execed != -1 ) {
227   if ( roar_get_stream(con, &s, c.execed) == -1 ) {
228    ROAR_ERR("esd_get_all_info(*): can not get stream info");
229    continue;
230   }
231
232   if ( (new_player = malloc(sizeof(esd_player_info_t))) == NULL ) {
233    ROAR_ERR("esd_get_all_info(*): can not alloc memory for new player! BAD");
234    continue;
235   }
236
237   new_player->next = NULL;
238
239   new_player->source_id      = c.execed;
240   new_player->rate           = s.info.rate;
241
242   new_player->format         = ROAR_S2ESD(&s);
243//   sprintf(new_player->name, "roar stream %i", c.execed);
244   strncpy(new_player->name, c.name, ESD_NAME_MAX < ROAR_BUFFER_NAME ? ESD_NAME_MAX : ESD_NAME_MAX);
245
246   new_player->server         = r->server;
247
248   if ( roar_get_vol(con, c.execed, &mixer, &channels) == -1 ) {
249    ROAR_ERR("esd_get_all_info(*): can not get stream mixer info");
250    new_player->left_vol_scale = new_player->right_vol_scale = 256;
251   } else {
252    if ( channels == 1 ) {
253     new_player->left_vol_scale = new_player->right_vol_scale = mixer.mixer[0] == 65536 ? 256 : mixer.mixer[0] / 256;
254    } else {
255     if ( channels != 2 ) {
256      ROAR_ERR("esd_get_all_info(*): server seems to run in > 2 channel mode. ignoring any but the first two channels!");
257     }
258     new_player->left_vol_scale  = mixer.mixer[0] == 65536 ? 256 : mixer.mixer[0] / 256;
259     new_player->right_vol_scale = mixer.mixer[1] == 65536 ? 256 : mixer.mixer[1] / 256;
260    }
261   }
262
263
264   if ( r->player_list == NULL ) {
265     r->player_list = cur = new_player;
266   } else {
267     cur->next = new_player; // add to old player
268     cur       = new_player; // hop to next player
269   }
270
271  }
272 }
273
274 return r;
275}
276
277/* retrieve all information from server, and update until unsubsribed or closed */
278esd_info_t *esd_subscribe_all_info( int esd );
279
280/* call to update the info structure with new information, and call callbacks */
281esd_info_t *esd_update_info( int esd, esd_info_t *info,
282                             esd_update_info_callbacks_t *callbacks );
283esd_info_t *esd_unsubscribe_info( int esd );
284
285/* release all memory allocated for the esd info structure */
286void esd_free_all_info( esd_info_t *info ) {
287 esd_player_info_t *player, *oplayer;
288 esd_sample_info_t *sample, *osample;
289
290 if ( info != NULL ) {
291
292/*
293  if ( info->server )
294   free(info->server);
295*/
296  esd_free_server_info(info->server);
297
298
299/*
300  // TODO: do we need to free more?
301  if ( info->player_list )
302   free(info->player_list);
303
304  if ( info->sample_list )
305   free(info->sample_list);
306*/
307
308 player = info->player_list;
309
310 while (player) {
311  oplayer = player;
312  player  = player->next;
313
314  free(oplayer);
315 }
316
317 sample = info->sample_list;
318
319 while (sample) {
320  osample = sample;
321  sample  = sample->next;
322
323  free(osample);
324 }
325
326  free(info);
327 }
328}
329
330
331/* reset the volume panning for a stream */
332int esd_set_stream_pan( int esd, int stream_id,
333                        int left_scale, int right_scale ) {
334 struct roar_connection con;
335 struct roar_mixer_settings mixer;
336
337 roar_connect_fh(&con, esd);
338
339 mixer.mixer[0] = left_scale  == 256 ? 65535 : left_scale  * 256;
340 mixer.mixer[1] = right_scale == 256 ? 65535 : right_scale * 256;
341
342 ROAR_DBG("esd_set_stream_pan(esd=%i, stream_id=%i, left_scale=%i, right_scale=%i) = ?",
343                esd, stream_id, left_scale, right_scale);
344
345 return roar_set_vol(&con, stream_id, &mixer, 2);
346}
347
348/* reset the default volume panning for a sample */
349int esd_set_default_sample_pan( int esd, int sample_id,
350                                int left_scale, int right_scale ) {
351 return -1;
352}
353
354/* see if the server is in stnaby, autostandby, etc */
355esd_standby_mode_t esd_get_standby_mode( int esd ) {
356 return roar_simple_get_standby(esd);
357}
358
359//ll
Note: See TracBrowser for help on using the repository browser.