changeset 4234:b293ce14a01a

partially works...
author Eugene Zagidullin <e.asphyx@gmail.com>
date Thu, 31 Jan 2008 12:04:13 +0300
parents 74c6f3d3cf1d
children 2d4b4f13d10d
files src/audacious/main.c src/audacious/output.c src/libSAD/Makefile src/libSAD/dither.c src/libSAD/dither.h src/libSAD/dither_ops.c src/libSAD/dither_ops.h src/libSAD/libSAD.h src/libSAD/noicegen.c src/libSAD/noicegen.h
diffstat 10 files changed, 338 insertions(+), 204 deletions(-) [+]
line wrap: on
line diff
--- a/src/audacious/main.c	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/audacious/main.c	Thu Jan 31 12:04:13 2008 +0300
@@ -79,6 +79,7 @@
 #include "ui_fileinfo.h"
 #include "signals.h"
 #include "ui_skinned_window.h"
+#include "libSAD.h"
 
 #include "icons-stock.h"
 #include "images/audacious_player.xpm"
@@ -1429,6 +1430,7 @@
     signal_handlers_init();
 
     g_random_set_seed(time(NULL));
+    SAD_dither_init_rand((gint32)time(NULL));
 
     bmp_config_load();
 
--- a/src/audacious/output.c	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/audacious/output.c	Thu Jan 31 12:04:13 2008 +0300
@@ -1,5 +1,5 @@
 /*  Audacious - Cross-platform multimedia player
- *  Copyright (C) 2005-2007  Audacious team
+ *  Copyright (C) 2005-2008  Audacious team
  *
  *  Based on BMP:
  *  Copyright (C) 2003-2004  BMP development team.
@@ -23,6 +23,8 @@
  *  Audacious or using our public API to be a derived work.
  */
 
+#define AUD_DEBUG
+
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
@@ -42,6 +44,8 @@
 #include "volumecontrol.h"
 #include "visualization.h"
 
+#include "libSAD.h"
+
 #include <math.h>
 
 #ifdef USE_SRC
@@ -77,6 +81,78 @@
     .written_time = get_written_time,
 };
 
