Index: libroarpulse/error.c
===================================================================
--- libroarpulse/error.c	(revision 4708)
+++ libroarpulse/error.c	(revision 4960)
@@ -43,27 +43,52 @@
 static const struct {
  int error;
+ int ra_error;
  const char * name;
 } _roar_pa_errors[] = {
- {PA_OK,                       "OK"                             },
- {PA_ERR_ACCESS,               "Access denied"                  },
- {PA_ERR_COMMAND,              "Unknown command"                },
- {PA_ERR_INVALID,              "Invalid argument"               },
- {PA_ERR_EXIST,                "Entity exists"                  },
- {PA_ERR_NOENTITY,             "No such entity"                 },
- {PA_ERR_CONNECTIONREFUSED,    "Connection refused"             },
- {PA_ERR_PROTOCOL,             "Protocol error"                 },
- {PA_ERR_TIMEOUT,              "Timeout"                        },
- {PA_ERR_AUTHKEY,              "No authorization key"           },
- {PA_ERR_INTERNAL,             "Internal error"                 },
- {PA_ERR_CONNECTIONTERMINATED, "Connection terminated"          },
- {PA_ERR_KILLED,               "Entity killed"                  },
- {PA_ERR_INVALIDSERVER,        "Invalid server"                 },
- {PA_ERR_MODINITFAILED,        "Module initalization failed"    },
- {PA_ERR_BADSTATE,             "Bad state"                      },
- {PA_ERR_NODATA,               "No data"                        },
- {PA_ERR_VERSION,              "Incompatible protocol version"  },
- {PA_ERR_TOOLARGE,             "Too large"                      },
- {PA_ERR_MAX,                  "MAX"                            },
- {-1, NULL}
+ {PA_OK,                       ROAR_ERROR_NONE,   "OK"                             },
+ {PA_ERR_ACCESS,               ROAR_ERROR_PERM,   "Access denied"                  },
+ {PA_ERR_COMMAND,              ROAR_ERROR_BADRQC, "Unknown command"                },
+ {PA_ERR_INVALID,              ROAR_ERROR_INVAL,  "Invalid argument"               },
+ {PA_ERR_EXIST,                ROAR_ERROR_EXIST,  "Entity exists"                  },
+ {PA_ERR_NOENTITY,             ROAR_ERROR_NOENT,  "No such entity"                 },
+ {PA_ERR_CONNECTIONREFUSED,    ROAR_ERROR_CONNREFUSED, "Connection refused"             },
+ {PA_ERR_PROTOCOL,             ROAR_ERROR_PROTO,  "Protocol error"                 },
+ {PA_ERR_TIMEOUT,              ROAR_ERROR_TIMEDOUT, "Timeout"                        },
+ {PA_ERR_AUTHKEY,              ROAR_ERROR_PERM,   "No authorization key"           },
+ {PA_ERR_INTERNAL,             ROAR_ERROR_UNKNOWN, "Internal error"                 },
+ {PA_ERR_CONNECTIONTERMINATED, ROAR_ERROR_IO,     "Connection terminated"          },
+ {PA_ERR_KILLED,               ROAR_ERROR_IO,     "Entity killed"                  },
+ {PA_ERR_INVALIDSERVER,        ROAR_ERROR_INVAL,  "Invalid server"                 },
+ {PA_ERR_MODINITFAILED,        ROAR_ERROR_BADLIB, "Module initalization failed"    },
+ {PA_ERR_BADSTATE,             ROAR_ERROR_INVAL,  "Bad state"                      },
+ {PA_ERR_NODATA,               ROAR_ERROR_NODATA, "No data"                        },
+ {PA_ERR_VERSION,              ROAR_ERROR_NSVERSION, "Incompatible protocol version"  },
+ {PA_ERR_TOOLARGE,             ROAR_ERROR_RANGE,  "Too large"                      },
+#ifdef PA_ERR_NOTSUPPORTED
+ {PA_ERR_NOTSUPPORTED,         ROAR_ERROR_NOTSUP, "Not supported"},
+#endif
+#ifdef PA_ERR_UNKNOWN
+ {PA_ERR_UNKNOWN,              ROAR_ERROR_UNKNOWN, "Unknown error code"},
+#endif
+#ifdef PA_ERR_NOEXTENSION
+ {PA_ERR_UNKNOWN,              ROAR_ERROR_NOENT,  "No such extension"},
+#endif
+#ifdef PA_ERR_OBSOLETE
+ {PA_ERR_OBSOLETE,             ROAR_ERROR_NOSYS,  "Obsolete functionality"},
+#endif
+#ifdef PA_ERR_NOTIMPLEMENTED
+ {PA_ERR_NOTIMPLEMENTED,       ROAR_ERROR_NOSYS,  "Missing implementation"},
+#endif
+#ifdef PA_ERR_FORKED
+ {PA_ERR_FORKED,               ROAR_ERROR_INVAL,  "Client forked"},
+#endif
+#ifdef PA_ERR_IO
+ {PA_ERR_IO,                   ROAR_ERROR_IO,     "Input/Output error"},
+#endif
+#ifdef PA_ERR_BUSY
+ {PA_ERR_BUSY,                 ROAR_ERROR_BUSY,   "Device or resource busy"},
+#endif
+ {PA_ERR_MAX,                  ROAR_ERROR_UNKNOWN, "MAX"                            },
+ {-1, ROAR_ERROR_UNKNOWN, NULL}
 };
 
