cannam@154: /*********************************************************************** cannam@154: Copyright (c) 2006-2011, Skype Limited. All rights reserved. cannam@154: Redistribution and use in source and binary forms, with or without cannam@154: modification, are permitted provided that the following conditions cannam@154: are met: cannam@154: - Redistributions of source code must retain the above copyright notice, cannam@154: this list of conditions and the following disclaimer. cannam@154: - Redistributions in binary form must reproduce the above copyright cannam@154: notice, this list of conditions and the following disclaimer in the cannam@154: documentation and/or other materials provided with the distribution. cannam@154: - Neither the name of Internet Society, IETF or IETF Trust, nor the cannam@154: names of specific contributors, may be used to endorse or promote cannam@154: products derived from this software without specific prior written cannam@154: permission. cannam@154: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" cannam@154: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE cannam@154: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE cannam@154: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE cannam@154: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR cannam@154: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF cannam@154: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS cannam@154: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN cannam@154: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) cannam@154: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE cannam@154: POSSIBILITY OF SUCH DAMAGE. cannam@154: ***********************************************************************/ cannam@154: cannam@154: #ifdef HAVE_CONFIG_H cannam@154: #include "config.h" cannam@154: #endif cannam@154: cannam@154: #include "main.h" cannam@154: cannam@154: /* Set decoder sampling rate */ cannam@154: opus_int silk_decoder_set_fs( cannam@154: silk_decoder_state *psDec, /* I/O Decoder state pointer */ cannam@154: opus_int fs_kHz, /* I Sampling frequency (kHz) */ cannam@154: opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ cannam@154: ) cannam@154: { cannam@154: opus_int frame_length, ret = 0; cannam@154: cannam@154: celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); cannam@154: celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); cannam@154: cannam@154: /* New (sub)frame length */ cannam@154: psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); cannam@154: frame_length = silk_SMULBB( psDec->nb_subfr, psDec->subfr_length ); cannam@154: cannam@154: /* Initialize resampler when switching internal or external sampling frequency */ cannam@154: if( psDec->fs_kHz != fs_kHz || psDec->fs_API_hz != fs_API_Hz ) { cannam@154: /* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */ cannam@154: ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 ); cannam@154: cannam@154: psDec->fs_API_hz = fs_API_Hz; cannam@154: } cannam@154: cannam@154: if( psDec->fs_kHz != fs_kHz || frame_length != psDec->frame_length ) { cannam@154: if( fs_kHz == 8 ) { cannam@154: if( psDec->nb_subfr == MAX_NB_SUBFR ) { cannam@154: psDec->pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; cannam@154: } else { cannam@154: psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; cannam@154: } cannam@154: } else { cannam@154: if( psDec->nb_subfr == MAX_NB_SUBFR ) { cannam@154: psDec->pitch_contour_iCDF = silk_pitch_contour_iCDF; cannam@154: } else { cannam@154: psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; cannam@154: } cannam@154: } cannam@154: if( psDec->fs_kHz != fs_kHz ) { cannam@154: psDec->ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); cannam@154: if( fs_kHz == 8 || fs_kHz == 12 ) { cannam@154: psDec->LPC_order = MIN_LPC_ORDER; cannam@154: psDec->psNLSF_CB = &silk_NLSF_CB_NB_MB; cannam@154: } else { cannam@154: psDec->LPC_order = MAX_LPC_ORDER; cannam@154: psDec->psNLSF_CB = &silk_NLSF_CB_WB; cannam@154: } cannam@154: if( fs_kHz == 16 ) { cannam@154: psDec->pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; cannam@154: } else if( fs_kHz == 12 ) { cannam@154: psDec->pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; cannam@154: } else if( fs_kHz == 8 ) { cannam@154: psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; cannam@154: } else { cannam@154: /* unsupported sampling rate */ cannam@154: celt_assert( 0 ); cannam@154: } cannam@154: psDec->first_frame_after_reset = 1; cannam@154: psDec->lagPrev = 100; cannam@154: psDec->LastGainIndex = 10; cannam@154: psDec->prevSignalType = TYPE_NO_VOICE_ACTIVITY; cannam@154: silk_memset( psDec->outBuf, 0, sizeof(psDec->outBuf)); cannam@154: silk_memset( psDec->sLPC_Q14_buf, 0, sizeof(psDec->sLPC_Q14_buf) ); cannam@154: } cannam@154: cannam@154: psDec->fs_kHz = fs_kHz; cannam@154: psDec->frame_length = frame_length; cannam@154: } cannam@154: cannam@154: /* Check that settings are valid */ cannam@154: celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); cannam@154: cannam@154: return ret; cannam@154: } cannam@154: