Index: roard/streams.c
===================================================================
--- roard/streams.c	(revision 6052)
+++ roard/streams.c	(revision 0)
@@ -1,134 +1,8 @@
 //streams.c:
 
-/*
- *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2015
- *
- *  This file is part of roard a part of RoarAudio,
- *  a cross-platform sound system for both, home and professional use.
- *  See README for details.
- *
- *  This file is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3
- *  as published by the Free Software Foundation.
- *
- *  RoarAudio is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this software; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
 #include "roard.h"
-
-// declared 'extern'
-struct roar_stream_server * g_streams[ROAR_STREAMS_MAX];
-
-#define _CHECK_SID_RET(id,ret) if ( (id) < 0 || (id) > ROAR_STREAMS_MAX || g_streams[(id)] == NULL ) return (ret)
-#define _CHECK_SID(id)         _CHECK_SID_RET((id), -1)
-
-static int streams_thru_num     =  0;
-static int streams_sync_num     =  0;
-int streams_recsource_id = -1;
-
-static const struct rolestack * streams_rolestack = NULL;
-static int streams_role_num     =  0;
-
-
-static void _streams_change_state(struct roar_stream_server * s, const int new, const char * func) {
- register int id  = ROAR_STREAM(s)->id;
- register int old = s->state;
-
- s->state = new;
-
- if ( func == NULL ) {
-  func = "(unknown)";
- }
-
- ROAR_INFO("_streams_change_state[by %s](id=%i): stream state: %s->%s", ROAR_DBG_INFO_VERBOSE,
-            func,
-            ROAR_STREAM(s)->id,
-            roar_streamstate2str(old), roar_streamstate2str(new));
-
- roar_notify_core_emit_simple(ROAR_OE_BASICS_CHANGE_STATE, -1, id, ROAR_OT_STREAM, old, new, NULL, 0);
-}
-
-void streams_change_sync_num(int id, int diff) {
- struct roar_stream_server * ss;
- int i;
-
- if ( diff != 0 )
-  if ( streams_get_dir(id) != ROAR_DIR_OUTPUT )
-   return;
-
- ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Number of sync streams changed from %i to %i",
-           ROAR_DBG_INFO_VERBOSE,
-           id, diff,
-           streams_sync_num, streams_sync_num + diff);
- streams_sync_num += diff;
-
- if ( !streams_sync_num && alive ) {
-  ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Number of sync streams changed to zero. Bad.",
-            ROAR_DBG_INFO_VERBOSE, id, diff
-            );
-
-  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-   if ( (ss = g_streams[i]) == NULL )
-    continue;
-
-   if ( ROAR_STREAM(ss)->dir != ROAR_DIR_OUTPUT )
-    continue;
-
-   if ( !ss->ready )
-    continue;
-
-   if ( ss->state == ROAR_STREAMSTATE_CLOSING )
-    continue;
-
-   if ( streams_get_flag(i, ROAR_FLAG_PRIMARY) ) {
-    ROAR_DBG("streams_change_sync_num(*): try to set sync on primary stream %i", i);
-    streams_set_flag(i, ROAR_FLAG_SYNC);
-    if ( streams_sync_num )
-     return;
-   }
-  }
-
-  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-   if ( (ss = g_streams[i]) == NULL )
-    continue;
-
-   if ( ROAR_STREAM(ss)->dir != ROAR_DIR_OUTPUT )
-    continue;
-
-   if ( !ss->ready )
-    continue;
-
-   if ( ss->state == ROAR_STREAMSTATE_CLOSING )
-    continue;
-
-   if ( !streams_get_flag(i, ROAR_FLAG_PRIMARY) ) {
-    ROAR_DBG("streams_change_sync_num(*): try to set sync on non-primary stream %i", i);
-    streams_set_flag(i, ROAR_FLAG_SYNC);
-    if ( streams_sync_num )
-     return;
-   }
-  }
-
-  ROAR_INFO("streams_change_sync_num(id=%i, diff=%i): Can not auto set sync flag to an output. Very Bad",
-            ROAR_DBG_INFO_VERBOSE, id, diff
-            );
-  ROAR_WARN("streams_change_sync_num(id=%i, diff=%i): Lost all sync streams and failed to set a new one. Very Bad.",
-            id, diff);
- }
-}
 
 int streams_init (void) {
  int i;
-
- streams_rolestack = rolestack_get_role(-1); // get default
 
  for (i = 0; i < ROAR_STREAMS_MAX; i++)
@@ -152,19 +26,10 @@
 
 int streams_new    (void) {
- int i, j;
- struct roar_stream        * n = NULL;
- struct roar_stream_server * s = NULL;
-
-#ifdef ROAR_SUPPORT_LISTEN
- if ( g_terminate && !g_no_listen ) // don't accept new streams in case of termination state
-  return -1;
-#else
- if ( g_terminate )                 // don't accept new streams in case of termination state
-  return -1;
-#endif
+ int i;
+ struct roar_stream * n = NULL;
 
  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
   if ( g_streams[i] == NULL ) {
-   s = ROAR_STREAM_SERVER(n = ROAR_STREAM(roar_mm_malloc(sizeof(struct roar_stream_server))));
+   n = malloc(sizeof(struct roar_stream_server));
    if ( n == NULL ) {
     ROAR_ERR("streams_new(void): can not allocate memory for new stream: %s", strerror(errno));
@@ -173,75 +38,18 @@
    }
 
-   memset(s, 0, sizeof(struct roar_stream_server));
-
    n->id         = i;
    n->fh         = -1;
-   n->pos_rel_id = -1;
-/*
+//   n->pos_rel_id = i;
    n->database   = NULL;
    n->dataoff    = NULL;
    n->datalen    = 0;
    n->offset     = 0;
-*/
-   n->pos        = 0;
-
-   s->name            = NULL;
-
-   s->state           = ROAR_STREAMSTATE_INITING;
-
-   s->client          = -1;
-   s->socktype        = ROAR_SOCKET_TYPE_UNKNOWN;
-   s->buffer          = NULL;
-   s->need_extra      =  0;
-   s->output          = NULL;
-   s->is_new          =  1;
-   s->codecfilter     = -1;
-   s->pre_underruns   =  0;
-   s->post_underruns  =  0;
-   s->delay           =  0;
-   s->codec_orgi      = -1;
-   s->primary         =  0;
-   s->ready           =  0;
-   s->outputbuffer    = NULL;
-   s->prethru         = NULL;
-   s->mixer_stream    = -1;
-   s->role            = ROAR_ROLE_UNKNOWN;
-   s->parent_stream   = -1;
-   s->single_sink_c   =  0;
-   s->single_sink_self_c =  0;
-
-   s->mixer.scale     = 65535;
-   s->mixer.rpg_mul   = 1;
-   s->mixer.rpg_div   = 1;
-   for (j = 0; j < ROAR_MAX_CHANNELS; j++)
-    s->mixer.mixer[j] = 65535;
-
-#ifdef ROAR_SUPPORT_META
-   for (j = 0; j < ROAR_META_MAX_PER_STREAM; j++) {
-    s->meta[j].type   = ROAR_META_TYPE_NONE;
-    s->meta[j].key[0] = 0;
-    s->meta[j].value  = NULL;
-   }
-#endif
-
-   roar_vio_clear_calls(&(s->vio));
-   roar_vio_clear_calls(&(s->jumbo));
-   s->viop      = &(s->vio);
-   s->driver_id = -1;
-   s->flags     =  ROAR_FLAG_NONE;
-
-#ifndef ROAR_WITHOUT_DCOMP_MIXER
-   s->mixerstream =  NULL;
-#endif
-
-   s->rpgmode = ROAR_RPGMODE_DEFAULT;
-
-   //roardsp_fchain_init(&(s->fc));
-
-   g_streams[i] = s;
-   counters_inc(streams, 1);
-   ROAR_INFO("streams_new(void): New stream %i created (state=initing)", ROAR_DBG_INFO_VERBOSE, i);
-   ROAR_DBG("streams_new(void): n->id=%i", n->id);
-   roar_notify_core_emit_snoargs(ROAR_OE_BASICS_NEW, -1, i, ROAR_OT_STREAM);
+
+   ((struct roar_stream_server*)n)->client     = -1;
+   ((struct roar_stream_server*)n)->buffer     = NULL;
+   ((struct roar_stream_server*)n)->need_extra = 0;
+   ((struct roar_stream_server*)n)->output     = NULL;
+
+   g_streams[i] = (struct roar_stream_server*)n;
    ROAR_DBG("streams_new(void) = %i", i);
    return i;
@@ -253,154 +61,27 @@
 
 int streams_delete (int id) {
- struct roar_stream_server * s;
- int prim;
- int no_vio_close = 0;
- int i;
- int client;
-
- _CHECK_SID(id);
-
- if ( (s = g_streams[id]) == NULL )
+ if ( g_streams[id] == NULL )
   return 0;
 
  ROAR_DBG("streams_delete(id=%i) = ?", id);
- ROAR_DBG("streams_delete(id=%i): g_streams[id]->id=%i", id, ROAR_STREAM(s)->id);
-
- // in case we are allready closing it...
- if ( s->state == ROAR_STREAMSTATE_CLOSING )
-  return 0;
-
- _streams_change_state(s, ROAR_STREAMSTATE_CLOSING, "streams_delete");
- roar_notify_core_emit_snoargs(ROAR_OE_BASICS_DELETE, -1, id, ROAR_OT_STREAM);
-
- streams_set_role(id, -1);
-
- prim = s->primary;
-
- if ( prim )
-  alive = 0;
-
- if ( s->flags & ROAR_FLAG_SINGLESINK )
-  streams_set_single_sink(id, 1);
-
- counters_inc(streams, -1);
-
- if ( streams_get_flag(id, ROAR_FLAG_RECSOURCE) == 1 )
-  streams_reset_flag(id, ROAR_FLAG_RECSOURCE);
-
- for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-  if ( g_streams[i] != NULL && ROAR_STREAM(g_streams[i])->pos_rel_id == id ) {
-   switch (ROAR_STREAM(g_streams[i])->dir) {
-    case ROAR_DIR_THRU:
-    case ROAR_DIR_RAW_IN:
-      if ( i != id )
-       streams_delete(i);
-     break;
-    default:
-      if ( streams_get_flag(i, ROAR_FLAG_VIRTUAL) == 1 ) {
-       if ( i != id ) {
-        ROAR_DBG("streams_delete(id=%i): Deleting virtual child stream %i", id, i);
-        streams_delete(i);
-       }
-      } else {
-       ROAR_STREAM(g_streams[i])->pos_rel_id = -1;
-      }
-   }
-  }
- }
-
- if ( ROAR_STREAM(s)->dir == ROAR_DIR_THRU )
-  streams_thru_num--;
-
- if ( streams_get_flag(id, ROAR_FLAG_VIRTUAL) == 1 ) {
-  // we un-group the stream here to avoid a client deleting the parent deleting the client deleting ...
-  i      = ROAR_STREAM(s)->pos_rel_id;
-  if ( i != -1 ) {
-   ROAR_STREAM(s)->pos_rel_id = -1;
-   client = streams_get_client(id);
-   streams_set_client(id, -1);
-   ROAR_DBG("streams_delete(id=%i): Stream has flag virtual, notifying parent stream %i", id, i);
-   streams_ctl(i, ROAR_CODECFILTER_CTL_VIRTUAL_DELETE|ROAR_STREAM_CTL_TYPE_INT, &id);
-   ROAR_DBG("streams_delete(id=%i): Notify send to stream %i", id, i);
-   streams_set_client(id, client);
-   ROAR_STREAM(s)->pos_rel_id = i;
-  }
- }
-
-#ifdef ROAR_SUPPORT_META
- // delete meta data form other meta streams if needed
- if ( streams_get_flag(id, ROAR_FLAG_META) == 1 ) {
-  ROAR_DBG("streams_delete(id=%i): deleting meta stream!", id);
-  stream_meta_clear(id);
-  stream_meta_finalize(id);
- }
-#endif
-
- if ( s->codecfilter != -1 ) {
-  codecfilter_close(s->codecfilter_inst, s->codecfilter);
-  s->codecfilter_inst = NULL;
-  s->codecfilter = -1;
- }
-
- if ( s->driver_id != -1 ) {
-  driver_closevio(&(s->vio), s->driver_id);
-  roar_vio_clear_calls(&(s->vio));
-  s->driver_id = -1;
-  no_vio_close =  1;
- }
-
-#ifndef ROAR_WITHOUT_DCOMP_MIXER
- if ( s->mixerstream != NULL ) {
-  hwmixer_close(id);
- }
-#endif
-
- // all IO is no disconnected:
- s->ready = 0;
-
- // re-try reset after all IO is disconnected.
- if ( streams_get_flag(id, ROAR_FLAG_RECSOURCE) == 1 )
-  streams_reset_flag(id, ROAR_FLAG_RECSOURCE);
-
- //roardsp_fchain_uninit(&(s->fc));
-
- if ( s->client != -1 ) {
+
+ if ( g_streams[id]->client != -1 ) {
   ROAR_DBG("streams_delete(id=%i): Stream is owned by client %i", id, g_streams[id]->client);
-  client_stream_delete(s->client, id);
- }
-
- stream_outputbuffer_destroy(id);
- stream_prethru_destroy(id);
-
- if ( s->buffer != NULL )
-  roar_buffer_free(s->buffer);
-
- if ( s->output != NULL )
-  roar_mm_free(s->output);
-
-/*
- if ( ROAR_STREAM(s)->fh != -1 )
-  close(ROAR_STREAM(s)->fh);
-*/
-
- if ( s->flags & ROAR_FLAG_SYNC )
-  streams_change_sync_num(id, -1);
-
- if ( !no_vio_close )
-  roar_vio_close(s->viop);
-
- if ( s->name != NULL )
-  roar_mm_free(s->name);
-
- roar_mm_free(s);
+  client_stream_delete(g_streams[id]->client, id);
+ }
+
+ if ( g_streams[id]->buffer != NULL )
+  roar_buffer_free(g_streams[id]->buffer);
+
+ if ( g_streams[id]->output != NULL )
+  free(g_streams[id]->output);
+
+ if ( ROAR_STREAM(g_streams[id])->fh != -1 )
+  close(ROAR_STREAM(g_streams[id])->fh);
+
+ free(g_streams[id]);
 
  g_streams[id] = NULL;
 
