source: roaraudio/roarclients/roarinterconnect.c @ 3784:435f61201111

Last change on this file since 3784:435f61201111 was 3673:f52a7c131e08, checked in by phi, 14 years ago

added info on --verbose/-v for roarinterconnect

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