+static const struct {
+    AFormat afmt;
+    SAD_sample_format sadfmt;
+} format_table[] = {
+    {FMT_U8, SAD_SAMPLE_U8},
+    {FMT_S8, SAD_SAMPLE_S8},
+
+    {FMT_S16_LE, SAD_SAMPLE_S16_LE},
+    {FMT_S16_BE, SAD_SAMPLE_S16_BE},
+    {FMT_S16_NE, SAD_SAMPLE_S16},
+
+    {FMT_U16_LE, SAD_SAMPLE_U16_LE},
+    {FMT_U16_BE, SAD_SAMPLE_U16_BE},
+    {FMT_U16_NE, SAD_SAMPLE_U16},
+
+    {FMT_S24_LE, SAD_SAMPLE_S24_LE},
+    {FMT_S24_BE, SAD_SAMPLE_S24_BE},
+    {FMT_S24_NE, SAD_SAMPLE_S24},
+    
+    {FMT_U24_LE, SAD_SAMPLE_U24_LE},
+    {FMT_U24_BE, SAD_SAMPLE_U24_BE},
+    {FMT_U24_NE, SAD_SAMPLE_U24},
+
+    {FMT_S32_LE, SAD_SAMPLE_S32_LE},
+    {FMT_S32_BE, SAD_SAMPLE_S32_BE},
+    {FMT_S32_NE, SAD_SAMPLE_S32},
+    
+    {FMT_U32_LE, SAD_SAMPLE_U32_LE},
+    {FMT_U32_BE, SAD_SAMPLE_U32_BE},
+    {FMT_U32_NE, SAD_SAMPLE_U32},
+    
+    {FMT_FLOAT, SAD_SAMPLE_FLOAT},
+};
+
+static inline unsigned sample_size(AFormat fmt) {
+  switch(fmt) {
+    case FMT_S8:
+    case FMT_U8: return sizeof(gint8);
+    case FMT_S16_NE:
+    case FMT_S16_LE:
+    case FMT_S16_BE:
+    case FMT_U16_NE:
+    case FMT_U16_LE:
+    case FMT_U16_BE: return sizeof(gint16);
+    case FMT_S24_NE:
+    case FMT_S24_LE:
+    case FMT_S24_BE:
+    case FMT_U24_NE:
+    case FMT_U24_LE:
+    case FMT_U24_BE:
+    case FMT_S32_NE:
+    case FMT_S32_LE:
+    case FMT_S32_BE:
+    case FMT_U32_NE:
+    case FMT_U32_LE:
+    case FMT_U32_BE: return sizeof(gint32);
+    case FMT_FLOAT: return sizeof(float);
+    default: return 0;
+  }
+}
+
+static SAD_sample_format
+sadfmt_from_afmt(AFormat fmt)
+{
+    int i;
+    for (i = 0; i < sizeof(format_table) / sizeof(format_table[0]); i++) {
+        if (format_table[i].afmt == fmt) return format_table[i].sadfmt;
+    }
+
+    return -1;
+}
+
 OutputPlugin *
 get_current_output_plugin(void)
 {
@@ -251,17 +327,39 @@
 
 #endif
 
+static SAD_dither_t *sad_state = NULL;
+static SAD_dither_t *sad_state_to_float = NULL;
+static SAD_dither_t *sad_state_from_float = NULL;
+static void *sad_out_buf = NULL;
+static int sad_out_buf_length = 0;
+
+static void
+freeSAD()
+{
+    if (sad_state != NULL)            {SAD_dither_free(sad_state);            sad_state = NULL;}
+    if (sad_state_from_float != NULL) {SAD_dither_free(sad_state_from_float); sad_state_from_float = NULL;}
+    if (sad_state_to_float != NULL)   {SAD_dither_free(sad_state_to_float);   sad_state_to_float = NULL;}
+    if (sad_out_buf != NULL)          {free(sad_out_buf);                     sad_out_buf = NULL; sad_out_buf_length = 0;}
+}
+
 gint
 output_open_audio(AFormat fmt, gint rate, gint nch)
 {
     gint ret;
     OutputPlugin *op;
+    ConfigDb *db;
+    AUDDBG("\n");
+
+    AFormat output_fmt;
+    int bit_depth;
+    SAD_buffer_format input_sad_fmt;
+    SAD_buffer_format output_sad_fmt;
     
+    db = cfg_db_open();
+
 #ifdef USE_SRC
-    ConfigDb *db;
     gboolean src_enabled;
     gint src_rate, src_type;
-    db = cfg_db_open();
     
     if (cfg_db_get_bool(db, NULL, "enable_src", &src_enabled) == FALSE)
       src_enabled = FALSE;
@@ -280,13 +378,9 @@
     else
       converter_type = src_type;
     
-    cfg_db_close(db);
-    
     freeSRC();
     
-    if(src_enabled&&
-       (fmt == FMT_S16_NE||(fmt == FMT_S16_LE && G_BYTE_ORDER == G_LITTLE_ENDIAN)||
-	(fmt == FMT_S16_BE && G_BYTE_ORDER == G_BIG_ENDIAN)))
+    if(src_enabled)
       {
 	src_state = src_new(converter_type, nch, &srcError);
 	if (src_state != NULL)
@@ -295,10 +389,94 @@
 	    rate = overSamplingFs;
 	  }
 	else
+        {
 	  fprintf(stderr, "src_new(): %s\n\n", src_strerror(srcError));
+          src_enabled = FALSE;
+        }
       }
 #endif
     
+    if (cfg_db_get_int(db, NULL, "output_bit_depth", &bit_depth) == FALSE) bit_depth = 16;
+    cfg_db_close(db);
+
+    AUDDBG("bit depth: %d\n", bit_depth);
+    output_fmt = (bit_depth == 24) ? FMT_S24_NE : FMT_S16_NE; /* no reason to support other output formats --asphyx */
+    
+    freeSAD();
+
+#ifdef USE_SRC
+    if (src_enabled) {
+        AUDDBG("initializing dithering engine for 2 stage conversion\n");
+        input_sad_fmt.sample_format = sadfmt_from_afmt(fmt);
+        if (input_sad_fmt.sample_format < 0) return -1;
+        input_sad_fmt.fracbits = 0;
+        input_sad_fmt.channels = nch;
+        input_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED;
+        input_sad_fmt.samplerate = 0;
+        
+        output_sad_fmt.sample_format = SAD_SAMPLE_FLOAT;
+        output_sad_fmt.fracbits = 0;
+        output_sad_fmt.channels = nch;
+        output_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED;
+        output_sad_fmt.samplerate = 0;
+        
+        sad_state_to_float = SAD_dither_init(&input_sad_fmt, &output_sad_fmt, &ret);
+        if (sad_state_to_float == NULL) {
+            AUDDBG("ditherer init failed (decoder's native --> float)\n");
+            return -1;
+        }
+        SAD_dither_set_dither (sad_state_to_float, FALSE);
+        
+        input_sad_fmt.sample_format = SAD_SAMPLE_FLOAT;
+        input_sad_fmt.fracbits = 0;
+        input_sad_fmt.channels = nch;
+        input_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED;
+        input_sad_fmt.samplerate = 0;
+        
+        output_sad_fmt.sample_format = sadfmt_from_afmt(output_fmt);
+        if (output_sad_fmt.sample_format < 0) return -1;
+        output_sad_fmt.fracbits = 0;
+        output_sad_fmt.channels = nch;
+        output_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED;
+        output_sad_fmt.samplerate = 0;
+        
+        sad_state_from_float = SAD_dither_init(&input_sad_fmt, &output_sad_fmt, &ret);
+        if (sad_state_from_float == NULL) {
+            SAD_dither_free(sad_state_to_float);
+            AUDDBG("ditherer init failed (float --> output)\n");
+            return -1;
+        }
+        SAD_dither_set_dither (sad_state_from_float, TRUE);
+        
+        fmt = output_fmt;
+    } else
+#endif /* USE_SRC */
+    if (output_fmt != fmt) {
+        AUDDBG("initializing dithering engine for direct conversion\n");
+
+        input_sad_fmt.sample_format = sadfmt_from_afmt(fmt);
+        if (input_sad_fmt.sample_format < 0) return -1;
+        input_sad_fmt.fracbits = 0;
+        input_sad_fmt.channels = nch;
+        input_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED;
+        input_sad_fmt.samplerate = 0; /* resampling not implemented yet in libSAD */
+        
+        output_sad_fmt.sample_format = sadfmt_from_afmt(output_fmt);
+        output_sad_fmt.fracbits = 0;
+        output_sad_fmt.channels = nch;
+        output_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED;
+        output_sad_fmt.samplerate = 0;
+
+        sad_state = SAD_dither_init(&input_sad_fmt, &output_sad_fmt, &ret);
+        if (sad_state == NULL) {
+            AUDDBG("ditherer init failed\n");
+            return -1;
+        }
+        SAD_dither_set_dither (sad_state, TRUE);
+
+        fmt = output_fmt;
+    }
+    
     op = get_current_output_plugin();
 
     if (op == NULL)
@@ -319,6 +497,7 @@
 
     if (ret == 1)            /* Success? */
     {
+        AUDDBG("opened audio: fmt=%d, rate=%d, nch=%d\n", fmt, rate, nch);
         op_state.fmt = fmt;
         op_state.rate = rate;
         op_state.nch = nch;
@@ -344,9 +523,12 @@
 {
     OutputPlugin *op = get_current_output_plugin();
 
+    AUDDBG("\n");
+
 #ifdef USE_SRC
     freeSRC();
 #endif
+    freeSAD();
 
     /* Do not close if there are still songs to play and the user has 
      * not requested a stop.  --nenolod
@@ -423,6 +605,8 @@
     static Flow *postproc_flow = NULL;
     OutputPlugin *op = playback->output;
     gint writeoffs;
+
+    if (length <= 0) return;
     gint time = playback->output->written_time();
 
     if (postproc_flow == NULL)
@@ -435,9 +619,10 @@
     }
 
 #ifdef USE_SRC
-    if(src_state != NULL&&length > 0)
+    if(src_state != NULL)
       {
-        int lrLength = length / nch;
+        /*int lrLength = length / nch;*/
+        int lrLength = length / sample_size(fmt);
         int overLrLength = (int)floor(lrLength*(src_data.src_ratio+1));
 	if(lengthOfSrcIn < lrLength)
 	  {
@@ -451,9 +636,10 @@
 	    free(srcOut);
 	    free(wOut);
 	    srcOut = (float*)malloc(sizeof(float)*overLrLength);
-	    wOut = (short int*)malloc(sizeof(short int)*overLrLength);
+	    wOut = (short int*)malloc(sample_size(op_state.fmt) * overLrLength);
 	  }
-        src_short_to_float_array((short int*)ptr, srcIn, lrLength);
+        /*src_short_to_float_array((short int*)ptr, srcIn, lrLength);*/
+        SAD_dither_process_buffer(sad_state_to_float, ptr, srcIn, lrLength / nch);
         src_data.data_in = srcIn;
         src_data.data_out = srcOut;
         src_data.end_of_input = 0;
@@ -465,14 +651,31 @@
           }
         else
           {
-            src_float_to_short_array(srcOut, wOut, src_data.output_frames_gen*2);
+            /*src_float_to_short_array(srcOut, wOut, src_data.output_frames_gen*2);*/
+            SAD_dither_process_buffer(sad_state_from_float, srcOut, wOut, src_data.output_frames_gen);
             ptr = wOut;
-            length = src_data.output_frames_gen * (nch * 2);
+            length = src_data.output_frames_gen *  op_state.nch * sample_size(op_state.fmt);
           }
-      }
+      } else
 #endif