- if ( prim && alive ) {
-  alive = 0;
-  clean_quit();
- }
-
- ROAR_INFO("streams_delete(id=%i): stream deleted", ROAR_DBG_INFO_VERBOSE, id);
  ROAR_DBG("streams_delete(id=%i) = 0", id);
  return 0;
@@ -408,8 +89,7 @@
 
 int streams_set_client (int id, int client) {
-
- _CHECK_SID(id);
-
- ROAR_DBG("streams_set_client(id=%i): g_streams[id]->id=%i", id, ROAR_STREAM(g_streams[id])->id);
+ if ( g_streams[id] == NULL )
+  return -1;
+
  g_streams[id]->client = client;
 
@@ -417,521 +97,21 @@
 }
 
-int streams_get_client (int id) {
- _CHECK_SID(id);
-
- return g_streams[id]->client;
-}
-
-int streams_set_dir    (int id, int dir, int defaults) {
- struct roar_stream_server * ss;
- int mixer;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL ) {
-  ROAR_ERR("streams_set_dir(id=%i, dir=%i, defaults=%i) = -1 // error=NOENT", id, dir, defaults);
-  roar_err_set(ROAR_ERROR_NOENT);
-  return -1;
- }
-
- ROAR_STREAM(ss)->dir = dir;
-
- if ( dir == ROAR_DIR_THRU )
-  streams_thru_num++;
-
- if ( defaults ) {
-  if ( dir <= 0 || dir >= ROAR_DIR_DIRIDS ) {
-   ROAR_ERR("streams_set_dir(id=%i, dir=%i, defaults=%i) = -1 // error=INVAL", id, dir, defaults);
-   roar_err_set(ROAR_ERROR_INVAL);
-   return -1;
-  }
-
-  ROAR_DBG("streams_set_dir(*): g_config->streams[dir=%i].flags = 0x%.4x", dir, g_config->streams[dir].flags);
-
-  if ( streams_set_flag(id, g_config->streams[dir].flags) == -1 ) {
-   ROAR_WARN("streams_set_dir(*) = -1 // can not set stream flags");
-   return -1;
-  }
-
-   ss->mixer.scale   = g_config->streams[dir].mixer.scale;
-   ss->mixer.rpg_mul = g_config->streams[dir].mixer.rpg_mul;
-   ss->mixer.rpg_div = g_config->streams[dir].mixer.rpg_div;
- }
-
- if ( dir != ROAR_DIR_MIXING ) {
-  switch (streams_get_subsys(id)) {
-   case ROAR_SUBSYS_WAVEFORM:
-     streams_set_mixer_stream(id, g_waveform_mixer.stream);
-     roardsp_chanlist_init(ss->chanmap.in,  ROAR_STREAM(ss)->info.channels, ROARDSP_CHANLIST_MAP_ROARAUDIO);
-    break;
-#ifndef ROAR_WITHOUT_DCOMP_MIDI
-   case ROAR_SUBSYS_MIDI:
-     roardsp_chanlist_init(ss->chanmap.in,  ROAR_STREAM(ss)->info.channels, ROARDSP_CHANLIST_MAP_MIDI);
-     streams_set_mixer_stream(id, g_midi_mixer.stream);
-    break;
-#endif
-#ifndef ROAR_WITHOUT_DCOMP_LIGHT
-   case ROAR_SUBSYS_LIGHT:
-     streams_set_mixer_stream(id, g_light_mixer.stream);
-    break;
-#endif
-  }
-
-  if ( streams_get_ssdir(id) & STREAM_DIR_OUT ) {
-   if ( (mixer = streams_get_mixer_stream(id)) != -1 ) {
-    if ( g_streams[mixer]->flags & ROAR_FLAG_SINGLESINK ) {
-     streams_set_mixer_stream(id, -1);
-     return -1;
-    }
-   }
-  }
-
-  memcpy(ss->chanmap.out, ss->chanmap.in, sizeof(ss->chanmap.out));
-  streams_set_map(id, NULL, 0);
+int streams_set_fh     (int id, int fh) {
+ if ( g_streams[id] == NULL )
+  return -1;
+
+ ((struct roar_stream *)g_streams[id])->fh = fh;
+
+ if ( ((struct roar_stream *)g_streams[id])->dir == ROAR_DIR_FILTER ) {
+  return 0;
  } else {
-  streams_set_mixer_stream(id, id);
- }
-
- ROAR_DBG("streams_set_dir(*) = 0");
- return 0;
-}
-
-int streams_get_dir    (int id) {
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- return ROAR_STREAM(ss)->dir;
-}
-
-int streams_set_mixer_stream(int id, int mixer) {
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- ss->mixer_stream = mixer;
-
- return 0;
-}
-
-int streams_get_mixer_stream(int id) {
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- return ss->mixer_stream;
-}
-
-static int streams_set_role_handle(int id) {
-   switch (streams_rolestack->action) {
-    case RS_ERROR: /* nothing to do */; break;
-    case RS_MIX:   /* nothing to do */; break;
-    case RS_KICK:  streams_delete(id);  break;
-    case RS_MUTE:  streams_set_flag(id, ROAR_FLAG_MUTE);  break;
-    case RS_PAUSE: streams_set_flag(id, ROAR_FLAG_PAUSE); break;
-   }
- return 0;
-}
-
-int streams_set_role   (int id, int role) {
- struct roar_stream_server * ss;
- const struct rolestack * rs;
- int old_role;
- int i;
-
- ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role);
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- old_role = ss->role;
- ss->role = role;
-
- ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role);
-
- if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY )
-  return 0;
-
- ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role);
-
- if ( old_role == role ) {
-  ROAR_DBG("streams_set_role(id=%i, role=%i) = 0", id, role);
-  return 0;
- }
-
- if ( old_role != role && old_role != -1 && role != -1 ) {
-  streams_set_role(id, -1);
-  streams_set_role(id, role);
- }
-
- ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role);
-
- if ( ss->role != -1 && ss->role == streams_rolestack->role ) {
-  ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role);
-
-  streams_role_num--;
-  if ( streams_role_num == 0 ) {
-   streams_rolestack = rolestack_get_role(-1); // get default
-   for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-    if ( (ss = g_streams[i]) == NULL )
-     continue;
-    if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY )
-     continue;
-    if ( ss->role == -1 )
-     continue;
-    rs = rolestack_get_role(ss->role);
-    if ( rs->index > streams_rolestack->role ) {
-     streams_rolestack = rs;
-    }
-   }
-   for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-    if ( (ss = g_streams[i]) == NULL )
-     continue;
-    if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY )
-     continue;
-    if ( ss->role == streams_rolestack->role )
-     streams_role_num++;
-   }
-  }
- } else if ( role != -1 ) {
-  ROAR_DBG("streams_set_role(id=%i, role=%i) = ?", id, role);
-
-  rs = rolestack_get_role(role);
-  ROAR_DBG("streams_set_role(id=%i, role=%i): rs->index=%i, streams_rolestack->index=%i", id, role, rs->index, streams_rolestack->index);
-  if ( rs->index == streams_rolestack->index ) {
-   ROAR_DBG("streams_set_role(id=%i, role=%i): rs->index=%i, streams_rolestack->index=%i", id, role, rs->index, streams_rolestack->index);
-   streams_role_num++;
-  } else if ( rs->index > streams_rolestack->index ) {
-   ROAR_DBG("streams_set_role(id=%i, role=%i): rs=%p{.index=%i, .action=%s}", id, role, rs, rs->index, rolestack_action2str(rs->action));
-   streams_role_num  = 1;
-   streams_rolestack = rs;
-   for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-    if ( (ss = g_streams[i]) == NULL )
-     continue;
-    if ( ROAR_STREAM(ss)->dir != ROAR_DIR_PLAY )
-     continue;
-    rs = rolestack_get_role(ss->role);
-    ROAR_DBG("streams_set_role(id=%i, role=%i): i=%i, rs->index=%i, streams_rolestack->index=%i", id, role, i, rs->index, streams_rolestack->index);
-    if ( rs->index < streams_rolestack->index )
-     streams_set_role_handle(i);
-   }
-  } else {
-   ROAR_DBG("streams_set_role(id=%i, role=%i): streams_rolestack->action=%s", id, role, rolestack_action2str(streams_rolestack->action));
-   streams_set_role_handle(id);
-  }
- }
-
- ROAR_DBG("streams_set_role(id=%i, role=%i) = 0", id, role);
- return 0;
-}
-
-int streams_get_subsys (int id) {
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( ROAR_STREAM(ss)->dir == ROAR_DIR_THRU )
-  return streams_get_subsys(ROAR_STREAM(ss)->pos_rel_id);
-
- return streams_dir2subsys(ROAR_STREAM(ss)->dir);
-}
-
-int streams_dir2subsys (int dir) {
- switch (dir) {
-  case ROAR_DIR_PLAY:
-  case ROAR_DIR_RECORD:
-  case ROAR_DIR_MONITOR:
-  case ROAR_DIR_FILTER:
-  case ROAR_DIR_OUTPUT:
-  case ROAR_DIR_BIDIR:
-  case ROAR_DIR_RECPLAY:
-    return ROAR_SUBSYS_WAVEFORM;
-   break;
-  case ROAR_DIR_MIDI_IN:
-  case ROAR_DIR_MIDI_OUT:
-    return ROAR_SUBSYS_MIDI;
-   break;
-  case ROAR_DIR_LIGHT_IN:
-  case ROAR_DIR_LIGHT_OUT:
-    return ROAR_SUBSYS_LIGHT;
-   break;
-  case ROAR_DIR_RAW_IN:
-  case ROAR_DIR_RAW_OUT:
-    return ROAR_SUBSYS_RAW;
-   break;
-  case ROAR_DIR_COMPLEX_IN:
-  case ROAR_DIR_COMPLEX_OUT:
-    return ROAR_SUBSYS_COMPLEX;
-   break;
-  case ROAR_DIR_MIXING:
-    return ROAR_SUBSYS_NONE;
-   break;
- }
-
- return -1;
-}
-
-int streams_get_ssdir  (int id) {
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- switch (ROAR_STREAM(ss)->dir) {
-  case ROAR_DIR_PLAY:
-  case ROAR_DIR_MIDI_IN:
-  case ROAR_DIR_LIGHT_IN:
-  case ROAR_DIR_RAW_IN:
-  case ROAR_DIR_COMPLEX_IN:
-    return STREAM_DIR_IN;
-   break;
-  case ROAR_DIR_RECORD:
-  case ROAR_DIR_MONITOR:
-  case ROAR_DIR_OUTPUT:
-  case ROAR_DIR_MIDI_OUT:
-  case ROAR_DIR_LIGHT_OUT:
-  case ROAR_DIR_RAW_OUT:
-  case ROAR_DIR_COMPLEX_OUT:
-    return STREAM_DIR_OUT;
-   break;
-  case ROAR_DIR_MIXING:
-    return STREAM_DIR_NONE;
-   break;
-  case ROAR_DIR_FILTER:
-  case ROAR_DIR_BIDIR:
-  case ROAR_DIR_RECPLAY:
-    return STREAM_DIR_BIDIR;
-   break;
-  case ROAR_DIR_THRU:
-    return streams_get_ssdir(ROAR_STREAM(ss)->pos_rel_id);
-   break;
- }
-
- return -1;
-}
-
-#define _err() streams_delete(id); return -1;
-int streams_new_virtual (int parent, struct roar_stream_server ** stream) {
- struct roar_stream_server * parent_ss, * ss;
- struct roar_stream        * parent_s , *  s;
- int id = -1;
- int client, dir;
-
- if ( streams_get(parent, &parent_ss) == -1 )
-  return -1;
-
- if ( (client = streams_get_client(parent)) == -1 )
-  return -1;
-
- if ( (dir = streams_get_dir(parent)) == -1 )
-  return -1;
-
- if ( (id = streams_new()) == -1 ) {
-  return -1;
- }
-
- if ( client_stream_add(client, id) == -1 ) {
-  _err();
- }
-
- if ( streams_get(id, &ss) == -1 ) {
-  _err();
- }
-
- if ( streams_set_dir(id, dir, 1) == -1 ) {
-  _err();
- }
-
- s        = ROAR_STREAM(       ss);
- parent_s = ROAR_STREAM(parent_ss);
-
- s->pos_rel_id = parent;
-
- if ( streams_set_rawflag(id, ROAR_FLAG_VIRTUAL) == -1 ) {
-  _err();
- }
-
- if ( stream != NULL )
-  *stream = ss;
-
- return id;
-}
-#undef _err
-
-int streams_set_fh     (int id, int fh) {
- struct roar_stream_server * ss;
- struct roar_stream        * s;
- int dir;
- int nonblock = 1;
-
- _CHECK_SID(id);
-
- if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL )
-  return -1;
-
- if ( ss->ready && !(s->fh == -1 && fh == -2) ) {
-  ROAR_DBG("streams_set_fh(id=%i, fh=%i) = -1 // try to set fh for stream which is already ready", id, fh);
-  return -1;
- }
-
- dir = s->dir;
-
- ROAR_DBG("streams_set_fh(id=%i, fh=%i): g_streams[id]->id=%i", id, fh, s->id);
-
- s->fh = fh;
-
- ROAR_DBG("streams_set_fh(id=%i, fh=%i): driverID=%i", id, fh, ss->driver_id);
-
- if ( ss->driver_id == -1 && fh != -2 ) {
-#ifndef ROAR_TARGET_WIN32
-  roar_vio_open_fh(&(ss->vio), fh);
-#else
-  roar_vio_open_fh_socket(&(ss->vio), fh);
-#endif
- }
-
- ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh);
-
- switch (dir) {
-  case ROAR_DIR_THRU:
-  case ROAR_DIR_RAW_IN:
-  case ROAR_DIR_RAW_OUT:
-   break;
-  default:
-    ROAR_DBG("streams_set_fh(id=%i, fh=%i): codec=%s(%i)", id, fh, roar_codec2str(s->info.codec), s->info.codec);
-    if ( codecfilter_open(&(ss->codecfilter_inst), &(ss->codecfilter), NULL,
-                     s->info.codec, ss) == -1 ) {
-     streams_delete(id); // TODO: FIXME: is this correct? shoudn't we return -1 in any case here?
-     ROAR_DBG("streams_set_fh(id=%i, fh=%i) = -1", id, fh);
-     return -1;
-    }
-   break;
- }
-
- ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh);
-
- if ( fh == -2 ) {
-  ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh);
-  if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_GET_READ_FH, &fh) == -1 ) {
-   fh = -2;
-  } else {
-   ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh);
-   if ( fh < 0 ) {
-    fh = -2;
-   } else {
-    s->fh = fh;
-   }
-  }
- }
-
- ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh);
-
- if ( fh == -1 || fh == -2 ) { // yes, this is valid, indecats full vio!
-  ss->ready = 1;
-  //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
-  _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh");
-  ROAR_DBG("streams_set_fh(id=%i, fh=%i): s->fh=%i", id, fh, s->fh);
-  ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh);
-  return 0;
- }
-
- ROAR_DBG("streams_set_fh(id=%i, fh=%i) = ?", id, fh);
-
- switch (dir) {
-  case ROAR_DIR_MONITOR:
-  case ROAR_DIR_RECORD:
-  case ROAR_DIR_OUTPUT:
-  case ROAR_DIR_MIDI_OUT:
-  case ROAR_DIR_LIGHT_OUT:
-  case ROAR_DIR_RAW_OUT:
-    ROAR_SHUTDOWN(fh, SHUT_RD);
-   break;
- }
-
- if ( dir >= ROAR_DIR_DIRIDS )
-  return -1;
-
- if ( g_config->streams[dir].flags & ROAR_FLAG_SYNC ) {
-  switch (dir) {
-   case ROAR_DIR_BRIDGE:
-   case ROAR_DIR_MIDI_OUT:
-    break;
-   default:
-     nonblock = 0;
-    break;
-  }
- }
-
-
- if ( !nonblock ) {
-  ss->ready = 1;
-  //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
-  _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh");
-
-  ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh);
-  return 0;
- } else {
-#ifndef ROAR_TARGET_WIN32
-  if ( roar_socket_nonblock(fh, ROAR_SOCKET_NONBLOCK) == -1 )
-   return -1;
-#endif
-
-  ss->ready = 1;
-  //ROAR_INFO("streams_set_fh(id=%i, fh=%i): stream state: %s->new", ROAR_DBG_INFO_VERBOSE, id, fh, roar_streamstate2str(ss->state));
-  _streams_change_state(ss, ROAR_STREAMSTATE_NEW, "streams_set_fh");
-
-  ROAR_DBG("streams_set_fh(id=%i, fh=%i) = 0", id, fh);
-  return 0;
- }
-}
-
-int streams_get_fh     (int id) {
- int ret;
-
- ROAR_DBG("streams_get_fh(id=%i) = ?", id);
-
- _CHECK_SID(id);
-
- ROAR_DBG("streams_get_fh(id=%i) = ?", id);
-
- ret = ROAR_STREAM(g_streams[id])->fh;
-
- ROAR_DBG("streams_get_fh(id=%i) = %i", id, ret);
-
- return ret;
-}
-
-int streams_set_null_io(int id) {
- struct roar_stream_server * ss;
- struct roar_stream        * s;
-
- _CHECK_SID(id);
-
- if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL )
-  return -1;
-
- s->fh = -1;
-
- return 0;
-}
+  return roar_socket_nonblock(fh, ROAR_SOCKET_NONBLOCK);
+ }
+}
+
 
 int streams_get    (int id, struct roar_stream_server ** stream) {
- _CHECK_SID(id);
+ if ( g_streams[id] == NULL )
+  return -1;
 
  *stream = g_streams[id];
@@ -940,863 +120,8 @@
 }
 
