Home | History | Annotate | Download | only in libspeex
      1 /* Copyright (C) 2002-2007 Jean-Marc Valin
      2    File: modes.c
      3 
      4    Describes the wideband modes of the codec
      5 
      6    Redistribution and use in source and binary forms, with or without
      7    modification, are permitted provided that the following conditions
      8    are met:
      9 
     10    - Redistributions of source code must retain the above copyright
     11    notice, this list of conditions and the following disclaimer.
     12 
     13    - Redistributions in binary form must reproduce the above copyright
     14    notice, this list of conditions and the following disclaimer in the
     15    documentation and/or other materials provided with the distribution.
     16 
     17    - Neither the name of the Xiph.org Foundation nor the names of its
     18    contributors may be used to endorse or promote products derived from
     19    this software without specific prior written permission.
     20 
     21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
     25    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     26    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     28    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     29    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     30    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     31    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 
     33 */
     34 
     35 #ifdef HAVE_CONFIG_H
     36 #include "config.h"
     37 #endif
     38 
     39 #include "modes.h"
     40 #include "ltp.h"
     41 #include "quant_lsp.h"
     42 #include "cb_search.h"
     43 #include "sb_celp.h"
     44 #include "nb_celp.h"
     45 #include "vbr.h"
     46 #include "arch.h"
     47 #include <math.h>
     48 #include "os_support.h"
     49 
     50 
     51 #ifndef NULL
     52 #define NULL 0
     53 #endif
     54 
     55 EXPORT const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
     56 
     57 extern const signed char hexc_table[];
     58 extern const signed char hexc_10_32_table[];
     59 
     60 #ifndef DISABLE_WIDEBAND
     61 
     62 /* Split-VQ innovation for high-band wideband */
     63 static const split_cb_params split_cb_high = {
     64    8,               /*subvect_size*/
     65    5,               /*nb_subvect*/
     66    hexc_table,       /*shape_cb*/
     67    7,               /*shape_bits*/
     68    1,
     69 };
     70 
     71 
     72 /* Split-VQ innovation for high-band wideband */
     73 static const split_cb_params split_cb_high_lbr = {
     74    10,               /*subvect_size*/
     75    4,               /*nb_subvect*/
     76    hexc_10_32_table,       /*shape_cb*/
     77    5,               /*shape_bits*/
     78    0,
     79 };
     80 
     81 #endif
     82 
     83 
     84 static const SpeexSubmode wb_submode1 = {
     85    0,
     86    0,
     87    1,
     88    0,
     89    /*LSP quantization*/
     90    lsp_quant_high,
     91    lsp_unquant_high,
     92    /*Pitch quantization*/
     93    NULL,
     94    NULL,
     95    NULL,
     96    /*No innovation quantization*/
     97    NULL,
     98    NULL,
     99    NULL,
    100    -1,
    101    36
    102 };
    103 
    104 
    105 static const SpeexSubmode wb_submode2 = {
    106    0,
    107    0,
    108    1,
    109    0,
    110    /*LSP quantization*/
    111    lsp_quant_high,
    112    lsp_unquant_high,
    113    /*Pitch quantization*/
    114    NULL,
    115    NULL,
    116    NULL,
    117    /*Innovation quantization*/
    118    split_cb_search_shape_sign,
    119    split_cb_shape_sign_unquant,
    120 #ifdef DISABLE_WIDEBAND
    121    NULL,
    122 #else
    123    &split_cb_high_lbr,
    124 #endif
    125    -1,
    126    112
    127 };
    128 
    129 
    130 static const SpeexSubmode wb_submode3 = {
    131    0,
    132    0,
    133    1,
    134    0,
    135    /*LSP quantization*/
    136    lsp_quant_high,
    137    lsp_unquant_high,
    138    /*Pitch quantization*/
    139    NULL,
    140    NULL,
    141    NULL,
    142    /*Innovation quantization*/
    143    split_cb_search_shape_sign,
    144    split_cb_shape_sign_unquant,
    145 #ifdef DISABLE_WIDEBAND
    146    NULL,
    147 #else
    148    &split_cb_high,
    149 #endif
    150    -1,
    151    192
    152 };
    153 
    154 static const SpeexSubmode wb_submode4 = {
    155    0,
    156    0,
    157    1,
    158    1,
    159    /*LSP quantization*/
    160    lsp_quant_high,
    161    lsp_unquant_high,
    162    /*Pitch quantization*/
    163    NULL,
    164    NULL,
    165    NULL,
    166    /*Innovation quantization*/
    167    split_cb_search_shape_sign,
    168    split_cb_shape_sign_unquant,
    169 #ifdef DISABLE_WIDEBAND
    170    NULL,
    171 #else
    172    &split_cb_high,
    173 #endif
    174    -1,
    175    352
    176 };
    177 
    178 
    179 /* Split-band wideband CELP mode*/
    180 static const SpeexSBMode sb_wb_mode = {
    181    &speex_nb_mode,
    182    160,    /*frameSize*/
    183    40,     /*subframeSize*/
    184    8,     /*lpcSize*/
    185 #ifdef FIXED_POINT
    186    29491, 19661, /* gamma1, gamma2 */
    187 #else
    188    0.9, 0.6, /* gamma1, gamma2 */
    189 #endif
    190    QCONST16(.0002,15), /*lpc_floor*/
    191    QCONST16(0.9f,15),
    192    {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
    193    3,
    194    {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
    195    {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
    196 #ifndef DISABLE_VBR
    197    vbr_hb_thresh,
    198 #endif
    199    5
    200 };
    201 
    202 
    203 EXPORT const SpeexMode speex_wb_mode = {
    204    &sb_wb_mode,
    205    wb_mode_query,
    206    "wideband (sub-band CELP)",
    207    1,
    208    4,
    209    &sb_encoder_init,
    210    &sb_encoder_destroy,
    211    &sb_encode,
    212    &sb_decoder_init,
    213    &sb_decoder_destroy,
    214    &sb_decode,
    215    &sb_encoder_ctl,
    216    &sb_decoder_ctl,
    217 };
    218 
    219 
    220 
    221 /* "Ultra-wideband" mode stuff */
    222 
    223 
    224 
    225 /* Split-band "ultra-wideband" (32 kbps) CELP mode*/
    226 static const SpeexSBMode sb_uwb_mode = {
    227    &speex_wb_mode,
    228    320,    /*frameSize*/
    229    80,     /*subframeSize*/
    230    8,     /*lpcSize*/
    231 #ifdef FIXED_POINT
    232    29491, 19661, /* gamma1, gamma2 */
    233 #else
    234    0.9, 0.6, /* gamma1, gamma2 */
    235 #endif
    236    QCONST16(.0002,15), /*lpc_floor*/
    237    QCONST16(0.7f,15),
    238    {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
    239    1,
    240    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
    241    {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    242 #ifndef DISABLE_VBR
    243    vbr_uhb_thresh,
    244 #endif
    245    2
    246 };
    247 
    248 int wb_mode_query(const void *mode, int request, void *ptr)
    249 {
    250    const SpeexSBMode *m = (const SpeexSBMode*)mode;
    251 
    252    switch (request)
    253    {
    254       case SPEEX_MODE_FRAME_SIZE:
    255          *((int*)ptr)=2*m->frameSize;
    256          break;
    257       case SPEEX_SUBMODE_BITS_PER_FRAME:
    258          if (*((int*)ptr)==0)
    259             *((int*)ptr) = SB_SUBMODE_BITS+1;
    260          else if (m->submodes[*((int*)ptr)]==NULL)
    261             *((int*)ptr) = -1;
    262          else
    263             *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
    264          break;
    265       default:
    266          speex_warning_int("Unknown wb_mode_query request: ", request);
    267          return -1;
    268    }
    269    return 0;
    270 }
    271 
    272 
    273 EXPORT const SpeexMode speex_uwb_mode = {
    274    &sb_uwb_mode,
    275    wb_mode_query,
    276    "ultra-wideband (sub-band CELP)",
    277    2,
    278    4,
    279    &sb_encoder_init,
    280    &sb_encoder_destroy,
    281    &sb_encode,
    282    &sb_decoder_init,
    283    &sb_decoder_destroy,
    284    &sb_decode,
    285    &sb_encoder_ctl,
    286    &sb_decoder_ctl,
    287 };
    288 
    289 /* We have defined speex_lib_get_mode() as a macro in speex.h */
    290 #undef speex_lib_get_mode
    291 
    292 EXPORT const SpeexMode * speex_lib_get_mode (int mode)
    293 {
    294    if (mode < 0 || mode >= SPEEX_NB_MODES) return NULL;
    295 
    296    return speex_mode_list[mode];
    297 }
    298 
    299 
    300 
    301