source: roaraudio/roarclients/roarinterconnect.c @ 3669:93a98c7f08f3

Last change on this file since 3669:93a98c7f08f3 was 3669:93a98c7f08f3, checked in by phi, 14 years ago

added support for OSS to roarinterconnect :)

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