Index: roard/hwmixer.c
===================================================================
--- roard/hwmixer.c	(revision 4752)
+++ roard/hwmixer.c	(revision 4852)
@@ -231,4 +231,70 @@
 }
 
+int hwmixer_add (char * drv, char * dev, char * opts, int prim, int count) {
+ char * basename = NULL;
+ char * subnames = NULL;
+ char * k, * v;
+ int basestream = streams_new();
+ int ret;
+ int error = 0;
+//int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) {
+
+ if ( basestream == -1 )
+  return -1;
+
+ client_stream_add(g_self_client, basestream);
+
+ if ( opts == NULL ) {
+  k = NULL;
+ } else {
+  k = strtok(opts, ",");
+ }
+
+ while (k != NULL) {
+//  ROAR_WARN("add_output(*): opts: %s", k);
+
+  if ( (v = strstr(k, "=")) != NULL ) {
+   *v++ = 0;
+  }
+
+  if ( strcmp(k, "primary") == 0 ) {
+   prim = 1;
+
+  } else if ( strcmp(k, "name") == 0 ) {
+   basename = v;
+  } else if ( strcmp(k, "subs") == 0 ) {
+   subnames = v;
+
+  } else if ( strcmp(k, "autoconf") == 0 ) {
+   streams_set_flag(basestream, ROAR_FLAG_AUTOCONF);
+  } else if ( strcmp(k, "passmixer") == 0 ) {
+   streams_set_flag(basestream, ROAR_FLAG_PASSMIXER);
+  } else {
+   ROAR_ERR("add_hwmixer(*): unknown option '%s'", k);
+   error++;
+  }
+
+  if ( error ) {
+   streams_delete(basestream);
+   if ( prim ) alive = 0;
+   return -1;
+  }
+
+  k = strtok(NULL, ",");
+ }
+
+ if ( prim ) {
+  streams_mark_primary(basestream);
+ }
+
+ ret = hwmixer_open(basestream, drv, dev, -1, basename, subnames);
+
+ if ( ret == -1 ) {
+  streams_delete(basestream);
+ }
+
+ return ret == -1 ? -1 : 0;
+}
+
 #endif
 
Index: roard/include/hwmixer.h
===================================================================
--- roard/include/hwmixer.h	(revision 4708)
+++ roard/include/hwmixer.h	(revision 4852)
@@ -51,4 +51,7 @@
 struct hwmixer_stream * hwmixer_substream_new(struct hwmixer_stream * parent);
 
+int hwmixer_add (char * drv, char * dev, char * opts, int prim, int count);
+
+
 // Mixers:
 
Index: roard/include/output.h
===================================================================
--- roard/include/output.h	(revision 4814)
+++ roard/include/output.h	(revision 4852)
@@ -77,4 +77,7 @@
 int output_buffer_free   (void);
 
+int output_add         (char * drv, char * dev, char * opts, int prim, int count);
+int output_add_default (char * drv, char * dev, char * opts, int prim, int count);
+
 #endif
 
Index: roard/output.c
===================================================================
--- roard/output.c	(revision 4814)
+++ roard/output.c	(revision 4852)
@@ -87,3 +87,409 @@
 }
 
