source: roaraudio/roard/sources.c @ 2290:ca4943a321fd

Last change on this file since 2290:ca4943a321fd was 2290:ca4943a321fd, checked in by phi, 15 years ago

yet another debug message

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