-int streams_get_clientobj (int id, struct roar_stream        ** stream) {
- _CHECK_SID(id);
-
- *stream = ROAR_STREAM(g_streams[id]);
-
- return 0;
-}
-
-int streams_set_socktype (int id, int socktype) {
- _CHECK_SID(id);
-
- g_streams[id]->socktype = socktype;
-
- return 0;
-}
-
-int streams_get_socktype (int id) {
- _CHECK_SID(id);
-
- return g_streams[id]->socktype;
-}
-
-int streams_is_ready     (int id) {
- _CHECK_SID(id);
-
- return g_streams[id]->ready;
-}
-
-int streams_is_new       (int id) {
- _CHECK_SID(id);
-
- return g_streams[id]->ready;
-}
-
-int streams_set_primary (int id, int prim) {
- _CHECK_SID(id);
-
- g_streams[id]->primary = prim;
-
- return 0;
-}
-
-int streams_mark_primary (int id) {
- return streams_set_primary(id, 1);
-}
-
-int streams_set_sync     (int id, int sync) {
- int fh = streams_get_fh(id);
-
- ROAR_DBG("streams_set_sync(id=%i, sync=%i) = ?", id, sync);
-
- _CHECK_SID(id);
-
- if ( fh > -1 ) {
-  if ( roar_socket_nonblock(fh, sync ? ROAR_SOCKET_BLOCK : ROAR_SOCKET_NONBLOCK) == -1 )
-   return -1;
-
-#ifdef ROAR_FDATASYNC
-  ROAR_FDATASYNC(fh);
-#endif
-
-  return 0;
- } else {
-  return roar_vio_nonblock(&(g_streams[id]->vio), sync);
- }
-}
-
-int streams_set_mmap (int id, int reset) {
- int use = !reset;
-
- _CHECK_SID(id);
-
- return roar_vio_ctl(&(g_streams[id]->vio), ROAR_VIO_CTL_SET_UMMAP, &use);
-}
-
-int streams_set_single_sink(int id, int reset) {
- struct roar_stream_server * self_ss, * ss;
- struct roar_stream                   *  s;
- int mixer;
- size_t count = 0;
- int i;
- int ssdir;
-
- /* FIXME: This code only uses one refc for the mixer shared with the inputs.
-  *        If the flag is unset on the mixer but got set by the sources the counter
-  *        may/will become corrupted.
-  */
-
- _CHECK_SID(id);
-
- self_ss = g_streams[id];
-
- mixer = self_ss->mixer_stream;
-
- ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer);
-
- if ( !reset && id != mixer )
-  if ( self_ss->flags & ROAR_FLAG_SINGLESINK )
-   return 0;
-
- if ( id == mixer ) {
-  if ( reset ) {
-   if ( self_ss->single_sink_self_c ) {
-    ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer);
-    self_ss->single_sink_self_c--;
-    self_ss->single_sink_c--;
-    if ( self_ss->single_sink_c == 0 ) {
-     ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer);
-     self_ss->flags |= ROAR_FLAG_SINGLESINK;
-     self_ss->flags -= ROAR_FLAG_SINGLESINK;
-    }
-    return 0;
-   } else {
-    return -1;
-   }
-  } else {
-   if ( self_ss->single_sink_c ) {
-    self_ss->single_sink_self_c++;
-    self_ss->single_sink_c++;
-    return 0;
-   }
-  }
- } else if ( reset ) {
-  ROAR_DBG("streams_set_single_sink(id=%i, reset=%i): mixer=%i", id, reset, mixer);
-
-  if ( (ss = g_streams[mixer]) == NULL )
-   return -1;
-
-  if ( ss->single_sink_c == 0 )
-   return -1;
-  ss->single_sink_c--;
-
-  if ( ss->single_sink_c == 0 ) {
-    self_ss->flags |= ROAR_FLAG_SINGLESINK;
-    self_ss->flags -= ROAR_FLAG_SINGLESINK;
-         ss->flags |= ROAR_FLAG_SINGLESINK;
-         ss->flags -= ROAR_FLAG_SINGLESINK;
-  }
-
-  return 0;
- }
-
-
-
- for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-  if ( (s = ROAR_STREAM((ss = g_streams[i]))) != NULL ) {
-   if ( s->dir == ROAR_DIR_THRU )
-    if ( s->pos_rel_id == id || s->pos_rel_id == mixer || g_streams[s->pos_rel_id]->mixer_stream == mixer )
-     return -1;
-
-   if ( ss->mixer_stream != mixer )
-    continue;
-
-   ssdir = streams_get_ssdir(i);
-
-   if ( ssdir & STREAM_DIR_OUT )
-    count++;
-  }
- }
-
- if ( count > 1 )
-  return -1;
-
- ss = g_streams[mixer];
-
- if ( id == mixer )
-  ss->single_sink_self_c++;
-
- ss->single_sink_c++;
-
- self_ss->flags |= ROAR_FLAG_SINGLESINK;
-      ss->flags |= ROAR_FLAG_SINGLESINK;
-
- return 0;
-}
-
-int streams_set_flag     (int id, uint32_t flag) {
- int parent;
- int tmp;
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- _CHECK_SID(id);
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_IMMUTABLE )
-  flag |= ROAR_FLAG_PRIMARY;
-
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- // check if flags we are going to change are protected:
- if ( g_streams[id]->flags_protection & flag )
-  return -1;
-
- flag |= g_streams[id]->flags;
- flag -= g_streams[id]->flags;
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_MMAP ) {
-  if ( streams_set_mmap(id, 0) == -1 ) {
-   flag -= ROAR_FLAG_MMAP;
-   return -1;
-  }
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_PRIMARY ) {
-  streams_set_primary(id, 1);
-  flag -= ROAR_FLAG_PRIMARY;
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_SINGLESINK ) {
-  if ( streams_set_single_sink(id, 0) == -1 ) {
-   return -1;
-  }
-  flag -= ROAR_FLAG_SINGLESINK;
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_VIRTUAL ) {
-  if ( (parent = ROAR_STREAM(g_streams[id])->pos_rel_id) == -1 )
-   return -1;
-
-  if ( streams_ctl(parent, ROAR_CODECFILTER_CTL_VIRTUAL_NEW|ROAR_STREAM_CTL_TYPE_INT, &id) == -1 ) {
-//   flag -= ROAR_FLAG_VIRTUAL;
-   return -1;
-  }
-
-  if ( client_stream_move(streams_get_client(parent), id) == -1 ) {
-   return -1;
-  }
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_SYNC ) {
-  ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-  switch (ROAR_STREAM(g_streams[id])->dir) {
-   // for this stream types the flag is used in the subsystem:
-   case ROAR_DIR_BRIDGE:
-   case ROAR_DIR_MIDI_OUT:
-    break;
-
-   // normal behavor (vio blocking):
-   default:
-     ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-     // the fh is updated as soon as the fh get ready in case the default ask to set sync
-     if ( g_streams[id]->ready || (!g_streams[id]->ready && !(g_config->streams[ROAR_STREAM(g_streams[id])->dir].flags & ROAR_FLAG_SYNC)) ) {
-      ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-      if ( streams_set_sync(id, 1) == -1 ) {
-       ROAR_WARN("streams_set_flag(id=%i, flag=0x%.8X): Can not set SYNC flag.", id, flag);
-       flag -= ROAR_FLAG_SYNC;
-      }
-     }
-    break;
-  }
-  ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
-  if ( flag & ROAR_FLAG_SYNC ) {
-   g_streams[id]->flags |= ROAR_FLAG_SYNC;
-   streams_change_sync_num(id, +1);
-  }
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_HWMIXER ) { // currently not supported -> ignored
-  g_streams[id]->flags |= flag;
-  if ( streams_set_mixer(id) == -1 ) {
-   g_streams[id]->flags -= flag;
-   return -1;
-  }
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( flag & ROAR_FLAG_RECSOURCE ) {
-  if ( streams_recsource_id != -1 ) {
-   if ( streams_reset_flag(streams_recsource_id, ROAR_FLAG_RECSOURCE) == -1 )
-    return -1;
-  }
-
-  if ( g_streams[id]->ready ) {
-   tmp = 1;
-   if ( stream_vio_ctl(id, ROAR_VIO_CTL_SET_RECORD, &tmp) == -1 )
-    return -1;
-  }
-
-  streams_recsource_id = id;
- }
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- g_streams[id]->flags |= flag;
-
-#ifdef ROAR_SUPPORT_META
- if ( flag & ROAR_FLAG_META )
-  stream_meta_finalize(id);
-#endif
-
- ROAR_DBG("streams_set_flag(id=%i, flag=0x%.8X) = 0", id, flag);
-
- return 0;
-}
-
-int streams_set_rawflag  (int id, uint32_t flag) {
- _CHECK_SID(id);
-
- g_streams[id]->flags |= flag;
-
- if ( flag & ROAR_FLAG_SYNC )
-  streams_change_sync_num(id, +1);
-
- return 0;
-}
-
-int streams_reset_flag   (int id, uint32_t flag) {
- int tmp;
-
- ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- _CHECK_SID(id);
-
- // check if flags we are going to change are protected:
- if ( g_streams[id]->flags_protection & flag )
-  return -1;
-
- if ( g_streams[id]->flags & ROAR_FLAG_IMMUTABLE ) {
-  flag |= ROAR_FLAG_PRIMARY;
-  flag -= ROAR_FLAG_PRIMARY;
- }
-
- flag &= g_streams[id]->flags;
-
- ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
- if ( (flag & ROAR_FLAG_RECSOURCE) && streams_recsource_id == id ) {
-  if ( g_streams[id]->ready ) {
-   tmp = 0;
-   if ( stream_vio_ctl(id, ROAR_VIO_CTL_SET_RECORD, &tmp) == -1 ) {
-    if ( alive ) { // do not warn if we are shutting down anyway.
-     ROAR_WARN("streams_reset_flag(id=%i, flag=0x%.8X): Driver refused to reset record flag.", id, flag);
-    }
-    ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = -1", id, flag);
-    return -1;
-   }
-  }
-
-  streams_recsource_id = -1;
- }
-
- ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = ?", id, flag);
-
-
- if ( flag & ROAR_FLAG_MMAP ) {
-  if ( streams_set_mmap(id, 1) == -1 ) {
-   flag -= ROAR_FLAG_MMAP;
-   return -1;
-  }
- }
-
- if ( flag & ROAR_FLAG_PRIMARY ) {
-  streams_set_primary(id, 0);
-  flag -= ROAR_FLAG_PRIMARY;
- }
-
- if ( flag & ROAR_FLAG_SINGLESINK ) {
-  if ( streams_set_single_sink(id, 1) == -1 ) {
-   return -1;
-  }
-  flag -= ROAR_FLAG_SINGLESINK;
- }
-
- if ( flag & ROAR_FLAG_SYNC ) {
-  // we refuse to reset the flag on FILTER streams
-  if ( streams_get_dir(id) == ROAR_DIR_FILTER ) {
-//   flags -= ROAR_FLAG_SYNC;
-   return -1;
-  } else {
-   if ( streams_set_sync(id, 0) == -1 )
-    return -1;
-
-   g_streams[id]->flags |= ROAR_FLAG_SYNC;
-   g_streams[id]->flags -= ROAR_FLAG_SYNC;
-   flag -= ROAR_FLAG_SYNC;
-   streams_change_sync_num(id, -1);
-  }
- }
-
- g_streams[id]->flags |= flag;
- g_streams[id]->flags -= flag;
-
- ROAR_DBG("streams_reset_flag(id=%i, flag=0x%.8X) = 0", id, flag);
-
- return 0;
-}
-
-int streams_get_flag     (int id, uint32_t flag) {
- _CHECK_SID(id);
-
- return g_streams[id]->flags & flag ? 1 : 0;
-}
-
-int streams_protect_flag (int id, uint32_t flag) {
- _CHECK_SID(id);
-
- g_streams[id]->flags_protection |= flag;
-
- return 0;
-}
-
-int streams_set_name     (int id, char * name) {
- char * str;
-
- _CHECK_SID(id);
-
- if ( (str = roar_mm_strdup(name)) == NULL )
-  return -1;
-
- if ( g_streams[id]->name != NULL )
-  roar_mm_free(g_streams[id]->name);
-
- g_streams[id]->name = str;
-
- return 0;
-}
-
-char * streams_get_name  (int id) {
- _CHECK_SID_RET(id, NULL);
-
- return g_streams[id]->name;
-}
-
-
-int streams_calc_delay    (int id) {
- struct roar_stream_server * ss;
- struct roar_stream        * s;
- register uint_least32_t d = 0;
- uint_least32_t t[1];
- uint64_t       tmp;
-
- _CHECK_SID(id);
-
- if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL )
-  return -1;
-
- // mixer store there value in ss->delay directly
- if ( s->dir == ROAR_DIR_MIXING )
-  return 0;
-
-#if 0
- // this only confuses the user...
- if ( ss->mixer_stream != id ) {
-  if ( streams_calc_delay(ss->mixer_stream) != -1 ) {
-   d += g_streams[ss->mixer_stream]->delay; // in case we can calc the delay
-                                            // the stream must exist, so no check here
-  }
- }
-#endif
-
- if ( ss->codecfilter != -1 ) {
-  if ( codecfilter_delay(ss->codecfilter_inst, ss->codecfilter, t) != -1 )
-   d += *t;
- }
-
- if ( ss->vio.ctl != NULL ) {
-  if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_GET_DELAY, t) != -1 ) { // *t is in byte
-   ROAR_DBG("streams_calc_delay(id=%i): VIO delay in byte: %i", id, *t);
-   tmp = *t;
-   tmp *= 1000000; // musec per sec
-   tmp /= s->info.rate * s->info.channels * (s->info.bits/8);
-   ROAR_DBG("streams_calc_delay(id=%i): VIO delay in musec: %llu", id, tmp);
-
-   d += tmp;
-  }
- }
-
- ROAR_DBG("streams_calc_delay(id=%i): delay in musec: %i", id, d);
-
- ss->delay = d;
-
- return 0;
-}
-
-int streams_set_mixer    (int id) {
- struct roar_stream_server * ss;
- struct roar_stream_server * pmss;
- int i;
- int subsys;
- int tsubsys;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( streams_get_flag(id, ROAR_FLAG_PASSMIXER) == 1 ) {
-  if ( (subsys = streams_get_subsys(id)) == -1 )
-   return -1;
-
-  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-   if ( (pmss = g_streams[i]) != NULL ) {
-    if ( streams_get_flag(i, ROAR_FLAG_PASSMIXER) == 1 ) {
-     tsubsys = streams_get_subsys(i);
-     if ( tsubsys == subsys || tsubsys == ROAR_SUBSYS_NONE ) {
-      if ( &(pmss->mixer) != &(ss->mixer) ) {
-       if ( roar_conv_volume(&(pmss->mixer), &(ss->mixer),
-                             ROAR_STREAM(pmss)->info.channels, ROAR_STREAM(ss)->info.channels) == -1 ) {
-        ROAR_WARN("streams_set_mixer(id=%i): Can not convert mixer settings for stream %i", id, i);
-       }
-      }
-
-      // update hwmixers and the like but do not set mixer value recrusivly.
-      streams_reset_flag(i, ROAR_FLAG_PASSMIXER);
-      streams_set_mixer(i);
-      streams_set_flag(i, ROAR_FLAG_PASSMIXER);
-     }
-    }
-   }
-  }
- }
-
- roar_notify_core_emit_snoargs(ROAR_OE_STREAM_CHANGE_VOLUME, -1, id, ROAR_OT_STREAM);
-
- if ( !streams_get_flag(id, ROAR_FLAG_HWMIXER) )
-  return 0;
-
- if ( ss->driver_id != -1 ) {
-  return driver_set_volume(id, &(ss->mixer));
-#ifndef ROAR_WITHOUT_DCOMP_MIXER
- } else if ( ss->mixerstream != NULL ) {
-  return hwmixer_set_volume(id, ss, ss->mixerstream, &(ss->mixer));
-#endif
- } else {
-  return 0;
- }
-}
-
-int streams_set_map      (int id, char * map, size_t len) {
- struct roar_stream_server * ss;
- int ssdir;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( map != NULL ) {
-  if ( ROAR_STREAM(ss)->info.channels != len )
-   return -1;
- }
-
- ssdir = streams_get_ssdir(id);
-
- switch (ssdir) {
-  case STREAM_DIR_IN:
-  case STREAM_DIR_NONE:
-    memset(ss->chanmap.in, 0, sizeof(ss->chanmap.in));
-
-    if ( map != NULL )
-     memcpy(ss->chanmap.in, map, len);
-
-    roardsp_chanmap_calc(&(ss->chanmap), ROARDSP_CHANMAP_MAP, 0);
-   break;
-  case STREAM_DIR_OUT:
-    memset(ss->chanmap.out, 0, sizeof(ss->chanmap.out));
-
-    if ( map != NULL )
-     memcpy(ss->chanmap.out, map, len);
-
-    roardsp_chanmap_calc(&(ss->chanmap), ROARDSP_CHANMAP_MAP, 0);
-   break;
-  default:
-    return -1;
- }
-
- return 0;
-}
-
-int streams_get_rpg      (int id, struct roar_stream_rpg * rpg) {
- _CHECK_SID(id);
-
- if ( rpg == NULL ) {
-  roar_err_set(ROAR_ERROR_FAULT);
-  return -1;
- }
-
- rpg->mode = g_streams[id]->rpgmode;
- rpg->mul  = g_streams[id]->mixer.rpg_mul;
- rpg->div  = g_streams[id]->mixer.rpg_div;
-
- if ( rpg->mode == ROAR_RPGMODE_DEFAULT )
-  rpg->mode = g_config->streams[ROAR_STREAM(g_streams[id])->dir].rpgmode;
-
- return 0;
-}
-
-int streams_set_rpg      (int id, const struct roar_stream_rpg * rpg) {
- int mode;
-
- _CHECK_SID(id);
-
- if ( rpg == NULL ) {
-  roar_err_set(ROAR_ERROR_FAULT);
-  return -1;
- }
-
- // test if we have a valid value at all.
- if ( rpg->mode > ROAR_RPGMODE_TRACKALBUM || rpg->mode < ROAR_RPGMODE_DEFAULT ) {
-  roar_err_set(ROAR_ERROR_RANGE);
-  return -1;
- }
-
- mode = g_streams[id]->rpgmode = rpg->mode;
-
- if ( mode == ROAR_RPGMODE_DEFAULT )
-  mode = g_config->streams[ROAR_STREAM(g_streams[id])->dir].rpgmode;
-
- switch (mode) {
-  case ROAR_RPGMODE_NONE:
-    g_streams[id]->mixer.rpg_mul = 1;
-    g_streams[id]->mixer.rpg_div = 1;
-   break;
-  case ROAR_RPGMODE_USER:
-    g_streams[id]->mixer.rpg_mul = rpg->mul;
-    g_streams[id]->mixer.rpg_div = rpg->div;
-   break;
- }
-
- return 0;
-}
-
-
-int streams_ltm_ctl      (int id, int mt, int window, int cmd) {
- struct roar_stream_server * ss;
- struct roar_stream_ltm *    ltm;
- int i;
-
- _CHECK_SID(id);
-
- // currently we only support the WORKBLOCK window
- if ( window != ROAR_LTM_WIN_WORKBLOCK )
-  return -1;
-
- // currently we only support ROAR_LTM_MT_RMS
- if ( (mt | ROAR_LTM_MT_RMS) - ROAR_LTM_MT_RMS )
-  return -1;
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- switch (cmd) {
-  case ROAR_LTM_SST_NOOP:
-    return 0;
-   break;
-  case ROAR_LTM_SST_REGISTER:
-    // test if the window is already registered:
-    for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) {
-     ltm = &(ss->ltm[i]);
-     if ( ltm->refc && ltm->window == window ) {
-      ltm->refc++;
-      ltm->mt |= mt;
-      return 0;
-     }
-    }
-
-    // register
-    for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) {
-     ltm = &(ss->ltm[i]);
-     if ( ltm->refc == 0 ) {
-      memset(ltm, 0, sizeof(struct roar_stream_ltm));
-      ltm->refc = 1;
-      ltm->window = window;
-      ltm->parent_window = -1;
-      ltm->mt = mt;
-      ltm->channels = ROAR_STREAM(ss)->info.channels;
-      if ( (ltm->cur = roar_mm_malloc(ltm->channels*sizeof(struct roar_ltm_vals))) == NULL ) {
-       ltm->refc = 0; // reset
-       return -1;
-      }
-      memset(ltm->cur, 0, ltm->channels*sizeof(struct roar_ltm_vals));
-      return 0;
-     }
-    }
-    return -1;
-   break;
-  case ROAR_LTM_SST_UNREGISTER:
-    for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) {
-     ltm = &(ss->ltm[i]);
-     if ( ltm->refc && ltm->window == window ) {
-      ltm->refc--;
-      if ( ! ltm->refc ) {
-       roar_mm_free(ltm->cur);
-       return 0;
-      }
-     }
-    }
-    return -1;
-   break;
-  default:
-    return -1;
-   break;
- }
-}
-
-int streams_ltm_calc     (int id, struct roar_audio_info * info, void * data, size_t len) {
- struct roar_stream_server * ss;
- struct roar_stream_ltm *    ltm = NULL;
- int64_t rmsbuf_real[8];
- int64_t * rmsbuf = rmsbuf_real;
- size_t samples = 0;
- int i;
-
- _CHECK_SID(id);
-
- if ( data == NULL || info == NULL )
-  return -1;
-
- if ( info->codec != ROAR_CODEC_DEFAULT )
-  return -1;
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) {
-  if ( ss->ltm[i].refc && ss->ltm[i].window == ROAR_LTM_WIN_WORKBLOCK ) {
-   ltm = &(ss->ltm[i]);
-   break;
-  }
- }
-
- if ( ltm == NULL )
-  return -1;
-
- // TODO: support change of number of channels
- if ( ltm->channels != info->channels )
-  return -1;
-
- if ( len == 0 ) {
-  memset(ltm->cur, 0, ltm->channels * sizeof(struct roar_ltm_vals));
-  return 0;
- }
-
- // TODO: support more channels then rmsbuf_real has space for
- if ( ltm->channels > (sizeof(rmsbuf_real)/sizeof(*rmsbuf_real)) ) {
-  return -1;
- }
-
- samples = len / info->bits;
-
- if ( ltm->mt & ROAR_LTM_MT_RMS ) {
-  if ( roar_rms2_1_b_n(data, samples, rmsbuf, ltm->channels, info->bits) == -1 )
-   return -1;
-
-  for (i = 0; i < ltm->channels; i++) {
-   ltm->cur[i].rms = rmsbuf[i] << (64 - info->bits*2);
-  }
-
-  ROAR_DBG("streams_ltm_calc(id=%i,...): rmsbuf[0]=%lli", id, (long long int)rmsbuf[0]);
- }
-
- return 0;
-}
-
-struct roar_stream_ltm * streams_ltm_get(int id, int mt, int window) {
- struct roar_stream_server * ss;
- struct roar_stream_ltm *    ltm = NULL;
- int i;
-
- _CHECK_SID_RET(id, NULL);
-
- if ( (ss = g_streams[id]) == NULL )
-  return NULL;
-
- for (i = 0; i < MAX_LTM_WINDOWS_PER_STREAM; i++) {
-  if ( ss->ltm[i].refc && ss->ltm[i].window == window ) {
-   ltm = &(ss->ltm[i]);
-   break;
-  }
- }
-
- if ( ltm == NULL )
-  return NULL;
-
- if ( (ltm->mt & mt) != mt )
-  return NULL;
-
- return ltm;
-}
-
-#ifndef ROAR_WITHOUT_DCOMP_MIXER
-struct hwmixer_stream * streams_get_mixerstream(int id) {
- _CHECK_SID_RET(id, NULL);
-
- return g_streams[id]->mixerstream;
-}
-
-int streams_set_mixerstream(int id, struct hwmixer_stream * mstream) {
- _CHECK_SID(id);
-
- g_streams[id]->mixerstream = mstream;
-
- return 0;
-}
-
-int streams_read_mixervalues(int id) {
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( ss->mixerstream == NULL )
-  return -1;
-
- return hwmixer_get_volume(id, ss, ss->mixerstream, &(ss->mixer));
-}
-#endif
-
-int streams_ctl          (int id, int_least32_t cmd, void * data) {
- struct roar_stream_server * ss;
- int_least32_t comp;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- comp = cmd & ROAR_STREAM_CTL_COMPMASK;
-
- cmd &= ~comp;
-
- ROAR_DBG("streams_ctl(id=%i, cmd=?, data=%p): comp=0x%.8x, cmd=0x%.4x", id, data, comp, cmd);
-
- switch (comp) {
-  case ROAR_STREAM_CTL_COMP_BASE:
-   break;
-  case ROAR_STREAM_CTL_COMP_CF:
-    return codecfilter_ctl(ss->codecfilter_inst, ss->codecfilter, cmd, data);
-   break;
-  case ROAR_STREAM_CTL_COMP_DRV:
-   break;
-  default:
-   return -1;
- }
-
- return -1;
-}
 
 int streams_get_outputbuffer  (int id, void ** buffer, size_t size) {
- _CHECK_SID(id);
+ if ( g_streams[id] == NULL )
+  return -1;
 
  // output buffer size does never change.
@@ -1806,5 +131,5 @@
  }
 
