X-Git-Url: http://git.xiph.org/?p=opus.git;a=blobdiff_plain;f=libcelt%2Fmodes.c;h=30d7a3e828a99254862a2bedfb4c3e4d7d92624e;hp=ff88f582932af94a755853572017cd8fdf9433f7;hb=e0c25452e802f546705a60b1c0a7b63c5f4cb7c0;hpb=bb8fa1fca2819ac4b7eb901a765a8854479c0b52 diff --git a/libcelt/modes.c b/libcelt/modes.c index ff88f582..30d7a3e8 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -42,14 +42,29 @@ #include "stack_alloc.h" #include "quant_bands.h" +static const celt_int16 eband5ms[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100 +}; + +#define BITALLOC_SIZE 9 +/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */ +static const unsigned char band_allocation[] = { +/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 80, 75, 70, 65, 60, 55, 50, 44, 40, 35, 30, 15, 1, 0, 0, 0, 0, 0, 0, 0, + 90, 85, 85, 85, 85, 82, 78, 74, 70, 65, 60, 54, 45, 35, 25, 15, 1, 0, 0, 0, 0, +120,110,110,110,100, 96, 90, 88, 84, 76, 70, 65, 60, 45, 35, 25, 20, 1, 1, 0, 0, +135,125,125,125,115,112,104,104,100, 96, 83, 78, 70, 55, 46, 36, 32, 28, 20, 8, 0, +175,170,167,155,149,145,143,138,138,138,129,124,108, 96, 88, 83, 72, 56, 44, 28, 2, +224,192,192,192,192,192,192,192,192,192,192,192,156,128,108, 96, 88, 76, 68, 44, 20, +255,224,224,224,224,224,224,224,224,224,224,224,224,188,164,148,124, 96, 80, 64, 40, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,220,188,144,104, 84, 60, +}; + #ifdef STATIC_MODES #include "static_modes.c" #endif -#define MODEVALID 0xa110ca7e -#define MODEPARTIAL 0x7eca10a1 -#define MODEFREED 0xb10cf8ee - #ifndef M_PI #define M_PI 3.141592653 #endif @@ -57,8 +72,6 @@ int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value) { - if (check_mode(mode) != CELT_OK) - return CELT_INVALID_MODE; switch (request) { case CELT_GET_LOOKAHEAD: @@ -89,45 +102,18 @@ static const celt_int16 bark_freq[BARK_BANDS+1] = { 6400, 7700, 9500, 12000, 15500, 20000}; -/* This allocation table is per critical band. When creating a mode, the bits get added together - into the codec bands, which are sometimes larger than one critical band at low frequency */ - -#ifdef STDIN_TUNING -int BITALLOC_SIZE; -int *band_allocation; -#else -#define BITALLOC_SIZE 12 -static const unsigned char band_allocation[BARK_BANDS*BITALLOC_SIZE] = - /* 0 100 200 300 400 510 630 770 920 1k 1.2 1.5 1.7 2k 2.3 2.7 3.1 3.7 4.4 5.3 6.4 7.7 9.5 12k 15k */ - { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*0*/ - 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*1*/ - 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, 5, 7, 7, 7, 5, 4, 0, 0, 0, 0, 0, 0, /*2*/ - 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 8, 8, 8, 6, 5, 4, 0, 0, 0, 0, 0, /*3*/ - 3, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 4, 6, 7, 9, 9, 9, 7, 6, 5, 5, 5, 0, 0, 0, /*4*/ - 3, 3, 3, 4, 4, 5, 6, 6, 6, 6, 6, 7, 7, 9, 10, 10, 10, 9, 6, 5, 5, 5, 5, 1, 0, /*5*/ - 4, 3, 3, 4, 6, 7, 7, 7, 7, 7, 8, 9, 9, 9, 11, 10, 10, 9, 9, 8, 11, 10, 10, 1, 0, /*6*/ - 5, 5, 5, 6, 7, 7, 7, 7, 8, 8, 9, 10, 10, 12, 12, 11, 11, 17, 12, 15, 15, 20, 18, 10, 1, /*7*/ - 6, 7, 7, 7, 8, 8, 8, 8, 9, 10, 11, 12, 14, 17, 18, 21, 22, 27, 29, 39, 37, 38, 40, 35, 1, /*8*/ - 7, 7, 7, 8, 8, 8, 10, 10, 10, 13, 14, 18, 20, 24, 28, 32, 32, 35, 38, 38, 42, 50, 59, 54, 31, /*9*/ - 8, 8, 8, 8, 8, 9, 10, 12, 14, 20, 22, 25, 28, 30, 35, 42, 46, 50, 55, 60, 62, 62, 72, 82, 62, /*10*/ - 9, 9, 9, 10, 12, 13, 15, 18, 22, 30, 32, 35, 40, 45, 55, 62, 66, 70, 85, 90, 92, 92, 92,102, 92, /*11*/ - }; -#endif - -static const celt_int16 eband5ms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100}; - static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands) { celt_int16 *eBands; int i, lin, low, high, nBark, offset=0; - if (Fs == 400*(celt_int32)frame_size && Fs >= 40000) + /* All modes that have 2.5 ms short blocks use the same definition */ + if (Fs == 400*(celt_int32)frame_size) { *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; - eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2)); - for (i=0;i<*nbEBands+2;i++) + eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1)); + for (i=0;i<*nbEBands+1;i++) eBands[i] = eband5ms[i]; - eBands[*nbEBands+1] = frame_size; return eBands; } /* Find the number of critical bands supported by our sampling rate */ @@ -165,9 +151,8 @@ static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *n if (eBands[i] < i) eBands[i] = i; eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res; - eBands[*nbEBands+1] = frame_size; - if (eBands[*nbEBands] > eBands[*nbEBands+1]) - eBands[*nbEBands] = eBands[*nbEBands+1]; + if (eBands[*nbEBands] > frame_size) + eBands[*nbEBands] = frame_size; for (i=1;i<*nbEBands-1;i++) { if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1]) @@ -185,33 +170,39 @@ static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *n static void compute_allocation_table(CELTMode *mode, int res) { - int i, j, nBark; - celt_int16 *allocVectors; - - /* Find the number of critical bands supported by our sampling rate */ - for (nBark=1;nBark= mode->Fs) - break; + int i, j; + unsigned char *allocVectors; + int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; mode->nbAllocVectors = BITALLOC_SIZE; - allocVectors = celt_alloc(sizeof(celt_int16)*(BITALLOC_SIZE*mode->nbEBands)); + allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands)); if (allocVectors==NULL) return; + + /* Check for standard mode */ + if (mode->Fs == 400*(celt_int32)mode->shortMdctSize && mode->Fs >= 40000) + { + for (i=0;inbEBands;i++) + allocVectors[i] = band_allocation[i]; + mode->allocVectors = allocVectors; + return; + } + /* If not the standard mode, interpolate */ + /* Compute per-codec-band allocation from per-critical-band matrix */ for (i=0;ishortMdctSize/mode->Fs)*band_allocation[i*BARK_BANDS+j]; - low = bark_freq[j]; - high = bark_freq[j+1]; - + alloc = band_allocation[i*maxBands + j]*(mode->eBands[eband+1]-mode->eBands[eband])<<4; + low = eband5ms[j]*200; + high = eband5ms[j+1]*200; edge = mode->eBands[eband+1]*res; while (edge <= high && eband < mode->nbEBands) { @@ -222,12 +213,7 @@ static void compute_allocation_table(CELTMode *mode, int res) den = high-low; /* Divide with rounding */ bits = (2*num+den)/(2*den); - allocVectors[i*mode->nbEBands+eband] = (current+bits+128)>>(8-BITRES); - /* Remove one bit from every band -- FIXME: this is just a temporary hack*/ - allocVectors[i*mode->nbEBands+eband] -= 1<nbEBands+eband]<0) - allocVectors[i*mode->nbEBands+eband]=0; - allocVectors[i*mode->nbEBands+eband] = (2*allocVectors[i*mode->nbEBands+eband]+N)/(2*N); + allocVectors[i*mode->nbEBands+eband] = (2*(current+bits)+(N<<4))/(2*N<<4); /* Remove the part of the band we just allocated */ low = edge; alloc -= bits; @@ -235,22 +221,19 @@ static void compute_allocation_table(CELTMode *mode, int res) /* Move to next eband */ current = 0; eband++; - edge = mode->eBands[eband+1]*res; + if (eband < mode->nbEBands) + edge = mode->eBands[eband+1]*res; } current += alloc; } if (eband < mode->nbEBands) { int N = (mode->eBands[eband+1]-mode->eBands[eband]); - allocVectors[i*mode->nbEBands+eband] = (current+128)>>(8-BITRES); - /* Same hack as above FIXME: again */ - allocVectors[i*mode->nbEBands+eband] -= 1<nbEBands+eband]<0) - allocVectors[i*mode->nbEBands+eband]=0; - allocVectors[i*mode->nbEBands+eband] = (2*allocVectors[i*mode->nbEBands+eband]+N)/(2*N); + allocVectors[i*mode->nbEBands+eband] = (2*current+(N<<4))/(2*N<<4); } } - /*for (i=0;inbEBands;j++) printf ("%d ", allocVectors[i*mode->nbEBands+j]); @@ -266,73 +249,49 @@ static void compute_allocation_table(CELTMode *mode, int res) CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) { int i; -#ifdef STDIN_TUNING - scanf("%d ", &MIN_BINS); - scanf("%d ", &BITALLOC_SIZE); - band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE); - for (i=0;iFs && - frame_size == static_mode_list[i]->mdctSize) + frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts) { - m = static_mode_list[i]; - break; + return (CELTMode*)static_mode_list[i]; } } - if (m == NULL) - { - celt_warning("Mode not included as part of the static modes"); - if (error) - *error = CELT_BAD_ARG; - return NULL; - } - mode = (CELTMode*)celt_alloc(sizeof(CELTMode)); - if (mode==NULL) - goto failure; - CELT_COPY(mode, m, 1); - mode->marker_start = MODEPARTIAL; + if (error) + *error = CELT_BAD_ARG; + return NULL; #else int res; CELTMode *mode=NULL; celt_word16 *window; celt_int16 *logN; + int LM; +#ifdef STDIN_TUNING + scanf("%d ", &MIN_BINS); + scanf("%d ", &BITALLOC_SIZE); + band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE); + for (i=0;i 96000) + if (Fs < 8000 || Fs > 96000) { - celt_warning("Sampling rate must be between 32 kHz and 96 kHz"); if (error) *error = CELT_BAD_ARG; return NULL; } - if (frame_size < 64 || frame_size > 1024 || frame_size%2!=0) + if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0) { - celt_warning("Only even frame sizes from 64 to 1024 are supported"); if (error) *error = CELT_BAD_ARG; return NULL; @@ -341,33 +300,63 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) mode = celt_alloc(sizeof(CELTMode)); if (mode==NULL) goto failure; - mode->marker_start = MODEPARTIAL; mode->Fs = Fs; - mode->mdctSize = frame_size; - mode->ePredCoef = QCONST16(.8f,15); - if (frame_size >= 640 && (frame_size%16)==0) + /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis + is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should + approximate that. */ + if(Fs < 12000) /* 8 kHz */ + { + mode->preemph[0] = QCONST16(.35f, 15); + mode->preemph[1] = -QCONST16(.18f, 15); + mode->preemph[2] = QCONST16(.272f, SIG_SHIFT); + mode->preemph[3] = QCONST16(3.6765f, 13); + } else if(Fs < 24000) /* 16 kHz */ + { + mode->preemph[0] = QCONST16(.6f, 15); + mode->preemph[1] = -QCONST16(.18f, 15); + mode->preemph[2] = QCONST16(.4425f, SIG_SHIFT); + mode->preemph[3] = QCONST16(2.259887f, 13); + } else if(Fs < 40000) /* 32 kHz */ + { + mode->preemph[0] = QCONST16(.78f, 15); + mode->preemph[1] = -QCONST16(.1f, 15); + mode->preemph[2] = QCONST16(.75f, SIG_SHIFT); + mode->preemph[3] = QCONST16(1.33333333f, 13); + } else /* 48 kHz */ + { + mode->preemph[0] = QCONST16(.85f, 15); + mode->preemph[1] = QCONST16(.0f, 15); + mode->preemph[2] = QCONST16(1.f, SIG_SHIFT); + mode->preemph[3] = QCONST16(1.f, 13); + } + + if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0) { - mode->nbShortMdcts = 8; - } else if (frame_size >= 320 && (frame_size%8)==0) + LM = 3; + } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0) { - mode->nbShortMdcts = 4; - } else if (frame_size >= 160 && (frame_size%4)==0) + LM = 2; + } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0) { - mode->nbShortMdcts = 2; + LM = 1; } else { - mode->nbShortMdcts = 1; + LM = 0; } - mode->shortMdctSize = mode->mdctSize/mode->nbShortMdcts; + mode->maxLM = LM; + mode->nbShortMdcts = 1<shortMdctSize = frame_size/mode->nbShortMdcts; res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize); mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands); if (mode->eBands==NULL) goto failure; - mode->pitchEnd = 4000*(celt_int32)mode->shortMdctSize/Fs; + mode->effEBands = mode->nbEBands; + while (mode->eBands[mode->effEBands] > mode->shortMdctSize) + mode->effEBands--; /* Overlap must be divisible by 4 */ if (mode->nbShortMdcts > 1) @@ -393,17 +382,6 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) #endif mode->window = window; - mode->bits = mode->_bits+1; - for (i=0;(1<nbShortMdcts;i++) - { - mode->bits[i] = (const celt_int16 **)compute_alloc_cache(mode, 1<bits[i]==NULL) - goto failure; - } - mode->bits[-1] = (const celt_int16 **)compute_alloc_cache(mode, 0); - if (mode->bits[-1]==NULL) - goto failure; - logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16)); if (logN==NULL) goto failure; @@ -411,26 +389,24 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) for (i=0;inbEBands;i++) logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES); 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) + compute_pulse_cache(mode, mode->maxLM); + + clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM); + 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; - mode->marker_start = MODEVALID; - mode->marker_end = MODEVALID; if (error) *error = CELT_OK; + return mode; failure: if (error) @@ -438,58 +414,14 @@ failure: if (mode!=NULL) celt_mode_destroy(mode); return NULL; +#endif /* !STATIC_MODES */ } void celt_mode_destroy(CELTMode *mode) { - int i, m; - const celt_int16 *prevPtr = NULL; +#ifndef STATIC_MODES if (mode == NULL) - { - celt_warning("NULL passed to celt_mode_destroy"); return; - } - - if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED) - { - celt_warning("Freeing a mode which has already been freed"); - return; - } - - if (mode->marker_start != MODEVALID && mode->marker_start != MODEPARTIAL) - { - celt_warning("This is not a valid CELT mode structure"); - return; - } - mode->marker_start = MODEFREED; -#ifndef STATIC_MODES - for (m=0;(1<nbShortMdcts;m++) - { - if (mode->bits[m]!=NULL) - { - for (i=0;inbEBands;i++) - { - if (mode->bits[m][i] != prevPtr) - { - prevPtr = mode->bits[m][i]; - celt_free((int*)mode->bits[m][i]); - } - } - } - celt_free((celt_int16**)mode->bits[m]); - } - if (mode->bits[-1]!=NULL) - { - for (i=0;inbEBands;i++) - { - if (mode->bits[-1][i] != prevPtr) - { - prevPtr = mode->bits[-1][i]; - celt_free((int*)mode->bits[-1][i]); - } - } - } - celt_free((celt_int16**)mode->bits[-1]); celt_free((celt_int16*)mode->eBands); celt_free((celt_int16*)mode->allocVectors); @@ -497,24 +429,11 @@ void celt_mode_destroy(CELTMode *mode) celt_free((celt_word16*)mode->window); celt_free((celt_int16*)mode->logN); -#endif - for (i=0;(1<nbShortMdcts;i++) - clt_mdct_clear(&mode->mdct[i]); - + celt_free((celt_int16*)mode->cache.index); + celt_free((unsigned char*)mode->cache.bits); + clt_mdct_clear(&mode->mdct); quant_prob_free(mode->prob); - mode->marker_end = MODEFREED; - celt_free((CELTMode *)mode); -} -int check_mode(const CELTMode *mode) -{ - if (mode==NULL) - return CELT_INVALID_MODE; - if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID) - return CELT_OK; - if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED) - celt_warning("Using a mode that has already been freed"); - else - celt_warning("This is not a valid CELT mode"); - return CELT_INVALID_MODE; + celt_free((CELTMode *)mode); +#endif }