More simplifications from denorm pitch
[opus.git] / libcelt / modes.c
index b7c39d7..8a9f223 100644 (file)
@@ -82,14 +82,6 @@ int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
 
 #ifndef STATIC_MODES
 
-#define PBANDS 8
-
-#ifdef STDIN_TUNING
-int MIN_BINS;
-#else
-#define MIN_BINS 3
-#endif
-
 /* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
    Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
 #define BARK_BANDS 25
@@ -101,8 +93,6 @@ static const celt_int16_t bark_freq[BARK_BANDS+1] = {
    6400,  7700,  9500, 12000, 15500,
   20000};
 
-static const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
-
 /* 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 */
 
@@ -112,28 +102,32 @@ int *band_allocation;
 #else
 #define BITALLOC_SIZE 12
 static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] = 
-   {  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,
-      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,
-      2,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  4,  5,  7,  7,  7,  5,  4,  0,  0,  0,  0,  0,  0,
-      2,  2,  2,  2,  3,  2,  2,  2,  2,  2,  3,  3,  5,  6,  8,  8,  8,  6,  5,  4,  0,  0,  0,  0,  0,
-      3,  2,  2,  2,  3,  3,  2,  3,  2,  3,  4,  4,  6,  7,  9,  9,  9,  7,  6,  5,  5,  5,  0,  0,  0,
-      3,  3,  2,  2,  3,  3,  3,  3,  3,  4,  4,  5,  7,  9, 10, 10, 10,  9,  6,  5,  5,  5,  5,  1,  0,
-      4,  3,  3,  3,  3,  3,  3,  3,  4,  4,  6,  7,  7,  9, 11, 10, 10,  9,  9,  8, 11, 10, 10,  1,  1,
-      5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  8,  8, 10, 12, 12, 11, 11, 17, 12, 15, 15, 20, 18, 10,  1,
-      8,  7,  7,  7,  7,  7,  8,  8,  9, 10, 11, 12, 14, 17, 18, 21, 22, 27, 29, 39, 37, 38, 40, 35,  1,
-      7,  7,  7,  7,  7,  7, 10, 10, 10, 13, 14, 18, 20, 24, 28, 32, 32, 35, 38, 38, 42, 50, 59, 54, 31,
-      8,  8,  8,  8,  8,  9, 10, 12, 14, 20, 22, 25, 28, 30, 35, 42, 46, 50, 55, 60, 62, 62, 62, 62, 62,
-     12, 12, 12, 12, 12, 13, 15, 18, 22, 30, 32, 35, 40, 45, 55, 62, 66, 70, 85, 90, 92, 92, 92, 92, 92,
+   /* 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 celt_int16_t *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBands)
+static celt_int16_t *compute_ebands(celt_int32_t Fs, int frame_size, int nbShortMdcts, int *nbEBands)
 {
+   int min_bins = 2;
    celt_int16_t *eBands;
    int i, res, min_width, lin, low, high, nBark;
+
+   if (min_bins < nbShortMdcts)
+      min_bins = nbShortMdcts;
    res = (Fs+frame_size)/(2*frame_size);
-   min_width = MIN_BINS*res;
-   /*printf ("min_width = %d\n", min_width);*/
+   min_width = min_bins*res;
 
    /* Find the number of critical bands supported by our sampling rate */
    for (nBark=1;nBark<BARK_BANDS;nBark++)
@@ -145,8 +139,7 @@ static celt_int16_t *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBan
       if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
          break;
    
-   /*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
-   low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
+   low = ((bark_freq[lin]/res)+(min_bins-1))/min_bins;
    high = nBark-lin;
    *nbEBands = low+high;
    eBands = celt_alloc(sizeof(celt_int16_t)*(*nbEBands+2));
@@ -156,63 +149,30 @@ static celt_int16_t *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBan
    
    /* Linear spacing (min_width) */
    for (i=0;i<low;i++)
-      eBands[i] = MIN_BINS*i;
+      eBands[i] = min_bins*i;
    /* Spacing follows critical bands */
    for (i=0;i<high;i++)
-      eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
+      eBands[i+low] = (bark_freq[lin+i]+res/2)/res/nbShortMdcts*nbShortMdcts;
    /* Enforce the minimum spacing at the boundary */
    for (i=0;i<*nbEBands;i++)
-      if (eBands[i] < MIN_BINS*i)
-         eBands[i] = MIN_BINS*i;
-   eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
+      if (eBands[i] < min_bins*i)
+         eBands[i] = min_bins*i;
+   eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res/nbShortMdcts*nbShortMdcts;
    eBands[*nbEBands+1] = frame_size;
    if (eBands[*nbEBands] > eBands[*nbEBands+1])
       eBands[*nbEBands] = eBands[*nbEBands+1];
-   
-   /* FIXME: Remove last band if too small */
-   /*for (i=0;i<*nbEBands+2;i++)
-      printf("%d ", eBands[i]);
-   printf ("\n");
-   exit(1);*/
-   return eBands;
-}
-
-static void compute_pbands(CELTMode *mode, int res)
-{
-   int i;
-   celt_int16_t *pBands;
-   pBands=celt_alloc(sizeof(celt_int16_t)*(PBANDS+2));
-   mode->pBands = pBands;
-   if (pBands==NULL)
-     return;
-   mode->nbPBands = PBANDS;
-   for (i=0;i<PBANDS+1;i++)
-   {
-      pBands[i] = (pitch_freq[i]+res/2)/res;
-      if (pBands[i] < mode->eBands[i])
-         pBands[i] = mode->eBands[i];
-   }
-   pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
-   for (i=1;i<mode->nbPBands+1;i++)
+   for (i=1;i<*nbEBands-1;i++)
    {
-      int j;
-      for (j=0;j<mode->nbEBands;j++)
-         if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
-            break;
-      /*printf ("%d %d\n", i, j);*/
-      if (mode->eBands[j] != pBands[i])
+      if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
       {
-         if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] && 
-             mode->eBands[j] != pBands[i-1])
-            pBands[i] = mode->eBands[j];
-         else
-            pBands[i] = mode->eBands[j+1];
+         eBands[i] -= min_bins;
       }
    }