- if ( (g_streams[id]->output = roar_mm_malloc(size)) == NULL ) {
+ if ( (g_streams[id]->output = malloc(size)) == NULL ) {
   ROAR_ERR("streams_get_outputbuffer(*): Can not alloc: %s", strerror(errno));
   return -1;
@@ -1816,152 +141,198 @@
 }
 
-int streams_fill_mixbuffer2 (int id, struct roar_audio_info * info) {
- size_t   outlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(info);
- void   * outdata;
- size_t   inlen;
- size_t   inlen_got;
- void   * indata = NULL;
- size_t   buflen;
- void   * bufdata = NULL;
- struct roar_buffer * bufbuf = NULL;
- int      is_the_same = 0;
- struct roar_audio_info    * stream_info;
- struct roar_stream        * s;
- struct roar_stream_server * ss;
-
- _CHECK_SID(id);
-
- if ( (s = ROAR_STREAM(ss = g_streams[id])) == NULL )
-  return -1;
+int streams_fill_mixbuffer (int id, struct roar_audio_info * info) {
+ // TODO: decide: is this the most complex, hacked, un-understadable,
+ //               un-writeable and even worse: un-readable
+ //               function in the whole project?
+ size_t todo = ROAR_OUTPUT_CALC_OUTBUFSIZE(info);
+ size_t todo_in;
+ size_t len, outlen;
+ size_t mul = 1, div = 1;
+ void * rest = NULL;
+ void * in   = NULL;
+ struct roar_buffer     * buf;
+ struct roar_audio_info * stream_info;
+ int is_the_same = 0;
+
+ if ( g_streams[id] == NULL )
+  return -1;
+
+ if ( streams_get_outputbuffer(id, &rest, todo) == -1 ) {
+  return -1;
+ }
+
+ if ( rest == NULL ) {
+  return -1;
+ }
 
  // set up stream_info
- stream_info = &(s->info);
+
+ stream_info = &(((struct roar_stream*)g_streams[id])->info);
 
  // calc todo_in
- inlen = ROAR_OUTPUT_CALC_OUTBUFSIZE(stream_info);
-
- buflen = ROAR_OUTPUT_CALC_OUTBUFSIZE_MAX(info, stream_info);
-
- ROAR_DBG("streams_fill_mixbuffer2(id=%i, info=%p{...}): inlen=%lu, buflen=%lu", id, info, (unsigned long)inlen, (unsigned long)buflen);
-
- if ( inlen == 0 ) {
-  ROAR_WARN("streams_fill_mixbuffer2(id=%i, info=%p{...}): inlen == 0, this should not happen!", id, info);
-  return -1;
- }
-
- if ( streams_get_outputbuffer(id, &outdata, outlen) == -1 ) {
-  return -1;
- }
-
- if ( outdata == NULL ) {
-  return -1;
- }
-
- ROAR_DBG("streams_fill_mixbuffer2(*): outdata=%p, len=%i->%i (in->out)", outdata, inlen, outlen);
+ todo_in = ROAR_OUTPUT_CALC_OUTBUFSIZE(stream_info);
+
+ // calc mul and div:
+ mul = todo    / todo_in;
+ div = todo_in / todo;
+
+ if ( mul == 0 ) {
+  mul = 1;
+ } else {
+  div = 1;
+ }
+
+ ROAR_DBG("streams_fill_mixbuffer(*): mul=%i, div=%i", mul, div);
+
+ ROAR_DBG("streams_fill_mixbuffer(*): rest=%p, todo=%i->%i (in->out)", rest, todo_in, todo);
+ // are both (input and output) of same format?
+
+
+ ROAR_DBG("streams_fill_mixbuffer(*): stream_info:");
+ roar_debug_audio_info_print(stream_info);
+ ROAR_DBG("streams_fill_mixbuffer(*): info:");
+ roar_debug_audio_info_print(info);
 
  is_the_same = stream_info->rate     == info->rate     && stream_info->bits  == info->bits &&
                stream_info->channels == info->channels && stream_info->codec == info->codec;
 
- ROAR_DBG("streams_fill_mixbuffer2(*): is_the_same=%i", is_the_same);
-
- if ( !is_the_same && buflen > outlen ) {
+ ROAR_DBG("streams_fill_mixbuffer(*): is_the_same=%i", is_the_same);
+
+/* How it works:
+ *
+ * set a counter to the number of samples we need.
+ * loop until we have all samples done or no samples are
+ * left in our input buffer.
+ * If there a no samples left in the input buffer: fill the rest
+ * of the output buffer with zeros.
+ *
+ * The loop:
+ * get a buffer from the input.
+ * if it's bigger than needed, set an offset.
+ * The rest of the data:
+ * 0) convert endianness (codec) from remote to local...
+ * 1) change bits in of the samples
+ * 2) change sample rate
+ * 3) change the nummber of channels
+ * 4) insert into output buffer
+ */
+
 /*
-  // this is not supported at the moment
-  memset(outdata, 0, outlen);
-  return -1;
+ // get our first buffer:
+
+ if ( stream_shift_buffer(id, &buf) == -1 ) {
+  return -1;
+ }
+
+ // first test for some basic simple cases...
+
+ if ( buf == NULL ) { // we habe nothing in input queue
+                      // we may memset() our output buffer OR
+                      // just return with -1 so we are going to
+                      // be ignored.
+  return -1;
+ }
 */
 
-  if ( roar_buffer_new(&bufbuf, buflen) == -1 )
-   return -1;
-
-  if ( roar_buffer_get_data(bufbuf, &bufdata) == -1 )
-   return -1;
-  indata  = bufdata;
- } else {
-  indata  = outdata;
-  bufdata = outdata;
- }
-
- inlen_got = inlen;
-
- ROAR_DBG("streams_fill_mixbuffer2(id=%i, info=...): inlen_got=%u", id, inlen_got);
-
- if ( stream_shift_out_buffer(id, indata, &inlen_got) == -1 ) {
-  if ( ss->is_new ) {
-   ss->pre_underruns++;
-   roar_notify_core_emit_simple(ROAR_OE_STREAM_XRUN, -1, id, ROAR_OT_STREAM, ROAR_XRUN_UNDER_PRE, ss->pre_underruns, NULL, 0);
+ while (todo) { // main loop
+  ROAR_DBG("streams_fill_mixbuffer(*): looping...");
+  // exit loop if nothing is left, even if we need more data..
+  if ( stream_shift_buffer(id, &buf) == -1 )
+   break;
+  if ( buf == NULL )
+   break;
+
+  // read the data for this loop...
+  roar_buffer_get_data(buf, &in);
+  roar_buffer_get_len(buf, &len);
+
+  ROAR_DBG("streams_fill_mixbuffer(*): len = %i", len);
+
+  if ( len > todo_in ) {
+   roar_buffer_set_offset(buf, todo_in);
+   len = todo_in;
   } else {
-   ROAR_WARN("streams_fill_mixbuffer2(id=%i, info=...): underrun in stream", id);
-   ss->post_underruns++;
-   roar_notify_core_emit_simple(ROAR_OE_STREAM_XRUN, -1, id, ROAR_OT_STREAM, ROAR_XRUN_UNDER_POST, ss->post_underruns, NULL, 0);
+   roar_buffer_set_len(buf, 0); // queue for deletation
   }
-  memset(outdata, 0, outlen);
-  return 0;
- }
-
- ROAR_DBG("streams_fill_mixbuffer2(id=%i, info=...): inlen_got=%u", id, inlen_got);
-
- if ( ss->is_new ) {
-  //ROAR_INFO("streams_fill_mixbuffer2(id=%i, info=...): stream state: new->old", ROAR_DBG_INFO_VERBOSE, id);
-  _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_fill_mixbuffer2");
- }
-
- ss->is_new = 0;
-
- // check channel map:
-#if 0
- if ( roardsp_chanmap_mappcm(indata, indata, inlen, stream_info->channels, &(ss->chanmap), stream_info->bits) == -1 ) {
-  if ( bufbuf != NULL )
-   roar_buffer_free(bufbuf);
-  return -1;
- }
-#endif
-
- // TODO: this only works in case a we have a amp for the given stream parameters.
- if ( !streams_get_flag(id, ROAR_FLAG_HWMIXER) && !streams_get_flag(id, ROAR_FLAG_PASSMIXER) ) {
-  ROAR_DBG("streams_fill_mixbuffer2(*): CALL roar_amp_pcm(*)...");
-  if ( roar_amp_pcm(indata, stream_info->bits, indata, 8*inlen / stream_info->bits, stream_info->channels, &(ss->mixer)) == -1 )
-   return -1;
- }
-
- // check codec, bits, channels, rate...
- if ( is_the_same ) {
-  if ( indata != outdata )
-   memcpy(outdata, indata, inlen);
-
-  if ( inlen < outlen )
-   memset(outdata+inlen, 0, outlen-inlen);
- } else {
-//  if ( roar_conv(outdata, indata, (8*inlen_got*info->rate)/(stream_info->rate * stream_info->bits), stream_info, info) == -1 ) {
-  ROAR_DBG("streams_fill_mixbuffer2(*): CALL roar_conv2(*)...");
-  if ( roar_conv2(bufdata, indata, inlen, stream_info, info, outlen) == -1 ) {
-   if ( bufbuf != NULL )
-    roar_buffer_free(bufbuf);
+
+  // we now have 'len' bytes in 'in'
+
+  // calc how much outlen this has...
+  outlen = (len * mul) / div;
+
+  ROAR_DBG("streams_fill_mixbuffer(*): outlen = %i, buf = %p, len = %i", outlen, in, len);
+
+  if ( is_the_same ) {
+/*
+ * 0) convert endianness (codec) from remote to local...
+ * 1) change bits in of the samples
+ * 2) change sample rate
+ * 3) change the nummber of channels
+   \\==> skiping,...
+ */
+   // * 4) insert into output buffer
+   ROAR_DBG("streams_fill_mixbuffer(*): memcpy: in->rest: %p -> %p", in, rest);
+   if ( memcpy(rest, in, len) != rest ) {
+    ROAR_ERR("streams_fill_mixbuffer(*): memcpy returned invalid pointer.");
+   }
+
+  } else {
+
+/*
+   // * 0) convert endianness (codec) from remote to local...
+   if ( stream_info->codec != info->codec ) {
+    // we neet to convert...
+    return -1;
+   }
+
+   // * 1) change bits in of the samples
+   if ( stream_info->bits != info->bits ) {
+    return -1;
+   }
+
+   // * 2) change sample rate
+   if ( stream_info->rate != info->rate ) {
+    return -1;
+   }
+
+   // * 3) change the nummber of channels
+   if ( stream_info->channels != info->channels ) {
+    return -1;
+   }
+
+   // * 4) insert into output buffer
+*/
+  // hey! we have roar_conv() :)
+
+  if ( roar_conv(rest, in, 8*len / stream_info->bits, stream_info, info) == -1 )
    return -1;
   }
 
-//  memset(outdata, 0, outlen);
- }
-
- if ( bufbuf != NULL ) {
-  memcpy(outdata, bufdata, outlen);
-  roar_buffer_free(bufbuf);
- }
-
- streams_ltm_calc(id, stream_info, outdata, outlen);
-
- if ( streams_get_flag(id, ROAR_FLAG_ANTIECHO) ) {
-  ROAR_DBG("streams_fill_mixbuffer2(*): Calcing antiecho...");
-  // we can ignore errors here:
-  if ( stream_outputbuffer_request(id, &bufbuf, buflen) == 0 ) {
-   if ( roar_buffer_get_data(bufbuf, &bufdata) != -1 )
-    memcpy(bufdata, outdata, outlen);
-  }
- }
-
- ROAR_DBG("streams_fill_mixbuffer2(*): inlen_got=%llu, stream_info={.bits=%i, .rate=%i,...}", (long long unsigned int)inlen_got, stream_info->bits, stream_info->rate);
- s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, (inlen_got*8)/stream_info->bits);
-
- ROAR_DBG("streams_fill_mixbuffer2(*) = 0");
+  // we habe outlen bytes more...
+  todo    -= outlen;
+  rest    += outlen;
+  todo_in -= len;
+
+  roar_buffer_get_len(buf, &len);
+  ROAR_DBG("streams_fill_mixbuffer(*): New length of buffer %p is %i", buf, len);
+  if ( len == 0 )
+   roar_buffer_delete(buf, NULL);
+ }
+
+ //len = 0;
+ //buffer_get_len(buf, &len);
+
+/*
+ if ( len > 0 ) // we still have some data in this buffer, re-inserting it to the input buffers...
+  stream_unshift_buffer(id, buf);
+ else
+  buffer_delete(buf, NULL);
+*/
+
+ if ( todo > 0 ) { // zeroize the rest of teh buffer
+  memset(rest, 0, todo);
+  ROAR_ERR("streams_fill_mixbuffer(*): Underrun in stream: %i bytes missing, filling with zeros", todo);
+ }
+
  return 0;
 }
@@ -1969,27 +340,11 @@
 
 int streams_get_mixbuffers (void *** bufferlist, struct roar_audio_info * info, unsigned int pos) {
- static void * bufs[ROAR_STREAMS_MAX+1];
+ static void * bufs[ROAR_STREAMS_MAX];
  int i;
  int have = 0;
- int dir;
 
  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
   if ( g_streams[i] != NULL ) {
-   dir = streams_get_dir(i);
-
-   switch (dir) {
-    case ROAR_DIR_PLAY:
-    case ROAR_DIR_BIDIR:
-    case ROAR_DIR_RECPLAY:
-     break;
-    case ROAR_DIR_BRIDGE:
-      if ( g_streams[i]->buffer == NULL )
-       continue;
-     break;
-    default:
-      continue;
-   }
-
-   if ( streams_get_flag(i, ROAR_FLAG_PAUSE) )
+   if ( ((struct roar_stream *)g_streams[i])->dir != ROAR_DIR_PLAY )
     continue;
 
@@ -1999,216 +354,72 @@
     continue;
    }
-   if ( streams_fill_mixbuffer2(i, info) == -1 ) {
+   if ( streams_fill_mixbuffer(i, info) == -1 ) {
     ROAR_ERR("streams_get_mixbuffer(*): Can not fill output buffer for stream %i, this should not happen", i);
     continue;
    }
 
-//   printf("D: bufs[have=%i] = %p\n", have, bufs[have]);
-
    ROAR_DBG("streams_get_mixbuffers(*):  bufs[have] = %p", bufs[have]);
    ROAR_DBG("streams_get_mixbuffers(*): *bufs[have] = 0x%08x...", *(uint32_t*)bufs[have]);
 
-   if ( !streams_get_flag(i, ROAR_FLAG_MUTE) )
-    have++; // we have a new stream!
+   have++; // we have a new stream!
   }
  }
 
  bufs[have] = NULL;
- //printf("D: bufs[have=%i] = %p\n", have, bufs[have]);
 
  ROAR_DBG("streams_get_mixbuffers(*): have = %i", have);
 
  *bufferlist = bufs;
- return have;
-}
-
-
-int stream_add_buffer  (int id, struct roar_buffer ** buf) {
+ return 0;
+}
+
+
+int stream_add_buffer  (int id, struct roar_buffer * buf) {
  ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = ?", id, buf);
 
- _CHECK_SID(id);
+ if ( g_streams[id] == NULL )
+  return -1;
 
  if ( g_streams[id]->buffer == NULL ) {
-  g_streams[id]->buffer = *buf;
+  g_streams[id]->buffer = buf;
+  ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = 0", id, buf);
+  return 0;
+ }
+
+ ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = ?", id, buf);
+ return roar_buffer_add(g_streams[id]->buffer, buf);
+}
+
+int stream_shift_buffer   (int id, struct roar_buffer ** buf) {
+ struct roar_buffer * next;
+
+ if ( g_streams[id] == NULL )
+  return -1;
+
+ if ( g_streams[id]->buffer == NULL ) {
   *buf = NULL;
-  ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = 0", id, buf);
-  return 0;
- }
-
- ROAR_DBG("stream_add_buffer(id=%i, buf=%p) = ?", id, buf);
- return roar_buffer_moveinto(g_streams[id]->buffer, buf);
-}
-
-int stream_shift_out_buffer   (int id, void * data, size_t * len) {
- _CHECK_SID(id);
-
- if ( g_streams[id]->buffer == NULL )
-  return -1;
-
- return roar_buffer_shift_out(&(g_streams[id]->buffer), data, len);
-}
-
-int stream_outputbuffer_request(int id, struct roar_buffer ** buf, size_t len) {
- register struct roar_stream_server *  ss;
- size_t buflen;
- void * bufdata;
- int ret;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( buf != NULL ) /* just be be sure */
-  *buf = NULL;
-
- if ( ss->outputbuffer != NULL ) {
-  if ( roar_buffer_get_len(ss->outputbuffer, &buflen) == 0 ) {
-   if ( buflen == len ) {
-    if ( buf != NULL )
-     *buf = ss->outputbuffer;
-    return 0;
-   } else if ( buflen > len ) {
-    if ( roar_buffer_set_len(ss->outputbuffer, len) == 0 ) {
-     if ( buf != NULL )
-      *buf = ss->outputbuffer;
-     return 0;
-    }
-   }
-  }
-
-  // if the buffer is not suitable:
-
-  ret = roar_buffer_free(ss->outputbuffer);
-  ss->outputbuffer = NULL;
-  if ( ret == -1 )
-   return ret;
- }
-
- if ( roar_buffer_new(&(ss->outputbuffer), len) == -1 )
-  return -1;
-
- if ( roar_buffer_get_data(ss->outputbuffer, &bufdata) == -1 ) {
-  roar_buffer_free(ss->outputbuffer);
-  ss->outputbuffer = NULL;
-  return -1;
- }
-
- memset(bufdata, 0, len);
-
- if ( buf != NULL )
-  *buf = ss->outputbuffer;
-
- return 0;
-}
-
-int stream_outputbuffer_destroy(int id) {
- int ret;
- register struct roar_stream_server *  ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( ss->outputbuffer != NULL ) {
-  ret = roar_buffer_free(ss->outputbuffer);
-  ss->outputbuffer = NULL;
-  return ret;
- }
-
- return 0;
-}
-
-int stream_prethru_add(int id, struct roar_buffer ** buf) {
- register struct roar_stream_server *  ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( ss->prethru == NULL ) {
-  ss->prethru = *buf;
-  *buf = NULL;
-  return 0;
- }
-
- if ( roar_buffer_moveinto(ss->prethru, buf) == -1 ) {
-  return -1;
- }
-
- return 0;
-}
-
-int stream_prethru_add_data(int id, void ** buf, size_t len) {
- struct roar_buffer * buffer;
-
- _CHECK_SID(id);
-
- if ( roar_buffer_new_data(&buffer, len, buf) == -1 )
-  return -1;
-
- if ( stream_prethru_add(id, &buffer) == -1 ) {
-  roar_buffer_free(buffer);
-  return -1;
- }
-
- return 0;
-}
-
-int stream_prethru_destroy(int id) {
- int ret;
- register struct roar_stream_server *  ss;
-
- _CHECK_SID(id);
-
- if ( (ss = g_streams[id]) == NULL )
-  return -1;
-
- if ( ss->prethru != NULL ) {
-  ret = roar_buffer_free(ss->prethru);
-  ss->prethru = NULL;
-  return ret;
- }
-
- return 0;
-}
-
-int stream_prethru_send(int dst, int src) {
- struct roar_stream_server *  dst_ss, * src_ss;
- struct roar_buffer * bufbuf;
- void * bufdata;
- size_t buflen;
-
- ROAR_DBG("stream_prethru_send(dst=%i, src=%i) = ?", dst, src);
-
- _CHECK_SID(dst);
- _CHECK_SID(src);
-
- if ( (dst_ss = g_streams[dst]) == NULL )
-  return -1;
-
- if ( (src_ss = g_streams[src]) == NULL )
-  return -1;
-
- bufbuf = src_ss->prethru;
-
- ROAR_DBG("stream_prethru_send(dst=%i, src=%i): prethru buffer at %p", dst, src, bufbuf);
-
- roar_buffer_foreach(bufbuf) {
-  ROAR_DBG("stream_prethru_send(dst=%i, src=%i): looping with buffer at %p", dst, src, bufbuf);
-
-  if ( roar_buffer_get_data(bufbuf, &bufdata) == -1 )
-   return -1;
-
-  if ( roar_buffer_get_len(bufbuf, &buflen) == -1 )
-   return -1;
-
-  if ( stream_vio_s_write(dst_ss, bufdata, buflen) != buflen )
-   return -1;
- }
-
- ROAR_DBG("stream_prethru_send(dst=%i, src=%i) = 0", dst, src);
+  return 0;
+ }
+
+ roar_buffer_get_next(g_streams[id]->buffer, &next);
+
+ *buf                  = g_streams[id]->buffer;
+ g_streams[id]->buffer = next;
+
+ return 0;
+}
+int stream_unshift_buffer (int id, struct roar_buffer *  buf) {
+ if ( g_streams[id] == NULL )
+  return -1;
+
+ if ( g_streams[id]->buffer == NULL ) {
+  g_streams[id]->buffer = buf;
+  return 0;
+ }
+
+ roar_buffer_add(buf, g_streams[id]->buffer);
+
+ g_streams[id]->buffer = buf;
+
  return 0;
 }
@@ -2216,93 +427,29 @@
 int streams_check  (int id) {
  int fh;
- ssize_t req, realreq, done;
+ size_t req;
  struct roar_stream        *   s;
  struct roar_stream_server *  ss;
  struct roar_buffer        *   b;
- void                      * buf;
-// char                        tmp;
-
- _CHECK_SID(id);
+ char                      * buf;
+
+ if ( g_streams[id] == NULL )
+  return -1;
 
  ROAR_DBG("streams_check(id=%i) = ?", id);
 
- s = ROAR_STREAM(ss = g_streams[id]);
+ s = (struct roar_stream *) (ss = g_streams[id]);
 
  if ( (fh = s->fh) == -1 )
   return 0;
 
- if ( streams_get_flag(id, ROAR_FLAG_PAUSE) )
-  return 0;
-
- switch (s->dir) {
-  case ROAR_DIR_LIGHT_IN:
-#ifndef ROAR_WITHOUT_DCOMP_LIGHT
-    return light_check_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-  case ROAR_DIR_MIDI_IN:
-#ifndef ROAR_WITHOUT_DCOMP_MIDI
-    return midi_check_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-  case ROAR_DIR_RAW_IN:
-#ifndef ROAR_WITHOUT_DCOMP_RAW
-    return raw_check_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-  case ROAR_DIR_RDTCS_IN:
-#ifndef ROAR_WITHOUT_DCOMP_RDTCS
-    return rdtcs_check_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-  case ROAR_DIR_PLAY:
-  case ROAR_DIR_BIDIR:
-  case ROAR_DIR_RECPLAY:
-   break;
-  case ROAR_DIR_OUTPUT:
-    if ( !streams_get_flag(id, ROAR_FLAG_RECSOURCE) )
-     return 0;
-   break;
-  default:
-/*
-    ROAR_WARN("streams_check(id=%i): Read event on non input stream of type/dir %s", id, roar_dir2str(s->dir));
-    errno = 0;
-    req = stream_vio_s_read(ss, &tmp, 1);
-    ROAR_DBG("streams_check(id=%i): stream_vio_s_read(ss, &tmp, 1) = %li // errno=%s(%i)", id, req, strerror(errno), errno);
-    if ( req == 1 ) {
-     ROAR_ERR("streams_check(id=%i): Client violates protocol, got one byte of data on output stream, kicking stream");
-     streams_delete(id);
-     return -1;
-    }
-*/
-    return 0;
-   break;
- }
+ if ( s->dir != ROAR_DIR_PLAY )
+  return 0;
 
  ROAR_DBG("streams_check(id=%i): fh = %i", id, fh);
 
-/*
- ROAR_DBG("streams_check(id=%i): ROAR_OUTPUT_BUFFER_SAMPLES=%i, s->info.channels=%i, s->info.bits=%i, s->info.rat=%i, g_sa->rate=%i", id, ROAR_OUTPUT_BUFFER_SAMPLES, s->info.channels, s->info.bits, s->info.rate, g_sa->rate);
-*/
-
- req  = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info)); // optimal size
-// req  = ROAR_OUTPUT_BUFFER_SAMPLES * s->info.channels * (s->info.bits / 8) * ((float)s->info.rate/g_sa->rate);
+ req  = ROAR_OUTPUT_BUFFER_SAMPLES * s->info.channels * s->info.bits / 8; // optimal size
  req += ss->need_extra; // bytes left we sould get....
 
