Index: include/libroardsp/convert.h
===================================================================
--- include/libroardsp/convert.h	(revision 3811)
+++ include/libroardsp/convert.h	(revision 4111)
@@ -94,4 +94,7 @@
 int roar_conv_rate_SRC   (void * out, void * in, int samples, int from, int to, int bits, int channels);
 
+int roar_conv_rate2      (void * out, void * in, int samples, int outsamples, int bits, int channels);
+int roar_conv_poly3_16   (int16_t * out, int16_t * in, size_t olen, size_t ilen, int channels);
+
 int roar_conv_codec (void * out, void * in, int samples, int from, int to, int bits);
 
Index: libroardsp/convert.c
===================================================================
--- libroardsp/convert.c	(revision 4110)
+++ libroardsp/convert.c	(revision 4111)
@@ -626,4 +626,13 @@
 }
 
+int roar_conv_rate2      (void * out, void * in, int samples, int outsamples, int bits, int channels) {
+ switch (bits) {
+  case 16:
+    return roar_conv_poly3_16(out, in, outsamples, samples, channels);
+   break;
+ }
+ return -1;
+}
+
 int roar_conv_signedness  (void * out, void * in, int samples, int from, int to, int bits) {
 
@@ -1018,4 +1027,5 @@
  ROAR_DBG("roar_conv2(*): input samples: %i", samples);
 
+#if 0
  // calculate size per frame
  needed_buffer  = ROAR_MAX(from->channels, to->channels) * ROAR_MAX(from->bits, to->bits) / 8;
@@ -1032,4 +1042,5 @@
  if ( needed_buffer > bufsize )
   return -1;
+#endif
 
  if ( from->rate != to->rate || from->channels != to->channels )
@@ -1078,9 +1089,9 @@
 //--//
  if ( from->rate != to->rate ) {
-  if ( roar_conv_rate(out, cin, samples, from->rate, to->rate, cinfo.bits, cinfo.channels) == -1 )
+  if ( roar_conv_rate2(out, cin, samples, bufsize/(cinfo.bits/8), cinfo.bits, cinfo.channels) == -1 )
    return -1;
 
   cin            = out;
-  samples        = (float)samples * (float)to->rate / (float)from->rate;
+  samples        = bufsize/(cinfo.bits/8);
   cinfo.rate     = to->rate;
  }
@@ -1188,2 +1199,71 @@
 
 //ll
+/***********************************/
+// ilen and olen are in samples, not frames.
+int roar_conv_poly3_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen, int channels) {
+ float ratio = (float)olen / (float)ilen;
+ int16_t *ip;
+ int c, x;
+
+ /* Can't create poly out of less than 3 samples in each channel. */
+ if ( ilen < 3 * channels )
+  return -1;
+
+ ip = roar_mm_malloc(ilen * sizeof(int16_t));
+ if ( ip == NULL )
+  return -1;
+
+ memcpy(ip, in, ilen * sizeof(int16_t));
+
+ for ( x = 0; x < olen/channels; x++ ) {
+  for ( c = 0; c < channels; c++ ) {
+   float pos_out;
+   float pos_in;
+
+   float poly[3];
+   float y[3];
+   float x_val;
+
+   pos_out = x;
+   pos_in = pos_out / ratio;
+
+   if ( (int)pos_in == 0 ) {
+    y[0] = ip[c];
+    y[1] = ip[channels + c];
+    y[2] = ip[2 * channels + c];
+    x_val = pos_in;
+   } else if ( (int)pos_in + 1 >= ilen/channels ) {
+    /* If we're at the end of the block, we will need to interpolate against a value that is not yet known.
+     * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */
+    y[0] = ip[((int)pos_in - 1) * channels + c];
+    y[1] = ip[(int)pos_in * channels + c];
+    y[2] = y[1] * 2.0 - y[0];
+    /* We have to clip this value. */
+    if ( (int32_t)y[2] > 0x7FFE )
+     y[2] = 0x7FFE;
+    else if ( (int32_t)y[2] < -0x7FFE )
+     y[2] = -0x7FFE;
+
+    x_val = pos_in - (int)pos_in + 1.0;
+   } else {
+    y[0] = ip[((int)pos_in - 1) * channels + c];
+    y[1] = ip[(int)pos_in * channels + c];
+    y[2] = ip[((int)pos_in + 1) * channels + c];
+    x_val = pos_in - (int)pos_in + 1.0;
+   }
+
+   roar_math_mkpoly_3x3(poly, y);
+
+   int32_t temp = (int32_t)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5);
+   /* temp could be out of bounds, so need to check this */
+   if (temp > 0x7FFE )
+    out[x * channels + c] = 0x7FFE;
+   else if (temp < -0x7FFE)
+    out[x * channels + c] = -0x7FFE;
+   else
+    out[x * channels + c] = (int16_t)temp;
+  }
+ }
+ roar_mm_free(ip);
+ return 0;
+}
Index: roard/include/output.h
===================================================================
--- roard/include/output.h	(revision 3811)
+++ roard/include/output.h	(revision 4111)
@@ -52,5 +52,13 @@
 #define ROAR_OUTPUT_WRITE_SIZE     1024
 
-#define ROAR_OUTPUT_CALC_OUTBUFSIZE(x)   (ROAR_OUTPUT_BUFFER_SAMPLES * (x)->channels * ((x)->bits / 8) * ((float)(x)->rate/g_sa->rate))
+//#define ROAR_OUTPUT_CALC_OUTBUFSIZE(x)   (ROAR_OUTPUT_BUFFER_SAMPLES * (x)->channels * ((x)->bits / 8) * ((float)(x)->rate/g_sa->rate))
+// First rounds the samples count, and makes sure that the outbuffer size is divisible by the framesize (channels * bits/8)
+#define ROAR_OUTPUT_CALC_OUTBUFSIZE(x)   ( \
+                                          ( \
+                                           (int)(ROAR_OUTPUT_BUFFER_SAMPLES * ((float)(x)->rate/g_sa->rate) + 0.5) \
+                                          ) * \
+                                          (x)->channels * ((x)->bits / 8) \
+                                         )
+
 #define ROAR_OUTPUT_CALC_OUTBUFSAMP(x,y) ((y) / ((x)->channels * ((x)->bits / 8)*((float)(x)->rate/g_sa->rate)))
 #define ROAR_OUTPUT_CALC_OUTBUFSIZE_MAX(x0,x1)  (ROAR_OUTPUT_BUFFER_SAMPLES                                  * \
Index: roard/streams.c
===================================================================
--- roard/streams.c	(revision 4102)
+++ roard/streams.c	(revision 4111)
@@ -1165,5 +1165,5 @@
 //  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, buflen) == -1 ) {
+  if ( roar_conv2(bufdata, indata, inlen, stream_info, info, outlen) == -1 ) {
    if ( bufbuf != NULL )
     roar_buffer_free(bufbuf);