-
-    length = flow_execute(postproc_flow, time, &ptr, length, op_state.fmt, op_state.rate, op_state.nch);
+    if(sad_state != NULL) {
+        int frames  = length / nch / sample_size(fmt);
+        int len =  frames * op_state.nch * sample_size(op_state.fmt);
+        if(sad_out_buf == NULL || sad_out_buf_length < len ) {
+            if(sad_out_buf != NULL) free (sad_out_buf);
+            sad_out_buf = malloc(len);
+            sad_out_buf_length = len; 
+        }
+        SAD_dither_process_buffer(sad_state, ptr, sad_out_buf, frames);
+        ptr = sad_out_buf;
+    }
+    
+    if (op_state.fmt == FMT_S16_NE || (op_state.fmt == FMT_S16_LE && G_BYTE_ORDER == G_LITTLE_ENDIAN) ||
+                                      (op_state.fmt == FMT_S16_BE && G_BYTE_ORDER == G_BIG_ENDIAN)) {
+        length = flow_execute(postproc_flow, time, &ptr, length, op_state.fmt, op_state.rate, op_state.nch);
+    } else {
+        AUDDBG("postproc_flow can deal only with S16_NE streams\n"); /*FIXME*/
+    }
 
     writeoffs = 0;
     while (writeoffs < length)
