Reworked the static modes. Now, if all static modes have the same frame size,

overlap or number of channels, we can pass the hint to the compiler.
This commit is contained in:
Jean-Marc Valin 2008-04-11 04:07:52 +10:00
parent c1a4c2ec44
commit b18ec0b08d
6 changed files with 106 additions and 35 deletions

View file

@ -14,7 +14,7 @@ noinst_SCRIPTS = match-test.sh
lib_LTLIBRARIES = libcelt.la
# Sources for compilation in the library
libcelt_la_SOURCES = bands.c celt.c cwrs.c dump_modes.c ecintrin.h entcode.c \
libcelt_la_SOURCES = bands.c celt.c cwrs.c ecintrin.h entcode.c \
entdec.c entenc.c header.c kfft_single.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 \
vq.c
@ -29,8 +29,11 @@ noinst_HEADERS = _kiss_fft_guts.h arch.h bands.h fixed_c5x.h \
mathops.h modes.h os_support.h pgain_table.h pitch.h psy.h \
quant_bands.h quant_pitch.h rate.h stack_alloc.h vq.h
noinst_PROGRAMS = testcelt
noinst_PROGRAMS = testcelt dump_modes
testcelt_SOURCES = testcelt.c
testcelt_LDADD = libcelt.la
INCLUDES =
libcelt_la_LIBADD =
#libcelt_la_LIBADD =
dump_modes_SOURCES = dump_modes.c
dump_modes_LDADD = libcelt.la

View file

@ -153,13 +153,15 @@ static inline celt_int16_t SIG2INT16(celt_sig_t x)
}
/** Apply window and compute the MDCT for all sub-frames and all channels in a frame */
static void compute_mdcts(const CELTMode *mode, const celt_word16_t * restrict window, celt_sig_t * restrict in, celt_sig_t * restrict out, int N, int overlap)
static void compute_mdcts(const CELTMode *mode, const celt_word16_t * restrict window, celt_sig_t * restrict in, celt_sig_t * restrict out)
{
int c, N4;
VARDECL(celt_word32_t, x);
VARDECL(celt_word32_t, tmp);
const int C = CHANNELS(mode);
const mdct_lookup *lookup = MDCT(mode);
const int N = FRAMESIZE(mode);
const int overlap = OVERLAP(mode);
SAVE_STACK;
N4 = (N-overlap)>>1;
ALLOC(x, 2*N, celt_word32_t);
@ -193,13 +195,15 @@ static void compute_mdcts(const CELTMode *mode, const celt_word16_t * restrict w
}
/** Compute the IMDCT and apply window for all sub-frames and all channels in a frame */
static void compute_inv_mdcts(const CELTMode *mode, const celt_word16_t * restrict window, celt_sig_t *X, celt_sig_t * restrict out_mem, celt_sig_t * restrict mdct_overlap, int N, int overlap)
static void compute_inv_mdcts(const CELTMode *mode, const celt_word16_t * restrict window, celt_sig_t *X, celt_sig_t * restrict out_mem, celt_sig_t * restrict mdct_overlap)
{
int c, N4;
VARDECL(celt_word32_t, x);
VARDECL(celt_word32_t, tmp);
const int C = CHANNELS(mode);
const mdct_lookup *lookup = MDCT(mode);
const int N = FRAMESIZE(mode);
const int overlap = OVERLAP(mode);
SAVE_STACK;
ALLOC(x, 2*N, celt_word32_t);
ALLOC(tmp, N, celt_word32_t);
@ -266,7 +270,7 @@ int EXPORT celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compre
/*for (i=0;i<(B+1)*C*N;i++) printf ("%f(%d) ", in[i], i); printf ("\n");*/
/* Compute MDCTs */
compute_mdcts(st->mode, st->mode->window, in, freq, N, st->overlap);
compute_mdcts(st->mode, st->mode->window, in, freq);
#if 0 /* Mask disabled until it can be made to do something useful */
compute_mdct_masking(X, mask, B*C*N, st->Fs);
@ -299,8 +303,7 @@ int EXPORT celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compre
/*for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");*/
/* Compute MDCTs of the pitch part */
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq, N, st->overlap);
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
quant_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, &st->enc);
@ -363,7 +366,7 @@ int EXPORT celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compre
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD-N));
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap, N, st->overlap);
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
/* De-emphasis and put everything back at the right place in the synthesis history */
for (c=0;c<C;c++)
{
@ -508,11 +511,11 @@ static void celt_decode_lost(CELTDecoder *st, short *pcm)
pitch_index = st->last_pitch_index;
/* Use the pitch MDCT as the "guessed" signal */
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq, N, st->overlap);
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD-N));
/* Compute inverse MDCTs */
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap, N, st->overlap);
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
for (c=0;c<C;c++)
{
@ -587,7 +590,7 @@ int EXPORT celt_decode(CELTDecoder *st, unsigned char *data, int len, celt_int16
}
/* Pitch MDCT */
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq, N, st->overlap);
compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq);
{
VARDECL(celt_ener_t, bandEp);
@ -616,7 +619,7 @@ int EXPORT celt_decode(CELTDecoder *st, unsigned char *data, int len, celt_int16
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD-N));
/* Compute inverse MDCTs */
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap, N, st->overlap);
compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem, st->mdct_overlap);
for (c=0;c<C;c++)
{

View file

@ -78,7 +78,7 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
fprintf (file, "static const celt_int16_t pBands%d_%d[%d] = {\n", mode->Fs, mode->mdctSize, mode->nbPBands+2);
for (j=0;j<mode->nbPBands+2;j++)
fprintf (file, "%d, ", mode->pBands[j]);
printf ("};\n");
fprintf (file, "};\n");
fprintf(file, "#endif\n");
fprintf(file, "\n");
@ -88,7 +88,7 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
fprintf (file, "static const celt_word16_t window%d[%d] = {\n", mode->overlap, mode->overlap);
for (j=0;j<mode->overlap;j++)
fprintf (file, WORD16 ", ", mode->window[j]);
printf ("};\n");
fprintf (file, "};\n");
fprintf(file, "#endif\n");
fprintf(file, "\n");
@ -97,7 +97,7 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
fprintf (file, "static const celt_word16_t psy_decayR_%d[%d] = {\n", mode->Fs, MAX_PERIOD/2);
for (j=0;j<MAX_PERIOD/2;j++)
fprintf (file, WORD16 ", ", mode->psy.decayR[j]);
printf ("};\n");
fprintf (file, "};\n");
fprintf(file, "#endif\n");
fprintf(file, "\n");
@ -146,7 +146,6 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
fprintf(file, "%d,\t/* mdctSize */\n", mode->mdctSize);
fprintf(file, "%d,\t/* nbMdctBlocks */\n", mode->nbMdctBlocks);
fprintf(file, "%d,\t/* nbChannels */\n", mode->nbChannels);
fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
fprintf(file, "%d,\t/* nbPBands */\n", mode->nbPBands);
@ -175,14 +174,71 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
fprintf(file, "};\n");
}
#if 0
int main()
void dump_header(FILE *file, CELTMode **modes, int nb_modes)
{
CELTMode *m[3];
m[0] = celt_mode_create(44100, 1, 256, 128, NULL);
m[1] = celt_mode_create(48000, 1, 256, 128, NULL);
m[2] = celt_mode_create(51200, 1, 256, 128, NULL);
dump_modes(stdout, m, 1);
int i;
int channels = 0;
int frame_size = 0;
int overlap = 0;
fprintf (file, "/* This header file is generated automatically*/\n");
for (i=0;i<nb_modes;i++)
{
CELTMode *mode = modes[i];
if (channels==0)
channels = mode->nbChannels;
else if (channels != mode->nbChannels)
channels = -1;
if (frame_size==0)
frame_size = mode->mdctSize;
else if (frame_size != mode->mdctSize)
frame_size = -1;
if (overlap==0)
overlap = mode->overlap;
else if (overlap != mode->overlap)
overlap = -1;
}
if (channels>0)
{
fprintf (file, "#define CHANNELS(mode) %d\n", channels);
if (channels==1)
fprintf (file, "#define DISABLE_STEREO\n");
}
if (frame_size>0)
{
fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
}
if (overlap>0)
{
fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
}
}
int main(int argc, char **argv)
{
int i, nb;
FILE *file;
if (argc%4 != 1)
{
fprintf (stderr, "must have a multiple of 4 arguments\n");
return 1;
}
nb = (argc-1)/4;
CELTMode **m;
m = malloc(nb*sizeof(CELTMode*));
for (i=0;i<nb;i++)
{
int Fs, ch, frame, overlap;
Fs = atoi(argv[4*i+1]);
ch = atoi(argv[4*i+2]);
frame = atoi(argv[4*i+3]);
overlap = atoi(argv[4*i+4]);
m[i] = celt_mode_create(Fs, ch, frame, overlap, NULL);
}
file = fopen("static_modes.c", "w");
dump_modes(file, m, nb);
fclose(file);
file = fopen("static_modes.h", "w");
dump_header(file, m, nb);
fclose(file);
return 0;
}
#endif

