[xiph-commits] r13219 - in trunk/ghost: . libghost
jm at svn.xiph.org
jm at svn.xiph.org
Wed Jul 4 08:49:13 PDT 2007
Author: jm
Date: 2007-07-04 08:49:12 -0700 (Wed, 04 Jul 2007)
New Revision: 13219
Added:
trunk/ghost/libghost/lpc.c
trunk/ghost/libghost/lpc.h
trunk/ghost/libghost/vorbis_psy.c
trunk/ghost/libghost/vorbis_psy.h
Modified:
trunk/ghost/.gitignore
trunk/ghost/libghost/Makefile.am
trunk/ghost/libghost/arch.h
trunk/ghost/libghost/ghost.c
trunk/ghost/libghost/misc.c
trunk/ghost/libghost/misc.h
Log:
Including vorbis-psy (along with a couple dependenties/updates from the Speex
tree)
Modified: trunk/ghost/.gitignore
===================================================================
--- trunk/ghost/.gitignore 2007-07-04 05:39:12 UTC (rev 13218)
+++ trunk/ghost/.gitignore 2007-07-04 15:49:12 UTC (rev 13219)
@@ -3,6 +3,7 @@
*.o
*.lo
*.la
+*~
.deps
.libs
libtool
@@ -21,4 +22,6 @@
libghost/testghost
missing
stamp-h1
+*.kdevelop.pcs
+*.kdevses
Modified: trunk/ghost/libghost/Makefile.am
===================================================================
--- trunk/ghost/libghost/Makefile.am 2007-07-04 05:39:12 UTC (rev 13218)
+++ trunk/ghost/libghost/Makefile.am 2007-07-04 15:49:12 UTC (rev 13219)
@@ -10,13 +10,15 @@
# Sources for compilation in the library
libghost_la_SOURCES = ghost.c sinusoids.c pitch.c lifting.c \
- smallft.c fftwrap.c misc.c
+ smallft.c fftwrap.c misc.c vorbis_psy.c lpc.c
#noinst_HEADERS =
libghost_la_LDFLAGS = -version-info @GHOST_LT_CURRENT@:@GHOST_LT_REVISION@:@GHOST_LT_AGE@
-noinst_HEADERS = ghost.h pitch.h lifting.h smallft.h fftwrap.h arch.h misc.h
+noinst_HEADERS = ghost.h pitch.h lifting.h smallft.h fftwrap.h \
+ arch.h misc.h vorbis_psy.h lpc.h
+
noinst_PROGRAMS = testghost
testghost_SOURCES = testghost.c
testghost_LDADD = $(top_builddir)/libghost/libghost.la
Modified: trunk/ghost/libghost/arch.h
===================================================================
--- trunk/ghost/libghost/arch.h 2007-07-04 05:39:12 UTC (rev 13218)
+++ trunk/ghost/libghost/arch.h 2007-07-04 15:49:12 UTC (rev 13219)
@@ -35,27 +35,22 @@
#ifndef ARCH_H
#define ARCH_H
-/*#include "speex/speex_types.h" */
-typedef int spx_int32_t;
-typedef unsigned int spx_uint32_t;
-typedef short spx_int16_t;
+#ifndef OUTSIDE_SPEEX
+#include "speex/speex_types.h"
+#endif
#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */
#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */
+#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */
+#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */
+#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
#ifdef FIXED_POINT
typedef spx_int16_t spx_word16_t;
typedef spx_int32_t spx_word32_t;
-#ifdef _MSC_VER
-typedef __int64 spx_word64_t;
-#elif defined NO_LONGLONG
-typedef double spx_word64_t;
-#else
-typedef long long spx_word64_t;
-#endif
typedef spx_word32_t spx_mem_t;
typedef spx_word16_t spx_coef_t;
typedef spx_word16_t spx_lsp_t;
@@ -77,6 +72,7 @@
#define VERY_SMALL 0
#define VERY_LARGE32 ((spx_word32_t)2147483647)
#define VERY_LARGE16 ((spx_word16_t)32767)
+#define Q15_ONE ((spx_word16_t)32767)
#ifdef FIXED_DEBUG
@@ -106,7 +102,6 @@
typedef float spx_sig_t;
typedef float spx_word16_t;
typedef float spx_word32_t;
-typedef float spx_word64_t;
#define Q15ONE 1.0f
#define LPC_SCALING 1.f
@@ -123,6 +118,7 @@
#define VERY_SMALL 1e-15f
#define VERY_LARGE32 1e15f
#define VERY_LARGE16 1e15f
+#define Q15_ONE ((spx_word16_t)1.f)
#define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x)
@@ -137,6 +133,7 @@
#define SHL32(a,shift) (a)
#define PSHR16(a,shift) (a)
#define PSHR32(a,shift) (a)
+#define VSHR32(a,shift) (a)
#define SATURATE16(x,a) (x)
#define SATURATE32(x,a) (x)
@@ -149,7 +146,6 @@
#define SUB16(a,b) ((a)-(b))
#define ADD32(a,b) ((a)+(b))
#define SUB32(a,b) ((a)-(b))
-#define ADD64(a,b) ((a)+(b))
#define MULT16_16_16(a,b) ((a)*(b))
#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b))
#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
@@ -158,26 +154,32 @@
#define MULT16_32_Q13(a,b) ((a)*(b))
#define MULT16_32_Q14(a,b) ((a)*(b))
#define MULT16_32_Q15(a,b) ((a)*(b))
+#define MULT16_32_P15(a,b) ((a)*(b))
#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b))
#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b))
+#define MAC16_16_P13(c,a,b) ((c)+(a)*(b))
#define MULT16_16_Q11_32(a,b) ((a)*(b))
#define MULT16_16_Q13(a,b) ((a)*(b))
#define MULT16_16_Q14(a,b) ((a)*(b))
#define MULT16_16_Q15(a,b) ((a)*(b))
#define MULT16_16_P15(a,b) ((a)*(b))
+#define MULT16_16_P13(a,b) ((a)*(b))
+#define MULT16_16_P14(a,b) ((a)*(b))
-#define DIV32_16(a,b) ((a)/(b))
-#define DIV32(a,b) ((a)/(b))
+#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
+#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b))
+#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
+#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b))
#endif
-#ifdef CONFIG_TI_C55X
+#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
/* 2 on TI C5x DSP */
#define BYTES_PER_CHAR 2
Modified: trunk/ghost/libghost/ghost.c
===================================================================
--- trunk/ghost/libghost/ghost.c 2007-07-04 05:39:12 UTC (rev 13218)
+++ trunk/ghost/libghost/ghost.c 2007-07-04 15:49:12 UTC (rev 13219)
@@ -70,51 +70,7 @@
}
}
-spx_word32_t _spx_lpc(
-spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */
-const spx_word16_t *ac, /* in: [0...p] autocorrelation values */
-int p
- )
-{
- int i, j;
- spx_word16_t r;
- spx_word16_t error = ac[0];
- if (ac[0] == 0)
- {
- for (i = 0; i < p; i++)
- lpc[i] = 0;
- return 0;
- }
-
- for (i = 0; i < p; i++) {
-
- /* Sum up this iteration's reflection coefficient */
- spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));
- for (j = 0; j < i; j++)
- rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));
-#ifdef FIXED_POINT
- r = DIV32_16(rr,ADD16(error,16));
-#else
- r = rr/(error+.0000003*ac[0]);
-#endif
- /* Update LPC coefficients and total error */
- lpc[i] = r;
- for (j = 0; j < i>>1; j++)
- {
- spx_word16_t tmp = lpc[j];
- lpc[j] = MAC16_16_Q13(lpc[j],r,lpc[i-1-j]);
- lpc[i-1-j] = MAC16_16_Q13(lpc[i-1-j],r,tmp);
- }
- if (i & 1)
- lpc[j] = MAC16_16_Q13(lpc[j],lpc[j],r);
-
- error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));
- }
- return error;
-}
-
-
GhostEncState *ghost_encoder_state_new(int sampling_rate)
{
int i;
@@ -125,7 +81,13 @@
st->lpc_length = 384;
st->lpc_order = 40;
st->pcm_buf = calloc(PCM_BUF_SIZE,sizeof(float));
+#if 0
+ /* pre-analysis window centered around the current frame */
st->current_frame = st->pcm_buf + PCM_BUF_SIZE/2 - st->length/2;
+#else
+ /* causal pre-analysis window (delayed) */
+ st->current_frame = st->pcm_buf + PCM_BUF_SIZE - st->length;
+#endif
st->new_pcm = st->pcm_buf + PCM_BUF_SIZE - st->advance;
st->noise_buf = calloc(PCM_BUF_SIZE,sizeof(float));
@@ -180,6 +142,8 @@
st->pcm_buf[i] = st->pcm_buf[i+st->advance];
for (i=0;i<st->advance;i++)
st->new_pcm[i]=pcm[i];
+ /*for (i=0;i<st->advance;i++)
+ st->new_pcm[i]=pcm[i]+10*3.4641f*.001f*(rand()%1000-500);*/
{
float wi[SINUSOIDS];
float x[st->length];
@@ -307,8 +271,9 @@
/*for (i=0;i<st->advance;i++)
pcm[i] = st->current_frame[i]-st->new_noise[i];*/
+ /* Remove the 0* if you want to include the lpc-generated noise as well */
for (i=0;i<st->advance;i++)
- pcm[i] = st->current_frame[i]-st->new_noise[i] + noise[i];
+ pcm[i] = st->current_frame[i]-st->new_noise[i] + 0*noise[i];
}
Added: trunk/ghost/libghost/lpc.c
===================================================================
--- trunk/ghost/libghost/lpc.c (rev 0)
+++ trunk/ghost/libghost/lpc.c 2007-07-04 15:49:12 UTC (rev 13219)
@@ -0,0 +1,201 @@
+/*
+ Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+ Technische Universitaet Berlin
+
+ Any use of this software is permitted provided that this notice is not
+ removed and that neither the authors nor the Technische Universitaet Berlin
+ are deemed to have made any representations as to the suitability of this
+ software for any purpose nor are held responsible for any defects of
+ this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+ As a matter of courtesy, the authors request to be informed about uses
+ this software has found, about bugs in this software, and about any
+ improvements that may be of general interest.
+
+ Berlin, 28.11.1994
+ Jutta Degener
+ Carsten Bormann
+
+
+ Code modified by Jean-Marc Valin
+
+ Speex License:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "lpc.h"
+
+#ifdef BFIN_ASM
+#include "lpc_bfin.h"
+#endif
+
+/* LPC analysis
+ *
+ * The next two functions calculate linear prediction coefficients
+ * and/or the related reflection coefficients from the first P_MAX+1
+ * values of the autocorrelation function.
+ */
+
+/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
+ */
+
+/* returns minimum mean square error */
+spx_word32_t _spx_lpc(
+spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */
+const spx_word16_t *ac, /* in: [0...p] autocorrelation values */
+int p
+)
+{
+ int i, j;
+ spx_word16_t r;
+ spx_word16_t error = ac[0];
+
+ if (ac[0] == 0)
+ {
+ for (i = 0; i < p; i++)
+ lpc[i] = 0;
+ return 0;
+ }
+
+ for (i = 0; i < p; i++) {
+
+ /* Sum up this iteration's reflection coefficient */
+ spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));
+ for (j = 0; j < i; j++)
+ rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));
+#ifdef FIXED_POINT
+ r = DIV32_16(rr+PSHR32(error,1),ADD16(error,8));
+#else
+ r = rr/(error+.003*ac[0]);
+#endif
+ /* Update LPC coefficients and total error */
+ lpc[i] = r;
+ for (j = 0; j < i>>1; j++)
+ {
+ spx_word16_t tmp = lpc[j];
+ lpc[j] = MAC16_16_P13(lpc[j],r,lpc[i-1-j]);
+ lpc[i-1-j] = MAC16_16_P13(lpc[i-1-j],r,tmp);
+ }
+ if (i & 1)
+ lpc[j] = MAC16_16_P13(lpc[j],lpc[j],r);
+
+ error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));
+ }
+ return error;
+}
+
+
+#ifdef FIXED_POINT
+
+/* Compute the autocorrelation
+ * ,--,
+ * ac(i) = > x(n) * x(n-i) for all n
+ * `--'
+ * for lags between 0 and lag-1, and x == 0 outside 0...n-1
+ */
+
+#ifndef OVERRIDE_SPEEX_AUTOCORR
+void _spx_autocorr(
+const spx_word16_t *x, /* in: [0...n-1] samples x */
+spx_word16_t *ac, /* out: [0...lag-1] ac values */
+int lag,
+int n
+)
+{
+ spx_word32_t d;
+ int i, j;
+ spx_word32_t ac0=1;
+ int shift, ac_shift;
+
+ for (j=0;j<n;j++)
+ ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));
+ ac0 = ADD32(ac0,n);
+ shift = 8;
+ while (shift && ac0<0x40000000)
+ {
+ shift--;
+ ac0 <<= 1;
+ }
+ ac_shift = 18;
+ while (ac_shift && ac0<0x40000000)
+ {
+ ac_shift--;
+ ac0 <<= 1;
+ }
+
+
+ for (i=0;i<lag;i++)
+ {
+ d=0;
+ for (j=i;j<n;j++)
+ {
+ d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));
+ }
+
+ ac[i] = SHR32(d, ac_shift);
+ }
+}
+#endif
+
+
+#else
+
+
+
+/* Compute the autocorrelation
+ * ,--,
+ * ac(i) = > x(n) * x(n-i) for all n
+ * `--'
+ * for lags between 0 and lag-1, and x == 0 outside 0...n-1
+ */
+void _spx_autocorr(
+const spx_word16_t *x, /* in: [0...n-1] samples x */
+float *ac, /* out: [0...lag-1] ac values */
+int lag,
+int n
+)
+{
+ float d;
+ int i;
+ while (lag--)
+ {
+ for (i = lag, d = 0; i < n; i++)
+ d += x[i] * x[i-lag];
+ ac[lag] = d;
+ }
+ ac[0] += 10;
+}
+
+#endif
+
+
Added: trunk/ghost/libghost/lpc.h
===================================================================
--- trunk/ghost/libghost/lpc.h (rev 0)
+++ trunk/ghost/libghost/lpc.h 2007-07-04 15:49:12 UTC (rev 13219)
@@ -0,0 +1,53 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+ @file lpc.h
+ @brief Functions for LPC (Linear Prediction Coefficients) analysis
+*/
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef LPC_H
+#define LPC_H
+
+#include "misc.h"
+
+void _spx_autocorr(
+ const spx_word16_t * x, /* in: [0...n-1] samples x */
+ spx_word16_t *ac, /* out: [0...lag-1] ac values */
+ int lag, int n);
+
+spx_word32_t /* returns minimum mean square error */
+_spx_lpc(
+ spx_coef_t * lpc, /* [0...p-1] LPC coefficients */
+ const spx_word16_t * ac, /* in: [0...p] autocorrelation values */
+ int p
+ );
+
+
+#endif
Modified: trunk/ghost/libghost/misc.c
===================================================================
--- trunk/ghost/libghost/misc.c 2007-07-04 05:39:12 UTC (rev 13218)
+++ trunk/ghost/libghost/misc.c 2007-07-04 15:49:12 UTC (rev 13219)
@@ -63,74 +63,6 @@
#endif
-spx_uint32_t be_int(spx_uint32_t i)
-{
- spx_uint32_t ret=i;
-#ifndef WORDS_BIGENDIAN
- ret = i>>24;
- ret += (i>>8)&0x0000ff00;
- ret += (i<<8)&0x00ff0000;
- ret += (i<<24);
-#endif
- return ret;
-}
-
-spx_uint32_t le_int(spx_uint32_t i)
-{
- spx_uint32_t ret=i;
-#ifdef WORDS_BIGENDIAN
- ret = i>>24;
- ret += (i>>8)&0x0000ff00;
- ret += (i<<8)&0x00ff0000;
- ret += (i<<24);
-#endif
- return ret;
-}
-
-#if BYTES_PER_CHAR == 2
-void speex_memcpy_bytes(char *dst, char *src, int nbytes)
-{
- int i;
- int nchars = nbytes/BYTES_PER_CHAR;
- for (i=0;i<nchars;i++)
- dst[i]=src[i];
- if (nbytes & 1) {
- /* copy in the last byte */
- int last_i = nchars;
- char last_dst_char = dst[last_i];
- char last_src_char = src[last_i];
- last_dst_char &= 0xff00;
- last_dst_char |= (last_src_char & 0x00ff);
- dst[last_i] = last_dst_char;
- }
-}
-void speex_memset_bytes(char *dst, char c, int nbytes)
-{
- int i;
- spx_int16_t cc = ((c << 8) | c);
- int nchars = nbytes/BYTES_PER_CHAR;
- for (i=0;i<nchars;i++)
- dst[i]=cc;
- if (nbytes & 1) {
- /* copy in the last byte */
- int last_i = nchars;
- char last_dst_char = dst[last_i];
- last_dst_char &= 0xff00;
- last_dst_char |= (c & 0x00ff);
- dst[last_i] = last_dst_char;
- }
-}
-#else
-void speex_memcpy_bytes(char *dst, char *src, int nbytes)
-{
- memcpy(dst, src, nbytes);
-}
-void speex_memset_bytes(char *dst, char src, int nbytes)
-{
- memset(dst, src, nbytes);
-}
-#endif
-
#ifndef OVERRIDE_SPEEX_ALLOC
void *speex_alloc (int size)
{
@@ -173,10 +105,10 @@
}
#endif
-#ifndef OVERRIDE_SPEEX_ERROR
-void speex_error(const char *str)
+#ifndef OVERRIDE_SPEEX_FATAL
+void _speex_fatal(const char *str, const char *file, int line)
{
- fprintf (stderr, "Fatal error: %s\n", str);
+ fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
exit(1);
}
#endif
@@ -184,24 +116,37 @@
#ifndef OVERRIDE_SPEEX_WARNING
void speex_warning(const char *str)
{
+#ifndef DISABLE_WARNINGS
fprintf (stderr, "warning: %s\n", str);
+#endif
}
#endif
#ifndef OVERRIDE_SPEEX_WARNING_INT
void speex_warning_int(const char *str, int val)
{
+#ifndef DISABLE_WARNINGS
fprintf (stderr, "warning: %s %d\n", str, val);
+#endif
}
#endif
+#ifndef OVERRIDE_SPEEX_NOTIFY
+void speex_notify(const char *str)
+{
+#ifndef DISABLE_NOTIFICATIONS
+ fprintf (stderr, "notification: %s\n", str);
+#endif
+}
+#endif
+
#ifdef FIXED_POINT
-spx_word32_t speex_rand(spx_word16_t std, spx_int32_t *seed)
+spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
{
spx_word32_t res;
*seed = 1664525 * *seed + 1013904223;
res = MULT16_16(EXTRACT16(SHR32(*seed,16)),std);
- return SUB32(res, SHR(res, 3));
+ return EXTRACT16(PSHR32(SUB32(res, SHR32(res, 3)),14));
}
#else
spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed)
@@ -216,19 +161,6 @@
}
#endif
-void speex_rand_vec(float std, spx_sig_t *data, int len)
-{
- int i;
- for (i=0;i<len;i++)
- data[i]+=SIG_SCALING*3*std*((((float)rand())/RAND_MAX)-.5);
-}
-
-
-/*float speex_rand(float std)
-{
- return 3*std*((((float)rand())/RAND_MAX)-.5);
-}*/
-
#ifndef OVERRIDE_SPEEX_PUTC
void _speex_putc(int ch, void *file)
{
Modified: trunk/ghost/libghost/misc.h
===================================================================
--- trunk/ghost/libghost/misc.h 2007-07-04 05:39:12 UTC (rev 13218)
+++ trunk/ghost/libghost/misc.h 2007-07-04 15:49:12 UTC (rev 13219)
@@ -38,11 +38,36 @@
#ifndef SPEEX_VERSION
#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */
#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */
-#define SPEEX_MICRO_VERSION 11 /**< Micro Speex version. */
-#define SPEEX_EXTRA_VERSION ".1" /**< Extra Speex version. */
-#define SPEEX_VERSION "speex-1.1.11.1" /**< Speex version string. */
+#define SPEEX_MICRO_VERSION 14 /**< Micro Speex version. */
+#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */
+#define SPEEX_VERSION "speex-1.2beta2" /**< Speex version string. */
#endif
+/* A couple test to catch stupid option combinations */
+#ifdef FIXED_POINT
+
+#ifdef _USE_SSE
+#error SSE is only for floating-point
+#endif
+#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
+#error Make up your mind. What CPU do you have?
+#endif
+#ifdef VORBIS_PSYCHO
+#error Vorbis-psy model currently not implemented in fixed-point
+#endif
+
+#else
+
+#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
+#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
+#endif
+#ifdef FIXED_POINT_DEBUG
+#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
+#endif
+
+
+#endif
+
#include "arch.h"
#ifndef RELEASE
@@ -50,11 +75,25 @@
void print_vec(float *vec, int len, char *name);
#endif
-/** Convert big endian */
-spx_uint32_t be_int(spx_uint32_t i);
/** Convert little endian */
-spx_uint32_t le_int(spx_uint32_t i);
+static inline spx_int32_t le_int(spx_int32_t i)
+{
+#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
+ spx_uint32_t ui, ret;
+ ui = i;
+ ret = ui>>24;
+ ret |= (ui>>8)&0x0000ff00;
+ ret |= (ui<<8)&0x00ff0000;
+ ret |= (ui<<24);
+ return ret;
+#else
+ return i;
+#endif
+}
+#define speex_fatal(str) _speex_fatal(str, __FILE__, __LINE__);
+#define speex_assert(cond) {if (!(cond)) {speex_fatal("assertion failed: " #cond);}}
+
/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */
void *speex_alloc (int size);
@@ -73,26 +112,20 @@
/** Speex wrapper for mem_move */
void *speex_move (void *dest, void *src, int n);
-/** Speex wrapper for memcpy */
-void speex_memcpy_bytes(char *dst, char *src, int nbytes);
+/** Abort with an error message to stderr (internal Speex error) */
+void _speex_fatal(const char *str, const char *file, int line);
-/** Speex wrapper for memset */
-void speex_memset_bytes(char *dst, char src, int nbytes);
-
-/** Print error message to stderr */
-void speex_error(const char *str);
-
-/** Print warning message to stderr */
+/** Print warning message to stderr (programming error) */
void speex_warning(const char *str);
/** Print warning message with integer argument to stderr */
void speex_warning_int(const char *str, int val);
-/** Generate a vector of random numbers */
-void speex_rand_vec(float std, spx_sig_t *data, int len);
+/** Print notification message to stderr */
+void speex_notify(const char *str);
/** Generate a random number */
-spx_word32_t speex_rand(spx_word16_t std, spx_int32_t *seed);
+spx_word16_t speex_rand(spx_word16_t std, spx_int32_t *seed);
/** Speex wrapper for putc */
void _speex_putc(int ch, void *file);
Added: trunk/ghost/libghost/vorbis_psy.c
===================================================================
--- trunk/ghost/libghost/vorbis_psy.c (rev 0)
+++ trunk/ghost/libghost/vorbis_psy.c 2007-07-04 15:49:12 UTC (rev 13219)
@@ -0,0 +1,505 @@
+/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
+ File: vorbis_psy.c
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "misc.h"
+#include "smallft.h"
+#include "lpc.h"
+#include "vorbis_psy.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+/* psychoacoustic setup ********************************************/
+
+static VorbisPsyInfo example_tuning = {
+
+ .5,.5,
+ 3,3,25,
+
+ /*63 125 250 500 1k 2k 4k 8k 16k*/
+ // vorbis mode 4 style
+ //{-32,-32,-32,-32,-28,-24,-22,-20,-20, -20, -20, -8, -6, -6, -6, -6, -6},
+ { -4, -6, -6, -6, -6, -6, -6, -6, -8, -8,-10,-10, -8, -6, -4, -4, -2},
+
+ {
+ 0, 1, 2, 3, 4, 5, 5, 5, /* 7dB */
+ 6, 6, 6, 5, 4, 4, 4, 4, /* 15dB */
+ 4, 4, 5, 5, 5, 6, 6, 6, /* 23dB */
+ 7, 7, 7, 8, 8, 8, 9, 10, /* 31dB */
+ 11,12,13,14,15,16,17, 18, /* 39dB */
+ }
+
+};
+
+
+
+/* there was no great place to put this.... */
+#include <stdio.h>
+static void _analysis_output(char *base,int i,float *v,int n,int bark,int dB){
+ int j;
+ FILE *of;
+ char buffer[80];
+
+ sprintf(buffer,"%s_%d.m",base,i);
+ of=fopen(buffer,"w");
+
+ if(!of)perror("failed to open data dump file");
+
+ for(j=0;j<n;j++){
+ if(bark){
+ float b=toBARK((4000.f*j/n)+.25);
+ fprintf(of,"%f ",b);
+ }else
+ fprintf(of,"%f ",(double)j);
+
+ if(dB){
+ float val;
+ if(v[j]==0.)
+ val=-140.;
+ else
+ val=todB(v[j]);
+ fprintf(of,"%f\n",val);
+ }else{
+ fprintf(of,"%f\n",v[j]);
+ }
+ }
+ fclose(of);
+}
+
+static void bark_noise_hybridmp(int n,const long *b,
+ const float *f,
+ float *noise,
+ const float offset,
+ const int fixed){
+
+ float *N=alloca(n*sizeof(*N));
+ float *X=alloca(n*sizeof(*N));
+ float *XX=alloca(n*sizeof(*N));
+ float *Y=alloca(n*sizeof(*N));
+ float *XY=alloca(n*sizeof(*N));
+
+ float tN, tX, tXX, tY, tXY;
+ int i;
+
+ int lo, hi;
+ float R, A, B, D;
+ float w, x, y;
+
+ tN = tX = tXX = tY = tXY = 0.f;
+
+ y = f[0] + offset;
+ if (y < 1.f) y = 1.f;
+
+ w = y * y * .5;
+
+ tN += w;
+ tX += w;
+ tY += w * y;
+
+ N[0] = tN;
+ X[0] = tX;
+ XX[0] = tXX;
+ Y[0] = tY;
+ XY[0] = tXY;
+
+ for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
+
+ y = f[i] + offset;
+ if (y < 1.f) y = 1.f;
+
+ w = y * y;
+
+ tN += w;
+ tX += w * x;
+ tXX += w * x * x;
+ tY += w * y;
+ tXY += w * x * y;
+
+ N[i] = tN;
+ X[i] = tX;
+ XX[i] = tXX;
+ Y[i] = tY;
+ XY[i] = tXY;
+ }
+
+ for (i = 0, x = 0.f;; i++, x += 1.f) {
+
+ lo = b[i] >> 16;
+ if( lo>=0 ) break;
+ hi = b[i] & 0xffff;
+
+ tN = N[hi] + N[-lo];
+ tX = X[hi] - X[-lo];
+ tXX = XX[hi] + XX[-lo];
+ tY = Y[hi] + Y[-lo];
+ tXY = XY[hi] - XY[-lo];
+
+ A = tY * tXX - tX * tXY;
+ B = tN * tXY - tX * tY;
+ D = tN * tXX - tX * tX;
+ R = (A + x * B) / D;
+ if (R < 0.f)
+ R = 0.f;
+
+ noise[i] = R - offset;
+ }
+
+ for ( ;; i++, x += 1.f) {
+
+ lo = b[i] >> 16;
+ hi = b[i] & 0xffff;
+ if(hi>=n)break;
+
+ tN = N[hi] - N[lo];
+ tX = X[hi] - X[lo];
+ tXX = XX[hi] - XX[lo];
+ tY = Y[hi] - Y[lo];
+ tXY = XY[hi] - XY[lo];
+
+ A = tY * tXX - tX * tXY;
+ B = tN * tXY - tX * tY;
+ D = tN * tXX - tX * tX;
+ R = (A + x * B) / D;
+ if (R < 0.f) R = 0.f;
+
+ noise[i] = R - offset;
+ }
+ for ( ; i < n; i++, x += 1.f) {
+
+ R = (A + x * B) / D;
+ if (R < 0.f) R = 0.f;
+
+ noise[i] = R - offset;
+ }
+
+ if (fixed <= 0) return;
+
+ for (i = 0, x = 0.f;; i++, x += 1.f) {
+ hi = i + fixed / 2;
+ lo = hi - fixed;
+ if(lo>=0)break;
+
+ tN = N[hi] + N[-lo];
+ tX = X[hi] - X[-lo];
+ tXX = XX[hi] + XX[-lo];
+ tY = Y[hi] + Y[-lo];
+ tXY = XY[hi] - XY[-lo];
+
+
+ A = tY * tXX - tX * tXY;
+ B = tN * tXY - tX * tY;
+ D = tN * tXX - tX * tX;
+ R = (A + x * B) / D;
+
+ if (R - offset < noise[i]) noise[i] = R - offset;
+ }
+ for ( ;; i++, x += 1.f) {
+
+ hi = i + fixed / 2;
+ lo = hi - fixed;
+ if(hi>=n)break;
+
+ tN = N[hi] - N[lo];
+ tX = X[hi] - X[lo];
+ tXX = XX[hi] - XX[lo];
+ tY = Y[hi] - Y[lo];
+ tXY = XY[hi] - XY[lo];
+
+ A = tY * tXX - tX * tXY;
+ B = tN * tXY - tX * tY;
+ D = tN * tXX - tX * tX;
+ R = (A + x * B) / D;
+
+ if (R - offset < noise[i]) noise[i] = R - offset;
+ }
+ for ( ; i < n; i++, x += 1.f) {
+ R = (A + x * B) / D;
+ if (R - offset < noise[i]) noise[i] = R - offset;
+ }
+}
+
+static void _vp_noisemask(VorbisPsy *p,
+ float *logfreq,
+ float *logmask){
+
+ int i,n=p->n/2;
+ float *work=alloca(n*sizeof(*work));
+
+ bark_noise_hybridmp(n,p->bark,logfreq,logmask,
+ 140.,-1);
+
+ for(i=0;i<n;i++)work[i]=logfreq[i]-logmask[i];
+
+ bark_noise_hybridmp(n,p->bark,work,logmask,0.,
+ p->vi->noisewindowfixed);
+
+ for(i=0;i<n;i++)work[i]=logfreq[i]-work[i];
+
+ {
+ static int seq=0;
+
+ float work2[n];
+ for(i=0;i<n;i++){
+ work2[i]=logmask[i]+work[i];
+ }
+
+ //_analysis_output("logfreq",seq,logfreq,n,0,0);
+ //_analysis_output("median",seq,work,n,0,0);
+ //_analysis_output("envelope",seq,work2,n,0,0);
+ seq++;
+ }
+
+ for(i=0;i<n;i++){
+ int dB=logmask[i]+.5;
+ if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
+ if(dB<0)dB=0;
+ logmask[i]= work[i]+p->vi->noisecompand[dB]+p->noiseoffset[i];
+ }
+
+}
+
+VorbisPsy *vorbis_psy_init(int rate, int n)
+{
+ long i,j,lo=-99,hi=1;
+ VorbisPsy *p = speex_alloc(sizeof(VorbisPsy));
+ memset(p,0,sizeof(*p));
+
+ p->n = n;
+ spx_drft_init(&p->lookup, n);
+ p->bark = speex_alloc(n*sizeof(*p->bark));
+ p->rate=rate;
+ p->vi = &example_tuning;
+
+ /* BH4 window */
+ p->window = speex_alloc(sizeof(*p->window)*n);
+ float a0 = .35875f;
+ float a1 = .48829f;
+ float a2 = .14128f;
+ float a3 = .01168f;
+ for(i=0;i<n;i++)
+ p->window[i] = //a0 - a1*cos(2.*M_PI/n*(i+.5)) + a2*cos(4.*M_PI/n*(i+.5)) - a3*cos(6.*M_PI/n*(i+.5));
+ sin((i+.5)/n * M_PI)*sin((i+.5)/n * M_PI);
+ /* bark scale lookups */
+ for(i=0;i<n;i++){
+ float bark=toBARK(rate/(2*n)*i);
+
+ for(;lo+p->vi->noisewindowlomin<i &&
+ toBARK(rate/(2*n)*lo)<(bark-p->vi->noisewindowlo);lo++);
+
+ for(;hi<=n && (hi<i+p->vi->noisewindowhimin ||
+ toBARK(rate/(2*n)*hi)<(bark+p->vi->noisewindowhi));hi++);
+
+ p->bark[i]=((lo-1)<<16)+(hi-1);
+
+ }
+
+ /* set up rolling noise median */
+ p->noiseoffset=speex_alloc(n*sizeof(*p->noiseoffset));
+
+ for(i=0;i<n;i++){
+ float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
+ int inthalfoc;
+ float del;
+
+ if(halfoc<0)halfoc=0;
+ if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
+ inthalfoc=(int)halfoc;
+ del=halfoc-inthalfoc;
+
+ p->noiseoffset[i]=
+ p->vi->noiseoff[inthalfoc]*(1.-del) +
+ p->vi->noiseoff[inthalfoc+1]*del;
+
+ }
+#if 0
+ _analysis_output_always("noiseoff0",ls,p->noiseoffset,n,1,0,0);
+#endif
+
+ return p;
+}
+
+void vorbis_psy_destroy(VorbisPsy *p)
+{
+ if(p){
+ spx_drft_clear(&p->lookup);
+ if(p->bark)
+ speex_free(p->bark);
+ if(p->noiseoffset)
+ speex_free(p->noiseoffset);
+ if(p->window)
+ speex_free(p->window);
+ memset(p,0,sizeof(*p));
+ speex_free(p);
+ }
+}
+
+void compute_curve(VorbisPsy *psy, float *audio, float *curve)
+{
+ int i;
+ float work[psy->n];
+
+ float scale=4.f/psy->n;
+ float scale_dB;
+
+ scale_dB=todB(scale);
+
+ /* window the PCM data; use a BH4 window, not vorbis */
+ for(i=0;i<psy->n;i++)
+ work[i]=audio[i] * psy->window[i];
+
+ {
+ static int seq=0;
+
+ //_analysis_output("win",seq,work,psy->n,0,0);
+
+ seq++;
+ }
+
+ /* FFT yields more accurate tonal estimation (not phase sensitive) */
+ spx_drft_forward(&psy->lookup,work);
+
+ /* magnitudes */
+ work[0]=scale_dB+todB(work[0]);
+ for(i=1;i<psy->n-1;i+=2){
+ float temp = work[i]*work[i] + work[i+1]*work[i+1];
+ work[(i+1)>>1] = scale_dB+.5f * todB(temp);
+ }
+
+ /* derive a noise curve */
+ _vp_noisemask(psy,work,curve);
+#define SIDEL 12
+ for (i=0;i<SIDEL;i++)
+ {
+ curve[i]=curve[SIDEL];
+ }
+#define SIDEH 12
+ for (i=0;i<SIDEH;i++)
+ {
+ curve[(psy->n>>1)-i-1]=curve[(psy->n>>1)-SIDEH];
+ }
+ for(i=0;i<((psy->n)>>1);i++)
+ curve[i] = fromdB(1.2*curve[i]+.2*i);
+ //curve[i] = fromdB(0.8*curve[i]+.35*i);
+ //curve[i] = fromdB(0.9*curve[i])*pow(1.0*i+45,1.3);
+}
+
+/* Transform a masking curve (power spectrum) into a pole-zero filter */
+void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord)
+{
+ int i;
+ float ac[psy->n];
+ float tmp;
+ int len = psy->n >> 1;
+ for (i=0;i<2*len;i++)
+ ac[i] = 0;
+ for (i=1;i<len;i++)
+ ac[2*i-1] = curve[i];
+ ac[0] = curve[0];
+ ac[2*len-1] = curve[len-1];
+
+ spx_drft_backward(&psy->lookup, ac);
+ _spx_lpc(awk1, ac, ord);
+ tmp = 1.;
+ for (i=0;i<ord;i++)
+ {
+ tmp *= .99;
+ awk1[i] *= tmp;
+ }
+#if 0
+ for (i=0;i<ord;i++)
+ awk2[i] = 0;
+#else
+ /* Use the second (awk2) filter to correct the first one */
+ for (i=0;i<2*len;i++)
+ ac[i] = 0;
+ for (i=0;i<ord;i++)
+ ac[i+1] = awk1[i];
+ ac[0] = 1;
+ spx_drft_forward(&psy->lookup, ac);
+ /* Compute (power) response of awk1 (all zero) */
+ ac[0] *= ac[0];
+ for (i=1;i<len;i++)
+ ac[i] = ac[2*i-1]*ac[2*i-1] + ac[2*i]*ac[2*i];
+ ac[len] = ac[2*len-1]*ac[2*len-1];
+ /* Compute correction required */
+ for (i=0;i<len;i++)
+ curve[i] = 1. / (1e-6f+curve[i]*ac[i]);
+
+ for (i=0;i<2*len;i++)
+ ac[i] = 0;
+ for (i=1;i<len;i++)
+ ac[2*i-1] = curve[i];
+ ac[0] = curve[0];
+ ac[2*len-1] = curve[len-1];
+
+ spx_drft_backward(&psy->lookup, ac);
+ _spx_lpc(awk2, ac, ord);
+ tmp = 1;
+ for (i=0;i<ord;i++)
+ {
+ tmp *= .99;
+ awk2[i] *= tmp;
+ }
+#endif
+}
+
+#if 0
+#include <stdio.h>
+#include <math.h>
+
+#define ORDER 10
+#define CURVE_SIZE 24
+
+int main()
+{
+ int i;
+ float curve[CURVE_SIZE];
+ float awk1[ORDER], awk2[ORDER];
+ for (i=0;i<CURVE_SIZE;i++)
+ scanf("%f ", &curve[i]);
+ for (i=0;i<CURVE_SIZE;i++)
+ curve[i] = pow(10.f, .1*curve[i]);
+ curve_to_lpc(curve, CURVE_SIZE, awk1, awk2, ORDER);
+ for (i=0;i<ORDER;i++)
+ printf("%f ", awk1[i]);
+ printf ("\n");
+ for (i=0;i<ORDER;i++)
+ printf("%f ", awk2[i]);
+ printf ("\n");
+ return 0;
+}
+#endif
+
Added: trunk/ghost/libghost/vorbis_psy.h
===================================================================
--- trunk/ghost/libghost/vorbis_psy.h (rev 0)
+++ trunk/ghost/libghost/vorbis_psy.h 2007-07-04 15:49:12 UTC (rev 13219)
@@ -0,0 +1,94 @@
+/* Copyright (C) 2005 Jean-Marc Valin, CSIRO, Christopher Montgomery
+ File: vorbis_psy.h
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the Xiph.org Foundation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef VORBIS_PSY_H
+#define VORBIS_PSY_H
+
+#include "smallft.h"
+#define P_BANDS 17 /* 62Hz to 16kHz */
+#define NOISE_COMPAND_LEVELS 40
+
+
+#define todB(x) ((x)>1e-13?log((x)*(x))*4.34294480f:-30)
+#define fromdB(x) (exp((x)*.11512925f))
+
+/* The bark scale equations are approximations, since the original
+ table was somewhat hand rolled. The below are chosen to have the
+ best possible fit to the rolled tables, thus their somewhat odd
+ appearance (these are more accurate and over a longer range than
+ the oft-quoted bark equations found in the texts I have). The
+ approximations are valid from 0 - 30kHz (nyquist) or so.
+
+ all f in Hz, z in Bark */
+
+#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
+#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
+
+/* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave
+ 0.0 */
+
+#define toOC(n) (log(n)*1.442695f-5.965784f)
+#define fromOC(o) (exp(((o)+5.965784f)*.693147f))
+
+
+typedef struct {
+
+ float noisewindowlo;
+ float noisewindowhi;
+ int noisewindowlomin;
+ int noisewindowhimin;
+ int noisewindowfixed;
+ float noiseoff[P_BANDS];
+ float noisecompand[NOISE_COMPAND_LEVELS];
+
+} VorbisPsyInfo;
+
+
+
+typedef struct {
+ int n;
+ int rate;
+ struct drft_lookup lookup;
+ VorbisPsyInfo *vi;
+
+ float *window;
+ float *noiseoffset;
+ long *bark;
+
+} VorbisPsy;
+
+
+VorbisPsy *vorbis_psy_init(int rate, int size);
+void vorbis_psy_destroy(VorbisPsy *psy);
+void compute_curve(VorbisPsy *psy, float *audio, float *curve);
+void curve_to_lpc(VorbisPsy *psy, float *curve, float *awk1, float *awk2, int ord);
+
+#endif
More information about the commits
mailing list