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