Changeset 4852:166a9cc557c9 in roaraudio for roard
- Timestamp:
- 04/10/11 02:12:57 (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- roard
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
roard/hwmixer.c
r4752 r4852 231 231 } 232 232 233 int hwmixer_add (char * drv, char * dev, char * opts, int prim, int count) { 234 char * basename = NULL; 235 char * subnames = NULL; 236 char * k, * v; 237 int basestream = streams_new(); 238 int ret; 239 int error = 0; 240 //int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) { 241 242 if ( basestream == -1 ) 243 return -1; 244 245 client_stream_add(g_self_client, basestream); 246 247 if ( opts == NULL ) { 248 k = NULL; 249 } else { 250 k = strtok(opts, ","); 251 } 252 253 while (k != NULL) { 254 // ROAR_WARN("add_output(*): opts: %s", k); 255 256 if ( (v = strstr(k, "=")) != NULL ) { 257 *v++ = 0; 258 } 259 260 if ( strcmp(k, "primary") == 0 ) { 261 prim = 1; 262 263 } else if ( strcmp(k, "name") == 0 ) { 264 basename = v; 265 } else if ( strcmp(k, "subs") == 0 ) { 266 subnames = v; 267 268 } else if ( strcmp(k, "autoconf") == 0 ) { 269 streams_set_flag(basestream, ROAR_FLAG_AUTOCONF); 270 } else if ( strcmp(k, "passmixer") == 0 ) { 271 streams_set_flag(basestream, ROAR_FLAG_PASSMIXER); 272 } else { 273 ROAR_ERR("add_hwmixer(*): unknown option '%s'", k); 274 error++; 275 } 276 277 if ( error ) { 278 streams_delete(basestream); 279 if ( prim ) alive = 0; 280 return -1; 281 } 282 283 k = strtok(NULL, ","); 284 } 285 286 if ( prim ) { 287 streams_mark_primary(basestream); 288 } 289 290 ret = hwmixer_open(basestream, drv, dev, -1, basename, subnames); 291 292 if ( ret == -1 ) { 293 streams_delete(basestream); 294 } 295 296 return ret == -1 ? -1 : 0; 297 } 298 233 299 #endif 234 300 -
roard/include/hwmixer.h
r4708 r4852 51 51 struct hwmixer_stream * hwmixer_substream_new(struct hwmixer_stream * parent); 52 52 53 int hwmixer_add (char * drv, char * dev, char * opts, int prim, int count); 54 55 53 56 // Mixers: 54 57 -
roard/include/output.h
r4814 r4852 77 77 int output_buffer_free (void); 78 78 79 int output_add (char * drv, char * dev, char * opts, int prim, int count); 80 int output_add_default (char * drv, char * dev, char * opts, int prim, int count); 81 79 82 #endif 80 83 -
roard/output.c
r4814 r4852 87 87 } 88 88 89 90 91 92 93 94 #ifdef ROAR_DRIVER_DEFAULT 95 int output_add_default (char * drv, char * dev, char * opts, int prim, int count) { 96 return output_add(drv, dev, opts, prim, count); 97 } 98 #else 99 int output_add_default (char * drv, char * dev, char * opts, int prim, int count) { 100 char * drvs[] = { 101 // operating system depended things: 102 #ifdef __OpenBSD__ 103 /* OpenBSD use sndio natively, this check is discusses with upstream (See ML archive August 2010) */ 104 "sndio", 105 #endif 106 // native and pseudo-native interfaces: 107 "oss", "alsa", "sndio", "wmm", 108 // sound libs: 109 "ao", "portaudio", 110 // other sound systems: 111 "esd", "rsound", "pulsesimple", "roar", 112 // specal buildins: 113 "sysclock", "null", 114 // terminator: 115 NULL 116 }; 117 int i; 118 int ret; 119 int _alive; 120 char * _opts; 121 122 if ( drv != NULL ) 123 return output_add(drv, dev, opts, prim, count); 124 125 if ( dev != NULL ) { 126 ROAR_WARN("add_default_output(drv=(none), dev='%s', opts='%s', prim=%i, count=%i): It's not recommended to use device name without driver name.", dev, opts, prim, count); 127 } 128 129 for (i = 0; drvs[i] != NULL; i++) { 130 ROAR_INFO("add_default_output(*): trying driver %s", ROAR_DBG_INFO_INFO, drvs[i]); 131 _alive = alive; // save global alive setting 132 133 if ( opts == NULL ) { 134 _opts = NULL; 135 } else { 136 _opts = roar_mm_strdup(opts); 137 } 138 139 ret = output_add(drvs[i], dev, _opts, prim, count); 140 141 if ( _opts != NULL ) 142 roar_mm_free(_opts); 143 144 if ( ret != -1 ) 145 return ret; 146 147 alive = _alive; // restore global alive setting 148 ROAR_INFO("add_default_output(*): Driver %s faild to load", ROAR_DBG_INFO_VERBOSE, drvs[i]); 149 } 150 151 return -1; 152 } 153 #endif 154 155 156 #define _CKPARAM(n) if ( n (v == NULL) ) { \ 157 ROAR_WARN("add_output(drv='%s', dev='%s', opts=..., prim=%i, count=%i): " \ 158 "Parameter '%s' expects %s parameter.", \ 159 drv, dev, prim, count, k, (n 1) ? "a" : "no"); \ 160 error++; \ 161 } else 162 163 int output_add (char * drv, char * dev, char * opts, int prim, int count) { 164 int stream; 165 int default_flags; 166 struct roar_stream * s; 167 struct roar_stream_server * ss; 168 char * k, * v; 169 #ifdef ROAR_DRIVER_CODEC 170 char * to_free = NULL; 171 #endif 172 int sync = 0, f_mmap = 0; 173 int32_t blocks = -1, blocksize = -1; 174 int dir = ROAR_DIR_OUTPUT; 175 int error = 0; 176 // DMX: 177 int32_t channel = -1; 178 int32_t universe = -1; 179 uint16_t tu16; 180 float q = -32e6; 181 182 ROAR_INFO("add_output(drv='%s', dev='%s', opts='%s', prim=%i, count=%i): trying to add output driver", ROAR_DBG_INFO_INFO, drv, dev, opts, prim, count); 183 184 if ( drv == NULL && count == 0 ) { 185 #ifdef ROAR_DRIVER_DEFAULT 186 drv = ROAR_DRIVER_DEFAULT; 187 prim = 1; 188 sync = 1; 189 190 #ifdef ROAR_DRIVER_CODEC 191 if ( opts == NULL ) { 192 opts = to_free = strdup("codec=" ROAR_DRIVER_CODEC); 193 } 194 #endif 195 #else 196 ROAR_ERR("add_output(*): Can not find default driver"); 197 return -1; 198 #endif 199 } 200 201 if ( opts == NULL && count == 0 ) { 202 default_flags = ROAR_FLAG_AUTOCONF|ROAR_FLAG_RECSOURCE; 203 sync = 1; 204 prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 1 205 } 206 207 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); 208 209 if ( (stream = streams_new()) == -1 ) { 210 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts); 211 if ( prim ) alive = 0; 212 return -1; 213 } 214 215 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); 216 217 streams_get(stream, &ss); 218 s = ROAR_STREAM(ss); 219 220 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); 221 222 memset(&(s->info), 0xFF, sizeof(struct roar_audio_info)); // set everything to -1 223 224 s->pos_rel_id = -1; 225 // s->info.codec = codec; 226 227 // seting default flags: 228 streams_set_flag(stream, default_flags); 229 230 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); 231 232 if ( opts == NULL ) { 233 k = NULL; 234 } else { 235 k = strtok(opts, ","); 236 } 237 238 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s'): initial k='%s'(%p)", drv, dev, opts, k, k); 239 240 while (k != NULL) { 241 // ROAR_WARN("add_output(*): opts: %s", k); 242 243 if ( (v = strstr(k, "=")) != NULL ) { 244 *v++ = 0; 245 } 246 247 ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v); 248 if ( strcmp(k, "rate") == 0 ) { 249 _CKPARAM() 250 s->info.rate = atoi(v); 251 } else if ( strcmp(k, "channels") == 0 ) { 252 _CKPARAM() 253 s->info.channels = atoi(v); 254 } else if ( strcmp(k, "bits") == 0 ) { 255 _CKPARAM() 256 s->info.bits = atoi(v); 257 } else if ( strcmp(k, "codec") == 0 ) { 258 _CKPARAM() 259 if ( (s->info.codec = roar_str2codec(v)) == -1 ) { 260 ROAR_ERR("add_output(*): unknown codec '%s'", v); 261 error++; 262 } 263 } else if ( strcmp(k, "q") == 0 ) { 264 _CKPARAM() 265 q = atof(v); 266 } else if ( strcmp(k, "blocks") == 0 ) { 267 _CKPARAM() 268 blocks = atoi(v); 269 } else if ( strcmp(k, "blocksize") == 0 ) { 270 _CKPARAM() 271 blocksize = atoi(v); 272 } else if ( strcmp(k, "mmap") == 0 ) { 273 _CKPARAM(!) 274 f_mmap = 1; 275 } else if ( strcmp(k, "subsystem") == 0 ) { 276 _CKPARAM() { 277 if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) { 278 dir = ROAR_DIR_OUTPUT; 279 #ifndef ROAR_WITHOUT_DCOMP_MIDI 280 } else if ( !strcasecmp(v, "midi") ) { 281 dir = ROAR_DIR_MIDI_OUT; 282 #endif 283 #ifndef ROAR_WITHOUT_DCOMP_LIGHT 284 } else if ( !strcasecmp(v, "light") ) { 285 dir = ROAR_DIR_LIGHT_OUT; 286 #endif 287 #ifndef ROAR_WITHOUT_DCOMP_RAW 288 } else if ( !strcasecmp(v, "raw") ) { 289 dir = ROAR_DIR_RAW_OUT; 290 #endif 291 } else if ( !strcasecmp(v, "complex") ) { 292 dir = ROAR_DIR_COMPLEX_OUT; 293 } else { 294 ROAR_ERR("add_output(*): unknown/unsupported subsystem '%s'", k); 295 error++; 296 } 297 } 298 // DMX: 299 } else if ( strcmp(k, "channel") == 0 ) { 300 _CKPARAM() { 301 channel = atoi(v); 302 if ( channel < 0 || channel > 65535 ) { 303 ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel); 304 channel = -1; 305 error++; 306 } 307 } 308 } else if ( strcmp(k, "universe") == 0 ) { 309 _CKPARAM() { 310 universe = atoi(v); 311 if ( universe < 0 || universe > 255 ) { 312 ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe); 313 universe = -1; 314 error++; 315 } 316 } 317 318 } else if ( strcmp(k, "name") == 0 ) { 319 _CKPARAM() { 320 if ( streams_set_name(stream, v) == -1 ) { 321 ROAR_ERR("add_output(*): Can not set Stream name"); 322 error++; 323 } 324 } 325 326 } else if ( strcmp(k, "meta") == 0 ) { 327 _CKPARAM(!) 328 streams_set_flag(stream, ROAR_FLAG_META); 329 } else if ( strcmp(k, "sync") == 0 ) { 330 _CKPARAM(!) 331 sync = 1; 332 } else if ( strcmp(k, "primary") == 0 ) { 333 _CKPARAM(!) 334 prim = 1; 335 336 } else if ( strcmp(k, "cleanmeta") == 0 ) { 337 _CKPARAM(!) 338 streams_set_flag(stream, ROAR_FLAG_CLEANMETA); 339 } else if ( strcmp(k, "autoconf") == 0 ) { 340 _CKPARAM(!) 341 streams_set_flag(stream, ROAR_FLAG_AUTOCONF); 342 } else if ( strcmp(k, "recsource") == 0 ) { 343 _CKPARAM(!) 344 streams_set_flag(stream, ROAR_FLAG_RECSOURCE); 345 } else if ( strcmp(k, "passmixer") == 0 ) { 346 _CKPARAM(!) 347 streams_set_flag(stream, ROAR_FLAG_PASSMIXER); 348 } else if ( strcmp(k, "recsource") == 0 ) { 349 _CKPARAM(!) 350 streams_set_flag(stream, ROAR_FLAG_RECSOURCE); 351 } else { 352 ROAR_ERR("add_output(*): unknown option '%s'", k); 353 error++; 354 } 355 356 if ( error ) { 357 streams_delete(stream); 358 if ( prim ) alive = 0; 359 #ifdef ROAR_DRIVER_CODEC 360 if ( to_free != NULL ) 361 free(to_free); 362 #endif 363 return -1; 364 } 365 366 k = strtok(NULL, ","); 367 } 368 369 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts); 370 371 // set audio info... 372 switch (dir) { 373 case ROAR_DIR_LIGHT_OUT: 374 switch (s->info.codec) { 375 case ROAR_CODEC_DMX512: 376 case -1: 377 if ( s->info.rate == -1 ) 378 s->info.rate = ROAR_OUTPUT_CFREQ; 379 380 s->info.channels = 0; 381 s->info.bits = 8; 382 s->info.codec = ROAR_CODEC_DMX512; // in case codec == -1 383 break; 384 } 385 break; 386 case ROAR_DIR_MIDI_OUT: 387 switch (s->info.codec) { 388 case ROAR_CODEC_MIDI: 389 case -1: 390 if ( s->info.rate == -1 ) 391 s->info.rate = ROAR_MIDI_TICKS_PER_BEAT; 392 393 s->info.channels = ROAR_MIDI_CHANNELS_DEFAULT; 394 s->info.bits = ROAR_MIDI_BITS; 395 s->info.codec = ROAR_CODEC_MIDI; // in case codec == -1 396 break; 397 } 398 break; 399 case ROAR_DIR_RAW_OUT: 400 if ( s->info.rate == -1 ) 401 s->info.rate = 0; 402 if ( s->info.bits == -1 ) 403 s->info.bits = 0; 404 if ( s->info.channels == -1 ) 405 s->info.channels = 0; 406 if ( s->info.codec == -1 ) 407 s->info.codec = 0; 408 break; 409 } 410 411 if ( s->info.rate == -1 ) 412 s->info.rate = g_sa->rate; 413 if ( s->info.bits == -1 ) 414 s->info.bits = g_sa->bits; 415 if ( s->info.channels == -1 ) 416 s->info.channels = g_sa->channels; 417 if ( s->info.codec == -1 ) 418 s->info.codec = g_sa->codec; 419 420 ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec); 421 422 if ( streams_set_dir(stream, dir, 1) == -1 ) { 423 streams_delete(stream); 424 return -1; 425 } 426 427 #ifdef ROAR_DRIVER_CODEC 428 if ( to_free != NULL ) 429 free(to_free); 430 #endif 431 432 if ( s->info.codec == ROAR_CODEC_ALAW || s->info.codec == ROAR_CODEC_MULAW ) 433 s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter 434 435 ROAR_STREAM_SERVER(s)->codec_orgi = s->info.codec; 436 437 if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) { 438 ss->driver_id = -1; // don't close a driver not opened... 439 memset(&(ss->vio), 0, sizeof(struct roar_vio_calls)); 440 streams_delete(stream); 441 if ( prim ) alive = 0; 442 ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not open output driver.", drv, dev, opts); 443 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts); 444 return -1; 445 } 446 447 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here 448 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM, s); // ignore errors here 449 450 if ( blocks != -1 ) 451 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks); 452 453 if ( blocksize != -1 ) 454 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize); 455 456 // TODO: we shoudld *really* check for errors here... 457 if ( channel != -1 ) { 458 tu16 = channel; 459 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16); 460 } 461 if ( universe != -1 ) { 462 tu16 = universe; 463 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16); 464 } 465 466 ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id); 467 468 streams_set_fh(stream, -1); // update some internal structures 469 470 if ( q > -1e6 ) { 471 ROAR_DBG("add_output(*): setting q=%f", q); 472 streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q); 473 } 474 475 client_stream_add(g_self_client, stream); 476 477 if ( prim ) { 478 streams_mark_primary(stream); 479 s->pos_rel_id = stream; 480 } 481 482 if ( sync ) { 483 streams_set_flag(stream, ROAR_FLAG_SYNC); 484 } else { 485 streams_reset_flag(stream, ROAR_FLAG_SYNC); 486 } 487 488 if ( f_mmap ) 489 streams_set_flag(stream, ROAR_FLAG_MMAP); 490 491 ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec); 492 return 0; 493 } 494 89 495 //ll -
roard/roard.c
r4851 r4852 56 56 char * x11display = NULL; 57 57 #endif 58 59 int add_output (char * drv, char * dev, char * opts, int prim, int count);60 58 61 59 void dbg_notify_cb(struct roar_notify_core * core, struct roar_event * event, void * userdata) { … … 965 963 } 966 964 967 #ifdef ROAR_DRIVER_DEFAULT968 #define add_default_output add_output969 #else970 int add_default_output (char * drv, char * dev, char * opts, int prim, int count) {971 char * drvs[] = {972 // operating system depended things:973 #ifdef __OpenBSD__974 /* OpenBSD use sndio natively, this check is discusses with upstream (See ML archive August 2010) */975 "sndio",976 #endif977 // native and pseudo-native interfaces:978 "oss", "alsa", "sndio", "wmm",979 // sound libs:980 "ao", "portaudio",981 // other sound systems:982 "esd", "rsound", "pulsesimple", "roar",983 // specal buildins:984 "sysclock", "null",985 // terminator:986 NULL987 };988 int i;989 int ret;990 int _alive;991 char * _opts;992 993 if ( drv != NULL )994 return add_output(drv, dev, opts, prim, count);995 996 if ( dev != NULL ) {997 ROAR_WARN("add_default_output(drv=(none), dev='%s', opts='%s', prim=%i, count=%i): It's not recommended to use device name without driver name.", dev, opts, prim, count);998 }999 1000 for (i = 0; drvs[i] != NULL; i++) {1001 ROAR_INFO("add_default_output(*): trying driver %s", ROAR_DBG_INFO_INFO, drvs[i]);1002 _alive = alive; // save global alive setting1003 1004 if ( opts == NULL ) {1005 _opts = NULL;1006 } else {1007 _opts = roar_mm_strdup(opts);1008 }1009 1010 ret = add_output(drvs[i], dev, _opts, prim, count);1011 1012 if ( _opts != NULL )1013 roar_mm_free(_opts);1014 1015 if ( ret != -1 )1016 return ret;1017 1018 alive = _alive; // restore global alive setting1019 ROAR_INFO("add_default_output(*): Driver %s faild to load", ROAR_DBG_INFO_VERBOSE, drvs[i]);1020 }1021 1022 return -1;1023 }1024 #endif1025 1026 #define _CKPARAM(n) if ( n (v == NULL) ) { \1027 ROAR_WARN("add_output(drv='%s', dev='%s', opts=..., prim=%i, count=%i): " \1028 "Parameter '%s' expects %s parameter.", \1029 drv, dev, prim, count, k, (n 1) ? "a" : "no"); \1030 error++; \1031 } else1032 1033 int add_output (char * drv, char * dev, char * opts, int prim, int count) {1034 int stream;1035 int default_flags;1036 struct roar_stream * s;1037 struct roar_stream_server * ss;1038 char * k, * v;1039 #ifdef ROAR_DRIVER_CODEC1040 char * to_free = NULL;1041 #endif1042 int sync = 0, f_mmap = 0;1043 int32_t blocks = -1, blocksize = -1;1044 int dir = ROAR_DIR_OUTPUT;1045 int error = 0;1046 // DMX:1047 int32_t channel = -1;1048 int32_t universe = -1;1049 uint16_t tu16;1050 float q = -32e6;1051 1052 ROAR_INFO("add_output(drv='%s', dev='%s', opts='%s', prim=%i, count=%i): trying to add output driver", ROAR_DBG_INFO_INFO, drv, dev, opts, prim, count);1053 1054 if ( drv == NULL && count == 0 ) {1055 #ifdef ROAR_DRIVER_DEFAULT1056 drv = ROAR_DRIVER_DEFAULT;1057 prim = 1;1058 sync = 1;1059 1060 #ifdef ROAR_DRIVER_CODEC1061 if ( opts == NULL ) {1062 opts = to_free = strdup("codec=" ROAR_DRIVER_CODEC);1063 }1064 #endif1065 #else1066 ROAR_ERR("add_output(*): Can not find default driver");1067 return -1;1068 #endif1069 }1070 1071 if ( opts == NULL && count == 0 ) {1072 default_flags = ROAR_FLAG_AUTOCONF|ROAR_FLAG_RECSOURCE;1073 sync = 1;1074 prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 11075 }1076 1077 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1078 1079 if ( (stream = streams_new()) == -1 ) {1080 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);1081 if ( prim ) alive = 0;1082 return -1;1083 }1084 1085 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1086 1087 streams_get(stream, &ss);1088 s = ROAR_STREAM(ss);1089 1090 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1091 1092 memset(&(s->info), 0xFF, sizeof(struct roar_audio_info)); // set everything to -11093 1094 s->pos_rel_id = -1;1095 // s->info.codec = codec;1096 1097 // seting default flags:1098 streams_set_flag(stream, default_flags);1099 1100 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1101 1102 if ( opts == NULL ) {1103 k = NULL;1104 } else {1105 k = strtok(opts, ",");1106 }1107 1108 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s'): initial k='%s'(%p)", drv, dev, opts, k, k);1109 1110 while (k != NULL) {1111 // ROAR_WARN("add_output(*): opts: %s", k);1112 1113 if ( (v = strstr(k, "=")) != NULL ) {1114 *v++ = 0;1115 }1116 1117 ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v);1118 if ( strcmp(k, "rate") == 0 ) {1119 _CKPARAM()1120 s->info.rate = atoi(v);1121 } else if ( strcmp(k, "channels") == 0 ) {1122 _CKPARAM()1123 s->info.channels = atoi(v);1124 } else if ( strcmp(k, "bits") == 0 ) {1125 _CKPARAM()1126 s->info.bits = atoi(v);1127 } else if ( strcmp(k, "codec") == 0 ) {1128 _CKPARAM()1129 if ( (s->info.codec = roar_str2codec(v)) == -1 ) {1130 ROAR_ERR("add_output(*): unknown codec '%s'", v);1131 error++;1132 }1133 } else if ( strcmp(k, "q") == 0 ) {1134 _CKPARAM()1135 q = atof(v);1136 } else if ( strcmp(k, "blocks") == 0 ) {1137 _CKPARAM()1138 blocks = atoi(v);1139 } else if ( strcmp(k, "blocksize") == 0 ) {1140 _CKPARAM()1141 blocksize = atoi(v);1142 } else if ( strcmp(k, "mmap") == 0 ) {1143 _CKPARAM(!)1144 f_mmap = 1;1145 } else if ( strcmp(k, "subsystem") == 0 ) {1146 _CKPARAM() {1147 if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) {1148 dir = ROAR_DIR_OUTPUT;1149 #ifndef ROAR_WITHOUT_DCOMP_MIDI1150 } else if ( !strcasecmp(v, "midi") ) {1151 dir = ROAR_DIR_MIDI_OUT;1152 #endif1153 #ifndef ROAR_WITHOUT_DCOMP_LIGHT1154 } else if ( !strcasecmp(v, "light") ) {1155 dir = ROAR_DIR_LIGHT_OUT;1156 #endif1157 #ifndef ROAR_WITHOUT_DCOMP_RAW1158 } else if ( !strcasecmp(v, "raw") ) {1159 dir = ROAR_DIR_RAW_OUT;1160 #endif1161 } else if ( !strcasecmp(v, "complex") ) {1162 dir = ROAR_DIR_COMPLEX_OUT;1163 } else {1164 ROAR_ERR("add_output(*): unknown/unsupported subsystem '%s'", k);1165 error++;1166 }1167 }1168 // DMX:1169 } else if ( strcmp(k, "channel") == 0 ) {1170 _CKPARAM() {1171 channel = atoi(v);1172 if ( channel < 0 || channel > 65535 ) {1173 ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel);1174 channel = -1;1175 error++;1176 }1177 }1178 } else if ( strcmp(k, "universe") == 0 ) {1179 _CKPARAM() {1180 universe = atoi(v);1181 if ( universe < 0 || universe > 255 ) {1182 ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe);1183 universe = -1;1184 error++;1185 }1186 }1187 1188 } else if ( strcmp(k, "name") == 0 ) {1189 _CKPARAM() {1190 if ( streams_set_name(stream, v) == -1 ) {1191 ROAR_ERR("add_output(*): Can not set Stream name");1192 error++;1193 }1194 }1195 1196 } else if ( strcmp(k, "meta") == 0 ) {1197 _CKPARAM(!)1198 streams_set_flag(stream, ROAR_FLAG_META);1199 } else if ( strcmp(k, "sync") == 0 ) {1200 _CKPARAM(!)1201 sync = 1;1202 } else if ( strcmp(k, "primary") == 0 ) {1203 _CKPARAM(!)1204 prim = 1;1205 1206 } else if ( strcmp(k, "cleanmeta") == 0 ) {1207 _CKPARAM(!)1208 streams_set_flag(stream, ROAR_FLAG_CLEANMETA);1209 } else if ( strcmp(k, "autoconf") == 0 ) {1210 _CKPARAM(!)1211 streams_set_flag(stream, ROAR_FLAG_AUTOCONF);1212 } else if ( strcmp(k, "recsource") == 0 ) {1213 _CKPARAM(!)1214 streams_set_flag(stream, ROAR_FLAG_RECSOURCE);1215 } else if ( strcmp(k, "passmixer") == 0 ) {1216 _CKPARAM(!)1217 streams_set_flag(stream, ROAR_FLAG_PASSMIXER);1218 } else if ( strcmp(k, "recsource") == 0 ) {1219 _CKPARAM(!)1220 streams_set_flag(stream, ROAR_FLAG_RECSOURCE);1221 } else {1222 ROAR_ERR("add_output(*): unknown option '%s'", k);1223 error++;1224 }1225 1226 if ( error ) {1227 streams_delete(stream);1228 if ( prim ) alive = 0;1229 #ifdef ROAR_DRIVER_CODEC1230 if ( to_free != NULL )1231 free(to_free);1232 #endif1233 return -1;1234 }1235 1236 k = strtok(NULL, ",");1237 }1238 1239 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);1240 1241 // set audio info...1242 switch (dir) {1243 case ROAR_DIR_LIGHT_OUT:1244 switch (s->info.codec) {1245 case ROAR_CODEC_DMX512:1246 case -1:1247 if ( s->info.rate == -1 )1248 s->info.rate = ROAR_OUTPUT_CFREQ;1249 1250 s->info.channels = 0;1251 s->info.bits = 8;1252 s->info.codec = ROAR_CODEC_DMX512; // in case codec == -11253 break;1254 }1255 break;1256 case ROAR_DIR_MIDI_OUT:1257 switch (s->info.codec) {1258 case ROAR_CODEC_MIDI:1259 case -1:1260 if ( s->info.rate == -1 )1261 s->info.rate = ROAR_MIDI_TICKS_PER_BEAT;1262 1263 s->info.channels = ROAR_MIDI_CHANNELS_DEFAULT;1264 s->info.bits = ROAR_MIDI_BITS;1265 s->info.codec = ROAR_CODEC_MIDI; // in case codec == -11266 break;1267 }1268 break;1269 case ROAR_DIR_RAW_OUT:1270 if ( s->info.rate == -1 )1271 s->info.rate = 0;1272 if ( s->info.bits == -1 )1273 s->info.bits = 0;1274 if ( s->info.channels == -1 )1275 s->info.channels = 0;1276 if ( s->info.codec == -1 )1277 s->info.codec = 0;1278 break;1279 }1280 1281 if ( s->info.rate == -1 )1282 s->info.rate = g_sa->rate;1283 if ( s->info.bits == -1 )1284 s->info.bits = g_sa->bits;1285 if ( s->info.channels == -1 )1286 s->info.channels = g_sa->channels;1287 if ( s->info.codec == -1 )1288 s->info.codec = g_sa->codec;1289 1290 ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec);1291 1292 if ( streams_set_dir(stream, dir, 1) == -1 ) {1293 streams_delete(stream);1294 return -1;1295 }1296 1297 #ifdef ROAR_DRIVER_CODEC1298 if ( to_free != NULL )1299 free(to_free);1300 #endif1301 1302 if ( s->info.codec == ROAR_CODEC_ALAW || s->info.codec == ROAR_CODEC_MULAW )1303 s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter1304 1305 ROAR_STREAM_SERVER(s)->codec_orgi = s->info.codec;1306 1307 if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) {1308 ss->driver_id = -1; // don't close a driver not opened...1309 memset(&(ss->vio), 0, sizeof(struct roar_vio_calls));1310 streams_delete(stream);1311 if ( prim ) alive = 0;1312 ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not open output driver.", drv, dev, opts);1313 ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);1314 return -1;1315 }1316 1317 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here1318 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM, s); // ignore errors here1319 1320 if ( blocks != -1 )1321 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks);1322 1323 if ( blocksize != -1 )1324 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize);1325 1326 // TODO: we shoudld *really* check for errors here...1327 if ( channel != -1 ) {1328 tu16 = channel;1329 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16);1330 }1331 if ( universe != -1 ) {1332 tu16 = universe;1333 roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16);1334 }1335 1336 ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id);1337 1338 streams_set_fh(stream, -1); // update some internal structures1339 1340 if ( q > -1e6 ) {1341 ROAR_DBG("add_output(*): setting q=%f", q);1342 streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q);1343 }1344 1345 client_stream_add(g_self_client, stream);1346 1347 if ( prim ) {1348 streams_mark_primary(stream);1349 s->pos_rel_id = stream;1350 }1351 1352 if ( sync ) {1353 streams_set_flag(stream, ROAR_FLAG_SYNC);1354 } else {1355 streams_reset_flag(stream, ROAR_FLAG_SYNC);1356 }1357 1358 if ( f_mmap )1359 streams_set_flag(stream, ROAR_FLAG_MMAP);1360 1361 ROAR_DBG("add_output(*): s->info = {.rate=%i, .bits=%i, .channels=%i, .codec=%i}", s->info.rate, s->info.bits, s->info.channels, s->info.codec);1362 return 0;1363 }1364 1365 #ifndef ROAR_WITHOUT_DCOMP_MIXER1366 int add_hwmixer (char * drv, char * dev, char * opts, int prim, int count) {1367 char * basename = NULL;1368 char * subnames = NULL;1369 char * k, * v;1370 int basestream = streams_new();1371 int ret;1372 int error = 0;1373 //int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) {1374 1375 if ( basestream == -1 )1376 return -1;1377 1378 client_stream_add(g_self_client, basestream);1379 1380 if ( opts == NULL ) {1381 k = NULL;1382 } else {1383 k = strtok(opts, ",");1384 }1385 1386 while (k != NULL) {1387 // ROAR_WARN("add_output(*): opts: %s", k);1388 1389 if ( (v = strstr(k, "=")) != NULL ) {1390 *v++ = 0;1391 }1392 1393 if ( strcmp(k, "primary") == 0 ) {1394 prim = 1;1395 1396 } else if ( strcmp(k, "name") == 0 ) {1397 basename = v;1398 } else if ( strcmp(k, "subs") == 0 ) {1399 subnames = v;1400 1401 } else if ( strcmp(k, "autoconf") == 0 ) {1402 streams_set_flag(basestream, ROAR_FLAG_AUTOCONF);1403 } else if ( strcmp(k, "passmixer") == 0 ) {1404 streams_set_flag(basestream, ROAR_FLAG_PASSMIXER);1405 } else {1406 ROAR_ERR("add_hwmixer(*): unknown option '%s'", k);1407 error++;1408 }1409 1410 if ( error ) {1411 streams_delete(basestream);1412 if ( prim ) alive = 0;1413 return -1;1414 }1415 1416 k = strtok(NULL, ",");1417 }1418 1419 if ( prim ) {1420 streams_mark_primary(basestream);1421 }1422 1423 ret = hwmixer_open(basestream, drv, dev, -1, basename, subnames);1424 1425 if ( ret == -1 ) {1426 streams_delete(basestream);1427 }1428 1429 return ret == -1 ? -1 : 0;1430 }1431 #endif1432 1433 965 int add_authfile (const char * file, const char * type, enum af_mode mode, enum roard_client_acclev acclev) { 1434 966 struct roar_authfile * authfile = NULL; … … 2147 1679 } else if ( strcmp(k, "-oN") == 0 ) { 2148 1680 if ( action == START || action == RESTART ) { 2149 if ( add_output(o_drv, o_dev, o_opts, o_prim, o_count) != -1 )1681 if ( output_add(o_drv, o_dev, o_opts, o_prim, o_count) != -1 ) 2150 1682 o_count++; 2151 1683 … … 2245 1777 } else if ( strcmp(k, "-mN") == 0 ) { 2246 1778 #ifndef ROAR_WITHOUT_DCOMP_MIXER 2247 if ( add_hwmixer(m_drv, m_dev, m_opts, m_prim, m_count) != -1 )1779 if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) != -1 ) 2248 1780 m_count++; 2249 1781 … … 2652 2184 #ifndef ROAR_WITHOUT_DCOMP_MIXER 2653 2185 if ( m_drv != NULL ) { 2654 if ( add_hwmixer(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) {2186 if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) { 2655 2187 ROAR_ERR("main(*): adding mixer '%s' via '%s' failed!", m_dev, m_drv); 2656 2188 } … … 2666 2198 #endif 2667 2199 2668 if ( add_default_output(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) {2200 if ( output_add_default(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) { 2669 2201 ROAR_ERR("Can not initialize default driver"); 2670 2202 return 1;
Note: See TracChangeset
for help on using the changeset viewer.