From: Josh Coalson Date: Fri, 23 Aug 2002 06:28:59 +0000 (+0000) Subject: initial import X-Git-Tag: 1.2.0~1606 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1180f23006549b8479bd32e2ae3de1e03b227ae5;p=platform%2Fupstream%2Fflac.git initial import --- diff --git a/src/plugin_common/Makefile.am b/src/plugin_common/Makefile.am new file mode 100644 index 0000000..56f759b --- /dev/null +++ b/src/plugin_common/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = foreign + +INCLUDES = -I$(top_srcdir)/include + +noinst_LIBRARIES = libplugin-common.a + +noinst_HEADERS = \ + all.h \ + canonical_tag.h \ + dither.h + +libplugin_common_a_SOURCES = \ + canonical_tag.c \ + dither.c + +EXTRA_DIST = \ + Makefile.lite \ + Makefile.vc \ + README + +debug: + $(MAKE) all CFLAGS="@DEBUG@" + +profile: + $(MAKE) all CFLAGS="@PROFILE@" diff --git a/src/plugin_common/Makefile.lite b/src/plugin_common/Makefile.lite new file mode 100644 index 0000000..253d2d9 --- /dev/null +++ b/src/plugin_common/Makefile.lite @@ -0,0 +1,14 @@ +# +# GNU makefile +# + +LIB_NAME = libplugin-common +INCLUDES = -I../../include + +OBJS = \ + canonical_tag.o \ + dither.o + +include ../../build/lib.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/src/plugin_common/Makefile.vc b/src/plugin_common/Makefile.vc new file mode 100644 index 0000000..11f3127 --- /dev/null +++ b/src/plugin_common/Makefile.vc @@ -0,0 +1,24 @@ +!include + +!IFDEF DEBUG +.c.obj: + $(cc) /D "_LIB" /GX $(cdebug) $(cflags) /I "..\..\include" -DSTRICT -YX /Od /D "_DEBUG" $< +!else +.c.obj: + $(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG $< +!endif + +C_FILES= \ + canonical_tag.c \ + dither.c + +OBJS= $(C_FILES:.c=.obj) + +all: plugin-common.lib + +plugin-common.lib: $(OBJS) + link.exe -lib /nodefaultlib -out:../../obj/lib/$*.lib $(OBJS) + +clean: + -del *.obj *.pch + -del ..\..\obj\lib\plugin-common.lib ..\..\obj\lib\plugin-common.pdb diff --git a/src/plugin_common/README b/src/plugin_common/README new file mode 100644 index 0000000..5a33526 --- /dev/null +++ b/src/plugin_common/README @@ -0,0 +1,2 @@ +This directory contains a convenience library of routines that are +common to the plugins. diff --git a/src/plugin_common/all.h b/src/plugin_common/all.h new file mode 100644 index 0000000..a8e7927 --- /dev/null +++ b/src/plugin_common/all.h @@ -0,0 +1,29 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002 Josh Coalson + * + * dithering routine derived from (other GPLed source): + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * 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. + */ + +#ifndef FLAC__PLUGIN_COMMON__ALL_H +#define FLAC__PLUGIN_COMMON__ALL_H + +#include "canonical_tag.h" +#include "dither.h" + +#endif diff --git a/src/plugin_common/canonical_tag.c b/src/plugin_common/canonical_tag.c new file mode 100644 index 0000000..fc05e9b --- /dev/null +++ b/src/plugin_common/canonical_tag.c @@ -0,0 +1,24 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002 Josh Coalson + * + * dithering routine derived from (other GPLed source): + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * 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. + */ + +#include "canonical_tag.h" +#include "FLAC/assert.h" diff --git a/src/plugin_common/canonical_tag.h b/src/plugin_common/canonical_tag.h new file mode 100644 index 0000000..2701b54 --- /dev/null +++ b/src/plugin_common/canonical_tag.h @@ -0,0 +1,26 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002 Josh Coalson + * + * dithering routine derived from (other GPLed source): + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * 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. + */ + +#ifndef FLAC__PLUGIN_COMMON__CANONICAL_TAG_H +#define FLAC__PLUGIN_COMMON__CANONICAL_TAG_H + +#endif diff --git a/src/plugin_common/dither.c b/src/plugin_common/dither.c new file mode 100644 index 0000000..5571b8a --- /dev/null +++ b/src/plugin_common/dither.c @@ -0,0 +1,168 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002 Josh Coalson + * + * dithering routine derived from (other GPLed source): + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * 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. + */ + +#include "dither.h" +#include "FLAC/assert.h" + +#ifdef max +#undef max +#endif +#define max(a,b) ((a)>(b)?(a):(b)) + + +#define FLAC__DO_DITHER + +#define MAX_SUPPORTED_CHANNELS 2 + +#if defined _MSC_VER || defined __MINGW32__ +#define FLAC__INLINE __inline +#else +#define FLAC__INLINE +#endif + +/* 32-bit pseudo-random number generator */ +static FLAC__INLINE FLAC__uint32 prng(FLAC__uint32 state) +{ + return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL; +} + +/* dither routine derived from MAD winamp plugin */ + +typedef struct { + FLAC__int32 error[3]; + FLAC__int32 random; +} dither_state; + +static FLAC__INLINE FLAC__int32 linear_dither(unsigned source_bps, unsigned target_bps, FLAC__int32 sample, dither_state *dither, const FLAC__int32 MIN, const FLAC__int32 MAX) +{ + unsigned scalebits; + FLAC__int32 output, mask, random; + + FLAC__ASSERT(source_bps < 32); + FLAC__ASSERT(target_bps <= 24); + FLAC__ASSERT(target_bps <= source_bps); + + /* noise shape */ + sample += dither->error[0] - dither->error[1] + dither->error[2]; + + dither->error[2] = dither->error[1]; + dither->error[1] = dither->error[0] / 2; + + /* bias */ + output = sample + (1L << (source_bps - target_bps - 1)); + + scalebits = source_bps - target_bps; + mask = (1L << scalebits) - 1; + + /* dither */ + random = (FLAC__int32)prng(dither->random); + output += (random & mask) - (dither->random & mask); + + dither->random = random; + + /* clip */ + if(output > MAX) { + output = MAX; + + if(sample > MAX) + sample = MAX; + } + else if(output < MIN) { + output = MIN; + + if(sample < MIN) + sample = MIN; + } + + /* quantize */ + output &= ~mask; + + /* error feedback */ + dither->error[0] = sample - output; + + /* scale */ + return output >> scalebits; +} + +unsigned FLAC__plugin_common__pack_pcm(FLAC__byte *data, FLAC__int32 *input, unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps) +{ + static dither_state dither[MAX_SUPPORTED_CHANNELS]; + FLAC__byte * const start = data; + FLAC__int32 sample; + unsigned samples = wide_samples * channels; + const unsigned bytes_per_sample = target_bps / 8; + + FLAC__ASSERT(MAX_SUPPORTED_CHANNELS == 2); + FLAC__ASSERT(channels > 0 && channels <= MAX_SUPPORTED_CHANNELS); + FLAC__ASSERT(source_bps < 32); + FLAC__ASSERT(target_bps <= 24); + FLAC__ASSERT(target_bps <= source_bps); + FLAC__ASSERT((source_bps & 7) == 0); + FLAC__ASSERT((target_bps & 7) == 0); + + if(source_bps != target_bps) { + const FLAC__int32 MIN = -(1L << source_bps); + const FLAC__int32 MAX = ~MIN; /*(1L << (source_bps-1)) - 1 */ + const unsigned dither_twiggle = channels - 1; + unsigned dither_source = 0; + + while(samples--) { + sample = linear_dither(source_bps, target_bps, *input++, &dither[dither_source], MIN, MAX); + dither_source ^= dither_twiggle; + + switch(target_bps) { + case 8: + data[0] = sample ^ 0x80; + break; + case 24: + data[2] = (FLAC__byte)(sample >> 16); + /* fall through */ + case 16: + data[1] = (FLAC__byte)(sample >> 8); + data[0] = (FLAC__byte)sample; + } + + data += bytes_per_sample; + } + } + else { + while(samples--) { + sample = *input++; + + switch(target_bps) { + case 8: + data[0] = sample ^ 0x80; + break; + case 24: + data[2] = (FLAC__byte)(sample >> 16); + /* fall through */ + case 16: + data[1] = (FLAC__byte)(sample >> 8); + data[0] = (FLAC__byte)sample; + } + + data += bytes_per_sample; + } + } + + return data - start; +} diff --git a/src/plugin_common/dither.h b/src/plugin_common/dither.h new file mode 100644 index 0000000..b57e93a --- /dev/null +++ b/src/plugin_common/dither.h @@ -0,0 +1,30 @@ +/* plugin_common - Routines common to several plugins + * Copyright (C) 2002 Josh Coalson + * + * dithering routine derived from (other GPLed source): + * mad - MPEG audio decoder + * Copyright (C) 2000-2001 Robert Leslie + * + * 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. + */ + +#ifndef FLAC__PLUGIN_COMMON__DITHER_H +#define FLAC__PLUGIN_COMMON__DITHER_H + +#include "FLAC/ordinals.h" + +unsigned FLAC__plugin_common__pack_pcm(FLAC__byte *data, FLAC__int32 *input, unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps); + +#endif