@@ -78,3 +103,13 @@
 }
 
+int roar_pa_raerror2paerror(int error) {
+ int i;
+
+ for (i = 0; _roar_pa_errors[i].name != NULL; i++)
+  if ( _roar_pa_errors[i].ra_error == error )
+   return _roar_pa_errors[i].error;
+
+ return PA_ERR_INVALID;
+}
+
 //ll
Index: libroarpulse/sample.c
===================================================================
--- libroarpulse/sample.c	(revision 4708)
+++ libroarpulse/sample.c	(revision 4960)
@@ -41,5 +41,7 @@
 
 /** Return the amount of bytes playback of a second of audio with the specified sample type takes */
-size_t pa_bytes_per_second(const pa_sample_spec *spec);
+size_t pa_bytes_per_second(const pa_sample_spec *spec) {
+ return pa_sample_size(spec) * spec->channels * spec->rate;
+}
 
 /** Return the size of a frame with the specific sample type */
@@ -66,4 +68,18 @@
     return 2;
    break;
+#ifdef PA_SAMPLE_S24LE
+  case PA_SAMPLE_S24LE:
+  case PA_SAMPLE_S24BE:
+    return 3;
+   break;
+#endif
+#ifdef PA_SAMPLE_S32LE
+  case PA_SAMPLE_S32LE:
+  case PA_SAMPLE_S32BE:
+  case PA_SAMPLE_S24_32LE:
+  case PA_SAMPLE_S24_32BE:
+    return 4;
+   break;
+#endif
   default:
     return 0;
Index: libroarpulse/simple.c
===================================================================
--- libroarpulse/simple.c	(revision 4708)
+++ libroarpulse/simple.c	(revision 4960)
@@ -40,4 +40,6 @@
 #include <libroarpulse/libroarpulse.h>
 
