diff Plugins/Output/crossfade/convert.c @ 259:88b38e2414a1 trunk

[svn] First attempt at porting the crossfade plugin; patches from bug #363 applied, GThreadified, includes fixed. Will most probably not compile as of yet.
author chainsaw
date Sun, 04 Dec 2005 15:58:55 -0800
parents
children 5b81b0f310e5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Output/crossfade/convert.c	Sun Dec 04 15:58:55 2005 -0800
@@ -0,0 +1,132 @@
+/*
+ *  XMMS Crossfade Plugin
+ *  Copyright (C) 2000-2004  Peter Eisenlohr <peter@eisenlohr.org>
+ *
+ *  based on the original OSS Output Plugin
+ *  Copyright (C) 1998-2000  Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ *  USA.
+ */
+
+/*
+ *  Convert to standard (16bit-le stereo)
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+#include "convert.h"
+
+void
+convert_init(convert_context_t *cc)
+{
+  memset(cc, 0, sizeof(*cc));
+}
+
+gint
+convert_flow(convert_context_t *cc,
+	     gpointer          *buffer,
+	     gint               length,
+	     format_t          *format)
+{
+  gpointer data;
+  gint     size;
+  gint     sample_size, sample_count;
+  gint     element_count;
+  gint16  *out, s;
+
+  if(!cc) return 0;
+  if(length <= 0) return 0;
+
+  /* calculate sample count */
+  sample_size  = format->is_8bit ? 1 : 2;
+  sample_count = length / sample_size;
+  if(sample_count == 0) return 0;
+
+  /* calculate buffer size */
+  size = sample_count * 2;
+  if(format->nch == 1) size *= 2;
+
+  /* resize buffer if necessary */
+  if(!cc->data || (size > cc->size)) {
+    if(!(data = g_realloc(cc->data, size))) {
+      DEBUG(("[crossfade] convert: g_realloc(%d) failed!\n", size));
+      return 0;
+    }
+    cc->data = data;
+    cc->size = size;
+  }
+
+  /* calculate number of stereo samples */
+  element_count = sample_count;
+  if(format->nch == 2) element_count /= 2;
+  
+#define CONVERT(x)						\
+  if(format->nch == 1) {					\
+    while(sample_count--) { s = x; *out++ = s; *out++ = s; }	\
+  }								\
+  else {							\
+    while(sample_count--) *out++ = x;				\
+  }
+
+  out = cc->data;
+  if(format->is_8bit) {
+    if(format->is_unsigned) {
+      guint8 *in = *buffer;
+      CONVERT((gint16)(*in++ ^ 128) << 8);
+    }
+    else {
+      gint8 *in = *buffer;
+      CONVERT((gint16)*in++ << 8);
+    }
+  }
+  else {
+    if(format->is_unsigned) {
+      guint16 *in = *buffer;
+      if(format->is_swapped) {
+	CONVERT((gint16)(((*in & 0x00ff) << 8) | (*in >> 8)) ^ 32768); in++;
+      } else {
+	CONVERT((gint16)*in++ ^ 32768);
+      }
+    }
+    else {
+      gint16 *in = *buffer;
+      if(format->is_swapped) {
+	CONVERT(((*in & 0x00ff) << 8) | (*in >> 8)); in++;
+      } else {
+	if(format->nch == 1) {
+	  CONVERT(*in++);
+	}
+	else memcpy(out, in, size);
+      }
+    }
+  }
+  *buffer = cc->data;
+
+  return size;
+}
+
+void
+convert_free(convert_context_t *cc)
+{
+  if(cc->data) {
+    g_free(cc->data);
+    cc->data = NULL;
+  }
+}
+