View file

@ -39,7 +39,7 @@
#include "os_support.h"
#ifdef STATIC_MODES
#include "static_modes.h"
#include "static_modes.c"
#endif
#define MODEVALID 0xa110ca7e
@ -287,7 +287,6 @@ CELTMode EXPORT *celt_mode_create(celt_int32_t Fs, int channels, int frame_size,
mode->Fs = Fs;
mode->overlap = lookahead;
mode->mdctSize = frame_size;
mode->nbMdctBlocks = 1;
mode->nbChannels = channels;
mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
compute_pbands(mode, res);

View file

@ -38,18 +38,29 @@
#include "mdct.h"
#include "psy.h"
#ifdef STATIC_MODES
#include "static_modes.h"
#endif
#define MAX_PERIOD 1024
#ifdef DISABLE_STEREO
#define CHANNELS(mode) (1)
#else
#define CHANNELS(mode) ((mode)->nbChannels)
#ifndef CHANNELS
# ifdef DISABLE_STEREO
# define CHANNELS(mode) (1)
# else
# define CHANNELS(mode) ((mode)->nbChannels)
# endif
#endif
#define MDCT(mode) (&(mode)->mdct)
#define OVERLAP(mode) ((mode)->overlap)
#define FRAMESIZE(mode) ((mode)->mdctSize)
#ifndef OVERLAP
#define OVERLAP(mode) ((mode)->overlap)
#endif
#ifndef FRAMESIZE
#define FRAMESIZE(mode) ((mode)->mdctSize)
#endif
/** Mode definition (opaque)
@brief Mode definition
@ -59,7 +70,6 @@ struct CELTMode {
celt_int32_t Fs;
int overlap;
int mdctSize;
int nbMdctBlocks;
int nbChannels;
int nbEBands;

View file

@ -103,7 +103,7 @@ void compute_alloc_cache(CELTMode *m)
bits = celt_alloc(m->nbEBands*sizeof(celt_int16_t*));
BC = m->nbMdctBlocks*m->nbChannels;
BC = m->nbChannels;
prevN = -1;
for (i=0;i<m->nbEBands;i++)
{