+
+
+
+
+
+#ifdef ROAR_DRIVER_DEFAULT
+int output_add_default (char * drv, char * dev, char * opts, int prim, int count) {
+ return output_add(drv, dev, opts, prim, count);
+}
+#else
+int output_add_default (char * drv, char * dev, char * opts, int prim, int count) {
+ char * drvs[] = {
+  // operating system depended things:
+#ifdef __OpenBSD__
+  /* OpenBSD use sndio natively, this check is discusses with upstream (See ML archive August 2010) */
+  "sndio",
+#endif
+  // native and pseudo-native interfaces:
+  "oss", "alsa", "sndio", "wmm",
+  // sound libs:
+  "ao", "portaudio",
+  // other sound systems:
+  "esd", "rsound", "pulsesimple", "roar",
+  // specal buildins:
+  "sysclock", "null",
+  // terminator:
+  NULL
+ };
+ int i;
+ int ret;
+ int _alive;
+ char * _opts;
+
+ if ( drv != NULL )
+  return output_add(drv, dev, opts, prim, count);
+
+ if ( dev != NULL ) {
+  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);
+ }
+
+ for (i = 0; drvs[i] != NULL; i++) {
+  ROAR_INFO("add_default_output(*): trying driver %s", ROAR_DBG_INFO_INFO, drvs[i]);
+  _alive = alive; // save global alive setting
+
+  if ( opts == NULL ) {
+   _opts = NULL;
+  } else {
+   _opts = roar_mm_strdup(opts);
+  }
+
+  ret = output_add(drvs[i], dev, _opts, prim, count);
+
+  if ( _opts != NULL )
+   roar_mm_free(_opts);
+
+  if ( ret != -1 )
+   return ret;
+
+  alive = _alive; // restore global alive setting
+  ROAR_INFO("add_default_output(*): Driver %s faild to load", ROAR_DBG_INFO_VERBOSE, drvs[i]);
+ }
+
+ return -1;
+}
+#endif
+
+
+#define _CKPARAM(n) if ( n (v == NULL) ) { \
+                     ROAR_WARN("add_output(drv='%s', dev='%s', opts=..., prim=%i, count=%i): " \
+                               "Parameter '%s' expects %s parameter.", \
+                               drv, dev, prim, count, k, (n 1) ? "a" : "no"); \
+                     error++; \
+                    } else
+
+int output_add (char * drv, char * dev, char * opts, int prim, int count) {
+ int stream;
+ int default_flags;
+ struct roar_stream * s;
+ struct roar_stream_server * ss;
+ char * k, * v;
+#ifdef ROAR_DRIVER_CODEC
+ char * to_free = NULL;
+#endif
+ int sync = 0, f_mmap = 0;
+ int32_t blocks = -1, blocksize = -1;
+ int dir = ROAR_DIR_OUTPUT;
+ int error = 0;
+ // DMX:
+ int32_t channel  = -1;
+ int32_t universe = -1;
+ uint16_t tu16;
+ float q = -32e6;
+
+ 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);
+
+ if ( drv == NULL && count == 0 ) {
+#ifdef ROAR_DRIVER_DEFAULT
+  drv  = ROAR_DRIVER_DEFAULT;
+  prim = 1;
+  sync = 1;
+
+#ifdef ROAR_DRIVER_CODEC
+  if ( opts == NULL ) {
+   opts = to_free = strdup("codec=" ROAR_DRIVER_CODEC);
+  }
+#endif
+#else
+  ROAR_ERR("add_output(*): Can not find default driver");
+  return -1;
+#endif
+ }
+
+ if ( opts == NULL && count == 0 ) {
+  default_flags = ROAR_FLAG_AUTOCONF|ROAR_FLAG_RECSOURCE;
+  sync = 1;
+  prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 1
+ }
+
+ ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
+
+ if ( (stream = streams_new()) == -1 ) {
+  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
+  if ( prim ) alive = 0;
+  return -1;
+ }
+
+ ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
+
+ streams_get(stream, &ss);
+ s = ROAR_STREAM(ss);
+
+ ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
+
+ memset(&(s->info), 0xFF, sizeof(struct roar_audio_info)); // set everything to -1
+
+ s->pos_rel_id = -1;
+// s->info.codec = codec;
+
+ // seting default flags:
+ streams_set_flag(stream, default_flags);
+
+ ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
+
+ if ( opts == NULL ) {
+  k = NULL;
+ } else {
+  k = strtok(opts, ",");
+ }
+
+ ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s'): initial k='%s'(%p)", drv, dev, opts, k, k);
+
+ while (k != NULL) {
+//  ROAR_WARN("add_output(*): opts: %s", k);
+
+  if ( (v = strstr(k, "=")) != NULL ) {
+   *v++ = 0;
+  }
+
+  ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v);
+  if ( strcmp(k, "rate") == 0 ) {
+   _CKPARAM()
+    s->info.rate = atoi(v);
+  } else if ( strcmp(k, "channels") == 0 ) {
+   _CKPARAM()
+    s->info.channels = atoi(v);
+  } else if ( strcmp(k, "bits") == 0 ) {
+   _CKPARAM()
+    s->info.bits = atoi(v);
+  } else if ( strcmp(k, "codec") == 0 ) {
+   _CKPARAM()
+    if ( (s->info.codec = roar_str2codec(v)) == -1 ) {
+     ROAR_ERR("add_output(*): unknown codec '%s'", v);
+     error++;
+    }
+  } else if ( strcmp(k, "q") == 0 ) {
+   _CKPARAM()
+    q = atof(v);
+  } else if ( strcmp(k, "blocks") == 0 ) {
+   _CKPARAM()
+    blocks = atoi(v);
+  } else if ( strcmp(k, "blocksize") == 0 ) {
+   _CKPARAM()
+    blocksize = atoi(v);
+  } else if ( strcmp(k, "mmap") == 0 ) {
+   _CKPARAM(!)
+    f_mmap = 1;
+  } else if ( strcmp(k, "subsystem") == 0 ) {
+   _CKPARAM() {
+    if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) {
+     dir = ROAR_DIR_OUTPUT;
+#ifndef ROAR_WITHOUT_DCOMP_MIDI
+    } else if ( !strcasecmp(v, "midi") ) {
+     dir = ROAR_DIR_MIDI_OUT;
+#endif
+#ifndef ROAR_WITHOUT_DCOMP_LIGHT
+    } else if ( !strcasecmp(v, "light") ) {
+     dir = ROAR_DIR_LIGHT_OUT;
+#endif
+#ifndef ROAR_WITHOUT_DCOMP_RAW
+    } else if ( !strcasecmp(v, "raw") ) {
+     dir = ROAR_DIR_RAW_OUT;
+#endif
+    } else if ( !strcasecmp(v, "complex") ) {
+     dir = ROAR_DIR_COMPLEX_OUT;
+    } else {
+     ROAR_ERR("add_output(*): unknown/unsupported subsystem '%s'", k);
+     error++;
+    }
+   }
+  // DMX:
+  } else if ( strcmp(k, "channel") == 0 ) {
+   _CKPARAM() {
+    channel  = atoi(v);
+    if ( channel < 0 || channel > 65535 ) {
+     ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel);
+     channel = -1;
+     error++;
+    }
+   }
+  } else if ( strcmp(k, "universe") == 0 ) {
+   _CKPARAM() {
+    universe = atoi(v);
+    if ( universe < 0 || universe > 255 ) {
+     ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe);
+     universe = -1;
+     error++;
+    }
+   }
+
+  } else if ( strcmp(k, "name") == 0 ) {
+   _CKPARAM() {
+    if ( streams_set_name(stream, v) == -1 ) {
+     ROAR_ERR("add_output(*): Can not set Stream name");
+     error++;
+    }
+   }
+
+  } else if ( strcmp(k, "meta") == 0 ) {
+   _CKPARAM(!)
+    streams_set_flag(stream, ROAR_FLAG_META);
+  } else if ( strcmp(k, "sync") == 0 ) {
+   _CKPARAM(!)
+    sync = 1;
+  } else if ( strcmp(k, "primary") == 0 ) {
+   _CKPARAM(!)
+    prim = 1;
+
+  } else if ( strcmp(k, "cleanmeta") == 0 ) {
+   _CKPARAM(!)
+    streams_set_flag(stream, ROAR_FLAG_CLEANMETA);
+  } else if ( strcmp(k, "autoconf") == 0 ) {
+   _CKPARAM(!)
+    streams_set_flag(stream, ROAR_FLAG_AUTOCONF);
+  } else if ( strcmp(k, "recsource") == 0 ) {
+   _CKPARAM(!)
+    streams_set_flag(stream, ROAR_FLAG_RECSOURCE);
+  } else if ( strcmp(k, "passmixer") == 0 ) {
+   _CKPARAM(!)
+    streams_set_flag(stream, ROAR_FLAG_PASSMIXER);
+  } else if ( strcmp(k, "recsource") == 0 ) {
+   _CKPARAM(!)
+    streams_set_flag(stream, ROAR_FLAG_RECSOURCE);
+  } else {
+   ROAR_ERR("add_output(*): unknown option '%s'", k);
+   error++;
+  }
+
+  if ( error ) {
+   streams_delete(stream);
+   if ( prim ) alive = 0;
+#ifdef ROAR_DRIVER_CODEC
+   if ( to_free != NULL )
+    free(to_free);
+#endif
+   return -1;
+  }
+
+  k = strtok(NULL, ",");
+ }
+
+ ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
+
+ // set audio info...
+ switch (dir) {
+  case ROAR_DIR_LIGHT_OUT:
+    switch (s->info.codec) {
+     case ROAR_CODEC_DMX512:
+     case -1:
+       if ( s->info.rate == -1 )
+        s->info.rate = ROAR_OUTPUT_CFREQ;
+
+       s->info.channels =   0;
+       s->info.bits     =   8;
+       s->info.codec    = ROAR_CODEC_DMX512; // in case codec == -1
+      break;
+    }
+   break;
+  case ROAR_DIR_MIDI_OUT:
+    switch (s->info.codec) {
+     case ROAR_CODEC_MIDI:
+     case -1:
+       if ( s->info.rate == -1 )
+        s->info.rate    = ROAR_MIDI_TICKS_PER_BEAT;
+
+       s->info.channels = ROAR_MIDI_CHANNELS_DEFAULT;
+       s->info.bits     = ROAR_MIDI_BITS;
+       s->info.codec    = ROAR_CODEC_MIDI; // in case codec == -1
+      break;
+    }
+   break;
+  case ROAR_DIR_RAW_OUT:
+    if ( s->info.rate == -1 )
+     s->info.rate = 0;
+    if ( s->info.bits == -1 )
+     s->info.bits = 0;
+    if ( s->info.channels == -1 )
+     s->info.channels = 0;
+    if ( s->info.codec == -1 )
+     s->info.codec = 0;
+   break;
+ }
+
+ if ( s->info.rate == -1 )
+  s->info.rate = g_sa->rate;
+ if ( s->info.bits == -1 )
+  s->info.bits = g_sa->bits;
+ if ( s->info.channels == -1 )
+  s->info.channels = g_sa->channels;
+ if ( s->info.codec == -1 )
+  s->info.codec = g_sa->codec;
+
+ 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);
+
+ if ( streams_set_dir(stream, dir, 1) == -1 ) {
+  streams_delete(stream);
+  return -1;
+ }
+
+#ifdef ROAR_DRIVER_CODEC
+ if ( to_free != NULL )
+  free(to_free);
+#endif
+
+ if ( s->info.codec == ROAR_CODEC_ALAW || s->info.codec == ROAR_CODEC_MULAW )
+  s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter
+
+ ROAR_STREAM_SERVER(s)->codec_orgi = s->info.codec;
+
+ if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) {
+  ss->driver_id = -1; // don't close a driver not opened...
+  memset(&(ss->vio), 0, sizeof(struct roar_vio_calls));
+  streams_delete(stream);
+  if ( prim ) alive = 0;
+  ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not open output driver.", drv, dev, opts);
+  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
+  return -1;
+ }
+
+ roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here
+ roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM,   s); // ignore errors here
+
+ if ( blocks != -1 )
+  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks);
+
+ if ( blocksize != -1 )
+  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize);
+
+ // TODO: we shoudld *really* check for errors here...
+ if ( channel != -1 ) {
+  tu16 = channel;
+  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16);
+ }
+ if ( universe != -1 ) {
+  tu16 = universe;
+  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16);
+ }
+
+ ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id);
+
+ streams_set_fh(stream, -1); // update some internal structures
+
+ if ( q > -1e6 ) {
+  ROAR_DBG("add_output(*): setting q=%f", q);
+  streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q);
+ }
+
+ client_stream_add(g_self_client, stream);
+
+ if ( prim ) {
+  streams_mark_primary(stream);
+  s->pos_rel_id = stream;
+ }
+
+ if ( sync ) {
+  streams_set_flag(stream, ROAR_FLAG_SYNC);
+ } else {
+  streams_reset_flag(stream, ROAR_FLAG_SYNC);
+ }
+
+ if ( f_mmap )
+  streams_set_flag(stream, ROAR_FLAG_MMAP);
+
+ 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);
+ return 0;
+}
+
 //ll
