📄 modes_noglobals.c
字号:
/* Copyright (C) 2004 CSIRO Australia
File: modes_noglobals.c
Hacked by Conrad Parker, based on modes.c:
Copyright (C) 2002 Jean-Marc Valin
Describes the different modes of the codec. This file differs from
modes.c in that SpeexMode structures are dynamically allocated,
rather than being statically defined. This introduces some minor
API changes which are described in the file README.symbian in the
top level of the Speex source distribution.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "modes.h"
#include "ltp.h"
#include "quant_lsp.h"
#include "cb_search.h"
#include "sb_celp.h"
#include "nb_celp.h"
#include "vbr.h"
#include "misc.h"
#include <math.h>
#include <string.h>
#ifndef NULL
#define NULL 0
#endif
/* Extern declarations for all codebooks we use here */
extern const signed char gain_cdbk_nb[];
extern const signed char gain_cdbk_lbr[];
extern const signed char hexc_table[];
extern const signed char exc_5_256_table[];
extern const signed char exc_5_64_table[];
extern const signed char exc_8_128_table[];
extern const signed char exc_10_32_table[];
extern const signed char exc_10_16_table[];
extern const signed char exc_20_32_table[];
extern const signed char hexc_10_32_table[];
static const ltp_params *
speex_ltp_params_new (const signed char * gain_cdbk, int gain_bits,
int pitch_bits)
{
ltp_params * params;
params = (ltp_params *) speex_alloc (sizeof (ltp_params));
if (params == NULL) return NULL;
params->gain_cdbk = gain_cdbk;
params->gain_bits = gain_bits;
params->pitch_bits = pitch_bits;
return params;
}
static void
speex_ltp_params_free (const ltp_params * params)
{
speex_free ((void *)params);
}
static const split_cb_params *
speex_split_cb_params_new (int subvect_size, int nb_subvect,
const signed char * shape_cb, int shape_bits,
int have_sign)
{
split_cb_params * params;
params = (split_cb_params *) speex_alloc (sizeof (split_cb_params));
if (params == NULL) return NULL;
params->subvect_size = subvect_size;
params->nb_subvect = nb_subvect;
params->shape_cb = shape_cb;
params->shape_bits = shape_bits;
params->have_sign = have_sign;
return params;
}
static void
speex_split_cb_params_free (const split_cb_params * params)
{
speex_free ((void *)params);
}
static SpeexSubmode *
speex_submode_new (int lbr_pitch, int forced_pitch_gain,
int have_subframe_gain, int double_codebook,
lsp_quant_func lsp_quant, lsp_unquant_func lsp_unquant,
ltp_quant_func ltp_quant, ltp_unquant_func ltp_unquant,
const void * ltp_params,
innovation_quant_func innovation_quant,
innovation_unquant_func innovation_unquant,
const void * innovation_params,
/*Synthesis filter enhancement*/
spx_word16_t lpc_enh_k1, /**< Enhancer constant */
spx_word16_t lpc_enh_k2, /**< Enhancer constant */
spx_word16_t lpc_enh_k3, /**< Enhancer constant */
spx_word16_t comb_gain, /**< Gain of enhancer comb filter */
int bits_per_frame /**< Number of bits per frame after encoding*/
)
{
SpeexSubmode * submode;
submode = (SpeexSubmode *) speex_alloc (sizeof (SpeexSubmode));
if (submode == NULL) return NULL;
submode->lbr_pitch = lbr_pitch;
submode->forced_pitch_gain = forced_pitch_gain;
submode->have_subframe_gain = have_subframe_gain;
submode->double_codebook = double_codebook;
submode->lsp_quant = lsp_quant;
submode->lsp_unquant = lsp_unquant;
submode->ltp_quant = ltp_quant;
submode->ltp_unquant = ltp_unquant;
submode->ltp_params = ltp_params;
submode->innovation_quant = innovation_quant;
submode->innovation_unquant = innovation_unquant;
submode->innovation_params = innovation_params;
submode->lpc_enh_k1 = lpc_enh_k1;
submode->lpc_enh_k2 = lpc_enh_k2;
submode->lpc_enh_k3 = lpc_enh_k3;
submode->comb_gain = comb_gain;
submode->bits_per_frame = bits_per_frame;
return submode;
}
static void
speex_submode_free (const SpeexSubmode * submode)
{
if (submode->ltp_params)
speex_ltp_params_free (submode->ltp_params);
if (submode->innovation_params)
speex_split_cb_params_free (submode->innovation_params);
speex_free ((void *)submode);
}
static SpeexNBMode *
nb_mode_new (int frameSize, int subframeSize, int lpcSize, int bufSize,
int pitchStart, int pitchEnd, spx_word16_t gamma1,
spx_word16_t gamma2, float lag_factor, float lpc_floor,
#ifdef EPIC_48K
int lbr48k,
#endif
const SpeexSubmode * submodes[], int defaultSubmode,
int quality_map[])
{
SpeexNBMode * nb_mode;
nb_mode = (SpeexNBMode *) speex_alloc (sizeof (SpeexNBMode));
if (nb_mode == NULL) return NULL;
nb_mode->frameSize = frameSize;
nb_mode->subframeSize = subframeSize;
nb_mode->lpcSize = lpcSize;
nb_mode->bufSize = bufSize;
nb_mode->pitchStart = pitchStart;
nb_mode->pitchEnd = pitchEnd;
nb_mode->gamma1 = gamma1;
nb_mode->gamma2 = gamma2;
nb_mode->lag_factor = lag_factor;
nb_mode->lpc_floor = lpc_floor;
#ifdef EPIC_48K
nb_mode->lbr48k = lbr48k;
#endif
memcpy (nb_mode->submodes, submodes, sizeof (nb_mode->submodes));
nb_mode->defaultSubmode = defaultSubmode;
memcpy (nb_mode->quality_map, quality_map, sizeof (nb_mode->quality_map));
return nb_mode;
}
static void
nb_mode_free (const SpeexNBMode * nb_mode)
{
speex_free ((void *)nb_mode);
}
static SpeexSBMode *
sb_mode_new (
const SpeexMode *nb_mode, /**< Embedded narrowband mode */
int frameSize, /**< Size of frames used for encoding */
int subframeSize, /**< Size of sub-frames used for encoding */
int lpcSize, /**< Order of LPC filter */
int bufSize, /**< Signal buffer size in encoder */
spx_word16_t gamma1, /**< Perceptual filter parameter #1 */
spx_word16_t gamma2, /**< Perceptual filter parameter #1 */
float lag_factor, /**< Lag-windowing parameter */
float lpc_floor, /**< Noise floor for LPC analysis */
float folding_gain,
const SpeexSubmode *submodes[], /**< Sub-mode data for the mode */
int defaultSubmode, /**< Default sub-mode to use when encoding */
int low_quality_map[], /**< Mode corresponding to each quality setting */
int quality_map[], /**< Mode corresponding to each quality setting */
const float (*vbr_thresh)[11],
int nb_modes
)
{
SpeexSBMode * sb_mode;
sb_mode = (SpeexSBMode *) speex_alloc (sizeof (SpeexSBMode));
if (sb_mode == NULL) return NULL;
sb_mode->nb_mode = nb_mode;
sb_mode->frameSize = frameSize;
sb_mode->subframeSize = subframeSize;
sb_mode->lpcSize = lpcSize;
sb_mode->bufSize = bufSize;
sb_mode->gamma1 = gamma1;
sb_mode->gamma2 = gamma2;
sb_mode->lag_factor = lag_factor;
sb_mode->lpc_floor = lpc_floor;
sb_mode->folding_gain = folding_gain;
memcpy (sb_mode->submodes, submodes, sizeof (sb_mode->submodes));
sb_mode->defaultSubmode = defaultSubmode;
memcpy (sb_mode->low_quality_map, low_quality_map, sizeof (sb_mode->low_quality_map));
memcpy (sb_mode->quality_map, quality_map, sizeof (sb_mode->quality_map));
sb_mode->vbr_thresh = vbr_thresh;
sb_mode->nb_modes = nb_modes;
return sb_mode;
}
static void
sb_mode_free (const SpeexSBMode * sb_mode)
{
int i;
for (i = 0; i < SB_SUBMODES; i++)
if (sb_mode->submodes[i]) speex_submode_free (sb_mode->submodes[i]);
speex_free ((void *)sb_mode);
}
static SpeexMode *
mode_new (const void * b_mode, mode_query_func query, char * modeName,
int modeID, int bitstream_version, encoder_init_func enc_init,
encoder_destroy_func enc_destroy, encode_func enc,
decoder_init_func dec_init, decoder_destroy_func dec_destroy,
decode_func dec, encoder_ctl_func enc_ctl,
decoder_ctl_func dec_ctl)
{
SpeexMode * mode;
mode = (SpeexMode *) speex_alloc (sizeof (SpeexMode));
if (mode == NULL) return NULL;
mode->mode = b_mode;
mode->query = query;
mode->modeName = modeName;
mode->modeID = modeID;
mode->bitstream_version = bitstream_version;
mode->enc_init = enc_init;
mode->enc_destroy = enc_destroy;
mode->enc = enc;
mode->dec_init = dec_init;
mode->dec_destroy = dec_destroy;
mode->dec = dec;
mode->enc_ctl = enc_ctl;
mode->dec_ctl = dec_ctl;
return mode;
}
/* Freeing each kind of created (SpeexMode *) is done separately below */
/* Parameters for Long-Term Prediction (LTP)*/
static const ltp_params * ltp_params_nb (void)
{
return speex_ltp_params_new (
gain_cdbk_nb,
7,
7
);
}
/* Parameters for Long-Term Prediction (LTP)*/
static const ltp_params * ltp_params_vlbr (void)
{
return speex_ltp_params_new (
gain_cdbk_lbr,
5,
0
);
}
/* Parameters for Long-Term Prediction (LTP)*/
static const ltp_params * ltp_params_lbr (void)
{
return speex_ltp_params_new (
gain_cdbk_lbr,
5,
7
);
}
/* Parameters for Long-Term Prediction (LTP)*/
static const ltp_params * ltp_params_med (void)
{
return speex_ltp_params_new (
gain_cdbk_lbr,
5,
7
);
}
/* Split-VQ innovation parameters for very low bit-rate narrowband */
static const split_cb_params * split_cb_nb_vlbr (void)
{
return speex_split_cb_params_new (
10, /*subvect_size*/
4, /*nb_subvect*/
exc_10_16_table, /*shape_cb*/
4, /*shape_bits*/
0
);
}
/* Split-VQ innovation parameters for very low bit-rate narrowband */
static const split_cb_params * split_cb_nb_ulbr (void)
{
return speex_split_cb_params_new (
20, /*subvect_size*/
2, /*nb_subvect*/
exc_20_32_table, /*shape_cb*/
5, /*shape_bits*/
0
);
}
/* Split-VQ innovation parameters for low bit-rate narrowband */
static const split_cb_params * split_cb_nb_lbr (void)
{
return speex_split_cb_params_new (
10, /*subvect_size*/
4, /*nb_subvect*/
exc_10_32_table, /*shape_cb*/
5, /*shape_bits*/
0
);
}
/* Split-VQ innovation parameters narrowband */
static const split_cb_params * split_cb_nb (void)
{
return speex_split_cb_params_new (
5, /*subvect_size*/
8, /*nb_subvect*/
exc_5_64_table, /*shape_cb*/
6, /*shape_bits*/
0
);
}
/* Split-VQ innovation parameters narrowband */
static const split_cb_params * split_cb_nb_med (void)
{
return speex_split_cb_params_new (
8, /*subvect_size*/
5, /*nb_subvect*/
exc_8_128_table, /*shape_cb*/
7, /*shape_bits*/
0
);
}
/* Split-VQ innovation for low-band wideband */
static const split_cb_params * split_cb_sb (void)
{
return speex_split_cb_params_new (
5, /*subvect_size*/
8, /*nb_subvect*/
exc_5_256_table, /*shape_cb*/
8, /*shape_bits*/
0
);
}
/* Split-VQ innovation for high-band wideband */
static const split_cb_params * split_cb_high (void)
{
return speex_split_cb_params_new (
8, /*subvect_size*/
5, /*nb_subvect*/
hexc_table, /*shape_cb*/
7, /*shape_bits*/
1
);
}
/* Split-VQ innovation for high-band wideband */
static const split_cb_params * split_cb_high_lbr (void)
{
return speex_split_cb_params_new (
10, /*subvect_size*/
4, /*nb_subvect*/
hexc_10_32_table, /*shape_cb*/
5, /*shape_bits*/
0
);
}
/* 2150 bps "vocoder-like" mode for comfort noise */
static const SpeexSubmode * nb_submode1 (void)
{
return speex_submode_new (
0,
1,
0,
0,
/* LSP quantization */
lsp_quant_lbr,
lsp_unquant_lbr,
/* No pitch quantization */
forced_pitch_quant,
forced_pitch_unquant,
NULL,
/* No innovation quantization (noise only) */
noise_codebook_quant,
noise_codebook_unquant,
NULL,
#ifdef FIXED_POINT
22938, 22938, 0, -1,
#else
.7, .7, 0, -1,
#endif
43
);
}
/* 3.95 kbps very low bit-rate mode */
static const SpeexSubmode * nb_submode8 (void)
{
const split_cb_params * params;
params = split_cb_nb_ulbr();
if (params == NULL) return NULL;
return speex_submode_new (
0,
1,
0,
0,
/*LSP quantization*/
lsp_quant_lbr,
lsp_unquant_lbr,
/*No pitch quantization*/
forced_pitch_quant,
forced_pitch_unquant,
NULL,
/*Innovation quantization*/
split_cb_search_shape_sign,
split_cb_shape_sign_unquant,
params,
#ifdef FIXED_POINT
22938, 16384, 11796, 21299,
#else
0.7, 0.5, .36, .65,
#endif
79
);
}
/* 5.95 kbps very low bit-rate mode */
static const SpeexSubmode * nb_submode2 (void)
{
return speex_submode_new (
0,
0,
0,
0,
/*LSP quantization*/
lsp_quant_lbr,
lsp_unquant_lbr,
/*No pitch quantization*/
pitch_search_3tap,
pitch_unquant_3tap,
ltp_params_vlbr(),
/*Innovation quantization*/
split_cb_search_shape_sign,
split_cb_shape_sign_unquant,
split_cb_nb_vlbr(),
#ifdef FIXED_POINT
22938, 16384, 11796, 18022,
#else
0.7, 0.5, .36, .55,
#endif
119
);
}
/* 8 kbps low bit-rate mode */
static const SpeexSubmode * nb_submode3 (void)
{
return speex_submode_new (
-1,
0,
1,
0,
/*LSP quantization*/
lsp_quant_lbr,
lsp_unquant_lbr,
/*Pitch quantization*/
pitch_search_3tap,
pitch_unquant_3tap,
ltp_params_lbr(),
/*Innovation quantization*/
split_cb_search_shape_sign,
split_cb_shape_sign_unquant,
split_cb_nb_lbr(),
#ifdef FIXED_POINT
22938, 18022, 9830, 14746,
#else
0.7, 0.55, .30, .45,
#endif
160
);
}
/* 11 kbps medium bit-rate mode */
static const SpeexSubmode * nb_submode4 (void)
{
return speex_submode_new (
-1,
0,
1,
0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -