diff --git a/libcelt/celt.c b/libcelt/celt.c index 62b60854..0c03103b 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -317,11 +317,9 @@ static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * rest const int C = CHANNELS(_C); if (C==1 && !shortBlocks) { - const mdct_lookup *lookup = &mode->mdct[LM]; const int overlap = OVERLAP(mode); - clt_mdct_forward(lookup, in, out, mode->window, overlap); + clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM); } else { - const mdct_lookup *lookup = &mode->mdct[LM]; const int overlap = OVERLAP(mode); int N = mode->shortMdctSize<mdct[0]; + /*lookup = &mode->mdct[0];*/ N = mode->shortMdctSize; B = shortBlocks; } @@ -344,7 +342,7 @@ static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * rest int j; for (j=0;jwindow, overlap); + clt_mdct_forward(&mode->mdct, x, tmp, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM); /* Interleaving the sub-frames */ for (j=0;jmdct[LM]; - clt_mdct_backward(lookup, X, out_mem+C*(MAX_PERIOD-N-N4), mode->window, overlap); + clt_mdct_backward(&mode->mdct, X, out_mem+C*(MAX_PERIOD-N-N4), mode->window, overlap, mode->maxLM-LM); } else { VARDECL(celt_word32, x); VARDECL(celt_word32, tmp); @@ -376,7 +373,6 @@ static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X int N2 = N; int B = 1; int n4offset=0; - const mdct_lookup *lookup = &mode->mdct[LM]; SAVE_STACK; ALLOC(x, 2*N, celt_word32); @@ -384,7 +380,7 @@ static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X if (shortBlocks) { - lookup = &mode->mdct[0]; + /*lookup = &mode->mdct[0];*/ N2 = mode->shortMdctSize; B = shortBlocks; n4offset = N4; @@ -397,7 +393,7 @@ static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X /* De-interleaving the sub-frames */ for (j=0;jwindow, overlap); + clt_mdct_backward(&mode->mdct, tmp, x+n4offset+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM); } if (transient_shift > 0) diff --git a/libcelt/mdct.c b/libcelt/mdct.c index 0bfe5c59..653aff0b 100644 --- a/libcelt/mdct.c +++ b/libcelt/mdct.c @@ -58,18 +58,23 @@ #define M_PI 3.141592653 #endif -void clt_mdct_init(mdct_lookup *l,int N) +void clt_mdct_init(mdct_lookup *l,int N, int maxshift) { int i; int N2, N4; l->n = N; N2 = N>>1; N4 = N>>2; - l->kfft = cpx32_fft_alloc(N>>2); + l->kfft = celt_alloc(sizeof(kiss_fft_cfg)*(maxshift+1)); + l->maxshift = maxshift; + for (i=0;i<=maxshift;i++) + { + l->kfft[i] = cpx32_fft_alloc(N>>2>>i); #ifndef ENABLE_TI_DSPLIB55 - if (l->kfft==NULL) - return; + if (l->kfft[i]==NULL) + return; #endif + } l->trig = (kiss_twiddle_scalar*)celt_alloc((N4+1)*sizeof(kiss_twiddle_scalar)); if (l->trig==NULL) return; @@ -90,11 +95,14 @@ void clt_mdct_init(mdct_lookup *l,int N) void clt_mdct_clear(mdct_lookup *l) { - cpx32_fft_free(l->kfft); + int i; + for (i=0;i<=l->maxshift;i++) + cpx32_fft_free(l->kfft[i]); + celt_free(l->kfft); celt_free(l->trig); } -void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out, const celt_word16 *window, int overlap) +void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out, const celt_word16 *window, int overlap, int shift) { int i; int N, N2, N4; @@ -102,6 +110,7 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar VARDECL(kiss_fft_scalar, f); SAVE_STACK; N = l->n; + N >>= shift; N2 = N>>1; N4 = N>>2; ALLOC(f, N2, kiss_fft_scalar); @@ -161,8 +170,8 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar kiss_fft_scalar re, im, yr, yi; re = yp[0]; im = yp[1]; - yr = -S_MUL(re,t[i]) - S_MUL(im,t[N4-i]); - yi = -S_MUL(im,t[i]) + S_MUL(re,t[N4-i]); + yr = -S_MUL(re,t[i<kfft, out, f, N4); + cpx32_fft(l->kfft[shift], out, f, N4); /* Post-rotate */ { @@ -183,8 +192,8 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar for(i=0;in; + N >>= shift; N2 = N>>1; N4 = N>>2; ALLOC(f, N2, kiss_fft_scalar); @@ -227,8 +237,8 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala for(i=0;ikfft, f2, f, N4); + cpx32_ifft(l->kfft[shift], f2, f, N4); /* Post-rotate */ { @@ -251,8 +261,8 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala re = fp[0]; im = fp[1]; /* We'd scale up by 2 here, but instead it's done when mixing the windows */ - yr = S_MUL(re,t[i]) - S_MUL(im,t[N4-i]); - yi = S_MUL(im,t[i]) + S_MUL(re,t[N4-i]); + yr = S_MUL(re,t[i<= 640 && (frame_size%16)==0) { - mode->nbShortMdcts = 8; + LM = 3; } else if (frame_size >= 320 && (frame_size%8)==0) { - mode->nbShortMdcts = 4; + LM = 2; } else if (frame_size >= 160 && (frame_size%4)==0) { - mode->nbShortMdcts = 2; + LM = 1; } else { - mode->nbShortMdcts = 1; + LM = 0; } + mode->maxLM = LM; + mode->nbShortMdcts = 1<shortMdctSize = frame_size/mode->nbShortMdcts; res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize); @@ -402,16 +405,14 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) mode->logN = logN; #endif /* !STATIC_MODES */ - for (i=0;(1<nbShortMdcts;i++) - { - clt_mdct_init(&mode->mdct[i], 2*mode->shortMdctSize<mdct[i].trig==NULL) + clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, LM); + if ((mode->mdct.trig==NULL) #ifndef ENABLE_TI_DSPLIB55 - || (mode->mdct[i].kfft==NULL) + || (mode->mdct.kfft==NULL) #endif - ) - goto failure; - } + ) + goto failure; + mode->prob = quant_prob_alloc(mode); if (mode->prob==NULL) goto failure; @@ -487,8 +488,7 @@ void celt_mode_destroy(CELTMode *mode) celt_free((celt_int16*)mode->logN); #endif - for (i=0;(1<nbShortMdcts;i++) - clt_mdct_clear(&mode->mdct[i]); + clt_mdct_clear(&mode->mdct); quant_prob_free(mode->prob); mode->marker_end = MODEFREED; diff --git a/libcelt/modes.h b/libcelt/modes.h index e35213a5..9db98609 100644 --- a/libcelt/modes.h +++ b/libcelt/modes.h @@ -98,10 +98,11 @@ struct CELTMode { const celt_int16 * const *(_bits[MAX_CONFIG_SIZES]); /**< Cache for pulses->bits mapping in each band */ /* Stuff that could go in the {en,de}coder, but we save space this way */ - mdct_lookup mdct[MAX_CONFIG_SIZES]; + mdct_lookup mdct; const celt_word16 *window; + int maxLM; int nbShortMdcts; int shortMdctSize; diff --git a/libcelt/os_support.h b/libcelt/os_support.h index 8a47df9a..a02c131f 100644 --- a/libcelt/os_support.h +++ b/libcelt/os_support.h @@ -45,7 +45,7 @@ /** CELT wrapper for calloc(). To do your own dynamic allocation, all you need to do is replace this function, celt_realloc and celt_free NOTE: celt_alloc needs to CLEAR THE MEMORY */ #ifndef OVERRIDE_CELT_ALLOC -static inline void *celt_alloc (int size) +static void *celt_alloc (int size) { /* WARNING: this is not equivalent to malloc(). If you want to use malloc() or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise diff --git a/tests/mdct-test.c b/tests/mdct-test.c index df5e7cfa..ed8d98b7 100644 --- a/tests/mdct-test.c +++ b/tests/mdct-test.c @@ -89,7 +89,7 @@ void test1d(int nfft,int isinverse) celt_word16 * window= (celt_word16*)malloc(sizeof(celt_word16)*nfft/2); int k; - clt_mdct_init(&cfg, nfft); + clt_mdct_init(&cfg, nfft, 0); for (k=0;k