Index: roard/roard.c
===================================================================
--- roard/roard.c	(revision 4851)
+++ roard/roard.c	(revision 4852)
@@ -56,6 +56,4 @@
 char * x11display = NULL;
 #endif
-
-int add_output (char * drv, char * dev, char * opts, int prim, int count);
 
 void dbg_notify_cb(struct roar_notify_core * core, struct roar_event * event, void * userdata) {
@@ -965,470 +963,4 @@
 }
 
-#ifdef ROAR_DRIVER_DEFAULT
-#define add_default_output add_output
-#else
-int add_default_output (char * drv, char * dev, char * opts, int prim, int count) {
- char * drvs[] = {
-  // operating system depended things:
-#ifdef __OpenBSD__
-  /* OpenBSD use sndio natively, this check is discusses with upstream (See ML archive August 2010) */
-  "sndio",
-#endif
-  // native and pseudo-native interfaces:
-  "oss", "alsa", "sndio", "wmm",
-  // sound libs:
-  "ao", "portaudio",
-  // other sound systems:
-  "esd", "rsound", "pulsesimple", "roar",
-  // specal buildins:
-  "sysclock", "null",
-  // terminator:
-  NULL
- };
- int i;
- int ret;
- int _alive;
- char * _opts;
-
- if ( drv != NULL )
-  return add_output(drv, dev, opts, prim, count);
-
- if ( dev != NULL ) {
-  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);
- }
-
- for (i = 0; drvs[i] != NULL; i++) {
-  ROAR_INFO("add_default_output(*): trying driver %s", ROAR_DBG_INFO_INFO, drvs[i]);
-  _alive = alive; // save global alive setting
-
-  if ( opts == NULL ) {
-   _opts = NULL;
-  } else {
-   _opts = roar_mm_strdup(opts);
-  }
-
-  ret = add_output(drvs[i], dev, _opts, prim, count);
-
-  if ( _opts != NULL )
-   roar_mm_free(_opts);
-
-  if ( ret != -1 )
-   return ret;
-
-  alive = _alive; // restore global alive setting
-  ROAR_INFO("add_default_output(*): Driver %s faild to load", ROAR_DBG_INFO_VERBOSE, drvs[i]);
- }
-
- return -1;
-}
-#endif
-
-#define _CKPARAM(n) if ( n (v == NULL) ) { \
-                     ROAR_WARN("add_output(drv='%s', dev='%s', opts=..., prim=%i, count=%i): " \
-                               "Parameter '%s' expects %s parameter.", \
-                               drv, dev, prim, count, k, (n 1) ? "a" : "no"); \
-                     error++; \
-                    } else
-
-int add_output (char * drv, char * dev, char * opts, int prim, int count) {
- int stream;
- int default_flags;
- struct roar_stream * s;
- struct roar_stream_server * ss;
- char * k, * v;
-#ifdef ROAR_DRIVER_CODEC
- char * to_free = NULL;
-#endif
- int sync = 0, f_mmap = 0;
- int32_t blocks = -1, blocksize = -1;
- int dir = ROAR_DIR_OUTPUT;
- int error = 0;
- // DMX:
- int32_t channel  = -1;
- int32_t universe = -1;
- uint16_t tu16;
- float q = -32e6;
-
- 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);
-
- if ( drv == NULL && count == 0 ) {
-#ifdef ROAR_DRIVER_DEFAULT
-  drv  = ROAR_DRIVER_DEFAULT;
-  prim = 1;
-  sync = 1;
-
-#ifdef ROAR_DRIVER_CODEC
-  if ( opts == NULL ) {
-   opts = to_free = strdup("codec=" ROAR_DRIVER_CODEC);
-  }
-#endif
-#else
-  ROAR_ERR("add_output(*): Can not find default driver");
-  return -1;
-#endif
- }
-
- if ( opts == NULL && count == 0 ) {
-  default_flags = ROAR_FLAG_AUTOCONF|ROAR_FLAG_RECSOURCE;
-  sync = 1;
-  prim = 1; // if ( prim == 0 ) prim = 1; -> prim allways = 1
- }
-
- ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
-
- if ( (stream = streams_new()) == -1 ) {
-  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
-  if ( prim ) alive = 0;
-  return -1;
- }
-
- ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
-
- streams_get(stream, &ss);
- s = ROAR_STREAM(ss);
-
- ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
-
- memset(&(s->info), 0xFF, sizeof(struct roar_audio_info)); // set everything to -1
-
- s->pos_rel_id = -1;
-// s->info.codec = codec;
-
- // seting default flags:
- streams_set_flag(stream, default_flags);
-
- ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
-
- if ( opts == NULL ) {
-  k = NULL;
- } else {
-  k = strtok(opts, ",");
- }
-
- ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s'): initial k='%s'(%p)", drv, dev, opts, k, k);
-
- while (k != NULL) {
-//  ROAR_WARN("add_output(*): opts: %s", k);
-
-  if ( (v = strstr(k, "=")) != NULL ) {
-   *v++ = 0;
-  }
-
-  ROAR_DBG("add_output(*): opts: k='%s', v='%s'", k, v);
-  if ( strcmp(k, "rate") == 0 ) {
-   _CKPARAM()
-    s->info.rate = atoi(v);
-  } else if ( strcmp(k, "channels") == 0 ) {
-   _CKPARAM()
-    s->info.channels = atoi(v);
-  } else if ( strcmp(k, "bits") == 0 ) {
-   _CKPARAM()
-    s->info.bits = atoi(v);
-  } else if ( strcmp(k, "codec") == 0 ) {
-   _CKPARAM()
-    if ( (s->info.codec = roar_str2codec(v)) == -1 ) {
-     ROAR_ERR("add_output(*): unknown codec '%s'", v);
-     error++;
-    }
-  } else if ( strcmp(k, "q") == 0 ) {
-   _CKPARAM()
-    q = atof(v);
-  } else if ( strcmp(k, "blocks") == 0 ) {
-   _CKPARAM()
-    blocks = atoi(v);
-  } else if ( strcmp(k, "blocksize") == 0 ) {
-   _CKPARAM()
-    blocksize = atoi(v);
-  } else if ( strcmp(k, "mmap") == 0 ) {
-   _CKPARAM(!)
-    f_mmap = 1;
-  } else if ( strcmp(k, "subsystem") == 0 ) {
-   _CKPARAM() {
-    if ( !strcasecmp(v, "wave") || !strcasecmp(v, "waveform") ) {
-     dir = ROAR_DIR_OUTPUT;
-#ifndef ROAR_WITHOUT_DCOMP_MIDI
-    } else if ( !strcasecmp(v, "midi") ) {
-     dir = ROAR_DIR_MIDI_OUT;
-#endif
-#ifndef ROAR_WITHOUT_DCOMP_LIGHT
-    } else if ( !strcasecmp(v, "light") ) {
-     dir = ROAR_DIR_LIGHT_OUT;
-#endif
-#ifndef ROAR_WITHOUT_DCOMP_RAW
-    } else if ( !strcasecmp(v, "raw") ) {
-     dir = ROAR_DIR_RAW_OUT;
-#endif
-    } else if ( !strcasecmp(v, "complex") ) {
-     dir = ROAR_DIR_COMPLEX_OUT;
-    } else {
-     ROAR_ERR("add_output(*): unknown/unsupported subsystem '%s'", k);
-     error++;
-    }
-   }
-  // DMX:
-  } else if ( strcmp(k, "channel") == 0 ) {
-   _CKPARAM() {
-    channel  = atoi(v);
-    if ( channel < 0 || channel > 65535 ) {
-     ROAR_ERR("add_output(*): Invalide channel (not within 0..65535): %i", channel);
-     channel = -1;
-     error++;
-    }
-   }
-  } else if ( strcmp(k, "universe") == 0 ) {
-   _CKPARAM() {
-    universe = atoi(v);
-    if ( universe < 0 || universe > 255 ) {
-     ROAR_ERR("add_output(*): Invalide universe (not within 0..255): %i", universe);
-     universe = -1;
-     error++;
-    }
-   }
-
-  } else if ( strcmp(k, "name") == 0 ) {
-   _CKPARAM() {
-    if ( streams_set_name(stream, v) == -1 ) {
-     ROAR_ERR("add_output(*): Can not set Stream name");
-     error++;
-    }
-   }
-
-  } else if ( strcmp(k, "meta") == 0 ) {
-   _CKPARAM(!)
-    streams_set_flag(stream, ROAR_FLAG_META);
-  } else if ( strcmp(k, "sync") == 0 ) {
-   _CKPARAM(!)
-    sync = 1;
-  } else if ( strcmp(k, "primary") == 0 ) {
-   _CKPARAM(!)
-    prim = 1;
-
-  } else if ( strcmp(k, "cleanmeta") == 0 ) {
-   _CKPARAM(!)
-    streams_set_flag(stream, ROAR_FLAG_CLEANMETA);
-  } else if ( strcmp(k, "autoconf") == 0 ) {
-   _CKPARAM(!)
-    streams_set_flag(stream, ROAR_FLAG_AUTOCONF);
-  } else if ( strcmp(k, "recsource") == 0 ) {
-   _CKPARAM(!)
-    streams_set_flag(stream, ROAR_FLAG_RECSOURCE);
-  } else if ( strcmp(k, "passmixer") == 0 ) {
-   _CKPARAM(!)
-    streams_set_flag(stream, ROAR_FLAG_PASSMIXER);
-  } else if ( strcmp(k, "recsource") == 0 ) {
-   _CKPARAM(!)
-    streams_set_flag(stream, ROAR_FLAG_RECSOURCE);
-  } else {
-   ROAR_ERR("add_output(*): unknown option '%s'", k);
-   error++;
-  }
-
-  if ( error ) {
-   streams_delete(stream);
-   if ( prim ) alive = 0;
-#ifdef ROAR_DRIVER_CODEC
-   if ( to_free != NULL )
-    free(to_free);
-#endif
-   return -1;
-  }
-
-  k = strtok(NULL, ",");
- }
-
- ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
-
- // set audio info...
- switch (dir) {
-  case ROAR_DIR_LIGHT_OUT:
-    switch (s->info.codec) {
-     case ROAR_CODEC_DMX512:
-     case -1:
-       if ( s->info.rate == -1 )
-        s->info.rate = ROAR_OUTPUT_CFREQ;
-
-       s->info.channels =   0;
-       s->info.bits     =   8;
-       s->info.codec    = ROAR_CODEC_DMX512; // in case codec == -1
-      break;
-    }
-   break;
-  case ROAR_DIR_MIDI_OUT:
-    switch (s->info.codec) {
-     case ROAR_CODEC_MIDI:
-     case -1:
-       if ( s->info.rate == -1 )
-        s->info.rate    = ROAR_MIDI_TICKS_PER_BEAT;
-
-       s->info.channels = ROAR_MIDI_CHANNELS_DEFAULT;
-       s->info.bits     = ROAR_MIDI_BITS;
-       s->info.codec    = ROAR_CODEC_MIDI; // in case codec == -1
-      break;
-    }
-   break;
-  case ROAR_DIR_RAW_OUT:
-    if ( s->info.rate == -1 )
-     s->info.rate = 0;
-    if ( s->info.bits == -1 )
-     s->info.bits = 0;
-    if ( s->info.channels == -1 )
-     s->info.channels = 0;
-    if ( s->info.codec == -1 )
-     s->info.codec = 0;
-   break;
- }
-
- if ( s->info.rate == -1 )
-  s->info.rate = g_sa->rate;
- if ( s->info.bits == -1 )
-  s->info.bits = g_sa->bits;
- if ( s->info.channels == -1 )
-  s->info.channels = g_sa->channels;
- if ( s->info.codec == -1 )
-  s->info.codec = g_sa->codec;
-
- 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);
-
- if ( streams_set_dir(stream, dir, 1) == -1 ) {
-  streams_delete(stream);
-  return -1;
- }
-
-#ifdef ROAR_DRIVER_CODEC
- if ( to_free != NULL )
-  free(to_free);
-#endif
-
- if ( s->info.codec == ROAR_CODEC_ALAW || s->info.codec == ROAR_CODEC_MULAW )
-  s->info.bits = 8; // needed to open OSS driver, will be overriden by codecfilter
-
- ROAR_STREAM_SERVER(s)->codec_orgi = s->info.codec;
-
- if ( driver_openvio(&(ss->vio), &(ss->driver_id), drv, dev, &(s->info), -1, ss) == -1 ) {
-  ss->driver_id = -1; // don't close a driver not opened...
-  memset(&(ss->vio), 0, sizeof(struct roar_vio_calls));
-  streams_delete(stream);
-  if ( prim ) alive = 0;
-  ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not open output driver.", drv, dev, opts);
-  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
-  return -1;
- }
-
- roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream); // ignore errors here
- roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM,   s); // ignore errors here
-
- if ( blocks != -1 )
-  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks);
-
- if ( blocksize != -1 )
-  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize);
-
- // TODO: we shoudld *really* check for errors here...
- if ( channel != -1 ) {
-  tu16 = channel;
-  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16);
- }
- if ( universe != -1 ) {
-  tu16 = universe;
-  roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16);
- }
-
- ROAR_DBG("add_output(*): ss->driver_id=%i", ss->driver_id);
-
- streams_set_fh(stream, -1); // update some internal structures
-
- if ( q > -1e6 ) {
-  ROAR_DBG("add_output(*): setting q=%f", q);
-  streams_ctl(stream, ROAR_CODECFILTER_CTL_SET_Q|ROAR_STREAM_CTL_TYPE_FLOAT, &q);
- }
-
- client_stream_add(g_self_client, stream);
-
- if ( prim ) {
-  streams_mark_primary(stream);
-  s->pos_rel_id = stream;
- }
-
- if ( sync ) {
-  streams_set_flag(stream, ROAR_FLAG_SYNC);
- } else {
-  streams_reset_flag(stream, ROAR_FLAG_SYNC);
- }
-
- if ( f_mmap )
-  streams_set_flag(stream, ROAR_FLAG_MMAP);
-
- 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);
- return 0;
-}
-
-#ifndef ROAR_WITHOUT_DCOMP_MIXER
-int add_hwmixer (char * drv, char * dev, char * opts, int prim, int count) {
- char * basename = NULL;
- char * subnames = NULL;
- char * k, * v;
- int basestream = streams_new();
- int ret;
- int error = 0;
-//int hwmixer_open(int basestream, char * drv, char * dev, int fh, char * basename, char * subnames) {
-
- if ( basestream == -1 )
-  return -1;
-
- client_stream_add(g_self_client, basestream);
-
- if ( opts == NULL ) {
-  k = NULL;
- } else {
-  k = strtok(opts, ",");
- }
-
- while (k != NULL) {
-//  ROAR_WARN("add_output(*): opts: %s", k);
-
-  if ( (v = strstr(k, "=")) != NULL ) {
-   *v++ = 0;
-  }
-
-  if ( strcmp(k, "primary") == 0 ) {
-   prim = 1;
-
-  } else if ( strcmp(k, "name") == 0 ) {
-   basename = v;
-  } else if ( strcmp(k, "subs") == 0 ) {
-   subnames = v;
-
-  } else if ( strcmp(k, "autoconf") == 0 ) {
-   streams_set_flag(basestream, ROAR_FLAG_AUTOCONF);
-  } else if ( strcmp(k, "passmixer") == 0 ) {
-   streams_set_flag(basestream, ROAR_FLAG_PASSMIXER);
-  } else {
-   ROAR_ERR("add_hwmixer(*): unknown option '%s'", k);
-   error++;
-  }
-
-  if ( error ) {
-   streams_delete(basestream);
-   if ( prim ) alive = 0;
-   return -1;
-  }
-
-  k = strtok(NULL, ",");
- }
-
- if ( prim ) {
-  streams_mark_primary(basestream);
- }
-
- ret = hwmixer_open(basestream, drv, dev, -1, basename, subnames);
-
- if ( ret == -1 ) {
-  streams_delete(basestream);
- }
-
- return ret == -1 ? -1 : 0;
-}
-#endif
-
 int add_authfile (const char * file, const char * type, enum af_mode mode, enum roard_client_acclev acclev) {
  struct roar_authfile * authfile = NULL;
@@ -2147,5 +1679,5 @@
   } else if ( strcmp(k, "-oN") == 0 ) {
    if ( action == START || action == RESTART ) {
-    if ( add_output(o_drv, o_dev, o_opts, o_prim, o_count) != -1 )
+    if ( output_add(o_drv, o_dev, o_opts, o_prim, o_count) != -1 )
      o_count++;
 
@@ -2245,5 +1777,5 @@
   } else if ( strcmp(k, "-mN") == 0 ) {
 #ifndef ROAR_WITHOUT_DCOMP_MIXER
-   if ( add_hwmixer(m_drv, m_dev, m_opts, m_prim, m_count) != -1 )
+   if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) != -1 )
     m_count++;
 
@@ -2652,5 +2184,5 @@
 #ifndef ROAR_WITHOUT_DCOMP_MIXER
  if ( m_drv != NULL ) {
-  if ( add_hwmixer(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) {
+  if ( hwmixer_add(m_drv, m_dev, m_opts, m_prim, m_count) == -1 ) {
    ROAR_ERR("main(*): adding mixer '%s' via '%s' failed!", m_dev, m_drv);
   }
@@ -2666,5 +2198,5 @@
 #endif
 
- if ( add_default_output(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) {
+ if ( output_add_default(o_drv, o_dev, o_opts, o_prim, o_count) == -1 ) {
   ROAR_ERR("Can not initialize default driver");
   return 1;
