# HG changeset patch # User Andrew O. Shadoura # Date 1218071777 -10800 # Node ID 11ef2164d90b7c04099254e753edf29273dcab71 # Parent 31d6c44ffef2a8a5f5097bee267eaa266f2767e9 re-written format conversion using libSAD; please test this on Big Endian system diff -r 31d6c44ffef2 -r 11ef2164d90b src/filewriter/Makefile --- a/src/filewriter/Makefile Wed Jul 16 23:09:38 2008 +0300 +++ b/src/filewriter/Makefile Thu Aug 07 04:16:17 2008 +0300 @@ -4,7 +4,8 @@ wav.c \ mp3.c \ vorbis.c \ - flac.c + flac.c \ + convert.c include ../../buildsys.mk include ../../extra.mk @@ -13,4 +14,4 @@ CFLAGS += ${PLUGIN_CFLAGS} CPPFLAGS += ${PLUGIN_CPPFLAGS} ${GLIB_CFLAGS} ${GTK_CFLAGS} ${MOWGLI_CFLAGS} ${FILEWRITER_CFLAGS} ${OGG_VORBIS_CFLAGS} -I../.. -LIBS += ${GTK_LIBS} ${FILEWRITER_LIBS} +LIBS += ${GTK_LIBS} ${FILEWRITER_LIBS} -lSAD diff -r 31d6c44ffef2 -r 11ef2164d90b src/filewriter/convert.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/filewriter/convert.c Thu Aug 07 04:16:17 2008 +0300 @@ -0,0 +1,64 @@ +#include "convert.h" + +static SAD_dither_t *sad_state = NULL; +gpointer convert_output = NULL; +static gsize convert_output_length = 0; +static gint nch; +static AFormat in_fmt; +static AFormat out_fmt; + +gboolean convert_init(AFormat input_fmt, AFormat output_fmt, gint channels) +{ + gint ret; + SAD_buffer_format input_sad_fmt; + SAD_buffer_format output_sad_fmt; + + + input_sad_fmt.sample_format = aud_sadfmt_from_afmt(input_fmt); + if (input_sad_fmt.sample_format < 0) return FALSE; + input_sad_fmt.fracbits = FMT_FRACBITS(input_fmt); + input_sad_fmt.channels = channels; + input_sad_fmt.channels_order = SAD_CHORDER_INTERLEAVED; + input_sad_fmt.samplerate = 0; + + output_sad_fmt.sample_format = aud_sadfmt_from_afmt(output_fmt); + if (output_sad_fmt.sample_format < 0) return FALSE; + output_sad_fmt.fracbits = FMT_FRACBITS(output_fmt); + output_sad_fmt.channels = channels; + 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 FALSE; + } + + in_fmt = input_fmt; + out_fmt = output_fmt; + nch = channels; + + SAD_dither_set_dither(sad_state, FALSE); + return TRUE; +} + +gint convert_process(gpointer ptr, gint length) +{ + gint frames, len; + frames = length / nch / FMT_SIZEOF(in_fmt); + len = frames * nch * FMT_SIZEOF(out_fmt); + + if (convert_output == NULL || convert_output_length < len) + { + convert_output_length = len; + convert_output = aud_smart_realloc(convert_output, &convert_output_length); + } + + SAD_dither_process_buffer(sad_state, ptr, convert_output, frames); + return len; +} + +void convert_free(void) +{ + if (sad_state != NULL) {SAD_dither_free(sad_state); sad_state = NULL;} +} diff -r 31d6c44ffef2 -r 11ef2164d90b src/filewriter/convert.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/filewriter/convert.h Thu Aug 07 04:16:17 2008 +0300 @@ -0,0 +1,14 @@ +#ifndef CONVERT_H +#define CONVERT_H + +#include "filewriter.h" + +gpointer convert_output; + +gboolean convert_init(AFormat input_fmt, AFormat output_fmt, gint channels); + +gint convert_process(gpointer ptr, gint length); + +void convert_free(void); + +#endif diff -r 31d6c44ffef2 -r 11ef2164d90b src/filewriter/filewriter.c --- a/src/filewriter/filewriter.c Wed Jul 16 23:09:38 2008 +0300 +++ b/src/filewriter/filewriter.c Thu Aug 07 04:16:17 2008 +0300 @@ -22,6 +22,7 @@ #include "filewriter.h" #include "plugins.h" +#include "convert.h" struct format_info input; @@ -261,77 +262,20 @@ if (!output_file) return 0; + convert_init(fmt, plugin.format_required, nch); + rv = (plugin.open)(); return rv; } -static void convert_buffer(gpointer buffer, gint length) -{ - gint i; - - if (input.format == FMT_S8) - { - guint8 *ptr1 = buffer; - gint8 *ptr2 = buffer; - - for (i = 0; i < length; i++) - *(ptr1++) = *(ptr2++) + 128; - } - if (input.format == FMT_S16_BE) - { - gint16 *ptr = buffer; - - for (i = 0; i < length >> 1; i++, ptr++) - *ptr = GINT16_FROM_BE(*ptr); - } - if (input.format == FMT_S16_LE) - { - gint16 *ptr = buffer; - - for (i = 0; i < length >> 1; i++, ptr++) - *ptr = GINT16_FROM_LE(*ptr); - } - if (input.format == FMT_U16_BE) - { - gint16 *ptr1 = buffer; - guint16 *ptr2 = buffer; - - for (i = 0; i < length >> 1; i++, ptr2++) - *(ptr1++) = GUINT16_FROM_BE(*ptr2) - 32768; - } - if (input.format == FMT_U16_LE) - { - gint16 *ptr1 = buffer; - guint16 *ptr2 = buffer; - - for (i = 0; i < length >> 1; i++, ptr2++) - *(ptr1++) = GUINT16_FROM_LE(*ptr2) - 32768; - } - if (input.format == FMT_U16_NE) - { - gint16 *ptr1 = buffer; - guint16 *ptr2 = buffer; - - for (i = 0; i < length >> 1; i++, ptr2++) - *(ptr1++) = (*ptr2) - 32768; - } -} - static void file_write(void *ptr, gint length) { - if (input.format == FMT_S8 || input.format == FMT_U16_NE || - input.format == FMT_U16_LE || input.format == FMT_U16_BE) - convert_buffer(ptr, length); -#ifdef WORDS_BIGENDIAN - if (input.format == FMT_S16_LE) - convert_buffer(ptr, length); -#else - if (input.format == FMT_S16_BE) - convert_buffer(ptr, length); -#endif + int len; - plugin.write(ptr, length); + len = convert_process(ptr, length); + + plugin.write(convert_output, len); } static gint file_write_output(void *ptr, gint length) @@ -342,6 +286,7 @@ static void file_close(void) { plugin.close(); + convert_free(); if (output_file) { diff -r 31d6c44ffef2 -r 11ef2164d90b src/filewriter/filewriter.h --- a/src/filewriter/filewriter.h Wed Jul 16 23:09:38 2008 +0300 +++ b/src/filewriter/filewriter.h Thu Aug 07 04:16:17 2008 +0300 @@ -37,6 +37,8 @@ #include #include +#include + struct format_info { AFormat format; int frequency;