source: roaraudio/roard/sources.c @ 2285:3e05ea92950e

Last change on this file since 2285:3e05ea92950e was 2285:3e05ea92950e, checked in by phi, 15 years ago

added driver name to parameter list of new streams, corected flag name

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