Mercurial > audlegacy-plugins
diff src/crossfade/convert.c @ 3059:2e241e90494a
Import work in progress xmms-crossfade rewrite.
| author | William Pitcock <nenolod@atheme.org> |
|---|---|
| date | Fri, 24 Apr 2009 05:57:35 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/crossfade/convert.c Fri Apr 24 05:57:35 2009 -0500 @@ -0,0 +1,152 @@ +/* + * XMMS Crossfade Plugin + * Copyright (C) 2000-2007 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; + } +}
