Index: roard/output.c
===================================================================
--- roard/output.c	(revision 6052)
+++ roard/output.c	(revision 0)
@@ -1,38 +1,19 @@
 //output.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"
 
-// stuff we defined 'extern'
-void         * g_output_buffer     = NULL;
-void         * g_input_buffer      = NULL;
-size_t         g_output_buffer_len = 0;
-// //
+/*
+void         * g_output_buffer;
+unsigned int   g_output_buffer_len;
+*/
 
 int output_buffer_init   (struct roar_audio_info * info) {
- size_t   size;
+ size_t   size; // = ROAR_OUTPUT_BUFFER_SAMPLES;
  void   * buf;
+
+/*
+ size *= info->channels;
+ size *= info->bits / 8;
+*/
 
  size = ROAR_OUTPUT_CALC_OUTBUFSIZE(info);
@@ -40,5 +21,5 @@
  ROAR_DBG("output_buffer_init(*): output buffer size is %i", size);
 
- if ( (buf = roar_mm_malloc(size)) == NULL )
+ if ( (buf = malloc(size)) == NULL )
   return -1;
 
@@ -46,17 +27,5 @@
  g_output_buffer_len = size;
 
- if ( (buf = roar_mm_malloc(size)) == NULL ) {
-  g_output_buffer     = NULL;
-  g_output_buffer_len = 0;
-  roar_mm_free(g_output_buffer);
-  return -1;
- }
-
- g_input_buffer = buf;
-
  ROAR_DBG("output_buffer_init(*): output buffer is at %p", buf);
-
- memlock_register(MEMLOCK_LOW, g_output_buffer, size);
- memlock_register(MEMLOCK_LOW, g_input_buffer,  size);
 
  output_buffer_reinit();
@@ -76,12 +45,8 @@
  ROAR_DBG("output_buffer_init(*): freeing output buffer at %p", g_output_buffer);
 
- if ( g_output_buffer != NULL )
-  roar_mm_free(g_output_buffer);
-
- if ( g_input_buffer != NULL )
-  roar_mm_free(g_input_buffer);
+ if ( g_output_buffer )
+  free(g_output_buffer);
 
  g_output_buffer     = NULL;
- g_input_buffer      = NULL;
  g_output_buffer_len = 0;
 
@@ -89,436 +54,8 @@
 }
 
+int output_buffer_flush  (DRIVER_USERDATA_T inst, int driver) {
+ ROAR_DBG("output_buffer_init(*): flushing output buffer");
 
-
-
-
-
-#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
-#ifdef ROAR_TARGET_WIN32
-  /* on Win32 we use WMM API. We may also test for ROAR_HAVE_LIBWINMM. I'm not sure what is better.
-   * both, WMM and UNIX like stuff is supported in cygwin.
-   */
-  "wmm",
-#endif
-  // native and pseudo-native interfaces:
-  "oss", "alsa", "sndio", "wmm",
-  // sound libs:
-  "ao", "portaudio",
-  // other sound systems:
-  "esd", "rsound", "artsc", "pulsesimple", "roar",
-  // libroareio's drivers:
-  "cdriver",
-  // 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 = 0;
- 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;
- char * strtok_store;
-
- 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 = roar_mm_strdup("codec=" ROAR_DRIVER_CODEC);
-  }
-#endif
-#else
-  ROAR_ERR("add_output(*): Can not find default driver");
-  return -1;
-#endif
- }
-
- if ( opts == NULL && count == 0 ) {
-  ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = ?", drv, dev, opts);
-  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 = roar_mm_strtok_r(opts, ",", &strtok_store);
- }
-
- 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 )
-    roar_mm_free(to_free);
-#endif
-   return -1;
-  }
-
-  k = roar_mm_strtok_r(NULL, ",", &strtok_store);
- }
-
- 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 )
-  roar_mm_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;
- }
-
- _LIBROAR_IGNORE_RET(roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAMID, &stream)); // ignore errors here
- _LIBROAR_IGNORE_RET(roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_SSTREAM,   s)); // ignore errors here
-
- if ( blocks != -1 ) {
-  if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLOCKS, &blocks) == -1 ) {
-   ROAR_WARN("add_output(drv='%s', dev='%s', opts='%s'): can not set number of blocks.", drv, dev, opts);
-  }
- }
-
- if ( blocksize != -1 ) {
-  if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DBLKSIZE, &blocksize) == -1 ) {
-   ROAR_WARN("add_output(drv='%s', dev='%s', opts='%s'): can not set blocksize.", drv, dev, opts);
-  }
- }
-
- // TODO: we shoudld *really* check for errors here...
- if ( channel != -1 ) {
-  tu16 = channel;
-  if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXSCHAN, &tu16) == -1 ) {
-   streams_delete(stream);
-   if ( prim ) alive = 0;
-   ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not set DMX channel number.", drv, dev, opts);
-   ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
-   return -1;
-  }
- }
- if ( universe != -1 ) {
-  tu16 = universe;
-  if ( roar_vio_ctl(&(ss->vio), ROAR_VIO_CTL_SET_DMXUNIV, &tu16) == -1 ) {
-   streams_delete(stream);
-   if ( prim ) alive = 0;
-   ROAR_ERR("add_output(drv='%s', dev='%s', opts='%s'): can not set DMX universe.", drv, dev, opts);
-   ROAR_DBG("add_output(drv='%s', dev='%s', opts='%s') = -1", drv, dev, opts);
-   return -1;
-  }
- }
-
- 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;
+ return driver_write(inst, driver, g_output_buffer, g_output_buffer_len);
 }
 
