[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