Everything converted to use kiss-fft. Got rid of smallft and fftwrap.

Code much leaner now.
This commit is contained in:
Jean-Marc Valin 2008-02-08 15:09:45 +11:00
parent 6211c90def
commit 7351e286c8
10 changed files with 30 additions and 1684 deletions

View file

@ -15,19 +15,19 @@ lib_LTLIBRARIES = libcelt.la
# Sources for compilation in the library # Sources for compilation in the library
libcelt_la_SOURCES = bands.c bitrdec.c bitree.c bitrenc.c celt.c cwrs.c \ 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 \ 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 = #noinst_HEADERS =
libcelt_la_LDFLAGS = -version-info @CELT_LT_CURRENT@:@CELT_LT_REVISION@:@CELT_LT_AGE@ 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 \ 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 \ 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 \ 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 noinst_PROGRAMS = testcelt
testcelt_SOURCES = testcelt.c testcelt_SOURCES = testcelt.c

View file

@ -34,7 +34,7 @@
#include <math.h> #include <math.h>
#include "celt.h" #include "celt.h"
#include "pitch.h" #include "pitch.h"
#include "fftwrap.h" #include "kiss_fftr.h"
#include "bands.h" #include "bands.h"
#include "modes.h" #include "modes.h"
#include "entcode.h" #include "entcode.h"
@ -63,7 +63,7 @@ struct CELTEncoder {
float *preemph_memD; float *preemph_memD;
mdct_lookup mdct_lookup; mdct_lookup mdct_lookup;
void *fft; kiss_fftr_cfg fft;
float *window; float *window;
float *in_mem; float *in_mem;
@ -97,7 +97,7 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode)
ec_enc_init(&st->enc,&st->buf); ec_enc_init(&st->enc,&st->buf);
mdct_init(&st->mdct_lookup, 2*N); 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->window = celt_alloc(2*N*sizeof(float));
st->in_mem = celt_alloc(N*C*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); ec_byte_writeclear(&st->buf);
mdct_clear(&st->mdct_lookup); mdct_clear(&st->mdct_lookup);
spx_fft_destroy(st->fft); free(st->fft);
celt_free(st->window); celt_free(st->window);
celt_free(st->in_mem); celt_free(st->in_mem);
@ -138,6 +138,10 @@ void celt_encoder_destroy(CELTEncoder *st)
celt_free(st->out_mem); celt_free(st->out_mem);
celt_free(st->oldBandE); celt_free(st->oldBandE);
celt_free(st->preemph_memE);
celt_free(st->preemph_memD);
alloc_clear(&st->alloc); alloc_clear(&st->alloc);
celt_free(st); celt_free(st);
@ -453,6 +457,9 @@ void celt_decoder_destroy(CELTDecoder *st)
celt_free(st->out_mem); celt_free(st->out_mem);
celt_free(st->oldBandE); celt_free(st->oldBandE);
celt_free(st->preemph_memD);
alloc_clear(&st->alloc); alloc_clear(&st->alloc);
celt_free(st); celt_free(st);

View file

@ -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;i<len;i++)
{
if (in[i]>max_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<len;i++)
{
out[i] = in[i] << shift;
}
return shift;
}
static void renorm_range(spx_word16_t *in, spx_word16_t *out, int shift, int len)
{
int i;
for (i=0;i<len;i++)
{
out[i] = (in[i] + (1<<(shift-1))) >> shift;
}
}
#endif
#ifdef USE_SMALLFT
#include "smallft.h"
#include <math.h>
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;i<t->N>>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;i<t->N>>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;i<t->N>>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;i<N;i++)
_in[i] = (int)floor(.5+in[i]);
spx_fft(table, _in, _out);
for (i=0;i<N;i++)
out[i] = _out[i];
if (!fixed_point)
{
struct drft_lookup t;
spx_drft_init(&t, ((struct kiss_config *)table)->N);
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;i<N;i++)
_in[i] = (int)floor(.5+in[i]);
spx_ifft(table, _in, _out);
for (i=0;i<N;i++)
out[i] = _out[i];
if (!fixed_point)
{
int i;
struct drft_lookup t;
spx_drft_init(&t, ((struct kiss_config *)table)->N);
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

View file

@ -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

View file

@ -23,11 +23,10 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include "fftwrap.h"
#include "pitch.h" #include "pitch.h"
#include "psy.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 c;
int n2 = lag/2; 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]; 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); compute_masking(X, curve, lag*C, 44100);
X[0] = 0;
for (i=1;i<C*n2;i++) for (i=1;i<C*n2;i++)
{ {
float n; float n;
@ -61,13 +60,12 @@ void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int C,
//n = 1; //n = 1;
n = 1.f/pow(1+curve[i],.5)/(i+60); n = 1.f/pow(1+curve[i],.5)/(i+60);
//n = 1.f/(1+curve[i]); //n = 1.f/(1+curve[i]);
float tmp = X[2*i-1]; float tmp = X[2*i];
X[2*i-1] = (X[2*i-1]*Y[2*i-1] + X[2*i ]*Y[2*i ])*n; X[2*i] = (X[2*i ]*Y[2*i ] + X[2*i+1]*Y[2*i+1])*n;
X[2*i ] = (- X[2*i ]*Y[2*i-1] + tmp*Y[2*i ])*n; X[2*i+1] = (- X[2*i+1]*Y[2*i ] + tmp*Y[2*i+1])*n;
} }
X[C*lag-1] = 0; X[0] = X[1] = 0;
X[0] = X[C*lag-1] = 0; kiss_fftri(fft, X, xx);
spx_ifft(fft, X, xx);
float max_corr=-1e10; float max_corr=-1e10;
//int pitch; //int pitch;

View file

@ -23,6 +23,8 @@
#ifndef _PITCH_H #ifndef _PITCH_H
#define _PITCH_H #define _PITCH_H
void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int C, int *pitch); #include "kiss_fftr.h"
void find_spectral_pitch(kiss_fftr_cfg fft, float *x, float *y, int lag, int len, int C, int *pitch);
#endif #endif

View file

@ -111,7 +111,7 @@ void compute_masking(float *X, float *mask, int len, int Fs)
float psd[N]; float psd[N];
psd[0] = X[0]*X[0]; psd[0] = X[0]*X[0];
for (i=1;i<N;i++) for (i=1;i<N;i++)
psd[i] = X[i*2-1]*X[i*2-1] + X[i*2]*X[i*2]; psd[i] = X[i*2]*X[i*2] + X[i*2+1]*X[i*2+1];
/* TODO: Do tone masking */ /* TODO: Do tone masking */
/* Noise masking */ /* Noise masking */
spreading_func(psd, mask, N, Fs); spreading_func(psd, mask, N, Fs);

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -97,6 +97,8 @@ int main(int argc, char *argv[])
celt_int16_t in[frame_size*channels]; celt_int16_t in[frame_size*channels];
celt_int16_t out[frame_size*channels]; celt_int16_t out[frame_size*channels];
fread(in, sizeof(short), frame_size*channels, fin); fread(in, sizeof(short), frame_size*channels, fin);
if (feof(fin))
break;
len = celt_encode(enc, in, data, bytes_per_packet); len = celt_encode(enc, in, data, bytes_per_packet);
if (len <= 0) if (len <= 0)
{ {