- ROAR_DBG("streams_check(id=%i): asking for %i bytes", id, req);
-
- if ( roar_buffer_new_data(&b, req, &buf) == -1 ) {
+ if ( roar_buffer_new(&b, req) == -1 ) {
   ROAR_ERR("streams_check(*): Can not alloc buffer space!");
   ROAR_DBG("streams_check(*) = -1");
@@ -2310,52 +457,23 @@
  }
 
+ roar_buffer_get_data(b, (void **)&buf);
+
  ROAR_DBG("streams_check(id=%i): buffer is up and ready ;)", id);
- ROAR_DBG("streams_check(id=%i): asking for %i bytes", id, req);
-
- if ( ss->codecfilter == -1 ) {
-  realreq = req;
-/*
-  req = read(fh, buf, req);
-  if ( req < realreq ) { // we can do this as the stream is in nonblocking mode!
-   if ( (realreq = read(fh, buf+req, realreq-req)) > 0 )
-    req += realreq;
-  }
-*/
-  done = 0;
-  while (req > 0 && done != realreq) {
-   if ( (req = stream_vio_s_read(ss, buf+done, realreq-done)) > 0 )
-    done += req;
-  }
-  req = done;
-
- } else {
-  req = codecfilter_read(ss->codecfilter_inst, ss->codecfilter, buf, req);
- }
-
- if ( req > 0 ) {
+
+ if ( (req = read(fh, buf, req)) > 0 ) {
   ROAR_DBG("streams_check(id=%i): got %i bytes", id, req);
 
-  if ( roar_buffer_set_len(b, req) != -1 ) {
-   if ( stream_add_buffer(id, &b) != -1 )
-    return 0;
-
-   ROAR_ERR("streams_check(id=%i): something is wrong, could not add buffer to stream!", id);
-  } else {
-   ROAR_ERR("streams_check(id=%i): something is wrong, could not set size of buffer!", id);
-  }
-
+  roar_buffer_set_len(b, req);
+
+  if ( stream_add_buffer(id, b) != -1 )
+   return 0;
+
+  ROAR_ERR("streams_check(id=%i): something is wrong, could not add buffer to stream!", id);
   roar_buffer_free(b);
  } else {
-  ROAR_DBG("streams_check(id=%i): read() = %i // errno: %s", id, req, strerror(errno));
-#ifdef ROAR_HAVE_LIBVORBISFILE
-  if ( errno != EAGAIN && errno != ESPIPE ) { // libvorbis file trys to seek a bit ofen :)
-#else
-  if ( errno != EAGAIN ) {
-#endif
-   ROAR_DBG("streams_check(id=%i): EOF!", id);
-   streams_delete(id);
-   ROAR_DBG("streams_check(id=%i) = 0", id);
-  }
+  ROAR_DBG("streams_check(id=%i): EOF!", id);
   roar_buffer_free(b);
+  streams_delete(id);
+  ROAR_DBG("streams_check(id=%i) = 0", id);
   return 0;
  }
@@ -2367,231 +485,26 @@
 
 
-#define _return(x) return (x)
 int streams_send_mon   (int id) {
-// int fh;
+ int fh;
  struct roar_stream        *   s;
  struct roar_stream_server *  ss;
- struct roar_buffer        *  bufbuf = NULL;
- struct roar_remove_state     removalstate;
- void  * ip              = g_output_buffer;
- void  * obuf;
- int     olen;
- int     is_the_same     = 1;
- int     is_vol_eq       = 1;
- int     is_muted;
- int     antiecho        = 0;
- ssize_t ret;
-
- _CHECK_SID(id);
+
+ if ( g_streams[id] == NULL )
+  return -1;
 
  ROAR_DBG("streams_send_mon(id=%i) = ?", id);
 
- s = ROAR_STREAM((ss = g_streams[id]));
-
-/*
+ s = (struct roar_stream *) (ss = g_streams[id]);
+
  if ( (fh = s->fh) == -1 )
   return 0;
-*/
-
- if ( !ss->ready )
-  return 0;
-
- if ( g_config->jumbo_mtu )
-  roar_vio_sync(ss->viop);
-
- if ( streams_get_flag(id, ROAR_FLAG_PAUSE) )
-  return 0;
-
- switch (s->dir) {
-  case ROAR_DIR_LIGHT_OUT:
-#ifndef ROAR_WITHOUT_DCOMP_LIGHT
-    return light_send_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-  case ROAR_DIR_MIDI_OUT:
-#ifndef ROAR_WITHOUT_DCOMP_MIDI
-    return midi_send_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-  case ROAR_DIR_RDTCS_OUT:
-#ifndef ROAR_WITHOUT_DCOMP_RDTCS
-    return rdtcs_send_stream(id);
-#else
-    streams_delete(id);
-    return -1;
-#endif
-   break;
-
-  case ROAR_DIR_COMPLEX_OUT:
-    // send a tick:
-    if ( ss->codecfilter != -1 ) {
-     if ( codecfilter_write(ss->codecfilter_inst, ss->codecfilter, NULL, 0) == 0 )
-      if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-       //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
-       _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
-      }
-    }
-    return 0;
-   break;
-
-  case ROAR_DIR_OUTPUT:
-    if ( g_standby )
-     return 0;
-  case ROAR_DIR_MONITOR:
-  case ROAR_DIR_BIDIR:
-   break;
-
-  case ROAR_DIR_RECORD:
-  case ROAR_DIR_RECPLAY:
-    ip = g_input_buffer;
-   break;
-  default:
-    return 0;
-   break;
- }
-
-
- ROAR_DBG("streams_send_mon(id=%i): fh = %i", id, s->fh);
-
- if ( s->info.channels != g_sa->channels || s->info.bits  != g_sa->bits ||
-      s->info.rate     != g_sa->rate     || s->info.codec != g_sa->codec  )
-  is_the_same = 0;
-
- is_muted = streams_get_flag(id, ROAR_FLAG_MUTE);
-
- if ( !is_muted && !streams_get_flag(id, ROAR_FLAG_HWMIXER) ) {
-  is_vol_eq = need_vol_change(g_sa->channels, &(ss->mixer)) ? 0 : 1;
- }
-
- if ( streams_get_flag(id, ROAR_FLAG_ANTIECHO) )
-  antiecho = 1;
-
- if ( !is_the_same || !is_vol_eq || antiecho || is_muted ) {
-  olen = ROAR_OUTPUT_CALC_OUTBUFSIZE(&(s->info)); // we hope g_output_buffer_len
-                                                  // is ROAR_OUTPUT_CALC_OUTBUFSIZE(g_sa) here
-  if ( stream_outputbuffer_request(id, &bufbuf, ROAR_OUTPUT_CALC_OUTBUFSIZE_MAX(&(s->info), g_sa)) == -1 )
-   return -1;
-
-  if ( roar_buffer_get_data(bufbuf, &obuf) == -1 ) {
-   _return(-1);
-  }
-
-  ROAR_DBG("streams_send_mon(id=%i): obuf=%p, olen=%i", id, obuf, olen);
- } else {
-  obuf = ip;
-  olen = g_output_buffer_len;
- }
-
- if ( antiecho ) {
-  ROAR_DBG("streams_send_mon(id=%i): antiecho=%i", id, antiecho);
-  if ( roar_remove_init(&removalstate) == -1 ) {
-   _return(-1);
-  }
-
-  ROAR_DBG("streams_send_mon(id=%i): antiecho=%i", id, antiecho);
-  if ( roar_remove_so(obuf, ip, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa->bits, &removalstate) == -1 ) {
-   ROAR_DBG("streams_send_mon(id=%i): anti echo failed", id);
-   _return(-1);
-  }
-  ROAR_DBG("streams_send_mon(id=%i): antiecho=%i", id, antiecho);
- }
-
- if ( !is_vol_eq ) {
-  if ( roar_amp_pcm(obuf, g_sa->bits, ip, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa->channels, &(ss->mixer)) == -1 ) {
-   _return(-1);
-  }
-
-  ip = obuf;
- }
-
- if ( is_muted ) {
-  memset(obuf, 0, (g_sa->bits*ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels)/8);
-  ip = obuf;
- }
-
- streams_ltm_calc(id, &(s->info), ip, (ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels*g_sa->bits)/8);
-
- if ( !is_the_same ) {
-  if ( roar_conv(obuf, ip, ROAR_OUTPUT_BUFFER_SAMPLES*g_sa->channels, g_sa, &(s->info)) == -1 ) {
-   _return(-1);
-  }
- }
-
- roar_err_clear_errno();
-
- if ( ss->codecfilter == -1 ) {
-  ROAR_DBG("streams_send_mon(id=%i): not a CF stream", id);
-  if ( s->fh == -1 && ss->vio.inst == NULL ) {
-   ROAR_DBG("streams_send_mon(id=%i) = 0", id);
-   _return(0);
-  }
-
-  ROAR_DBG("streams_send_mon(id=%i) = ?", id);
-
-  if ( (ret = stream_vio_s_write(ss, obuf, olen)) == olen ) {
-   s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels);
-   if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
-    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
-   }
-   ROAR_DBG("streams_send_mon(id=%i) = 0", id);
-   _return(0);
-  }
-
-  ROAR_DBG("streams_send_mon(id=%i) = ?", id);
-
-  if ( ret > 0 && roar_err_is_errno_clear() ) {
-   ROAR_WARN("streams_send_mon(id=%i): Overrun in stream: wrote %i of %i bytes, %i bytes missing", id, (int)ret, olen, olen-(int)ret);
-   roar_notify_core_emit_simple(ROAR_OE_STREAM_XRUN, -1, id, ROAR_OT_STREAM, ROAR_XRUN_OVER_POST, -1, NULL, 0);
-   s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), ret)*s->info.channels);
-   if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
-    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
-   }
-   _return(0);
-  }
- } else {
-  if ( codecfilter_write(ss->codecfilter_inst, ss->codecfilter, obuf, olen)
-            == olen ) {
-   s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels);
-   if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
-    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
-   }
-   _return(0);
-  } else { // we cann't retry on codec filetered streams
-   if ( errno != EAGAIN ) {
-    streams_delete(id);
-    _return(-1);
-   }
-  }
- }
-
- if ( errno == EAGAIN ) {
-  // ok, the client blocks for a moment, we try to sleep a bit an retry in the hope not to
-  // make any gapes in any output because of this
-
-#ifdef ROAR_HAVE_USLEEP
-  roar_usleep(100); // 0.1ms
-#endif
-
-  if ( stream_vio_s_write(ss, obuf, olen) == olen ) {
-   s->pos = ROAR_MATH_OVERFLOW_ADD(s->pos, ROAR_OUTPUT_CALC_OUTBUFSAMP(&(s->info), olen)*s->info.channels);
-   if ( ss->state != ROAR_STREAMSTATE_OLD ) {
-    //ROAR_INFO("streams_send_mon(id=%i): stream state: %s->old", ROAR_DBG_INFO_VERBOSE, id, roar_streamstate2str(ss->state));
-    _streams_change_state(ss, ROAR_STREAMSTATE_OLD, "streams_send_mon");
-   }
-   _return(0);
-  } else if ( errno == EAGAIN ) {
-   ROAR_WARN("streams_send_mon(id=%i): Can not send data to client: %s", id, strerror(errno));
-   _return(0);
-  }
- }
+
+ if ( s->dir != ROAR_DIR_MONITOR )
+  return 0;
+
+ ROAR_DBG("streams_send_mon(id=%i): fh = %i", id, fh);
+
+ if ( write(fh, g_output_buffer, g_output_buffer_len) == g_output_buffer_len )
+  return 0;
 
  // ug... error... delete stream!