--- a/src/libSAD/Makefile	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/Makefile	Thu Jan 31 12:04:13 2008 +0300
@@ -4,3 +4,5 @@
        noicegen.c
 
 include ../../buildsys.mk
+
+CPPFLAGS += ${SIMD_CFLAGS}
--- a/src/libSAD/dither.c	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/dither.c	Thu Jan 31 12:04:13 2008 +0300
@@ -18,7 +18,7 @@
  */
 
 
-#include "libSAD.h"
+#include "common.h"
 #include "dither_ops.h"
 #include "noicegen.h"
 
@@ -303,6 +303,7 @@
     case SAD_SAMPLE_S8:
     case SAD_SAMPLE_U8: priv->output_bits = 8; break;
     case SAD_SAMPLE_S16:
+    case SAD_SAMPLE_S16_LE:
     case SAD_SAMPLE_U16: priv->output_bits = 16; break;
     case SAD_SAMPLE_S24:
     case SAD_SAMPLE_U24: priv->output_bits = 24; break;
@@ -319,6 +320,7 @@
     case SAD_SAMPLE_S8:
     case SAD_SAMPLE_U8: priv->input_bits = 8; break;
     case SAD_SAMPLE_S16:
+    case SAD_SAMPLE_S16_LE:
     case SAD_SAMPLE_U16: priv->input_bits = 16; break;
     case SAD_SAMPLE_S24:
     case SAD_SAMPLE_U24: priv->input_bits = 24; break;
@@ -490,3 +492,7 @@
   priv->dither = dither;
   return SAD_ERROR_OK;
 }
+
+void SAD_dither_init_rand(uint32_t seed) {
+  noicegen_init_rand(seed);
+}
--- a/src/libSAD/dither.h	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/dither.h	Thu Jan 31 12:04:13 2008 +0300
@@ -20,7 +20,7 @@
 #ifndef DITHER_H
 #define DITHER_H
 
-#include "libSAD.h"
+#include "common.h"
 
 #define SAD_ERROR_INCORRECT_INPUT_SAMPLEFORMAT -2
 #define SAD_ERROR_INCORRECT_OUTPUT_SAMPLEFORMAT -3
@@ -37,6 +37,8 @@
 /* private data */
 typedef struct {} SAD_dither_t;
 
+void SAD_dither_init_rand(uint32_t seed);
+
 SAD_dither_t* SAD_dither_init(SAD_buffer_format *inbuf_format, SAD_buffer_format *outbuf_format, int *error);
 int SAD_dither_free(SAD_dither_t* state);
 int SAD_dither_process_buffer (SAD_dither_t *state, void *inbuf, void *outbuf, int frames);
--- a/src/libSAD/dither_ops.c	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/dither_ops.c	Thu Jan 31 12:04:13 2008 +0300
@@ -17,14 +17,28 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "libSAD.h"
+#include "common.h"
 #include "dither_ops.h"
 #include "dither.h"
 
