|
Packit |
664db3 |
/* (C) 2007-2008 Jean-Marc Valin, CSIRO
|
|
Packit |
664db3 |
*/
|
|
Packit |
664db3 |
/*
|
|
Packit |
664db3 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
664db3 |
modification, are permitted provided that the following conditions
|
|
Packit |
664db3 |
are met:
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
- Redistributions of source code must retain the above copyright
|
|
Packit |
664db3 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
- Redistributions in binary form must reproduce the above copyright
|
|
Packit |
664db3 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
664db3 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
- Neither the name of the Xiph.org Foundation nor the names of its
|
|
Packit |
664db3 |
contributors may be used to endorse or promote products derived from
|
|
Packit |
664db3 |
this software without specific prior written permission.
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
664db3 |
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
664db3 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
664db3 |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
|
Packit |
664db3 |
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
Packit |
664db3 |
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
Packit |
664db3 |
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
664db3 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
664db3 |
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit |
664db3 |
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
664db3 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
664db3 |
*/
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
664db3 |
#include "config.h"
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#include "celt.h"
|
|
Packit |
664db3 |
#include "modes.h"
|
|
Packit |
664db3 |
#include "rate.h"
|
|
Packit |
664db3 |
#include "os_support.h"
|
|
Packit |
664db3 |
#include "stack_alloc.h"
|
|
Packit |
664db3 |
#include "quant_bands.h"
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifdef STATIC_MODES
|
|
Packit |
664db3 |
#include "static_modes.c"
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#define MODEVALID 0xa110ca7e
|
|
Packit |
664db3 |
#define MODEFREED 0xb10cf8ee
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifndef M_PI
|
|
Packit |
664db3 |
#define M_PI 3.141592653
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
int celt051_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
switch (request)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
case CELT_GET_FRAME_SIZE:
|
|
Packit |
664db3 |
*value = mode->mdctSize;
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
case CELT_GET_LOOKAHEAD:
|
|
Packit |
664db3 |
*value = mode->overlap;
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
case CELT_GET_NB_CHANNELS:
|
|
Packit |
664db3 |
*value = mode->nbChannels;
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
case CELT_GET_BITSTREAM_VERSION:
|
|
Packit |
664db3 |
*value = CELT_BITSTREAM_VERSION;
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
default:
|
|
Packit |
664db3 |
return CELT_UNIMPLEMENTED;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
return CELT_OK;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifndef STATIC_MODES
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#define PBANDS 8
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifdef STDIN_TUNING
|
|
Packit |
664db3 |
int MIN_BINS;
|
|
Packit |
664db3 |
#else
|
|
Packit |
664db3 |
#define MIN_BINS 3
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
|
|
Packit |
664db3 |
Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
|
|
Packit |
664db3 |
#define BARK_BANDS 25
|
|
Packit |
664db3 |
static const celt_int16_t bark_freq[BARK_BANDS+1] = {
|
|
Packit |
664db3 |
0, 100, 200, 300, 400,
|
|
Packit |
664db3 |
510, 630, 770, 920, 1080,
|
|
Packit |
664db3 |
1270, 1480, 1720, 2000, 2320,
|
|
Packit |
664db3 |
2700, 3150, 3700, 4400, 5300,
|
|
Packit |
664db3 |
6400, 7700, 9500, 12000, 15500,
|
|
Packit |
664db3 |
20000};
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
static const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* This allocation table is per critical band. When creating a mode, the bits get added together
|
|
Packit |
664db3 |
into the codec bands, which are sometimes larger than one critical band at low frequency */
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifdef STDIN_TUNING
|
|
Packit |
664db3 |
int BITALLOC_SIZE;
|
|
Packit |
664db3 |
int *band_allocation;
|
|
Packit |
664db3 |
#else
|
|
Packit |
664db3 |
#define BITALLOC_SIZE 12
|
|
Packit |
664db3 |
static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
|
|
Packit |
664db3 |
{ 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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
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,
|
|
Packit |
664db3 |
};
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
static celt_int16_t *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBands)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
celt_int16_t *eBands;
|
|
Packit |
664db3 |
int i, res, min_width, lin, low, high, nBark;
|
|
Packit |
664db3 |
res = (Fs+frame_size)/(2*frame_size);
|
|
Packit |
664db3 |
min_width = MIN_BINS*res;
|
|
Packit |
664db3 |
/*printf ("min_width = %d\n", min_width);*/
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* Find the number of critical bands supported by our sampling rate */
|
|
Packit |
664db3 |
for (nBark=1;nBark
|
|
Packit |
664db3 |
if (bark_freq[nBark+1]*2 >= Fs)
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* Find where the linear part ends (i.e. where the spacing is more than min_width */
|
|
Packit |
664db3 |
for (lin=0;lin
|
|
Packit |
664db3 |
if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
|
|
Packit |
664db3 |
low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
|
|
Packit |
664db3 |
high = nBark-lin;
|
|
Packit |
664db3 |
*nbEBands = low+high;
|
|
Packit |
664db3 |
eBands = celt_alloc(sizeof(celt_int16_t)*(*nbEBands+2));
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* Linear spacing (min_width) */
|
|
Packit |
664db3 |
for (i=0;i
|
|
Packit |
664db3 |
eBands[i] = MIN_BINS*i;
|
|
Packit |
664db3 |
/* Spacing follows critical bands */
|
|
Packit |
664db3 |
for (i=0;i
|
|
Packit |
664db3 |
eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
|
|
Packit |
664db3 |
/* Enforce the minimum spacing at the boundary */
|
|
Packit |
664db3 |
for (i=0;i<*nbEBands;i++)
|
|
Packit |
664db3 |
if (eBands[i] < MIN_BINS*i)
|
|
Packit |
664db3 |
eBands[i] = MIN_BINS*i;
|
|
Packit |
664db3 |
eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
|
|
Packit |
664db3 |
eBands[*nbEBands+1] = frame_size;
|
|
Packit |
664db3 |
if (eBands[*nbEBands] > eBands[*nbEBands+1])
|
|
Packit |
664db3 |
eBands[*nbEBands] = eBands[*nbEBands+1];
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* FIXME: Remove last band if too small */
|
|
Packit |
664db3 |
/*for (i=0;i<*nbEBands+2;i++)
|
|
Packit |
664db3 |
printf("%d ", eBands[i]);
|
|
Packit |
664db3 |
printf ("\n");
|
|
Packit |
664db3 |
exit(1);*/
|
|
Packit |
664db3 |
return eBands;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
static void compute_pbands(CELTMode *mode, int res)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int i;
|
|
Packit |
664db3 |
celt_int16_t *pBands;
|
|
Packit |
664db3 |
pBands=celt_alloc(sizeof(celt_int16_t)*(PBANDS+2));
|
|
Packit |
664db3 |
mode->nbPBands = PBANDS;
|
|
Packit |
664db3 |
for (i=0;i
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
pBands[i] = (pitch_freq[i]+res/2)/res;
|
|
Packit |
664db3 |
if (pBands[i] < mode->eBands[i])
|
|
Packit |
664db3 |
pBands[i] = mode->eBands[i];
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
|
|
Packit |
664db3 |
for (i=1;i<mode->nbPBands+1;i++)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int j;
|
|
Packit |
664db3 |
for (j=0;j<mode->nbEBands;j++)
|
|
Packit |
664db3 |
if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
/*printf ("%d %d\n", i, j);*/
|
|
Packit |
664db3 |
if (mode->eBands[j] != pBands[i])
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
|
|
Packit |
664db3 |
mode->eBands[j] != pBands[i-1])
|
|
Packit |
664db3 |
pBands[i] = mode->eBands[j];
|
|
Packit |
664db3 |
else
|
|
Packit |
664db3 |
pBands[i] = mode->eBands[j+1];
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
/*for (i=0;i<mode->nbPBands+2;i++)
|
|
Packit |
664db3 |
printf("%d ", pBands[i]);
|
|
Packit |
664db3 |
printf ("\n");*/
|
|
Packit |
664db3 |
mode->pBands = pBands;
|
|
Packit |
664db3 |
mode->pitchEnd = pBands[PBANDS];
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
static void compute_allocation_table(CELTMode *mode, int res)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int i, j, eband, nBark;
|
|
Packit |
664db3 |
celt_int32_t *allocVectors;
|
|
Packit |
664db3 |
celt_int16_t *allocVectorsS;
|
|
Packit |
664db3 |
celt_int16_t *allocEnergy;
|
|
Packit |
664db3 |
const int C = CHANNELS(mode);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* Find the number of critical bands supported by our sampling rate */
|
|
Packit |
664db3 |
for (nBark=1;nBark
|
|
Packit |
664db3 |
if (bark_freq[nBark+1]*2 >= mode->Fs)
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode->nbAllocVectors = BITALLOC_SIZE;
|
|
Packit |
664db3 |
allocVectors = celt_alloc(sizeof(celt_int32_t)*(BITALLOC_SIZE*mode->nbEBands));
|
|
Packit |
664db3 |
allocEnergy = celt_alloc(sizeof(celt_int16_t)*(mode->nbAllocVectors*(mode->nbEBands+1)));
|
|
Packit |
664db3 |
/* Compute per-codec-band allocation from per-critical-band matrix */
|
|
Packit |
664db3 |
for (i=0;i
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
eband = 0;
|
|
Packit |
664db3 |
for (j=0;j
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int edge, low;
|
|
Packit |
664db3 |
celt_int32_t alloc;
|
|
Packit |
664db3 |
edge = mode->eBands[eband+1]*res;
|
|
Packit |
664db3 |
alloc = band_allocation[i*BARK_BANDS+j];
|
|
Packit |
664db3 |
alloc = alloc*C*mode->mdctSize/256;
|
|
Packit |
664db3 |
if (edge < bark_freq[j+1])
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int num, den;
|
|
Packit |
664db3 |
num = alloc * (edge-bark_freq[j]);
|
|
Packit |
664db3 |
den = bark_freq[j+1]-bark_freq[j];
|
|
Packit |
664db3 |
low = (num+den/2)/den;
|
|
Packit |
664db3 |
allocVectors[i*mode->nbEBands+eband] += low;
|
|
Packit |
664db3 |
eband++;
|
|
Packit |
664db3 |
allocVectors[i*mode->nbEBands+eband] += alloc-low;
|
|
Packit |
664db3 |
} else {
|
|
Packit |
664db3 |
allocVectors[i*mode->nbEBands+eband] += alloc;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
/* Compute fine energy resolution and update the pulse allocation table to subtract that */
|
|
Packit |
664db3 |
for (i=0;i<mode->nbAllocVectors;i++)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int sum = 0;
|
|
Packit |
664db3 |
for (j=0;j<mode->nbEBands;j++)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int ebits;
|
|
Packit |
664db3 |
int min_bits=0;
|
|
Packit |
664db3 |
if (allocVectors[i*mode->nbEBands+j] > 0)
|
|
Packit |
664db3 |
min_bits = 1;
|
|
Packit |
664db3 |
ebits = IMAX(min_bits , allocVectors[i*mode->nbEBands+j] / (C*(mode->eBands[j+1]-mode->eBands[j])));
|
|
Packit |
664db3 |
if (ebits>7)
|
|
Packit |
664db3 |
ebits=7;
|
|
Packit |
664db3 |
/* The bits used for fine allocation can't be used for pulses */
|
|
Packit |
664db3 |
/* However, we give two "free" bits to all modes to compensate for the fact that some energy
|
|
Packit |
664db3 |
resolution is needed regardless of the frame size. */
|
|
Packit |
664db3 |
if (ebits>1)
|
|
Packit |
664db3 |
allocVectors[i*mode->nbEBands+j] -= C*(ebits-2);
|
|
Packit |
664db3 |
if (allocVectors[i*mode->nbEBands+j] < 0)
|
|
Packit |
664db3 |
allocVectors[i*mode->nbEBands+j] = 0;
|
|
Packit |
664db3 |
sum += ebits;
|
|
Packit |
664db3 |
allocEnergy[i*(mode->nbEBands+1)+j] = ebits;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
allocEnergy[i*(mode->nbEBands+1)+mode->nbEBands] = sum;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
mode->energy_alloc = allocEnergy;
|
|
Packit |
664db3 |
allocVectorsS = celt_alloc(sizeof(celt_int16_t)*(BITALLOC_SIZE*mode->nbEBands));
|
|
Packit |
664db3 |
for(i=0;i<(BITALLOC_SIZE*mode->nbEBands);i++)
|
|
Packit |
664db3 |
allocVectorsS[i] = (celt_int16_t)allocVectors[i];
|
|
Packit |
664db3 |
mode->allocVectors = allocVectorsS;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#endif /* STATIC_MODES */
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
CELTMode *celt051_mode_create(celt_int32_t Fs, int channels, int frame_size, int *error)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
int i;
|
|
Packit |
664db3 |
#ifdef STDIN_TUNING
|
|
Packit |
664db3 |
scanf("%d ", &MIN_BINS);
|
|
Packit |
664db3 |
scanf("%d ", &BITALLOC_SIZE);
|
|
Packit |
664db3 |
band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
|
|
Packit |
664db3 |
for (i=0;i
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
scanf("%d ", band_allocation+i);
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
#ifdef STATIC_MODES
|
|
Packit |
664db3 |
const CELTMode *m = NULL;
|
|
Packit |
664db3 |
CELTMode *mode=NULL;
|
|
Packit |
664db3 |
ALLOC_STACK;
|
|
Packit |
664db3 |
for (i=0;i
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
if (Fs == static_mode_list[i]->Fs &&
|
|
Packit |
664db3 |
channels == static_mode_list[i]->nbChannels &&
|
|
Packit |
664db3 |
frame_size == static_mode_list[i]->mdctSize)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
m = static_mode_list[i];
|
|
Packit |
664db3 |
break;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
if (m == NULL)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
celt_warning("Mode not included as part of the static modes");
|
|
Packit |
664db3 |
if (error)
|
|
Packit |
664db3 |
*error = CELT_BAD_ARG;
|
|
Packit |
664db3 |
return NULL;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
mode = (CELTMode*)celt_alloc(sizeof(CELTMode));
|
|
Packit |
664db3 |
CELT_COPY(mode, m, 1);
|
|
Packit |
664db3 |
#else
|
|
Packit |
664db3 |
int res;
|
|
Packit |
664db3 |
CELTMode *mode;
|
|
Packit |
664db3 |
celt_word16_t *window;
|
|
Packit |
664db3 |
ALLOC_STACK;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
/* The good thing here is that permutation of the arguments will automatically be invalid */
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
if (Fs < 32000 || Fs > 96000)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
celt_warning("Sampling rate must be between 32 kHz and 96 kHz");
|
|
Packit |
664db3 |
if (error)
|
|
Packit |
664db3 |
*error = CELT_BAD_ARG;
|
|
Packit |
664db3 |
return NULL;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
if (channels < 0 || channels > 2)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
celt_warning("Only mono and stereo supported");
|
|
Packit |
664db3 |
if (error)
|
|
Packit |
664db3 |
*error = CELT_BAD_ARG;
|
|
Packit |
664db3 |
return NULL;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
if (frame_size < 64 || frame_size > 512 || frame_size%2!=0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
celt_warning("Only even frame sizes from 64 to 512 are supported");
|
|
Packit |
664db3 |
if (error)
|
|
Packit |
664db3 |
*error = CELT_BAD_ARG;
|
|
Packit |
664db3 |
return NULL;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
res = (Fs+frame_size)/(2*frame_size);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode = celt_alloc(sizeof(CELTMode));
|
|
Packit |
664db3 |
mode->Fs = Fs;
|
|
Packit |
664db3 |
mode->mdctSize = frame_size;
|
|
Packit |
664db3 |
mode->nbChannels = channels;
|
|
Packit |
664db3 |
mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
|
|
Packit |
664db3 |
compute_pbands(mode, res);
|
|
Packit |
664db3 |
mode->ePredCoef = QCONST16(.8f,15);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
if (frame_size > 384 && (frame_size%8)==0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 4;
|
|
Packit |
664db3 |
} else if (frame_size > 384 && (frame_size%10)==0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 5;
|
|
Packit |
664db3 |
} else if (frame_size > 256 && (frame_size%6)==0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 3;
|
|
Packit |
664db3 |
} else if (frame_size > 256 && (frame_size%8)==0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 4;
|
|
Packit |
664db3 |
} else if (frame_size > 64 && (frame_size%4)==0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 2;
|
|
Packit |
664db3 |
} else if (frame_size > 128 && (frame_size%6)==0)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 3;
|
|
Packit |
664db3 |
} else
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
mode->nbShortMdcts = 1;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
if (mode->nbShortMdcts > 1)
|
|
Packit |
664db3 |
mode->overlap = ((frame_size/mode->nbShortMdcts)>>2)<<2; /* Overlap must be divisible by 4 */
|
|
Packit |
664db3 |
else
|
|
Packit |
664db3 |
mode->overlap = (frame_size>>3)<<2;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
compute_allocation_table(mode, res);
|
|
Packit |
664db3 |
/*printf ("%d bands\n", mode->nbEBands);*/
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
window = (celt_word16_t*)celt_alloc(mode->overlap*sizeof(celt_word16_t));
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifndef FIXED_POINT
|
|
Packit |
664db3 |
for (i=0;i<mode->overlap;i++)
|
|
Packit |
664db3 |
window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
|
|
Packit |
664db3 |
#else
|
|
Packit |
664db3 |
for (i=0;i<mode->overlap;i++)
|
|
Packit |
664db3 |
window[i] = MIN32(32767,32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)));
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
mode->window = window;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode->bits = (const celt_int16_t **)compute_alloc_cache(mode, 1);
|
|
Packit |
664db3 |
if (mode->nbChannels>=2)
|
|
Packit |
664db3 |
mode->bits_stereo = (const celt_int16_t **)compute_alloc_cache(mode, mode->nbChannels);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
#ifndef SHORTCUTS
|
|
Packit |
664db3 |
psydecay_init(&mode->psy, MAX_PERIOD/2, mode->Fs);
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode->marker_start = MODEVALID;
|
|
Packit |
664db3 |
mode->marker_end = MODEVALID;
|
|
Packit |
664db3 |
#endif /* !STATIC_MODES */
|
|
Packit |
664db3 |
mdct_init(&mode->mdct, 2*mode->mdctSize);
|
|
Packit |
664db3 |
mode->fft = pitch_state_alloc(MAX_PERIOD);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode->shortMdctSize = mode->mdctSize/mode->nbShortMdcts;
|
|
Packit |
664db3 |
mdct_init(&mode->shortMdct, 2*mode->shortMdctSize);
|
|
Packit |
664db3 |
mode->shortWindow = mode->window;
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode->prob = quant_prob_alloc(mode);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
if (error)
|
|
Packit |
664db3 |
*error = CELT_OK;
|
|
Packit |
664db3 |
return mode;
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
void celt051_mode_destroy(CELTMode *mode)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
#ifndef STATIC_MODES
|
|
Packit |
664db3 |
int i;
|
|
Packit |
664db3 |
const celt_int16_t *prevPtr = NULL;
|
|
Packit |
664db3 |
for (i=0;i<mode->nbEBands;i++)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
if (mode->bits[i] != prevPtr)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
prevPtr = mode->bits[i];
|
|
Packit |
664db3 |
celt_free((int*)mode->bits[i]);
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
celt_free((int**)mode->bits);
|
|
Packit |
664db3 |
if (mode->bits_stereo != NULL)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
for (i=0;i<mode->nbEBands;i++)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
if (mode->bits_stereo[i] != prevPtr)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
prevPtr = mode->bits_stereo[i];
|
|
Packit |
664db3 |
celt_free((int*)mode->bits_stereo[i]);
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
celt_free((int**)mode->bits_stereo);
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
if (check_mode(mode) != CELT_OK)
|
|
Packit |
664db3 |
return;
|
|
Packit |
664db3 |
celt_free((int*)mode->eBands);
|
|
Packit |
664db3 |
celt_free((int*)mode->pBands);
|
|
Packit |
664db3 |
celt_free((int*)mode->allocVectors);
|
|
Packit |
664db3 |
celt_free((celt_int16_t *)mode->energy_alloc);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
celt_free((celt_word16_t*)mode->window);
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
mode->marker_start = MODEFREED;
|
|
Packit |
664db3 |
mode->marker_end = MODEFREED;
|
|
Packit |
664db3 |
#ifndef SHORTCUTS
|
|
Packit |
664db3 |
psydecay_clear(&mode->psy);
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
#endif
|
|
Packit |
664db3 |
mdct_clear(&mode->mdct);
|
|
Packit |
664db3 |
mdct_clear(&mode->shortMdct);
|
|
Packit |
664db3 |
pitch_state_free(mode->fft);
|
|
Packit |
664db3 |
quant_prob_free(mode->prob);
|
|
Packit |
664db3 |
celt_free((CELTMode *)mode);
|
|
Packit |
664db3 |
}
|
|
Packit |
664db3 |
|
|
Packit |
664db3 |
int check_mode(const CELTMode *mode)
|
|
Packit |
664db3 |
{
|
|
Packit |
664db3 |
if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
|
|
Packit |
664db3 |
return CELT_OK;
|
|
Packit |
664db3 |
if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
|
|
Packit |
664db3 |
celt_warning("Using a mode that has already been freed");
|
|
Packit |
664db3 |
else
|
|
Packit |
664db3 |
celt_warning("This is not a valid CELT mode");
|
|
Packit |
664db3 |
return CELT_INVALID_MODE;
|
|
Packit |
664db3 |
}
|