source: roaraudio/roard/sources.c @ 2507:946700cef0b8

Last change on this file since 2507:946700cef0b8 was 2507:946700cef0b8, checked in by phi, 15 years ago

make cdriver support in roard optional, disable it on --minimal

File size: 11.1 KB
Line 
1//sources.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
5 *
6 *  This file is part of roard 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, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "roard.h"
26
27#ifndef ROAR_WITHOUT_DCOMP_SOURCES
28
29struct roar_source g_source[] = {
30 {"raw",  "Raw source",                  "/some/file",     SRC_FLAG_FHSEC, ROAR_SUBSYS_WAVEFORM, NULL,  sources_add_raw},
31#ifdef ROAR_HAVE_IO_POSIX
32 {"wav",  "Old RIFF/WAVE source",        "/some/file.wav", SRC_FLAG_NONE,  ROAR_SUBSYS_WAVEFORM, sources_add_wav,  NULL},
33#endif
34 {"cf",   "Old CF source",               "/some/file.ext", SRC_FLAG_NONE,  ROAR_SUBSYS_WAVEFORM, sources_add_cf,   NULL},
35 {"roar", "Old simple RoarAudio source", "some.host",      SRC_FLAG_NONE,  ROAR_SUBSYS_WAVEFORM, sources_add_roar, NULL},
36#ifndef ROAR_WITHOUT_DCOMP_CDRIVER
37 {"oss",  "OSS CDriver",                 "/dev/audio",     SRC_FLAG_NONE,  ROAR_SUBSYS_WAVEFORM, NULL, sources_add_cdriver},
38#endif
39 {NULL, NULL, NULL, SRC_FLAG_NONE, 0, NULL, NULL} // EOL
40};
41
42int sources_init (void) {
43 g_source_client = -1;
44 return 0;
45}
46
47void print_sourcelist (void) {
48 int i;
49 char subsys[7] = "      ";
50
51 printf("  Source   Flag Subsys - Description (devices)\n");
52 printf("------------------------------------------------------\n");
53
54 for (i = 0; g_source[i].name != NULL; i++) {
55  strncpy(subsys, "      ", 6);
56
57  if ( g_source[i].subsystems & ROAR_SUBSYS_WAVEFORM )
58   subsys[0] = 'W';
59  if ( g_source[i].subsystems & ROAR_SUBSYS_MIDI )
60   subsys[1] = 'M';
61  if ( g_source[i].subsystems & ROAR_SUBSYS_CB )
62   subsys[2] = 'C';
63  if ( g_source[i].subsystems & ROAR_SUBSYS_LIGHT )
64   subsys[3] = 'L';
65  if ( g_source[i].subsystems & ROAR_SUBSYS_RAW )
66   subsys[4] = 'R';
67
68  printf("  %-9s %c%c%c %6s - %s (devices: %s)\n", g_source[i].name,
69                g_source[i].flags & SRC_FLAG_FHSEC      ? 's' : ' ',
70                g_source[i].old_open != NULL            ? 'S' : ' ',
71                g_source[i].new_open != NULL            ? 'N' : ' ',
72                subsys,
73                g_source[i].desc, g_source[i].devices);
74 }
75}
76
77
78int sources_set_client (int client) {
79 if ( client >= 0 ) {
80  g_source_client = client;
81  return 0;
82 } else {
83  return -1;
84 }
85}
86
87int sources_free (void) {
88 return 0;
89}
90
91int sources_add (char * driver, char * device, char * container, char * options, int primary) {
92 int i;
93
94 for (i = 0; g_source[i].name != NULL; i++) {
95  if ( !strcmp(g_source[i].name, driver) ) {
96   if ( g_source[i].new_open != NULL ) {
97    return sources_add_new(&(g_source[i]), driver, device, container, options, primary);
98   } else if ( g_source[i].old_open != NULL ) {
99    return g_source[i].old_open(driver, device, container, options, primary);
100   } else {
101    ROAR_ERR("sources_add(driver='%s', ...): Found source but did not find any open rutine", driver);
102    return -1;
103   }
104  }
105 }
106
107 ROAR_ERR("sources_add(driver='%s', ...): Source not found", driver);
108 return -1;
109}
110
111int sources_add_new (struct roar_source * source,
112                     char * driver, char * device,
113                     char * container,
114                     char * options, int primary) {
115 int  stream;
116 int  fh = -1;
117 struct roar_stream        *  s;
118 struct roar_stream_server * ss;
119 char * k, * v;
120 int error = 0;
121 int f_sync = 0, f_mmap = 0;
122 int codec;
123
124 if ( source == NULL )
125  return -1;
126
127 if ( (stream = streams_new()) == -1 ) {
128  return -1;
129 }
130
131 streams_get(stream, &ss);
132 s = ROAR_STREAM(ss);
133
134 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
135
136 codec = s->info.codec;
137
138 if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) {
139  streams_delete(stream);
140  return -1;
141 }
142
143 s->pos_rel_id = -1;
144
145 k = strtok(options, ",");
146 while (k != NULL) {
147  if ( (v = strstr(k, "=")) != NULL ) {
148   *v++ = 0;
149  }
150
151  if ( strcmp(k, "rate") == 0 ) {
152   s->info.rate = atoi(v);
153  } else if ( strcmp(k, "channels") == 0 ) {
154   s->info.channels = atoi(v);
155  } else if ( strcmp(k, "bits") == 0 ) {
156   s->info.bits = atoi(v);
157  } else if ( strcmp(k, "codec") == 0 ) {
158   if ( (codec = roar_str2codec(v)) == -1 ) {
159    ROAR_ERR("sources_add_new(*): unknown codec '%s'", v);
160    error++;
161   }
162
163  } else if ( strcmp(k, "name") == 0 ) {
164   if ( streams_set_name(stream, v) == -1 ) {
165    ROAR_ERR("add_output(*): Can not set Stream name");
166    error++;
167   }
168
169  } else if ( strcmp(k, "mmap") == 0 ) {
170   f_mmap = 1;
171  } else if ( strcmp(k, "sync") == 0 ) {
172   f_sync = 1;
173  } else if ( strcmp(k, "primary") == 0 ) {
174   primary = 1;
175  } else if ( strcmp(k, "meta") == 0 ) {
176   streams_set_flag(stream, ROAR_FLAG_META);
177  } else if ( strcmp(k, "cleanmeta") == 0 ) {
178   streams_set_flag(stream, ROAR_FLAG_CLEANMETA);
179  } else if ( strcmp(k, "autoconf") == 0 ) {
180   streams_set_flag(stream, ROAR_FLAG_AUTOCONF);
181
182  } else {
183   ROAR_ERR("sources_add_new(*): unknown option '%s'", k);
184   error++;
185  }
186
187  if ( error ) {
188   streams_delete(stream);
189   if ( primary ) alive = 0;
190   return -1;
191  }
192
193  k = strtok(NULL, ",");
194 }
195
196 if ( primary )
197  streams_mark_primary(stream);
198
199 streams_set_flag(stream, ROAR_FLAG_SOURCE);
200 client_stream_add(g_source_client, stream);
201
202 if ( codec == ROAR_CODEC_ALAW || codec == ROAR_CODEC_MULAW )
203  s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter
204
205 s->info.codec = codec;
206 ROAR_STREAM_SERVER(s)->codec_orgi = codec;
207
208 if ( source->new_open(stream, device, fh, driver) == -1 ) {
209  streams_delete(stream);
210  return -1;
211 }
212
213 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here
214 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM,   s); // ignore errors here
215
216 if ( f_sync ) {
217  streams_set_flag(stream, ROAR_FLAG_SYNC);
218 } else {
219  streams_reset_flag(stream, ROAR_FLAG_SYNC);
220 }
221
222 if ( f_mmap )
223  streams_set_flag(stream, ROAR_FLAG_MMAP);
224
225 return 0;
226}
227
228int sources_add_raw  (int stream   , char * device, int fh, char * driver) {
229 struct roar_stream_server * ss;
230
231 if ( fh > -1 )
232  return streams_set_fh(stream, fh);
233
234 streams_get(stream, &ss);
235
236 if ( roar_vio_open_file(&(ss->vio), device, O_RDONLY, 0644) == -1 )
237  return -1;
238
239 return streams_set_fh(stream, -2);
240}
241
242#ifdef ROAR_HAVE_IO_POSIX
243int sources_add_wav (char * driver, char * device, char * container, char * options, int primary) {
244 int stream;
245 int fh;
246 char buf[44];
247 struct roar_stream * s;
248
249 ROAR_WARN("sources_add_raw(*): The wav(e) source is obsolete, use source 'cf' (default)!");
250
251 if ( (fh = open(device, O_RDONLY, 0644)) == -1 ) {
252  return -1;
253 }
254
255 if (read(fh, buf, 44) != 44) {
256  close(fh);
257  return -1;
258 }
259
260 if ( (stream = streams_new()) == -1 ) {
261  close(fh);
262  return -1;
263 }
264
265 streams_get(stream, (struct roar_stream_server **)&s);
266
267 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
268
269 memcpy(&(s->info.rate    ), buf+24, 4);
270 memcpy(&(s->info.channels), buf+22, 2);
271 memcpy(&(s->info.bits    ), buf+34, 2);
272
273 if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) {
274  streams_delete(stream);
275  close(fh);
276  return -1;
277 }
278 s->pos_rel_id = -1;
279
280 streams_set_fh(stream, fh);
281
282 streams_set_flag(stream, ROAR_FLAG_SOURCE);
283 client_stream_add(g_source_client, stream);
284
285 return 0;
286}
287#endif
288
289#define _ret(x) streams_delete(stream); return (x)
290
291int sources_add_cf (char * driver, char * device, char * container, char * options, int primary) {
292 int  stream;
293 int  codec;
294 int  len;
295 char buf[64];
296 struct roar_stream    * s;
297 struct roar_vio_calls * vio;
298 struct roar_vio_defaults def;
299
300 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 )
301  return -1;
302
303 if ( (stream = streams_new()) == -1 ) {
304  return -1;
305 }
306
307 streams_get(stream, (struct roar_stream_server **)&s);
308
309 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
310
311 if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) {
312  streams_delete(stream);
313  return -1;
314 }
315
316 s->pos_rel_id = -1;
317
318/*
319 if ( (fh = open(device, O_RDONLY, 0644)) == -1 ) {
320  return -1;
321 }
322*/
323
324 vio = &(ROAR_STREAM_SERVER(s)->vio);
325
326 //if ( roar_vio_open_file(vio, device, O_RDONLY, 0644) == -1 ) {
327 if ( roar_vio_open_dstr(vio, device, &def, 1) == -1 ) {
328  _ret(-1);
329 }
330
331 ROAR_DBG("sources_add_cf(*) = ?");
332
333 // TODO: finy out a better way of doing auto detetion without need for seek!
334 if ( options == NULL ) {
335  if ( (len = roar_vio_read(vio, buf, 64)) < 1 ) {
336   _ret(-1);
337  }
338
339  if ( roar_vio_lseek(vio, -len, SEEK_CUR) == (off_t)-1 ) {
340   _ret(-1);
341  }
342
343  if ( (codec = roar_file_codecdetect(buf, len)) == -1 ) {
344   _ret(-1);
345  }
346 } else {
347  if ( !strncmp(options, "codec=", 6) )
348   options += 6;
349
350  if ( (codec = roar_str2codec(options)) == -1 ) {
351   _ret(-1);
352  }
353 }
354
355 s->info.codec = codec;
356
357 ROAR_STREAM_SERVER(s)->codec_orgi = codec;
358
359 ROAR_DBG("sources_add_cf(*) = ?");
360 streams_set_fh(stream, -2);
361 ROAR_DBG("sources_add_cf(*) = ?");
362 streams_set_socktype(stream, ROAR_SOCKET_TYPE_FILE);
363
364 if ( primary )
365  streams_mark_primary(stream);
366
367 streams_set_flag(stream, ROAR_FLAG_SOURCE);
368 client_stream_add(g_source_client, stream);
369
370 return 0;
371}
372
373#undef _ret
374
375
376int sources_add_roar (char * driver, char * device, char * container, char * options, int primary) {
377 int  stream;
378 int  fh;
379 int  codec = ROAR_CODEC_DEFAULT;
380 struct roar_stream * s;
381
382 if ( options != NULL && *options ) {
383  if ( !strncmp(options, "codec=", 6) )
384   options += 6;
385
386  if ( (codec = roar_str2codec(options)) == -1 ) {
387   return -1;
388  }
389 }
390
391 if ( (fh = roar_simple_monitor(g_sa->rate, g_sa->channels, g_sa->bits, codec, device, "roard")) == -1 ) {
392  return -1;
393 }
394
395 if ( (stream = streams_new()) == -1 ) {
396  close(fh);
397  return -1;
398 }
399
400 streams_get(stream, (struct roar_stream_server **)&s);
401
402 memcpy(&(s->info), g_sa, sizeof(struct roar_audio_info));
403
404 if ( streams_set_dir(stream, ROAR_DIR_PLAY, 1) == -1 ) {
405  streams_delete(stream);
406  close(fh);
407  return -1;
408 }
409
410 s->pos_rel_id = -1;
411 s->info.codec = codec;
412
413 ROAR_STREAM_SERVER(s)->codec_orgi = codec;
414
415 streams_set_fh(stream, fh);
416
417 if ( primary )
418  streams_mark_primary(stream);
419
420 streams_set_flag(stream, ROAR_FLAG_SOURCE);
421 client_stream_add(g_source_client, stream);
422
423 return 0;
424}
425
426#ifndef ROAR_WITHOUT_DCOMP_CDRIVER
427int sources_add_cdriver (int stream   , char * device, int fh, char * driver) {
428 int roar_cdriver_open(struct roar_vio_calls * calls, char * name, char * dev, struct roar_audio_info * info, int dir);
429 struct roar_stream_server * ss;
430
431 if ( fh > -1 )
432  return -1;
433
434 streams_get(stream, &ss);
435
436 if ( !strncmp(driver, "cdriver:", 8) )
437  driver += 8;
438
439 ROAR_DBG("sources_add_cdriver(stream=%i, device='%s', fh=%i, driver='%s') = ?", stream, device, fh, driver);
440
441 if ( roar_cdriver_open(&(ss->vio), driver, device, &(ROAR_STREAM(ss)->info), ROAR_DIR_RECORD) == -1 )
442  return -1;
443
444 return streams_set_fh(stream, -2);
445}
446#endif
447
448#endif
449
450//ll
Note: See TracBrowser for help on using the repository browser.