-   /*for (i=0;i<mode->nbPBands+2;i++)
-      printf("%d ", pBands[i]);
+   /*for (i=0;i<*nbEBands+1;i++)
+      printf ("%d ", eBands[i]);
    printf ("\n");*/
-   mode->pitchEnd = pBands[PBANDS];
+   /* FIXME: Remove last band if too small */
+   return eBands;
 }
 
 static void compute_allocation_table(CELTMode *mode, int res)
@@ -310,7 +270,7 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e
    mode->marker_start = MODEPARTIAL;
 #else
    int res;
-   CELTMode *mode;
+   CELTMode *mode=NULL;
    celt_word16_t *window;
    ALLOC_STACK;
 #if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
@@ -337,9 +297,9 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e
          *error = CELT_BAD_ARG;
       return NULL;
    }
-   if (frame_size < 64 || frame_size > 512 || frame_size%2!=0)
+   if (frame_size < 64 || frame_size > 1024 || frame_size%2!=0)
    {
-      celt_warning("Only even frame sizes from 64 to 512 are supported");
+      celt_warning("Only even frame sizes from 64 to 1024 are supported");
       if (error)
          *error = CELT_BAD_ARG;
       return NULL;
@@ -353,15 +313,12 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e
    mode->Fs = Fs;
    mode->mdctSize = frame_size;
    mode->nbChannels = channels;
-   mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
-   if (mode->eBands==NULL)
-      goto failure;
-   compute_pbands(mode, res);
-   if (mode->pBands==NULL)
-      goto failure;
    mode->ePredCoef = QCONST16(.8f,15);
 
-   if (frame_size > 384 && (frame_size%8)==0)
+   if (frame_size > 640 && (frame_size%16)==0)
+   {
+     mode->nbShortMdcts = 8;
+   } else if (frame_size > 384 && (frame_size%8)==0)
    {
      mode->nbShortMdcts = 4;
    } else if (frame_size > 384 && (frame_size%10)==0)
@@ -384,15 +341,21 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e
      mode->nbShortMdcts = 1;
    }
 
+   mode->eBands = compute_ebands(Fs, frame_size, mode->nbShortMdcts, &mode->nbEBands);
+   if (mode->eBands==NULL)
+      goto failure;
+
+   mode->pitchEnd = 3000*(celt_int32_t)frame_size/Fs;
+   
+   /* Overlap must be divisible by 4 */
    if (mode->nbShortMdcts > 1)
-      mode->overlap = ((frame_size/mode->nbShortMdcts)>>2)<<2; /* Overlap must be divisible by 4 */
+      mode->overlap = ((frame_size/mode->nbShortMdcts)>>2)<<2; 
    else
       mode->overlap = (frame_size>>3)<<2;
 
    compute_allocation_table(mode, res);
    if (mode->allocVectors==NULL)
       goto failure;
-   /*printf ("%d bands\n", mode->nbEBands);*/
    
    window = (celt_word16_t*)celt_alloc(mode->overlap*sizeof(celt_word16_t));
    if (window==NULL)
@@ -418,6 +381,17 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e
 #endif
    
 #endif /* !STATIC_MODES */
+
+#ifdef DISABLE_STEREO
+   if (channels > 1)
+   {
+      celt_warning("Stereo support was disable from this build");
+      if (error)
+         *error = CELT_BAD_ARG;
+      return NULL;
+   }
+#endif
+
    mdct_init(&mode->mdct, 2*mode->mdctSize);
    mode->fft = pitch_state_alloc(MAX_PERIOD);
 
@@ -425,8 +399,11 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e
    mdct_init(&mode->shortMdct, 2*mode->shortMdctSize);
    mode->shortWindow = mode->window;
    mode->prob = quant_prob_alloc(mode);
-   if ((mode->mdct.trig==NULL) || (mode->mdct.kfft==NULL) || (mode->fft==NULL) ||
-       (mode->shortMdct.trig==NULL) || (mode->shortMdct.kfft==NULL) || (mode->prob==NULL))
+   if ((mode->mdct.trig==NULL) || (mode->shortMdct.trig==NULL)
+#ifndef ENABLE_TI_DSPLIB55
+        || (mode->mdct.kfft==NULL) || (mode->fft==NULL) || (mode->shortMdct.kfft==NULL)
+#endif
+        || (mode->prob==NULL))
      goto failure;
 
    mode->marker_start = MODEVALID;
@@ -444,6 +421,8 @@ failure:
 
 void celt_mode_destroy(CELTMode *mode)
 {
+   int i;
+   const celt_int16_t *prevPtr = NULL;
    if (mode == NULL)
    {
       celt_warning("NULL passed to celt_mode_destroy");
@@ -463,8 +442,6 @@ void celt_mode_destroy(CELTMode *mode)
    }
    mode->marker_start = MODEFREED;
 #ifndef STATIC_MODES
-   int i;
-   const celt_int16_t *prevPtr = NULL;
    if (mode->bits!=NULL)
    {
       for (i=0;i<mode->nbEBands;i++)
@@ -478,7 +455,6 @@ void celt_mode_destroy(CELTMode *mode)
    }   
    celt_free((int**)mode->bits);
    celt_free((int*)mode->eBands);
-   celt_free((int*)mode->pBands);
    celt_free((int*)mode->allocVectors);
    
    celt_free((celt_word16_t*)mode->window);