@@ -2599,43 +512,18 @@
  streams_delete(id);
 
- _return(-1);
-}
-#undef _return
-
-int streams_send_filter_all(void) {
- struct roar_stream_server *  ss;
- int i;
-
- for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-  if ( (ss = g_streams[i]) == NULL )
-   continue;
-
-  if ( ROAR_STREAM(ss)->dir != ROAR_DIR_FILTER )
-   continue;
-
-  if ( !ss->ready )
-   continue;
-
-  if ( ss->state == ROAR_STREAMSTATE_CLOSING )
-   continue;
-
-  streams_send_filter(i);
- }
-
- return 0;
+ return -1;
 }
 
 int streams_send_filter(int id) {
  int fh;
- int have = 0;
- int len;
  struct roar_stream        *   s;
  struct roar_stream_server *  ss;
 
- _CHECK_SID(id);
+ if ( g_streams[id] == NULL )
+  return -1;
 
  ROAR_DBG("streams_send_filter(id=%i) = ?", id);
 
- s = ROAR_STREAM(ss = g_streams[id]);
+ s = (struct roar_stream *) (ss = g_streams[id]);
 
  if ( (fh = s->fh) == -1 )
@@ -2645,19 +533,13 @@
   return 0;
 
- if ( streams_get_flag(id, ROAR_FLAG_PAUSE) )
-  return 0;
-
-
  ROAR_DBG("streams_send_filter(id=%i): fh = %i", id, fh);
 
- if ( stream_vio_s_write(ss, g_output_buffer, g_output_buffer_len) == g_output_buffer_len ) {
-  while ( have < g_output_buffer_len ) {
-   if ( (len = stream_vio_s_read(ss, g_output_buffer+have, g_output_buffer_len-have)) < 1 ) {
-    streams_delete(id);
-    return -1;
-   }
-   have += len;
+ if ( write(fh, g_output_buffer, g_output_buffer_len) == g_output_buffer_len ) {
+  if ( read(fh, g_output_buffer, g_output_buffer_len) == g_output_buffer_len ) {
+   return 0;
+  } else {
+   streams_delete(id);
+   return -1;
   }
-  return 0;
  }
 
@@ -2669,139 +551,3 @@
 }
 
-
-// VIO:
-
-ssize_t stream_vio_read (int stream, void *buf, size_t count) {
- _CHECK_SID(stream);
-
- return stream_vio_s_read(g_streams[stream], buf, count);
-}
-
-ssize_t stream_vio_write(int stream, void *buf, size_t count) {
- _CHECK_SID(stream);
-
- return stream_vio_s_write(g_streams[stream], buf, count);
-}
-
-int     stream_vio_ctl  (int stream, roar_vio_ctl_t cmd,   void * data) {
- _CHECK_SID(stream);
-
- return stream_vio_s_ctl(g_streams[stream], cmd, data);
-}
-
-ssize_t stream_vio_s_read (struct roar_stream_server * stream, void *buf, size_t count) {
- void    * orig_buf = buf;
-  size_t   len      =  0;
- ssize_t   r        = -1;
- int       i;
-
- errno = 0;
-
- if ( stream == NULL ) {
-  roar_err_set(ROAR_ERROR_FAULT);
-  return -1;
- }
-
- if ( stream->vio.read == NULL ) {
-  roar_err_set(ROAR_ERROR_NOTSUP);
-  return -1;
- }
-
- while ( (r = roar_vio_read(&(stream->vio), buf, count)) > 0 ) {
-  len   += r;
-  buf   += r;
-  count -= r;
-  if ( count == 0 )
-   break;
- }
-
- if ( len == 0 && r == -1 )
-  return -1;
-
- if ( streams_thru_num ) {
-  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-   if ( g_streams[i] != NULL && ROAR_STREAM(g_streams[i])->pos_rel_id == ROAR_STREAM(stream)->id ) {
-    if ( ROAR_STREAM(g_streams[i])->dir == ROAR_DIR_THRU ) {
-     if ( g_streams[i]->ready ) {
-      if ( stream_vio_write(i, orig_buf, len) != len )
-       streams_delete(i);
-
-      if ( g_streams[i] != NULL ) {
-       if ( g_streams[i]->state != ROAR_STREAMSTATE_OLD ) {
-        //ROAR_INFO("stream_vio_s_read(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state));
-        _streams_change_state(g_streams[i], ROAR_STREAMSTATE_OLD, "stream_vio_s_read");
-       }
-      }
-     }
-    }
-   }
-  }
- }
-
- return len;
-}
-
-ssize_t stream_vio_s_write(struct roar_stream_server * stream, void *buf, size_t count) {
- int i;
-
- errno = 0;
-
- if ( stream == NULL ) {
-  roar_err_set(ROAR_ERROR_FAULT);
-  return -1;
- }
-
-// ROAR_WARN("stream_vio_s_write(*): writing...");
-
- if ( streams_thru_num ) {
-  for (i = 0; i < ROAR_STREAMS_MAX; i++) {
-   if ( g_streams[i] != NULL && ROAR_STREAM(g_streams[i])->pos_rel_id == ROAR_STREAM(stream)->id ) {
-    if ( ROAR_STREAM(g_streams[i])->dir == ROAR_DIR_THRU ) {
-     if ( g_streams[i]->ready ) {
-      if ( g_streams[i]->state == ROAR_STREAMSTATE_NEW ) {
-       if ( streams_get_flag(i, ROAR_FLAG_PRETHRU) == 1 ) {
-        if ( stream_prethru_send(i, ROAR_STREAM(stream)->id) == -1 ) {
-         streams_delete(i);
-        }
-       }
-      }
-
-      if ( stream_vio_write(i, buf, count) != count ) {
-       streams_delete(i);
-      }
-
-      if ( g_streams[i] != NULL ) {
-       if ( g_streams[i]->state != ROAR_STREAMSTATE_OLD ) {
-        //ROAR_INFO("stream_vio_s_write(*): (stream: %i) stream state: %s->old", ROAR_DBG_INFO_VERBOSE, i, roar_streamstate2str(g_streams[i]->state));
-        _streams_change_state(g_streams[i], ROAR_STREAMSTATE_OLD, "stream_vio_s_write");
-       }
-      }
-     }
-    }
-   }
-  }
- }
-
- if ( g_config->jumbo_mtu ) {
-  if ( stream->viop != &(stream->jumbo) ) {
-   if ( roar_vio_open_jumbo(&(stream->jumbo), &(stream->vio), g_config->jumbo_mtu) != -1 ) {
-    // if that works we continue using the jumbo vio,
-    // in case it didn't we dont, just use normal VIO.
-    stream->viop = &(stream->jumbo);
-   }
-  }
- }
-
- return roar_vio_write(stream->viop, buf, count);
-}
-
-int     stream_vio_s_ctl  (struct roar_stream_server * stream, roar_vio_ctl_t cmd,   void * data) {
- if ( stream == NULL ) {
-  roar_err_set(ROAR_ERROR_FAULT);
-  return -1;
- }
-
- return roar_vio_ctl(stream->viop, cmd, data);
-}
-
 //ll