+#define SAD_GET_LE16(a) ( (uint16_t)(((uint8_t*)(a))[0]) | (uint16_t)(((uint8_t*)(a))[1]) << 8 )
+#define SAD_GET_BE16(a) ( (uint16_t)(((uint8_t*)(a))[1]) | (uint16_t)(((uint8_t*)(a))[0]) << 8 )
+
+#define SAD_PUT_LE16(a,b) { \
+          ((uint8_t*)(a))[0] = (uint8_t)((uint32_t)(b) & 0x000000ff);        \
+          ((uint8_t*)(a))[1] = (uint8_t)(((uint32_t)(b) & 0x0000ff00) >> 8); \
+        }
+
+#define SAD_PUT_BE16(a,b) { \
+          ((uint8_t*)(a))[1] = (uint8_t)((uint32_t)(b) & 0x000000ff);        \
+          ((uint8_t*)(a))[0] = (uint8_t)(((uint32_t)(b) & 0x0000ff00) >> 8); \
+        }
+
+
 /* buffer ops: */
-/********** 
- * 8-bit  *
- **********/
+/**************************************************************************************************************** 
+ * 8-bit                                                                                                        *
+ ****************************************************************************************************************/
 
 /* signed */
 static int32_t get_s8_i_sample (void *buf, int nch, int ch, int i) {
@@ -45,19 +59,19 @@
 
 /* unsigned */
 static int32_t get_u8_i_sample (void *buf, int nch, int ch, int i) {
-  return (int32_t)(((u_int8_t*)buf)[i*nch+ch]) - 128;
+  return (int32_t)(((uint8_t*)buf)[i*nch+ch]) - 128;
 }
 
 static int32_t get_u8_s_sample (void *buf, int nch, int ch, int i) {
-  return (int32_t)(((u_int8_t**)buf)[ch][i]) - 128;
+  return (int32_t)(((uint8_t**)buf)[ch][i]) - 128;
 }
 
 static void put_u8_i_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int8_t*)buf)[i*nch+ch] = (u_int8_t)sample + 128;
+  ((uint8_t*)buf)[i*nch+ch] = (uint8_t)sample + 128;
 }
 
 static void put_u8_s_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int8_t**)buf)[ch][i] = (u_int8_t)sample + 128;
+  ((uint8_t**)buf)[ch][i] = (uint8_t)sample + 128;
 }
 
 static SAD_buffer_ops buf_s8_i_ops = {
@@ -80,9 +94,9 @@
   &put_u8_s_sample
 };
 
-/**********
- * 16-bit *
- **********/
+/**************************************************************************************************************** 
+ * 16-bit                                                                                                       *
+ ****************************************************************************************************************/
 
 /* signed */
 static int32_t get_s16_i_sample (void *buf, int nch, int ch, int i) {
@@ -94,34 +108,49 @@
 }
 
 static void put_s16_i_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-/*#ifdef DEEP_DEBUG
-  printf("f: put_s16_i_sample\n");
-#endif*/
   ((int16_t*)buf)[i*nch+ch] = (int16_t)sample;
 }
 
 static void put_s16_s_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-/*#ifdef DEEP_DEBUG
-  printf("f: put_s16_s_sample\n");
-#endif*/
   ((int16_t**)buf)[ch][i] = (int16_t)sample;
 }
 
 /* unsigned */
 static int32_t get_u16_i_sample (void *buf, int nch, int ch, int i) {
-  return ((int32_t)(((u_int16_t*)buf)[i*nch+ch])) - 32768;
+  return ((int32_t)(((uint16_t*)buf)[i*nch+ch])) - 32768;
 }
 
 static int32_t get_u16_s_sample (void *buf, int nch, int ch, int i) {
-  return ((int32_t)(((u_int16_t**)buf)[ch][i])) - 32768;
+  return ((int32_t)(((uint16_t**)buf)[ch][i])) - 32768;
 }
 
 static void put_u16_i_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int16_t*)buf)[i*nch+ch] = (u_int16_t)(sample + 32768);
+  ((uint16_t*)buf)[i*nch+ch] = (uint16_t)(sample + 32768);
 }
 
 static void put_u16_s_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int16_t**)buf)[ch][i] = (u_int16_t)(sample + 32768);
