Index: roarclients/roarbidir.c
===================================================================
--- roarclients/roarbidir.c	(revision 4997)
+++ roarclients/roarbidir.c	(revision 5022)
@@ -50,12 +50,17 @@
  char * server   = NULL;
  char * k;
- int    fh;
  int    i;
- int    in  = -1;
- int    out = -1;
+ struct roar_vio_defaults  def;
+ struct roar_vio_calls in_store;
+ struct roar_vio_calls * in = NULL, * out = NULL;
+ struct roar_vio_calls * vss_vio = NULL;
+ roar_vs_t * vss;
+ struct roar_vio_select vios[2];
  char buf[BUFSIZE];
- fd_set sl;
- struct timeval tv;
- int max_fh;
+ int err;
+ ssize_t ret;
+
+ if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 )
+  return 1;
 
  for (i = 1; i < argc; i++) {
@@ -75,9 +80,10 @@
    usage();
    return 0;
-  } else if ( in == -1 ) {
-   if ( (in = open(k, O_RDONLY, 0644)) == -1 ) {
-    fprintf(stderr, "Error: can not open file: %s: %s\n", k, strerror(errno));
+  } else if ( in == NULL ) {
+   if ( roar_vio_open_dstr(&in_store, k, &def, 1) == -1 ) {
+    fprintf(stderr, "Error: can not open file: %s: %s\n", k, roar_error2str(roar_error));
     return 1;
    }
+   in = &in_store;
   } else {
    fprintf(stderr, "Error: unknown argument: %s\n", k);
@@ -87,46 +93,47 @@
  }
 
- if ( (fh = roar_simple_stream(rate, channels, bits, codec, server, ROAR_DIR_BIDIR, "roarbidir")) == -1 ) {
-  fprintf(stderr, "Error: can not start playback: %s\n", roar_error2str(roar_error));
-  if ( in != -1 )
-   close(in);
+ if ( (vss = roar_vs_new_simple(server, "roarbidir", rate, channels, codec, bits, ROAR_DIR_BIDIR, &err)) == NULL ) {
+  fprintf(stderr, "Error: can not start playback: %s\n", roar_error2str(err));
+  if ( in != NULL )
+   roar_vio_close(in);
   return 1;
  }
 
- if ( in  == -1 )
-  in  = ROAR_STDIN;
- if ( out == -1 )
-  out = ROAR_STDOUT;
+ if ( in  == NULL )
+  in  = roar_stdin;
+ if ( out == NULL )
+  out = roar_stdout;
 
- max_fh = (in > fh ? in : fh) + 1;
- i      = 1;
+ vss_vio = roar_vs_vio_obj(vss, NULL);
 
- while (i > 0) {
-  FD_ZERO(&sl);
-  FD_SET(in, &sl);
-  FD_SET(fh, &sl);
+ while (1) {
+  memset(vios, 0, sizeof(vios));
 
-  tv.tv_sec  = 0;
-  tv.tv_usec = 50000;
+  ROAR_VIO_SELECT_SETVIO(&(vios[0]), vss_vio, ROAR_VIO_SELECT_READ);
+  ROAR_VIO_SELECT_SETVIO(&(vios[1]), in, ROAR_VIO_SELECT_READ);
 
-  if (select(max_fh, &sl, NULL, NULL, &tv) > 0) {
-   if ( FD_ISSET(fh, &sl) ) {
-    if ( (i = read(fh, buf, BUFSIZE)) == -1 )
-     return -1;
-    if ( write(out, buf, i) != i )
-     return -1;
-   }
-   if ( FD_ISSET(in, &sl) ) {
-    if ( (i = read(in, buf, BUFSIZE)) == -1 )
-     return -1;
-    if ( write(fh, buf, i) != i )
-     return -1;
-   }
+  if ( (ret = roar_vio_select(vios, 2, NULL, NULL)) == -1 )
+   break;
+
+  if ( ret < 0 )
+   continue;
+
+  if ( vios[0].eventsa & ROAR_VIO_SELECT_READ ) {
+   if ( (ret = roar_vs_read(vss, buf, sizeof(buf), NULL)) == -1 )
+    break;
+   if ( roar_vio_write(out, buf, ret) != ret )
+    break;
+  }
+  if ( vios[1].eventsa & ROAR_VIO_SELECT_READ ) {
+   if ( (ret = roar_vio_read(in, buf, sizeof(buf))) == -1 )
+    break;
+   if ( roar_vs_write(vss, buf, ret, NULL) != ret )
+    break;
   }
  }
 
- roar_simple_close(fh);
+ roar_vs_close(vss, ROAR_VS_TRUE, NULL);
 
- close(in);
+ roar_vio_close(in);
 
  return 0;
Index: roarclients/roarcatplay.c
===================================================================
--- roarclients/roarcatplay.c	(revision 4914)
+++ roarclients/roarcatplay.c	(revision 5022)
@@ -54,4 +54,6 @@
  int    bg      = 0;
  int    verbose = 0;
+ roar_vs_t * vss;
+ int err;
 #ifdef ROAR_HAVE_UNIX
  struct roar_connection con[1];
@@ -121,8 +123,11 @@
  } else { // MODE_SIMPLE
 #endif
-  if ( roar_simple_play_file(file, server, "roarcatplay") == -1 ) {
-   ROAR_ERR("Can not start playback");
+  if ( (vss = roar_vs_new_from_file(server, "roarcatplay", file, &err)) == NULL ) {
+   ROAR_ERR("Can not start playback: %s", roar_error2str(err));
    return 1;
   }
+  roar_vs_run(vss, NULL);
+  roar_vs_sync(vss, ROAR_VS_WAIT, NULL);
+  roar_vs_close(vss, ROAR_VS_FALSE, NULL);
 #ifdef ROAR_HAVE_UNIX
  }
Index: roarclients/roarcatvio.c
===================================================================
--- roarclients/roarcatvio.c	(revision 4708)
+++ roarclients/roarcatvio.c	(revision 5022)
@@ -44,22 +44,14 @@
 
 int main (int argc, char * argv[]) {
- int    rate     = ROAR_RATE_DEFAULT;
- int    bits     = ROAR_BITS_DEFAULT;
- int    channels = ROAR_CHANNELS_DEFAULT;
+ struct roar_audio_info info = {.rate = ROAR_RATE_DEFAULT, .bits = ROAR_BITS_DEFAULT, .channels = ROAR_CHANNELS_DEFAULT};
  int    codec    = -1;
+ int    auinfo_changed = 0;
  char * server   = NULL;
  char * k;
  int    i;
  char * name = "roarcatvio";
- struct roar_vio_calls file, stream;
- struct roar_vio_defaults def;
- int file_opened = 0;
- const char * content_type;
-
- if ( roar_vio_open_fh(&file, ROAR_STDIN) == -1 )
-  return 1;
-
- if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 )
-  return 1;
+ roar_vs_t * vss;
+ char * filename = NULL;
+ int err;
 
  for (i = 1; i < argc; i++) {
@@ -71,30 +63,26 @@
    name = argv[++i];
   } else if ( !strcmp(k, "--rate") || !strcmp(k, "-r") ) {
-   rate = atoi(argv[++i]);
+   info.rate = roar_str2rate(argv[++i]);
+   auinfo_changed = 1;
   } else if ( !strcmp(k, "--bits") ) {
-   bits = atoi(argv[++i]);
+   info.bits = roar_str2bits(argv[++i]);
+   auinfo_changed = 1;
   } else if ( !strcmp(k, "-b") ) {
-   bits = 8;
+   info.bits = 8;
+   auinfo_changed = 1;
   } else if ( !strcmp(k, "--channels") || !strcmp(k, "--chans") ) {
-   channels = atoi(argv[++i]);
+   info.channels = roar_str2channels(argv[++i]);
+   auinfo_changed = 1;
   } else if ( !strcmp(k, "-m") ) {
-   channels = 1;
+   info.channels = 1;
+   auinfo_changed = 1;
   } else if ( !strcmp(k, "--codec") ) {
    codec = roar_str2codec(argv[++i]);
+   auinfo_changed = 1;
   } else if ( !strcmp(k, "--help") ) {
    usage();
    return 0;
-  } else if ( !file_opened ) {
-   file_opened = 1;
-   if ( roar_vio_open_dstr(&file, k, &def, 1) == -1 ) {
-    fprintf(stderr, "Error: can not open file: %s: %s\n", k, strerror(errno));
-    return 1;
-   }
-
-   if ( codec == -1 ) {
-    if ( roar_vio_ctl(&file, ROAR_VIO_CTL_GET_MIMETYPE, &content_type) != -1 ) {
-     codec = roar_mime2codec(content_type);
-    }
-   }
+  } else if ( filename == NULL ) {
+   filename    = k;
   } else {
    fprintf(stderr, "Error: unknown argument: %s\n", k);
@@ -107,13 +95,30 @@
   codec = ROAR_CODEC_DEFAULT;
 
- if ( roar_vio_simple_stream(&stream, rate, channels, bits, codec, server, ROAR_DIR_PLAY, name) == -1 ) {
-  fprintf(stderr, "Error: can not start playback\n");
-  return 1;
+ info.codec = codec;
+
+ if ( (vss = roar_vs_new(server, name, &err)) == NULL ) {
+  fprintf(stderr, "Error: can not connect to server: %s: %s\n",
+   server == NULL ? "(default)" : server, roar_error2str(err));
+  return 10;
  }
 
- roar_vio_copy_data(&stream, &file);
+ if ( auinfo_changed ) {
+  if ( roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) == -1 ) {
+   fprintf(stderr, "Error: can not create new stream: %s\n", roar_error2str(err));
+   roar_vs_close(vss, ROAR_VS_TRUE, NULL);
+   return 10;
+  }
+ }
 
- roar_vio_close(&file);
- roar_vio_close(&stream);
+ if ( roar_vs_file_simple(vss, filename, &err) == -1 ) {
+  fprintf(stderr, "Error: can not open file: %s: %s\n", filename, roar_error2str(err));
+  roar_vs_close(vss, ROAR_VS_TRUE, NULL);
+  return 10;
+ }
+
+ roar_vs_run(vss, NULL);
+
+ roar_vs_sync(vss, ROAR_VS_WAIT, NULL);
+ roar_vs_close(vss, ROAR_VS_FALSE, NULL);
 
  return 0;
