From 7351e286c81e98b10ddebfbe3e7c31c866fb3ad5 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Fri, 8 Feb 2008 15:09:45 +1100 Subject: [PATCH] Everything converted to use kiss-fft. Got rid of smallft and fftwrap. Code much leaner now. --- libcelt/Makefile.am | 8 +- libcelt/celt.c | 15 +- libcelt/fftwrap.c | 299 ---------- libcelt/fftwrap.h | 58 -- libcelt/pitch.c | 20 +- libcelt/pitch.h | 4 +- libcelt/psy.c | 2 +- libcelt/smallft.c | 1260 ------------------------------------------- libcelt/smallft.h | 46 -- libcelt/testcelt.c | 2 + 10 files changed, 30 insertions(+), 1684 deletions(-) delete mode 100644 libcelt/fftwrap.c delete mode 100644 libcelt/fftwrap.h delete mode 100644 libcelt/smallft.c delete mode 100644 libcelt/smallft.h diff --git a/libcelt/Makefile.am b/libcelt/Makefile.am index ec2e4d20..3370dc26 100644 --- a/libcelt/Makefile.am +++ b/libcelt/Makefile.am @@ -15,19 +15,19 @@ lib_LTLIBRARIES = libcelt.la # Sources for compilation in the library libcelt_la_SOURCES = bands.c bitrdec.c bitree.c bitrenc.c celt.c cwrs.c \ - ecintrin.h entcode.c entdec.c entenc.c fftwrap.c header.c kiss_fft.c \ + ecintrin.h entcode.c entdec.c entenc.c header.c kiss_fft.c \ kiss_fftr.c laplace.c mdct.c modes.c pitch.c psy.c quant_bands.c \ - quant_pitch.c rangedec.c rangeenc.c rate.c smallft.c vq.c + quant_pitch.c rangedec.c rangeenc.c rate.c vq.c #noinst_HEADERS = libcelt_la_LDFLAGS = -version-info @CELT_LT_CURRENT@:@CELT_LT_REVISION@:@CELT_LT_AGE@ noinst_HEADERS = arch.h bands.h bitrdec.h bitree.h bitrenc.h cwrs.h \ - ecintrin.h entcode.h entdec.h entenc.h fftwrap.h kiss_fft.h \ + ecintrin.h entcode.h entdec.h entenc.h kiss_fft.h \ kiss_fftr.h _kiss_fft_guts.h laplace.h mdct.h \ mfrngcod.h modes.h os_support.h pgain_table.h pitch.h psy.h \ - quant_bands.h quant_pitch.h rate.h smallft.h vq.h + quant_bands.h quant_pitch.h rate.h vq.h noinst_PROGRAMS = testcelt testcelt_SOURCES = testcelt.c diff --git a/libcelt/celt.c b/libcelt/celt.c index bf813541..26f337a0 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -34,7 +34,7 @@ #include #include "celt.h" #include "pitch.h" -#include "fftwrap.h" +#include "kiss_fftr.h" #include "bands.h" #include "modes.h" #include "entcode.h" @@ -63,7 +63,7 @@ struct CELTEncoder { float *preemph_memD; mdct_lookup mdct_lookup; - void *fft; + kiss_fftr_cfg fft; float *window; float *in_mem; @@ -97,7 +97,7 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode) ec_enc_init(&st->enc,&st->buf); mdct_init(&st->mdct_lookup, 2*N); - st->fft = spx_fft_init(MAX_PERIOD*C); + st->fft = kiss_fftr_alloc(MAX_PERIOD*C, 0, 0); st->window = celt_alloc(2*N*sizeof(float)); st->in_mem = celt_alloc(N*C*sizeof(float)); @@ -130,7 +130,7 @@ void celt_encoder_destroy(CELTEncoder *st) ec_byte_writeclear(&st->buf); mdct_clear(&st->mdct_lookup); - spx_fft_destroy(st->fft); + free(st->fft); celt_free(st->window); celt_free(st->in_mem); @@ -138,6 +138,10 @@ void celt_encoder_destroy(CELTEncoder *st) celt_free(st->out_mem); celt_free(st->oldBandE); + + celt_free(st->preemph_memE); + celt_free(st->preemph_memD); + alloc_clear(&st->alloc); celt_free(st); @@ -453,6 +457,9 @@ void celt_decoder_destroy(CELTDecoder *st) celt_free(st->out_mem); celt_free(st->oldBandE); + + celt_free(st->preemph_memD); + alloc_clear(&st->alloc); celt_free(st); diff --git a/libcelt/fftwrap.c b/libcelt/fftwrap.c deleted file mode 100644 index ef3c1d4a..00000000 --- a/libcelt/fftwrap.c +++ /dev/null @@ -1,299 +0,0 @@ -/* Copyright (C) 2005 Jean-Marc Valin - File: fftwrap.c - - Wrapper for various FFTs - - 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 - -#define USE_SMALLFT -/*#define USE_KISS_FFT*/ - - -#include "arch.h" -#include "os_support.h" - -#ifdef FIXED_POINT -static int maximize_range(spx_word16_t *in, spx_word16_t *out, spx_word16_t bound, int len) -{ - int i, shift; - spx_word16_t max_val = 0; - for (i=0;imax_val) - max_val = in[i]; - if (-in[i]>max_val) - max_val = -in[i]; - } - shift=0; - while (max_val <= (bound>>1) && max_val != 0) - { - max_val <<= 1; - shift++; - } - for (i=0;i> shift; - } -} -#endif - -#ifdef USE_SMALLFT - -#include "smallft.h" -#include - -void *spx_fft_init(int size) -{ - struct drft_lookup *table; - table = celt_alloc(sizeof(struct drft_lookup)); - spx_drft_init((struct drft_lookup *)table, size); - return (void*)table; -} - -void spx_fft_destroy(void *table) -{ - spx_drft_clear(table); - celt_free(table); -} - -void spx_fft(void *table, float *in, float *out) -{ - if (in==out) - { - int i; - celt_warning("FFT should not be done in-place"); - float scale = 1./((struct drft_lookup *)table)->n; - for (i=0;i<((struct drft_lookup *)table)->n;i++) - out[i] = scale*in[i]; - } else { - int i; - float scale = 1./((struct drft_lookup *)table)->n; - for (i=0;i<((struct drft_lookup *)table)->n;i++) - out[i] = scale*in[i]; - } - spx_drft_forward((struct drft_lookup *)table, out); -} - -void spx_ifft(void *table, float *in, float *out) -{ - if (in==out) - { - celt_warning("FFT should not be done in-place"); - } else { - int i; - for (i=0;i<((struct drft_lookup *)table)->n;i++) - out[i] = in[i]; - } - spx_drft_backward((struct drft_lookup *)table, out); -} - -#elif defined(USE_KISS_FFT) - -#include "kiss_fftr.h" -#include "kiss_fft.h" - -struct kiss_config { - kiss_fftr_cfg forward; - kiss_fftr_cfg backward; - kiss_fft_cpx *freq_data; - int N; -}; - -void *spx_fft_init(int size) -{ - struct kiss_config *table; - table = speex_alloc(sizeof(struct kiss_config)); - table->freq_data = speex_alloc(sizeof(kiss_fft_cpx)*((size>>1)+1)); - table->forward = kiss_fftr_alloc(size,0,NULL,NULL); - table->backward = kiss_fftr_alloc(size,1,NULL,NULL); - table->N = size; - return table; -} - -void spx_fft_destroy(void *table) -{ - struct kiss_config *t = (struct kiss_config *)table; - kiss_fftr_free(t->forward); - kiss_fftr_free(t->backward); - speex_free(t->freq_data); - speex_free(table); -} - -#ifdef FIXED_POINT - -void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) -{ - int i; - int shift; - struct kiss_config *t = (struct kiss_config *)table; - shift = maximize_range(in, in, 32000, t->N); - kiss_fftr(t->forward, in, t->freq_data); - out[0] = t->freq_data[0].r; - for (i=1;iN>>1;i++) - { - out[(i<<1)-1] = t->freq_data[i].r; - out[(i<<1)] = t->freq_data[i].i; - } - out[(i<<1)-1] = t->freq_data[i].r; - renorm_range(in, in, shift, t->N); - renorm_range(out, out, shift, t->N); -} - -#else - -void spx_fft(void *table, spx_word16_t *in, spx_word16_t *out) -{ - int i; - float scale; - struct kiss_config *t = (struct kiss_config *)table; - scale = 1./t->N; - kiss_fftr(t->forward, in, t->freq_data); - out[0] = scale*t->freq_data[0].r; - for (i=1;iN>>1;i++) - { - out[(i<<1)-1] = scale*t->freq_data[i].r; - out[(i<<1)] = scale*t->freq_data[i].i; - } - out[(i<<1)-1] = scale*t->freq_data[i].r; -} -#endif - -void spx_ifft(void *table, spx_word16_t *in, spx_word16_t *out) -{ - int i; - struct kiss_config *t = (struct kiss_config *)table; - t->freq_data[0].r = in[0]; - t->freq_data[0].i = 0; - for (i=1;iN>>1;i++) - { - t->freq_data[i].r = in[(i<<1)-1]; - t->freq_data[i].i = in[(i<<1)]; - } - t->freq_data[i].r = in[(i<<1)-1]; - t->freq_data[i].i = 0; - - kiss_fftri(t->backward, t->freq_data, out); -} - - -#else - -#error No other FFT implemented - -#endif - - -int fixed_point = 1; -#ifdef FIXED_POINT -#include "smallft.h" - - -void spx_fft_float(void *table, float *in, float *out) -{ - int i; -#ifdef USE_SMALLFT - int N = ((struct drft_lookup *)table)->n; -#elif defined(USE_KISS_FFT) - int N = ((struct kiss_config *)table)->N; -#else -#endif - spx_word16_t _in[N]; - spx_word16_t _out[N]; - for (i=0;iN); - float scale = 1./((struct kiss_config *)table)->N; - for (i=0;i<((struct kiss_config *)table)->N;i++) - out[i] = scale*in[i]; - spx_drft_forward(&t, out); - spx_drft_clear(&t); - } -} - -void spx_ifft_float(void *table, float *in, float *out) -{ - int i; -#ifdef USE_SMALLFT - int N = ((struct drft_lookup *)table)->n; -#elif defined(USE_KISS_FFT) - int N = ((struct kiss_config *)table)->N; -#else -#endif - spx_word16_t _in[N]; - spx_word16_t _out[N]; - for (i=0;iN); - for (i=0;i<((struct kiss_config *)table)->N;i++) - out[i] = in[i]; - spx_drft_backward(&t, out); - spx_drft_clear(&t); - } -} - -#else - -void spx_fft_float(void *table, float *in, float *out) -{ - spx_fft(table, in, out); -} -void spx_ifft_float(void *table, float *in, float *out) -{ - spx_ifft(table, in, out); -} - -#endif diff --git a/libcelt/fftwrap.h b/libcelt/fftwrap.h deleted file mode 100644 index e1ddcdb1..00000000 --- a/libcelt/fftwrap.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2005 Jean-Marc Valin - File: fftwrap.h - - Wrapper for various FFTs - - 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 FFTWRAP_H -#define FFTWRAP_H - -#include "arch.h" - -/** Compute tables for an FFT */ -void *spx_fft_init(int size); - -/** Destroy tables for an FFT */ -void spx_fft_destroy(void *table); - -/** Forward (real to half-complex) transform */ -void spx_fft(void *table, celt_word16_t *in, celt_word16_t *out); - -/** Backward (half-complex to real) transform */ -void spx_ifft(void *table, celt_word16_t *in, celt_word16_t *out); - -/** Forward (real to half-complex) transform of float data */ -void spx_fft_float(void *table, float *in, float *out); - -/** Backward (half-complex to real) transform of float data */ -void spx_ifft_float(void *table, float *in, float *out); - -#endif diff --git a/libcelt/pitch.c b/libcelt/pitch.c index e32ead6c..4985a11f 100644 --- a/libcelt/pitch.c +++ b/libcelt/pitch.c @@ -23,11 +23,10 @@ #include #include -#include "fftwrap.h" #include "pitch.h" #include "psy.h" -void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int C, int *pitch) +void find_spectral_pitch(kiss_fftr_cfg fft, float *x, float *y, int lag, int len, int C, int *pitch) { int c; int n2 = lag/2; @@ -48,12 +47,12 @@ void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int C, yy[c*lag+i] = y[C*i+c]; } - spx_fft(fft, xx, X); - spx_fft(fft, yy, Y); + + kiss_fftr(fft, xx, X); + kiss_fftr(fft, yy, Y); compute_masking(X, curve, lag*C, 44100); - X[0] = 0; for (i=1;i -#include "smallft.h" -#include "os_support.h" - -static void drfti1(int n, float *wa, int *ifac){ - static int ntryh[4] = { 4,2,3,5 }; - static float tpi = 6.28318530717958648f; - float arg,argh,argld,fi; - int ntry=0,i,j=-1; - int k1, l1, l2, ib; - int ld, ii, ip, is, nq, nr; - int ido, ipm, nfm1; - int nl=n; - int nf=0; - - L101: - j++; - if (j < 4) - ntry=ntryh[j]; - else - ntry+=2; - - L104: - nq=nl/ntry; - nr=nl-ntry*nq; - if (nr!=0) goto L101; - - nf++; - ifac[nf+1]=ntry; - nl=nq; - if(ntry!=2)goto L107; - if(nf==1)goto L107; - - for (i=1;i>1; - ipp2=ip; - idp2=ido; - nbd=(ido-1)>>1; - t0=l1*ido; - t10=ip*ido; - - if(ido==1)goto L119; - for(ik=0;ikl1){ - for(j=1;j>1; - ipp2=ip; - ipph=(ip+1)>>1; - if(idol1)goto L139; - - is= -ido-1; - t1=0; - for(j=1;jn==1)return; - drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); -} - -void spx_drft_backward(struct drft_lookup *l,float *data){ - if (l->n==1)return; - drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); -} - -void spx_drft_init(struct drft_lookup *l,int n) -{ - l->n=n; - l->trigcache=(float*)celt_alloc(3*n*sizeof(*l->trigcache)); - l->splitcache=(int*)celt_alloc(32*sizeof(*l->splitcache)); - fdrffti(n, l->trigcache, l->splitcache); -} - -void spx_drft_clear(struct drft_lookup *l) -{ - if(l) - { - if(l->trigcache) - celt_free(l->trigcache); - if(l->splitcache) - celt_free(l->splitcache); - } -} diff --git a/libcelt/smallft.h b/libcelt/smallft.h deleted file mode 100644 index 446e2f65..00000000 --- a/libcelt/smallft.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * - * by the XIPHOPHORUS Company http://www.xiph.org/ * - * * - ******************************************************************** - - function: fft transform - last mod: $Id: smallft.h,v 1.3 2003/09/16 18:35:45 jm Exp $ - - ********************************************************************/ -/** - @file smallft.h - @brief Discrete Rotational Fourier Transform (DRFT) -*/ - -#ifndef _V_SMFT_H_ -#define _V_SMFT_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -/** Discrete Rotational Fourier Transform lookup */ -struct drft_lookup{ - int n; - float *trigcache; - int *splitcache; -}; - -extern void spx_drft_forward(struct drft_lookup *l,float *data); -extern void spx_drft_backward(struct drft_lookup *l,float *data); -extern void spx_drft_init(struct drft_lookup *l,int n); -extern void spx_drft_clear(struct drft_lookup *l); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libcelt/testcelt.c b/libcelt/testcelt.c index dcdcfbd5..fa246218 100644 --- a/libcelt/testcelt.c +++ b/libcelt/testcelt.c @@ -97,6 +97,8 @@ int main(int argc, char *argv[]) celt_int16_t in[frame_size*channels]; celt_int16_t out[frame_size*channels]; fread(in, sizeof(short), frame_size*channels, fin); + if (feof(fin)) + break; len = celt_encode(enc, in, data, bytes_per_packet); if (len <= 0) {