+  ((uint16_t**)buf)[ch][i] = (uint16_t)(sample + 32768);
+}
+
+/* LE: signed */
+static int32_t get_s16_le_i_sample (void *buf, int nch, int ch, int i) {
+  int16_t *tmp = (int16_t*)buf+i*nch+ch;
+  return (int16_t)SAD_GET_LE16(tmp);
+}
+
+static int32_t get_s16_le_s_sample (void *buf, int nch, int ch, int i) {
+  int16_t *tmp = ((int16_t**)buf)[ch]+i;
+  return (int16_t)SAD_GET_LE16(tmp);
+}
+
+static void put_s16_le_i_sample (void *buf, int32_t sample, int nch, int ch, int i) {
+  int16_t *tmp = (int16_t*)buf+i*nch+ch;
+  SAD_PUT_LE16(tmp, sample);
+}
+
+static void put_s16_le_s_sample (void *buf, int32_t sample, int nch, int ch, int i) {
+  int16_t *tmp = ((int16_t**)buf)[ch]+i;
+  SAD_PUT_LE16(tmp, sample);
 }
 
 static SAD_buffer_ops buf_s16_i_ops = {
@@ -134,6 +163,16 @@
   &put_s16_s_sample
 };
 
+static SAD_buffer_ops buf_s16_le_i_ops = {
+  &get_s16_le_i_sample,
+  &put_s16_le_i_sample
+};
+
+static SAD_buffer_ops buf_s16_le_s_ops = {
+  &get_s16_le_s_sample,
+  &put_s16_le_s_sample
+};
+
 static SAD_buffer_ops buf_u16_i_ops = {
   &get_u16_i_sample,
   &put_u16_i_sample
@@ -144,9 +183,9 @@
   &put_u16_s_sample
 };
 
-/**********
- * 24-bit *
- **********/
+/**************************************************************************************************************** 
+ * 24-bit                                                                                                       *
+ ****************************************************************************************************************/
 
 /*expand 24-bit signed value to 32-bit*/
 #define EXPAND_24_TO_32(x) (((int32_t)(((x) & 0x00ffffff) << 8)) >> 8)
@@ -170,19 +209,19 @@
 
 /* unsigned */
 static int32_t get_u24_i_sample (void *buf, int nch, int ch, int i) {
-  return (int32_t)EXPAND_24_TO_32(((u_int32_t*)buf)[i*nch+ch]) - 8388608;
+  return (int32_t)EXPAND_24_TO_32(((uint32_t*)buf)[i*nch+ch]) - 8388608;
 }
 
 static int32_t get_u24_s_sample (void *buf, int nch, int ch, int i) {
-  return (int32_t)EXPAND_24_TO_32(((u_int32_t**)buf)[ch][i]) - 8388608;
+  return (int32_t)EXPAND_24_TO_32(((uint32_t**)buf)[ch][i]) - 8388608;
 }
 
 static void put_u24_i_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int32_t*)buf)[i*nch+ch] = ((u_int32_t)sample + 8388608) & 0x00ffffff;
+  ((uint32_t*)buf)[i*nch+ch] = ((uint32_t)sample + 8388608) & 0x00ffffff;
 }
 
 static void put_u24_s_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int32_t**)buf)[ch][i] = ((u_int32_t)sample + 8388608) & 0x00ffffff;
+  ((uint32_t**)buf)[ch][i] = ((uint32_t)sample + 8388608) & 0x00ffffff;
 }
 
 static SAD_buffer_ops buf_s24_i_ops = {
@@ -205,9 +244,9 @@
   &put_u24_s_sample
 };
 
-/**********
- * 32-bit *
- **********/
+/**************************************************************************************************************** 
+ * 32-bit                                                                                                       *
+ ****************************************************************************************************************/
 
 /* signed */
 static int32_t get_s32_i_sample (void *buf, int nch, int ch, int i) {
@@ -236,11 +275,11 @@
 }
 
 static void put_u32_i_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int32_t*)buf)[i*nch+ch] = (u_int32_t)(sample + (int32_t)(1L<<31));
