source: roaraudio/libroaresd/esdctl.c @ 5226:3cb3cab29e5e

Last change on this file since 5226:3cb3cab29e5e was 5226:3cb3cab29e5e, checked in by phi, 12 years ago

Removed roarcat2sock as well as roar_simple_stream(), roar_simple_new_stream(), roar_simple_play(), roar_simple_monitor(), roar_simple_record(), roar_simple_filter(), roar_simple_close() and roar_simple_get_standby().

File size: 9.8 KB
Line 
1//esdctl.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
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 = roar_mm_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
153 memset(&m, 0, sizeof(m));
154
155 m.cmd     = ROAR_CMD_SERVER_OINFO;
156 m.datalen = 0;
157
158 if ( roar_req(&con, &m, NULL) == -1 ) {
159  roar_mm_free(r);
160  return NULL;
161 }
162
163 if ( m.cmd != ROAR_CMD_OK ) {
164  roar_mm_free(r);
165  return NULL;
166 }
167
168 if ( roar_stream_m2s(&s, &m) == -1 ) {
169  roar_mm_free(r);
170  return NULL;
171 }
172
173 r->rate   = s.info.rate;
174 r->format = 0;
175
176 if ( s.info.channels  == 1 )
177  r->format |= ESD_MONO;
178 else
179  r->format |= ESD_STEREO;
180
181 if ( s.info.bits == 8 )
182  r->format |= ESD_BITS8;
183 else
184  r->format |= ESD_BITS16;
185
186 return r;
187}
188/* release all memory allocated for the server properties structure */
189void esd_free_server_info( esd_server_info_t *server_info ) {
190 if (server_info != NULL)
191  roar_mm_free(server_info);
192}
193
194/* retrieve all information from server */
195esd_info_t *esd_get_all_info( int esd ) {
196 esd_info_t * r;
197 int i;
198 int num;
199 int clients[ROAR_CLIENTS_MAX];
200 struct roar_client c;
201 struct roar_stream s;
202 struct roar_connection con[1];
203 struct roar_mixer_settings mixer;
204 int channels;
205 float fs;
206 esd_player_info_t * new_player, * cur = NULL; // = NULL to avoid gcc warning
207
208 roar_connect_fh(con, esd);
209
210 r = roar_mm_malloc(sizeof(esd_info_t));
211
212 if ( r == NULL )
213  return NULL;
214
215 r->server      = esd_get_server_info(esd);
216 r->player_list = NULL;
217 r->sample_list = NULL;
218
219 if ( (num = roar_list_clients(con, clients, ROAR_CLIENTS_MAX)) == -1 ) {
220  ROAR_ERR("esd_get_all_info(*): can not get client list");
221  num = 0;
222 }
223
224 for (i = 0; i < num; i++) {
225  if ( roar_get_client(con, &c, clients[i]) == -1 ) {
226   ROAR_ERR("esd_get_all_info(*): can not get client info");
227   continue;
228  }
229
230  if ( c.execed != -1 ) {
231   if ( roar_get_stream(con, &s, c.execed) == -1 ) {
232    ROAR_ERR("esd_get_all_info(*): can not get stream info");
233    continue;
234   }
235
236   if ( (new_player = roar_mm_malloc(sizeof(esd_player_info_t))) == NULL ) {
237    ROAR_ERR("esd_get_all_info(*): can not alloc memory for new player! BAD");
238    continue;
239   }
240
241   new_player->next = NULL;
242
243   new_player->source_id      = c.execed;
244   new_player->rate           = s.info.rate;
245
246   new_player->format         = ROAR_S2ESD(&s);
247//   sprintf(new_player->name, "roar stream %i", c.execed);
248   strncpy(new_player->name, c.name, ESD_NAME_MAX < ROAR_BUFFER_NAME ? ESD_NAME_MAX : ESD_NAME_MAX);
249
250   new_player->server         = r->server;
251
252   if ( roar_get_vol(con, c.execed, &mixer, &channels) == -1 ) {
253    ROAR_ERR("esd_get_all_info(*): can not get stream mixer info");
254    new_player->left_vol_scale = new_player->right_vol_scale = 256;
255   } else {
256    fs = mixer.scale / 257;
257    if ( channels == 1 ) {
258     new_player->left_vol_scale = new_player->right_vol_scale = mixer.mixer[0] == mixer.scale ? 256 : mixer.mixer[0] / fs;
259    } else {
260     if ( channels != 2 ) {
261      ROAR_ERR("esd_get_all_info(*): server seems to run in > 2 channel mode. ignoring any but the first two channels!");
262     }
263     new_player->left_vol_scale  = mixer.mixer[0] == mixer.scale ? 256 : mixer.mixer[0] / fs;
264     new_player->right_vol_scale = mixer.mixer[1] == mixer.scale ? 256 : mixer.mixer[1] / fs;
265    }
266   }
267
268
269   if ( r->player_list == NULL ) {
270     r->player_list = cur = new_player;
271   } else {
272     cur->next = new_player; // add to old player
273     cur       = new_player; // hop to next player
274   }
275
276  }
277 }
278
279 return r;
280}
281
282/* retrieve all information from server, and update until unsubsribed or closed */
283esd_info_t *esd_subscribe_all_info( int esd ) {
284 return NULL; // Not yet implemented in upstream esd
285}
286
287/* call to update the info structure with new information, and call callbacks */
288esd_info_t *esd_update_info( int esd, esd_info_t *info,
289                             esd_update_info_callbacks_t *callbacks ) {
290 return NULL; // Not yet implemented in upstream esd
291}
292
293esd_info_t *esd_unsubscribe_info( int esd ) {
294 return NULL; // Not yet implemented in upstream esd
295}
296
297/* release all memory allocated for the esd info structure */
298void esd_free_all_info( esd_info_t *info ) {
299 esd_player_info_t *player, *oplayer;
300 esd_sample_info_t *sample, *osample;
301
302 if ( info != NULL ) {
303
304/*
305  if ( info->server )
306   free(info->server);
307*/
308  esd_free_server_info(info->server);
309
310
311/*
312  // TODO: do we need to free more?
313  if ( info->player_list )
314   free(info->player_list);
315
316  if ( info->sample_list )
317   free(info->sample_list);
318*/
319
320 player = info->player_list;
321
322 while (player != NULL) {
323  oplayer = player;
324  player  = player->next;
325
326  roar_mm_free(oplayer);
327 }
328
329 sample = info->sample_list;
330
331 while (sample) {
332  osample = sample;
333  sample  = sample->next;
334
335  roar_mm_free(osample);
336 }
337
338  roar_mm_free(info);
339 }
340}
341
342
343/* reset the volume panning for a stream */
344int esd_set_stream_pan( int esd, int stream_id,
345                        int left_scale, int right_scale ) {
346 struct roar_connection con;
347 struct roar_mixer_settings mixer;
348
349 roar_connect_fh(&con, esd);
350
351 mixer.scale    = 256;
352 mixer.mixer[0] = left_scale;
353 mixer.mixer[1] = right_scale;
354
355 ROAR_DBG("esd_set_stream_pan(esd=%i, stream_id=%i, left_scale=%i, right_scale=%i) = ?",
356                esd, stream_id, left_scale, right_scale);
357
358 return roar_set_vol(&con, stream_id, &mixer, 2);
359}
360
361/* reset the default volume panning for a sample */
362int esd_set_default_sample_pan( int esd, int sample_id,
363                                int left_scale, int right_scale ) {
364 return -1;
365}
366
367/* see if the server is in stnaby, autostandby, etc */
368esd_standby_mode_t esd_get_standby_mode( int esd ) {
369 struct roar_connection con;
370
371 if ( roar_connect_fh(&con, esd) == -1 )
372  return -1;
373
374 return roar_get_standby(&con);
375}
376
377//ll
Note: See TracBrowser for help on using the repository browser.