source: roaraudio/libroar/stream.c @ 3857:8ed6d81a32d6

Last change on this file since 3857:8ed6d81a32d6 was 3857:8ed6d81a32d6, checked in by phi, 14 years ago

use roar_debug_warn_obsolete() and roar_libroar_*warn()

File size: 22.6 KB
Line 
1//stream.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010
5 *
6 *  This file is part of libroar 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 *  libroar 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, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38int roar_stream_connect (struct roar_connection * con, struct roar_stream * s, int dir) {
39 struct roar_libroar_config * config = roar_libroar_get_config();
40 struct roar_stream  ms;
41 struct roar_message m;
42
43 s->dir = dir;
44
45 memcpy(&ms, s, sizeof(ms));
46
47 m.cmd     = ROAR_CMD_NEW_STREAM;
48 m.stream  = -1;
49 m.pos     = 0;
50
51 if ( config != NULL ) {
52  if ( config->info.rate )
53   ms.info.rate = config->info.rate;
54  if ( config->info.bits )
55   ms.info.bits = config->info.bits;
56  if ( config->info.channels )
57   ms.info.channels = config->info.channels;
58  if ( config->info.codec )
59   ms.info.codec = config->info.codec;
60 }
61
62 roar_stream_s2m(&ms, &m);
63
64 if ( roar_req(con, &m, NULL) != 0 )
65  return -1;
66
67 if ( m.cmd == ROAR_CMD_OK ) {
68  s->id = m.stream;
69
70  ROAR_DBG("roar_stream_connect(*) = 0");
71  return 0;
72 }
73
74 ROAR_ERR("roar_stream_connect(*): Connecting new stream faild!");
75 ROAR_DBG("roar_stream_connect(*) = -1");
76 return -1;
77}
78
79int roar_stream_new (struct roar_stream * s, unsigned int rate,
80                     unsigned int channels, unsigned int bits, unsigned int codec) {
81
82 if ( s == NULL )
83  return -1;
84
85 s->fh         = -1;
86 s->id         = -1;
87 s->pos        =  0;
88 s->pos_rel_id = -1;
89
90 s->dir        = ROAR_DIR_DEFAULT;
91
92/*
93 s->datalen    = 0;
94 s->offset     = 0;
95
96 s->database   = NULL;
97 s->dataoff    = NULL;
98*/
99
100 s->info.rate     = rate;
101 s->info.channels = channels;
102 s->info.bits     = bits;
103 s->info.codec    = codec;
104
105 if ( bits > ROAR_BITS_MAX )
106  return -1;
107
108 return 0;
109}
110
111int roar_stream_set_rel_id(struct roar_stream * s, int id) {
112 if ( s == NULL )
113  return -1;
114
115 s->pos_rel_id = id;
116
117 return 0;
118}
119
120int roar_stream_get_rel_id(struct roar_stream * s) {
121 if ( s == NULL )
122  return -1;
123
124 return s->pos_rel_id;
125}
126
127int roar_stream_new_by_id(struct roar_stream * s, int id) {
128 if ( s == NULL )
129  return -1;
130
131 if ( roar_stream_new_empty(s) == -1 )
132  return -1;
133
134 return roar_stream_set_id(s, id);
135}
136
137int roar_stream_new_empty(struct roar_stream * s) {
138 if ( s == NULL )
139  return -1;
140
141 return roar_stream_new(s, 0, 0, 0, 0);
142}
143
144int roar_stream_set_id (struct roar_stream * s, int id) {
145 if ( s == NULL )
146  return -1;
147
148 s->id = id;
149
150 return 0;
151}
152
153int roar_stream_get_id (struct roar_stream * s) {
154 if ( s == NULL )
155  return -1;
156
157 return s->id;
158}
159
160int roar_stream_set_fh (struct roar_stream * s, int fh) {
161 if ( s == NULL )
162  return -1;
163
164 s->fh = fh;
165
166 return 0;
167}
168
169int roar_stream_get_fh (struct roar_stream * s) {
170 if ( s == NULL )
171  return -1;
172
173 return s->fh;
174}
175
176int roar_stream_set_dir (struct roar_stream * s, int dir) {
177 if ( s == NULL )
178  return -1;
179
180 s->dir = dir;
181
182 return 0;
183}
184
185int roar_stream_get_dir (struct roar_stream * s) {
186 if ( s == NULL )
187  return -1;
188
189 return s->dir;
190}
191
192
193int roar_stream_exec    (struct roar_connection * con, struct roar_stream * s) {
194 struct roar_message m;
195
196 m.cmd     = ROAR_CMD_EXEC_STREAM;
197 m.stream  = s->id;
198 m.datalen = 0;
199 m.pos     = 0;
200
201 if ( roar_req(con, &m, NULL) == -1 )
202  return -1;
203
204 if ( m.cmd == ROAR_CMD_OK )
205  return 0;
206 return -1;
207}
208
209int roar_stream_connect_to (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port) {
210 struct roar_message m;
211
212 if ( roar_stream_connect_to_ask(con, s, type, host, port) == -1 )
213  return -1;
214
215 if ( roar_recv_message(con, &m, NULL) == -1 )
216  return -1;
217
218 if ( m.cmd == ROAR_CMD_OK )
219  return 0;
220 return -1;
221}
222
223int roar_stream_connect_to_ask (struct roar_connection * con, struct roar_stream * s, int type, char * host, int port) {
224 struct roar_message m;
225 int len = 0;
226
227 if ( host == NULL )
228  return -1;
229
230 ROAR_DBG("roar_stream_connect_to_ask(*): Ask the server to connect to: %s:%i", host, port);
231
232 m.cmd     = ROAR_CMD_CON_STREAM;
233 m.stream  = s->id;
234 m.pos     = 0;
235
236 m.data[0] = 0;
237 m.data[1] = type;
238 ((uint16_t*)&(m.data))[1] = ROAR_HOST2NET16(port);
239
240 len = strlen(host);
241
242 if ( len > 76 )
243  return -1;
244
245 strncpy(&(m.data[4]), host, len);
246
247 m.datalen = len + 4;
248
249 if ( roar_send_message(con, &m, NULL) == -1 )
250  return -1;
251
252 return 0;
253}
254
255int roar_stream_passfh  (struct roar_connection * con, struct roar_stream * s, int fh) {
256 struct roar_message m;
257 int confh;
258
259 m.cmd     = ROAR_CMD_PASSFH;
260 m.stream  = s->id;
261 m.pos     = 0;
262 m.datalen = 0;
263
264 ROAR_DBG("roar_stream_passfh(con=%p{...}, s={.id=%i,...}, fh=%i) = ?", con, s->id, fh);
265
266 roar_libroar_nowarn();
267 if ( (confh = roar_get_connection_fh(con)) == -1 ) {
268  roar_libroar_warn();
269  return -1;
270 }
271 roar_libroar_warn();
272
273 if ( roar_send_message(con, &m, NULL) == -1 ) {
274  ROAR_DBG("roar_stream_passfh(con=%p{...}, s={.id=%i,...}, fh=%i) = -1 // can not send message", con, s->id, fh);
275  return -1;
276 }
277
278 ROAR_DBG("roar_stream_passfh(*): msg send");
279
280 if ( roar_socket_send_fh(confh, fh, NULL, 0) == -1 )
281  return -1;
282
283 ROAR_DBG("roar_stream_passfh(*): fh send");
284
285 if ( roar_recv_message(con, &m, NULL) == -1 )
286  return -1;
287
288 ROAR_DBG("roar_stream_passfh(*): mes recved");
289
290 if ( m.cmd == ROAR_CMD_OK )
291  return 0;
292
293 return -1;
294}
295
296int roar_stream_attach_simple (struct roar_connection * con, struct roar_stream * s, int client) {
297 struct roar_message m;
298 uint16_t * info = (uint16_t *) m.data;
299 int i;
300
301 m.cmd     = ROAR_CMD_ATTACH;
302 m.stream  = s->id;
303 m.pos     = 0;
304 m.datalen = 6;
305
306 info[0] = 0;
307 info[1] = ROAR_ATTACH_SIMPLE;
308 info[2] = client;
309
310 for (i = 0; i < m.datalen/2; i++) {
311  info[i] = ROAR_HOST2NET16(info[i]);
312 }
313
314 if ( roar_req(con, &m, NULL) == -1 )
315  return -1;
316
317 if ( m.cmd != ROAR_CMD_OK )
318  return -1;
319
320 return 0;
321}
322
323int roar_stream_add_data (struct roar_connection * con, struct roar_stream * s, char * data, size_t len) {
324 struct roar_message m;
325
326 m.cmd     = ROAR_CMD_ADD_DATA;
327 m.stream  = s->id;
328 m.pos     = 0;
329 m.datalen = len;
330
331// if ( roar_req(con, &m, (void**)&data) == -1 )
332//  return -1;
333 if ( roar_send_message(con, &m, data) != 0 )
334  return -1;
335
336 if ( roar_recv_message(con, &m, NULL) == -1 )
337  return -1;
338
339 if ( m.cmd == ROAR_CMD_OK )
340  return 0;
341 return -1;
342}
343
344int roar_stream_send_data (struct roar_connection * con, struct roar_stream * s, char * data, size_t len) {
345
346 roar_debug_warn_obsolete("roar_stream_send_data", "roar_vio_write", NULL);
347
348 if ( s == NULL )
349  return -1;
350
351 if ( s->fh == -1 ) {
352  if ( con == NULL )
353   return -1;
354
355  if ( roar_stream_add_data(con, s, data, len) == -1 )
356   return -1;
357
358  return len;
359 }
360
361#ifdef ROAR_HAVE_IO_POSIX
362 return write(s->fh, data, len);
363#endif
364
365 return -1;
366}
367
368int roar_stream_get_info (struct roar_connection * con, struct roar_stream * s, struct roar_stream_info * info) {
369 struct roar_message m;
370 uint16_t * data = (uint16_t *) m.data;
371 int i;
372
373 m.cmd     = ROAR_CMD_GET_STREAM_PARA;
374 m.stream  = s->id;
375 m.datalen = 4;
376 m.pos     = 0;
377
378 data[0] = 0; // Version and reserved
379 data[1] = ROAR_STREAM_PARA_INFO; // stream
380
381 for (i = 0; i < m.datalen/2; i++) {
382  data[i] = ROAR_HOST2NET16(data[i]);
383 }
384
385 if ( roar_req(con, &m, NULL) == -1 )
386  return -1;
387
388 if ( m.cmd != ROAR_CMD_OK )
389  return -1;
390
391 for (i = 0; i < m.datalen/2; i++) {
392  data[i] = ROAR_NET2HOST16(data[i]);
393 }
394
395 if ( m.datalen < 7*2 )
396  return -1;
397
398 if ( data[0] != 0 || data[1] != 1 )
399  return -1;
400
401 memset(info, 0, sizeof(struct roar_stream_info));
402 info->mixer = -1;
403 info->role  = ROAR_ROLE_UNKNOWN;
404
405 info->block_size     = data[2];
406 info->pre_underruns  = data[3];
407 info->post_underruns = data[4];
408 info->codec          = data[5];
409 info->flags          = data[6];
410 info->delay          = data[7]*1000;
411
412 if ( m.datalen < 9*2 ) {
413  info->state         = ROAR_STREAMSTATE_UNKNOWN;
414  return 0;
415 } else {
416  info->state         = data[8];
417 }
418
419 if ( m.datalen < 10*2 ) {
420  return 0;
421 } else {
422  info->flags        |= ((uint32_t)data[9]) << 16;
423 }
424
425 if ( m.datalen < 11*2 ) {
426  return 0;
427 } else {
428  info->mixer         = data[10];
429 }
430
431 if ( m.datalen < 12*2 ) {
432  return 0;
433 } else {
434  info->role          = data[11];
435 }
436
437 return 0;
438}
439
440int roar_stream_get_name (struct roar_connection * con, struct roar_stream * s, char * name, size_t len) {
441 struct roar_message m;
442 uint16_t * data = (uint16_t *) m.data;
443
444 if ( con == NULL || s == NULL || name == NULL || len == 0 )
445  return -1;
446
447 name[0] = 0; // just in case...
448
449 m.cmd     = ROAR_CMD_GET_STREAM_PARA;
450 m.stream  = s->id;
451 m.datalen = 4;
452 m.pos     = 0;
453
454 data[0] = 0; // Version and reserved
455 data[1] = ROAR_STREAM_PARA_NAME; // stream
456
457 data[0] = ROAR_HOST2NET16(data[0]);
458 data[1] = ROAR_HOST2NET16(data[1]);
459
460 ROAR_DBG("roar_stream_get_name(*) = ?");
461
462 if ( roar_req(con, &m, NULL) == -1 )
463  return -1;
464
465 ROAR_DBG("roar_stream_get_name(*) = ?");
466
467 if ( m.cmd != ROAR_CMD_OK )
468  return -1;
469
470 ROAR_DBG("roar_stream_get_name(*) = ?");
471
472 if ( m.datalen < 4 )
473  return -1;
474
475 data[0] = ROAR_NET2HOST16(data[0]);
476 data[1] = ROAR_NET2HOST16(data[1]);
477
478 ROAR_DBG("roar_stream_get_name(*) = ?");
479
480 if ( data[0] != 0 || data[1] != ROAR_STREAM_PARA_NAME )
481  return -1;
482
483 m.datalen -= 4;
484
485 len--;
486
487 if ( len > m.datalen )
488  len = m.datalen;
489
490 strncpy(name, ((char*)m.data)+4, len);
491 name[len] = 0;
492
493 ROAR_DBG("roar_stream_get_name(*) = 0");
494
495 return 0;
496}
497
498int roar_stream_get_chanmap (struct roar_connection * con, struct roar_stream * s, char * map, size_t * len) {
499 struct roar_message m;
500 uint16_t * data = (uint16_t *) m.data;
501
502 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p, map=%p, len=%p) = ?", con, s, map, len);
503
504 if ( con == NULL || s == NULL || map == NULL || len == NULL )
505  return -1;
506
507 if ( *len == 0 )
508  return -1;
509
510 memset(&m, 0, sizeof(m));
511
512 m.cmd     = ROAR_CMD_GET_STREAM_PARA;
513 m.stream  = s->id;
514 m.datalen = 2*2;
515
516 data[0] = 0; // Version and reserved
517 data[1] = ROAR_STREAM_PARA_CHANMAP;
518
519 data[0] = ROAR_HOST2NET16(data[0]);
520 data[1] = ROAR_HOST2NET16(data[1]);
521
522 if ( roar_req(con, &m, NULL) == -1 )
523  return -1;
524
525 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len);
526
527 if ( m.cmd != ROAR_CMD_OK )
528  return -1;
529
530 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len);
531
532 if ( m.datalen < 4 )
533  return -1;
534
535 data[0] = ROAR_NET2HOST16(data[0]);
536 data[1] = ROAR_NET2HOST16(data[1]);
537
538 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len);
539
540 if ( data[0] != 0 || data[1] != ROAR_STREAM_PARA_CHANMAP )
541  return -1;
542
543 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len);
544
545 m.datalen -= 4;
546
547 if ( m.datalen > *len )
548  return -1;
549
550 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = ?", con, s, s->id, map, len);
551
552 memcpy(map, &(m.data[4]), m.datalen);
553
554 *len = m.datalen;
555
556 ROAR_DBG("roar_stream_get_chanmap(con=%p, s=%p{.id=%i}, map=%p, len=%p) = 0", con, s, s->id, map, len);
557 return 0;
558}
559
560int roar_stream_set_chanmap (struct roar_connection * con, struct roar_stream * s, char * map, size_t   len) {
561 struct roar_message m;
562 uint16_t * data = (uint16_t *) m.data;
563
564 if ( con == NULL || s == NULL || map == NULL )
565  return -1;
566
567 if ( len == 0 )
568  return 0;
569
570 memset(&m, 0, sizeof(m));
571
572 m.cmd     = ROAR_CMD_SET_STREAM_PARA;
573 m.stream  = s->id;
574 m.datalen = 2*2 + len;
575
576 if ( m.datalen > sizeof(m.data) )
577  return -1;
578
579 data[0] = 0; // Version and reserved
580 data[1] = ROAR_STREAM_PARA_CHANMAP;
581
582 data[0] = ROAR_HOST2NET16(data[0]);
583 data[1] = ROAR_HOST2NET16(data[1]);
584
585 memcpy(&(m.data[4]), map, len);
586
587 if ( roar_req(con, &m, NULL) == -1 )
588  return -1;
589
590 if ( m.cmd != ROAR_CMD_OK )
591  return -1;
592
593 return 0;
594}
595
596
597int roar_stream_set_flags (struct roar_connection * con, struct roar_stream * s, int flags, int reset) {
598 struct roar_message m;
599 uint16_t * data = (uint16_t *) m.data;
600 int i;
601
602 m.cmd     = ROAR_CMD_SET_STREAM_PARA;
603 m.stream  = s->id;
604 m.datalen = 8;
605 m.pos     = 0;
606
607 data[0] = 0; // Version and reserved
608 data[1] = ROAR_STREAM_PARA_FLAGS; // flags
609 data[2] = reset == ROAR_RESET_FLAG ? ROAR_RESET_FLAG : ROAR_SET_FLAG;
610 data[3] = flags;
611
612 for (i = 0; i < m.datalen/2; i++) {
613  data[i] = ROAR_HOST2NET16(data[i]);
614 }
615
616 if ( roar_req(con, &m, NULL) == -1 )
617  return -1;
618
619 if ( m.cmd != ROAR_CMD_OK )
620  return -1;
621
622 return 0;
623}
624
625int roar_stream_set_role  (struct roar_connection * con, struct roar_stream * s, int role) {
626 struct roar_message m;
627 uint16_t * data = (uint16_t *) m.data;
628 int i;
629
630 m.cmd     = ROAR_CMD_SET_STREAM_PARA;
631 m.stream  = s->id;
632 m.datalen = 6;
633 m.pos     = 0;
634
635 data[0] = 0; // Version and reserved
636 data[1] = ROAR_STREAM_PARA_ROLE; // flags
637 data[2] = role;
638
639 for (i = 0; i < m.datalen/2; i++) {
640  data[i] = ROAR_HOST2NET16(data[i]);
641 }
642
643 if ( roar_req(con, &m, NULL) == -1 )
644  return -1;
645
646 if ( m.cmd != ROAR_CMD_OK )
647  return -1;
648
649 return 0;
650}
651
652#define _ROAR_STREAM_MESSAGE_LEN ((5+1)*4)
653
654int roar_stream_s2m     (struct roar_stream * s, struct roar_message * m) {
655 uint32_t * data;
656 int i;
657
658 if ( !(s && m) )
659  return -1;
660
661 m->datalen = _ROAR_STREAM_MESSAGE_LEN;
662 data = (uint32_t*) m->data;
663
664 data[0] = s->dir;
665 data[1] = s->pos_rel_id;
666 data[2] = s->info.rate;
667 data[3] = s->info.bits;
668 data[4] = s->info.channels;
669 data[5] = s->info.codec;
670
671 for (i = 0; i < _ROAR_STREAM_MESSAGE_LEN/4; i++)
672  data[i] = ROAR_HOST2NET32(data[i]);
673
674 ROAR_DBG("roar_stream_s2m(*): s->info:");
675 roar_debug_audio_info_print(&s->info);
676
677 m->pos = s->pos;
678
679 return 0;
680}
681int roar_stream_m2s     (struct roar_stream * s, struct roar_message * m) {
682 uint32_t * data;
683 int i;
684
685 if ( !(s && m) )
686  return -1;
687
688 if ( m->datalen != _ROAR_STREAM_MESSAGE_LEN )
689  return -1;
690
691 s->pos = m->pos;
692
693 data = (uint32_t*) m->data;
694
695 for (i = 0; i < _ROAR_STREAM_MESSAGE_LEN/4; i++)
696  data[i] = ROAR_NET2HOST32(data[i]);
697
698 s->id            = m->stream;
699 s->dir           = data[0];
700 s->pos_rel_id    = data[1];
701 s->info.rate     = data[2];
702 s->info.bits     = data[3];
703 s->info.channels = data[4];
704 s->info.codec    = data[5];
705
706 ROAR_DBG("roar_stream_m2s(*): s->info:");
707 roar_debug_audio_info_print(&s->info);
708
709 return 0;
710}
711
712// stream direction funcs:
713/*
714#define roar_dir2str(x)   ((x) == ROAR_DIR_PLAY   ? "play"   : (x) == ROAR_DIR_MONITOR ? "monitor" : \
715                           (x) == ROAR_DIR_FILTER ? "filter" : (x) == ROAR_DIR_RECORD  ? "record"  : \
716                           (x) == ROAR_DIR_OUTPUT ? "output" : (x) == ROAR_DIR_BIDIR   ? "bidir"   : \
717                           (x) == ROAR_DIR_MIXING ? "mixing" : \
718                           "unknown")
719*/
720
721struct {
722 int    dir;
723 char * name;
724} _libroar_dir[] = {
725 {ROAR_DIR_PLAY,        "play"       },
726 {ROAR_DIR_RECORD,      "record"     },
727 {ROAR_DIR_MONITOR,     "monitor"    },
728 {ROAR_DIR_FILTER,      "filter"     },
729 {ROAR_DIR_OUTPUT,      "output"     },
730 {ROAR_DIR_MIXING,      "mixing"     },
731 {ROAR_DIR_META,        "meta"       },
732 {ROAR_DIR_BIDIR,       "bidir"      },
733 {ROAR_DIR_THRU,        "thru"       },
734 {ROAR_DIR_BRIDGE,      "bridge"     },
735 {ROAR_DIR_MIDI_IN,     "midi_in"    },
736 {ROAR_DIR_MIDI_OUT,    "midi_out"   },
737 {ROAR_DIR_LIGHT_IN,    "light_in"   },
738 {ROAR_DIR_LIGHT_OUT,   "light_out"  },
739 {ROAR_DIR_RAW_IN,      "raw_in"     },
740 {ROAR_DIR_RAW_OUT,     "raw_out"    },
741 {ROAR_DIR_COMPLEX_IN,  "complex_in" },
742 {ROAR_DIR_COMPLEX_OUT, "complex_out"},
743 {ROAR_DIR_RDTCS_IN,    "rdtcs_in"   },
744 {ROAR_DIR_RDTCS_OUT,   "rdtcs_out"  },
745 {-1,                   "unknown"    }
746};
747
748char * roar_dir2str (int dir) {
749 int i;
750
751 for (i = 0; _libroar_dir[i].dir != -1; i++)
752  if ( _libroar_dir[i].dir == dir )
753   return _libroar_dir[i].name;
754
755 return _libroar_dir[i].name;
756}
757
758int roar_str2dir (char * name) {
759 int i;
760
761 for (i = 0; _libroar_dir[i].dir != -1; i++)
762  if ( !strcmp(_libroar_dir[i].name, name) )
763   return _libroar_dir[i].dir;
764
765 return _libroar_dir[i].dir;
766}
767
768// codec funcs:
769
770/*
771#define roar_codec2str(x) ((x) == ROAR_CODEC_PCM_S_LE  ? "pcm_s_le"  : (x) == ROAR_CODEC_PCM_S_BE  ? "pcm_s_be"  : \
772                           (x) == ROAR_CODEC_PCM_S_PDP ? "pcm_s_pdp" : (x) == ROAR_CODEC_MIDI_FILE ? "midi_file" : \
773                           "unknown" )
774*/
775
776struct {
777 int    codec;
778 char * name;
779} _libroar_codec[] = {
780 // PCM:
781 {ROAR_CODEC_PCM_S_LE,    "pcm_s_le"   },
782 {ROAR_CODEC_PCM_S_BE,    "pcm_s_be"   },
783 {ROAR_CODEC_PCM_S_PDP,   "pcm_s_pdp"  },
784 {ROAR_CODEC_PCM_U_LE,    "pcm_u_le"   },
785 {ROAR_CODEC_PCM_U_BE,    "pcm_u_be"   },
786 {ROAR_CODEC_PCM_U_PDP,   "pcm_u_pdp"  },
787 {ROAR_CODEC_DEFAULT,     "default"    }, // alias
788 {ROAR_CODEC_DEFAULT,     "pcm"        }, // alias
789 {ROAR_CODEC_DEFAULT,     "raw"        }, // alias
790
791 // MIDI:
792 {ROAR_CODEC_MIDI_FILE,   "midi_file"  },
793 {ROAR_CODEC_MIDI,        "midi"       },
794
795 // XIPH:
796 {ROAR_CODEC_OGG_VORBIS,  "ogg_vorbis" },
797 {ROAR_CODEC_OGG_VORBIS,  "vorbis"     }, // alias
798 {ROAR_CODEC_FLAC,        "flac"       },
799 {ROAR_CODEC_OGG_SPEEX,   "ogg_speex"  },
800 {ROAR_CODEC_OGG_SPEEX,   "speex"      }, // alias
801 {ROAR_CODEC_OGG_FLAC,    "ogg_flac"   },
802 {ROAR_CODEC_OGG_GENERAL, "ogg_general"},
803 {ROAR_CODEC_OGG_CELT,    "ogg_celt"   },
804 {ROAR_CODEC_OGG,         "ogg"        },
805 {ROAR_CODEC_ROAR_CELT,   "roar_celt"  },
806 {ROAR_CODEC_ROAR_SPEEX,  "roar_speex" },
807
808 // RAUM:
809 {ROAR_CODEC_RAUM,        "raum"       },
810 {ROAR_CODEC_RAUM_VORBIS, "raum_vorbis"},
811 {ROAR_CODEC_RAUM_FLAC,   "raum_flac"  },
812
813 // RIFF/WAVE like:
814 {ROAR_CODEC_RIFF_WAVE,   "riff_wave"  },
815 {ROAR_CODEC_RIFF_WAVE,   "wave"       }, // alias
816 {ROAR_CODEC_RIFF_WAVE,   "wav"        }, // alias
817
818 //Log codecs:
819 {ROAR_CODEC_ALAW,        "alaw"       },
820 {ROAR_CODEC_MULAW,       "mulaw"      },
821 {ROAR_CODEC_MULAW,       "ulaw"       }, // alias
822
823 // Meta Codecs:
824 {ROAR_CODEC_META_VCLT,     "meta_vclt"    },
825 {ROAR_CODEC_META_RALT,     "meta_ralt"    },
826 {ROAR_CODEC_META_RALB,     "meta_ralb"    },
827 {ROAR_CODEC_META_RALB_LE,  "meta_ralb_le" },
828 {ROAR_CODEC_META_RALB_BE,  "meta_ralb_be" },
829 {ROAR_CODEC_META_RALB_PDP, "meta_ralb_pdp"},
830
831 // light control:
832 {ROAR_CODEC_DMX512,      "dmx512"     },
833 {ROAR_CODEC_ROARDMX,     "roardmx"    },
834
835 // Radio Data and Transmitter Control System:
836 {ROAR_CODEC_RDS,         "rds"        },
837
838 // User specific:
839 {ROAR_CODEC_USER0,       "user0"      },
840 {ROAR_CODEC_USER1,       "user1"      },
841 {ROAR_CODEC_USER2,       "user2"      },
842 {ROAR_CODEC_USER3,       "user3"      },
843 {ROAR_CODEC_USER4,       "user4"      },
844 {ROAR_CODEC_USER5,       "user5"      },
845 {ROAR_CODEC_USER6,       "user6"      },
846 {ROAR_CODEC_USER7,       "user7"      },
847 {ROAR_CODEC_USER8,       "user8"      },
848 {ROAR_CODEC_USER9,       "user9"      },
849 {ROAR_CODEC_USER10,      "user10"     },
850 {ROAR_CODEC_USER11,      "user11"     },
851 {ROAR_CODEC_USER12,      "user12"     },
852 {ROAR_CODEC_USER13,      "user13"     },
853 {ROAR_CODEC_USER14,      "user14"     },
854 {ROAR_CODEC_USER15,      "user15"     },
855 {-1, NULL}
856};
857
858int roar_str2codec(char * codec) {
859 int i;
860 int guess;
861
862 if ( codec == NULL || *codec == 0 )
863  return ROAR_CODEC_DEFAULT;
864
865 if ( (guess = atoi(codec)) > 0 )
866  return guess;
867
868 if ( codec == NULL || *codec == 0 )
869  return ROAR_CODEC_DEFAULT;
870
871 for (i = 0; _libroar_codec[i].codec != -1; i++)
872  if ( strcasecmp(_libroar_codec[i].name, codec) == 0 )
873   return _libroar_codec[i].codec;
874
875 return -1;
876}
877
878
879char * roar_codec2str (int codec) {
880 int i;
881
882 for (i = 0; _libroar_codec[i].codec != -1; i++)
883  if ( _libroar_codec[i].codec == codec )
884   return _libroar_codec[i].name;
885
886 return "unknown";
887}
888
889char * roar_streamstate2str(int streamstate) {
890 switch (streamstate) {
891  case ROAR_STREAMSTATE_UNUSED:  return "unused";  break;
892  case ROAR_STREAMSTATE_INITING: return "initing"; break;
893  case ROAR_STREAMSTATE_NEW:     return "new";     break;
894  case ROAR_STREAMSTATE_OLD:     return "old";     break;
895  case ROAR_STREAMSTATE_CLOSING: return "closing"; break;
896 }
897
898 return "unknown";
899}
900
901struct {
902 int    role;
903 char * name;
904} _libroar_role[] = {
905 {ROAR_ROLE_UNKNOWN,          "unknown"         },
906 {ROAR_ROLE_NONE,             "none"            },
907 {ROAR_ROLE_MUSIC,            "music"           },
908 {ROAR_ROLE_VIDEO,            "video"           },
909 {ROAR_ROLE_GAME,             "game"            },
910 {ROAR_ROLE_EVENT,            "event"           },
911 {ROAR_ROLE_BEEP,             "beep"            },
912 {ROAR_ROLE_PHONE,            "phone"           },
913 {ROAR_ROLE_BACKGROUND_MUSIC, "background music"},
914 {ROAR_ROLE_BACKGROUND_MUSIC, "background_music"}, // alias
915 {ROAR_ROLE_VOICE,            "voice"           },
916 {ROAR_ROLE_INSTRUMENT,       "instrument"      },
917 {ROAR_ROLE_RHYTHM,           "rhythm"          },
918 {ROAR_ROLE_CLICK,            "click",          },
919 {ROAR_ROLE_MIXED,            "mixed",          },
920 {-1, NULL}
921};
922
923int    roar_str2role  (char * role) {
924 int i;
925
926 for (i = 0; _libroar_role[i].name != NULL; i++)
927  if ( !strcasecmp(_libroar_role[i].name, role) )
928   return _libroar_role[i].role;
929
930 return ROAR_ROLE_UNKNOWN;
931}
932
933char * roar_role2str  (int    role) {
934 int i;
935
936 for (i = 0; _libroar_role[i].name != NULL; i++)
937  if ( _libroar_role[i].role == role )
938   return _libroar_role[i].name;
939
940 return "unknown";
941}
942
943ssize_t roar_info2samplesize (struct roar_audio_info * info) {
944 if ( info == NULL )
945  return -1;
946
947 switch (info->codec) {
948  case ROAR_CODEC_PCM_S_LE:
949  case ROAR_CODEC_PCM_S_BE:
950  case ROAR_CODEC_PCM_S_PDP:
951  case ROAR_CODEC_PCM_U_LE:
952  case ROAR_CODEC_PCM_U_BE:
953  case ROAR_CODEC_PCM_U_PDP:
954    return info->bits;
955   break;
956  case ROAR_CODEC_ALAW:
957  case ROAR_CODEC_MULAW:
958    return 8;
959   break;
960  case ROAR_CODEC_DMX512:
961    return 8;
962   break;
963  case ROAR_CODEC_RDS:
964    return 26;
965   break;
966  default:
967    return -1;
968   break;
969 }
970}
971
972ssize_t roar_info2framesize  (struct roar_audio_info * info) {
973 ssize_t ret = roar_info2samplesize(info);
974
975 if ( ret == -1 )
976  return -1;
977
978 ret *= info->channels;
979
980 return ret;
981}
982
983ssize_t roar_info2bitspersec(struct roar_audio_info * info) {
984 ssize_t ret = roar_info2samplesize(info);
985
986 if ( ret == -1 )
987  return -1;
988
989 ret *= info->channels * info->rate;
990
991 return ret;
992}
993
994//ll
Note: See TracBrowser for help on using the repository browser.