source: roaraudio/roarclients/roarinterconnect.c @ 3670:8e29cd7e4cdb

Last change on this file since 3670:8e29cd7e4cdb was 3670:8e29cd7e4cdb, checked in by phi, 14 years ago

added verbose mode

File size: 9.8 KB
Line 
1//roarinterconnect.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009
5 *
6 *  This file is part of roarclients a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26// configure ROAR_INFO()
27int g_verbose = 0;
28#define ROAR_DBG_INFOVAR g_verbose
29
30#include <roaraudio.h>
31#include <libroareio/libroareio.h>
32
33#ifdef ROAR_HAVE_ESD
34#include <esd.h>
35#endif
36
37#define MT_NONE     0x00
38#define MT_MASK     0xF0
39#define MT_ROAR     0x10
40#define MT_ESD      0x20
41#define MT_SIMPLE   0x30
42#define MT_OSS      0x40
43#define MT_DEFAULT  MT_ROAR
44
45#define ST_NONE     0x00
46#define ST_MASK     0x0F
47#define ST_BIDIR    0x01
48#define ST_FILTER   0x02
49#define ST_TRANSMIT 0x03
50#define ST_RECEIVE  0x04
51// no default here as the default depend on the server type
52
53void usage (void) {
54 printf("roarinterconnect [OPTIONS]...\n");
55
56 printf("\nOptions:\n\n");
57
58 printf("  --server SERVER    - Set server hostname\n"
59        "  --remote SERVER    - Set remote server\n"
60        "  --type   TYPE      - Set type of remote server\n"
61        "  --rate   RATE      - Set sample rate\n"
62        "  --bits   BITS      - Set bits per sample\n"
63        "  --chans  CHANNELS  - Set number of channels\n"
64        "  --codec  CODEC     - Set the codec\n"
65        "  --help             - Show this help\n"
66       );
67
68 printf("\nPossible Types:\n\n");
69 printf("  roar               - RoarAudio Server\n"
70        "  esd                - EsounD Server\n"
71        "  simple             - PulseAudio using simple protocol\n"
72        "  oss                - Open Sound System (OSS) device\n"
73        "\n"
74        "  bidir              - Connect bidirectional\n"
75        "  filter             - Use local server as filter for remote server\n"
76        "  transmit           - Transmit data from local server to remote server\n"
77        "  receive            - Receive data from remote server\n"
78       );
79
80}
81
82int parse_type (char * type) {
83 int ret = MT_NONE|ST_NONE;
84 char * colon;
85
86 if ( type != NULL ) {
87  while (type != NULL && *type) {
88   if ( (colon = strstr(type, ":")) != NULL ) {
89    *colon = 0;
90     colon++;
91   }
92
93   if ( !strcmp(type, "roar") ) {
94    ret -= ret & MT_MASK;
95    ret += MT_ROAR;
96   } else if ( !strcmp(type, "esd") ) {
97    ret -= ret & MT_MASK;
98    ret += MT_ESD;
99   } else if ( !strcmp(type, "simple") ) {
100    ret -= ret & MT_MASK;
101    ret += MT_SIMPLE;
102   } else if ( !strcmp(type, "oss") ) {
103    ret -= ret & MT_MASK;
104    ret += MT_OSS;
105   } else if ( !strcmp(type, "bidir") ) {
106    ret -= ret & ST_MASK;
107    ret += ST_BIDIR;
108   } else if ( !strcmp(type, "filter") ) {
109    ret -= ret & ST_MASK;
110    ret += ST_FILTER;
111   } else if ( !strcmp(type, "transmit") ) {
112    ret -= ret & ST_MASK;
113    ret += ST_TRANSMIT;
114   } else if ( !strcmp(type, "receive") ) {
115    ret -= ret & ST_MASK;
116    ret += ST_RECEIVE;
117   } else {
118    return MT_NONE|ST_NONE;
119   }
120
121   type = colon;
122  }
123 }
124
125 if ( (ret & MT_MASK) == MT_NONE )
126  ret |= MT_DEFAULT;
127
128 if ( (ret & ST_MASK) == ST_NONE ) {
129  switch (ret & MT_MASK) {
130   case MT_ROAR:   ret |= ST_BIDIR;    break;
131   case MT_ESD:    ret |= ST_FILTER;   break;
132   case MT_SIMPLE: ret |= ST_TRANSMIT; break; // we use ST_TRANSMIT because ST_BIDIR is
133                                              // very unlike to be configured at the server side.
134   case MT_OSS:    ret |= ST_BIDIR;    break;
135   default:
136     return MT_NONE|ST_NONE; // error case
137    break;
138  }
139 }
140
141 return ret;
142}
143
144int main (int argc, char * argv[]) {
145 struct roar_connection con[1];
146 struct roar_stream     stream[1];
147 struct roar_vio_calls  vio;
148 struct roar_audio_info info;
149 int    rate     = 44100;
150 int    bits     = 16;
151 int    channels = 2;
152 int    codec    = ROAR_CODEC_DEFAULT;
153 int    type     = parse_type(NULL);
154 int    tmp;
155 char * server   = NULL;
156 char * remote   = "+slp"; // we hope SLP located server is not local one
157 char * k;
158 int    rfh;
159 int    i;
160 int    localdir = ROAR_DIR_BIDIR;
161 int    rport;
162
163 for (i = 1; i < argc; i++) {
164  k = argv[i];
165
166  if ( strcmp(k, "--server") == 0 ) {
167   server = argv[++i];
168  } else if ( strcmp(k, "--remote") == 0 ) {
169   remote = argv[++i];
170  } else if ( strcmp(k, "--type") == 0 ) {
171   type = parse_type(argv[++i]);
172  } else if ( strcmp(k, "--rate") == 0 ) {
173   rate = atoi(argv[++i]);
174  } else if ( strcmp(k, "--bits") == 0 ) {
175   bits = atoi(argv[++i]);
176  } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) {
177   channels = atoi(argv[++i]);
178  } else if ( strcmp(k, "--codec") == 0 ) {
179   codec = roar_str2codec(argv[++i]);
180  } else if ( strcmp(k, "--verbose") == 0 || strcmp(k, "-v") == 0 ) {
181   g_verbose++;
182  } else if ( strcmp(k, "--help") == 0 ) {
183   usage();
184   return 0;
185  } else {
186   fprintf(stderr, "Error: unknown argument: %s\n", k);
187   usage();
188   return 1;
189  }
190 }
191
192 switch (type & MT_MASK) {
193  case MT_ROAR:
194    switch (type & ST_MASK) {
195     case ST_BIDIR:
196       tmp      = ROAR_DIR_BIDIR;
197      break;
198     case ST_FILTER:
199       tmp      = ROAR_DIR_FILTER;
200      break;
201     case ST_TRANSMIT:
202       tmp      = ROAR_DIR_PLAY;
203       localdir = ROAR_DIR_MONITOR;
204      break;
205     case ST_RECEIVE:
206       tmp      = ROAR_DIR_MONITOR;
207       localdir = ROAR_DIR_PLAY;
208      break;
209     default:
210       fprintf(stderr, "Error: unknown stream type\n");
211       return 2;
212    }
213    rfh = roar_simple_stream(rate, channels, bits, codec, remote, tmp, "roarinterconnect");
214   break;
215  case MT_OSS:
216    switch (type & ST_MASK) {
217     case ST_BIDIR:
218       tmp      = ROAR_DIR_BIDIR;
219      break;
220     case ST_TRANSMIT:
221       tmp      = ROAR_DIR_PLAY;
222       localdir = ROAR_DIR_MONITOR;
223      break;
224     case ST_RECEIVE:
225       tmp      = ROAR_DIR_RECORD;
226       localdir = ROAR_DIR_PLAY;
227      break;
228     default:
229       fprintf(stderr, "Error: unknown stream type\n");
230       return 2;
231    }
232    info.rate     = rate;
233    info.channels = channels;
234    info.bits     = bits;
235    info.codec    = codec;
236    if ( roar_cdriver_oss(&vio, "OSS", remote, &info, tmp) == -1 ) {
237     fprintf(stderr, "Error: can not open OSS device %s\n", remote);
238     return 2;
239    }
240    if ( roar_vio_ctl(&vio, ROAR_VIO_CTL_GET_FH, &rfh) == -1 ) {
241     roar_vio_close(&vio);
242     fprintf(stderr, "Error: can not get filehandle for OSS device %s\n", remote);
243     return 2;
244    }
245   break;
246#ifdef ROAR_HAVE_ESD
247  case MT_ESD:
248    tmp = ESD_STREAM|ESD_PLAY;
249
250    switch (bits) {
251     case  8: tmp |= ESD_BITS8;  break;
252     case 16: tmp |= ESD_BITS16; break;
253     default:
254       fprintf(stderr, "Error: EsounD only supports 8 and 16 bit streams\n");
255       return 2;
256    }
257
258    switch (channels) {
259     case 1: tmp |= ESD_MONO;   break;
260     case 2: tmp |= ESD_STEREO; break;
261     default:
262       fprintf(stderr, "Error: EsounD only supports mono and stereo streams\n");
263       return 2;
264    }
265
266    // this is only true if the esd runs on a LE system,...
267    if ( bits == 8 && codec != ROAR_CODEC_PCM_U_LE ) {
268     fprintf(stderr, "Error: EsounD only supports unsigned PCM in 8 bit mode\n");
269     return 2;
270    } else if ( bits == 16 && codec != ROAR_CODEC_DEFAULT ) {
271     fprintf(stderr, "Error: EsounD only supports signed PCM in 16 bit mode\n");
272     return 2;
273    }
274
275    switch (type & ST_MASK) {
276     case ST_FILTER:
277       rfh = esd_filter_stream(tmp, rate, remote, "roarinterconnect");
278      break;
279     case ST_TRANSMIT:
280       rfh = esd_play_stream(tmp, rate, remote, "roarinterconnect");
281      break;
282     case ST_RECEIVE:
283       rfh = esd_monitor_stream(tmp, rate, remote, "roarinterconnect");
284      break;
285     default:
286       fprintf(stderr, "Error: this type is not supported by EsounD\n");
287       return 2;
288      break;
289    }
290   break;
291#endif
292  case MT_SIMPLE:
293    switch (type & ST_MASK) {
294     case ST_BIDIR:
295       tmp = -1;
296       localdir = ROAR_DIR_BIDIR;
297      break;
298     case ST_TRANSMIT:
299       tmp = SHUT_RD;
300       localdir = ROAR_DIR_MONITOR;
301      break;
302     case ST_RECEIVE:
303       tmp = SHUT_WR;
304       localdir = ROAR_DIR_PLAY;
305      break;
306     default:
307       fprintf(stderr, "Error: this type is not supported by PulseAudio\n");
308       return 2;
309    }
310    // we guess INET here...
311    if ( strstr(remote, "/") == NULL && (k = strstr(remote, ":")) != NULL ) {
312     *k = 0;
313     k++;
314     rport = atoi(k);
315    } else {
316     rport = 4712;
317    }
318    rfh = roar_socket_connect(remote, rport);
319    if ( tmp != -1 ) {
320     ROAR_SHUTDOWN(rfh, tmp);
321    }
322   break;
323  default:
324    fprintf(stderr, "Error: unknown/not supported server type\n");
325    return 2;
326 }
327
328 if ( rfh == -1 ) {
329  fprintf(stderr, "Error: can not connect to remote server\n");
330  return 10;
331 }
332
333 if ( roar_simple_connect(con, server, "roarinterconnect") == -1 ) {
334  fprintf(stderr, "Can not connect to local server\n");
335  return 20;
336 }
337
338 if ( roar_stream_new(stream, rate, channels, bits, codec) == -1 ) {
339  roar_disconnect(con);
340  return 21;
341 }
342
343 if ( roar_stream_connect(con, stream, localdir) == -1 ) {
344  roar_disconnect(con);
345  return 22;
346 }
347
348 if ( roar_stream_passfh(con, stream, rfh) == -1 ) {
349  roar_disconnect(con);
350  return 23;
351 }
352
353 roar_simple_close(rfh);
354
355 if ( roar_stream_attach_simple(con, stream, 0) == -1 ) {
356  fprintf(stderr, "Can not attach remote stream to local server\n");
357 }
358
359 roar_disconnect(con);
360
361 ROAR_INFO("Stream ID: %i", 1, stream->id);
362
363 return 0;
364}
365
366//ll
Note: See TracBrowser for help on using the repository browser.