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