+  ((uint32_t*)buf)[i*nch+ch] = (uint32_t)(sample + (int32_t)(1L<<31));
 }
 
 static void put_u32_s_sample (void *buf, int32_t sample, int nch, int ch, int i) {
-  ((u_int32_t**)buf)[ch][i] = (u_int32_t)(sample + (int32_t)(1L<<31));
+  ((uint32_t**)buf)[ch][i] = (uint32_t)(sample + (int32_t)(1L<<31));
 }
 
 static SAD_buffer_ops buf_s32_i_ops = {
@@ -264,28 +303,28 @@
 };
 
 static SAD_buffer_ops *SAD_buffer_optable[SAD_SAMPLE_MAX][SAD_CHORDER_MAX] = {
-  {&buf_s8_i_ops, &buf_s8_s_ops},	/* SAD_SAMPLE_S8     */
-  {&buf_u8_i_ops, &buf_u8_s_ops},	/* SAD_SAMPLE_U8     */
-  {&buf_s16_i_ops, &buf_s16_s_ops},	/* SAD_SAMPLE_S16    */
-  {NULL,           NULL},		/* SAD_SAMPLE_S16_LE */
-  {NULL,           NULL},		/* SAD_SAMPLE_S16_BE */
-  {&buf_u16_i_ops, &buf_u16_s_ops},	/* SAD_SAMPLE_U16    */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_U16_LE */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_U16_BE */
-  {&buf_s24_i_ops, &buf_s24_s_ops},	/* SAD_SAMPLE_S24    */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_S24_LE */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_S24_BE */
-  {&buf_u24_i_ops, &buf_u24_s_ops},	/* SAD_SAMPLE_U24    */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_U24_LE */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_U24_BE */
-  {&buf_s32_i_ops, &buf_s32_s_ops}, 	/* SAD_SAMPLE_S32    */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_S32_LE */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_S32_BE */
-  {&buf_u32_i_ops, &buf_u32_s_ops}, 	/* SAD_SAMPLE_U32    */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_U32_LE */
-  {NULL,           NULL}, 		/* SAD_SAMPLE_U32_BE */
-  {&buf_s32_i_ops, &buf_s32_s_ops}, 	/* SAD_SAMPLE_FIXED32*/
-  {NULL,           NULL}		/* SAD_SAMPLE_FLOAT  */
+  {&buf_s8_i_ops,     &buf_s8_s_ops},	  /* SAD_SAMPLE_S8     */
+  {&buf_u8_i_ops,     &buf_u8_s_ops},	  /* SAD_SAMPLE_U8     */
+  {&buf_s16_i_ops,    &buf_s16_s_ops},	  /* SAD_SAMPLE_S16    */
+  {&buf_s16_le_i_ops, &buf_s16_le_s_ops}, /* SAD_SAMPLE_S16_LE */
+  {NULL,              NULL},		  /* SAD_SAMPLE_S16_BE */
+  {&buf_u16_i_ops,    &buf_u16_s_ops},	  /* SAD_SAMPLE_U16    */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_U16_LE */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_U16_BE */
+  {&buf_s24_i_ops,    &buf_s24_s_ops},	  /* SAD_SAMPLE_S24    */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_S24_LE */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_S24_BE */
+  {&buf_u24_i_ops,    &buf_u24_s_ops},	  /* SAD_SAMPLE_U24    */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_U24_LE */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_U24_BE */
+  {&buf_s32_i_ops,    &buf_s32_s_ops}, 	  /* SAD_SAMPLE_S32    */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_S32_LE */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_S32_BE */
+  {&buf_u32_i_ops,    &buf_u32_s_ops}, 	  /* SAD_SAMPLE_U32    */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_U32_LE */
+  {NULL,              NULL}, 		  /* SAD_SAMPLE_U32_BE */
+  {&buf_s32_i_ops,    &buf_s32_s_ops}, 	  /* SAD_SAMPLE_FIXED32*/
+  {NULL,              NULL}		  /* SAD_SAMPLE_FLOAT  */
 };
 
 SAD_buffer_ops* SAD_assign_buf_ops (SAD_buffer_format *format) {
--- a/src/libSAD/dither_ops.h	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/dither_ops.h	Thu Jan 31 12:04:13 2008 +0300
@@ -20,7 +20,7 @@
 #ifndef DITHER_OPS_H
 #define DITHER_OPS_H
 
-#include "libSAD.h"
+#include "common.h"
 #include "dither.h"
 
 SAD_buffer_ops* SAD_assign_buf_ops (SAD_buffer_format *format);
--- a/src/libSAD/libSAD.h	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/libSAD.h	Thu Jan 31 12:04:13 2008 +0300
@@ -20,134 +20,7 @@
 #ifndef LIBSAD_H
 #define LIBSAD_H
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <math.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#include "../../config.h"
-
-typedef int SAD_error;
-
-typedef enum {
-  SAD_SAMPLE_S8,
-  SAD_SAMPLE_U8,
-  SAD_SAMPLE_S16, 
-  SAD_SAMPLE_S16_LE, 
-  SAD_SAMPLE_S16_BE, 
-  SAD_SAMPLE_U16,
-  SAD_SAMPLE_U16_LE,
-  SAD_SAMPLE_U16_BE,
-  SAD_SAMPLE_S24,
-  SAD_SAMPLE_S24_LE,
-  SAD_SAMPLE_S24_BE,
-  SAD_SAMPLE_U24,
-  SAD_SAMPLE_U24_LE,
-  SAD_SAMPLE_U24_BE,
-  SAD_SAMPLE_S32,
-  SAD_SAMPLE_S32_LE,
-  SAD_SAMPLE_S32_BE,
-  SAD_SAMPLE_U32,
-  SAD_SAMPLE_U32_LE,
-  SAD_SAMPLE_U32_BE,
-  SAD_SAMPLE_FIXED32,
-  SAD_SAMPLE_FLOAT,
-  SAD_SAMPLE_MAX /*EOF*/
-} SAD_sample_format;
-
-/* sample format -> sample size */
-static inline unsigned sf2ss(SAD_sample_format fmt) {
-  switch(fmt) {
-    case SAD_SAMPLE_S8:
-    case SAD_SAMPLE_U8: return sizeof(int8_t);
-    case SAD_SAMPLE_S16:
-    case SAD_SAMPLE_S16_LE:
-    case SAD_SAMPLE_S16_BE:
-    case SAD_SAMPLE_U16:
-    case SAD_SAMPLE_U16_LE:
-    case SAD_SAMPLE_U16_BE: return sizeof(int16_t);
-    case SAD_SAMPLE_S24:
-    case SAD_SAMPLE_S24_LE:
-    case SAD_SAMPLE_S24_BE:
-    case SAD_SAMPLE_U24:
-    case SAD_SAMPLE_U24_LE:
-    case SAD_SAMPLE_U24_BE:
-    case SAD_SAMPLE_S32:
-    case SAD_SAMPLE_S32_LE:
-    case SAD_SAMPLE_S32_BE:
-    case SAD_SAMPLE_U32:
-    case SAD_SAMPLE_U32_LE:
-    case SAD_SAMPLE_U32_BE:
-    case SAD_SAMPLE_FIXED32: return sizeof(int32_t);
-    case SAD_SAMPLE_FLOAT: return sizeof(float);
-    default: return 0;
-  }
-}
-
-typedef enum {
-  SAD_CHORDER_INTERLEAVED,
-  SAD_CHORDER_SEPARATED,
-  SAD_CHORDER_MAX /*EOF*/
-} SAD_channels_order;
-
-typedef struct {
-  SAD_sample_format sample_format;
-  int fracbits; /* for fixed-point only */
-  int channels;
-  SAD_channels_order channels_order;
-  int samplerate;
-} SAD_buffer_format;
-
-static inline unsigned bytes2frames(SAD_buffer_format *fmt, unsigned bytes) {
-  return bytes / sf2ss(fmt->sample_format) / fmt->channels;
-}
-
-static inline unsigned frames2bytes(SAD_buffer_format *fmt, unsigned frames) {
-  return frames * sf2ss(fmt->sample_format) * fmt->channels;
-}
-
-static inline float db2scale(float db) {
-  return pow(10, db / 20);
-}
-
-enum {
-  SAD_RG_NONE,
-  SAD_RG_TRACK,
-  SAD_RG_ALBUM
-};
-
-#define SAD_ERROR_OK 0
-#define SAD_ERROR_FAIL -1
-
-#ifdef DEBUG
-#define DEBUG_MSG(f,x) {printf("debug: "f, x);}
-#else
-#define DEBUG_MSG(f,x) {}
-#endif
-
-typedef struct {
-  int present;
-  float track_gain; // in dB !!!
-  float track_peak;
-  float album_gain;
-  float album_peak;
-} SAD_replaygain_info;
-
-typedef struct {
-  int mode;
-  int clipping_prevention;
-  int hard_limit;
-  float preamp;
-} SAD_replaygain_mode;
-
+#include "common.h"
+#include "dither.h"
 
 #endif /* LIBSAD_H */
-
--- a/src/libSAD/noicegen.c	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/noicegen.c	Thu Jan 31 12:04:13 2008 +0300
@@ -40,3 +40,7 @@
   // Please, check it thoroughly: is this assumption correct in floatin-point arithmetic?
   return (float) triangular_dither_noise(17) / 65536.0;
 }
+
+void noicegen_init_rand(uint32_t seed) {
+  init_gen_rand(seed);
+}
--- a/src/libSAD/noicegen.h	Wed Jan 30 03:36:22 2008 +0300
+++ b/src/libSAD/noicegen.h	Thu Jan 31 12:04:13 2008 +0300
@@ -1,7 +1,10 @@
 #ifndef NOICEGEN_H
 #define NOICEGEN_H
 
+#include <inttypes.h>
+
 int triangular_dither_noise(int nbits);
 float triangular_dither_noise_f(void);
+void noicegen_init_rand(uint32_t seed);
 
 #endif /*NOICEGEN_H*/