source: roaraudio/roard/sources.c @ 2502:6e79ef338c39

Last change on this file since 2502:6e79ef338c39 was 2485:1cbb82cde915, checked in by phi, 15 years ago

make sources optional

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