[xiph-commits] r13562 - trunk/ghost/libghost
jm at svn.xiph.org
jm at svn.xiph.org
Thu Aug 16 17:05:45 PDT 2007
Author: jm
Date: 2007-08-16 17:05:45 -0700 (Thu, 16 Aug 2007)
New Revision: 13562
Added:
trunk/ghost/libghost/filterbank.c
trunk/ghost/libghost/filterbank.h
Modified:
trunk/ghost/libghost/Makefile.am
trunk/ghost/libghost/ghost.c
trunk/ghost/libghost/ghost.h
Log:
Bark filterbank code
Modified: trunk/ghost/libghost/Makefile.am
===================================================================
--- trunk/ghost/libghost/Makefile.am 2007-08-16 23:03:03 UTC (rev 13561)
+++ trunk/ghost/libghost/Makefile.am 2007-08-17 00:05:45 UTC (rev 13562)
@@ -9,15 +9,15 @@
lib_LTLIBRARIES = libghost.la
# Sources for compilation in the library
-libghost_la_SOURCES = adpcm.c fftwrap.c ghost.c lifting.c lpc.c misc.c pitch.c \
- sinusoids.c smallft.c vorbis_psy.c
+libghost_la_SOURCES = adpcm.c fftwrap.c filterbank.c ghost.c lifting.c lpc.c \
+ misc.c pitch.c sinusoids.c smallft.c vorbis_psy.c
#noinst_HEADERS =
libghost_la_LDFLAGS = -version-info @GHOST_LT_CURRENT@:@GHOST_LT_REVISION@:@GHOST_LT_AGE@
-noinst_HEADERS = adpcm.h arch.h fftwrap.h ghost.h lifting.h lpc.h misc.h \
- pitch.h smallft.h vorbis_psy.h
+noinst_HEADERS = adpcm.h arch.h fftwrap.h filterbank.h ghost.h lifting.h lpc.h \
+ misc.h pitch.h smallft.h vorbis_psy.h
noinst_PROGRAMS = testghost
testghost_SOURCES = testghost.c
Added: trunk/ghost/libghost/filterbank.c
===================================================================
--- trunk/ghost/libghost/filterbank.c (rev 0)
+++ trunk/ghost/libghost/filterbank.c 2007-08-17 00:05:45 UTC (rev 13562)
@@ -0,0 +1,226 @@
+/* Copyright (C) 2006 Jean-Marc Valin */
+/**
+ @file filterbank.c
+ @brief Converting between psd and filterbank
+ */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. 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.
+
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 "filterbank.h"
+#include "misc.h"
+#include <math.h>
+//#include "math_approx.h"
+
+#ifdef FIXED_POINT
+
+#define toBARK(n) (MULT16_16(26829,spx_atan(SHR32(MULT16_16(97,n),2))) + MULT16_16(4588,spx_atan(MULT16_32_Q15(20,MULT16_16(n,n)))) + MULT16_16(3355,n))
+
+#else
+#define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
+#endif
+
+#define toMEL(n) (2595.f*log10(1.f+(n)/700.f))
+
+FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type)
+{
+ FilterBank *bank;
+ spx_word32_t df;
+ spx_word32_t max_mel, mel_interval;
+ int i;
+ int id1;
+ int id2;
+ df = DIV32(SHL32(sampling,15),MULT16_16(2,len));
+ max_mel = toBARK(EXTRACT16(sampling/2));
+ mel_interval = PDIV32(max_mel,banks-1);
+
+ bank = (FilterBank*)speex_alloc(sizeof(FilterBank));
+ bank->nb_banks = banks;
+ bank->len = len;
+ bank->bank_left = (int*)speex_alloc(len*sizeof(int));
+ bank->bank_right = (int*)speex_alloc(len*sizeof(int));
+ bank->filter_left = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
+ bank->filter_right = (spx_word16_t*)speex_alloc(len*sizeof(spx_word16_t));
+ /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
+#ifndef FIXED_POINT
+ bank->scaling = (float*)speex_alloc(banks*sizeof(float));
+#endif
+ for (i=0;i<len;i++)
+ {
+ spx_word16_t curr_freq;
+ spx_word32_t mel;
+ spx_word16_t val;
+ curr_freq = EXTRACT16(MULT16_32_P15(i,df));
+ mel = toBARK(curr_freq);
+ if (mel > max_mel)
+ break;
+#ifdef FIXED_POINT
+ id1 = DIV32(mel,mel_interval);
+#else
+ id1 = (int)(floor(mel/mel_interval));
+#endif
+ if (id1>banks-2)
+ {
+ id1 = banks-2;
+ val = Q15_ONE;
+ } else {
+ val = DIV32_16(mel - id1*mel_interval,EXTRACT16(PSHR32(mel_interval,15)));
+ }
+ id2 = id1+1;
+ bank->bank_left[i] = id1;
+ bank->filter_left[i] = SUB16(Q15_ONE,val);
+ bank->bank_right[i] = id2;
+ bank->filter_right[i] = val;
+ }
+
+ /* Think I can safely disable normalisation for fixed-point (and probably float as well) */
+#ifndef FIXED_POINT
+ for (i=0;i<bank->nb_banks;i++)
+ bank->scaling[i] = 0;
+ for (i=0;i<bank->len;i++)
+ {
+ int id = bank->bank_left[i];
+ bank->scaling[id] += bank->filter_left[i];
+ id = bank->bank_right[i];
+ bank->scaling[id] += bank->filter_right[i];
+ }
+ for (i=0;i<bank->nb_banks;i++)
+ bank->scaling[i] = Q15_ONE/(bank->scaling[i]);
+#endif
+ return bank;
+}
+
+void filterbank_destroy(FilterBank *bank)
+{
+ speex_free(bank->bank_left);
+ speex_free(bank->bank_right);
+ speex_free(bank->filter_left);
+ speex_free(bank->filter_right);
+#ifndef FIXED_POINT
+ speex_free(bank->scaling);
+#endif
+ speex_free(bank);
+}
+
+void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel)
+{
+ int i;
+ for (i=0;i<bank->nb_banks;i++)
+ mel[i] = 0;
+
+ for (i=0;i<bank->len;i++)
+ {
+ int id;
+ id = bank->bank_left[i];
+ mel[id] += MULT16_32_P15(bank->filter_left[i],ps[i]);
+ id = bank->bank_right[i];
+ mel[id] += MULT16_32_P15(bank->filter_right[i],ps[i]);
+ }
+ /* Think I can safely disable normalisation that for fixed-point (and probably float as well) */
+#ifndef FIXED_POINT
+ for (i=0;i<bank->nb_banks;i++)
+ mel[i] = bank->scaling[i] * mel[i];
+
+#endif
+}
+
+void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *ps)
+{
+ int i;
+ for (i=0;i<bank->len;i++)
+ {
+ spx_word32_t tmp;
+ int id1, id2;
+ id1 = bank->bank_left[i];
+ id2 = bank->bank_right[i];
+ tmp = MULT16_16(mel[id1],bank->filter_left[i]);
+ tmp += MULT16_16(mel[id2],bank->filter_right[i]);
+ ps[i] = EXTRACT16(PSHR32(tmp,15));
+ }
+}
+
+
+#ifndef FIXED_POINT
+void filterbank_compute_bank(FilterBank *bank, float *ps, float *mel)
+{
+ int i;
+ for (i=0;i<bank->nb_banks;i++)
+ mel[i] = 0;
+
+ for (i=0;i<bank->len;i++)
+ {
+ int id = bank->bank_left[i];
+ mel[id] += bank->filter_left[i]*ps[i];
+ id = bank->bank_right[i];
+ mel[id] += bank->filter_right[i]*ps[i];
+ }
+ for (i=0;i<bank->nb_banks;i++)
+ mel[i] *= bank->scaling[i];
+}
+
+void filterbank_compute_psd(FilterBank *bank, float *mel, float *ps)
+{
+ int i;
+ for (i=0;i<bank->len;i++)
+ {
+ int id = bank->bank_left[i];
+ ps[i] = mel[id]*bank->filter_left[i];
+ id = bank->bank_right[i];
+ ps[i] += mel[id]*bank->filter_right[i];
+ }
+}
+
+void filterbank_psy_smooth(FilterBank *bank, float *ps, float *mask)
+{
+ /* Low freq slope: 14 dB/Bark*/
+ /* High freq slope: 9 dB/Bark*/
+ /* Noise vs tone: 5 dB difference */
+ /* FIXME: Temporary kludge */
+ float bark[100];
+ int i;
+ /* Assumes 1/3 Bark resolution */
+ float decay_low = 0.34145f;
+ float decay_high = 0.50119f;
+ filterbank_compute_bank(bank, ps, bark);
+ for (i=1;i<bank->nb_banks;i++)
+ {
+ /*float decay_high = 13-1.6*log10(bark[i-1]);
+ decay_high = pow(10,(-decay_high/30.f));*/
+ bark[i] = bark[i] + decay_high*bark[i-1];
+ }
+ for (i=bank->nb_banks-2;i>=0;i--)
+ {
+ bark[i] = bark[i] + decay_low*bark[i+1];
+ }
+ filterbank_compute_psd(bank, bark, mask);
+}
+
+#endif
Added: trunk/ghost/libghost/filterbank.h
===================================================================
--- trunk/ghost/libghost/filterbank.h (rev 0)
+++ trunk/ghost/libghost/filterbank.h 2007-08-17 00:05:45 UTC (rev 13562)
@@ -0,0 +1,66 @@
+/* Copyright (C) 2006 Jean-Marc Valin */
+/**
+ @file filterbank.h
+ @brief Converting between psd and filterbank
+ */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. 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.
+
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 FILTERBANK_H
+#define FILTERBANK_H
+
+#include "misc.h"
+
+typedef struct {
+ int *bank_left;
+ int *bank_right;
+ spx_word16_t *filter_left;
+ spx_word16_t *filter_right;
+#ifndef FIXED_POINT
+ float *scaling;
+#endif
+ int nb_banks;
+ int len;
+} FilterBank;
+
+
+FilterBank *filterbank_new(int banks, spx_word32_t sampling, int len, int type);
+
+void filterbank_destroy(FilterBank *bank);
+
+void filterbank_compute_bank32(FilterBank *bank, spx_word32_t *ps, spx_word32_t *mel);
+
+void filterbank_compute_psd16(FilterBank *bank, spx_word16_t *mel, spx_word16_t *psd);
+
+#ifndef FIXED_POINT
+void filterbank_compute_bank(FilterBank *bank, float *psd, float *mel);
+void filterbank_compute_psd(FilterBank *bank, float *mel, float *psd);
+#endif
+
+
+#endif
Modified: trunk/ghost/libghost/ghost.c
===================================================================
--- trunk/ghost/libghost/ghost.c 2007-08-16 23:03:03 UTC (rev 13561)
+++ trunk/ghost/libghost/ghost.c 2007-08-17 00:05:45 UTC (rev 13562)
@@ -29,11 +29,13 @@
#include "pitch.h"
#include "sinusoids.h"
#include "fftwrap.h"
+#include "filterbank.h"
#define PCM_BUF_SIZE 2048
#define SINUSOIDS 30
#define MASK_LPC_ORDER 10
+#define BARK_BANDS 20
void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
{
@@ -135,7 +137,9 @@
for (i=st->lpc_order;i<st->lpc_length;i++)
st->lpc_window[i] = .5-.5*cos(2*M_PI*(i-st->lpc_order)/(st->lpc_length-st->lpc_order));
#endif
+ st->bank = filterbank_new(BARK_BANDS, 48000, st->length>>1, 0);
st->big_fft = spx_fft_init(PCM_BUF_SIZE);
+ st->frame_fft = spx_fft_init(st->length);
st->lpc_fft = spx_fft_init(st->lpc_length);
for (i=0;i<PCM_BUF_SIZE;i++)
st->big_window[i] = .5-.5*cos(2*M_PI*(i+1)/PCM_BUF_SIZE);
@@ -155,7 +159,9 @@
float gain;
float curve[PCM_BUF_SIZE>>1];
float awk1[MASK_LPC_ORDER], awk2[MASK_LPC_ORDER];
+ float X[st->length];
float mask_gain;
+ float bark[BARK_BANDS];
int q[st->advance];
for (i=0;i<PCM_BUF_SIZE-st->advance;i++)
@@ -194,6 +200,19 @@
fprintf (stderr, "\n");*/
for (i=0;i<st->length;i++)
x[i] = st->analysis_window[i]*st->current_frame[i];
+
+ spx_fft_float(st->frame_fft, x, X);
+ X[0] = X[0]*X[0];
+ for (i=1;i<st->length>>1;i++)
+ X[i] = X[2*i-1]*X[2*i-1] + X[2*i]*X[2*i];
+ filterbank_compute_bank32(st->bank, X, bark);
+#if 0
+ for(i=0;i<BARK_BANDS;i++)
+ {
+ printf("%f ", bark[i]);
+ }
+ printf ("\n");
+#endif
//extract_sinusoids(x, wi, st->window, ai, bi, y, SINUSOIDS, st->length);
//nb_sinusoids=1;
//wi[0] = 0.42745;
Modified: trunk/ghost/libghost/ghost.h
===================================================================
--- trunk/ghost/libghost/ghost.h 2007-08-16 23:03:03 UTC (rev 13561)
+++ trunk/ghost/libghost/ghost.h 2007-08-17 00:05:45 UTC (rev 13562)
@@ -25,6 +25,7 @@
#include "vorbis_psy.h"
#include "adpcm.h"
+#include "filterbank.h"
typedef struct {
float *pcm_buf;
@@ -52,7 +53,9 @@
int lpc_length;
int lpc_order;
+ FilterBank *bank;
void *big_fft;
+ void *frame_fft;
void *lpc_fft;
ADPCMState *adpcm;
} GhostEncState;
More information about the commits
mailing list