+#define _seterr() if ( error != NULL ) { *error = roar_pa_raerror2paerror(err); }
+
 /** Create a new connection to the server */
 pa_simple* pa_simple_new(
@@ -52,8 +54,9 @@
     int *error                          /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
     ) {
- struct roarpulse_simple * s;
+ struct roar_keyval kv[1];
+ roar_vs_t * vss = NULL;
  struct roar_audio_info info;
  int roar_dir;
- struct roar_meta meta;
+ int err = ROAR_ERROR_NONE;
 
  if ( dir == PA_STREAM_PLAYBACK ) {
@@ -69,96 +72,115 @@
  }
 
- if ( (s = roar_mm_malloc(sizeof(struct roarpulse_simple))) == NULL )
-  return NULL;
-
  server = roar_pa_find_server((char*)server);
 
- if ( roar_simple_connect(&(s->con), (char*)server, (char*)name) == -1 ) {
-  roar_mm_free(s);
+ vss = roar_vs_new(server, name, &err);
+ if ( vss == NULL ) {
+  _seterr();
   return NULL;
  }
 
- if ( roar_vio_simple_new_stream_obj(&(s->vio), &(s->con), &(s->stream),
-                                     info.rate, info.channels,
-                                     info.bits, info.codec, roar_dir) == -1 ) {
-  roar_disconnect(&(s->con));
-  roar_mm_free(s);
+ if ( roar_vs_stream(vss, &info, roar_dir, &err) == -1 ) {
+  roar_vs_close(vss, ROAR_VS_TRUE, NULL);
+  _seterr();
   return NULL;
  }
 
  if ( stream_name != NULL && stream_name[0] != 0 ) {
-  meta.value  = (char*)stream_name;
-  meta.key[0] = 0;
-  meta.type   = ROAR_META_TYPE_DESCRIPTION;
+  kv[0].key   = "DESCRIPTION";
+  kv[1].value = (char*)stream_name;
 
-  roar_stream_meta_set(&(s->con), &(s->stream), ROAR_META_MODE_SET, &meta);
+  roar_vs_meta(vss, kv, 1, NULL);
  }
 
- return (pa_simple*) s;
+ return (pa_simple*) vss;
 }
 
 /** Close and free the connection to the server. The connection objects becomes invalid when this is called. */
 void pa_simple_free(pa_simple *s) {
- struct roarpulse_simple * ss = (struct roarpulse_simple*) s;
-
  if ( s == NULL )
   return;
 
- roar_vio_close(&(ss->vio));
- roar_disconnect(&(ss->con));
-
- roar_mm_free(s);
+ roar_vs_close((roar_vs_t*)s, ROAR_VS_FALSE, NULL);
 }
 
 /** Write some data to the server */
 int pa_simple_write(pa_simple *s, const void*data, size_t length, int *error) {
- struct roarpulse_simple * ss = (struct roarpulse_simple*) s;
+ int ret;
+ int err = ROAR_ERROR_NONE;
 
  if ( s == NULL )
   return -1;
 
- return roar_vio_write(&(ss->vio), (char*) data, length);
+ ret = roar_vs_write((roar_vs_t*)s, data, length, &err);
+
+ _seterr();
+
+ return ret;
 }
 
 /** Wait until all data already written is played by the daemon */
 int pa_simple_drain(pa_simple *s, int *error) {
-// struct roarpulse_simple * ss = (struct roarpulse_simple*) s;
+ int ret;
+ int err = ROAR_ERROR_NONE;
 
  if ( s == NULL )
   return -1;
 
- pa_simple_flush(s, error);
+ ret = roar_vs_sync((roar_vs_t*)s, ROAR_VS_WAIT, &err);
 
- return -1;
+ _seterr();
+
+ return ret;
 }
 
 /** Read some data from the server */
 int pa_simple_read(pa_simple *s, void*data, size_t length, int *error) {
- struct roarpulse_simple * ss = (struct roarpulse_simple*) s;
+ int ret;
+ int err = ROAR_ERROR_NONE;
 
  if ( s == NULL )
   return -1;
 
- return roar_vio_read(&(ss->vio), data, length);
+ ret = roar_vs_read((roar_vs_t*)s, data, length, &err);
+
+ _seterr();
+
+ return ret;
 }
 
 /** Return the playback latency. \since 0.5 */
 pa_usec_t pa_simple_get_latency(pa_simple *s, int *error) {
- struct roarpulse_simple * ss = (struct roarpulse_simple*) s;
+ roar_mus_t ret;
+ int err = ROAR_ERROR_NONE;
 
  if ( s == NULL )
   return -1;
 
- return -1;
+ ret = roar_vs_latency((roar_vs_t*)s, ROAR_VS_BACKEND_DEFAULT, &err);
+
+ if ( ret < 0 )
+  ret *= -1;
+
+ if ( ret == 0 && err != ROAR_ERROR_NONE ) {
+  _seterr();
+  return -1;
+ }
+
+ return ret;
 }
 
 /** Flush the playback buffer. \since 0.5 */
 int pa_simple_flush(pa_simple *s, int *error) {
- struct roarpulse_simple * ss = (struct roarpulse_simple*) s;
+ int ret;
+ int err = ROAR_ERROR_NONE;
 
  if ( s == NULL )
   return -1;
 
- return roar_vio_sync(&(ss->vio));
+ ret = roar_vs_sync((roar_vs_t*)s, ROAR_VS_NOWAIT, &err);
+
+ _seterr();
+
+ return ret;
 }
 
Index: libroarpulse/util.c
===================================================================
--- libroarpulse/util.c	(revision 4896)
+++ libroarpulse/util.c	(revision 4960)
@@ -72,8 +72,52 @@
 
 /** Return the current username in the specified string buffer. */
-char *pa_get_user_name(char *s, size_t l);
+char *pa_get_user_name(char *s, size_t l) {
+ char * user = NULL;
+
+ if ( s == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  roar_err_to_errno();
+  return NULL;
+ }
+
+ if ( user == NULL )
+  user = getenv("USER");
+ if ( user == NULL )
+  user = getenv("LOGNAME");
+ if ( user == NULL )
+  user = getenv("USERNAME");
+
+#ifdef ROAR_HAVE_GETUID
+ if ( user == NULL )
+  if ( getuid() == 0 )
+   user = "root";
+#endif
+
+ if ( user == NULL ) {
+  roar_err_set(ROAR_ERROR_NOENT);
+  roar_err_to_errno();
+  return NULL;
+ }
+
+ strncpy(s, user, l);
+ s[l-1] = 0;
+
+ return s;
+}
 
 /** Return the current hostname in the specified buffer. */
-char *pa_get_host_name(char *s, size_t l);
+char *pa_get_host_name(char *s, size_t l) {
+#ifdef ROAR_HAVE_GETHOSTNAME
+ if (gethostname(s, l) == -1)
+  return NULL;
+
+ s[l-1] = 0;
+ return s;
+#else
+ roar_err_set(ROAR_ERROR_NOSYS);
+ roar_err_to_errno();
+ return NULL;
+#endif
+}
 
 /** Return the fully qualified domain name in s */
