source: roaraudio/roard/sources.c @ 2681:359a85bcf5e9

Last change on this file since 2681:359a85bcf5e9 was 2681:359a85bcf5e9, checked in by phi, 15 years ago

added new subsystem complex

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