Repository: ketn4391/android_silk_v3_decoder Branch: master Commit: 3cf7b032f867 Files: 218 Total size: 2.0 MB Directory structure: gitextract_cflykvbw/ ├── .gitignore ├── README.md ├── app/ │ ├── .gitignore │ ├── CMakeLists.txt │ ├── build.gradle │ ├── jni/ │ │ ├── SKP_Silk_A2NLSF.c │ │ ├── SKP_Silk_CNG.c │ │ ├── SKP_Silk_HP_variable_cutoff_FIX.c │ │ ├── SKP_Silk_LBRR_reset.c │ │ ├── SKP_Silk_LPC_inv_pred_gain.c │ │ ├── SKP_Silk_LPC_synthesis_filter.c │ │ ├── SKP_Silk_LPC_synthesis_order16.c │ │ ├── SKP_Silk_LP_variable_cutoff.c │ │ ├── SKP_Silk_LSF_cos_table.c │ │ ├── SKP_Silk_LTP_analysis_filter_FIX.c │ │ ├── SKP_Silk_LTP_scale_ctrl_FIX.c │ │ ├── SKP_Silk_MA.c │ │ ├── SKP_Silk_NLSF2A.c │ │ ├── SKP_Silk_NLSF2A_stable.c │ │ ├── SKP_Silk_NLSF_MSVQ_decode.c │ │ ├── SKP_Silk_NLSF_MSVQ_encode_FIX.c │ │ ├── SKP_Silk_NLSF_VQ_rate_distortion_FIX.c │ │ ├── SKP_Silk_NLSF_VQ_sum_error_FIX.c │ │ ├── SKP_Silk_NLSF_VQ_weights_laroia.c │ │ ├── SKP_Silk_NLSF_stabilize.c │ │ ├── SKP_Silk_NSQ.c │ │ ├── SKP_Silk_NSQ_del_dec.c │ │ ├── SKP_Silk_PLC.c │ │ ├── SKP_Silk_VAD.c │ │ ├── SKP_Silk_VQ_nearest_neighbor_FIX.c │ │ ├── SKP_Silk_ana_filt_bank_1.c │ │ ├── SKP_Silk_apply_sine_window.c │ │ ├── SKP_Silk_array_maxabs.c │ │ ├── SKP_Silk_autocorr.c │ │ ├── SKP_Silk_biquad.c │ │ ├── SKP_Silk_biquad_alt.c │ │ ├── SKP_Silk_burg_modified.c │ │ ├── SKP_Silk_bwexpander.c │ │ ├── SKP_Silk_bwexpander_32.c │ │ ├── SKP_Silk_code_signs.c │ │ ├── SKP_Silk_control_audio_bandwidth.c │ │ ├── SKP_Silk_control_codec_FIX.c │ │ ├── SKP_Silk_corrMatrix_FIX.c │ │ ├── SKP_Silk_create_init_destroy.c │ │ ├── SKP_Silk_dec_API.c │ │ ├── SKP_Silk_decode_core.c │ │ ├── SKP_Silk_decode_frame.c │ │ ├── SKP_Silk_decode_parameters.c │ │ ├── SKP_Silk_decode_pitch.c │ │ ├── SKP_Silk_decode_pulses.c │ │ ├── SKP_Silk_decoder_set_fs.c │ │ ├── SKP_Silk_detect_SWB_input.c │ │ ├── SKP_Silk_div_oabi.c │ │ ├── SKP_Silk_enc_API.c │ │ ├── SKP_Silk_encode_frame_FIX.c │ │ ├── SKP_Silk_encode_parameters.c │ │ ├── SKP_Silk_encode_pulses.c │ │ ├── SKP_Silk_find_LPC_FIX.c │ │ ├── SKP_Silk_find_LTP_FIX.c │ │ ├── SKP_Silk_find_pitch_lags_FIX.c │ │ ├── SKP_Silk_find_pred_coefs_FIX.c │ │ ├── SKP_Silk_gain_quant.c │ │ ├── SKP_Silk_init_encoder_FIX.c │ │ ├── SKP_Silk_inner_prod_aligned.c │ │ ├── SKP_Silk_interpolate.c │ │ ├── SKP_Silk_k2a.c │ │ ├── SKP_Silk_k2a_Q16.c │ │ ├── SKP_Silk_lin2log.c │ │ ├── SKP_Silk_log2lin.c │ │ ├── SKP_Silk_noise_shape_analysis_FIX.c │ │ ├── SKP_Silk_pitch_analysis_core.c │ │ ├── SKP_Silk_pitch_est_tables.c │ │ ├── SKP_Silk_prefilter_FIX.c │ │ ├── SKP_Silk_process_NLSFs_FIX.c │ │ ├── SKP_Silk_process_gains_FIX.c │ │ ├── SKP_Silk_quant_LTP_gains_FIX.c │ │ ├── SKP_Silk_range_coder.c │ │ ├── SKP_Silk_regularize_correlations_FIX.c │ │ ├── SKP_Silk_resampler.c │ │ ├── SKP_Silk_resampler_down2.c │ │ ├── SKP_Silk_resampler_down2_3.c │ │ ├── SKP_Silk_resampler_down3.c │ │ ├── SKP_Silk_resampler_private_AR2.c │ │ ├── SKP_Silk_resampler_private_ARMA4.c │ │ ├── SKP_Silk_resampler_private_IIR_FIR.c │ │ ├── SKP_Silk_resampler_private_copy.c │ │ ├── SKP_Silk_resampler_private_down4.c │ │ ├── SKP_Silk_resampler_private_down_FIR.c │ │ ├── SKP_Silk_resampler_private_up2_HQ.c │ │ ├── SKP_Silk_resampler_private_up4.c │ │ ├── SKP_Silk_resampler_rom.c │ │ ├── SKP_Silk_resampler_up2.c │ │ ├── SKP_Silk_residual_energy16_FIX.c │ │ ├── SKP_Silk_residual_energy_FIX.c │ │ ├── SKP_Silk_scale_copy_vector16.c │ │ ├── SKP_Silk_scale_vector.c │ │ ├── SKP_Silk_schur.c │ │ ├── SKP_Silk_schur64.c │ │ ├── SKP_Silk_shell_coder.c │ │ ├── SKP_Silk_sigm_Q15.c │ │ ├── SKP_Silk_solve_LS_FIX.c │ │ ├── SKP_Silk_sort.c │ │ ├── SKP_Silk_sum_sqr_shift.c │ │ ├── SKP_Silk_tables_LTP.c │ │ ├── SKP_Silk_tables_NLSF_CB0_10.c │ │ ├── SKP_Silk_tables_NLSF_CB0_16.c │ │ ├── SKP_Silk_tables_NLSF_CB1_10.c │ │ ├── SKP_Silk_tables_NLSF_CB1_16.c │ │ ├── SKP_Silk_tables_gain.c │ │ ├── SKP_Silk_tables_other.c │ │ ├── SKP_Silk_tables_pitch_lag.c │ │ ├── SKP_Silk_tables_pulses_per_block.c │ │ ├── SKP_Silk_tables_sign.c │ │ ├── SKP_Silk_tables_type_offset.c │ │ ├── SKP_Silk_warped_autocorrelation_FIX.c │ │ ├── decoder.c │ │ ├── decoder.cpp │ │ ├── include/ │ │ │ ├── SKP_Silk_AsmHelper.h │ │ │ ├── SKP_Silk_AsmPreproc.h │ │ │ ├── SKP_Silk_Inlines.h │ │ │ ├── SKP_Silk_PLC.h │ │ │ ├── SKP_Silk_SDK_API.h │ │ │ ├── SKP_Silk_SigProc_FIX.h │ │ │ ├── SKP_Silk_common_pitch_est_defines.h │ │ │ ├── SKP_Silk_control.h │ │ │ ├── SKP_Silk_define.h │ │ │ ├── SKP_Silk_errors.h │ │ │ ├── SKP_Silk_macros.h │ │ │ ├── SKP_Silk_macros_arm.h │ │ │ ├── SKP_Silk_main.h │ │ │ ├── SKP_Silk_main_FIX.h │ │ │ ├── SKP_Silk_pitch_est_defines.h │ │ │ ├── SKP_Silk_resampler_private.h │ │ │ ├── SKP_Silk_resampler_rom.h │ │ │ ├── SKP_Silk_resampler_structs.h │ │ │ ├── SKP_Silk_setup_complexity.h │ │ │ ├── SKP_Silk_structs.h │ │ │ ├── SKP_Silk_structs_FIX.h │ │ │ ├── SKP_Silk_tables.h │ │ │ ├── SKP_Silk_tables_NLSF_CB0_10.h │ │ │ ├── SKP_Silk_tables_NLSF_CB0_16.h │ │ │ ├── SKP_Silk_tables_NLSF_CB1_10.h │ │ │ ├── SKP_Silk_tables_NLSF_CB1_16.h │ │ │ ├── SKP_Silk_tuning_parameters.h │ │ │ ├── SKP_Silk_typedef.h │ │ │ ├── lame.h │ │ │ └── silk.h │ │ ├── libmp3lame/ │ │ │ ├── VbrTag.c │ │ │ ├── VbrTag.h │ │ │ ├── bitstream.c │ │ │ ├── bitstream.h │ │ │ ├── encoder.c │ │ │ ├── encoder.h │ │ │ ├── fft.c │ │ │ ├── fft.h │ │ │ ├── gain_analysis.c │ │ │ ├── gain_analysis.h │ │ │ ├── id3tag.c │ │ │ ├── id3tag.h │ │ │ ├── l3side.h │ │ │ ├── lame-analysis.h │ │ │ ├── lame.c │ │ │ ├── lame_global_flags.h │ │ │ ├── lameerror.h │ │ │ ├── machine.h │ │ │ ├── mpglib_interface.c │ │ │ ├── newmdct.c │ │ │ ├── newmdct.h │ │ │ ├── presets.c │ │ │ ├── psymodel.c │ │ │ ├── psymodel.h │ │ │ ├── quantize.c │ │ │ ├── quantize.h │ │ │ ├── quantize_pvt.c │ │ │ ├── quantize_pvt.h │ │ │ ├── reservoir.c │ │ │ ├── reservoir.h │ │ │ ├── set_get.c │ │ │ ├── set_get.h │ │ │ ├── tables.c │ │ │ ├── tables.h │ │ │ ├── takehiro.c │ │ │ ├── util.c │ │ │ ├── util.h │ │ │ ├── vbrquantize.c │ │ │ ├── vbrquantize.h │ │ │ ├── vector/ │ │ │ │ ├── Makefile.am │ │ │ │ ├── Makefile.in │ │ │ │ ├── lame_intrin.h │ │ │ │ └── xmm_quantize_sub.c │ │ │ ├── version.c │ │ │ └── version.h │ │ └── silk.c │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── ketian/ │ │ └── android/ │ │ └── silkv3/ │ │ ├── App.kt │ │ ├── ExportFragment.kt │ │ ├── MainActivity.kt │ │ ├── PathUtils.kt │ │ ├── VoiceFragment.kt │ │ └── jni/ │ │ └── JNI.kt │ └── res/ │ ├── layout/ │ │ ├── activity_main.xml │ │ ├── export_item_layout.xml │ │ ├── fragment_export.xml │ │ ├── fragment_voice.xml │ │ └── item_layout.xml │ ├── values/ │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── values-w820dp/ │ └── dimens.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures .idea # Built application files *.apk *.ap_ # Files for the ART/Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ out/ # Gradle files .gradle/ build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log # Android Studio Navigation editor temp files .navigation/ # Android Studio captures folder captures/ # Intellij *.iml .idea/workspace.xml # Keystore files *.jks ================================================ FILE: README.md ================================================ # android_silk_v3_decoder Convert silk v3 audio files (QQ & WeChat voice files) to mp3 files on android. please refer to this app, https://play.google.com/store/apps/details?id=com.pleasure.trace_wechat #2019-04-26 更新构建系统为Cmake+Clang(NDK15(记不清是不是)以后官方默认),转换成kotlin编写,修改lame/machine.h报错的部分,修改silkx JNI入口参数错误问题,增加权限验证(Android7+),替换Android支持包为AndroidX 国内的可以搜索“微痕迹”,此应用集成了微信和QQ语音的转成mp3的功能,另外提供管理微信QQ图片语音文件的功能。 因为语音转换这部分参考了一些开源工程,特将此部分开源,回馈开源社区。 ================================================ FILE: app/.gitignore ================================================ /build *.iml .gradle .idea .DS_Store /captures .externalNativeBuild ================================================ FILE: app/CMakeLists.txt ================================================ # documentation: https://d.android.com/studio/projects/add-native-code.html cmake_minimum_required(VERSION 3.4.1) SET(CMAKE_BUILE_TYPE DEBUG) if (${ANDROID_ABI} STREQUAL arm) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=vfp -mfloat-abi=softfp -fno-short-enums") endif () set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -std=c++11") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s") #find_library(log-lib log) #find_library(z-lib z) #include_directories(jni/include) #message("搜索结果:") add_library(mp3lame STATIC jni/libmp3lame/bitstream.c jni/libmp3lame/fft.c jni/libmp3lame/id3tag.c jni/libmp3lame/mpglib_interface.c jni/libmp3lame/presets.c jni/libmp3lame/quantize.c jni/libmp3lame/reservoir.c jni/libmp3lame/tables.c jni/libmp3lame/util.c jni/libmp3lame/VbrTag.c jni/libmp3lame/encoder.c jni/libmp3lame/gain_analysis.c jni/libmp3lame/lame.c jni/libmp3lame/newmdct.c jni/libmp3lame/psymodel.c jni/libmp3lame/quantize_pvt.c jni/libmp3lame/set_get.c jni/libmp3lame/takehiro.c jni/libmp3lame/vbrquantize.c jni/libmp3lame/version.c ) target_include_directories(mp3lame PUBLIC jni/include/lame.h) add_library(silkx SHARED jni/SKP_Silk_dec_API.c jni/SKP_Silk_create_init_destroy.c jni/SKP_Silk_decoder_set_fs.c jni/SKP_Silk_tables_NLSF_CB0_10.c jni/SKP_Silk_tables_NLSF_CB1_10.c jni/SKP_Silk_tables_NLSF_CB0_16.c jni/SKP_Silk_tables_NLSF_CB1_16.c jni/SKP_Silk_tables_other.c jni/SKP_Silk_CNG.c jni/SKP_Silk_NLSF2A_stable.c jni/SKP_Silk_NLSF2A.c jni/SKP_Silk_bwexpander_32.c jni/SKP_Silk_LSF_cos_table.c jni/SKP_Silk_bwexpander.c jni/SKP_Silk_LPC_inv_pred_gain.c jni/SKP_Silk_LPC_synthesis_filter.c jni/SKP_Silk_LPC_synthesis_order16.c jni/SKP_Silk_PLC.c jni/SKP_Silk_sum_sqr_shift.c jni/SKP_Silk_decode_frame.c jni/SKP_Silk_range_coder.c jni/SKP_Silk_decode_parameters.c jni/SKP_Silk_tables_pitch_lag.c jni/SKP_Silk_tables_type_offset.c jni/SKP_Silk_gain_quant.c jni/SKP_Silk_lin2log.c jni/SKP_Silk_NLSF_MSVQ_decode.c jni/SKP_Silk_NLSF_stabilize.c jni/SKP_Silk_sort.c jni/SKP_Silk_decode_pitch.c jni/SKP_Silk_pitch_est_tables.c jni/SKP_Silk_tables_LTP.c jni/SKP_Silk_tables_gain.c jni/SKP_Silk_decode_pulses.c jni/SKP_Silk_tables_pulses_per_block.c jni/SKP_Silk_code_signs.c jni/SKP_Silk_tables_sign.c jni/SKP_Silk_shell_coder.c jni/SKP_Silk_biquad.c jni/SKP_Silk_decode_core.c jni/SKP_Silk_MA.c jni/SKP_Silk_resampler.c jni/SKP_Silk_resampler_private_down4.c jni/SKP_Silk_resampler_rom.c jni/SKP_Silk_resampler_private_copy.c jni/SKP_Silk_resampler_private_down_FIR.c jni/SKP_Silk_resampler_private_AR2.c jni/SKP_Silk_resampler_down2.c jni/SKP_Silk_resampler_private_up2_HQ.c jni/SKP_Silk_resampler_private_IIR_FIR.c jni/SKP_Silk_resampler_private_ARMA4.c jni/SKP_Silk_resampler_private_up4.c jni/SKP_Silk_resampler_up2.c jni/SKP_Silk_log2lin.c jni/silk.c jni/decoder.cpp # jni/decoder.c ) #target_include_directories(silkx PUBLIC # $ # $ # /include/mylib # ) target_include_directories(mp3lame PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/jni/include) target_link_libraries(silkx mp3lame log z ) ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android' android { compileSdkVersion 28 defaultConfig { applicationId "com.ketian.android.silkv3" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" externalNativeBuild { cmake { cFlags "-frtti -fexceptions -Werror -DANDROID -DSTDC_HEADERS -Werror -fno-short-enums" cppFlags "-frtti -fexceptions -Werror -DANDROID -DSTDC_HEADERS -Werror -std=gnu++0x" } ndk { // abiFilters "armeabi" abiFilters "armeabi-v7a", "x86_64","x86","arm64-v8a" } } } externalNativeBuild { cmake { path "CMakeLists.txt" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation "androidx.core:core-ktx:1.0.1" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } repositories { mavenCentral() } ================================================ FILE: app/jni/SKP_Silk_A2NLSF.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* Conversion between prediction filter coefficients and NLSFs */ /* Requires the order to be an even number */ /* A piecewise linear approximation maps LSF <-> cos(LSF) */ /* Therefore the result is not accurate NLSFs, but the two */ /* function are accurate inverses of each other */ #include "SKP_Silk_SigProc_FIX.h" /* Number of binary divisions */ #define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ #define QPoly 16 #define MAX_ITERATIONS_A2NLSF_FIX 30 /* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */ #define OVERSAMPLE_COSINE_TABLE 0 /* Helper function for A2NLSF(..) */ /* Transforms polynomials from cos(n*f) to cos(f)^n */ SKP_INLINE void SKP_Silk_A2NLSF_trans_poly( SKP_int32 *p, /* I/O Polynomial */ const SKP_int dd /* I Polynomial order (= filter order / 2 ) */ ) { SKP_int k, n; for( k = 2; k <= dd; k++ ) { for( n = dd; n > k; n-- ) { p[ n - 2 ] -= p[ n ]; } p[ k - 2 ] -= SKP_LSHIFT( p[ k ], 1 ); } } #if EMBEDDED_ARM<6 /* Helper function for A2NLSF(..) */ /* Polynomial evaluation */ SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */ SKP_int32 *p, /* I Polynomial, QPoly */ const SKP_int32 x, /* I Evaluation point, Q12 */ const SKP_int dd /* I Order */ ) { SKP_int n; SKP_int32 x_Q16, y32; y32 = p[ dd ]; /* QPoly */ x_Q16 = SKP_LSHIFT( x, 4 ); for( n = dd - 1; n >= 0; n-- ) { y32 = SKP_SMLAWW( p[ n ], y32, x_Q16 ); /* QPoly */ } return y32; } #else SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */ SKP_int32 *p, /* I Polynomial, QPoly */ const SKP_int32 x, /* I Evaluation point, Q12 */ const SKP_int dd /* I Order */ ); #endif SKP_INLINE void SKP_Silk_A2NLSF_init( const SKP_int32 *a_Q16, SKP_int32 *P, SKP_int32 *Q, const SKP_int dd ) { SKP_int k; /* Convert filter coefs to even and odd polynomials */ P[dd] = SKP_LSHIFT( 1, QPoly ); Q[dd] = SKP_LSHIFT( 1, QPoly ); for( k = 0; k < dd; k++ ) { #if( QPoly < 16 ) P[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */ Q[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */ #elif( QPoly == 16 ) P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; // QPoly Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; // QPoly #else P[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */ Q[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */ #endif } /* Divide out zeros as we have that for even filter orders, */ /* z = 1 is always a root in Q, and */ /* z = -1 is always a root in P */ for( k = dd; k > 0; k-- ) { P[ k - 1 ] -= P[ k ]; Q[ k - 1 ] += Q[ k ]; } /* Transform polynomials from cos(n*f) to cos(f)^n */ SKP_Silk_A2NLSF_trans_poly( P, dd ); SKP_Silk_A2NLSF_trans_poly( Q, dd ); } /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ void SKP_Silk_A2NLSF( SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */ SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ const SKP_int d /* I Filter order (must be even) */ ) { SKP_int i, k, m, dd, root_ix, ffrac; SKP_int32 xlo, xhi, xmid; SKP_int32 ylo, yhi, ymid; SKP_int32 nom, den; SKP_int32 P[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ]; SKP_int32 Q[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ]; SKP_int32 *PQ[ 2 ]; SKP_int32 *p; /* Store pointers to array */ PQ[ 0 ] = P; PQ[ 1 ] = Q; dd = SKP_RSHIFT( d, 1 ); SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd ); /* Find roots, alternating between P and Q */ p = P; /* Pointer to polynomial */ xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12 ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); if( ylo < 0 ) { /* Set the first NLSF to zero and move on to the next */ NLSF[ 0 ] = 0; p = Q; /* Pointer to polynomial */ ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); root_ix = 1; /* Index of current root */ } else { root_ix = 0; /* Index of current root */ } k = 1; /* Loop counter */ i = 0; /* Counter for bandwidth expansions applied */ while( 1 ) { /* Evaluate polynomial */ #if OVERSAMPLE_COSINE_TABLE xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] + ( ( SKP_Silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] - SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] ) >> 1 ); /* Q12 */ #else xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */ #endif yhi = SKP_Silk_A2NLSF_eval_poly( p, xhi, dd ); /* Detect zero crossing */ if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) { /* Binary division */ #if OVERSAMPLE_COSINE_TABLE ffrac = -128; #else ffrac = -256; #endif for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) { /* Evaluate polynomial */ xmid = SKP_RSHIFT_ROUND( xlo + xhi, 1 ); ymid = SKP_Silk_A2NLSF_eval_poly( p, xmid, dd ); /* Detect zero crossing */ if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) { /* Reduce frequency */ xhi = xmid; yhi = ymid; } else { /* Increase frequency */ xlo = xmid; ylo = ymid; #if OVERSAMPLE_COSINE_TABLE ffrac = SKP_ADD_RSHIFT( ffrac, 64, m ); #else ffrac = SKP_ADD_RSHIFT( ffrac, 128, m ); #endif } } /* Interpolate */ if( SKP_abs( ylo ) < 65536 ) { /* Avoid dividing by zero */ den = ylo - yhi; nom = SKP_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + SKP_RSHIFT( den, 1 ); if( den != 0 ) { ffrac += SKP_DIV32( nom, den ); } } else { /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */ ffrac += SKP_DIV32( ylo, SKP_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ); } #if OVERSAMPLE_COSINE_TABLE NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 7 ) + ffrac, SKP_int16_MAX ); #else NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 8 ) + ffrac, SKP_int16_MAX ); #endif SKP_assert( NLSF[ root_ix ] >= 0 ); SKP_assert( NLSF[ root_ix ] <= 32767 ); root_ix++; /* Next root */ if( root_ix >= d ) { /* Found all roots */ break; } /* Alternate pointer to polynomial */ p = PQ[ root_ix & 1 ]; /* Evaluate polynomial */ #if OVERSAMPLE_COSINE_TABLE xlo = SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] + ( ( SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] - SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); // Q12 #else xlo = SKP_Silk_LSFCosTab_FIX_Q12[ k - 1 ]; // Q12 #endif ylo = SKP_LSHIFT( 1 - ( root_ix & 2 ), 12 ); } else { /* Increment loop counter */ k++; xlo = xhi; ylo = yhi; #if OVERSAMPLE_COSINE_TABLE if( k > 2 * LSF_COS_TAB_SZ_FIX ) { #else if( k > LSF_COS_TAB_SZ_FIX ) { #endif i++; if( i > MAX_ITERATIONS_A2NLSF_FIX ) { /* Set NLSFs to white spectrum and exit */ NLSF[ 0 ] = SKP_DIV32_16( 1 << 15, d + 1 ); for( k = 1; k < d; k++ ) { NLSF[ k ] = SKP_SMULBB( k + 1, NLSF[ 0 ] ); } return; } /* Error: Apply progressively more bandwidth expansion and run again */ SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 10 + i, i ) ); // 10_Q16 = 0.00015 SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd ); p = P; /* Pointer to polynomial */ xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12 ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); if( ylo < 0 ) { /* Set the first NLSF to zero and move on to the next */ NLSF[ 0 ] = 0; p = Q; /* Pointer to polynomial */ ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd ); root_ix = 1; /* Index of current root */ } else { root_ix = 0; /* Index of current root */ } k = 1; /* Reset loop counter */ } } } } ================================================ FILE: app/jni/SKP_Silk_CNG.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Generates excitation for CNG LPC synthesis */ SKP_INLINE void SKP_Silk_CNG_exc( SKP_int16 residual[], /* O CNG residual signal Q0 */ SKP_int32 exc_buf_Q10[], /* I Random samples buffer Q10 */ SKP_int32 Gain_Q16, /* I Gain to apply */ SKP_int length, /* I Length */ SKP_int32 *rand_seed /* I/O Seed to random index generator */ ) { SKP_int32 seed; SKP_int i, idx, exc_mask; exc_mask = CNG_BUF_MASK_MAX; while( exc_mask > length ) { exc_mask = SKP_RSHIFT( exc_mask, 1 ); } seed = *rand_seed; for( i = 0; i < length; i++ ) { seed = SKP_RAND( seed ); idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask ); SKP_assert( idx >= 0 ); SKP_assert( idx <= CNG_BUF_MASK_MAX ); residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) ); } *rand_seed = seed; } void SKP_Silk_CNG_Reset( SKP_Silk_decoder_state *psDec /* I/O Decoder state */ ) { SKP_int i, NLSF_step_Q15, NLSF_acc_Q15; NLSF_step_Q15 = SKP_DIV32_16( SKP_int16_MAX, psDec->LPC_order + 1 ); NLSF_acc_Q15 = 0; for( i = 0; i < psDec->LPC_order; i++ ) { NLSF_acc_Q15 += NLSF_step_Q15; psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15; } psDec->sCNG.CNG_smth_Gain_Q16 = 0; psDec->sCNG.rand_seed = 3176576; } /* Updates CNG estimate, and applies the CNG when packet was lost */ void SKP_Silk_CNG( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* I/O Signal */ SKP_int length /* I Length of residual */ ) { SKP_int i, subfr; SKP_int32 tmp_32, Gain_Q26, max_Gain_Q16; SKP_int16 LPC_buf[ MAX_LPC_ORDER ]; SKP_int16 CNG_sig[ MAX_FRAME_LENGTH ]; SKP_Silk_CNG_struct *psCNG; psCNG = &psDec->sCNG; if( psDec->fs_kHz != psCNG->fs_kHz ) { /* Reset state */ SKP_Silk_CNG_Reset( psDec ); psCNG->fs_kHz = psDec->fs_kHz; } if( psDec->lossCnt == 0 && psDec->vadFlag == NO_VOICE_ACTIVITY ) { /* Update CNG parameters */ /* Smoothing of LSF's */ for( i = 0; i < psDec->LPC_order; i++ ) { psCNG->CNG_smth_NLSF_Q15[ i ] += SKP_SMULWB( psDec->prevNLSF_Q15[ i ] - psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 ); } /* Find the subframe with the highest gain */ max_Gain_Q16 = 0; subfr = 0; for( i = 0; i < NB_SUBFR; i++ ) { if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) { max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ]; subfr = i; } } /* Update CNG excitation buffer with excitation from this subframe */ SKP_memmove( &psCNG->CNG_exc_buf_Q10[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q10, ( NB_SUBFR - 1 ) * psDec->subfr_length * sizeof( SKP_int32 ) ); SKP_memcpy( psCNG->CNG_exc_buf_Q10, &psDec->exc_Q10[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( SKP_int32 ) ); /* Smooth gains */ for( i = 0; i < NB_SUBFR; i++ ) { psCNG->CNG_smth_Gain_Q16 += SKP_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 ); } } /* Add CNG when packet is lost and / or when low speech activity */ if( psDec->lossCnt ) {//|| psDec->vadFlag == NO_VOICE_ACTIVITY ) { /* Generate CNG excitation */ SKP_Silk_CNG_exc( CNG_sig, psCNG->CNG_exc_buf_Q10, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed ); /* Convert CNG NLSF to filter representation */ SKP_Silk_NLSF2A_stable( LPC_buf, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); Gain_Q26 = ( SKP_int32 )1 << 26; /* 1.0 */ /* Generate CNG signal, by synthesis filtering */ if( psDec->LPC_order == 16 ) { SKP_Silk_LPC_synthesis_order16( CNG_sig, LPC_buf, Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length ); } else { SKP_Silk_LPC_synthesis_filter( CNG_sig, LPC_buf, Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length, psDec->LPC_order ); } /* Mix with signal */ for( i = 0; i < length; i++ ) { tmp_32 = signal[ i ] + CNG_sig[ i ]; signal[ i ] = SKP_SAT16( tmp_32 ); } } else { SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( SKP_int32 ) ); } } ================================================ FILE: app/jni/SKP_Silk_HP_variable_cutoff_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" #if HIGH_PASS_INPUT #define SKP_RADIANS_CONSTANT_Q19 1482 // 0.45f * 2.0f * 3.14159265359 / 1000 #define SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 809 // log(80) in Q7 /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void SKP_Silk_HP_variable_cutoff_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ SKP_int16 *out, /* O high-pass filtered output signal */ const SKP_int16 *in /* I input signal */ ) { SKP_int quality_Q15; SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ]; SKP_int32 Fc_Q19, r_Q28, r_Q22; SKP_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7; /*********************************************/ /* Estimate Low End of Pitch Frequency Range */ /*********************************************/ if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) { /* difference, in log domain */ pitch_freq_Hz_Q16 = SKP_DIV32_16( SKP_LSHIFT( SKP_MUL( psEnc->sCmn.fs_kHz, 1000 ), 16 ), psEnc->sCmn.prevLag ); pitch_freq_log_Q7 = SKP_Silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); //0x70 /* adjustment based on quality */ quality_Q15 = psEncCtrl->input_quality_bands_Q15[ 0 ]; pitch_freq_log_Q7 = SKP_SUB32( pitch_freq_log_Q7, SKP_SMULWB( SKP_SMULWB( SKP_LSHIFT( quality_Q15, 2 ), quality_Q15 ), pitch_freq_log_Q7 - SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 ) ); pitch_freq_log_Q7 = SKP_ADD32( pitch_freq_log_Q7, SKP_RSHIFT( SKP_FIX_CONST( 0.6, 15 ) - quality_Q15, 9 ) ); //delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; delta_freq_Q7 = pitch_freq_log_Q7 - SKP_RSHIFT( psEnc->variable_HP_smth1_Q15, 8 ); if( delta_freq_Q7 < 0 ) { /* less smoothing for decreasing pitch frequency, to track something close to the minimum */ delta_freq_Q7 = SKP_MUL( delta_freq_Q7, 3 ); } /* limit delta, to reduce impact of outliers */ delta_freq_Q7 = SKP_LIMIT_32( delta_freq_Q7, -SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) ); /* update smoother */ psEnc->variable_HP_smth1_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth1_Q15, SKP_MUL( SKP_LSHIFT( psEnc->speech_activity_Q8, 1 ), delta_freq_Q7 ), SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) ); } /* second smoother */ psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15, psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) ); /* convert from log scale to Hertz */ psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) ); /* limit frequency range */ psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT_32( psEncCtrl->pitch_freq_low_Hz, SKP_FIX_CONST( VARIABLE_HP_MIN_FREQ, 0 ), SKP_FIX_CONST( VARIABLE_HP_MAX_FREQ, 0 ) ); /********************************/ /* Compute Filter Coefficients */ /********************************/ /* compute cut-off frequency, in radians */ //Fc_num = (SKP_float)( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz ); //Fc_denom = (SKP_float)( 1e3f * psEnc->sCmn.fs_kHz ); SKP_assert( psEncCtrl->pitch_freq_low_Hz <= SKP_int32_MAX / SKP_RADIANS_CONSTANT_Q19 ); Fc_Q19 = SKP_DIV32_16( SKP_SMULBB( SKP_RADIANS_CONSTANT_Q19, psEncCtrl->pitch_freq_low_Hz ), psEnc->sCmn.fs_kHz ); // range: 3704 - 27787, 11-15 bits SKP_assert( Fc_Q19 >= 3704 ); SKP_assert( Fc_Q19 <= 27787 ); r_Q28 = SKP_FIX_CONST( 1.0, 28 ) - SKP_MUL( SKP_FIX_CONST( 0.92, 9 ), Fc_Q19 ); SKP_assert( r_Q28 >= 255347779 ); SKP_assert( r_Q28 <= 266690872 ); /* b = r * [ 1; -2; 1 ]; */ /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */ B_Q28[ 0 ] = r_Q28; B_Q28[ 1 ] = SKP_LSHIFT( -r_Q28, 1 ); B_Q28[ 2 ] = r_Q28; // -r * ( 2 - Fc * Fc ); r_Q22 = SKP_RSHIFT( r_Q28, 6 ); A_Q28[ 0 ] = SKP_SMULWW( r_Q22, SKP_SMULWW( Fc_Q19, Fc_Q19 ) - SKP_FIX_CONST( 2.0, 22 ) ); A_Q28[ 1 ] = SKP_SMULWW( r_Q22, r_Q22 ); /********************************/ /* High-Pass Filter */ /********************************/ SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length ); } #endif // HIGH_PASS_INPUT ================================================ FILE: app/jni/SKP_Silk_LBRR_reset.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Resets LBRR buffer, used if packet size changes */ void SKP_Silk_LBRR_reset( SKP_Silk_encoder_state *psEncC /* I/O state */ ) { SKP_int i; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { psEncC->LBRR_buffer[ i ].usage = SKP_SILK_NO_LBRR; } } ================================================ FILE: app/jni/SKP_Silk_LPC_inv_pred_gain.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_LPC_inverse_pred_gain.c * * * * Compute inverse of LPC prediction gain, and * * test if LPC coefficients are stable (all poles within unit circle) * * * * Copyright 2008 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #define QA 16 #define A_LIMIT SKP_FIX_CONST( 0.99975, QA ) /* Compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ static SKP_int LPC_inverse_pred_gain_QA( /* O: Returns 1 if unstable, otherwise 0 */ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */ SKP_int32 A_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ], /* I: Prediction coefficients */ const SKP_int order /* I: Prediction order */ ) { SKP_int k, n, headrm; SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16, tmp_QA; SKP_int32 *Aold_QA, *Anew_QA; Anew_QA = A_QA[ order & 1 ]; *invGain_Q30 = ( 1 << 30 ); for( k = order - 1; k > 0; k-- ) { /* Check for stability */ if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { return 1; } /* Set RC equal to negated AR coef */ rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA ); /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */ rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 ); SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) ); /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */ rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 ); /* 16 = 46 - 30 */ /* Update inverse gain */ /* invGain_Q30 range: [ 0 : 2^30 ] */ *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 ); SKP_assert( *invGain_Q30 >= 0 ); SKP_assert( *invGain_Q30 <= ( 1 << 30 ) ); /* Swap pointers */ Aold_QA = Anew_QA; Anew_QA = A_QA[ k & 1 ]; /* Update AR coefficient */ headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1; rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm ); /* Q: 16 + headrm */ for( n = 0; n < k; n++ ) { tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 ); Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm ); } } /* Check for stability */ if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { return 1; } /* Set RC equal to negated AR coef */ rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA ); /* Range: [ 1 : 2^30 ] */ rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 ); /* Update inverse gain */ /* Range: [ 0 : 2^30 ] */ *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 ); SKP_assert( *invGain_Q30 >= 0 ); SKP_assert( *invGain_Q30 <= 1<<30 ); return 0; } /* For input in Q12 domain */ SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */ const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */ const SKP_int order /* I: Prediction order */ ) { SKP_int k; SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ]; SKP_int32 *Anew_QA; Anew_QA = Atmp_QA[ order & 1 ]; /* Increase Q domain of the AR coefficients */ for( k = 0; k < order; k++ ) { Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 ); } return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order ); } /* For input in Q24 domain */ SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */ const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */ const SKP_int order /* I: Prediction order */ ) { SKP_int k; SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ]; SKP_int32 *Anew_QA; Anew_QA = Atmp_QA[ order & 1 ]; /* Increase Q domain of the AR coefficients */ for( k = 0; k < order; k++ ) { Anew_QA[ k ] = SKP_RSHIFT_ROUND( A_Q24[ k ], 24 - QA ); } return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order ); } ================================================ FILE: app/jni/SKP_Silk_LPC_synthesis_filter.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_LPC_synthesis_filter.c * * Coefficients are in Q12 * * * * even order AR filter * * */ #include "SKP_Silk_SigProc_FIX.h" /* even order AR filter */ void SKP_Silk_LPC_synthesis_filter( const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [Order] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len, /* I: signal length */ const SKP_int Order /* I: filter order, must be even */ ) { SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 ); SKP_int32 SA, SB, out32_Q10, out32; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 Atmp, A_align_Q12[ SKP_Silk_MAX_ORDER_LPC >> 1 ]; /* combine two A_Q12 values and ensure 32-bit alignment */ for( k = 0; k < Order_half; k++ ) { idx = SKP_SMULBB( 2, k ); A_align_Q12[ k ] = ( ( ( SKP_int32 )A_Q12[ idx ] ) & 0x0000ffff ) | SKP_LSHIFT( ( SKP_int32 )A_Q12[ idx + 1 ], 16 ); } #endif /* Order must be even */ SKP_assert( 2 * Order_half == Order ); /* S[] values are in Q14 */ for( k = 0; k < len; k++ ) { SA = S[ Order - 1 ]; out32_Q10 = 0; for( j = 0; j < ( Order_half - 1 ); j++ ) { idx = SKP_SMULBB( 2, j ) + 1; #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* multiply-add two prediction coefficients for each loop */ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ Atmp = A_align_Q12[ j ]; SB = S[ Order - 1 - idx ]; S[ Order - 1 - idx ] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp ); SA = S[ Order - 2 - idx ]; S[ Order - 2 - idx ] = SB; #else SB = S[ Order - 1 - idx ]; S[ Order - 1 - idx ] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] ); out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] ); SA = S[ Order - 2 - idx ]; S[ Order - 2 - idx ] = SB; #endif } #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* unrolled loop: epilog */ Atmp = A_align_Q12[ Order_half - 1 ]; SB = S[ 0 ]; S[ 0 ] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp ); #else /* unrolled loop: epilog */ SB = S[ 0 ]; S[ 0 ] = SA; out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] ); out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] ); #endif /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) ); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 ); /* saturate output */ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 ); /* move result into delay line */ S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 ); } } ================================================ FILE: app/jni/SKP_Silk_LPC_synthesis_order16.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_LPC_synthesis_order16.c * * Coefficients are in Q12 * * * * 16th order AR filter * * */ #include "SKP_Silk_SigProc_FIX.h" /* 16th order AR filter */ void SKP_Silk_LPC_synthesis_order16(const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [16] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len /* I: signal length, must be multiple of 16 */ ) { SKP_int k; SKP_int32 SA, SB, out32_Q10, out32; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 Atmp, A_align_Q12[ 8 ]; /* combine two A_Q12 values and ensure 32-bit alignment */ for( k = 0; k < 8; k++ ) { A_align_Q12[ k ] = ( ( ( SKP_int32 )A_Q12[ 2 * k ] ) & 0x0000ffff ) | SKP_LSHIFT( ( SKP_int32 )A_Q12[ 2 * k + 1 ], 16 ); } /* S[] values are in Q14 */ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ for( k = 0; k < len; k++ ) { /* unrolled loop: prolog */ /* multiply-add two prediction coefficients per iteration */ SA = S[ 15 ]; Atmp = A_align_Q12[ 0 ]; SB = S[ 14 ]; S[ 14 ] = SA; out32_Q10 = SKP_SMULWB( SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 13 ]; S[ 13 ] = SB; /* unrolled loop: main loop */ Atmp = A_align_Q12[ 1 ]; SB = S[ 12 ]; S[ 12 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 11 ]; S[ 11 ] = SB; Atmp = A_align_Q12[ 2 ]; SB = S[ 10 ]; S[ 10 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 9 ]; S[ 9 ] = SB; Atmp = A_align_Q12[ 3 ]; SB = S[ 8 ]; S[ 8 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 7 ]; S[ 7 ] = SB; Atmp = A_align_Q12[ 4 ]; SB = S[ 6 ]; S[ 6 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 5 ]; S[ 5 ] = SB; Atmp = A_align_Q12[ 5 ]; SB = S[ 4 ]; S[ 4 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 3 ]; S[ 3 ] = SB; Atmp = A_align_Q12[ 6 ]; SB = S[ 2 ]; S[ 2 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); SA = S[ 1 ]; S[ 1 ] = SB; /* unrolled loop: epilog */ Atmp = A_align_Q12[ 7 ]; SB = S[ 0 ]; S[ 0 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp ); out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp ); /* unrolled loop: end */ /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) ); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 ); /* saturate output */ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 ); /* move result into delay line */ S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 ); } #else for( k = 0; k < len; k++ ) { /* unrolled loop: prolog */ /* multiply-add two prediction coefficients per iteration */ SA = S[ 15 ]; SB = S[ 14 ]; S[ 14 ] = SA; out32_Q10 = SKP_SMULWB( SA, A_Q12[ 0 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] ); SA = S[ 13 ]; S[ 13 ] = SB; /* unrolled loop: main loop */ SB = S[ 12 ]; S[ 12 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] ); SA = S[ 11 ]; S[ 11 ] = SB; SB = S[ 10 ]; S[ 10 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] ); SA = S[ 9 ]; S[ 9 ] = SB; SB = S[ 8 ]; S[ 8 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] ); SA = S[ 7 ]; S[ 7 ] = SB; SB = S[ 6 ]; S[ 6 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] ); SA = S[ 5 ]; S[ 5 ] = SB; SB = S[ 4 ]; S[ 4 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] ); SA = S[ 3 ]; S[ 3 ] = SB; SB = S[ 2 ]; S[ 2 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] ); SA = S[ 1 ]; S[ 1 ] = SB; /* unrolled loop: epilog */ SB = S[ 0 ]; S[ 0 ] = SA; out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] ); out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] ); /* unrolled loop: end */ /* apply gain to excitation signal and add to prediction */ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) ); /* scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 ); /* saturate output */ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 ); /* move result into delay line */ S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 ); } #endif } ================================================ FILE: app/jni/SKP_Silk_LP_variable_cutoff.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* Elliptic/Cauer filters designed with 0.1 dB passband ripple, 80 dB minimum stopband attenuation, and [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ #include "SKP_Silk_main.h" #if SWITCH_TRANSITION_FILTERING /* Helper function, that interpolates the filter taps */ SKP_INLINE void SKP_Silk_LP_interpolate_filter_taps( SKP_int32 B_Q28[ TRANSITION_NB ], SKP_int32 A_Q28[ TRANSITION_NA ], const SKP_int ind, const SKP_int32 fac_Q16 ) { SKP_int nb, na; if( ind < TRANSITION_INT_NUM - 1 ) { if( fac_Q16 > 0 ) { if( fac_Q16 == SKP_SAT16( fac_Q16 ) ) { /* fac_Q16 is in range of a 16-bit int */ /* Piece-wise linear interpolation of B and A */ for( nb = 0; nb < TRANSITION_NB; nb++ ) { B_Q28[ nb ] = SKP_SMLAWB( SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ], SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ], fac_Q16 ); } for( na = 0; na < TRANSITION_NA; na++ ) { A_Q28[ na ] = SKP_SMLAWB( SKP_Silk_Transition_LP_A_Q28[ ind ][ na ], SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - SKP_Silk_Transition_LP_A_Q28[ ind ][ na ], fac_Q16 ); } } else if( fac_Q16 == ( 1 << 15 ) ) { /* Neither fac_Q16 nor ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */ /* Piece-wise linear interpolation of B and A */ for( nb = 0; nb < TRANSITION_NB; nb++ ) { B_Q28[ nb ] = SKP_RSHIFT( SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] + SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], 1 ); } for( na = 0; na < TRANSITION_NA; na++ ) { A_Q28[ na ] = SKP_RSHIFT( SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] + SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], 1 ); } } else { /* ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */ SKP_assert( ( ( 1 << 16 ) - fac_Q16 ) == SKP_SAT16( ( ( 1 << 16 ) - fac_Q16) ) ); /* Piece-wise linear interpolation of B and A */ for( nb = 0; nb < TRANSITION_NB; nb++ ) { B_Q28[ nb ] = SKP_SMLAWB( SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] - SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], ( 1 << 16 ) - fac_Q16 ); } for( na = 0; na < TRANSITION_NA; na++ ) { A_Q28[ na ] = SKP_SMLAWB( SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] - SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ], ( 1 << 16 ) - fac_Q16 ); } } } else { SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( SKP_int32 ) ); SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( SKP_int32 ) ); } } else { SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( SKP_int32 ) ); SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( SKP_int32 ) ); } } /* Low-pass filter with variable cutoff frequency based on */ /* piece-wise linear interpolation between elliptic filters */ /* Start by setting psEncC->transition_frame_no = 1; */ /* Deactivate by setting psEncC->transition_frame_no = 0; */ void SKP_Silk_LP_variable_cutoff( SKP_Silk_LP_state *psLP, /* I/O LP filter state */ SKP_int16 *out, /* O Low-pass filtered output signal */ const SKP_int16 *in, /* I Input signal */ const SKP_int frame_length /* I Frame length */ ) { SKP_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0; SKP_int ind = 0; SKP_assert( psLP->transition_frame_no >= 0 ); SKP_assert( ( ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_DOWN ) && ( psLP->mode == 0 ) ) || ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_UP ) && ( psLP->mode == 1 ) ) ) ); /* Interpolate filter coefficients if needed */ if( psLP->transition_frame_no > 0 ) { if( psLP->mode == 0 ) { if( psLP->transition_frame_no < TRANSITION_FRAMES_DOWN ) { /* Calculate index and interpolation factor for interpolation */ #if( TRANSITION_INT_STEPS_DOWN == 32 ) fac_Q16 = SKP_LSHIFT( psLP->transition_frame_no, 16 - 5 ); #else fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_DOWN ); #endif ind = SKP_RSHIFT( fac_Q16, 16 ); fac_Q16 -= SKP_LSHIFT( ind, 16 ); SKP_assert( ind >= 0 ); SKP_assert( ind < TRANSITION_INT_NUM ); /* Interpolate filter coefficients */ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); /* Increment transition frame number for next frame */ psLP->transition_frame_no++; } else { SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_DOWN ); /* End of transition phase */ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, TRANSITION_INT_NUM - 1, 0 ); } } else { SKP_assert( psLP->mode == 1 ); if( psLP->transition_frame_no < TRANSITION_FRAMES_UP ) { /* Calculate index and interpolation factor for interpolation */ #if( TRANSITION_INT_STEPS_UP == 64 ) fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 - 6 ); #else fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_UP ); #endif ind = SKP_RSHIFT( fac_Q16, 16 ); fac_Q16 -= SKP_LSHIFT( ind, 16 ); SKP_assert( ind >= 0 ); SKP_assert( ind < TRANSITION_INT_NUM ); /* Interpolate filter coefficients */ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); /* Increment transition frame number for next frame */ psLP->transition_frame_no++; } else { SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_UP ); /* End of transition phase */ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, 0, 0 ); } } } if( psLP->transition_frame_no > 0 ) { /* ARMA low-pass filtering */ SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 ); SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psLP->In_LP_State, out, frame_length ); } else { /* Instead of using the filter, copy input directly to output */ SKP_memcpy( out, in, frame_length * sizeof( SKP_int16 ) ); } } #endif ================================================ FILE: app/jni/SKP_Silk_LSF_cos_table.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" // Q12 values (even) const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[LSF_COS_TAB_SZ_FIX + 1] = { 8192, 8190, 8182, 8170, 8152, 8130, 8104, 8072, 8034, 7994, 7946, 7896, 7840, 7778, 7714, 7644, 7568, 7490, 7406, 7318, 7226, 7128, 7026, 6922, 6812, 6698, 6580, 6458, 6332, 6204, 6070, 5934, 5792, 5648, 5502, 5352, 5198, 5040, 4880, 4718, 4552, 4382, 4212, 4038, 3862, 3684, 3502, 3320, 3136, 2948, 2760, 2570, 2378, 2186, 1990, 1794, 1598, 1400, 1202, 1002, 802, 602, 402, 202, 0, -202, -402, -602, -802, -1002, -1202, -1400, -1598, -1794, -1990, -2186, -2378, -2570, -2760, -2948, -3136, -3320, -3502, -3684, -3862, -4038, -4212, -4382, -4552, -4718, -4880, -5040, -5198, -5352, -5502, -5648, -5792, -5934, -6070, -6204, -6332, -6458, -6580, -6698, -6812, -6922, -7026, -7128, -7226, -7318, -7406, -7490, -7568, -7644, -7714, -7778, -7840, -7896, -7946, -7994, -8034, -8072, -8104, -8130, -8152, -8170, -8182, -8190, -8192 }; ================================================ FILE: app/jni/SKP_Silk_LTP_analysis_filter_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" void SKP_Silk_LTP_analysis_filter_FIX( SKP_int16 *LTP_res, /* O: LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length ) */ const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each NB_SUBFR subframe */ const SKP_int pitchL[ NB_SUBFR ], /* I: Pitch lag, one for each subframe */ const SKP_int32 invGains_Q16[ NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */ const SKP_int subfr_length, /* I: Length of each subframe */ const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */ ) { const SKP_int16 *x_ptr, *x_lag_ptr; SKP_int16 Btmp_Q14[ LTP_ORDER ]; SKP_int16 *LTP_res_ptr; SKP_int k, i, j; SKP_int32 LTP_est; x_ptr = x; LTP_res_ptr = LTP_res; for( k = 0; k < NB_SUBFR; k++ ) { x_lag_ptr = x_ptr - pitchL[ k ]; for( i = 0; i < LTP_ORDER; i++ ) { Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ]; } /* LTP analysis FIR filter */ for( i = 0; i < subfr_length + pre_length; i++ ) { LTP_res_ptr[ i ] = x_ptr[ i ]; /* Long-term prediction */ LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); for( j = 1; j < LTP_ORDER; j++ ) { LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] ); } LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0 /* Subtract long-term prediction */ LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est ); /* Scale residual */ LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); x_lag_ptr++; } /* Update pointers */ LTP_res_ptr += subfr_length + pre_length; x_ptr += subfr_length; } } ================================================ FILE: app/jni/SKP_Silk_LTP_scale_ctrl_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #define NB_THRESHOLDS 11 /* Table containing trained thresholds for LTP scaling */ static const SKP_int16 LTPScaleThresholds_Q15[ NB_THRESHOLDS ] = { 31129, 26214, 16384, 13107, 9830, 6554, 4915, 3276, 2621, 2458, 0 }; void SKP_Silk_LTP_scale_ctrl_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control FIX */ ) { SKP_int round_loss, frames_per_packet; SKP_int g_out_Q5, g_limit_Q15, thrld1_Q15, thrld2_Q15; /* 1st order high-pass filter */ psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - psEnc->prevLTPredCodGain_Q7, 0 ) + SKP_RSHIFT_ROUND( psEnc->HPLTPredCodGain_Q7, 1 ); psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7; /* combine input and filtered input */ g_out_Q5 = SKP_RSHIFT_ROUND( SKP_RSHIFT( psEncCtrl->LTPredCodGain_Q7, 1 ) + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ), 3 ); g_limit_Q15 = SKP_Silk_sigm_Q15( g_out_Q5 - ( 3 << 5 ) ); /* Default is minimum scaling */ psEncCtrl->sCmn.LTP_scaleIndex = 0; /* Round the loss measure to whole pct */ round_loss = ( SKP_int )psEnc->sCmn.PacketLoss_perc; /* Only scale if first frame in packet 0% */ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) { frames_per_packet = SKP_DIV32_16( psEnc->sCmn.PacketSize_ms, FRAME_LENGTH_MS ); round_loss += frames_per_packet - 1; thrld1_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss, NB_THRESHOLDS - 1 ) ]; thrld2_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss + 1, NB_THRESHOLDS - 1 ) ]; if( g_limit_Q15 > thrld1_Q15 ) { /* Maximum scaling */ psEncCtrl->sCmn.LTP_scaleIndex = 2; } else if( g_limit_Q15 > thrld2_Q15 ) { /* Medium scaling */ psEncCtrl->sCmn.LTP_scaleIndex = 1; } } psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ]; } ================================================ FILE: app/jni/SKP_Silk_MA.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_MA.c * * * * Variable order MA filter * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" #if EMBEDDED_ARM<5 /* Variable order MA prediction error filter */ void SKP_Silk_MA_Prediction( const SKP_int16 *in, /* I: Input signal */ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */ SKP_int32 *S, /* I/O: State vector [order] */ SKP_int16 *out, /* O: Output signal */ const SKP_int32 len, /* I: Signal length */ const SKP_int32 order /* I: Filter order */ ) { SKP_int k, d, in16; SKP_int32 out32; for( k = 0; k < len; k++ ) { in16 = in[ k ]; out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ]; out32 = SKP_RSHIFT_ROUND( out32, 12 ); for( d = 0; d < order - 1; d++ ) { S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] ); } S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] ); /* Limit */ out[ k ] = (SKP_int16)SKP_SAT16( out32 ); } } #endif #if EMBEDDED_ARM<5 void SKP_Silk_LPC_analysis_filter( const SKP_int16 *in, /* I: Input signal */ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */ SKP_int16 *S, /* I/O: State vector [order] */ SKP_int16 *out, /* O: Output signal */ const SKP_int32 len, /* I: Signal length */ const SKP_int32 Order /* I: Filter order */ ) { SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 ); SKP_int32 out32_Q12, out32; SKP_int16 SA, SB; /* Order must be even */ SKP_assert( 2 * Order_half == Order ); /* S[] values are in Q0 */ for( k = 0; k < len; k++ ) { SA = S[ 0 ]; out32_Q12 = 0; for( j = 0; j < ( Order_half - 1 ); j++ ) { idx = SKP_SMULBB( 2, j ) + 1; /* Multiply-add two prediction coefficients for each loop */ SB = S[ idx ]; S[ idx ] = SA; out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ idx - 1 ] ); out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ idx ] ); SA = S[ idx + 1 ]; S[ idx + 1 ] = SB; } /* Unrolled loop: epilog */ SB = S[ Order - 1 ]; S[ Order - 1 ] = SA; out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ Order - 2 ] ); out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ Order - 1 ] ); /* Subtract prediction */ out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 ); /* Scale to Q0 */ out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 ); /* Saturate output */ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 ); /* Move input line */ S[ 0 ] = in[ k ]; } } #endif ================================================ FILE: app/jni/SKP_Silk_NLSF2A.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* conversion between prediction filter coefficients and LSFs */ /* order should be even */ /* a piecewise linear approximation maps LSF <-> cos(LSF) */ /* therefore the result is not accurate LSFs, but the two */ /* function are accurate inverses of each other */ #include "SKP_Silk_SigProc_FIX.h" /* helper function for NLSF2A(..) */ SKP_INLINE void SKP_Silk_NLSF2A_find_poly( SKP_int32 *out, /* o intermediate polynomial, Q20 */ const SKP_int32 *cLSF, /* i vector of interleaved 2*cos(LSFs), Q20 */ SKP_int dd /* i polynomial order (= 1/2 * filter order) */ ) { SKP_int k, n; SKP_int32 ftmp; out[0] = SKP_LSHIFT( 1, 20 ); out[1] = -cLSF[0]; for( k = 1; k < dd; k++ ) { ftmp = cLSF[2*k]; // Q20 out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 ); for( n = k; n > 1; n-- ) { out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 ); } out[1] -= ftmp; } } /* compute whitening filter coefficients from normalized line spectral frequencies */ void SKP_Silk_NLSF2A( SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */ const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */ const SKP_int d /* i filter order (should be even) */ ) { SKP_int k, i, dd; SKP_int32 cos_LSF_Q20[SKP_Silk_MAX_ORDER_LPC]; SKP_int32 P[SKP_Silk_MAX_ORDER_LPC/2+1], Q[SKP_Silk_MAX_ORDER_LPC/2+1]; SKP_int32 Ptmp, Qtmp; SKP_int32 f_int; SKP_int32 f_frac; SKP_int32 cos_val, delta; SKP_int32 a_int32[SKP_Silk_MAX_ORDER_LPC]; SKP_int32 maxabs, absval, idx=0, sc_Q16; SKP_assert(LSF_COS_TAB_SZ_FIX == 128); /* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */ for( k = 0; k < d; k++ ) { SKP_assert(NLSF[k] >= 0 ); SKP_assert(NLSF[k] <= 32767 ); /* f_int on a scale 0-127 (rounded down) */ f_int = SKP_RSHIFT( NLSF[k], 15 - 7 ); /* f_frac, range: 0..255 */ f_frac = NLSF[k] - SKP_LSHIFT( f_int, 15 - 7 ); SKP_assert(f_int >= 0); SKP_assert(f_int < LSF_COS_TAB_SZ_FIX ); /* Read start and end value from table */ cos_val = SKP_Silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */ delta = SKP_Silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */ /* Linear interpolation */ cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */ } dd = SKP_RSHIFT( d, 1 ); /* generate even and odd polynomials using convolution */ SKP_Silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd ); SKP_Silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd ); /* convert even and odd polynomials to SKP_int32 Q12 filter coefs */ for( k = 0; k < dd; k++ ) { Ptmp = P[k+1] + P[k]; Qtmp = Q[k+1] - Q[k]; /* the Ptmp and Qtmp values at this stage need to fit in int32 */ a_int32[k] = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */ a_int32[d-k-1] = SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */ } /* Limit the maximum absolute value of the prediction coefficients */ for( i = 0; i < 10; i++ ) { /* Find maximum absolute value and its index */ maxabs = 0; for( k = 0; k < d; k++ ) { absval = SKP_abs( a_int32[k] ); if( absval > maxabs ) { maxabs = absval; idx = k; } } if( maxabs > SKP_int16_MAX ) { /* Reduce magnitude of prediction coefficients */ maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369 sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ), SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) ); SKP_Silk_bwexpander_32( a_int32, d, sc_Q16 ); } else { break; } } /* Reached the last iteration */ if( i == 10 ) { SKP_assert(0); for( k = 0; k < d; k++ ) { a_int32[k] = SKP_SAT16( a_int32[k] ); } } /* Return as SKP_int16 Q12 coefficients */ for( k = 0; k < d; k++ ) { a[k] = (SKP_int16)a_int32[k]; } } ================================================ FILE: app/jni/SKP_Silk_NLSF2A_stable.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Convert NLSF parameters to stable AR prediction filter coefficients */ void SKP_Silk_NLSF2A_stable( SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */ const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */ const SKP_int LPC_order /* I LPC/LSF order */ ) { SKP_int i; SKP_int32 invGain_Q30; SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order ); /* Ensure stable LPCs */ for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) { SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015 */ } else { break; } } /* Reached the last iteration */ if( i == MAX_LPC_STABILIZE_ITERATIONS ) { SKP_assert( 0 ); for( i = 0; i < LPC_order; i++ ) { pAR_Q12[ i ] = 0; } } } ================================================ FILE: app/jni/SKP_Silk_NLSF_MSVQ_decode.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* NLSF vector decoder */ void SKP_Silk_NLSF_MSVQ_decode( SKP_int *pNLSF_Q15, /* O Pointer to decoded output vector [LPC_ORDER x 1] */ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */ const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */ const SKP_int LPC_order /* I LPC order used */ ) { const SKP_int16 *pCB_element; SKP_int s; SKP_int i; /* Check that each index is within valid range */ SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB->CBStages[ 0 ].nVectors ); /* Point to the first vector element */ pCB_element = &psNLSF_CB->CBStages[ 0 ].CB_NLSF_Q15[ SKP_MUL( NLSFIndices[ 0 ], LPC_order ) ]; /* Initialize with the codebook vector from stage 0 */ for( i = 0; i < LPC_order; i++ ) { pNLSF_Q15[ i ] = ( SKP_int )pCB_element[ i ]; } for( s = 1; s < psNLSF_CB->nStages; s++ ) { /* Check that each index is within valid range */ SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB->CBStages[ s ].nVectors ); if( LPC_order == 16 ) { /* Point to the first vector element */ pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_LSHIFT( NLSFIndices[ s ], 4 ) ]; /* Add the codebook vector from the current stage */ pNLSF_Q15[ 0 ] += pCB_element[ 0 ]; pNLSF_Q15[ 1 ] += pCB_element[ 1 ]; pNLSF_Q15[ 2 ] += pCB_element[ 2 ]; pNLSF_Q15[ 3 ] += pCB_element[ 3 ]; pNLSF_Q15[ 4 ] += pCB_element[ 4 ]; pNLSF_Q15[ 5 ] += pCB_element[ 5 ]; pNLSF_Q15[ 6 ] += pCB_element[ 6 ]; pNLSF_Q15[ 7 ] += pCB_element[ 7 ]; pNLSF_Q15[ 8 ] += pCB_element[ 8 ]; pNLSF_Q15[ 9 ] += pCB_element[ 9 ]; pNLSF_Q15[ 10 ] += pCB_element[ 10 ]; pNLSF_Q15[ 11 ] += pCB_element[ 11 ]; pNLSF_Q15[ 12 ] += pCB_element[ 12 ]; pNLSF_Q15[ 13 ] += pCB_element[ 13 ]; pNLSF_Q15[ 14 ] += pCB_element[ 14 ]; pNLSF_Q15[ 15 ] += pCB_element[ 15 ]; } else { /* Point to the first vector element */ pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_SMULBB( NLSFIndices[ s ], LPC_order ) ]; /* Add the codebook vector from the current stage */ for( i = 0; i < LPC_order; i++ ) { pNLSF_Q15[ i ] += pCB_element[ i ]; } } } /* NLSF stabilization */ SKP_Silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->NDeltaMin_Q15, LPC_order ); } ================================================ FILE: app/jni/SKP_Silk_NLSF_MSVQ_encode_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /***********************/ /* NLSF vector encoder */ /***********************/ void SKP_Silk_NLSF_MSVQ_encode_FIX( SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */ SKP_int *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const SKP_int *pNLSF_q_Q15_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */ const SKP_int *pW_Q6, /* I NLSF weight vector [ LPC_ORDER ] */ const SKP_int NLSF_mu_Q15, /* I Rate weight for the RD optimization */ const SKP_int NLSF_mu_fluc_red_Q16, /* I Fluctuation reduction error weight */ const SKP_int NLSF_MSVQ_Survivors, /* I Max survivors from each stage */ const SKP_int LPC_order, /* I LPC order */ const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */ ) { SKP_int i, s, k, cur_survivors = 0, prev_survivors, min_survivors, input_index, cb_index, bestIndex; SKP_int32 rateDistThreshold_Q18; #if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 ) SKP_int32 se_Q15, wsse_Q20, bestRateDist_Q20; #endif #if( LOW_COMPLEXITY_ONLY == 1 ) SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE ]; SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ]; SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ]; SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ]; #else SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED ]; SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS ]; SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS ]; SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS ]; SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ]; SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ]; #endif const SKP_int *pConstInt; SKP_int *pInt; const SKP_int16 *pCB_element; const SKP_Silk_NLSF_CBS *pCurrentCBStage; #ifdef USE_UNQUANTIZED_LSFS SKP_int NLSF_orig[ MAX_LPC_ORDER ]; SKP_memcpy( NLSF_orig, pNLSF_Q15, LPC_order * sizeof( SKP_int ) ); #endif SKP_assert( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS ); SKP_assert( ( LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) ); /****************************************************/ /* Tree search for the multi-stage vector quantizer */ /****************************************************/ /* Clear accumulated rates */ SKP_memset( pRate_Q5, 0, NLSF_MSVQ_Survivors * sizeof( SKP_int32 ) ); /* Copy NLSFs into residual signal vector */ for( i = 0; i < LPC_order; i++ ) { pRes_Q15[ i ] = pNLSF_Q15[ i ]; } /* Set first stage values */ prev_survivors = 1; /* Minimum number of survivors */ min_survivors = NLSF_MSVQ_Survivors / 2; /* Loop over all stages */ for( s = 0; s < psNLSF_CB->nStages; s++ ) { /* Set a pointer to the current stage codebook */ pCurrentCBStage = &psNLSF_CB->CBStages[ s ]; /* Calculate the number of survivors in the current stage */ cur_survivors = SKP_min_32( NLSF_MSVQ_Survivors, SKP_SMULBB( prev_survivors, pCurrentCBStage->nVectors ) ); #if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 ) /* Find a single best survivor in the last stage, if we */ /* do not need candidates for fluctuation reduction */ if( s == psNLSF_CB->nStages - 1 ) { cur_survivors = 1; } #endif /* Nearest neighbor clustering for multiple input data vectors */ SKP_Silk_NLSF_VQ_rate_distortion_FIX( pRateDist_Q18, pCurrentCBStage, pRes_Q15, pW_Q6, pRate_Q5, NLSF_mu_Q15, prev_survivors, LPC_order ); /* Sort the rate-distortion errors */ SKP_Silk_insertion_sort_increasing( pRateDist_Q18, pTempIndices, prev_survivors * pCurrentCBStage->nVectors, cur_survivors ); /* Discard survivors with rate-distortion values too far above the best one */ if( pRateDist_Q18[ 0 ] < SKP_int32_MAX / MAX_NLSF_MSVQ_SURVIVORS ) { rateDistThreshold_Q18 = SKP_SMLAWB( pRateDist_Q18[ 0 ], SKP_MUL( NLSF_MSVQ_Survivors, pRateDist_Q18[ 0 ] ), SKP_FIX_CONST( NLSF_MSVQ_SURV_MAX_REL_RD, 16 ) ); while( pRateDist_Q18[ cur_survivors - 1 ] > rateDistThreshold_Q18 && cur_survivors > min_survivors ) { cur_survivors--; } } /* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */ for( k = 0; k < cur_survivors; k++ ) { if( s > 0 ) { /* Find the indices of the input and the codebook vector */ if( pCurrentCBStage->nVectors == 8 ) { input_index = SKP_RSHIFT( pTempIndices[ k ], 3 ); cb_index = pTempIndices[ k ] & 7; } else { input_index = SKP_DIV32_16( pTempIndices[ k ], pCurrentCBStage->nVectors ); cb_index = pTempIndices[ k ] - SKP_SMULBB( input_index, pCurrentCBStage->nVectors ); } } else { /* Find the indices of the input and the codebook vector */ input_index = 0; cb_index = pTempIndices[ k ]; } /* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */ pConstInt = &pRes_Q15[ SKP_SMULBB( input_index, LPC_order ) ]; pCB_element = &pCurrentCBStage->CB_NLSF_Q15[ SKP_SMULBB( cb_index, LPC_order ) ]; pInt = &pRes_new_Q15[ SKP_SMULBB( k, LPC_order ) ]; for( i = 0; i < LPC_order; i++ ) { pInt[ i ] = pConstInt[ i ] - ( SKP_int )pCB_element[ i ]; } /* Update accumulated rate for stage 1 to the current */ pRate_new_Q5[ k ] = pRate_Q5[ input_index ] + pCurrentCBStage->Rates_Q5[ cb_index ]; /* Copy paths from previous matrix, starting with the best path */ pConstInt = &pPath[ SKP_SMULBB( input_index, psNLSF_CB->nStages ) ]; pInt = &pPath_new[ SKP_SMULBB( k, psNLSF_CB->nStages ) ]; for( i = 0; i < s; i++ ) { pInt[ i ] = pConstInt[ i ]; } /* Write the current stage indices for the 'cur_survivors' to the best path matrix */ pInt[ s ] = cb_index; } if( s < psNLSF_CB->nStages - 1 ) { /* Copy NLSF residual matrix for next stage */ SKP_memcpy( pRes_Q15, pRes_new_Q15, SKP_SMULBB( cur_survivors, LPC_order ) * sizeof( SKP_int ) ); /* Copy rate vector for next stage */ SKP_memcpy( pRate_Q5, pRate_new_Q5, cur_survivors * sizeof( SKP_int32 ) ); /* Copy best path matrix for next stage */ SKP_memcpy( pPath, pPath_new, SKP_SMULBB( cur_survivors, psNLSF_CB->nStages ) * sizeof( SKP_int ) ); } prev_survivors = cur_survivors; } /* (Preliminary) index of the best survivor, later to be decoded */ bestIndex = 0; #if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 ) /******************************/ /* NLSF fluctuation reduction */ /******************************/ if( deactivate_fluc_red != 1 ) { /* Search among all survivors, now taking also weighted fluctuation errors into account */ bestRateDist_Q20 = SKP_int32_MAX; for( s = 0; s < cur_survivors; s++ ) { /* Decode survivor to compare with previous quantized NLSF vector */ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, &pPath_new[ SKP_SMULBB( s, psNLSF_CB->nStages ) ], LPC_order ); /* Compare decoded NLSF vector with the previously quantized vector */ wsse_Q20 = 0; for( i = 0; i < LPC_order; i += 2 ) { /* Compute weighted squared quantization error for index i */ se_Q15 = pNLSF_Q15[ i ] - pNLSF_q_Q15_prev[ i ]; // range: [ -32767 : 32767 ] wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i ] ); /* Compute weighted squared quantization error for index i + 1 */ se_Q15 = pNLSF_Q15[ i + 1 ] - pNLSF_q_Q15_prev[ i + 1 ]; // range: [ -32767 : 32767 ] wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i + 1 ] ); } SKP_assert( wsse_Q20 >= 0 ); /* Add the fluctuation reduction penalty to the rate distortion error */ wsse_Q20 = SKP_ADD_POS_SAT32( pRateDist_Q18[ s ], SKP_SMULWB( wsse_Q20, NLSF_mu_fluc_red_Q16 ) ); /* Keep index of best survivor */ if( wsse_Q20 < bestRateDist_Q20 ) { bestRateDist_Q20 = wsse_Q20; bestIndex = s; } } } #endif /* Copy best path to output argument */ SKP_memcpy( NLSFIndices, &pPath_new[ SKP_SMULBB( bestIndex, psNLSF_CB->nStages ) ], psNLSF_CB->nStages * sizeof( SKP_int ) ); /* Decode and stabilize the best survivor */ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, LPC_order ); #ifdef USE_UNQUANTIZED_LSFS SKP_memcpy( pNLSF_Q15, NLSF_orig, LPC_order * sizeof( SKP_int ) ); #endif } ================================================ FILE: app/jni/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Rate-Distortion calculations for multiple input data vectors */ void SKP_Silk_NLSF_VQ_rate_distortion_FIX( SKP_int32 *pRD_Q20, /* O Rate-distortion values [psNLSF_CBS->nVectors*N] */ const SKP_Silk_NLSF_CBS *psNLSF_CBS, /* I NLSF codebook stage struct */ const SKP_int *in_Q15, /* I Input vectors to be quantized */ const SKP_int *w_Q6, /* I Weight vector */ const SKP_int32 *rate_acc_Q5, /* I Accumulated rates from previous stage */ const SKP_int mu_Q15, /* I Weight between weighted error and rate */ const SKP_int N, /* I Number of input vectors to be quantized */ const SKP_int LPC_order /* I LPC order */ ) { SKP_int i, n; SKP_int32 *pRD_vec_Q20; /* Compute weighted quantization errors for all input vectors over one codebook stage */ SKP_Silk_NLSF_VQ_sum_error_FIX( pRD_Q20, in_Q15, w_Q6, psNLSF_CBS->CB_NLSF_Q15, N, psNLSF_CBS->nVectors, LPC_order ); /* Loop over input vectors */ pRD_vec_Q20 = pRD_Q20; for( n = 0; n < N; n++ ) { /* Add rate cost to error for each codebook vector */ for( i = 0; i < psNLSF_CBS->nVectors; i++ ) { SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] >= 0 ); SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] <= SKP_int16_MAX ); pRD_vec_Q20[ i ] = SKP_SMLABB( pRD_vec_Q20[ i ], rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ], mu_Q15 ); SKP_assert( pRD_vec_Q20[ i ] >= 0 ); } pRD_vec_Q20 += psNLSF_CBS->nVectors; } } ================================================ FILE: app/jni/SKP_Silk_NLSF_VQ_sum_error_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #if (!defined(__mips__)) && (EMBEDDED_ARM < 6) /* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */ void SKP_Silk_NLSF_VQ_sum_error_FIX( SKP_int32 *err_Q20, /* O Weighted quantization errors [N*K] */ const SKP_int *in_Q15, /* I Input vectors to be quantized [N*LPC_order] */ const SKP_int *w_Q6, /* I Weighting vectors [N*LPC_order] */ const SKP_int16 *pCB_Q15, /* I Codebook vectors [K*LPC_order] */ const SKP_int N, /* I Number of input vectors */ const SKP_int K, /* I Number of codebook vectors */ const SKP_int LPC_order /* I Number of LPCs */ ) { SKP_int i, n, m; SKP_int32 diff_Q15, sum_error, Wtmp_Q6; SKP_int32 Wcpy_Q6[ MAX_LPC_ORDER / 2 ]; const SKP_int16 *cb_vec_Q15; SKP_assert( LPC_order <= 16 ); SKP_assert( ( LPC_order & 1 ) == 0 ); /* Copy to local stack and pack two weights per int32 */ for( m = 0; m < SKP_RSHIFT( LPC_order, 1 ); m++ ) { Wcpy_Q6[ m ] = w_Q6[ 2 * m ] | SKP_LSHIFT( ( SKP_int32 )w_Q6[ 2 * m + 1 ], 16 ); } /* Loop over input vectors */ for( n = 0; n < N; n++ ) { /* Loop over codebook */ cb_vec_Q15 = pCB_Q15; for( i = 0; i < K; i++ ) { sum_error = 0; for( m = 0; m < LPC_order; m += 2 ) { /* Get two weights packed in an int32 */ Wtmp_Q6 = Wcpy_Q6[ SKP_RSHIFT( m, 1 ) ]; /* Compute weighted squared quantization error for index m */ diff_Q15 = in_Q15[ m ] - *cb_vec_Q15++; // range: [ -32767 : 32767 ] sum_error = SKP_SMLAWB( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 ); /* Compute weighted squared quantization error for index m + 1 */ diff_Q15 = in_Q15[m + 1] - *cb_vec_Q15++; // range: [ -32767 : 32767 ] sum_error = SKP_SMLAWT( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 ); } SKP_assert( sum_error >= 0 ); err_Q20[ i ] = sum_error; } err_Q20 += K; in_Q15 += LPC_order; } } #endif ================================================ FILE: app/jni/SKP_Silk_NLSF_VQ_weights_laroia.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" /* R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech, Signal Processing, pp. 641-644, 1991. */ #define Q_OUT 6 #define MIN_NDELTA 3 /* Laroia low complexity NLSF weights */ void SKP_Silk_NLSF_VQ_weights_laroia( SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */ const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */ const SKP_int D /* I: Input vector dimension (even) */ ) { SKP_int k; SKP_int32 tmp1_int, tmp2_int; /* Check that we are guaranteed to end up within the required range */ SKP_assert( D > 0 ); SKP_assert( ( D & 1 ) == 0 ); /* First value */ tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], MIN_NDELTA ); tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int ); tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], MIN_NDELTA ); tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int ); pNLSFW_Q6[ 0 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX ); SKP_assert( pNLSFW_Q6[ 0 ] > 0 ); /* Main loop */ for( k = 1; k < D - 1; k += 2 ) { tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], MIN_NDELTA ); tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int ); pNLSFW_Q6[ k ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX ); SKP_assert( pNLSFW_Q6[ k ] > 0 ); tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], MIN_NDELTA ); tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int ); pNLSFW_Q6[ k + 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX ); SKP_assert( pNLSFW_Q6[ k + 1 ] > 0 ); } /* Last value */ tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], MIN_NDELTA ); tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int ); pNLSFW_Q6[ D - 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX ); SKP_assert( pNLSFW_Q6[ D - 1 ] > 0 ); } ================================================ FILE: app/jni/SKP_Silk_NLSF_stabilize.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* NLSF stabilizer: */ /* */ /* - Moves NLSFs futher apart if they are too close */ /* - Moves NLSFs away from borders if they are too close */ /* - High effort to achieve a modification with minimum */ /* Euclidean distance to input vector */ /* - Output are sorted NLSF coefficients */ /* */ #include "SKP_Silk_SigProc_FIX.h" /* Constant Definitions */ #define MAX_LOOPS 20 /* NLSF stabilizer, for a single input data vector */ void SKP_Silk_NLSF_stabilize( SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */ const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */ const SKP_int L /* I: Number of NLSF parameters in the input vector */ ) { SKP_int center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15; SKP_int32 min_diff_Q15; SKP_int loops; SKP_int i, I=0, k; /* This is necessary to ensure an output within range of a SKP_int16 */ SKP_assert( NDeltaMin_Q15[L] >= 1 ); for( loops = 0; loops < MAX_LOOPS; loops++ ) { /**************************/ /* Find smallest distance */ /**************************/ /* First element */ min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0]; I = 0; /* Middle elements */ for( i = 1; i <= L-1; i++ ) { diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); if( diff_Q15 < min_diff_Q15 ) { min_diff_Q15 = diff_Q15; I = i; } } /* Last element */ diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] ); if( diff_Q15 < min_diff_Q15 ) { min_diff_Q15 = diff_Q15; I = L; } /***************************************************/ /* Now check if the smallest distance non-negative */ /***************************************************/ if (min_diff_Q15 >= 0) { return; } if( I == 0 ) { /* Move away from lower limit */ NLSF_Q15[0] = NDeltaMin_Q15[0]; } else if( I == L) { /* Move away from higher limit */ NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L]; } else { /* Find the lower extreme for the location of the current center frequency */ min_center_Q15 = 0; for( k = 0; k < I; k++ ) { min_center_Q15 += NDeltaMin_Q15[k]; } min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 ); /* Find the upper extreme for the location of the current center frequency */ max_center_Q15 = (1<<15); for( k = L; k > I; k-- ) { max_center_Q15 -= NDeltaMin_Q15[k]; } max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) ); /* Move apart, sorted by value, keeping the same center frequency */ center_freq_Q15 = SKP_LIMIT_32( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ), min_center_Q15, max_center_Q15 ); NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ); NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I]; } } /* Safe and simple fall back method, which is less ideal than the above */ if( loops == MAX_LOOPS ) { /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ /* Worst case: O(n^2) for an inversely sorted array */ SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L); /* First NLSF should be no less than NDeltaMin[0] */ NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] ); /* Keep delta_min distance between the NLSFs */ for( i = 1; i < L; i++ ) NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); /* Keep NDeltaMin distance between the NLSFs */ for( i = L-2; i >= 0; i-- ) NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] ); } } ================================================ FILE: app/jni/SKP_Silk_NSQ.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" SKP_INLINE void SKP_Silk_nsq_scale_states( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ const SKP_int16 x[], /* I input in Q0 */ SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ SKP_int subfr_length, /* I length of input */ const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */ SKP_int subfr, /* I subframe number */ const SKP_int LTP_scale_Q14, /* I */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int pitchL[ NB_SUBFR ] /* I */ ); SKP_INLINE void SKP_Silk_noise_shape_quantizer( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ SKP_int sigtype, /* I Signal type */ const SKP_int32 x_sc_Q10[], /* I */ SKP_int8 q[], /* O */ SKP_int16 xq[], /* O */ SKP_int32 sLTP_Q16[], /* I/O LTP state */ const SKP_int16 a_Q12[], /* I Short term prediction coefs */ const SKP_int16 b_Q14[], /* I Long term prediction coefs */ const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ SKP_int lag, /* I Pitch lag */ SKP_int32 HarmShapeFIRPacked_Q14, /* I */ SKP_int Tilt_Q14, /* I Spectral tilt */ SKP_int32 LF_shp_Q14, /* I */ SKP_int32 Gain_Q16, /* I */ SKP_int Lambda_Q10, /* I */ SKP_int offset_Q10, /* I */ SKP_int length, /* I Input length */ SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */ SKP_int predictLPCOrder /* I Prediction filter order */ ); void SKP_Silk_NSQ( SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ const SKP_int16 x[], /* I prefiltered input signal */ SKP_int8 q[], /* O quantized qulse signal */ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int Lambda_Q10, /* I */ const SKP_int LTP_scale_Q14 /* I LTP state scaling */ ) { SKP_int k, lag, start_idx, LSF_interpolation_flag; const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13; SKP_int16 *pxq; SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ]; SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ]; SKP_int32 HarmShapeFIRPacked_Q14; SKP_int offset_Q10; SKP_int32 FiltState[ MAX_LPC_ORDER ]; SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ]; NSQ->rand_seed = psEncCtrlC->Seed; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; SKP_assert( NSQ->prev_inv_gain_Q16 != 0 ); offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ]; if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } /* Setup pointers to start of sub frame */ NSQ->sLTP_shp_buf_idx = psEncC->frame_length; NSQ->sLTP_buf_idx = psEncC->frame_length; pxq = &NSQ->xq[ psEncC->frame_length ]; for( k = 0; k < NB_SUBFR; k++ ) { A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ SKP_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) { /* Voiced */ lag = psEncCtrlC->pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { /* Rewhiten with new A coefs */ start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; SKP_assert( start_idx >= 0 ); SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder ); SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) ); SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * ( psEncC->frame_length >> 2 ) ], A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder ); NSQ->rewhite_flag = 1; NSQ->sLTP_buf_idx = psEncC->frame_length; } } SKP_Silk_nsq_scale_states( NSQ, x, x_sc_Q10, psEncC->subfr_length, sLTP, sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL ); SKP_Silk_noise_shape_quantizer( NSQ, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder ); x += psEncC->subfr_length; q += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Update lagPrev for next frame */ NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ]; /* Save quantized speech and noise shaping signals */ SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) ); SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) ); #ifdef USE_UNQUANTIZED_LSFS DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) ); #endif } /***********************************/ /* SKP_Silk_noise_shape_quantizer */ /***********************************/ SKP_INLINE void SKP_Silk_noise_shape_quantizer( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ SKP_int sigtype, /* I Signal type */ const SKP_int32 x_sc_Q10[], /* I */ SKP_int8 q[], /* O */ SKP_int16 xq[], /* O */ SKP_int32 sLTP_Q16[], /* I/O LTP state */ const SKP_int16 a_Q12[], /* I Short term prediction coefs */ const SKP_int16 b_Q14[], /* I Long term prediction coefs */ const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ SKP_int lag, /* I Pitch lag */ SKP_int32 HarmShapeFIRPacked_Q14, /* I */ SKP_int Tilt_Q14, /* I Spectral tilt */ SKP_int32 LF_shp_Q14, /* I */ SKP_int32 Gain_Q16, /* I */ SKP_int Lambda_Q10, /* I */ SKP_int offset_Q10, /* I */ SKP_int length, /* I Input length */ SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */ SKP_int predictLPCOrder /* I Prediction filter order */ ) { SKP_int i, j; SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14; SKP_int32 n_LF_Q10, r_Q10, q_Q0, q_Q10; SKP_int32 thr1_Q10, thr2_Q10, thr3_Q10; SKP_int32 dither, exc_Q10, LPC_exc_Q10, xq_Q10; SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10; SKP_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 a_Q12_tmp[ MAX_LPC_ORDER / 2 ], Atmp; /* Preload LPC coefficients to array on stack. Gives small performance gain */ SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) ); #endif shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; /* Setup short term AR state */ psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; /* Quantization thresholds */ thr1_Q10 = SKP_SUB_RSHIFT32( -1536, Lambda_Q10, 1 ); thr2_Q10 = SKP_SUB_RSHIFT32( -512, Lambda_Q10, 1 ); thr2_Q10 = SKP_ADD_RSHIFT32( thr2_Q10, SKP_SMULBB( offset_Q10, Lambda_Q10 ), 10 ); thr3_Q10 = SKP_ADD_RSHIFT32( 512, Lambda_Q10, 1 ); for( i = 0; i < length; i++ ) { /* Generate dither */ NSQ->rand_seed = SKP_RAND( NSQ->rand_seed ); /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ dither = SKP_RSHIFT( NSQ->rand_seed, 31 ); /* Short-term prediction */ SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */ /* check that array starts at 4-byte aligned address */ SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )a_Q12 - ( SKP_int8* )0 ) & 3 ) == 0 ); SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */ #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ /* Partially unrolled */ Atmp = a_Q12_tmp[ 0 ]; /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp ); Atmp = a_Q12_tmp[ 1 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp ); Atmp = a_Q12_tmp[ 2 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp ); Atmp = a_Q12_tmp[ 3 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp ); Atmp = a_Q12_tmp[ 4 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp ); for( j = 10; j < predictLPCOrder; j += 2 ) { Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp ); } #else /* Partially unrolled */ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); for( j = 10; j < predictLPCOrder; j ++ ) { LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] ); } #endif /* Long-term prediction */ if( sigtype == SIG_TYPE_VOICED ) { /* Unrolled loop */ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); pred_lag_ptr++; } else { LTP_pred_Q14 = 0; } /* Noise shape feedback */ SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ tmp2 = psLPC_Q14[ 0 ]; tmp1 = NSQ->sAR2_Q14[ 0 ]; NSQ->sAR2_Q14[ 0 ] = tmp2; n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] ); for( j = 2; j < shapingLPCOrder; j += 2 ) { tmp2 = NSQ->sAR2_Q14[ j - 1 ]; NSQ->sAR2_Q14[ j - 1 ] = tmp1; n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] ); tmp1 = NSQ->sAR2_Q14[ j + 0 ]; NSQ->sAR2_Q14[ j + 0 ] = tmp2; n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] ); } NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, NSQ->sLF_AR_shp_Q12, Tilt_Q14 ); n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ), 2 ); n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, NSQ->sLF_AR_shp_Q12, LF_shp_Q14 ); SKP_assert( lag > 0 || sigtype == SIG_TYPE_UNVOICED ); /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 ); shp_lag_ptr++; } else { n_LTP_Q14 = 0; } /* Input minus prediction plus noise feedback */ //r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP; tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */ tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */ tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */ tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */ tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */ r_Q10 = SKP_SUB32( x_sc_Q10[ i ], tmp1 ); /* Flip sign depending on dither */ r_Q10 = ( r_Q10 ^ dither ) - dither; r_Q10 = SKP_SUB32( r_Q10, offset_Q10 ); r_Q10 = SKP_LIMIT_32( r_Q10, -64 << 10, 64 << 10 ); /* Quantize */ q_Q0 = 0; q_Q10 = 0; if( r_Q10 < thr2_Q10 ) { if( r_Q10 < thr1_Q10 ) { q_Q0 = SKP_RSHIFT_ROUND( SKP_ADD_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 ); q_Q10 = SKP_LSHIFT( q_Q0, 10 ); } else { q_Q0 = -1; q_Q10 = -1024; } } else { if( r_Q10 > thr3_Q10 ) { q_Q0 = SKP_RSHIFT_ROUND( SKP_SUB_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 ); q_Q10 = SKP_LSHIFT( q_Q0, 10 ); } } q[ i ] = ( SKP_int8 )q_Q0; /* No saturation needed because max is 64 */ /* Excitation */ exc_Q10 = SKP_ADD32( q_Q10, offset_Q10 ); exc_Q10 = ( exc_Q10 ^ dither ) - dither; /* Add predictions */ LPC_exc_Q10 = SKP_ADD32( exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 ); /* Scale XQ back to normal level before saving */ xq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( xq_Q10, Gain_Q16 ), 10 ) ); /* Update states */ psLPC_Q14++; *psLPC_Q14 = SKP_LSHIFT( xq_Q10, 4 ); sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 ); NSQ->sLF_AR_shp_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 ); NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 ); sLTP_Q16[ NSQ->sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 ); NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Make dither dependent on quantized signal */ NSQ->rand_seed += q[ i ]; } /* Update LPC synth buffer */ SKP_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) ); } SKP_INLINE void SKP_Silk_nsq_scale_states( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ const SKP_int16 x[], /* I input in Q0 */ SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ SKP_int subfr_length, /* I length of input */ const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */ SKP_int subfr, /* I subframe number */ const SKP_int LTP_scale_Q14, /* I */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int pitchL[ NB_SUBFR ] /* I */ ) { SKP_int i, lag; SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32; inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 ); inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX ); lag = pitchL[ subfr ]; /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 ); if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 ); } for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { SKP_assert( i < MAX_FRAME_LENGTH ); sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] ); } } /* Adjust for changing gain */ if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) { gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 ); /* Scale long-term shaping state */ for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] ); } /* Scale long-term prediction state */ if( NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] ); } } NSQ->sLF_AR_shp_Q12 = SKP_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q12 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { NSQ->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { NSQ->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); } } /* Scale input */ for( i = 0; i < subfr_length; i++ ) { x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 ); } /* save inv_gain */ SKP_assert( inv_gain_Q16 != 0 ); NSQ->prev_inv_gain_Q16 = inv_gain_Q16; } ================================================ FILE: app/jni/SKP_Silk_NSQ_del_dec.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" typedef struct { SKP_int32 RandState[ DECISION_DELAY ]; SKP_int32 Q_Q10[ DECISION_DELAY ]; SKP_int32 Xq_Q10[ DECISION_DELAY ]; SKP_int32 Pred_Q16[ DECISION_DELAY ]; SKP_int32 Shape_Q10[ DECISION_DELAY ]; SKP_int32 Gain_Q16[ DECISION_DELAY ]; SKP_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ]; SKP_int32 LF_AR_Q12; SKP_int32 Seed; SKP_int32 SeedInit; SKP_int32 RD_Q10; } NSQ_del_dec_struct; typedef struct { SKP_int32 Q_Q10; SKP_int32 RD_Q10; SKP_int32 xq_Q14; SKP_int32 LF_AR_Q12; SKP_int32 sLTP_shp_Q10; SKP_int32 LPC_exc_Q16; } NSQ_sample_struct; SKP_INLINE void SKP_Silk_copy_del_dec_state( NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */ NSQ_del_dec_struct *DD_src, /* I Src del dec state */ SKP_int LPC_state_idx /* I Index to LPC buffer */ ); SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ const SKP_int16 x[], /* I Input in Q0 */ SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ SKP_int subfr_length, /* I Length of input */ const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */ SKP_int subfr, /* I Subframe number */ SKP_int nStatesDelayedDecision, /* I Number of del dec states */ SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */ const SKP_int LTP_scale_Q14, /* I LTP state scaling */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */ ); /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ SKP_int sigtype, /* I Signal type */ const SKP_int32 x_Q10[], /* I */ SKP_int8 q[], /* O */ SKP_int16 xq[], /* O */ SKP_int32 sLTP_Q16[], /* I/O LTP filter state */ const SKP_int16 a_Q12[], /* I Short term prediction coefs */ const SKP_int16 b_Q14[], /* I Long term prediction coefs */ const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */ SKP_int lag, /* I Pitch lag */ SKP_int32 HarmShapeFIRPacked_Q14, /* I */ SKP_int Tilt_Q14, /* I Spectral tilt */ SKP_int32 LF_shp_Q14, /* I */ SKP_int32 Gain_Q16, /* I */ SKP_int Lambda_Q10, /* I */ SKP_int offset_Q10, /* I */ SKP_int length, /* I Input length */ SKP_int subfr, /* I Subframe number */ SKP_int shapingLPCOrder, /* I Shaping LPC filter order */ SKP_int predictLPCOrder, /* I Prediction filter order */ SKP_int warping_Q16, /* I */ SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */ SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */ SKP_int decisionDelay /* I */ ); void SKP_Silk_NSQ_del_dec( SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ const SKP_int16 x[], /* I Prefiltered input signal */ SKP_int8 q[], /* O Quantized pulse signal */ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int Lambda_Q10, /* I */ const SKP_int LTP_scale_Q14 /* I LTP state scaling */ ) { SKP_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; SKP_int last_smple_idx, smpl_buf_idx, decisionDelay, subfr_length; const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13; SKP_int16 *pxq; SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ]; SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ]; SKP_int32 HarmShapeFIRPacked_Q14; SKP_int offset_Q10; SKP_int32 FiltState[ MAX_LPC_ORDER ], RDmin_Q10; SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ]; NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ]; NSQ_del_dec_struct *psDD; subfr_length = psEncC->frame_length / NB_SUBFR; /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; SKP_assert( NSQ->prev_inv_gain_Q16 != 0 ); /* Initialize delayed decision states */ SKP_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psDD->Seed = ( k + psEncCtrlC->Seed ) & 3; psDD->SeedInit = psDD->Seed; psDD->RD_Q10 = 0; psDD->LF_AR_Q12 = NSQ->sLF_AR_shp_Q12; psDD->Shape_Q10[ 0 ] = NSQ->sLTP_shp_Q10[ psEncC->frame_length - 1 ]; SKP_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) ); SKP_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); } offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ]; smpl_buf_idx = 0; /* index of oldest samples */ decisionDelay = SKP_min_int( DECISION_DELAY, subfr_length ); /* For voiced frames limit the decision delay to lower than the pitch lag */ if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) { for( k = 0; k < NB_SUBFR; k++ ) { decisionDelay = SKP_min_int( decisionDelay, psEncCtrlC->pitchL[ k ] - LTP_ORDER / 2 - 1 ); } } else { if( lag > 0 ) { decisionDelay = SKP_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); } } if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) { LSF_interpolation_flag = 0; } else { LSF_interpolation_flag = 1; } /* Setup pointers to start of sub frame */ pxq = &NSQ->xq[ psEncC->frame_length ]; NSQ->sLTP_shp_buf_idx = psEncC->frame_length; NSQ->sLTP_buf_idx = psEncC->frame_length; subfr = 0; for( k = 0; k < NB_SUBFR; k++ ) { A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ SKP_assert( HarmShapeGain_Q14[ k ] >= 0 ); HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); NSQ->rewhite_flag = 0; if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) { /* Voiced */ lag = psEncCtrlC->pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { if( k == 2 ) { /* RESET DELAYED DECISIONS */ /* Find winner */ RDmin_Q10 = psDelDec[ 0 ].RD_Q10; Winner_ind = 0; for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psDelDec[ i ].RD_Q10; Winner_ind = i; } } for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { if( i != Winner_ind ) { psDelDec[ i ].RD_Q10 += ( SKP_int32_MAX >> 4 ); SKP_assert( psDelDec[ i ].RD_Q10 >= 0 ); } } /* Copy final part of signals from winner state to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; last_smple_idx = smpl_buf_idx + decisionDelay; for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) ); NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ]; } subfr = 0; } /* Rewhiten with new A coefs */ start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; SKP_assert( start_idx >= 0 ); SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder ); SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) ); SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * psEncC->subfr_length ], A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder ); NSQ->sLTP_buf_idx = psEncC->frame_length; NSQ->rewhite_flag = 1; } } SKP_Silk_nsq_del_dec_scale_states( NSQ, psDelDec, x, x_sc_Q10, subfr_length, sLTP, sLTP_Q16, k, psEncC->nStatesDelayedDecision, smpl_buf_idx, LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL ); SKP_Silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); x += psEncC->subfr_length; q += psEncC->subfr_length; pxq += psEncC->subfr_length; } /* Find winner */ RDmin_Q10 = psDelDec[ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psDelDec[ k ].RD_Q10; Winner_ind = k; } } /* Copy final part of signals from winner state to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; psEncCtrlC->Seed = psDD->SeedInit; last_smple_idx = smpl_buf_idx + decisionDelay; for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) ); NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ]; sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay + i ] = psDD->Pred_Q16[ last_smple_idx ]; } SKP_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) ); SKP_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); /* Update states */ NSQ->sLF_AR_shp_Q12 = psDD->LF_AR_Q12; NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ]; /* Save quantized speech and noise shaping signals */ SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) ); SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) ); #ifdef USE_UNQUANTIZED_LSFS DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) ); #endif } /******************************************/ /* Noise shape quantizer for one subframe */ /******************************************/ SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ SKP_int sigtype, /* I Signal type */ const SKP_int32 x_Q10[], /* I */ SKP_int8 q[], /* O */ SKP_int16 xq[], /* O */ SKP_int32 sLTP_Q16[], /* I/O LTP filter state */ const SKP_int16 a_Q12[], /* I Short term prediction coefs */ const SKP_int16 b_Q14[], /* I Long term prediction coefs */ const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */ SKP_int lag, /* I Pitch lag */ SKP_int32 HarmShapeFIRPacked_Q14, /* I */ SKP_int Tilt_Q14, /* I Spectral tilt */ SKP_int32 LF_shp_Q14, /* I */ SKP_int32 Gain_Q16, /* I */ SKP_int Lambda_Q10, /* I */ SKP_int offset_Q10, /* I */ SKP_int length, /* I Input length */ SKP_int subfr, /* I Subframe number */ SKP_int shapingLPCOrder, /* I Shaping LPC filter order */ SKP_int predictLPCOrder, /* I Prediction filter order */ SKP_int warping_Q16, /* I */ SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */ SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */ SKP_int decisionDelay /* I */ ) { SKP_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; SKP_int32 Winner_rand_state; SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14; SKP_int32 n_LF_Q10, r_Q10, rr_Q20, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; SKP_int32 q1_Q10, q2_Q10, dither, exc_Q10, LPC_exc_Q10, xq_Q10; SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10; SKP_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; NSQ_del_dec_struct *psDD; NSQ_sample_struct *psSS; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 a_Q12_tmp[ MAX_LPC_ORDER / 2 ], Atmp; /* Preload LPC coeficients to array on stack. Gives small performance gain */ SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) ); #endif shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; for( i = 0; i < length; i++ ) { /* Perform common calculations used in all states */ /* Long-term prediction */ if( sigtype == SIG_TYPE_VOICED ) { /* Unrolled loop */ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); pred_lag_ptr++; } else { LTP_pred_Q14 = 0; } /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 ); shp_lag_ptr++; } else { n_LTP_Q14 = 0; } for( k = 0; k < nStatesDelayedDecision; k++ ) { /* Delayed decision state */ psDD = &psDelDec[ k ]; /* Sample state */ psSS = psSampleState[ k ]; /* Generate dither */ psDD->Seed = SKP_RAND( psDD->Seed ); /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ dither = SKP_RSHIFT( psDD->Seed, 31 ); /* Pointer used in short term prediction and shaping */ psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; /* Short-term prediction */ SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */ SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */ SKP_assert( ( ( ( int )( ( char* )( a_Q12 ) - ( ( char* ) 0 ) ) ) & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */ #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* Partially unrolled */ Atmp = a_Q12_tmp[ 0 ]; /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp ); Atmp = a_Q12_tmp[ 1 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp ); Atmp = a_Q12_tmp[ 2 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp ); Atmp = a_Q12_tmp[ 3 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp ); Atmp = a_Q12_tmp[ 4 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp ); for( j = 10; j < predictLPCOrder; j += 2 ) { Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp ); } #else /* Partially unrolled */ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); for( j = 10; j < predictLPCOrder; j ++ ) { LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] ); } #endif /* Noise shape feedback */ SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ /* Output of lowpass section */ tmp2 = SKP_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); /* Output of allpass section */ tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ 0 ] = tmp2; n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] ); /* Loop over allpass sections */ for( j = 2; j < shapingLPCOrder; j += 2 ) { /* Output of allpass section */ tmp2 = SKP_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); psDD->sAR2_Q14[ j - 1 ] = tmp1; n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] ); /* Output of allpass section */ tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ j + 0 ] = tmp2; n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] ); } psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psDD->LF_AR_Q12, Tilt_Q14 ); n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( psDD->Shape_Q10[ *smpl_buf_idx ], LF_shp_Q14 ), 2 ); n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, psDD->LF_AR_Q12, LF_shp_Q14 ); /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */ tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */ tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */ tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */ tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */ r_Q10 = SKP_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ /* Flip sign depending on dither */ r_Q10 = ( r_Q10 ^ dither ) - dither; r_Q10 = SKP_SUB32( r_Q10, offset_Q10 ); r_Q10 = SKP_LIMIT_32( r_Q10, -64 << 10, 64 << 10 ); /* Find two quantization level candidates and measure their rate-distortion */ if( r_Q10 < -1536 ) { q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 ); r_Q10 = SKP_SUB32( r_Q10, q1_Q10 ); rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( -SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 ); rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 ); rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ) ); q2_Q10 = SKP_ADD32( q1_Q10, 1024 ); } else if( r_Q10 > 512 ) { q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 ); r_Q10 = SKP_SUB32( r_Q10, q1_Q10 ); rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 ); rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 ); rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_SUB_LSHIFT32( Lambda_Q10, r_Q10, 1 ) ); q2_Q10 = SKP_SUB32( q1_Q10, 1024 ); } else { /* r_Q10 >= -1536 && q1_Q10 <= 512 */ rr_Q20 = SKP_SMULBB( offset_Q10, Lambda_Q10 ); rd2_Q10 = SKP_RSHIFT( SKP_SMLABB( rr_Q20, r_Q10, r_Q10 ), 10 ); rd1_Q10 = SKP_ADD32( rd2_Q10, 1024 ); rd1_Q10 = SKP_ADD32( rd1_Q10, SKP_SUB_RSHIFT32( SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ), rr_Q20, 9 ) ); q1_Q10 = -1024; q2_Q10 = 0; } if( rd1_Q10 < rd2_Q10 ) { psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 0 ].Q_Q10 = q1_Q10; psSS[ 1 ].Q_Q10 = q2_Q10; } else { psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 ); psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 ); psSS[ 0 ].Q_Q10 = q2_Q10; psSS[ 1 ].Q_Q10 = q1_Q10; } /* Update states for best quantization */ /* Quantized excitation */ exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 0 ].Q_Q10 ); exc_Q10 = ( exc_Q10 ^ dither ) - dither; /* Add predictions */ LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ); xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 ); /* Update states */ sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 ); psSS[ 0 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 ); psSS[ 0 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 ); psSS[ 0 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 ); psSS[ 0 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 ); /* Update states for second best quantization */ /* Quantized excitation */ exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 1 ].Q_Q10 ); exc_Q10 = ( exc_Q10 ^ dither ) - dither; /* Add predictions */ LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ); xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 ); /* Update states */ sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 ); psSS[ 1 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 ); psSS[ 1 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 ); psSS[ 1 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 ); psSS[ 1 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 ); } *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */ last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */ /* Find winner */ RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; Winner_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; Winner_ind = k; } } /* Increase RD values of expired states */ Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; for( k = 0; k < nStatesDelayedDecision; k++ ) { if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { psSampleState[ k ][ 0 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 0 ].RD_Q10, ( SKP_int32_MAX >> 4 ) ); psSampleState[ k ][ 1 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 1 ].RD_Q10, ( SKP_int32_MAX >> 4 ) ); SKP_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); } } /* Find worst in first set and best in second set */ RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; RDmax_ind = 0; RDmin_ind = 0; for( k = 1; k < nStatesDelayedDecision; k++ ) { /* find worst in first set */ if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; RDmax_ind = k; } /* find best in second set */ if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; RDmin_ind = k; } } /* Replace a state if best from second set outperforms worst in first set */ if( RDmin_Q10 < RDmax_Q10 ) { SKP_Silk_copy_del_dec_state( &psDelDec[ RDmax_ind ], &psDelDec[ RDmin_ind ], i ); SKP_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); } /* Write samples from winner to output and long-term filter states */ psDD = &psDelDec[ Winner_ind ]; if( subfr > 0 || i >= decisionDelay ) { q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 ); xq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) ); NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ]; sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q16[ last_smple_idx ]; } NSQ->sLTP_shp_buf_idx++; NSQ->sLTP_buf_idx++; /* Update states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; psSS = &psSampleState[ k ][ 0 ]; psDD->LF_AR_Q12 = psSS->LF_AR_Q12; psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; psDD->Xq_Q10[ *smpl_buf_idx ] = SKP_RSHIFT( psSS->xq_Q14, 4 ); psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; psDD->Pred_Q16[ *smpl_buf_idx ] = psSS->LPC_exc_Q16; psDD->Shape_Q10[ *smpl_buf_idx ] = psSS->sLTP_shp_Q10; psDD->Seed = SKP_ADD_RSHIFT32( psDD->Seed, psSS->Q_Q10, 10 ); psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; psDD->RD_Q10 = psSS->RD_Q10; psDD->Gain_Q16[ *smpl_buf_idx ] = Gain_Q16; } } /* Update LPC states */ for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; SKP_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) ); } } SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states( SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ const SKP_int16 x[], /* I Input in Q0 */ SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ SKP_int subfr_length, /* I Length of input */ const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */ SKP_int subfr, /* I Subframe number */ SKP_int nStatesDelayedDecision, /* I Number of del dec states */ SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */ const SKP_int LTP_scale_Q14, /* I LTP state scaling */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */ ) { SKP_int i, k, lag; SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32; NSQ_del_dec_struct *psDD; inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 ); inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX ); lag = pitchL[ subfr ]; /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 ); if( subfr == 0 ) { /* Do LTP downscaling */ inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 ); } for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { SKP_assert( i < MAX_FRAME_LENGTH ); sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] ); } } /* Adjust for changing gain */ if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) { gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 ); /* Scale long-term shaping state */ for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) { NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] ); } /* Scale long-term prediction state */ if( NSQ->rewhite_flag == 0 ) { for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] ); } } for( k = 0; k < nStatesDelayedDecision; k++ ) { psDD = &psDelDec[ k ]; /* Scale scalar states */ psDD->LF_AR_Q12 = SKP_SMULWW( gain_adj_Q16, psDD->LF_AR_Q12 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { psDD->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); } for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { psDD->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); } for( i = 0; i < DECISION_DELAY; i++ ) { psDD->Pred_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Pred_Q16[ i ] ); psDD->Shape_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Shape_Q10[ i ] ); } } } /* Scale input */ for( i = 0; i < subfr_length; i++ ) { x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 ); } /* save inv_gain */ SKP_assert( inv_gain_Q16 != 0 ); NSQ->prev_inv_gain_Q16 = inv_gain_Q16; } SKP_INLINE void SKP_Silk_copy_del_dec_state( NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */ NSQ_del_dec_struct *DD_src, /* I Src del dec state */ SKP_int LPC_state_idx /* I Index to LPC buffer */ ) { SKP_memcpy( DD_dst->RandState, DD_src->RandState, sizeof( DD_src->RandState ) ); SKP_memcpy( DD_dst->Q_Q10, DD_src->Q_Q10, sizeof( DD_src->Q_Q10 ) ); SKP_memcpy( DD_dst->Pred_Q16, DD_src->Pred_Q16, sizeof( DD_src->Pred_Q16 ) ); SKP_memcpy( DD_dst->Shape_Q10, DD_src->Shape_Q10, sizeof( DD_src->Shape_Q10 ) ); SKP_memcpy( DD_dst->Xq_Q10, DD_src->Xq_Q10, sizeof( DD_src->Xq_Q10 ) ); SKP_memcpy( DD_dst->sAR2_Q14, DD_src->sAR2_Q14, sizeof( DD_src->sAR2_Q14 ) ); SKP_memcpy( &DD_dst->sLPC_Q14[ LPC_state_idx ], &DD_src->sLPC_Q14[ LPC_state_idx ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) ); DD_dst->LF_AR_Q12 = DD_src->LF_AR_Q12; DD_dst->Seed = DD_src->Seed; DD_dst->SeedInit = DD_src->SeedInit; DD_dst->RD_Q10 = DD_src->RD_Q10; } ================================================ FILE: app/jni/SKP_Silk_PLC.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" #include "SKP_Silk_PLC.h" #define NB_ATT 2 static const SKP_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */ static const SKP_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */ static const SKP_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */ void SKP_Silk_PLC_Reset( SKP_Silk_decoder_state *psDec /* I/O Decoder state */ ) { psDec->sPLC.pitchL_Q8 = SKP_RSHIFT( psDec->frame_length, 1 ); } void SKP_Silk_PLC( SKP_Silk_decoder_state *psDec, /* I Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */ SKP_int16 signal[], /* O Concealed signal */ SKP_int length, /* I length of residual */ SKP_int lost /* I Loss flag */ ) { /* PLC control function */ if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) { SKP_Silk_PLC_Reset( psDec ); psDec->sPLC.fs_kHz = psDec->fs_kHz; } if( lost ) { /****************************/ /* Generate Signal */ /****************************/ SKP_Silk_PLC_conceal( psDec, psDecCtrl, signal, length ); psDec->lossCnt++; } else { /****************************/ /* Update state */ /****************************/ SKP_Silk_PLC_update( psDec, psDecCtrl, signal, length ); } } /**************************************************/ /* Update state of PLC */ /**************************************************/ void SKP_Silk_PLC_update( SKP_Silk_decoder_state *psDec, /* (I/O) Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* (I/O) Decoder control */ SKP_int16 signal[], SKP_int length ) { SKP_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14; SKP_int i, j; SKP_Silk_PLC_struct *psPLC; psPLC = &psDec->sPLC; /* Update parameters used in case of packet loss */ psDec->prev_sigtype = psDecCtrl->sigtype; LTP_Gain_Q14 = 0; if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) { /* Find the parameters for the last subframe which contains a pitch pulse */ for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ NB_SUBFR - 1 ]; j++ ) { temp_LTP_Gain_Q14 = 0; for( i = 0; i < LTP_ORDER; i++ ) { temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( NB_SUBFR - 1 - j ) * LTP_ORDER + i ]; } if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) { LTP_Gain_Q14 = temp_LTP_Gain_Q14; SKP_memcpy( psPLC->LTPCoef_Q14, &psDecCtrl->LTPCoef_Q14[ SKP_SMULBB( NB_SUBFR - 1 - j, LTP_ORDER ) ], LTP_ORDER * sizeof( SKP_int16 ) ); psPLC->pitchL_Q8 = SKP_LSHIFT( psDecCtrl->pitchL[ NB_SUBFR - 1 - j ], 8 ); } } #if USE_SINGLE_TAP SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) ); psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14; #endif /* Limit LT coefs */ if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) { SKP_int scale_Q10; SKP_int32 tmp; tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 ); scale_Q10 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) ); for( i = 0; i < LTP_ORDER; i++ ) { psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 ); } } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) { SKP_int scale_Q14; SKP_int32 tmp; tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 ); scale_Q14 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) ); for( i = 0; i < LTP_ORDER; i++ ) { psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 ); } } } else { psPLC->pitchL_Q8 = SKP_LSHIFT( SKP_SMULBB( psDec->fs_kHz, 18 ), 8 ); SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 )); } /* Save LPC coeficients */ SKP_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) ); psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14; /* Save Gains */ SKP_memcpy( psPLC->prevGain_Q16, psDecCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) ); } void SKP_Silk_PLC_conceal( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* O concealed signal */ SKP_int length /* I length of residual */ ) { SKP_int i, j, k; SKP_int16 *B_Q14, exc_buf[ MAX_FRAME_LENGTH ], *exc_buf_ptr; SKP_int16 rand_scale_Q14; union { SKP_int16 as_int16[ MAX_LPC_ORDER ]; SKP_int32 as_int32[ MAX_LPC_ORDER / 2 ]; } A_Q12_tmp; SKP_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15; SKP_int lag, idx, sLTP_buf_idx, shift1, shift2; SKP_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr; SKP_int32 sig_Q10[ MAX_FRAME_LENGTH ], *sig_Q10_ptr, LPC_exc_Q10, LPC_pred_Q10, LTP_pred_Q14; SKP_Silk_PLC_struct *psPLC; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 Atmp; #endif psPLC = &psDec->sPLC; /* Update LTP buffer */ SKP_memcpy( psDec->sLTP_Q16, &psDec->sLTP_Q16[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int32 ) ); /* LPC concealment. Apply BWE to previous LPC */ SKP_Silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, BWE_COEF_Q16 ); /* Find random noise component */ /* Scale previous excitation signal */ exc_buf_ptr = exc_buf; for( k = ( NB_SUBFR >> 1 ); k < NB_SUBFR; k++ ) { for( i = 0; i < psDec->subfr_length; i++ ) { exc_buf_ptr[ i ] = ( SKP_int16 )SKP_RSHIFT( SKP_SMULWW( psDec->exc_Q10[ i + k * psDec->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 ); } exc_buf_ptr += psDec->subfr_length; } /* Find the subframe with lowest energy of the last two and use that as random noise generator */ SKP_Silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psDec->subfr_length ); SKP_Silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psDec->subfr_length ); if( SKP_RSHIFT( energy1, shift2 ) < SKP_RSHIFT( energy2, shift1 ) ) { /* First sub-frame has lowest energy */ rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, 3 * psDec->subfr_length - RAND_BUF_SIZE ) ]; } else { /* Second sub-frame has lowest energy */ rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, psDec->frame_length - RAND_BUF_SIZE ) ]; } /* Setup Gain to random noise component */ B_Q14 = psPLC->LTPCoef_Q14; rand_scale_Q14 = psPLC->randScale_Q14; /* Setup attenuation gains */ harm_Gain_Q15 = HARM_ATT_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ]; if( psDec->prev_sigtype == SIG_TYPE_VOICED ) { rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ]; } else { rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ]; } /* First Lost frame */ if( psDec->lossCnt == 0 ) { rand_scale_Q14 = (1 << 14 ); /* Reduce random noise Gain for voiced frames */ if( psDec->prev_sigtype == SIG_TYPE_VOICED ) { for( i = 0; i < LTP_ORDER; i++ ) { rand_scale_Q14 -= B_Q14[ i ]; } rand_scale_Q14 = SKP_max_16( 3277, rand_scale_Q14 ); /* 0.2 */ rand_scale_Q14 = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 ); } /* Reduce random noise for unvoiced frames with high LPC gain */ if( psDec->prev_sigtype == SIG_TYPE_UNVOICED ) { SKP_int32 invGain_Q30, down_scale_Q30; SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, psPLC->prevLPC_Q12, psDec->LPC_order ); down_scale_Q30 = SKP_min_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); down_scale_Q30 = SKP_max_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); down_scale_Q30 = SKP_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES ); rand_Gain_Q15 = SKP_RSHIFT( SKP_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 ); } } rand_seed = psPLC->rand_seed; lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); sLTP_buf_idx = psDec->frame_length; /***************************/ /* LTP synthesis filtering */ /***************************/ sig_Q10_ptr = sig_Q10; for( k = 0; k < NB_SUBFR; k++ ) { /* Setup pointer */ pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; for( i = 0; i < psDec->subfr_length; i++ ) { rand_seed = SKP_RAND( rand_seed ); idx = SKP_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK; /* Unrolled loop */ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); pred_lag_ptr++; /* Generate LPC residual */ LPC_exc_Q10 = SKP_LSHIFT( SKP_SMULWB( rand_ptr[ idx ], rand_scale_Q14 ), 2 ); /* Random noise part */ LPC_exc_Q10 = SKP_ADD32( LPC_exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); /* Harmonic part */ /* Update states */ psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 ); sLTP_buf_idx++; /* Save LPC residual */ sig_Q10_ptr[ i ] = LPC_exc_Q10; } sig_Q10_ptr += psDec->subfr_length; /* Gradually reduce LTP gain */ for( j = 0; j < LTP_ORDER; j++ ) { B_Q14[ j ] = SKP_RSHIFT( SKP_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); } /* Gradually reduce excitation gain */ rand_scale_Q14 = SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); /* Slowly increase pitch lag */ psPLC->pitchL_Q8 += SKP_SMULWB( psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); psPLC->pitchL_Q8 = SKP_min_32( psPLC->pitchL_Q8, SKP_LSHIFT( SKP_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) ); lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); } /***************************/ /* LPC synthesis filtering */ /***************************/ sig_Q10_ptr = sig_Q10; /* Preload LPC coeficients to array on stack. Gives small performance gain */ SKP_memcpy( A_Q12_tmp.as_int16, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( SKP_int16 ) ); SKP_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ for( k = 0; k < NB_SUBFR; k++ ) { for( i = 0; i < psDec->subfr_length; i++ ){ /* partly unrolled */ #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ Atmp = A_Q12_tmp.as_int32[ 0 ]; /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp ); Atmp = A_Q12_tmp.as_int32[ 1 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp ); Atmp = A_Q12_tmp.as_int32[ 2 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp ); Atmp = A_Q12_tmp.as_int32[ 3 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp ); Atmp = A_Q12_tmp.as_int32[ 4 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp ); for( j = 10 ; j < psDec->LPC_order ; j+=2 ) { Atmp = A_Q12_tmp.as_int32[ j / 2 ]; LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 - j ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 - j ], Atmp ); } #else LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp.as_int16[ 0 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp.as_int16[ 1 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp.as_int16[ 2 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp.as_int16[ 3 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp.as_int16[ 4 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp.as_int16[ 5 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp.as_int16[ 6 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp.as_int16[ 7 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp.as_int16[ 8 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp.as_int16[ 9 ] ); for( j = 10; j < psDec->LPC_order; j++ ) { LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp.as_int16[ j ] ); } #endif /* Add prediction to LPC residual */ sig_Q10_ptr[ i ] = SKP_ADD32( sig_Q10_ptr[ i ], LPC_pred_Q10 ); /* Update states */ psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( sig_Q10_ptr[ i ], 4 ); } sig_Q10_ptr += psDec->subfr_length; /* Update LPC filter state */ SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) ); } /* Scale with Gain */ for( i = 0; i < psDec->frame_length; i++ ) { signal[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( sig_Q10[ i ], psPLC->prevGain_Q16[ NB_SUBFR - 1 ] ), 10 ) ); } /**************************************/ /* Update states */ /**************************************/ psPLC->rand_seed = rand_seed; psPLC->randScale_Q14 = rand_scale_Q14; for( i = 0; i < NB_SUBFR; i++ ) { psDecCtrl->pitchL[ i ] = lag; } } /* Glues concealed frames with new good recieved frames */ void SKP_Silk_PLC_glue_frames( SKP_Silk_decoder_state *psDec, /* I/O decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* I/O signal */ SKP_int length /* I length of residual */ ) { SKP_int i, energy_shift; SKP_int32 energy; SKP_Silk_PLC_struct *psPLC; psPLC = &psDec->sPLC; if( psDec->lossCnt ) { /* Calculate energy in concealed residual */ SKP_Silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, signal, length ); psPLC->last_frame_lost = 1; } else { if( psDec->sPLC.last_frame_lost ) { /* Calculate residual in decoded signal if last frame was lost */ SKP_Silk_sum_sqr_shift( &energy, &energy_shift, signal, length ); /* Normalize energies */ if( energy_shift > psPLC->conc_energy_shift ) { psPLC->conc_energy = SKP_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift ); } else if( energy_shift < psPLC->conc_energy_shift ) { energy = SKP_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift ); } /* Fade in the energy difference */ if( energy > psPLC->conc_energy ) { SKP_int32 frac_Q24, LZ; SKP_int32 gain_Q12, slope_Q12; LZ = SKP_Silk_CLZ32( psPLC->conc_energy ); LZ = LZ - 1; psPLC->conc_energy = SKP_LSHIFT( psPLC->conc_energy, LZ ); energy = SKP_RSHIFT( energy, SKP_max_32( 24 - LZ, 0 ) ); frac_Q24 = SKP_DIV32( psPLC->conc_energy, SKP_max( energy, 1 ) ); gain_Q12 = SKP_Silk_SQRT_APPROX( frac_Q24 ); slope_Q12 = SKP_DIV32_16( ( 1 << 12 ) - gain_Q12, length ); for( i = 0; i < length; i++ ) { signal[ i ] = SKP_RSHIFT( SKP_MUL( gain_Q12, signal[ i ] ), 12 ); gain_Q12 += slope_Q12; gain_Q12 = SKP_min( gain_Q12, ( 1 << 12 ) ); } } } psPLC->last_frame_lost = 0; } } ================================================ FILE: app/jni/SKP_Silk_VAD.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * File Name: SKP_Silk_VAD.c * Description: Silk VAD. */ #include #include "SKP_Silk_main.h" /**********************************/ /* Initialization of the Silk VAD */ /**********************************/ SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ) { SKP_int b, ret = 0; /* reset state memory */ SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) ); /* init noise levels */ /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NoiseLevelBias[ b ] = SKP_max_32( SKP_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); } /* Initialize state */ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NL[ b ] = SKP_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); psSilk_VAD->inv_NL[ b ] = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->NL[ b ] ); } psSilk_VAD->counter = 15; /* init smoothed energy-to-noise ratio*/ for( b = 0; b < VAD_N_BANDS; b++ ) { psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ } return( ret ); } /* Weighting factors for tilt measure */ const static SKP_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; /***************************************/ /* Get the speech activity level in Q8 */ /***************************************/ SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */ SKP_int *pSA_Q8, /* O Speech activity level in Q8 */ SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */ SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */ SKP_int *pTilt_Q15, /* O current frame's frequency tilt */ const SKP_int16 pIn[], /* I PCM input [framelength] */ const SKP_int framelength /* I Input frame length */ ) { SKP_int SA_Q15, input_tilt; SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH / 2 ]; SKP_int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; SKP_int32 sumSquared, smooth_coef_Q16; SKP_int16 HPstateTmp; SKP_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ]; SKP_int32 Xnrg[ VAD_N_BANDS ]; SKP_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; SKP_int32 speech_nrg, x_tmp; SKP_int ret = 0; /* Safety checks */ SKP_assert( VAD_N_BANDS == 4 ); SKP_assert( MAX_FRAME_LENGTH >= framelength ); SKP_assert( framelength <= 512 ); /***********************/ /* Filter and Decimate */ /***********************/ /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ SKP_Silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], &scratch[ 0 ], framelength ); /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 1 ) ); /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 2 ) ); /*********************************************/ /* HP filter on lowest band (differentiator) */ /*********************************************/ decimated_framelength = SKP_RSHIFT( framelength, 3 ); X[ 0 ][ decimated_framelength - 1 ] = SKP_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 ); HPstateTmp = X[ 0 ][ decimated_framelength - 1 ]; for( i = decimated_framelength - 1; i > 0; i-- ) { X[ 0 ][ i - 1 ] = SKP_RSHIFT( X[ 0 ][ i - 1 ], 1 ); X[ 0 ][ i ] -= X[ 0 ][ i - 1 ]; } X[ 0 ][ 0 ] -= psSilk_VAD->HPstate; psSilk_VAD->HPstate = HPstateTmp; /*************************************/ /* Calculate the energy in each band */ /*************************************/ for( b = 0; b < VAD_N_BANDS; b++ ) { /* Find the decimated framelength in the non-uniformly divided bands */ decimated_framelength = SKP_RSHIFT( framelength, SKP_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); /* Split length into subframe lengths */ dec_subframe_length = SKP_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); dec_subframe_offset = 0; /* Compute energy per sub-frame */ /* initialize with summed energy of last subframe */ Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { sumSquared = 0; for( i = 0; i < dec_subframe_length; i++ ) { /* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 ) ^ 2. */ /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ x_tmp = SKP_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 ); sumSquared = SKP_SMLABB( sumSquared, x_tmp, x_tmp ); /* Safety check */ SKP_assert( sumSquared >= 0 ); } /* Add/saturate summed energy of current subframe */ if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); } else { /* Look-ahead subframe */ Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], SKP_RSHIFT( sumSquared, 1 ) ); } dec_subframe_offset += dec_subframe_length; } psSilk_VAD->XnrgSubfr[ b ] = sumSquared; } /********************/ /* Noise estimation */ /********************/ SKP_Silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); /***********************************************/ /* Signal-plus-noise to noise ratio estimation */ /***********************************************/ sumSquared = 0; input_tilt = 0; for( b = 0; b < VAD_N_BANDS; b++ ) { speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; if( speech_nrg > 0 ) { /* Divide, with sufficient resolution */ if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( SKP_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); } else { NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( Xnrg[ b ], SKP_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); } /* Convert to log domain */ SNR_Q7 = SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; /* Sum-of-squares */ sumSquared = SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ /* Tilt measure */ if( speech_nrg < ( 1 << 20 ) ) { /* Scale down SNR value for small subband speech energies */ SNR_Q7 = SKP_SMULWB( SKP_LSHIFT( SKP_Silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); } input_tilt = SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); } else { NrgToNoiseRatio_Q8[ b ] = 256; } } /* Mean-of-squares */ sumSquared = SKP_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ /* Root-mean-square approximation, scale to dBs, and write to output pointer */ *pSNR_dB_Q7 = ( SKP_int16 )( 3 * SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ /*********************************/ /* Speech Probability Estimation */ /*********************************/ SA_Q15 = SKP_Silk_sigm_Q15( SKP_SMULWB( VAD_SNR_FACTOR_Q16, *pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); /**************************/ /* Frequency Tilt Measure */ /**************************/ *pTilt_Q15 = SKP_LSHIFT( SKP_Silk_sigm_Q15( input_tilt ) - 16384, 1 ); /**************************************************/ /* Scale the sigmoid output based on power levels */ /**************************************************/ speech_nrg = 0; for( b = 0; b < VAD_N_BANDS; b++ ) { /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ speech_nrg += ( b + 1 ) * SKP_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); } /* Power scaling */ if( speech_nrg <= 0 ) { SA_Q15 = SKP_RSHIFT( SA_Q15, 1 ); } else if( speech_nrg < 32768 ) { /* square-root */ speech_nrg = SKP_Silk_SQRT_APPROX( SKP_LSHIFT( speech_nrg, 15 ) ); SA_Q15 = SKP_SMULWB( 32768 + speech_nrg, SA_Q15 ); } /* Copy the resulting speech activity in Q8 to *pSA_Q8 */ *pSA_Q8 = SKP_min_int( SKP_RSHIFT( SA_Q15, 7 ), SKP_uint8_MAX ); /***********************************/ /* Energy Level and SNR estimation */ /***********************************/ /* Smoothing coefficient */ smooth_coef_Q16 = SKP_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, SKP_SMULWB( SA_Q15, SA_Q15 ) ); for( b = 0; b < VAD_N_BANDS; b++ ) { /* compute smoothed energy-to-noise ratio per band */ psSilk_VAD->NrgRatioSmth_Q8[ b ] = SKP_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); /* signal to noise ratio in dB per band */ SNR_Q7 = 3 * ( SKP_Silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ pQuality_Q15[ b ] = SKP_Silk_sigm_Q15( SKP_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); } return( ret ); } /**************************/ /* Noise level estimation */ /**************************/ void SKP_Silk_VAD_GetNoiseLevels( const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ) { SKP_int k; SKP_int32 nl, nrg, inv_nrg; SKP_int coef, min_coef; /* Initially faster smoothing */ if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */ min_coef = SKP_DIV32_16( SKP_int16_MAX, SKP_RSHIFT( psSilk_VAD->counter, 4 ) + 1 ); } else { min_coef = 0; } for( k = 0; k < VAD_N_BANDS; k++ ) { /* Get old noise level estimate for current band */ nl = psSilk_VAD->NL[ k ]; SKP_assert( nl >= 0 ); /* Add bias */ nrg = SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); SKP_assert( nrg > 0 ); /* Invert energies */ inv_nrg = SKP_DIV32( SKP_int32_MAX, nrg ); SKP_assert( inv_nrg >= 0 ); /* Less update when subband energy is high */ if( nrg > SKP_LSHIFT( nl, 3 ) ) { coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; } else if( nrg < nl ) { coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; } else { coef = SKP_SMULWB( SKP_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); } /* Initially faster smoothing */ coef = SKP_max_int( coef, min_coef ); /* Smooth inverse energies */ psSilk_VAD->inv_NL[ k ] = SKP_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef ); SKP_assert( psSilk_VAD->inv_NL[ k ] >= 0 ); /* Compute noise level by inverting again */ nl = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->inv_NL[ k ] ); SKP_assert( nl >= 0 ); /* Limit noise levels (guarantee 7 bits of head room) */ nl = SKP_min( nl, 0x00FFFFFF ); /* Store as part of state */ psSilk_VAD->NL[ k ] = nl; } /* Increment frame counter */ psSilk_VAD->counter++; } ================================================ FILE: app/jni/SKP_Silk_VQ_nearest_neighbor_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Entropy constrained MATRIX-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ void SKP_Silk_VQ_WMat_EC_FIX( SKP_int *ind, /* O index of best codebook vector */ SKP_int32 *rate_dist_Q14, /* O best weighted quantization error + mu * rate*/ const SKP_int16 *in_Q14, /* I input vector to be quantized */ const SKP_int32 *W_Q18, /* I weighting matrix */ const SKP_int16 *cb_Q14, /* I codebook */ const SKP_int16 *cl_Q6, /* I code length for each codebook vector */ const SKP_int mu_Q8, /* I tradeoff between weighted error and rate */ SKP_int L /* I number of vectors in codebook */ ) { SKP_int k; const SKP_int16 *cb_row_Q14; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 sum1_Q14, sum2_Q16, diff_Q14_01, diff_Q14_23, diff_Q14_4; #else SKP_int16 diff_Q14[ 5 ]; SKP_int32 sum1_Q14, sum2_Q16; #endif /* Loop over codebook */ *rate_dist_Q14 = SKP_int32_MAX; cb_row_Q14 = cb_Q14; for( k = 0; k < L; k++ ) { #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* Pack pairs of int16 values per int32 */ diff_Q14_01 = ( SKP_uint16 )( in_Q14[ 0 ] - cb_row_Q14[ 0 ] ) | SKP_LSHIFT( ( SKP_int32 )in_Q14[ 1 ] - cb_row_Q14[ 1 ], 16 ); diff_Q14_23 = ( SKP_uint16 )( in_Q14[ 2 ] - cb_row_Q14[ 2 ] ) | SKP_LSHIFT( ( SKP_int32 )in_Q14[ 3 ] - cb_row_Q14[ 3 ], 16 ); diff_Q14_4 = in_Q14[ 4 ] - cb_row_Q14[ 4 ]; #else diff_Q14[ 0 ] = in_Q14[ 0 ] - cb_row_Q14[ 0 ]; diff_Q14[ 1 ] = in_Q14[ 1 ] - cb_row_Q14[ 1 ]; diff_Q14[ 2 ] = in_Q14[ 2 ] - cb_row_Q14[ 2 ]; diff_Q14[ 3 ] = in_Q14[ 3 ] - cb_row_Q14[ 3 ]; diff_Q14[ 4 ] = in_Q14[ 4 ] - cb_row_Q14[ 4 ]; #endif /* Weighted rate */ sum1_Q14 = SKP_SMULBB( mu_Q8, cl_Q6[ k ] ); SKP_assert( sum1_Q14 >= 0 ); #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* Add weighted quantization error, assuming W_Q18 is symmetric */ /* NOTE: the code below loads two int16 values as one int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ /* first row of W_Q18 */ sum2_Q16 = SKP_SMULWT( W_Q18[ 1 ], diff_Q14_01 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14_23 ); sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 3 ], diff_Q14_23 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14_4 ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14_01 ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_01 ); /* second row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 7 ], diff_Q14_23 ); sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 8 ], diff_Q14_23 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14_4 ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 6 ], diff_Q14_01 ); sum1_Q14 = SKP_SMLAWT( sum1_Q14, sum2_Q16, diff_Q14_01 ); /* third row of W_Q18 */ sum2_Q16 = SKP_SMULWT( W_Q18[ 13 ], diff_Q14_23 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14_4 ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14_23 ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_23 ); /* fourth row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 19 ], diff_Q14_4 ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 18 ], diff_Q14_23 ); sum1_Q14 = SKP_SMLAWT( sum1_Q14, sum2_Q16, diff_Q14_23 ); /* last row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 24 ], diff_Q14_4 ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_4 ); #else /* first row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] ); /* second row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] ); /* third row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] ); /* fourth row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] ); sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 ); sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] ); /* last row of W_Q18 */ sum2_Q16 = SKP_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] ); sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] ); #endif SKP_assert( sum1_Q14 >= 0 ); /* find best */ if( sum1_Q14 < *rate_dist_Q14 ) { *rate_dist_Q14 = sum1_Q14; *ind = k; } /* Go to next cbk vector */ cb_row_Q14 += LTP_ORDER; } } ================================================ FILE: app/jni/SKP_Silk_ana_filt_bank_1.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_ana_filt_bank_1.c * * * * Split signal into two decimated bands using first-order allpass filters * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" #if EMBEDDED_ARM<5 /* Coefficients for 2-band filter bank based on first-order allpass filters */ // old static SKP_int16 A_fb1_20[ 1 ] = { 5394 << 1 }; static SKP_int16 A_fb1_21[ 1 ] = { 20623 << 1 }; /* wrap-around to negative number is intentional */ /* Split signal into two decimated bands using first-order allpass filters */ void SKP_Silk_ana_filt_bank_1( const SKP_int16 *in, /* I: Input signal [N] */ SKP_int32 *S, /* I/O: State vector [2] */ SKP_int16 *outL, /* O: Low band [N/2] */ SKP_int16 *outH, /* O: High band [N/2] */ SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */ // todo: remove - no longer used const SKP_int32 N /* I: Number of input samples */ ) { SKP_int k, N2 = SKP_RSHIFT( N, 1 ); SKP_int32 in32, X, Y, out_1, out_2; /* Internal variables and state are in Q10 format */ for( k = 0; k < N2; k++ ) { /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 ); /* All-pass section for even input sample */ Y = SKP_SUB32( in32, S[ 0 ] ); X = SKP_SMLAWB( Y, Y, A_fb1_21[ 0 ] ); out_1 = SKP_ADD32( S[ 0 ], X ); S[ 0 ] = SKP_ADD32( in32, X ); /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 ); /* All-pass section for odd input sample */ Y = SKP_SUB32( in32, S[ 1 ] ); X = SKP_SMULWB( Y, A_fb1_20[ 0 ] ); out_2 = SKP_ADD32( S[ 1 ], X ); S[ 1 ] = SKP_ADD32( in32, X ); /* Add/subtract, convert back to int16 and store to output */ outL[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_ADD32( out_2, out_1 ), 11 ) ); outH[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( out_2, out_1 ), 11 ) ); } } #endif ================================================ FILE: app/jni/SKP_Silk_apply_sine_window.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" /* Apply sine window to signal vector. */ /* Window types: */ /* 1 -> sine window from 0 to pi/2 */ /* 2 -> sine window from pi/2 to pi */ /* Every other sample is linearly interpolated, for speed. */ /* Window length must be between 16 and 120 (incl) and a multiple of 4. */ /* Matlab code for table: for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end */ static SKP_int16 freq_table_Q16[ 27 ] = { 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, }; //#if EMBEDDED_ARM<6 void SKP_Silk_apply_sine_window( SKP_int16 px_win[], /* O Pointer to windowed signal */ const SKP_int16 px[], /* I Pointer to input signal */ const SKP_int win_type, /* I Selects a window type */ const SKP_int length /* I Window length, multiple of 4 */ ) { SKP_int k, f_Q16, c_Q16; SKP_int32 S0_Q16, S1_Q16; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 px32; #endif SKP_assert( win_type == 1 || win_type == 2 ); /* Length must be in a range from 16 to 120 and a multiple of 4 */ SKP_assert( length >= 16 && length <= 120 ); SKP_assert( ( length & 3 ) == 0 ); /* Input pointer must be 4-byte aligned */ SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )px - ( SKP_int8* )0 ) & 3 ) == 0 ); /* Frequency */ k = ( length >> 2 ) - 4; SKP_assert( k >= 0 && k <= 26 ); f_Q16 = (SKP_int)freq_table_Q16[ k ]; /* Factor used for cosine approximation */ c_Q16 = SKP_SMULWB( f_Q16, -f_Q16 ); SKP_assert( c_Q16 >= -32768 ); /* initialize state */ if( win_type == 1 ) { /* start from 0 */ S0_Q16 = 0; /* approximation of sin(f) */ S1_Q16 = f_Q16 + SKP_RSHIFT( length, 3 ); } else { /* start from 1 */ S0_Q16 = ( 1 << 16 ); /* approximation of cos(f) */ S1_Q16 = ( 1 << 16 ) + SKP_RSHIFT( c_Q16, 1 ) + SKP_RSHIFT( length, 4 ); } /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ /* 4 samples at a time */ #if !defined(_SYSTEM_IS_BIG_ENDIAN) for( k = 0; k < length; k += 4 ) { px32 = *( (SKP_int32 *)&px[ k ] ); /* load two values at once */ px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px32 ); px_win[ k + 1 ] = (SKP_int16)SKP_SMULWT( S1_Q16, px32 ); S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) ); px32 = *( (SKP_int32 *)&px[k + 2] ); /* load two values at once */ px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px32 ); px_win[ k + 3 ] = (SKP_int16)SKP_SMULWT( S0_Q16, px32 ); S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16; S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) ); } #else for( k = 0; k < length; k += 4 ) { px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); px_win[ k + 1 ] = (SKP_int16)SKP_SMULWB( S1_Q16, px[ k + 1] ); S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) ); px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); px_win[ k + 3 ] = (SKP_int16)SKP_SMULWB( S0_Q16, px[ k + 3 ] ); S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16; S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) ); } #endif } //#endif ================================================ FILE: app/jni/SKP_Silk_array_maxabs.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_int16_array_maxabs.c * * * * Function that returns the maximum absolut value of * * the input vector * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Function that returns the maximum absolut value of the input vector */ #if (EMBEDDED_ARM<4) SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ const SKP_int16 *vec, /* I Input vector [len] */ const SKP_int32 len /* I Length of input vector */ ) { SKP_int32 max = 0, i, lvl = 0, ind; if( len == 0 ) return 0; ind = len - 1; max = SKP_SMULBB( vec[ ind ], vec[ ind ] ); for( i = len - 2; i >= 0; i-- ) { lvl = SKP_SMULBB( vec[ i ], vec[ i ] ); if( lvl > max ) { max = lvl; ind = i; } } /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */ if( max >= 1073676289 ) { // (2^15-1)^2 = 1073676289 return( SKP_int16_MAX ); } else { if( vec[ ind ] < 0 ) { return( -vec[ ind ] ); } else { return( vec[ ind ] ); } } } #endif ================================================ FILE: app/jni/SKP_Silk_autocorr.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_autocorr.c * * * * Calculates the autocorrelation * * The result has 29 non-zero bits for the first correlation, to leave * * some room for adding white noise fractions etc. * * * * Copyright 2008 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" /* Compute autocorrelation */ void SKP_Silk_autocorr( SKP_int32 *results, /* O Result (length correlationCount) */ SKP_int *scale, /* O Scaling of the correlation vector */ const SKP_int16 *inputData, /* I Input data to correlate */ const SKP_int inputDataSize, /* I Length of input */ const SKP_int correlationCount /* I Number of correlation taps to compute */ ) { SKP_int i, lz, nRightShifts, corrCount; SKP_int64 corr64; corrCount = SKP_min_int( inputDataSize, correlationCount ); /* compute energy (zero-lag correlation) */ corr64 = SKP_Silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize ); /* deal with all-zero input data */ corr64 += 1; /* number of leading zeros */ lz = SKP_Silk_CLZ64( corr64 ); /* scaling: number of right shifts applied to correlations */ nRightShifts = 35 - lz; *scale = nRightShifts; if( nRightShifts <= 0 ) { results[ 0 ] = SKP_LSHIFT( (SKP_int32)SKP_CHECK_FIT32( corr64 ), -nRightShifts ); /* compute remaining correlations based on int32 inner product */ for( i = 1; i < corrCount; i++ ) { results[ i ] = SKP_LSHIFT( SKP_Silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts ); } } else { results[ 0 ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( corr64, nRightShifts ) ); /* compute remaining correlations based on int64 inner product */ for( i = 1; i < corrCount; i++ ) { results[ i ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_Silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) ); } } } ================================================ FILE: app/jni/SKP_Silk_biquad.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_biquad.c * * * * Second order ARMA filter * * Can handle slowly varying filter coefficients * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Second order ARMA filter */ /* Can handle slowly varying filter coefficients */ void SKP_Silk_biquad( const SKP_int16 *in, /* I: input signal */ const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */ const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */ SKP_int32 *S, /* I/O: state vector [2] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len /* I: signal length */ ) { SKP_int k, in16; SKP_int32 A0_neg, A1_neg, S0, S1, out32, tmp32; S0 = S[ 0 ]; S1 = S[ 1 ]; A0_neg = -A[ 0 ]; A1_neg = -A[ 1 ]; for( k = 0; k < len; k++ ) { /* S[ 0 ], S[ 1 ]: Q13 */ in16 = in[ k ]; out32 = SKP_SMLABB( S0, in16, B[ 0 ] ); S0 = SKP_SMLABB( S1, in16, B[ 1 ] ); S0 += SKP_LSHIFT( SKP_SMULWB( out32, A0_neg ), 3 ); S1 = SKP_LSHIFT( SKP_SMULWB( out32, A1_neg ), 3 ); S1 = SKP_SMLABB( S1, in16, B[ 2 ] ); tmp32 = SKP_RSHIFT_ROUND( out32, 13 ) + 1; out[ k ] = (SKP_int16)SKP_SAT16( tmp32 ); } S[ 0 ] = S0; S[ 1 ] = S1; } ================================================ FILE: app/jni/SKP_Silk_biquad_alt.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_biquad_alt.c * * * * Second order ARMA filter * * Can handle slowly varying filter coefficients * * */ #include "SKP_Silk_SigProc_FIX.h" /* Second order ARMA filter, alternative implementation */ void SKP_Silk_biquad_alt( const SKP_int16 *in, /* I: Input signal */ const SKP_int32 *B_Q28, /* I: MA coefficients [3] */ const SKP_int32 *A_Q28, /* I: AR coefficients [2] */ SKP_int32 *S, /* I/O: State vector [2] */ SKP_int16 *out, /* O: Output signal */ const SKP_int32 len /* I: Signal length (must be even) */ ) { /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ SKP_int k; SKP_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14; /* Negate A_Q28 values and split in two parts */ A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ A0_U_Q28 = SKP_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ A1_U_Q28 = SKP_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ for( k = 0; k < len; k++ ) { /* S[ 0 ], S[ 1 ]: Q12 */ inval = in[ k ]; out32_Q14 = SKP_LSHIFT( SKP_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 ); S[ 0 ] = S[1] + SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A0_L_Q28 ), 14 ); S[ 0 ] = SKP_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 ); S[ 0 ] = SKP_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval); S[ 1 ] = SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A1_L_Q28 ), 14 ); S[ 1 ] = SKP_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 ); S[ 1 ] = SKP_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval ); /* Scale back to Q0 and saturate */ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) ); } } ================================================ FILE: app/jni/SKP_Silk_burg_modified.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_burg_modified.c * * * * Calculates the reflection coefficients from the input vector * * Input vector contains nb_subfr sub vectors of length L_sub + D * * * * Copyright 2009 (c), Skype Limited * * Date: 100105 * */ #include "SKP_Silk_SigProc_FIX.h" #define MAX_FRAME_SIZE 544 // subfr_length * nb_subfr = ( 0.005 * 24000 + 16 ) * 4 = 544 #define MAX_NB_SUBFR 4 #define QA 25 #define N_BITS_HEAD_ROOM 2 #define MIN_RSHIFTS -16 #define MAX_RSHIFTS (32 - QA) /* Compute reflection coefficients from input signal */ void SKP_Silk_burg_modified( SKP_int32 *res_nrg, /* O residual energy */ SKP_int *res_nrg_Q, /* O residual energy Q value */ SKP_int32 A_Q16[], /* O prediction coefficients (length order) */ const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */ const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */ const SKP_int nb_subfr, /* I number of subframes stacked in x */ const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */ const SKP_int D /* I order */ ) { SKP_int k, n, s, lz, rshifts, rshifts_extra; SKP_int32 C0, num, nrg, rc_Q31, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; const SKP_int16 *x_ptr; SKP_int32 C_first_row[ SKP_Silk_MAX_ORDER_LPC ]; SKP_int32 C_last_row[ SKP_Silk_MAX_ORDER_LPC ]; SKP_int32 Af_QA[ SKP_Silk_MAX_ORDER_LPC ]; SKP_int32 CAf[ SKP_Silk_MAX_ORDER_LPC + 1 ]; SKP_int32 CAb[ SKP_Silk_MAX_ORDER_LPC + 1 ]; SKP_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); SKP_assert( nb_subfr <= MAX_NB_SUBFR ); /* Compute autocorrelations, added over subframes */ SKP_Silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length ); if( rshifts > MAX_RSHIFTS ) { C0 = SKP_LSHIFT32( C0, rshifts - MAX_RSHIFTS ); SKP_assert( C0 > 0 ); rshifts = MAX_RSHIFTS; } else { lz = SKP_Silk_CLZ32( C0 ) - 1; rshifts_extra = N_BITS_HEAD_ROOM - lz; if( rshifts_extra > 0 ) { rshifts_extra = SKP_min( rshifts_extra, MAX_RSHIFTS - rshifts ); C0 = SKP_RSHIFT32( C0, rshifts_extra ); } else { rshifts_extra = SKP_max( rshifts_extra, MIN_RSHIFTS - rshifts ); C0 = SKP_LSHIFT32( C0, -rshifts_extra ); } rshifts += rshifts_extra; } SKP_memset( C_first_row, 0, SKP_Silk_MAX_ORDER_LPC * sizeof( SKP_int32 ) ); if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += (SKP_int32)SKP_RSHIFT64( SKP_Silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts ); } } } else { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += SKP_LSHIFT32( SKP_Silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts ); } } } SKP_memcpy( C_last_row, C_first_row, SKP_Silk_MAX_ORDER_LPC * sizeof( SKP_int32 ) ); /* Initialize */ CAb[ 0 ] = CAf[ 0 ] = C0 + SKP_SMMUL( WhiteNoiseFrac_Q32, C0 ) + 1; // Q(-rshifts) for( n = 0; n < D; n++ ) { /* Update first row of correlation matrix (without first element) */ /* Update last row of correlation matrix (without last element, stored in reversed order) */ /* Update C * Af */ /* Update C * flipud(Af) (stored in reversed order) */ if( rshifts > -2 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; x1 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], 16 - rshifts ); // Q(16-rshifts) x2 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); // Q(16-rshifts) tmp1 = SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], QA - 16 ); // Q(QA-16) tmp2 = SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); // Q(QA-16) for( k = 0; k < n; k++ ) { C_first_row[ k ] = SKP_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); // Q( -rshifts ) C_last_row[ k ] = SKP_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); // Q( -rshifts ) Atmp_QA = Af_QA[ k ]; tmp1 = SKP_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); // Q(QA-16) tmp2 = SKP_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); // Q(QA-16) } tmp1 = SKP_LSHIFT32( -tmp1, 32 - QA - rshifts ); // Q(16-rshifts) tmp2 = SKP_LSHIFT32( -tmp2, 32 - QA - rshifts ); // Q(16-rshifts) for( k = 0; k <= n; k++ ) { CAf[ k ] = SKP_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); // Q( -rshift ) CAb[ k ] = SKP_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); // Q( -rshift ) } } } else { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; x1 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], -rshifts ); // Q( -rshifts ) x2 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); // Q( -rshifts ) tmp1 = SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], 17 ); // Q17 tmp2 = SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], 17 ); // Q17 for( k = 0; k < n; k++ ) { C_first_row[ k ] = SKP_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); // Q( -rshifts ) C_last_row[ k ] = SKP_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); // Q( -rshifts ) Atmp1 = SKP_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); // Q17 tmp1 = SKP_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); // Q17 tmp2 = SKP_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); // Q17 } tmp1 = -tmp1; // Q17 tmp2 = -tmp2; // Q17 for( k = 0; k <= n; k++ ) { CAf[ k ] = SKP_SMLAWW( CAf[ k ], tmp1, SKP_LSHIFT32( (SKP_int32)x_ptr[ n - k ], -rshifts - 1 ) ); // Q( -rshift ) CAb[ k ] = SKP_SMLAWW( CAb[ k ], tmp2, SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) );// Q( -rshift ) } } } /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ tmp1 = C_first_row[ n ]; // Q( -rshifts ) tmp2 = C_last_row[ n ]; // Q( -rshifts ) num = 0; // Q( -rshifts ) nrg = SKP_ADD32( CAb[ 0 ], CAf[ 0 ] ); // Q( 1-rshifts ) for( k = 0; k < n; k++ ) { Atmp_QA = Af_QA[ k ]; lz = SKP_Silk_CLZ32( SKP_abs( Atmp_QA ) ) - 1; lz = SKP_min( 32 - QA, lz ); Atmp1 = SKP_LSHIFT32( Atmp_QA, lz ); // Q( QA + lz ) tmp1 = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts ) tmp2 = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts ) num = SKP_ADD_LSHIFT32( num, SKP_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts ) nrg = SKP_ADD_LSHIFT32( nrg, SKP_SMMUL( SKP_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), Atmp1 ), 32 - QA - lz ); // Q( 1-rshifts ) } CAf[ n + 1 ] = tmp1; // Q( -rshifts ) CAb[ n + 1 ] = tmp2; // Q( -rshifts ) num = SKP_ADD32( num, tmp2 ); // Q( -rshifts ) num = SKP_LSHIFT32( -num, 1 ); // Q( 1-rshifts ) /* Calculate the next order reflection (parcor) coefficient */ if( SKP_abs( num ) < nrg ) { rc_Q31 = SKP_DIV32_varQ( num, nrg, 31 ); } else { /* Negative energy or ratio too high; set remaining coefficients to zero and exit loop */ SKP_memset( &Af_QA[ n ], 0, ( D - n ) * sizeof( SKP_int32 ) ); SKP_assert( 0 ); break; } /* Update the AR coefficients */ for( k = 0; k < (n + 1) >> 1; k++ ) { tmp1 = Af_QA[ k ]; // QA tmp2 = Af_QA[ n - k - 1 ]; // QA Af_QA[ k ] = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( tmp2, rc_Q31 ), 1 ); // QA Af_QA[ n - k - 1 ] = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( tmp1, rc_Q31 ), 1 ); // QA } Af_QA[ n ] = SKP_RSHIFT32( rc_Q31, 31 - QA ); // QA /* Update C * Af and C * Ab */ for( k = 0; k <= n + 1; k++ ) { tmp1 = CAf[ k ]; // Q( -rshifts ) tmp2 = CAb[ n - k + 1 ]; // Q( -rshifts ) CAf[ k ] = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( tmp2, rc_Q31 ), 1 ); // Q( -rshifts ) CAb[ n - k + 1 ] = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( tmp1, rc_Q31 ), 1 ); // Q( -rshifts ) } } /* Return residual energy */ nrg = CAf[ 0 ]; // Q( -rshifts ) tmp1 = 1 << 16; // Q16 for( k = 0; k < D; k++ ) { Atmp1 = SKP_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); // Q16 nrg = SKP_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); // Q( -rshifts ) tmp1 = SKP_SMLAWW( tmp1, Atmp1, Atmp1 ); // Q16 A_Q16[ k ] = -Atmp1; } *res_nrg = SKP_SMLAWW( nrg, SKP_SMMUL( WhiteNoiseFrac_Q32, C0 ), -tmp1 ); // Q( -rshifts ) *res_nrg_Q = -rshifts; } ================================================ FILE: app/jni/SKP_Silk_bwexpander.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" /* Chirp (bandwidth expand) LP AR filter */ void SKP_Silk_bwexpander( SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ const SKP_int d, /* I Length of ar */ SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ ) { SKP_int i; SKP_int32 chirp_minus_one_Q16; chirp_minus_one_Q16 = chirp_Q16 - 65536; /* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL() , 16 ), below. */ /* Bias in SKP_SMULWB can lead to unstable filters */ for( i = 0; i < d - 1; i++ ) { ar[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ i ] ), 16 ); chirp_Q16 += SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); } ar[ d - 1 ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); } ================================================ FILE: app/jni/SKP_Silk_bwexpander_32.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" /* Chirp (bandwidth expand) LP AR filter */ void SKP_Silk_bwexpander_32( SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ const SKP_int d, /* I Length of ar */ SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */ ) { SKP_int i; SKP_int32 tmp_chirp_Q16; tmp_chirp_Q16 = chirp_Q16; for( i = 0; i < d - 1; i++ ) { ar[ i ] = SKP_SMULWW( ar[ i ], tmp_chirp_Q16 ); tmp_chirp_Q16 = SKP_SMULWW( chirp_Q16, tmp_chirp_Q16 ); } ar[ d - 1 ] = SKP_SMULWW( ar[ d - 1 ], tmp_chirp_Q16 ); } ================================================ FILE: app/jni/SKP_Silk_code_signs.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" //#define SKP_enc_map(a) ((a) > 0 ? 1 : 0) //#define SKP_dec_map(a) ((a) > 0 ? 1 : -1) /* shifting avoids if-statement */ #define SKP_enc_map(a) ( SKP_RSHIFT( (a), 15 ) + 1 ) #define SKP_dec_map(a) ( SKP_LSHIFT( (a), 1 ) - 1 ) /* Encodes signs of excitation */ void SKP_Silk_encode_signs( SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */ const SKP_int8 q[], /* I Pulse signal */ const SKP_int length, /* I Length of input */ const SKP_int sigtype, /* I Signal type */ const SKP_int QuantOffsetType, /* I Quantization offset type */ const SKP_int RateLevelIndex /* I Rate level index */ ) { SKP_int i; SKP_int inData; SKP_uint16 cdf[ 3 ]; i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex; cdf[ 0 ] = 0; cdf[ 1 ] = SKP_Silk_sign_CDF[ i ]; cdf[ 2 ] = 65535; for( i = 0; i < length; i++ ) { if( q[ i ] != 0 ) { inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */ SKP_Silk_range_encoder( sRC, inData, cdf ); } } } /* Decodes signs of excitation */ void SKP_Silk_decode_signs( SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */ SKP_int q[], /* I/O pulse signal */ const SKP_int length, /* I length of output */ const SKP_int sigtype, /* I Signal type */ const SKP_int QuantOffsetType, /* I Quantization offset type */ const SKP_int RateLevelIndex /* I Rate Level Index */ ) { SKP_int i; SKP_int data; SKP_uint16 cdf[ 3 ]; i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex; cdf[ 0 ] = 0; cdf[ 1 ] = SKP_Silk_sign_CDF[ i ]; cdf[ 2 ] = 65535; for( i = 0; i < length; i++ ) { if( q[ i ] > 0 ) { SKP_Silk_range_decoder( &data, sRC, cdf, 1 ); /* attach sign */ /* implementation with shift, subtraction, multiplication */ q[ i ] *= SKP_dec_map( data ); } } } ================================================ FILE: app/jni/SKP_Silk_control_audio_bandwidth.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Control internal sampling rate */ SKP_int SKP_Silk_control_audio_bandwidth( SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */ ) { SKP_int fs_kHz; fs_kHz = psEncC->fs_kHz; if( fs_kHz == 0 ) { /* Encoder has just been initialized */ if( TargetRate_bps >= SWB2WB_BITRATE_BPS ) { fs_kHz = 24; } else if( TargetRate_bps >= WB2MB_BITRATE_BPS ) { fs_kHz = 16; } else if( TargetRate_bps >= MB2NB_BITRATE_BPS ) { fs_kHz = 12; } else { fs_kHz = 8; } /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ fs_kHz = SKP_min( fs_kHz, SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ) ); fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz ); } else if( SKP_SMULBB( fs_kHz, 1000 ) > psEncC->API_fs_Hz || fs_kHz > psEncC->maxInternal_fs_kHz ) { /* Make sure internal rate is not higher than external rate or maximum allowed */ fs_kHz = SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ); fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz ); } else { /* State machine for the internal sampling rate switching */ if( psEncC->API_fs_Hz > 8000 ) { /* Accumulate the difference between the target rate and limit for switching down */ psEncC->bitrateDiff += SKP_MUL( psEncC->PacketSize_ms, TargetRate_bps - psEncC->bitrate_threshold_down ); psEncC->bitrateDiff = SKP_min( psEncC->bitrateDiff, 0 ); if( psEncC->vadFlag == NO_VOICE_ACTIVITY ) { /* Low speech activity */ /* Check if we should switch down */ #if SWITCH_TRANSITION_FILTERING if( ( psEncC->sLP.transition_frame_no == 0 ) && /* Transition phase not active */ ( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */ ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */ psEncC->sLP.transition_frame_no = 1; /* Begin transition phase */ psEncC->sLP.mode = 0; /* Switch down */ } else if( ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */ ( psEncC->sLP.mode == 0 ) ) { /* Ready to switch down */ psEncC->sLP.transition_frame_no = 0; /* Ready for new transition phase */ #else if( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */ #endif psEncC->bitrateDiff = 0; /* Switch to a lower sample frequency */ if( psEncC->fs_kHz == 24 ) { fs_kHz = 16; } else if( psEncC->fs_kHz == 16 ) { fs_kHz = 12; } else { SKP_assert( psEncC->fs_kHz == 12 ); fs_kHz = 8; } } /* Check if we should switch up */ if( ( ( psEncC->fs_kHz * 1000 < psEncC->API_fs_Hz ) && ( TargetRate_bps >= psEncC->bitrate_threshold_up ) && ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz < 16 ) ) && ( ( ( psEncC->fs_kHz == 16 ) && ( psEncC->maxInternal_fs_kHz >= 24 ) ) || ( ( psEncC->fs_kHz == 12 ) && ( psEncC->maxInternal_fs_kHz >= 16 ) ) || ( ( psEncC->fs_kHz == 8 ) && ( psEncC->maxInternal_fs_kHz >= 12 ) ) ) #if SWITCH_TRANSITION_FILTERING && ( psEncC->sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */ psEncC->sLP.mode = 1; /* Switch up */ #else ) { #endif psEncC->bitrateDiff = 0; /* Switch to a higher sample frequency */ if( psEncC->fs_kHz == 8 ) { fs_kHz = 12; } else if( psEncC->fs_kHz == 12 ) { fs_kHz = 16; } else { SKP_assert( psEncC->fs_kHz == 16 ); fs_kHz = 24; } } } } #if SWITCH_TRANSITION_FILTERING /* After switching up, stop transition filter during speech inactivity */ if( ( psEncC->sLP.mode == 1 ) && ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) && ( psEncC->vadFlag == NO_VOICE_ACTIVITY ) ) { psEncC->sLP.transition_frame_no = 0; /* Reset transition filter state */ SKP_memset( psEncC->sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) ); } #endif } return fs_kHz; } ================================================ FILE: app/jni/SKP_Silk_control_codec_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_setup_complexity.h" SKP_INLINE SKP_int SKP_Silk_setup_resamplers_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int fs_kHz /* I Internal sampling rate (kHz) */ ); SKP_INLINE SKP_int SKP_Silk_setup_packetsize_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int PacketSize_ms /* I Packet length (ms) */ ); SKP_INLINE SKP_int SKP_Silk_setup_fs_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int fs_kHz /* I Internal sampling rate (kHz) */ ); SKP_INLINE SKP_int SKP_Silk_setup_rate_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int32 TargetRate_bps /* I Target max bitrate (if SNR_dB == 0) */ ); SKP_INLINE SKP_int SKP_Silk_setup_LBRR_FIX( SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk encoder state FIX */ ); /* Control encoder */ SKP_int SKP_Silk_control_encoder_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */ const SKP_int PacketSize_ms, /* I Packet length (ms) */ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */ const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */ const SKP_int DTX_enabled, /* I Enable / disable DTX */ const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ ) { SKP_int fs_kHz, ret = 0; if( psEnc->sCmn.controlled_since_last_payload != 0 ) { if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) { /* Change in API sampling rate in the middle of encoding a packet */ ret += SKP_Silk_setup_resamplers_FIX( psEnc, psEnc->sCmn.fs_kHz ); } return ret; } /* Beyond this point we know that there are no previously coded frames in the payload buffer */ /********************************************/ /* Determine internal sampling rate */ /********************************************/ fs_kHz = SKP_Silk_control_audio_bandwidth( &psEnc->sCmn, TargetRate_bps ); /********************************************/ /* Prepare resampler and buffered data */ /********************************************/ ret += SKP_Silk_setup_resamplers_FIX( psEnc, fs_kHz ); /********************************************/ /* Set packet size */ /********************************************/ ret += SKP_Silk_setup_packetsize_FIX( psEnc, PacketSize_ms ); /********************************************/ /* Set internal sampling frequency */ /********************************************/ ret += SKP_Silk_setup_fs_FIX( psEnc, fs_kHz ); /********************************************/ /* Set encoding complexity */ /********************************************/ ret += SKP_Silk_setup_complexity( &psEnc->sCmn, Complexity ); /********************************************/ /* Set bitrate/coding quality */ /********************************************/ ret += SKP_Silk_setup_rate_FIX( psEnc, TargetRate_bps ); /********************************************/ /* Set packet loss rate measured by farend */ /********************************************/ if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) { ret = SKP_SILK_ENC_INVALID_LOSS_RATE; } psEnc->sCmn.PacketLoss_perc = PacketLoss_perc; /********************************************/ /* Set LBRR usage */ /********************************************/ ret += SKP_Silk_setup_LBRR_FIX( psEnc ); /********************************************/ /* Set DTX mode */ /********************************************/ if( DTX_enabled < 0 || DTX_enabled > 1 ) { ret = SKP_SILK_ENC_INVALID_DTX_SETTING; } psEnc->sCmn.useDTX = DTX_enabled; psEnc->sCmn.controlled_since_last_payload = 1; return ret; } /* Control low bitrate redundancy usage */ void SKP_Silk_LBRR_ctrl_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I Encoder state FIX */ SKP_Silk_encoder_control *psEncCtrlC /* I/O Encoder control */ ) { SKP_int LBRR_usage; if( psEnc->sCmn.LBRR_enabled ) { /* Control LBRR */ /* Usage Control based on sensitivity and packet loss caracteristics */ /* For now only enable adding to next for active frames. Make more complex later */ LBRR_usage = SKP_SILK_NO_LBRR; if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { // nb! maybe multiply loss prob and speech activity LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS1; } psEncCtrlC->LBRR_usage = LBRR_usage; } else { psEncCtrlC->LBRR_usage = SKP_SILK_NO_LBRR; } } SKP_INLINE SKP_int SKP_Silk_setup_resamplers_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int fs_kHz /* I Internal sampling rate (kHz) */ ) { SKP_int ret = SKP_SILK_NO_ERROR; if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) { if( psEnc->sCmn.fs_kHz == 0 ) { /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000 ); } else { /* Allocate space for worst case temporary upsampling, 8 to 48 kHz, so a factor 6 */ SKP_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * ( MAX_API_FS_KHZ / 8 ) ]; SKP_int32 nSamples_temp = SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + LA_SHAPE_MS * psEnc->sCmn.fs_kHz; if( SKP_SMULBB( fs_kHz, 1000 ) < psEnc->sCmn.API_fs_Hz && psEnc->sCmn.fs_kHz != 0 ) { /* Resample buffered data in x_buf to API_fs_Hz */ SKP_Silk_resampler_state_struct temp_resampler_state; /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ ret += SKP_Silk_resampler_init( &temp_resampler_state, SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz ); /* Temporary resampling of x_buf data to API_fs_Hz */ ret += SKP_Silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, psEnc->x_buf, nSamples_temp ); /* Calculate number of samples that has been temporarily upsampled */ nSamples_temp = SKP_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) ); /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, SKP_SMULBB( fs_kHz, 1000 ) ); } else { /* Copy data */ SKP_memcpy( x_buf_API_fs_Hz, psEnc->x_buf, nSamples_temp * sizeof( SKP_int16 ) ); } if( 1000 * fs_kHz != psEnc->sCmn.API_fs_Hz ) { /* Correct resampler state (unless resampling by a factor 1) by resampling buffered data from API_fs_Hz to fs_kHz */ ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state, psEnc->x_buf, x_buf_API_fs_Hz, nSamples_temp ); } } } psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz; return(ret); } SKP_INLINE SKP_int SKP_Silk_setup_packetsize_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int PacketSize_ms /* I Packet length (ms) */ ) { SKP_int ret = SKP_SILK_NO_ERROR; /* Set packet size */ if( ( PacketSize_ms != 20 ) && ( PacketSize_ms != 40 ) && ( PacketSize_ms != 60 ) && ( PacketSize_ms != 80 ) && ( PacketSize_ms != 100 ) ) { ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; } else { if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) { psEnc->sCmn.PacketSize_ms = PacketSize_ms; /* Packet length changes. Reset LBRR buffer */ SKP_Silk_LBRR_reset( &psEnc->sCmn ); } } return(ret); } SKP_INLINE SKP_int SKP_Silk_setup_fs_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int fs_kHz /* I Internal sampling rate (kHz) */ ) { SKP_int ret = SKP_SILK_NO_ERROR; /* Set internal sampling frequency */ if( psEnc->sCmn.fs_kHz != fs_kHz ) { /* reset part of the state */ SKP_memset( &psEnc->sShape, 0, sizeof( SKP_Silk_shape_state_FIX ) ); SKP_memset( &psEnc->sPrefilt, 0, sizeof( SKP_Silk_prefilter_state_FIX ) ); SKP_memset( &psEnc->sPred, 0, sizeof( SKP_Silk_predict_state_FIX ) ); SKP_memset( &psEnc->sCmn.sNSQ, 0, sizeof( SKP_Silk_nsq_state ) ); SKP_memset( psEnc->sCmn.sNSQ_LBRR.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) ); SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) ); #if SWITCH_TRANSITION_FILTERING SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) ); if( psEnc->sCmn.sLP.mode == 1 ) { /* Begin transition phase */ psEnc->sCmn.sLP.transition_frame_no = 1; } else { /* End transition phase */ psEnc->sCmn.sLP.transition_frame_no = 0; } #endif psEnc->sCmn.inputBufIx = 0; psEnc->sCmn.nFramesInPayloadBuf = 0; psEnc->sCmn.nBytesInPayloadBuf = 0; psEnc->sCmn.oldest_LBRR_idx = 0; psEnc->sCmn.TargetRate_bps = 0; /* Ensures that psEnc->SNR_dB is recomputed */ SKP_memset( psEnc->sPred.prev_NLSFq_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) ); /* Initialize non-zero parameters */ psEnc->sCmn.prevLag = 100; psEnc->sCmn.prev_sigtype = SIG_TYPE_UNVOICED; psEnc->sCmn.first_frame_after_reset = 1; psEnc->sPrefilt.lagPrev = 100; psEnc->sShape.LastGainIndex = 1; psEnc->sCmn.sNSQ.lagPrev = 100; psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536; psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536; psEnc->sCmn.fs_kHz = fs_kHz; if( psEnc->sCmn.fs_kHz == 8 ) { psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER; psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10; psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10; } else { psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER; psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16; psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16; } psEnc->sCmn.frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz ); psEnc->sCmn.subfr_length = SKP_DIV32_16( psEnc->sCmn.frame_length, NB_SUBFR ); psEnc->sCmn.la_pitch = SKP_SMULBB( LA_PITCH_MS, fs_kHz ); psEnc->sPred.min_pitch_lag = SKP_SMULBB( 3, fs_kHz ); psEnc->sPred.max_pitch_lag = SKP_SMULBB( 18, fs_kHz ); psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); if( psEnc->sCmn.fs_kHz == 24 ) { psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_SWB, 8 ); psEnc->sCmn.bitrate_threshold_up = SKP_int32_MAX; psEnc->sCmn.bitrate_threshold_down = SWB2WB_BITRATE_BPS; } else if( psEnc->sCmn.fs_kHz == 16 ) { psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_WB, 8 ); psEnc->sCmn.bitrate_threshold_up = WB2SWB_BITRATE_BPS; psEnc->sCmn.bitrate_threshold_down = WB2MB_BITRATE_BPS; } else if( psEnc->sCmn.fs_kHz == 12 ) { psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_MB, 8 ); psEnc->sCmn.bitrate_threshold_up = MB2WB_BITRATE_BPS; psEnc->sCmn.bitrate_threshold_down = MB2NB_BITRATE_BPS; } else { psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_NB, 8 ); psEnc->sCmn.bitrate_threshold_up = NB2MB_BITRATE_BPS; psEnc->sCmn.bitrate_threshold_down = 0; } psEnc->sCmn.fs_kHz_changed = 1; /* Check that settings are valid */ SKP_assert( ( psEnc->sCmn.subfr_length * NB_SUBFR ) == psEnc->sCmn.frame_length ); } return( ret ); } SKP_INLINE SKP_int SKP_Silk_setup_rate_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */ SKP_int32 TargetRate_bps /* I Target max bitrate (if SNR_dB == 0) */ ) { SKP_int k, ret = SKP_SILK_NO_ERROR; SKP_int32 frac_Q6; const SKP_int32 *rateTable; /* Set bitrate/coding quality */ if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) { psEnc->sCmn.TargetRate_bps = TargetRate_bps; /* If new TargetRate_bps, translate to SNR_dB value */ if( psEnc->sCmn.fs_kHz == 8 ) { rateTable = TargetRate_table_NB; } else if( psEnc->sCmn.fs_kHz == 12 ) { rateTable = TargetRate_table_MB; } else if( psEnc->sCmn.fs_kHz == 16 ) { rateTable = TargetRate_table_WB; } else { rateTable = TargetRate_table_SWB; } for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) { /* Find bitrate interval in table and interpolate */ if( TargetRate_bps <= rateTable[ k ] ) { frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), rateTable[ k ] - rateTable[ k - 1 ] ); psEnc->SNR_dB_Q7 = SKP_LSHIFT( SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] ); break; } } } return( ret ); } SKP_INLINE SKP_int SKP_Silk_setup_LBRR_FIX( SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk encoder state FIX */ ) { SKP_int ret = SKP_SILK_NO_ERROR; #if USE_LBRR SKP_int32 LBRRRate_thres_bps; if( psEnc->sCmn.useInBandFEC < 0 || psEnc->sCmn.useInBandFEC > 1 ) { ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING; } psEnc->sCmn.LBRR_enabled = psEnc->sCmn.useInBandFEC; if( psEnc->sCmn.fs_kHz == 8 ) { LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000; } else if( psEnc->sCmn.fs_kHz == 12 ) { LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;; } else if( psEnc->sCmn.fs_kHz == 16 ) { LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000; } else { LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS; } if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) { /* Set gain increase / rate reduction for LBRR usage */ /* Coarsely tuned with PESQ for now. */ /* Linear regression coefs G = 8 - 0.5 * loss */ /* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */ psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 ); /* Set main stream rate compensation */ if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { /* Tuned to give approx same mean / weighted bitrate as no inband FEC */ psEnc->inBandFEC_SNR_comp_Q8 = SKP_FIX_CONST( 6.0f, 8 ) - SKP_LSHIFT( psEnc->sCmn.LBRR_GainIncreases, 7 ); } else { psEnc->inBandFEC_SNR_comp_Q8 = 0; psEnc->sCmn.LBRR_enabled = 0; } } else { psEnc->inBandFEC_SNR_comp_Q8 = 0; psEnc->sCmn.LBRR_enabled = 0; } #else if( INBandFEC_enabled != 0 ) { ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING; } psEnc->sCmn.LBRR_enabled = 0; #endif return ret; } ================================================ FILE: app/jni/SKP_Silk_corrMatrix_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /********************************************************************** * Correlation Matrix Computations for LS estimate. **********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Calculates correlation vector X'*t */ void SKP_Silk_corrVector_FIX( const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const SKP_int16 *t, /* I target vector [L] */ const SKP_int L, /* I Length of vectors */ const SKP_int order, /* I Max lag for correlation */ SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ const SKP_int rshifts /* I Right shifts of correlations */ ) { SKP_int lag, i; const SKP_int16 *ptr1, *ptr2; SKP_int32 inner_prod; ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ ptr2 = t; /* Calculate X'*t */ if( rshifts > 0 ) { /* Right shifting used */ for( lag = 0; lag < order; lag++ ) { inner_prod = 0; for( i = 0; i < L; i++ ) { inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); } Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ ptr1--; /* Go to next column of X */ } } else { SKP_assert( rshifts == 0 ); for( lag = 0; lag < order; lag++ ) { Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */ ptr1--; /* Go to next column of X */ } } } /* Calculates correlation matrix X'*X */ void SKP_Silk_corrMatrix_FIX( const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const SKP_int L, /* I Length of vectors */ const SKP_int order, /* I Max lag for correlation */ const SKP_int head_room, /* I Desired headroom */ SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/ SKP_int *rshifts /* I/O Right shifts of correlations */ ) { SKP_int i, j, lag, rshifts_local, head_room_rshifts; SKP_int32 energy; const SKP_int16 *ptr1, *ptr2; /* Calculate energy to find shift used to fit in 32 bits */ SKP_Silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 ); /* Add shifts to get the desired head room */ head_room_rshifts = SKP_max( head_room - SKP_Silk_CLZ32( energy ), 0 ); energy = SKP_RSHIFT32( energy, head_room_rshifts ); rshifts_local += head_room_rshifts; /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ /* Remove contribution of first order - 1 samples */ for( i = 0; i < order - 1; i++ ) { energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local ); } if( rshifts_local < *rshifts ) { /* Adjust energy */ energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local ); rshifts_local = *rshifts; } /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ /* Fill out the diagonal of the correlation matrix */ matrix_ptr( XX, 0, 0, order ) = energy; ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ for( j = 1; j < order; j++ ) { energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) ); energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) ); matrix_ptr( XX, j, j, order ) = energy; } ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ /* Calculate the remaining elements of the correlation matrix */ if( rshifts_local > 0 ) { /* Right shifting used */ for( lag = 1; lag < order; lag++ ) { /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ energy = 0; for( i = 0; i < L; i++ ) { energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local ); } /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ matrix_ptr( XX, lag, 0, order ) = energy; matrix_ptr( XX, 0, lag, order ) = energy; for( j = 1; j < ( order - lag ); j++ ) { energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) ); energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) ); matrix_ptr( XX, lag + j, j, order ) = energy; matrix_ptr( XX, j, lag + j, order ) = energy; } ptr2--; /* Update pointer to first sample of next column (lag) in X */ } } else { for( lag = 1; lag < order; lag++ ) { /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ energy = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); matrix_ptr( XX, lag, 0, order ) = energy; matrix_ptr( XX, 0, lag, order ) = energy; /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ for( j = 1; j < ( order - lag ); j++ ) { energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); matrix_ptr( XX, lag + j, j, order ) = energy; matrix_ptr( XX, j, lag + j, order ) = energy; } ptr2--;/* Update pointer to first sample of next column (lag) in X */ } } *rshifts = rshifts_local; } ================================================ FILE: app/jni/SKP_Silk_create_init_destroy.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /************************/ /* Init Decoder State */ /************************/ SKP_int SKP_Silk_init_decoder( SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */ ) { SKP_memset( psDec, 0, sizeof( SKP_Silk_decoder_state ) ); /* Set sampling rate to 24 kHz, and init non-zero values */ SKP_Silk_decoder_set_fs( psDec, 24 ); /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */ psDec->first_frame_after_reset = 1; psDec->prev_inv_gain_Q16 = 65536; /* Reset CNG state */ SKP_Silk_CNG_Reset( psDec ); SKP_Silk_PLC_Reset( psDec ); return(0); } ================================================ FILE: app/jni/SKP_Silk_dec_API.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_main.h" /*********************/ /* Decoder functions */ /*********************/ SKP_int SKP_Silk_SDK_Get_Decoder_Size( SKP_int32 *decSizeBytes ) { SKP_int ret = 0; *decSizeBytes = sizeof( SKP_Silk_decoder_state ); return ret; } /* Reset decoder state */ SKP_int SKP_Silk_SDK_InitDecoder( void* decState /* I/O: State */ ) { SKP_int ret = 0; SKP_Silk_decoder_state *struc; struc = (SKP_Silk_decoder_state *)decState; ret = SKP_Silk_init_decoder( struc ); return ret; } /* Decode a frame */ SKP_int SKP_Silk_SDK_Decode( void* decState, /* I/O: State */ SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control structure */ SKP_int lostFlag, /* I: 0: no loss, 1 loss */ const SKP_uint8 *inData, /* I: Encoded input vector */ const SKP_int nBytesIn, /* I: Number of input Bytes */ SKP_int16 *samplesOut, /* O: Decoded output speech vector */ SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */ ) { SKP_int ret = 0, used_bytes, prev_fs_kHz; SKP_Silk_decoder_state *psDec; SKP_int16 samplesOutInternal[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ]; SKP_int16 *pSamplesOutInternal; psDec = (SKP_Silk_decoder_state *)decState; /* We need this buffer to have room for an internal frame */ pSamplesOutInternal = samplesOut; if( psDec->fs_kHz * 1000 > decControl->API_sampleRate ) { pSamplesOutInternal = samplesOutInternal; } /**********************************/ /* Test if first frame in payload */ /**********************************/ if( psDec->moreInternalDecoderFrames == 0 ) { /* First Frame in Payload */ psDec->nFramesDecoded = 0; /* Used to count frames in packet */ } if( psDec->moreInternalDecoderFrames == 0 && /* First frame in packet */ lostFlag == 0 && /* Not packet loss */ nBytesIn > MAX_ARITHM_BYTES ) { /* Too long payload */ /* Avoid trying to decode a too large packet */ lostFlag = 1; ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE; } /* Save previous sample frequency */ prev_fs_kHz = psDec->fs_kHz; /* Call decoder for one frame */ ret += SKP_Silk_decode_frame( psDec, pSamplesOutInternal, nSamplesOut, inData, nBytesIn, lostFlag, &used_bytes ); if( used_bytes ) { /* Only Call if not a packet loss */ if( psDec->nBytesLeft > 0 && psDec->FrameTermination == SKP_SILK_MORE_FRAMES && psDec->nFramesDecoded < 5 ) { /* We have more frames in the Payload */ psDec->moreInternalDecoderFrames = 1; } else { /* Last frame in Payload */ psDec->moreInternalDecoderFrames = 0; psDec->nFramesInPacket = psDec->nFramesDecoded; /* Track inband FEC usage */ if( psDec->vadFlag == VOICE_ACTIVITY ) { if( psDec->FrameTermination == SKP_SILK_LAST_FRAME ) { psDec->no_FEC_counter++; if( psDec->no_FEC_counter > NO_LBRR_THRES ) { psDec->inband_FEC_offset = 0; } } else if( psDec->FrameTermination == SKP_SILK_LBRR_VER1 ) { psDec->inband_FEC_offset = 1; /* FEC info with 1 packet delay */ psDec->no_FEC_counter = 0; } else if( psDec->FrameTermination == SKP_SILK_LBRR_VER2 ) { psDec->inband_FEC_offset = 2; /* FEC info with 2 packets delay */ psDec->no_FEC_counter = 0; } } } } if( MAX_API_FS_KHZ * 1000 < decControl->API_sampleRate || 8000 > decControl->API_sampleRate ) { ret = SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY; return( ret ); } /* Resample if needed */ if( psDec->fs_kHz * 1000 != decControl->API_sampleRate ) { SKP_int16 samplesOut_tmp[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ]; SKP_assert( psDec->fs_kHz <= MAX_API_FS_KHZ ); /* Copy to a tmp buffer as the resampling writes to samplesOut */ SKP_memcpy( samplesOut_tmp, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) ); /* (Re-)initialize resampler state when switching internal sampling frequency */ if( prev_fs_kHz != psDec->fs_kHz || psDec->prev_API_sampleRate != decControl->API_sampleRate ) { ret = SKP_Silk_resampler_init( &psDec->resampler_state, SKP_SMULBB( psDec->fs_kHz, 1000 ), decControl->API_sampleRate ); } /* Resample the output to API_sampleRate */ ret += SKP_Silk_resampler( &psDec->resampler_state, samplesOut, samplesOut_tmp, *nSamplesOut ); /* Update the number of output samples */ *nSamplesOut = SKP_DIV32( ( SKP_int32 )*nSamplesOut * decControl->API_sampleRate, psDec->fs_kHz * 1000 ); } else if( prev_fs_kHz * 1000 > decControl->API_sampleRate ) { SKP_memcpy( samplesOut, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) ); } psDec->prev_API_sampleRate = decControl->API_sampleRate; /* Copy all parameters that are needed out of internal structure to the control stucture */ decControl->frameSize = (SKP_uint16)( decControl->API_sampleRate / 50 ) ; decControl->framesPerPacket = ( SKP_int )psDec->nFramesInPacket; decControl->inBandFECOffset = ( SKP_int )psDec->inband_FEC_offset; decControl->moreInternalDecoderFrames = ( SKP_int )psDec->moreInternalDecoderFrames; return ret; } /* Function to find LBRR information in a packet */ void SKP_Silk_SDK_search_for_LBRR( const SKP_uint8 *inData, /* I: Encoded input vector */ const SKP_int nBytesIn, /* I: Number of input Bytes */ SKP_int lost_offset, /* I: Offset from lost packet */ SKP_uint8 *LBRRData, /* O: LBRR payload */ SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */ ) { SKP_Silk_decoder_state sDec; // Local decoder state to avoid interfering with running decoder */ SKP_Silk_decoder_control sDecCtrl; SKP_int TempQ[ MAX_FRAME_LENGTH ]; if( lost_offset < 1 || lost_offset > MAX_LBRR_DELAY ) { /* No useful FEC in this packet */ *nLBRRBytes = 0; return; } sDec.nFramesDecoded = 0; sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */ sDec.lossCnt = 0; /* Avoid running bw expansion of the LPC parameters when searching for LBRR data */ SKP_memset( sDec.prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) ); SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn ); while(1) { SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 ); if( sDec.sRC.error ) { /* Corrupt stream */ *nLBRRBytes = 0; return; }; if( ( sDec.FrameTermination - 1 ) & lost_offset && sDec.FrameTermination > 0 && sDec.nBytesLeft >= 0 ) { /* The wanted FEC is present in the packet */ *nLBRRBytes = sDec.nBytesLeft; SKP_memcpy( LBRRData, &inData[ nBytesIn - sDec.nBytesLeft ], sDec.nBytesLeft * sizeof( SKP_uint8 ) ); break; } if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) { sDec.nFramesDecoded++; } else { LBRRData = NULL; *nLBRRBytes = 0; break; } } } /* Getting type of content for a packet */ void SKP_Silk_SDK_get_TOC( const SKP_uint8 *inData, /* I: Encoded input vector */ const SKP_int nBytesIn, /* I: Number of input bytes */ SKP_Silk_TOC_struct *Silk_TOC /* O: Type of content */ ) { SKP_Silk_decoder_state sDec; // Local Decoder state to avoid interfering with running decoder */ SKP_Silk_decoder_control sDecCtrl; SKP_int TempQ[ MAX_FRAME_LENGTH ]; sDec.nFramesDecoded = 0; sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */ SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn ); Silk_TOC->corrupt = 0; while( 1 ) { SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 ); Silk_TOC->vadFlags[ sDec.nFramesDecoded ] = sDec.vadFlag; Silk_TOC->sigtypeFlags[ sDec.nFramesDecoded ] = sDecCtrl.sigtype; if( sDec.sRC.error ) { /* Corrupt stream */ Silk_TOC->corrupt = 1; break; }; if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) { sDec.nFramesDecoded++; } else { break; } } if( Silk_TOC->corrupt || sDec.FrameTermination == SKP_SILK_MORE_FRAMES || sDec.nFramesInPacket > SILK_MAX_FRAMES_PER_PACKET ) { /* Corrupt packet */ SKP_memset( Silk_TOC, 0, sizeof( SKP_Silk_TOC_struct ) ); Silk_TOC->corrupt = 1; } else { Silk_TOC->framesInPacket = sDec.nFramesDecoded + 1; Silk_TOC->fs_kHz = sDec.fs_kHz; if( sDec.FrameTermination == SKP_SILK_LAST_FRAME ) { Silk_TOC->inbandLBRR = sDec.FrameTermination; } else { Silk_TOC->inbandLBRR = sDec.FrameTermination - 1; } } } /**************************/ /* Get the version number */ /**************************/ /* Return a pointer to string specifying the version */ const char *SKP_Silk_SDK_get_version() { static const char version[] = "1.0.9"; return version; } ================================================ FILE: app/jni/SKP_Silk_decode_core.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" void SKP_Silk_decode_short_term_prediction( SKP_int32 *vec_Q10, SKP_int32 *pres_Q10, SKP_int32 *sLPC_Q14, SKP_int16 *A_Q12_tmp, SKP_int LPC_order, SKP_int subfr_length ); /**********************************************************/ /* Core decoder. Performs inverse NSQ operation LTP + LPC */ /**********************************************************/ void SKP_Silk_decode_core( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */ SKP_int16 xq[], /* O Decoded speech */ const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */ ) { SKP_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, sigtype; SKP_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ]; SKP_int16 sLTP[ MAX_FRAME_LENGTH ]; SKP_int32 LTP_pred_Q14, Gain_Q16, inv_gain_Q16, inv_gain_Q32, gain_adj_Q16, rand_seed, offset_Q10, dither; SKP_int32 *pred_lag_ptr, *pexc_Q10, *pres_Q10; SKP_int32 vec_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ]; SKP_int32 FiltState[ MAX_LPC_ORDER ]; SKP_assert( psDec->prev_inv_gain_Q16 != 0 ); offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psDecCtrl->sigtype ][ psDecCtrl->QuantOffsetType ]; if( psDecCtrl->NLSFInterpCoef_Q2 < ( 1 << 2 ) ) { NLSF_interpolation_flag = 1; } else { NLSF_interpolation_flag = 0; } /* Decode excitation */ rand_seed = psDecCtrl->Seed; for( i = 0; i < psDec->frame_length; i++ ) { rand_seed = SKP_RAND( rand_seed ); /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */ dither = SKP_RSHIFT( rand_seed, 31 ); psDec->exc_Q10[ i ] = SKP_LSHIFT( ( SKP_int32 )q[ i ], 10 ) + offset_Q10; psDec->exc_Q10[ i ] = ( psDec->exc_Q10[ i ] ^ dither ) - dither; rand_seed += q[ i ]; } pexc_Q10 = psDec->exc_Q10; pres_Q10 = psDec->res_Q10; pxq = &psDec->outBuf[ psDec->frame_length ]; sLTP_buf_idx = psDec->frame_length; /* Loop over subframes */ for( k = 0; k < NB_SUBFR; k++ ) { A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ]; /* Preload LPC coeficients to array on stack. Gives small performance gain */ SKP_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( SKP_int16 ) ); B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ]; Gain_Q16 = psDecCtrl->Gains_Q16[ k ]; sigtype = psDecCtrl->sigtype; inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gain_Q16, 1 ), 32 ); inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX ); /* Calculate Gain adjustment factor */ gain_adj_Q16 = ( SKP_int32 )1 << 16; if( inv_gain_Q16 != psDec->prev_inv_gain_Q16 ) { gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, psDec->prev_inv_gain_Q16, 16 ); } /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */ if( psDec->lossCnt && psDec->prev_sigtype == SIG_TYPE_VOICED && psDecCtrl->sigtype == SIG_TYPE_UNVOICED && k < ( NB_SUBFR >> 1 ) ) { SKP_memset( B_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) ); B_Q14[ LTP_ORDER/2 ] = ( SKP_int16 )1 << 12; /* 0.25 */ sigtype = SIG_TYPE_VOICED; psDecCtrl->pitchL[ k ] = psDec->lagPrev; } if( sigtype == SIG_TYPE_VOICED ) { /* Voiced */ lag = psDecCtrl->pitchL[ k ]; /* Re-whitening */ if( ( k & ( 3 - SKP_LSHIFT( NLSF_interpolation_flag, 1 ) ) ) == 0 ) { /* Rewhiten with new A coefs */ start_idx = psDec->frame_length - lag - psDec->LPC_order - LTP_ORDER / 2; SKP_assert( start_idx >= 0 ); SKP_assert( start_idx <= psDec->frame_length - psDec->LPC_order ); SKP_memset( FiltState, 0, psDec->LPC_order * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind and Coverity will complain otherwise */ SKP_Silk_MA_Prediction( &psDec->outBuf[ start_idx + k * ( psDec->frame_length >> 2 ) ], A_Q12, FiltState, sLTP + start_idx, psDec->frame_length - start_idx, psDec->LPC_order ); /* After rewhitening the LTP state is unscaled */ inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 ); if( k == 0 ) { /* Do LTP downscaling */ inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, psDecCtrl->LTP_scale_Q14 ), 2 ); } for( i = 0; i < (lag + LTP_ORDER/2); i++ ) { psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWB( inv_gain_Q32, sLTP[ psDec->frame_length - i - 1 ] ); } } else { /* Update LTP state when Gain changes */ if( gain_adj_Q16 != ( SKP_int32 )1 << 16 ) { for( i = 0; i < ( lag + LTP_ORDER / 2 ); i++ ) { psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWW( gain_adj_Q16, psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] ); } } } } /* Scale short term state */ for( i = 0; i < MAX_LPC_ORDER; i++ ) { psDec->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDec->sLPC_Q14[ i ] ); } /* Save inv_gain */ SKP_assert( inv_gain_Q16 != 0 ); psDec->prev_inv_gain_Q16 = inv_gain_Q16; /* Long-term prediction */ if( sigtype == SIG_TYPE_VOICED ) { /* Setup pointer */ pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; for( i = 0; i < psDec->subfr_length; i++ ) { /* Unrolled loop */ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); pred_lag_ptr++; /* Generate LPC residual */ pres_Q10[ i ] = SKP_ADD32( pexc_Q10[ i ], SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); /* Update states */ psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( pres_Q10[ i ], 6 ); sLTP_buf_idx++; } } else { SKP_memcpy( pres_Q10, pexc_Q10, psDec->subfr_length * sizeof( SKP_int32 ) ); } SKP_Silk_decode_short_term_prediction(vec_Q10, pres_Q10, psDec->sLPC_Q14,A_Q12_tmp,psDec->LPC_order,psDec->subfr_length); /* Scale with Gain */ for( i = 0; i < psDec->subfr_length; i++ ) { pxq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( vec_Q10[ i ], Gain_Q16 ), 10 ) ); } /* Update LPC filter state */ SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) ); pexc_Q10 += psDec->subfr_length; pres_Q10 += psDec->subfr_length; pxq += psDec->subfr_length; } /* Copy to output */ SKP_memcpy( xq, &psDec->outBuf[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int16 ) ); } #if EMBEDDED_ARM<5 void SKP_Silk_decode_short_term_prediction( SKP_int32 *vec_Q10, SKP_int32 *pres_Q10, SKP_int32 *sLPC_Q14, SKP_int16 *A_Q12_tmp, SKP_int LPC_order, SKP_int subfr_length ) { SKP_int i; SKP_int32 LPC_pred_Q10; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 Atmp; /* Short term prediction */ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLAWB and SMLAWT instructions should solve the problem. */ if( LPC_order == 16 ) { for( i = 0; i < subfr_length; i++ ) { /* unrolled */ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] ); /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 10 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 12 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 14 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], Atmp ); /* Add prediction to LPC residual */ vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 ); /* Update states */ sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 ); } } else { SKP_assert( LPC_order == 10 ); for( i = 0; i < subfr_length; i++ ) { /* unrolled */ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] ); /* read two coefficients at once */ LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp ); Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp ); LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp ); /* Add prediction to LPC residual */ vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 ); /* Update states */ sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 ); } } #else SKP_int j; for( i = 0; i < subfr_length; i++ ) { /* Partially unrolled */ LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); for( j = 10; j < LPC_order; j ++ ) { LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] ); } /* Add prediction to LPC residual */ vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 ); /* Update states */ sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 ); } #endif } #endif ================================================ FILE: app/jni/SKP_Silk_decode_frame.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" #include "SKP_Silk_PLC.h" /****************/ /* Decode frame */ /****************/ SKP_int SKP_Silk_decode_frame( SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ SKP_int16 pOut[], /* O Pointer to output speech frame */ SKP_int16 *pN, /* O Pointer to size of output frame */ const SKP_uint8 pCode[], /* I Pointer to payload */ const SKP_int nBytes, /* I Payload length */ SKP_int action, /* I Action from Jitter Buffer */ SKP_int *decBytes /* O Used bytes to decode this frame */ ) { SKP_Silk_decoder_control sDecCtrl; SKP_int L, fs_Khz_old, ret = 0; SKP_int Pulses[ MAX_FRAME_LENGTH ]; L = psDec->frame_length; sDecCtrl.LTP_scale_Q14 = 0; /* Safety checks */ SKP_assert( L > 0 && L <= MAX_FRAME_LENGTH ); /********************************************/ /* Decode Frame if packet is not lost */ /********************************************/ *decBytes = 0; if( action == 0 ) { /********************************************/ /* Initialize arithmetic coder */ /********************************************/ fs_Khz_old = psDec->fs_kHz; if( psDec->nFramesDecoded == 0 ) { /* Initialize range decoder state */ SKP_Silk_range_dec_init( &psDec->sRC, pCode, nBytes ); } /********************************************/ /* Decode parameters and pulse signal */ /********************************************/ SKP_Silk_decode_parameters( psDec, &sDecCtrl, Pulses, 1 ); if( psDec->sRC.error ) { psDec->nBytesLeft = 0; action = 1; /* PLC operation */ /* revert fs if changed in decode_parameters */ SKP_Silk_decoder_set_fs( psDec, fs_Khz_old ); /* Avoid crashing */ *decBytes = psDec->sRC.bufferLength; if( psDec->sRC.error == RANGE_CODER_DEC_PAYLOAD_TOO_LONG ) { ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE; } else { ret = SKP_SILK_DEC_PAYLOAD_ERROR; } } else { *decBytes = psDec->sRC.bufferLength - psDec->nBytesLeft; psDec->nFramesDecoded++; /* Update lengths. Sampling frequency could have changed */ L = psDec->frame_length; /********************************************************/ /* Run inverse NSQ */ /********************************************************/ SKP_Silk_decode_core( psDec, &sDecCtrl, pOut, Pulses ); /********************************************************/ /* Update PLC state */ /********************************************************/ SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action ); psDec->lossCnt = 0; psDec->prev_sigtype = sDecCtrl.sigtype; /* A frame has been decoded without errors */ psDec->first_frame_after_reset = 0; } } /*************************************************************/ /* Generate Concealment frame if packet is lost, or corrupt */ /*************************************************************/ if( action == 1 ) { /* Handle packet loss by extrapolation */ SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action ); } /*************************/ /* Update output buffer. */ /*************************/ SKP_memcpy( psDec->outBuf, pOut, L * sizeof( SKP_int16 ) ); /****************************************************************/ /* Ensure smooth connection of extrapolated and good frames */ /****************************************************************/ SKP_Silk_PLC_glue_frames( psDec, &sDecCtrl, pOut, L ); /************************************************/ /* Comfort noise generation / estimation */ /************************************************/ SKP_Silk_CNG( psDec, &sDecCtrl, pOut , L ); /********************************************/ /* HP filter output */ /********************************************/ SKP_assert( ( ( psDec->fs_kHz == 12 ) && ( L % 3 ) == 0 ) || ( ( psDec->fs_kHz != 12 ) && ( L % 2 ) == 0 ) ); SKP_Silk_biquad( pOut, psDec->HP_B, psDec->HP_A, psDec->HPState, pOut, L ); /********************************************/ /* set output frame length */ /********************************************/ *pN = ( SKP_int16 )L; /* Update some decoder state variables */ psDec->lagPrev = sDecCtrl.pitchL[ NB_SUBFR - 1 ]; return ret; } ================================================ FILE: app/jni/SKP_Silk_decode_parameters.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Decode parameters from payload */ void SKP_Silk_decode_parameters( SKP_Silk_decoder_state *psDec, /* I/O State */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int q[], /* O Excitation signal */ const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */ ) { SKP_int i, k, Ix, fs_kHz_dec, nBytesUsed; SKP_int Ixs[ NB_SUBFR ]; SKP_int GainsIndices[ NB_SUBFR ]; SKP_int NLSFIndices[ NLSF_MSVQ_MAX_CB_STAGES ]; SKP_int pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ]; const SKP_int16 *cbk_ptr_Q14; const SKP_Silk_NLSF_CB_struct *psNLSF_CB = NULL; SKP_Silk_range_coder_state *psRC = &psDec->sRC; /************************/ /* Decode sampling rate */ /************************/ /* only done for first frame of packet */ if( psDec->nFramesDecoded == 0 ) { SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_SamplingRates_CDF, SKP_Silk_SamplingRates_offset ); /* check that sampling rate is supported */ if( Ix < 0 || Ix > 3 ) { psRC->error = RANGE_CODER_ILLEGAL_SAMPLING_RATE; return; } fs_kHz_dec = SKP_Silk_SamplingRates_table[ Ix ]; SKP_Silk_decoder_set_fs( psDec, fs_kHz_dec ); } /*******************************************/ /* Decode signal type and quantizer offset */ /*******************************************/ if( psDec->nFramesDecoded == 0 ) { /* first frame in packet: independent coding */ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_CDF, SKP_Silk_type_offset_CDF_offset ); } else { /* condidtional coding */ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_joint_CDF[ psDec->typeOffsetPrev ], SKP_Silk_type_offset_CDF_offset ); } psDecCtrl->sigtype = SKP_RSHIFT( Ix, 1 ); psDecCtrl->QuantOffsetType = Ix & 1; psDec->typeOffsetPrev = Ix; /****************/ /* Decode gains */ /****************/ /* first subframe */ if( psDec->nFramesDecoded == 0 ) { /* first frame in packet: independent coding */ SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_gain_CDF[ psDecCtrl->sigtype ], SKP_Silk_gain_CDF_offset ); } else { /* condidtional coding */ SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset ); } /* remaining subframes */ for( i = 1; i < NB_SUBFR; i++ ) { SKP_Silk_range_decoder( &GainsIndices[ i ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset ); } /* Dequant Gains */ SKP_Silk_gains_dequant( psDecCtrl->Gains_Q16, GainsIndices, &psDec->LastGainIndex, psDec->nFramesDecoded ); /****************/ /* Decode NLSFs */ /****************/ /* Set pointer to NLSF VQ CB for the current signal type */ psNLSF_CB = psDec->psNLSF_CB[ psDecCtrl->sigtype ]; /* Range decode NLSF path */ SKP_Silk_range_decoder_multi( NLSFIndices, psRC, psNLSF_CB->StartPtr, psNLSF_CB->MiddleIx, psNLSF_CB->nStages ); /* From the NLSF path, decode an NLSF vector */ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, psDec->LPC_order ); /************************************/ /* Decode NLSF interpolation factor */ /************************************/ SKP_Silk_range_decoder( &psDecCtrl->NLSFInterpCoef_Q2, psRC, SKP_Silk_NLSF_interpolation_factor_CDF, SKP_Silk_NLSF_interpolation_factor_offset ); /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ /* improves the case of packet loss in the first frame after a switch */ if( psDec->first_frame_after_reset == 1 ) { psDecCtrl->NLSFInterpCoef_Q2 = 4; } if( fullDecoding ) { /* Convert NLSF parameters to AR prediction filter coefficients */ SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); if( psDecCtrl->NLSFInterpCoef_Q2 < 4 ) { /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ /* the previous NLSF1, and the current NLSF1 */ for( i = 0; i < psDec->LPC_order; i++ ) { pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + SKP_RSHIFT( SKP_MUL( psDecCtrl->NLSFInterpCoef_Q2, ( pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ) ), 2 ); } /* Convert NLSF parameters to AR prediction filter coefficients */ SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); } else { /* Copy LPC coefficients for first half from second half */ SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) ); } } SKP_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( SKP_int ) ); /* After a packet loss do BWE of LPC coefs */ if( psDec->lossCnt ) { SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); } if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) { /*********************/ /* Decode pitch lags */ /*********************/ /* Get lag index */ if( psDec->fs_kHz == 8 ) { SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_NB_CDF, SKP_Silk_pitch_lag_NB_CDF_offset ); } else if( psDec->fs_kHz == 12 ) { SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_MB_CDF, SKP_Silk_pitch_lag_MB_CDF_offset ); } else if( psDec->fs_kHz == 16 ) { SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_WB_CDF, SKP_Silk_pitch_lag_WB_CDF_offset ); } else { SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_SWB_CDF, SKP_Silk_pitch_lag_SWB_CDF_offset ); } /* Get countour index */ if( psDec->fs_kHz == 8 ) { /* Less codevectors used in 8 khz mode */ SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_NB_CDF, SKP_Silk_pitch_contour_NB_CDF_offset ); } else { /* Joint for 12, 16, and 24 khz */ SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_CDF, SKP_Silk_pitch_contour_CDF_offset ); } /* Decode pitch values */ SKP_Silk_decode_pitch( Ixs[ 0 ], Ixs[ 1 ], psDecCtrl->pitchL, psDec->fs_kHz ); /********************/ /* Decode LTP gains */ /********************/ /* Decode PERIndex value */ SKP_Silk_range_decoder( &psDecCtrl->PERIndex, psRC, SKP_Silk_LTP_per_index_CDF, SKP_Silk_LTP_per_index_CDF_offset ); /* Decode Codebook Index */ cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ psDecCtrl->PERIndex ]; /* set pointer to start of codebook */ for( k = 0; k < NB_SUBFR; k++ ) { SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTP_gain_CDF_ptrs[ psDecCtrl->PERIndex ], SKP_Silk_LTP_gain_CDF_offsets[ psDecCtrl->PERIndex ] ); for( i = 0; i < LTP_ORDER; i++ ) { psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = cbk_ptr_Q14[ Ix * LTP_ORDER + i ]; } } /**********************/ /* Decode LTP scaling */ /**********************/ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTPscale_CDF, SKP_Silk_LTPscale_offset ); psDecCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ Ix ]; } else { SKP_assert( psDecCtrl->sigtype == SIG_TYPE_UNVOICED ); SKP_memset( psDecCtrl->pitchL, 0, NB_SUBFR * sizeof( SKP_int ) ); SKP_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * NB_SUBFR * sizeof( SKP_int16 ) ); psDecCtrl->PERIndex = 0; psDecCtrl->LTP_scale_Q14 = 0; } /***************/ /* Decode seed */ /***************/ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_Seed_CDF, SKP_Silk_Seed_offset ); psDecCtrl->Seed = ( SKP_int32 )Ix; /*********************************************/ /* Decode quantization indices of excitation */ /*********************************************/ SKP_Silk_decode_pulses( psRC, psDecCtrl, q, psDec->frame_length ); /*********************************************/ /* Decode VAD flag */ /*********************************************/ SKP_Silk_range_decoder( &psDec->vadFlag, psRC, SKP_Silk_vadflag_CDF, SKP_Silk_vadflag_offset ); /**************************************/ /* Decode Frame termination indicator */ /**************************************/ SKP_Silk_range_decoder( &psDec->FrameTermination, psRC, SKP_Silk_FrameTermination_CDF, SKP_Silk_FrameTermination_offset ); /****************************************/ /* get number of bytes used so far */ /****************************************/ SKP_Silk_range_coder_get_length( psRC, &nBytesUsed ); psDec->nBytesLeft = psRC->bufferLength - nBytesUsed; if( psDec->nBytesLeft < 0 ) { psRC->error = RANGE_CODER_READ_BEYOND_BUFFER; } /****************************************/ /* check remaining bits in last byte */ /****************************************/ if( psDec->nBytesLeft == 0 ) { SKP_Silk_range_coder_check_after_decoding( psRC ); } } ================================================ FILE: app/jni/SKP_Silk_decode_pitch.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /*********************************************************** * Pitch analyser function ********************************************************** */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_common_pitch_est_defines.h" void SKP_Silk_decode_pitch( SKP_int lagIndex, /* I */ SKP_int contourIndex, /* O */ SKP_int pitch_lags[], /* O 4 pitch values */ SKP_int Fs_kHz /* I sampling frequency (kHz) */ ) { SKP_int lag, i, min_lag; min_lag = SKP_SMULBB( PITCH_EST_MIN_LAG_MS, Fs_kHz ); /* Only for 24 / 16 kHz version for now */ lag = min_lag + lagIndex; if( Fs_kHz == 8 ) { /* Only a small codebook for 8 khz */ for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) { pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage2[ i ][ contourIndex ]; } } else { for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) { pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage3[ i ][ contourIndex ]; } } } ================================================ FILE: app/jni/SKP_Silk_decode_pulses.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /*********************************************/ /* Decode quantization indices of excitation */ /*********************************************/ void SKP_Silk_decode_pulses( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int q[], /* O Excitation signal */ const SKP_int frame_length /* I Frame length (preliminary) */ ) { SKP_int i, j, k, iter, abs_q, nLS, bit; SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ]; SKP_int *pulses_ptr; const SKP_uint16 *cdf_ptr; /*********************/ /* Decode rate level */ /*********************/ SKP_Silk_range_decoder( &psDecCtrl->RateLevelIndex, psRC, SKP_Silk_rate_levels_CDF[ psDecCtrl->sigtype ], SKP_Silk_rate_levels_CDF_offset ); /* Calculate number of shell blocks */ iter = frame_length / SHELL_CODEC_FRAME_LENGTH; /***************************************************/ /* Sum-Weighted-Pulses Decoding */ /***************************************************/ cdf_ptr = SKP_Silk_pulses_per_block_CDF[ psDecCtrl->RateLevelIndex ]; for( i = 0; i < iter; i++ ) { nLshifts[ i ] = 0; SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, cdf_ptr, SKP_Silk_pulses_per_block_CDF_offset ); /* LSB indication */ while( sum_pulses[ i ] == ( MAX_PULSES + 1 ) ) { nLshifts[ i ]++; SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ], SKP_Silk_pulses_per_block_CDF_offset ); } } /***************************************************/ /* Shell decoding */ /***************************************************/ for( i = 0; i < iter; i++ ) { if( sum_pulses[ i ] > 0 ) { SKP_Silk_shell_decoder( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRC, sum_pulses[ i ] ); } else { SKP_memset( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( SKP_int ) ); } } /***************************************************/ /* LSB Decoding */ /***************************************************/ for( i = 0; i < iter; i++ ) { if( nLshifts[ i ] > 0 ) { nLS = nLshifts[ i ]; pulses_ptr = &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ]; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_q = pulses_ptr[ k ]; for( j = 0; j < nLS; j++ ) { abs_q = SKP_LSHIFT( abs_q, 1 ); SKP_Silk_range_decoder( &bit, psRC, SKP_Silk_lsb_CDF, 1 ); abs_q += bit; } pulses_ptr[ k ] = abs_q; } } } /****************************************/ /* Decode and add signs to pulse signal */ /****************************************/ SKP_Silk_decode_signs( psRC, q, frame_length, psDecCtrl->sigtype, psDecCtrl->QuantOffsetType, psDecCtrl->RateLevelIndex); } ================================================ FILE: app/jni/SKP_Silk_decoder_set_fs.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Set decoder sampling rate */ void SKP_Silk_decoder_set_fs( SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */ SKP_int fs_kHz /* I Sampling frequency (kHz) */ ) { if( psDec->fs_kHz != fs_kHz ) { psDec->fs_kHz = fs_kHz; psDec->frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz ); psDec->subfr_length = SKP_SMULBB( FRAME_LENGTH_MS / NB_SUBFR, fs_kHz ); if( psDec->fs_kHz == 8 ) { psDec->LPC_order = MIN_LPC_ORDER; psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10; psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10; } else { psDec->LPC_order = MAX_LPC_ORDER; psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16; psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16; } /* Reset part of the decoder state */ SKP_memset( psDec->sLPC_Q14, 0, MAX_LPC_ORDER * sizeof( SKP_int32 ) ); SKP_memset( psDec->outBuf, 0, MAX_FRAME_LENGTH * sizeof( SKP_int16 ) ); SKP_memset( psDec->prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) ); psDec->lagPrev = 100; psDec->LastGainIndex = 1; psDec->prev_sigtype = 0; psDec->first_frame_after_reset = 1; if( fs_kHz == 24 ) { psDec->HP_A = SKP_Silk_Dec_A_HP_24; psDec->HP_B = SKP_Silk_Dec_B_HP_24; } else if( fs_kHz == 16 ) { psDec->HP_A = SKP_Silk_Dec_A_HP_16; psDec->HP_B = SKP_Silk_Dec_B_HP_16; } else if( fs_kHz == 12 ) { psDec->HP_A = SKP_Silk_Dec_A_HP_12; psDec->HP_B = SKP_Silk_Dec_B_HP_12; } else if( fs_kHz == 8 ) { psDec->HP_A = SKP_Silk_Dec_A_HP_8; psDec->HP_B = SKP_Silk_Dec_B_HP_8; } else { /* unsupported sampling rate */ SKP_assert( 0 ); } } /* Check that settings are valid */ SKP_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); } ================================================ FILE: app/jni/SKP_Silk_detect_SWB_input.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * Detect SWB input by measuring energy above 8 kHz. */ #include "SKP_Silk_main.h" void SKP_Silk_detect_SWB_input( SKP_Silk_detect_SWB_state *psSWBdetect, /* (I/O) encoder state */ const SKP_int16 samplesIn[], /* (I) input to encoder */ SKP_int nSamplesIn /* (I) length of input */ ) { SKP_int HP_8_kHz_len, i, shift; SKP_int16 in_HP_8_kHz[ MAX_FRAME_LENGTH ]; SKP_int32 energy_32; /* High pass filter with cutoff at 8 khz */ HP_8_kHz_len = SKP_min_int( nSamplesIn, MAX_FRAME_LENGTH ); HP_8_kHz_len = SKP_max_int( HP_8_kHz_len, 0 ); /* Cutoff around 9 khz */ /* A = conv(conv([8192,14613, 6868], [8192,12883, 7337]), [8192,11586, 7911]); */ /* B = conv(conv([575, -948, 575], [575, -221, 575]), [575, 104, 575]); */ SKP_Silk_biquad( samplesIn, SKP_Silk_SWB_detect_B_HP_Q13[ 0 ], SKP_Silk_SWB_detect_A_HP_Q13[ 0 ], psSWBdetect->S_HP_8_kHz[ 0 ], in_HP_8_kHz, HP_8_kHz_len ); for( i = 1; i < NB_SOS; i++ ) { SKP_Silk_biquad( in_HP_8_kHz, SKP_Silk_SWB_detect_B_HP_Q13[ i ], SKP_Silk_SWB_detect_A_HP_Q13[ i ], psSWBdetect->S_HP_8_kHz[ i ], in_HP_8_kHz, HP_8_kHz_len ); } /* Calculate energy in HP signal */ SKP_Silk_sum_sqr_shift( &energy_32, &shift, in_HP_8_kHz, HP_8_kHz_len ); /* Count concecutive samples above threshold, after adjusting threshold for number of input samples and shift */ if( energy_32 > SKP_RSHIFT( SKP_SMULBB( HP_8_KHZ_THRES, HP_8_kHz_len ), shift ) ) { psSWBdetect->ConsecSmplsAboveThres += nSamplesIn; if( psSWBdetect->ConsecSmplsAboveThres > CONCEC_SWB_SMPLS_THRES ) { psSWBdetect->SWB_detected = 1; } } else { psSWBdetect->ConsecSmplsAboveThres -= nSamplesIn; psSWBdetect->ConsecSmplsAboveThres = SKP_max( psSWBdetect->ConsecSmplsAboveThres, 0 ); } /* If sufficient speech activity and no SWB detected, we detect the signal as being WB */ if( ( psSWBdetect->ActiveSpeech_ms > WB_DETECT_ACTIVE_SPEECH_MS_THRES ) && ( psSWBdetect->SWB_detected == 0 ) ) { psSWBdetect->WB_detected = 1; } } ================================================ FILE: app/jni/SKP_Silk_div_oabi.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_typedef.h" SKP_int32 SKP_DIV32_arm( SKP_int32 a32, SKP_int32 b32 ) { return ( ( SKP_int32 )( ( a32 ) / ( b32 ) ) ); } ================================================ FILE: app/jni/SKP_Silk_enc_API.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_define.h" #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_control.h" #include "SKP_Silk_typedef.h" #include "SKP_Silk_structs.h" #define SKP_Silk_EncodeControlStruct SKP_SILK_SDK_EncControlStruct /****************************************/ /* Encoder functions */ /****************************************/ SKP_int SKP_Silk_SDK_Get_Encoder_Size( SKP_int32 *encSizeBytes ) { SKP_int ret = 0; *encSizeBytes = sizeof( SKP_Silk_encoder_state_FIX ); return ret; } /***************************************/ /* Read control structure from encoder */ /***************************************/ SKP_int SKP_Silk_SDK_QueryEncoder( const void *encState, /* I: State Vector */ SKP_Silk_EncodeControlStruct *encStatus /* O: Control Structure */ ) { SKP_Silk_encoder_state_FIX *psEnc; SKP_int ret = 0; psEnc = ( SKP_Silk_encoder_state_FIX* )encState; encStatus->API_sampleRate = psEnc->sCmn.API_fs_Hz; encStatus->maxInternalSampleRate = SKP_SMULBB( psEnc->sCmn.maxInternal_fs_kHz, 1000 ); encStatus->packetSize = ( SKP_int )SKP_DIV32_16( psEnc->sCmn.API_fs_Hz * psEnc->sCmn.PacketSize_ms, 1000 ); /* convert samples -> ms */ encStatus->bitRate = psEnc->sCmn.TargetRate_bps; encStatus->packetLossPercentage = psEnc->sCmn.PacketLoss_perc; encStatus->complexity = psEnc->sCmn.Complexity; encStatus->useInBandFEC = psEnc->sCmn.useInBandFEC; encStatus->useDTX = psEnc->sCmn.useDTX; return ret; } /*************************/ /* Init or Reset encoder */ /*************************/ SKP_int SKP_Silk_SDK_InitEncoder( void *encState, /* I/O: State */ SKP_Silk_EncodeControlStruct *encStatus /* O: Control structure */ ) { SKP_Silk_encoder_state_FIX *psEnc; SKP_int ret = 0; psEnc = ( SKP_Silk_encoder_state_FIX* )encState; /* Reset Encoder */ if( ret += SKP_Silk_init_encoder_FIX( psEnc ) ) { SKP_assert( 0 ); } /* Read control structure */ if( ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus ) ) { SKP_assert( 0 ); } return ret; } /**************************/ /* Encode frame with Silk */ /**************************/ SKP_int SKP_Silk_SDK_Encode( void *encState, /* I/O: State */ const SKP_Silk_EncodeControlStruct *encControl, /* I: Control structure */ const SKP_int16 *samplesIn, /* I: Speech sample input vector */ SKP_int nSamplesIn, /* I: Number of samples in input vector */ SKP_uint8 *outData, /* O: Encoded output vector */ SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */ ) { SKP_int max_internal_fs_kHz, PacketSize_ms, PacketLoss_perc, UseInBandFEC, UseDTX, ret = 0; SKP_int nSamplesToBuffer, Complexity, input_10ms, nSamplesFromInput = 0; SKP_int32 TargetRate_bps, API_fs_Hz; SKP_int16 MaxBytesOut; SKP_Silk_encoder_state_FIX *psEnc = ( SKP_Silk_encoder_state_FIX* )encState; SKP_assert( encControl != NULL ); /* Check sampling frequency first, to avoid divide by zero later */ if( ( ( encControl->API_sampleRate != 8000 ) && ( encControl->API_sampleRate != 12000 ) && ( encControl->API_sampleRate != 16000 ) && ( encControl->API_sampleRate != 24000 ) && ( encControl->API_sampleRate != 32000 ) && ( encControl->API_sampleRate != 44100 ) && ( encControl->API_sampleRate != 48000 ) ) || ( ( encControl->maxInternalSampleRate != 8000 ) && ( encControl->maxInternalSampleRate != 12000 ) && ( encControl->maxInternalSampleRate != 16000 ) && ( encControl->maxInternalSampleRate != 24000 ) ) ) { ret = SKP_SILK_ENC_FS_NOT_SUPPORTED; SKP_assert( 0 ); return( ret ); } /* Set encoder parameters from control structure */ API_fs_Hz = encControl->API_sampleRate; max_internal_fs_kHz = (SKP_int)( encControl->maxInternalSampleRate >> 10 ) + 1; /* convert Hz -> kHz */ PacketSize_ms = SKP_DIV32( 1000 * (SKP_int)encControl->packetSize, API_fs_Hz ); TargetRate_bps = encControl->bitRate; PacketLoss_perc = encControl->packetLossPercentage; UseInBandFEC = encControl->useInBandFEC; Complexity = encControl->complexity; UseDTX = encControl->useDTX; /* Save values in state */ psEnc->sCmn.API_fs_Hz = API_fs_Hz; psEnc->sCmn.maxInternal_fs_kHz = max_internal_fs_kHz; psEnc->sCmn.useInBandFEC = UseInBandFEC; /* Only accept input lengths that are a multiple of 10 ms */ input_10ms = SKP_DIV32( 100 * nSamplesIn, API_fs_Hz ); if( input_10ms * API_fs_Hz != 100 * nSamplesIn || nSamplesIn < 0 ) { ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; SKP_assert( 0 ); return( ret ); } TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS ); if( ( ret = SKP_Silk_control_encoder_FIX( psEnc, PacketSize_ms, TargetRate_bps, PacketLoss_perc, UseDTX, Complexity) ) != 0 ) { SKP_assert( 0 ); return( ret ); } /* Make sure no more than one packet can be produced */ if( 1000 * (SKP_int32)nSamplesIn > psEnc->sCmn.PacketSize_ms * API_fs_Hz ) { ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; SKP_assert( 0 ); return( ret ); } #if MAX_FS_KHZ > 16 /* Detect energy above 8 kHz */ if( SKP_min( API_fs_Hz, 1000 * max_internal_fs_kHz ) == 24000 && psEnc->sCmn.sSWBdetect.SWB_detected == 0 && psEnc->sCmn.sSWBdetect.WB_detected == 0 ) { SKP_Silk_detect_SWB_input( &psEnc->sCmn.sSWBdetect, samplesIn, ( SKP_int )nSamplesIn ); } #endif /* Input buffering/resampling and encoding */ MaxBytesOut = 0; /* return 0 output bytes if no encoder called */ while( 1 ) { nSamplesToBuffer = psEnc->sCmn.frame_length - psEnc->sCmn.inputBufIx; if( API_fs_Hz == SKP_SMULBB( 1000, psEnc->sCmn.fs_kHz ) ) { nSamplesToBuffer = SKP_min_int( nSamplesToBuffer, nSamplesIn ); nSamplesFromInput = nSamplesToBuffer; /* Copy to buffer */ SKP_memcpy( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput * sizeof( SKP_int16 ) ); } else { nSamplesToBuffer = SKP_min( nSamplesToBuffer, 10 * input_10ms * psEnc->sCmn.fs_kHz ); nSamplesFromInput = SKP_DIV32_16( nSamplesToBuffer * API_fs_Hz, psEnc->sCmn.fs_kHz * 1000 ); /* Resample and write to buffer */ ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state, &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput ); } samplesIn += nSamplesFromInput; nSamplesIn -= nSamplesFromInput; psEnc->sCmn.inputBufIx += nSamplesToBuffer; /* Silk encoder */ if( psEnc->sCmn.inputBufIx >= psEnc->sCmn.frame_length ) { SKP_assert( psEnc->sCmn.inputBufIx == psEnc->sCmn.frame_length ); /* Enough data in input buffer, so encode */ if( MaxBytesOut == 0 ) { /* No payload obtained so far */ MaxBytesOut = *nBytesOut; if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, &MaxBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) { SKP_assert( 0 ); } } else { /* outData already contains a payload */ if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, nBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) { SKP_assert( 0 ); } /* Check that no second payload was created */ SKP_assert( *nBytesOut == 0 ); } psEnc->sCmn.inputBufIx = 0; psEnc->sCmn.controlled_since_last_payload = 0; if( nSamplesIn == 0 ) { break; } } else { break; } } *nBytesOut = MaxBytesOut; if( psEnc->sCmn.useDTX && psEnc->sCmn.inDTX ) { /* DTX simulation */ *nBytesOut = 0; } return ret; } ================================================ FILE: app/jni/SKP_Silk_encode_frame_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /****************/ /* Encode frame */ /****************/ SKP_int SKP_Silk_encode_frame_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ SKP_uint8 *pCode, /* O Pointer to payload */ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */ /* input: max length; output: used */ const SKP_int16 *pIn /* I Pointer to input speech frame */ ) { SKP_Silk_encoder_control_FIX sEncCtrl; SKP_int nBytes, ret = 0; SKP_int16 *x_frame, *res_pitch_frame; SKP_int16 xfw[ MAX_FRAME_LENGTH ]; SKP_int16 pIn_HP[ MAX_FRAME_LENGTH ]; SKP_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; SKP_int LBRR_idx, frame_terminator, SNR_dB_Q7; const SKP_uint16 *FrameTermination_CDF; /* Low bitrate redundancy parameters */ SKP_uint8 LBRRpayload[ MAX_ARITHM_BYTES ]; SKP_int16 nBytesLBRR; sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3; /**************************************************************/ /* Setup Input Pointers, and insert frame in input buffer */ /*************************************************************/ x_frame = psEnc->x_buf + psEnc->sCmn.frame_length; /* start of frame to encode */ res_pitch_frame = res_pitch + psEnc->sCmn.frame_length; /* start of pitch LPC residual frame */ /****************************/ /* Voice Activity Detection */ /****************************/ ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7, sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15, pIn,psEnc->sCmn.frame_length ); /*******************************************/ /* High-pass filtering of the input signal */ /*******************************************/ #if HIGH_PASS_INPUT /* Variable high-pass filter */ SKP_Silk_HP_variable_cutoff_FIX( psEnc, &sEncCtrl, pIn_HP, pIn ); #else SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); #endif #if SWITCH_TRANSITION_FILTERING /* Ensure smooth bandwidth transitions */ SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length ); #else SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) ); #endif /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame ); /************************/ /* Noise shape analysis */ /************************/ SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); /*****************************************/ /* Prefiltering for noise shaper */ /*****************************************/ SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame ); /***************************************************/ /* Find linear prediction coefficients (LPC + LTP) */ /***************************************************/ SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch ); /****************************************/ /* Process gains */ /****************************************/ SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl ); /****************************************/ /* Low Bitrate Redundant Encoding */ /****************************************/ nBytesLBRR = MAX_ARITHM_BYTES; SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw ); /*****************************************/ /* Noise shaping quantization */ /*****************************************/ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sNSQ, xfw, psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2, sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); } else { SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sNSQ, xfw, psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2, sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); } /**************************************************/ /* Convert speech activity into VAD and DTX flags */ /**************************************************/ if( psEnc->speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY; psEnc->sCmn.noSpeechCounter++; if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) { psEnc->sCmn.inDTX = 1; } if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NO_SPEECH_FRAMES_BEFORE_DTX ) { psEnc->sCmn.noSpeechCounter = NO_SPEECH_FRAMES_BEFORE_DTX; psEnc->sCmn.inDTX = 0; } } else { psEnc->sCmn.noSpeechCounter = 0; psEnc->sCmn.inDTX = 0; psEnc->sCmn.vadFlag = VOICE_ACTIVITY; } /****************************************/ /* Initialize range coder */ /****************************************/ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) { SKP_Silk_range_enc_init( &psEnc->sCmn.sRC ); psEnc->sCmn.nBytesInPayloadBuf = 0; } /****************************************/ /* Encode Parameters */ /****************************************/ SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC, psEnc->sCmn.q ); FrameTermination_CDF = SKP_Silk_FrameTermination_CDF; /****************************************/ /* Update Buffers and State */ /****************************************/ /* Update input buffer */ SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], ( psEnc->sCmn.frame_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) ); /* Parameters needed for next frame */ psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype; psEnc->sCmn.prevLag = sEncCtrl.sCmn.pitchL[ NB_SUBFR - 1]; psEnc->sCmn.first_frame_after_reset = 0; if( psEnc->sCmn.sRC.error ) { /* Encoder returned error: clear payload buffer */ psEnc->sCmn.nFramesInPayloadBuf = 0; } else { psEnc->sCmn.nFramesInPayloadBuf++; } /****************************************/ /* Finalize payload and copy to output */ /****************************************/ if( psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms ) { LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK; /* Check if FEC information should be added */ frame_terminator = SKP_SILK_LAST_FRAME; if( psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS1 ) { frame_terminator = SKP_SILK_LBRR_VER1; } if( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS2 ) { frame_terminator = SKP_SILK_LBRR_VER2; LBRR_idx = psEnc->sCmn.oldest_LBRR_idx; } /* Add the frame termination info to stream */ SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF ); /* Payload length so far */ SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes ); /* Check that there is enough space in external output buffer, and move data */ if( *pnBytesOut >= nBytes ) { SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC ); SKP_memcpy( pCode, psEnc->sCmn.sRC.buffer, nBytes * sizeof( SKP_uint8 ) ); if( frame_terminator > SKP_SILK_MORE_FRAMES && *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) { /* Get old packet and add to payload. */ SKP_memcpy( &pCode[ nBytes ], psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload, psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) ); nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes; } *pnBytesOut = nBytes; /* Update FEC buffer */ SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload, nBytesLBRR * sizeof( SKP_uint8 ) ); psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR; /* The line below describes how FEC should be used */ psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage; psEnc->sCmn.oldest_LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK; } else { /* Not enough space: Payload will be discarded */ *pnBytesOut = 0; nBytes = 0; ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT; } /* Reset the number of frames in payload buffer */ psEnc->sCmn.nFramesInPayloadBuf = 0; } else { /* No payload this time */ *pnBytesOut = 0; /* Encode that more frames follows */ frame_terminator = SKP_SILK_MORE_FRAMES; SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF ); /* Payload length so far */ SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes ); } /* Check for arithmetic coder errors */ if( psEnc->sCmn.sRC.error ) { ret = SKP_SILK_ENC_INTERNAL_ERROR; } /* Simulate number of ms buffered in channel because of exceeding TargetRate */ SKP_assert( ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) == SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) ); SKP_assert( psEnc->sCmn.TargetRate_bps > 0 ); psEnc->BufferedInChannel_ms += SKP_DIV32( 8 * 1000 * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ), psEnc->sCmn.TargetRate_bps ); psEnc->BufferedInChannel_ms -= FRAME_LENGTH_MS; psEnc->BufferedInChannel_ms = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 ); psEnc->sCmn.nBytesInPayloadBuf = nBytes; if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES, 8 ) ) { psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, FRAME_LENGTH_MS ); } return( ret ); } /* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */ void SKP_Silk_LBRR_encode_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk encoder control struct */ SKP_uint8 *pCode, /* O Pointer to payload */ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */ SKP_int16 xfw[] /* I Input signal */ ) { SKP_int TempGainsIndices[ NB_SUBFR ], frame_terminator; SKP_int nBytes, nFramesInPayloadBuf; SKP_int32 TempGains_Q16[ NB_SUBFR ]; SKP_int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0; /*******************************************/ /* Control use of inband LBRR */ /*******************************************/ SKP_Silk_LBRR_ctrl_FIX( psEnc, &psEncCtrl->sCmn ); if( psEnc->sCmn.LBRR_enabled ) { /* Save original gains */ SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, NB_SUBFR * sizeof( SKP_int ) ); SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) ); typeOffset = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex; /* Set max rate where quant signal is encoded */ if( psEnc->sCmn.fs_kHz == 8 ) { Rate_only_parameters = 13500; } else if( psEnc->sCmn.fs_kHz == 12 ) { Rate_only_parameters = 15500; } else if( psEnc->sCmn.fs_kHz == 16 ) { Rate_only_parameters = 17500; } else if( psEnc->sCmn.fs_kHz == 24 ) { Rate_only_parameters = 19500; } else { SKP_assert( 0 ); } if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) { if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) { /* First frame in packet; copy everything */ SKP_memcpy( &psEnc->sCmn.sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) ); psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; /* Increase Gains to get target LBRR rate */ psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 ); } /* Decode to get gains in sync with decoder */ /* Overwrite unquantized gains with quantized gains */ SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf ); /*****************************************/ /* Noise shaping quantization */ /*****************************************/ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); } else { SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); } } else { SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) ); psEncCtrl->sCmn.LTP_scaleIndex = 0; } /****************************************/ /* Initialize arithmetic coder */ /****************************************/ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) { SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR ); psEnc->sCmn.nBytesInPayloadBuf = 0; } /****************************************/ /* Encode Parameters */ /****************************************/ SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.q_LBRR ); if( psEnc->sCmn.sRC_LBRR.error ) { /* Encoder returned error: clear payload buffer */ nFramesInPayloadBuf = 0; } else { nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1; } /****************************************/ /* Finalize payload and copy to output */ /****************************************/ if( SKP_SMULBB( nFramesInPayloadBuf, FRAME_LENGTH_MS ) >= psEnc->sCmn.PacketSize_ms ) { /* Check if FEC information should be added */ frame_terminator = SKP_SILK_LAST_FRAME; /* Add the frame termination info to stream */ SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF ); /* Payload length so far */ SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes ); /* Check that there is enough space in external output buffer and move data */ if( *pnBytesOut >= nBytes ) { SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC_LBRR ); SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.buffer, nBytes * sizeof( SKP_uint8 ) ); *pnBytesOut = nBytes; } else { /* Not enough space: payload will be discarded */ *pnBytesOut = 0; SKP_assert( 0 ); } } else { /* No payload this time */ *pnBytesOut = 0; /* Encode that more frames follows */ frame_terminator = SKP_SILK_MORE_FRAMES; SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF ); } /* Restore original Gains */ SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, NB_SUBFR * sizeof( SKP_int ) ); SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, NB_SUBFR * sizeof( SKP_int32 ) ); /* Restore LTP scale index and typeoffset */ psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex; psEnc->sCmn.typeOffsetPrev = typeOffset; } } ================================================ FILE: app/jni/SKP_Silk_encode_parameters.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /*******************************************/ /* Encode parameters to create the payload */ /*******************************************/ void SKP_Silk_encode_parameters( SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */ SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */ SKP_Silk_range_coder_state *psRC, /* I/O Range encoder state */ const SKP_int8 *q /* I Quantization indices */ ) { SKP_int i, k, typeOffset; const SKP_Silk_NLSF_CB_struct *psNLSF_CB; /************************/ /* Encode sampling rate */ /************************/ /* only done for first frame in packet */ if( psEncC->nFramesInPayloadBuf == 0 ) { /* get sampling rate index */ for( i = 0; i < 3; i++ ) { if( SKP_Silk_SamplingRates_table[ i ] == psEncC->fs_kHz ) { break; } } SKP_Silk_range_encoder( psRC, i, SKP_Silk_SamplingRates_CDF ); } /*******************************************/ /* Encode signal type and quantizer offset */ /*******************************************/ typeOffset = 2 * psEncCtrlC->sigtype + psEncCtrlC->QuantOffsetType; if( psEncC->nFramesInPayloadBuf == 0 ) { /* first frame in packet: independent coding */ SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_CDF ); } else { /* condidtional coding */ SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_joint_CDF[ psEncC->typeOffsetPrev ] ); } psEncC->typeOffsetPrev = typeOffset; /****************/ /* Encode gains */ /****************/ /* first subframe */ if( psEncC->nFramesInPayloadBuf == 0 ) { /* first frame in packet: independent coding */ SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_gain_CDF[ psEncCtrlC->sigtype ] ); } else { /* condidtional coding */ SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_delta_gain_CDF ); } /* remaining subframes */ for( i = 1; i < NB_SUBFR; i++ ) { SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ i ], SKP_Silk_delta_gain_CDF ); } /****************/ /* Encode NLSFs */ /****************/ /* Range encoding of the NLSF path */ psNLSF_CB = psEncC->psNLSF_CB[ psEncCtrlC->sigtype ]; SKP_Silk_range_encoder_multi( psRC, psEncCtrlC->NLSFIndices, psNLSF_CB->StartPtr, psNLSF_CB->nStages ); /* Encode NLSF interpolation factor */ SKP_assert( psEncC->useInterpolatedNLSFs == 1 || psEncCtrlC->NLSFInterpCoef_Q2 == ( 1 << 2 ) ); SKP_Silk_range_encoder( psRC, psEncCtrlC->NLSFInterpCoef_Q2, SKP_Silk_NLSF_interpolation_factor_CDF ); if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) { /*********************/ /* Encode pitch lags */ /*********************/ /* lag index */ if( psEncC->fs_kHz == 8 ) { SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_NB_CDF ); } else if( psEncC->fs_kHz == 12 ) { SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_MB_CDF ); } else if( psEncC->fs_kHz == 16 ) { SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_WB_CDF ); } else { SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_SWB_CDF ); } /* countour index */ if( psEncC->fs_kHz == 8 ) { /* Less codevectors used in 8 khz mode */ SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_NB_CDF ); } else { /* Joint for 12, 16, 24 khz */ SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_CDF ); } /********************/ /* Encode LTP gains */ /********************/ /* PERIndex value */ SKP_Silk_range_encoder( psRC, psEncCtrlC->PERIndex, SKP_Silk_LTP_per_index_CDF ); /* Codebook Indices */ for( k = 0; k < NB_SUBFR; k++ ) { SKP_Silk_range_encoder( psRC, psEncCtrlC->LTPIndex[ k ], SKP_Silk_LTP_gain_CDF_ptrs[ psEncCtrlC->PERIndex ] ); } /**********************/ /* Encode LTP scaling */ /**********************/ SKP_Silk_range_encoder( psRC, psEncCtrlC->LTP_scaleIndex, SKP_Silk_LTPscale_CDF ); } /***************/ /* Encode seed */ /***************/ SKP_Silk_range_encoder( psRC, psEncCtrlC->Seed, SKP_Silk_Seed_CDF ); /*********************************************/ /* Encode quantization indices of excitation */ /*********************************************/ SKP_Silk_encode_pulses( psRC, psEncCtrlC->sigtype, psEncCtrlC->QuantOffsetType, q, psEncC->frame_length ); /*********************************************/ /* Encode VAD flag */ /*********************************************/ SKP_Silk_range_encoder( psRC, psEncC->vadFlag, SKP_Silk_vadflag_CDF ); } ================================================ FILE: app/jni/SKP_Silk_encode_pulses.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /*********************************************/ /* Encode quantization indices of excitation */ /*********************************************/ SKP_INLINE SKP_int combine_and_check( /* return ok */ SKP_int *pulses_comb, /* O */ const SKP_int *pulses_in, /* I */ SKP_int max_pulses, /* I max value for sum of pulses */ SKP_int len /* I number of output values */ ) { SKP_int k, sum; for( k = 0; k < len; k++ ) { sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ]; if( sum > max_pulses ) { return 1; } pulses_comb[ k ] = sum; } return 0; } /* Encode quantization indices of excitation */ void SKP_Silk_encode_pulses( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ const SKP_int sigtype, /* I Sigtype */ const SKP_int QuantOffsetType,/* I QuantOffsetType */ const SKP_int8 q[], /* I quantization indices */ const SKP_int frame_length /* I Frame length */ ) { SKP_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; SKP_int32 abs_q, minSumBits_Q6, sumBits_Q6; SKP_int abs_pulses[ MAX_FRAME_LENGTH ]; SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ]; SKP_int nRshifts[ MAX_NB_SHELL_BLOCKS ]; SKP_int pulses_comb[ 8 ]; SKP_int *abs_pulses_ptr; const SKP_int8 *pulses_ptr; const SKP_uint16 *cdf_ptr; const SKP_int16 *nBits_ptr; SKP_memset( pulses_comb, 0, 8 * sizeof( SKP_int ) ); // Fixing Valgrind reported problem /****************************/ /* Prepare for shell coding */ /****************************/ /* Calculate number of shell blocks */ iter = frame_length / SHELL_CODEC_FRAME_LENGTH; /* Take the absolute value of the pulses */ for( i = 0; i < frame_length; i+=4 ) { abs_pulses[i+0] = ( SKP_int )SKP_abs( q[ i + 0 ] ); abs_pulses[i+1] = ( SKP_int )SKP_abs( q[ i + 1 ] ); abs_pulses[i+2] = ( SKP_int )SKP_abs( q[ i + 2 ] ); abs_pulses[i+3] = ( SKP_int )SKP_abs( q[ i + 3 ] ); } /* Calc sum pulses per shell code frame */ abs_pulses_ptr = abs_pulses; for( i = 0; i < iter; i++ ) { nRshifts[ i ] = 0; while( 1 ) { /* 1+1 -> 2 */ scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, SKP_Silk_max_pulses_table[ 0 ], 8 ); /* 2+2 -> 4 */ scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 1 ], 4 ); /* 4+4 -> 8 */ scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 2 ], 2 ); /* 8+8 -> 16 */ sum_pulses[ i ] = pulses_comb[ 0 ] + pulses_comb[ 1 ]; if( sum_pulses[ i ] > SKP_Silk_max_pulses_table[ 3 ] ) { scale_down++; } if( scale_down ) { /* We need to down scale the quantization signal */ nRshifts[ i ]++; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_pulses_ptr[ k ] = SKP_RSHIFT( abs_pulses_ptr[ k ], 1 ); } } else { /* Jump out of while(1) loop and go to next shell coding frame */ break; } } abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH; } /**************/ /* Rate level */ /**************/ /* find rate level that leads to fewest bits for coding of pulses per block info */ minSumBits_Q6 = SKP_int32_MAX; for( k = 0; k < N_RATE_LEVELS - 1; k++ ) { nBits_ptr = SKP_Silk_pulses_per_block_BITS_Q6[ k ]; sumBits_Q6 = SKP_Silk_rate_levels_BITS_Q6[sigtype][ k ]; for( i = 0; i < iter; i++ ) { if( nRshifts[ i ] > 0 ) { sumBits_Q6 += nBits_ptr[ MAX_PULSES + 1 ]; } else { sumBits_Q6 += nBits_ptr[ sum_pulses[ i ] ]; } } if( sumBits_Q6 < minSumBits_Q6 ) { minSumBits_Q6 = sumBits_Q6; RateLevelIndex = k; } } SKP_Silk_range_encoder( psRC, RateLevelIndex, SKP_Silk_rate_levels_CDF[ sigtype ] ); /***************************************************/ /* Sum-Weighted-Pulses Encoding */ /***************************************************/ cdf_ptr = SKP_Silk_pulses_per_block_CDF[ RateLevelIndex ]; for( i = 0; i < iter; i++ ) { if( nRshifts[ i ] == 0 ) { SKP_Silk_range_encoder( psRC, sum_pulses[ i ], cdf_ptr ); } else { SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, cdf_ptr ); for( k = 0; k < nRshifts[ i ] - 1; k++ ) { SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] ); } SKP_Silk_range_encoder( psRC, sum_pulses[ i ], SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] ); } } /******************/ /* Shell Encoding */ /******************/ for( i = 0; i < iter; i++ ) { if( sum_pulses[ i ] > 0 ) { SKP_Silk_shell_encoder( psRC, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] ); } } /****************/ /* LSB Encoding */ /****************/ for( i = 0; i < iter; i++ ) { if( nRshifts[ i ] > 0 ) { pulses_ptr = &q[ i * SHELL_CODEC_FRAME_LENGTH ]; nLS = nRshifts[ i ] - 1; for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { abs_q = (SKP_int8)SKP_abs( pulses_ptr[ k ] ); for( j = nLS; j > 0; j-- ) { bit = SKP_RSHIFT( abs_q, j ) & 1; SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF ); } bit = abs_q & 1; SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF ); } } } /****************/ /* Encode signs */ /****************/ SKP_Silk_encode_signs( psRC, q, frame_length, sigtype, QuantOffsetType, RateLevelIndex ); } ================================================ FILE: app/jni/SKP_Silk_find_LPC_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /* Finds LPC vector from correlations, and converts to NLSF */ void SKP_Silk_find_LPC_FIX( SKP_int NLSF_Q15[], /* O NLSFs */ SKP_int *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */ const SKP_int prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */ const SKP_int useInterpolatedNLSFs, /* I Flag */ const SKP_int LPC_order, /* I LPC order */ const SKP_int16 x[], /* I Input signal */ const SKP_int subfr_length /* I Input signal subframe length including preceeding samples */ ) { SKP_int k; SKP_int32 a_Q16[ MAX_LPC_ORDER ]; SKP_int isInterpLower, shift; SKP_int16 S[ MAX_LPC_ORDER ]; SKP_int32 res_nrg0, res_nrg1; SKP_int rshift0, rshift1; /* Used only for LSF interpolation */ SKP_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg; SKP_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q; SKP_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; SKP_int NLSF0_Q15[ MAX_LPC_ORDER ]; SKP_int16 LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; /* Default: no interpolation */ *interpIndex = 4; /* Burg AR analysis for the full frame */ SKP_Silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, NB_SUBFR, SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order ); SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) ); if( useInterpolatedNLSFs == 1 ) { /* Optimal solution for last 10 ms */ SKP_Silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( NB_SUBFR >> 1 ) * subfr_length, subfr_length, ( NB_SUBFR >> 1 ), SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order ); SKP_Silk_bwexpander_32( a_tmp_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) ); /* subtract residual energy here, as that's easier than adding it to the */ /* residual energy of the first 10 ms in each iteration of the search below */ shift = res_tmp_nrg_Q - res_nrg_Q; if( shift >= 0 ) { if( shift < 32 ) { res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift ); } } else { SKP_assert( shift > -32 ); res_nrg = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; res_nrg_Q = res_tmp_nrg_Q; } /* Convert to NLSFs */ SKP_Silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order ); /* Search over interpolation indices to find the one with lowest residual energy */ for( k = 3; k >= 0; k-- ) { /* Interpolate NLSFs for first half */ SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order ); /* Convert to LPC for residual energy evaluation */ SKP_Silk_NLSF2A_stable( a_tmp_Q12, NLSF0_Q15, LPC_order ); /* Calculate residual energy with NLSF interpolation */ SKP_memset( S, 0, LPC_order * sizeof( SKP_int16 ) ); SKP_Silk_LPC_analysis_filter( x, a_tmp_Q12, S, LPC_res, 2 * subfr_length, LPC_order ); SKP_Silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order, subfr_length - LPC_order ); SKP_Silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order ); /* Add subframe energies from first half frame */ shift = rshift0 - rshift1; if( shift >= 0 ) { res_nrg1 = SKP_RSHIFT( res_nrg1, shift ); res_nrg_interp_Q = -rshift0; } else { res_nrg0 = SKP_RSHIFT( res_nrg0, -shift ); res_nrg_interp_Q = -rshift1; } res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 ); /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ shift = res_nrg_interp_Q - res_nrg_Q; if( shift >= 0 ) { if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { isInterpLower = SKP_TRUE; } else { isInterpLower = SKP_FALSE; } } else { if( -shift < 32 ) { if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) { isInterpLower = SKP_TRUE; } else { isInterpLower = SKP_FALSE; } } else { isInterpLower = SKP_FALSE; } } /* Determine whether current interpolated NLSFs are best so far */ if( isInterpLower == SKP_TRUE ) { /* Interpolation has lower residual energy */ res_nrg = res_nrg_interp; res_nrg_Q = res_nrg_interp_Q; *interpIndex = k; } } } if( *interpIndex == 4 ) { /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ SKP_Silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order ); } } ================================================ FILE: app/jni/SKP_Silk_find_LTP_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /* Head room for correlations */ #define LTP_CORRS_HEAD_ROOM 2 void SKP_Silk_fit_LTP( SKP_int32 LTP_coefs_Q16[ LTP_ORDER ], SKP_int16 LTP_coefs_Q14[ LTP_ORDER ] ); void SKP_Silk_find_LTP_FIX( SKP_int16 b_Q14[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */ const SKP_int16 r_first[], /* I residual signal after LPC signal + state for first 10 ms */ const SKP_int16 r_last[], /* I residual signal after LPC signal + state for last 10 ms */ const SKP_int lag[ NB_SUBFR ], /* I LTP lags */ const SKP_int32 Wght_Q15[ NB_SUBFR ], /* I weights */ const SKP_int subfr_length, /* I subframe length */ const SKP_int mem_offset, /* I number of samples in LTP memory */ SKP_int corr_rshifts[ NB_SUBFR ] /* O right shifts applied to correlations */ ) { SKP_int i, k, lshift; const SKP_int16 *r_ptr, *lag_ptr; SKP_int16 *b_Q14_ptr; SKP_int32 regu; SKP_int32 *WLTP_ptr; SKP_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ NB_SUBFR ], nrg[ NB_SUBFR ], g_Q26; SKP_int32 w[ NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits; SKP_int32 temp32, denom32; SKP_int extra_shifts; SKP_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs; SKP_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16; SKP_int32 Rr[ LTP_ORDER ], rr[ NB_SUBFR ]; SKP_int32 wd, m_Q12; b_Q14_ptr = b_Q14; WLTP_ptr = WLTP; r_ptr = &r_first[ mem_offset ]; for( k = 0; k < NB_SUBFR; k++ ) { if( k == ( NB_SUBFR >> 1 ) ) { /* shift residual for last 10 ms */ r_ptr = &r_last[ mem_offset ]; } lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); SKP_Silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */ /* Assure headroom */ LZs = SKP_Silk_CLZ32( rr[k] ); if( LZs < LTP_CORRS_HEAD_ROOM ) { rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs ); rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs ); } corr_rshifts[ k ] = rr_shifts; SKP_Silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */ /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */ SKP_Silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */ if( corr_rshifts[ k ] > rr_shifts ) { rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */ } SKP_assert( rr[ k ] >= 0 ); regu = 1; regu = SKP_SMLAWB( regu, rr[ k ], SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) ); SKP_Silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER ); SKP_Silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */ /* Limit and store in Q14 */ SKP_Silk_fit_LTP( b_Q16, b_Q14_ptr ); /* Calculate residual energy */ nrg[ k ] = SKP_Silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */ /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */ extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM ); denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */ SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ denom32 = SKP_max( denom32, 1 ); SKP_assert( ((SKP_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX ); /* Wght always < 0.5 in Q0 */ temp32 = SKP_DIV32( SKP_LSHIFT( ( SKP_int32 )Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */ temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */ /* Limit temp such that the below scaling never wraps around */ WLTP_max = 0; for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max ); } lshift = SKP_Silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */ SKP_assert( 26 - 18 + lshift >= 0 ); if( 26 - 18 + lshift < 31 ) { temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( SKP_int32 )1, 26 - 18 + lshift ) ); } SKP_Silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */ w[ k ] = matrix_ptr( WLTP_ptr, ( LTP_ORDER >> 1 ), ( LTP_ORDER >> 1 ), LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */ SKP_assert( w[k] >= 0 ); r_ptr += subfr_length; b_Q14_ptr += LTP_ORDER; WLTP_ptr += LTP_ORDER * LTP_ORDER; } maxRshifts = 0; for( k = 0; k < NB_SUBFR; k++ ) { maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts ); } /* Compute LTP coding gain */ if( LTPredCodGain_Q7 != NULL ) { LPC_LTP_res_nrg = 0; LPC_res_nrg = 0; SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */ for( k = 0; k < NB_SUBFR; k++ ) { LPC_res_nrg = SKP_ADD32( LPC_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ } LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */ div_Q16 = SKP_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 ); *LTPredCodGain_Q7 = ( SKP_int )SKP_SMULBB( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ); SKP_assert( *LTPredCodGain_Q7 == ( SKP_int )SKP_SAT16( SKP_MUL( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) ); } /* smoothing */ /* d = sum( B, 1 ); */ b_Q14_ptr = b_Q14; for( k = 0; k < NB_SUBFR; k++ ) { d_Q14[ k ] = 0; for( i = 0; i < LTP_ORDER; i++ ) { d_Q14[ k ] += b_Q14_ptr[ i ]; } b_Q14_ptr += LTP_ORDER; } /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */ max_abs_d_Q14 = 0; max_w_bits = 0; for( k = 0; k < NB_SUBFR; k++ ) { max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) ); /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */ /* Find bits needed in Q( 18 - maxRshifts ) */ max_w_bits = SKP_max_32( max_w_bits, 32 - SKP_Silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts ); } /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */ SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) ); /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */ extra_shifts = max_w_bits + 32 - SKP_Silk_CLZ32( max_abs_d_Q14 ) - 14; /* Subtract what we got available; bits in output var plus maxRshifts */ extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */ extra_shifts = SKP_max_int( extra_shifts, 0 ); maxRshifts_wxtra = maxRshifts + extra_shifts; temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */ wd = 0; for( k = 0; k < NB_SUBFR; k++ ) { /* w has at least 2 bits of headroom so no overflow should happen */ temp32 = SKP_ADD32( temp32, SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */ wd = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */ } m_Q12 = SKP_DIV32_varQ( wd, temp32, 12 ); b_Q14_ptr = b_Q14; for( k = 0; k < NB_SUBFR; k++ ) { /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */ if( 2 - corr_rshifts[k] > 0 ) { temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] ); } else { temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 ); } g_Q26 = SKP_MUL( SKP_DIV32( SKP_FIX_CONST( LTP_SMOOTHING, 26 ), SKP_RSHIFT( SKP_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */ SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( SKP_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */ temp32 = 0; for( i = 0; i < LTP_ORDER; i++ ) { delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */ temp32 += delta_b_Q14[ i ]; /* Q14 */ } temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */ for( i = 0; i < LTP_ORDER; i++ ) { b_Q14_ptr[ i ] = SKP_LIMIT_32( ( SKP_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 ); } b_Q14_ptr += LTP_ORDER; } } void SKP_Silk_fit_LTP( SKP_int32 LTP_coefs_Q16[ LTP_ORDER ], SKP_int16 LTP_coefs_Q14[ LTP_ORDER ] ) { SKP_int i; for( i = 0; i < LTP_ORDER; i++ ) { LTP_coefs_Q14[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) ); } } ================================================ FILE: app/jni/SKP_Silk_find_pitch_lags_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /* Find pitch lags */ void SKP_Silk_find_pitch_lags_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ SKP_int16 res[], /* O residual */ const SKP_int16 x[] /* I Speech signal */ ) { SKP_Silk_predict_state_FIX *psPredSt = &psEnc->sPred; SKP_int buf_len, i, scale; SKP_int32 thrhld_Q15, res_nrg; const SKP_int16 *x_buf, *x_buf_ptr; SKP_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr; SKP_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; SKP_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; SKP_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; SKP_int32 FiltState[ MAX_FIND_PITCH_LPC_ORDER ]; SKP_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; /******************************************/ /* Setup buffer lengths etc based on Fs */ /******************************************/ buf_len = SKP_ADD_LSHIFT( psEnc->sCmn.la_pitch, psEnc->sCmn.frame_length, 1 ); /* Safty check */ SKP_assert( buf_len >= psPredSt->pitch_LPC_win_length ); x_buf = x - psEnc->sCmn.frame_length; /*************************************/ /* Estimate LPC AR coefficients */ /*************************************/ /* Calculate windowed signal */ /* First LA_LTP samples */ x_buf_ptr = x_buf + buf_len - psPredSt->pitch_LPC_win_length; Wsig_ptr = Wsig; SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); /* Middle un - windowed samples */ Wsig_ptr += psEnc->sCmn.la_pitch; x_buf_ptr += psEnc->sCmn.la_pitch; SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( SKP_int16 ) ); /* Last LA_LTP samples */ Wsig_ptr += psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ); x_buf_ptr += psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ); SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); /* Calculate autocorrelation sequence */ SKP_Silk_autocorr( auto_corr, &scale, Wsig, psPredSt->pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); /* Add white noise, as fraction of energy */ auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); /* Calculate the reflection coefficients using schur */ res_nrg = SKP_Silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); /* Prediction gain */ psEncCtrl->predGain_Q16 = SKP_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 ); /* Convert reflection coefficients to prediction coefficients */ SKP_Silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { A_Q12[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) ); } /* Do BWE */ SKP_Silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SKP_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) ); /*****************************************/ /* LPC analysis filtering */ /*****************************************/ SKP_memset( FiltState, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind will complain otherwise */ SKP_Silk_MA_Prediction( x_buf, A_Q12, FiltState, res, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); SKP_memset( res, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_int16 ) ); /* Threshold for pitch estimator */ thrhld_Q15 = SKP_FIX_CONST( 0.45, 15 ); thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder ); thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.1, 7 ), psEnc->speech_activity_Q8 ); thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( 0.15, 15 ), psEnc->sCmn.prev_sigtype ); thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SKP_FIX_CONST( -0.1, 16 ), psEncCtrl->input_tilt_Q15 ); thrhld_Q15 = SKP_SAT16( thrhld_Q15 ); /*****************************************/ /* Call pitch estimator */ /*****************************************/ psEncCtrl->sCmn.sigtype = SKP_Silk_pitch_analysis_core( res, psEncCtrl->sCmn.pitchL, &psEncCtrl->sCmn.lagIndex, &psEncCtrl->sCmn.contourIndex, &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, ( SKP_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, SKP_FALSE ); } ================================================ FILE: app/jni/SKP_Silk_find_pred_coefs_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" void SKP_Silk_find_pred_coefs_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ const SKP_int16 res_pitch[] /* I Residual from pitch analysis */ ) { SKP_int i; SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ]; SKP_int32 invGains_Q16[ NB_SUBFR ], local_gains[ NB_SUBFR ], Wght_Q15[ NB_SUBFR ]; SKP_int NLSF_Q15[ MAX_LPC_ORDER ]; const SKP_int16 *x_ptr; SKP_int16 *x_pre_ptr, LPC_in_pre[ NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; SKP_int32 tmp, min_gain_Q16; SKP_int LTP_corrs_rshift[ NB_SUBFR ]; /* weighting for weighted least squares */ min_gain_Q16 = SKP_int32_MAX >> 6; for( i = 0; i < NB_SUBFR; i++ ) { min_gain_Q16 = SKP_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); } for( i = 0; i < NB_SUBFR; i++ ) { /* Divide to Q16 */ SKP_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ invGains_Q16[ i ] = SKP_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); /* Ensure Wght_Q15 a minimum value 1 */ invGains_Q16[ i ] = SKP_max( invGains_Q16[ i ], 363 ); /* Square the inverted gains */ SKP_assert( invGains_Q16[ i ] == SKP_SAT16( invGains_Q16[ i ] ) ); tmp = SKP_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] ); Wght_Q15[ i ] = SKP_RSHIFT( tmp, 1 ); /* Invert the inverted and normalized gains */ local_gains[ i ] = SKP_DIV32( ( 1 << 16 ), invGains_Q16[ i ] ); } if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /**********/ /* VOICED */ /**********/ SKP_assert( psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->sCmn.pitchL[ 0 ] + LTP_ORDER / 2 ); /* LTP analysis */ SKP_Silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, res_pitch, res_pitch + SKP_RSHIFT( psEnc->sCmn.frame_length, 1 ), psEncCtrl->sCmn.pitchL, Wght_Q15, psEnc->sCmn.subfr_length, psEnc->sCmn.frame_length, LTP_corrs_rshift ); /* Quantize LTP gain parameters */ SKP_Silk_quant_LTP_gains_FIX( psEncCtrl->LTPCoef_Q14, psEncCtrl->sCmn.LTPIndex, &psEncCtrl->sCmn.PERIndex, WLTP, psEnc->mu_LTP_Q8, psEnc->sCmn.LTPQuantLowComplexity ); /* Control LTP scaling */ SKP_Silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl ); /* Create LTP residual */ SKP_Silk_LTP_analysis_filter_FIX( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, psEncCtrl->sCmn.pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder ); } else { /************/ /* UNVOICED */ /************/ /* Create signal with prepended subframes, scaled by inverse gains */ x_ptr = psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder; x_pre_ptr = LPC_in_pre; for( i = 0; i < NB_SUBFR; i++ ) { SKP_Silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; x_ptr += psEnc->sCmn.subfr_length; } SKP_memset( psEncCtrl->LTPCoef_Q14, 0, NB_SUBFR * LTP_ORDER * sizeof( SKP_int16 ) ); psEncCtrl->LTPredCodGain_Q7 = 0; } /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ TIC(FIND_LPC) SKP_Silk_find_LPC_FIX( NLSF_Q15, &psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sPred.prev_NLSFq_Q15, psEnc->sCmn.useInterpolatedNLSFs * ( 1 - psEnc->sCmn.first_frame_after_reset ), psEnc->sCmn.predictLPCOrder, LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); TOC(FIND_LPC) /* Quantize LSFs */ TIC(PROCESS_LSFS) SKP_Silk_process_NLSFs_FIX( psEnc, psEncCtrl, NLSF_Q15 ); TOC(PROCESS_LSFS) /* Calculate residual energy using quantized LPC coefficients */ SKP_Silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder ); /* Copy to prediction struct for use in next frame for fluctuation reduction */ SKP_memcpy( psEnc->sPred.prev_NLSFq_Q15, NLSF_Q15, psEnc->sCmn.predictLPCOrder * sizeof( SKP_int ) ); } ================================================ FILE: app/jni/SKP_Silk_gain_quant.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" #define OFFSET ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 ) #define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) #define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) /* Gain scalar quantization with hysteresis, uniform on log scale */ void SKP_Silk_gains_quant( SKP_int ind[ NB_SUBFR ], /* O gain indices */ SKP_int32 gain_Q16[ NB_SUBFR ], /* I/O gains (quantized out) */ SKP_int *prev_ind, /* I/O last index in previous frame */ const SKP_int conditional /* I first gain is delta coded if 1 */ ) { SKP_int k; for( k = 0; k < NB_SUBFR; k++ ) { /* Add half of previous quantization error, convert to log scale, scale, floor() */ ind[ k ] = SKP_SMULWB( SCALE_Q16, SKP_Silk_lin2log( gain_Q16[ k ] ) - OFFSET ); /* Round towards previous quantized gain (hysteresis) */ if( ind[ k ] < *prev_ind ) { ind[ k ]++; } /* Compute delta indices and limit */ if( k == 0 && conditional == 0 ) { /* Full index */ ind[ k ] = SKP_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 ); ind[ k ] = SKP_max_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT ); *prev_ind = ind[ k ]; } else { /* Delta index */ ind[ k ] = SKP_LIMIT_int( ind[ k ] - *prev_ind, MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT ); /* Accumulate deltas */ *prev_ind += ind[ k ]; /* Shift to make non-negative */ ind[ k ] -= MIN_DELTA_GAIN_QUANT; } /* Convert to linear scale and scale */ gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3968 = 31 in Q7 */ } } /* Gains scalar dequantization, uniform on log scale */ void SKP_Silk_gains_dequant( SKP_int32 gain_Q16[ NB_SUBFR ], /* O quantized gains */ const SKP_int ind[ NB_SUBFR ], /* I gain indices */ SKP_int *prev_ind, /* I/O last index in previous frame */ const SKP_int conditional /* I first gain is delta coded if 1 */ ) { SKP_int k; for( k = 0; k < NB_SUBFR; k++ ) { if( k == 0 && conditional == 0 ) { *prev_ind = ind[ k ]; } else { /* Delta index */ *prev_ind += ind[ k ] + MIN_DELTA_GAIN_QUANT; } /* Convert to linear scale and scale */ gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3968 = 31 in Q7 */ } } ================================================ FILE: app/jni/SKP_Silk_init_encoder_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /*********************************/ /* Initialize Silk Encoder state */ /*********************************/ SKP_int SKP_Silk_init_encoder_FIX( SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ ) { SKP_int ret = 0; /* Clear the entire encoder state */ SKP_memset( psEnc, 0, sizeof( SKP_Silk_encoder_state_FIX ) ); #if HIGH_PASS_INPUT psEnc->variable_HP_smth1_Q15 = 200844; /* = SKP_Silk_log2(70)_Q0; */ psEnc->variable_HP_smth2_Q15 = 200844; /* = SKP_Silk_log2(70)_Q0; */ #endif /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */ psEnc->sCmn.first_frame_after_reset = 1; /* Initialize Silk VAD */ ret += SKP_Silk_VAD_Init( &psEnc->sCmn.sVAD ); /* Initialize NSQ */ psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536; psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536; return( ret ); } ================================================ FILE: app/jni/SKP_Silk_inner_prod_aligned.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_inner_prod_aligned.c * * * * * * Copyright 2008-2010 (c), Skype Limited * * Date: 080601 * * */ #include "SKP_Silk_SigProc_FIX.h" /* sum= for(i=0;i6, memory access can be reduced by half. */ #if (EMBEDDED_ARM<5) SKP_int32 SKP_Silk_inner_prod_aligned( const SKP_int16* const inVec1, /* I input vector 1 */ const SKP_int16* const inVec2, /* I input vector 2 */ const SKP_int len /* I vector lengths */ ) { SKP_int i; SKP_int32 sum = 0; for( i = 0; i < len; i++ ) { sum = SKP_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); } return sum; } #endif #if (EMBEDDED_ARM<5) SKP_int64 SKP_Silk_inner_prod16_aligned_64( const SKP_int16 *inVec1, /* I input vector 1 */ const SKP_int16 *inVec2, /* I input vector 2 */ const SKP_int len /* I vector lengths */ ) { SKP_int i; SKP_int64 sum = 0; for( i = 0; i < len; i++ ) { sum = SKP_SMLALBB( sum, inVec1[ i ], inVec2[ i ] ); } return sum; } #endif ================================================ FILE: app/jni/SKP_Silk_interpolate.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Interpolate two vectors */ void SKP_Silk_interpolate( SKP_int xi[ MAX_LPC_ORDER ], /* O interpolated vector */ const SKP_int x0[ MAX_LPC_ORDER ], /* I first vector */ const SKP_int x1[ MAX_LPC_ORDER ], /* I second vector */ const SKP_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ const SKP_int d /* I number of parameters */ ) { SKP_int i; SKP_assert( ifact_Q2 >= 0 ); SKP_assert( ifact_Q2 <= ( 1 << 2 ) ); for( i = 0; i < d; i++ ) { xi[ i ] = ( SKP_int )( ( SKP_int32 )x0[ i ] + SKP_RSHIFT( SKP_MUL( ( SKP_int32 )x1[ i ] - ( SKP_int32 )x0[ i ], ifact_Q2 ), 2 ) ); } } ================================================ FILE: app/jni/SKP_Silk_k2a.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_k2a.c * * * * Step up function, converts reflection coefficients to prediction * * coefficients * * * * Copyright 2008 (c), Skype Limited * * Date: 080103 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Step up function, converts reflection coefficients to prediction coefficients */ void SKP_Silk_k2a( SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */ const SKP_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */ const SKP_int32 order /* I: Prediction order */ ) { SKP_int k, n; SKP_int32 Atmp[ SKP_Silk_MAX_ORDER_LPC ]; for( k = 0; k < order; k++ ) { for( n = 0; n < k; n++ ) { Atmp[ n ] = A_Q24[ n ]; } for( n = 0; n < k; n++ ) { A_Q24[ n ] = SKP_SMLAWB( A_Q24[ n ], SKP_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] ); } A_Q24[ k ] = -SKP_LSHIFT( (SKP_int32)rc_Q15[ k ], 9 ); } } ================================================ FILE: app/jni/SKP_Silk_k2a_Q16.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_k2a.c * * * * Step up function, converts reflection coefficients to prediction * * coefficients * * * * Copyright 2008 (c), Skype Limited * * Date: 080103 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Step up function, converts reflection coefficients to prediction coefficients */ void SKP_Silk_k2a_Q16( SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */ const SKP_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */ const SKP_int32 order /* I: Prediction order */ ) { SKP_int k, n; SKP_int32 Atmp[ SKP_Silk_MAX_ORDER_LPC ]; for( k = 0; k < order; k++ ) { for( n = 0; n < k; n++ ) { Atmp[ n ] = A_Q24[ n ]; } for( n = 0; n < k; n++ ) { A_Q24[ n ] = SKP_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] ); } A_Q24[ k ] = -SKP_LSHIFT( rc_Q16[ k ], 8 ); } } ================================================ FILE: app/jni/SKP_Silk_lin2log.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_lin2log.c * * * * Convert input to a log scale * * Approximation of 128 * log2() * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" #if EMBEDDED_ARM<4 /* Approximation of 128 * log2() (very close inverse of approx 2^() below) */ /* Convert input to a log scale */ SKP_int32 SKP_Silk_lin2log( const SKP_int32 inLin ) /* I: Input in linear scale */ { SKP_int32 lz, frac_Q7; SKP_Silk_CLZ_FRAC( inLin, &lz, &frac_Q7 ); /* Piece-wise parabolic approximation */ return( SKP_LSHIFT( 31 - lz, 7 ) + SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), 179 ) ); } #endif ================================================ FILE: app/jni/SKP_Silk_log2lin.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_log2lin.c * * * * Convert input to a linear scale * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Approximation of 2^() (very close inverse of SKP_Silk_lin2log()) */ /* Convert input to a linear scale */ SKP_int32 SKP_Silk_log2lin( const SKP_int32 inLog_Q7 ) /* I: Input on log scale */ { SKP_int32 out, frac_Q7; if( inLog_Q7 < 0 ) { return( 0 ); } else if( inLog_Q7 >= ( 31 << 7 ) ) { /* Saturate, and prevent wrap-around */ return( SKP_int32_MAX ); } out = SKP_LSHIFT( 1, SKP_RSHIFT( inLog_Q7, 7 ) ); frac_Q7 = inLog_Q7 & 0x7F; if( inLog_Q7 < 2048 ) { /* Piece-wise parabolic approximation */ out = SKP_ADD_RSHIFT( out, SKP_MUL( out, SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); } else { /* Piece-wise parabolic approximation */ out = SKP_MLA( out, SKP_RSHIFT( out, 7 ), SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ); } return out; } ================================================ FILE: app/jni/SKP_Silk_noise_shape_analysis_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ /* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ SKP_INLINE SKP_int32 warped_gain( // gain in Q16 const SKP_int32 *coefs_Q24, SKP_int lambda_Q16, SKP_int order ) { SKP_int i; SKP_int32 gain_Q24; lambda_Q16 = -lambda_Q16; gain_Q24 = coefs_Q24[ order - 1 ]; for( i = order - 2; i >= 0; i-- ) { gain_Q24 = SKP_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); } gain_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); return SKP_INVERSE32_varQ( gain_Q24, 40 ); } /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ SKP_INLINE void limit_warped_coefs( SKP_int32 *coefs_syn_Q24, SKP_int32 *coefs_ana_Q24, SKP_int lambda_Q16, SKP_int32 limit_Q24, SKP_int order ) { SKP_int i, iter, ind = 0; SKP_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16; SKP_int32 nom_Q16, den_Q24; /* Convert to monic coefficients */ lambda_Q16 = -lambda_Q16; for( i = order - 1; i > 0; i-- ) { coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); for( i = 0; i < order; i++ ) { coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); } for( iter = 0; iter < 10; iter++ ) { /* Find maximum absolute value */ maxabs_Q24 = -1; for( i = 0; i < order; i++ ) { tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) ); if( tmp > maxabs_Q24 ) { maxabs_Q24 = tmp; ind = i; } } if( maxabs_Q24 <= limit_Q24 ) { /* Coefficients are within range - done */ return; } /* Convert back to true warped coefficients */ for( i = 1; i < order; i++ ) { coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } gain_syn_Q16 = SKP_INVERSE32_varQ( gain_syn_Q16, 32 ); gain_ana_Q16 = SKP_INVERSE32_varQ( gain_ana_Q16, 32 ); for( i = 0; i < order; i++ ) { coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); } /* Apply bandwidth expansion */ chirp_Q16 = SKP_FIX_CONST( 0.99, 16 ) - SKP_DIV32_varQ( SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SKP_FIX_CONST( 0.8, 10 ), SKP_FIX_CONST( 0.1, 10 ), iter ) ), SKP_MUL( maxabs_Q24, ind + 1 ), 22 ); SKP_Silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 ); SKP_Silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 ); /* Convert to monic warped coefficients */ lambda_Q16 = -lambda_Q16; for( i = order - 1; i > 0; i-- ) { coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); } lambda_Q16 = -lambda_Q16; nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 ); for( i = 0; i < order; i++ ) { coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); } } SKP_assert( 0 ); } /**************************************************************/ /* Compute noise shaping coefficients and initial gain values */ /**************************************************************/ void SKP_Silk_noise_shape_analysis_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ const SKP_int16 *pitch_res, /* I LPC residual from pitch analysis */ const SKP_int16 *x /* I Input signal [ frame_length + la_shape ] */ ) { SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; SKP_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; SKP_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; SKP_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; SKP_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; SKP_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; SKP_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; SKP_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; SKP_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; SKP_int16 x_windowed[ SHAPE_LPC_WIN_MAX ]; const SKP_int16 *x_ptr, *pitch_res_ptr; /* Point to start of first LPC analysis block */ x_ptr = x - psEnc->sCmn.la_shape; /****************/ /* CONTROL SNR */ /****************/ /* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */ psEncCtrl->current_SNR_dB_Q7 = psEnc->SNR_dB_Q7 - SKP_SMULWB( SKP_LSHIFT( ( SKP_int32 )psEnc->BufferedInChannel_ms, 7 ), SKP_FIX_CONST( 0.05, 16 ) ); /* Reduce SNR_dB if inband FEC used */ if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { psEncCtrl->current_SNR_dB_Q7 -= SKP_RSHIFT( psEnc->inBandFEC_SNR_comp_Q8, 1 ); } /****************/ /* GAIN CONTROL */ /****************/ /* Input quality is the average of the quality in the lowest two VAD bands */ psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEncCtrl->input_quality_bands_Q15[ 0 ] + psEncCtrl->input_quality_bands_Q15[ 1 ], 2 ); /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->current_SNR_dB_Q7 - SKP_FIX_CONST( 18.0, 7 ), 4 ) ), 1 ); /* Reduce coding SNR during low speech activity */ b_Q8 = SKP_FIX_CONST( 1.0, 8 ) - psEnc->speech_activity_Q8; b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 ); SNR_adj_dB_Q7 = SKP_SMLAWB( psEncCtrl->current_SNR_dB_Q7, SKP_SMULBB( SKP_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), // Q11 SKP_SMULWB( SKP_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); // Q12 if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /* Reduce gains for periodic signals */ SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); } else { /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_SMLAWB( SKP_FIX_CONST( 6.0, 9 ), -SKP_FIX_CONST( 0.4, 18 ), psEncCtrl->current_SNR_dB_Q7 ), SKP_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); } /*************************/ /* SPARSENESS PROCESSING */ /*************************/ /* Set quantizer offset */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /* Initally set to 0; may be overruled in process_gains(..) */ psEncCtrl->sCmn.QuantOffsetType = 0; psEncCtrl->sparseness_Q8 = 0; } else { /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); energy_variation_Q7 = 0; log_energy_prev_Q7 = 0; pitch_res_ptr = pitch_res; for( k = 0; k < FRAME_LENGTH_MS / 2; k++ ) { SKP_Silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); nrg += SKP_RSHIFT( nSamples, scale ); // Q(-scale) log_energy_Q7 = SKP_Silk_lin2log( nrg ); if( k > 0 ) { energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 ); } log_energy_prev_Q7 = log_energy_Q7; pitch_res_ptr += nSamples; } psEncCtrl->sparseness_Q8 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 - SKP_FIX_CONST( 5.0, 7 ), SKP_FIX_CONST( 0.1, 16 ) ) ), 7 ); /* Set quantization offset depending on sparseness measure */ if( psEncCtrl->sparseness_Q8 > SKP_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { psEncCtrl->sCmn.QuantOffsetType = 0; } else { psEncCtrl->sCmn.QuantOffsetType = 1; } /* Increase coding SNR for sparse signals */ SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SKP_FIX_CONST( 0.5, 8 ) ); } /*******************************/ /* Control bandwidth expansion */ /*******************************/ /* More BWE for signals with high prediction gain */ strength_Q16 = SKP_SMULWB( psEncCtrl->predGain_Q16, SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); BWExp1_Q16 = BWExp2_Q16 = SKP_DIV32_varQ( SKP_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), SKP_SMLAWW( SKP_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); delta_Q16 = SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), SKP_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); BWExp1_Q16 = SKP_SUB32( BWExp1_Q16, delta_Q16 ); BWExp2_Q16 = SKP_ADD32( BWExp2_Q16, delta_Q16 ); /* BWExp1 will be applied after BWExp2, so make it relative */ BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ warping_Q16 = SKP_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( 0.01, 18 ) ); } else { warping_Q16 = 0; } /********************************************/ /* Compute noise shaping AR coefs and gains */ /********************************************/ for( k = 0; k < NB_SUBFR; k++ ) { /* Apply window: sine slope followed by flat part followed by cosine slope */ SKP_int shift, slope_part, flat_part; flat_part = psEnc->sCmn.fs_kHz * 5; slope_part = SKP_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); SKP_Silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); shift = slope_part; SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_int16) ); shift += flat_part; SKP_Silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); /* Update pointer: next LPC analysis block */ x_ptr += psEnc->sCmn.subfr_length; if( psEnc->sCmn.warping_Q16 > 0 ) { /* Calculate warped auto correlation */ SKP_Silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); } else { /* Calculate regular auto correlation */ SKP_Silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); } /* Add white noise, as a fraction of energy */ auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ), SKP_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); /* Calculate the reflection coefficients using schur */ nrg = SKP_Silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); SKP_assert( nrg >= 0 ); /* Convert reflection coefficients to prediction coefficients */ SKP_Silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); Qnrg = -scale; // range: -12...30 SKP_assert( Qnrg >= -12 ); SKP_assert( Qnrg <= 30 ); /* Make sure that Qnrg is an even number */ if( Qnrg & 1 ) { Qnrg -= 1; nrg >>= 1; } tmp32 = SKP_Silk_SQRT_APPROX( nrg ); Qnrg >>= 1; // range: -6...15 psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg ); if( psEnc->sCmn.warping_Q16 > 0 ) { /* Adjust gain for warping */ gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); if( psEncCtrl->Gains_Q16[ k ] < 0 ) { psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX; } } /* Bandwidth expansion for synthesis filter shaping */ SKP_Silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); /* Compute noise shaping filter coefficients */ SKP_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( SKP_int32 ) ); /* Bandwidth expansion for analysis filter shaping */ SKP_assert( BWExp1_Q16 <= SKP_FIX_CONST( 1.0, 16 ) ); SKP_Silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); /* Ratio of prediction gains, in energy domain */ SKP_Silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder ); SKP_Silk_LPC_inverse_pred_gain_Q24( &nrg, AR1_Q24, psEnc->sCmn.shapingLPCOrder ); //psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg; pre_nrg_Q30 = SKP_LSHIFT32( SKP_SMULWB( pre_nrg_Q30, SKP_FIX_CONST( 0.7, 15 ) ), 1 ); psEncCtrl->GainsPre_Q14[ k ] = ( SKP_int ) SKP_FIX_CONST( 0.3, 14 ) + SKP_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); /* Convert to monic warped prediction coefficients and limit absolute values */ limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SKP_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); /* Convert from Q24 to Q13 and store in int16 */ for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); } } /*****************/ /* Gain tweaking */ /*****************/ /* Increase gains during low speech activity and put lower limit on gains */ gain_mult_Q16 = SKP_Silk_log2lin( -SKP_SMLAWB( -SKP_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SKP_FIX_CONST( 0.16, 16 ) ) ); gain_add_Q16 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( NOISE_FLOOR_dB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) ); tmp32 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( RELATIVE_MIN_GAIN_dB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) ); tmp32 = SKP_SMULWW( psEnc->avgGain_Q16, tmp32 ); gain_add_Q16 = SKP_ADD_SAT32( gain_add_Q16, tmp32 ); SKP_assert( gain_mult_Q16 >= 0 ); for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); if( psEncCtrl->Gains_Q16[ k ] < 0 ) { psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX; } } for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); psEnc->avgGain_Q16 = SKP_ADD_SAT32( psEnc->avgGain_Q16, SKP_SMULWB( psEncCtrl->Gains_Q16[ k ] - psEnc->avgGain_Q16, SKP_RSHIFT_ROUND( SKP_SMULBB( psEnc->speech_activity_Q8, SKP_FIX_CONST( GAIN_SMOOTHING_COEF, 10 ) ), 2 ) ) ); } /************************************************/ /* Decrease level during fricatives (de-essing) */ /************************************************/ gain_mult_Q16 = SKP_FIX_CONST( 1.0, 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); if( psEncCtrl->input_tilt_Q15 <= 0 && psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED ) { if( psEnc->sCmn.fs_kHz == 24 ) { SKP_int32 essStrength_Q15 = SKP_SMULWW( -psEncCtrl->input_tilt_Q15, SKP_SMULBB( psEnc->speech_activity_Q8, SKP_FIX_CONST( 1.0, 8 ) - psEncCtrl->sparseness_Q8 ) ); tmp32 = SKP_Silk_log2lin( SKP_FIX_CONST( 16.0, 7 ) - SKP_SMULWB( essStrength_Q15, SKP_SMULWB( SKP_FIX_CONST( DE_ESSER_COEF_SWB_dB, 7 ), SKP_FIX_CONST( 0.16, 17 ) ) ) ); gain_mult_Q16 = SKP_SMULWW( gain_mult_Q16, tmp32 ); } else if( psEnc->sCmn.fs_kHz == 16 ) { SKP_int32 essStrength_Q15 = SKP_SMULWW(-psEncCtrl->input_tilt_Q15, SKP_SMULBB( psEnc->speech_activity_Q8, SKP_FIX_CONST( 1.0, 8 ) - psEncCtrl->sparseness_Q8 )); tmp32 = SKP_Silk_log2lin( SKP_FIX_CONST( 16.0, 7 ) - SKP_SMULWB( essStrength_Q15, SKP_SMULWB( SKP_FIX_CONST( DE_ESSER_COEF_WB_dB, 7 ), SKP_FIX_CONST( 0.16, 17 ) ) ) ); gain_mult_Q16 = SKP_SMULWW( gain_mult_Q16, tmp32 ); } else { SKP_assert( psEnc->sCmn.fs_kHz == 12 || psEnc->sCmn.fs_kHz == 8 ); } } for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); } /************************************************/ /* Control low-frequency shaping and noise tilt */ /************************************************/ /* Less low frequency shaping for noisy inputs */ strength_Q16 = SKP_MUL( SKP_FIX_CONST( LOW_FREQ_SHAPING, 0 ), SKP_FIX_CONST( 1.0, 16 ) + SKP_SMULBB( SKP_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 1 ), psEncCtrl->input_quality_bands_Q15[ 0 ] - SKP_FIX_CONST( 1.0, 15 ) ) ); if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ SKP_int fs_kHz_inv = SKP_DIV32_16( SKP_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); for( k = 0; k < NB_SUBFR; k++ ) { b_Q14 = fs_kHz_inv + SKP_DIV32_16( SKP_FIX_CONST( 3.0, 14 ), psEncCtrl->sCmn.pitchL[ k ] ); /* Pack two coefficients in one int32 */ psEncCtrl->LF_shp_Q14[ k ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 ); psEncCtrl->LF_shp_Q14[ k ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) ); } SKP_assert( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SKP_FIX_CONST( 0.5, 24 ) ); // Guarantees that second argument to SMULWB() is within range of an SKP_int16 Tilt_Q16 = - SKP_FIX_CONST( HP_NOISE_COEF, 16 ) - SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_FIX_CONST( HP_NOISE_COEF, 16 ), SKP_SMULWB( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->speech_activity_Q8 ) ); } else { b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14 /* Pack two coefficients in one int32 */ psEncCtrl->LF_shp_Q14[ 0 ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, SKP_SMULWB( SKP_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); psEncCtrl->LF_shp_Q14[ 0 ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) ); for( k = 1; k < NB_SUBFR; k++ ) { psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; } Tilt_Q16 = -SKP_FIX_CONST( HP_NOISE_COEF, 16 ); } /****************************/ /* HARMONIC SHAPING CONTROL */ /****************************/ /* Control boosting of harmonic frequencies */ HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( SKP_FIX_CONST( 1.0, 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), psEnc->LTPCorr_Q15 ), SKP_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); /* More harmonic boost for noisy input signals */ HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16, SKP_FIX_CONST( 1.0, 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SKP_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); if( USE_HARM_SHAPING && psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /* More harmonic noise shaping for high bitrates or noisy input */ HarmShapeGain_Q16 = SKP_SMLAWB( SKP_FIX_CONST( HARMONIC_SHAPING, 16 ), SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULWB( SKP_FIX_CONST( 1.0, 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), psEncCtrl->input_quality_Q14 ), SKP_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); /* Less harmonic noise shaping for less periodic signals */ HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ), SKP_Silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); } else { HarmShapeGain_Q16 = 0; } /*************************/ /* Smooth over subframes */ /*************************/ for( k = 0; k < NB_SUBFR; k++ ) { psShapeSt->HarmBoost_smth_Q16 = SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psShapeSt->HarmShapeGain_smth_Q16 = SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psShapeSt->Tilt_smth_Q16 = SKP_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); psEncCtrl->HarmBoost_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); psEncCtrl->HarmShapeGain_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); psEncCtrl->Tilt_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); } } ================================================ FILE: app/jni/SKP_Silk_pitch_analysis_core.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /*********************************************************** * Pitch analyser function ********************************************************** */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_pitch_est_defines.h" #include "SKP_Silk_common_pitch_est_defines.h" #define SCRATCH_SIZE 22 /************************************************************/ /* Internally used functions */ /************************************************************/ void SKP_FIX_P_Ana_calc_corr_st3( SKP_int32 cross_corr_st3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX][PITCH_EST_NB_STAGE3_LAGS],/* (O) 3 DIM correlation array */ const SKP_int16 signal[], /* I vector to correlate */ SKP_int start_lag, /* I lag offset to search around */ SKP_int sf_length, /* I length of a 5 ms subframe */ SKP_int complexity /* I Complexity setting */ ); void SKP_FIX_P_Ana_calc_energy_st3( SKP_int32 energies_st3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX][PITCH_EST_NB_STAGE3_LAGS],/* (O) 3 DIM energy array */ const SKP_int16 signal[], /* I vector to calc energy in */ SKP_int start_lag, /* I lag offset to search around */ SKP_int sf_length, /* I length of one 5 ms subframe */ SKP_int complexity /* I Complexity setting */ ); SKP_int32 SKP_FIX_P_Ana_find_scaling( const SKP_int16 *signal, const SKP_int signal_length, const SKP_int sum_sqr_len ); /*************************************************************/ /* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ /*************************************************************/ SKP_int SKP_Silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ const SKP_int16 *signal, /* I Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */ SKP_int *pitch_out, /* O 4 pitch lag values */ SKP_int *lagIndex, /* O Lag Index */ SKP_int *contourIndex, /* O Pitch contour Index */ SKP_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ SKP_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const SKP_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ const SKP_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ const SKP_int Fs_kHz, /* I Sample frequency (kHz) */ const SKP_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const SKP_int forLJC /* I 1 if this function is called from LJC code, 0 otherwise. */ ) { SKP_int16 signal_8kHz[ PITCH_EST_MAX_FRAME_LENGTH_ST_2 ]; SKP_int16 signal_4kHz[ PITCH_EST_MAX_FRAME_LENGTH_ST_1 ]; SKP_int32 scratch_mem[ 3 * PITCH_EST_MAX_FRAME_LENGTH ]; SKP_int16 *input_signal_ptr; SKP_int32 filt_state[ PITCH_EST_MAX_DECIMATE_STATE_LENGTH ]; SKP_int i, k, d, j; SKP_int16 C[ PITCH_EST_NB_SUBFR ][ ( PITCH_EST_MAX_LAG >> 1 ) + 5 ]; const SKP_int16 *target_ptr, *basis_ptr; SKP_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target; SKP_int d_srch[ PITCH_EST_D_SRCH_LENGTH ]; SKP_int16 d_comp[ ( PITCH_EST_MAX_LAG >> 1 ) + 5 ]; SKP_int Cmax, length_d_srch, length_d_comp; SKP_int32 sum, threshold, temp32; SKP_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; SKP_int32 CC[ PITCH_EST_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; SKP_int32 energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ]; SKP_int32 crosscorr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ]; SKP_int32 lag_counter; SKP_int frame_length, frame_length_8kHz, frame_length_4kHz, max_sum_sq_length; SKP_int sf_length, sf_length_8kHz; SKP_int min_lag, min_lag_8kHz, min_lag_4kHz; SKP_int max_lag, max_lag_8kHz, max_lag_4kHz; SKP_int32 contour_bias, diff; SKP_int32 lz, lshift; SKP_int cbk_offset, cbk_size, nb_cbks_stage2; SKP_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q15, corr_thres_Q15; /* Check for valid sampling frequency */ SKP_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 || Fs_kHz == 24 ); /* Check for valid complexity setting */ SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX ); SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX ); SKP_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); SKP_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) ); /* Setup frame lengths max / min lag for the sampling frequency */ frame_length = PITCH_EST_FRAME_LENGTH_MS * Fs_kHz; frame_length_4kHz = PITCH_EST_FRAME_LENGTH_MS * 4; frame_length_8kHz = PITCH_EST_FRAME_LENGTH_MS * 8; sf_length = SKP_RSHIFT( frame_length, 3 ); sf_length_8kHz = SKP_RSHIFT( frame_length_8kHz, 3 ); min_lag = PITCH_EST_MIN_LAG_MS * Fs_kHz; min_lag_4kHz = PITCH_EST_MIN_LAG_MS * 4; min_lag_8kHz = PITCH_EST_MIN_LAG_MS * 8; max_lag = PITCH_EST_MAX_LAG_MS * Fs_kHz; max_lag_4kHz = PITCH_EST_MAX_LAG_MS * 4; max_lag_8kHz = PITCH_EST_MAX_LAG_MS * 8; SKP_memset( C, 0, sizeof( SKP_int16 ) * PITCH_EST_NB_SUBFR * ( ( PITCH_EST_MAX_LAG >> 1 ) + 5) ); /* Resample from input sampled at Fs_kHz to 8 kHz */ if( Fs_kHz == 16 ) { SKP_memset( filt_state, 0, 2 * sizeof( SKP_int32 ) ); SKP_Silk_resampler_down2( filt_state, signal_8kHz, signal, frame_length ); } else if ( Fs_kHz == 12 ) { SKP_int32 R23[ 6 ]; SKP_memset( R23, 0, 6 * sizeof( SKP_int32 ) ); SKP_Silk_resampler_down2_3( R23, signal_8kHz, signal, PITCH_EST_FRAME_LENGTH_MS * 12 ); } else if( Fs_kHz == 24 ) { SKP_int32 filt_state_fix[ 8 ]; SKP_memset( filt_state_fix, 0, 8 * sizeof(SKP_int32) ); SKP_Silk_resampler_down3( filt_state_fix, signal_8kHz, signal, 24 * PITCH_EST_FRAME_LENGTH_MS ); } else { SKP_assert( Fs_kHz == 8 ); SKP_memcpy( signal_8kHz, signal, frame_length_8kHz * sizeof(SKP_int16) ); } /* Decimate again to 4 kHz */ SKP_memset( filt_state, 0, 2 * sizeof( SKP_int32 ) );/* Set state to zero */ SKP_Silk_resampler_down2( filt_state, signal_4kHz, signal_8kHz, frame_length_8kHz ); /* Low-pass filter */ for( i = frame_length_4kHz - 1; i > 0; i-- ) { signal_4kHz[ i ] = SKP_ADD_SAT16( signal_4kHz[ i ], signal_4kHz[ i - 1 ] ); } /******************************************************************************* ** Scale 4 kHz signal down to prevent correlations measures from overflowing ** find scaling as max scaling for each 8kHz(?) subframe *******************************************************************************/ /* Inner product is calculated with different lengths, so scale for the worst case */ max_sum_sq_length = SKP_max_32( sf_length_8kHz, SKP_RSHIFT( frame_length_4kHz, 1 ) ); shift = SKP_FIX_P_Ana_find_scaling( signal_4kHz, frame_length_4kHz, max_sum_sq_length ); if( shift > 0 ) { for( i = 0; i < frame_length_4kHz; i++ ) { signal_4kHz[ i ] = SKP_RSHIFT( signal_4kHz[ i ], shift ); } } /****************************************************************************** * FIRST STAGE, operating in 4 khz ******************************************************************************/ target_ptr = &signal_4kHz[ SKP_RSHIFT( frame_length_4kHz, 1 ) ]; for( k = 0; k < 2; k++ ) { /* Check that we are within range of the array */ SKP_assert( target_ptr >= signal_4kHz ); SKP_assert( target_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz ); basis_ptr = target_ptr - min_lag_4kHz; /* Check that we are within range of the array */ SKP_assert( basis_ptr >= signal_4kHz ); SKP_assert( basis_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz ); normalizer = 0; cross_corr = 0; /* Calculate first vector products before loop */ cross_corr = SKP_Silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); normalizer = SKP_Silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz ); normalizer = SKP_ADD_SAT32( normalizer, SKP_SMULBB( sf_length_8kHz, 4000 ) ); temp32 = SKP_DIV32( cross_corr, SKP_Silk_SQRT_APPROX( normalizer ) + 1 ); C[ k ][ min_lag_4kHz ] = (SKP_int16)SKP_SAT16( temp32 ); /* Q0 */ /* From now on normalizer is computed recursively */ for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { basis_ptr--; /* Check that we are within range of the array */ SKP_assert( basis_ptr >= signal_4kHz ); SKP_assert( basis_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz ); cross_corr = SKP_Silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); /* Add contribution of new sample and remove contribution from oldest sample */ normalizer += SKP_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - SKP_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] ); temp32 = SKP_DIV32( cross_corr, SKP_Silk_SQRT_APPROX( normalizer ) + 1 ); C[ k ][ d ] = (SKP_int16)SKP_SAT16( temp32 ); /* Q0 */ } /* Update target pointer */ target_ptr += sf_length_8kHz; } /* Combine two subframes into single correlation measure and apply short-lag bias */ for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { sum = (SKP_int32)C[ 0 ][ i ] + (SKP_int32)C[ 1 ][ i ]; /* Q0 */ SKP_assert( SKP_RSHIFT( sum, 1 ) == SKP_SAT16( SKP_RSHIFT( sum, 1 ) ) ); sum = SKP_RSHIFT( sum, 1 ); /* Q-1 */ SKP_assert( SKP_LSHIFT( (SKP_int32)-i, 4 ) == SKP_SAT16( SKP_LSHIFT( (SKP_int32)-i, 4 ) ) ); sum = SKP_SMLAWB( sum, sum, SKP_LSHIFT( -i, 4 ) ); /* Q-1 */ SKP_assert( sum == SKP_SAT16( sum ) ); C[ 0 ][ i ] = (SKP_int16)sum; /* Q-1 */ } /* Sort */ length_d_srch = 4 + 2 * complexity; SKP_assert( 3 * length_d_srch <= PITCH_EST_D_SRCH_LENGTH ); SKP_Silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); /* Escape if correlation is very low already here */ target_ptr = &signal_4kHz[ SKP_RSHIFT( frame_length_4kHz, 1 ) ]; energy = SKP_Silk_inner_prod_aligned( target_ptr, target_ptr, SKP_RSHIFT( frame_length_4kHz, 1 ) ); energy = SKP_ADD_POS_SAT32( energy, 1000 ); /* Q0 */ Cmax = (SKP_int)C[ 0 ][ min_lag_4kHz ]; /* Q-1 */ threshold = SKP_SMULBB( Cmax, Cmax ); /* Q-2 */ /* Compare in Q-2 domain */ if( SKP_RSHIFT( energy, 4 + 2 ) > threshold ) { SKP_memset( pitch_out, 0, PITCH_EST_NB_SUBFR * sizeof( SKP_int ) ); *LTPCorr_Q15 = 0; *lagIndex = 0; *contourIndex = 0; return 1; } threshold = SKP_SMULWB( search_thres1_Q16, Cmax ); for( i = 0; i < length_d_srch; i++ ) { /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { d_srch[ i ] = ( d_srch[ i ] + min_lag_4kHz ) << 1; } else { length_d_srch = i; break; } } SKP_assert( length_d_srch > 0 ); for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { d_comp[ i ] = 0; } for( i = 0; i < length_d_srch; i++ ) { d_comp[ d_srch[ i ] ] = 1; } /* Convolution */ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; } length_d_srch = 0; for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { if( d_comp[ i + 1 ] > 0 ) { d_srch[ length_d_srch ] = i; length_d_srch++; } } /* Convolution */ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; } length_d_comp = 0; for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { if( d_comp[ i ] > 0 ) { d_comp[ length_d_comp ] = i - 2; length_d_comp++; } } /********************************************************************************** ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation *************************************************************************************/ /****************************************************************************** ** Scale signal down to avoid correlations measures from overflowing *******************************************************************************/ /* find scaling as max scaling for each subframe */ shift = SKP_FIX_P_Ana_find_scaling( signal_8kHz, frame_length_8kHz, sf_length_8kHz ); if( shift > 0 ) { for( i = 0; i < frame_length_8kHz; i++ ) { signal_8kHz[ i ] = SKP_RSHIFT( signal_8kHz[ i ], shift ); } } /********************************************************************************* * Find energy of each subframe projected onto its history, for a range of delays *********************************************************************************/ SKP_memset( C, 0, PITCH_EST_NB_SUBFR * ( ( PITCH_EST_MAX_LAG >> 1 ) + 5 ) * sizeof( SKP_int16 ) ); target_ptr = &signal_8kHz[ frame_length_4kHz ]; /* point to middle of frame */ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { /* Check that we are within range of the array */ SKP_assert( target_ptr >= signal_8kHz ); SKP_assert( target_ptr + sf_length_8kHz <= signal_8kHz + frame_length_8kHz ); energy_target = SKP_Silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz ); // ToDo: Calculate 1 / energy_target here and save one division inside next for loop for( j = 0; j < length_d_comp; j++ ) { d = d_comp[ j ]; basis_ptr = target_ptr - d; /* Check that we are within range of the array */ SKP_assert( basis_ptr >= signal_8kHz ); SKP_assert( basis_ptr + sf_length_8kHz <= signal_8kHz + frame_length_8kHz ); cross_corr = SKP_Silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); energy_basis = SKP_Silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz ); if( cross_corr > 0 ) { energy = SKP_max( energy_target, energy_basis ); /* Find max to make sure first division < 1.0 */ lz = SKP_Silk_CLZ32( cross_corr ); lshift = SKP_LIMIT_32( lz - 1, 0, 15 ); temp32 = SKP_DIV32( SKP_LSHIFT( cross_corr, lshift ), SKP_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15 */ SKP_assert( temp32 == SKP_SAT16( temp32 ) ); temp32 = SKP_SMULWB( cross_corr, temp32 ); /* Q(-1), cc * ( cc / max(b, t) ) */ temp32 = SKP_ADD_SAT32( temp32, temp32 ); /* Q(0) */ lz = SKP_Silk_CLZ32( temp32 ); lshift = SKP_LIMIT_32( lz - 1, 0, 15 ); energy = SKP_min( energy_target, energy_basis ); C[ k ][ d ] = SKP_DIV32( SKP_LSHIFT( temp32, lshift ), SKP_RSHIFT( energy, 15 - lshift ) + 1 ); // Q15 } else { C[ k ][ d ] = 0; } } target_ptr += sf_length_8kHz; } /* search over lag range and lags codebook */ /* scale factor for lag codebook, as a function of center lag */ CCmax = SKP_int32_MIN; CCmax_b = SKP_int32_MIN; CBimax = 0; /* To avoid returning undefined lag values */ lag = -1; /* To check if lag with strong enough correlation has been found */ if( prevLag > 0 ) { if( Fs_kHz == 12 ) { prevLag = SKP_DIV32_16( SKP_LSHIFT( prevLag, 1 ), 3 ); } else if( Fs_kHz == 16 ) { prevLag = SKP_RSHIFT( prevLag, 1 ); } else if( Fs_kHz == 24 ) { prevLag = SKP_DIV32_16( prevLag, 3 ); } prevLag_log2_Q7 = SKP_Silk_lin2log( (SKP_int32)prevLag ); } else { prevLag_log2_Q7 = 0; } SKP_assert( search_thres2_Q15 == SKP_SAT16( search_thres2_Q15 ) ); corr_thres_Q15 = SKP_RSHIFT( SKP_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 13 ); /* If input is 8 khz use a larger codebook here because it is last stage */ if( Fs_kHz == 8 && complexity > SKP_Silk_PITCH_EST_MIN_COMPLEX ) { nb_cbks_stage2 = PITCH_EST_NB_CBKS_STAGE2_EXT; } else { nb_cbks_stage2 = PITCH_EST_NB_CBKS_STAGE2; } for( k = 0; k < length_d_srch; k++ ) { d = d_srch[ k ]; for( j = 0; j < nb_cbks_stage2; j++ ) { CC[ j ] = 0; for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) { /* Try all codebooks */ CC[ j ] = CC[ j ] + (SKP_int32)C[ i ][ d + SKP_Silk_CB_lags_stage2[ i ][ j ] ]; } } /* Find best codebook */ CCmax_new = SKP_int32_MIN; CBimax_new = 0; for( i = 0; i < nb_cbks_stage2; i++ ) { if( CC[ i ] > CCmax_new ) { CCmax_new = CC[ i ]; CBimax_new = i; } } /* Bias towards shorter lags */ lag_log2_Q7 = SKP_Silk_lin2log( (SKP_int32)d ); /* Q7 */ SKP_assert( lag_log2_Q7 == SKP_SAT16( lag_log2_Q7 ) ); SKP_assert( PITCH_EST_NB_SUBFR * PITCH_EST_SHORTLAG_BIAS_Q15 == SKP_SAT16( PITCH_EST_NB_SUBFR * PITCH_EST_SHORTLAG_BIAS_Q15 ) ); if (forLJC) { CCmax_new_b = CCmax_new; } else { CCmax_new_b = CCmax_new - SKP_RSHIFT( SKP_SMULBB( PITCH_EST_NB_SUBFR * PITCH_EST_SHORTLAG_BIAS_Q15, lag_log2_Q7 ), 7 ); /* Q15 */ } /* Bias towards previous lag */ SKP_assert( PITCH_EST_NB_SUBFR * PITCH_EST_PREVLAG_BIAS_Q15 == SKP_SAT16( PITCH_EST_NB_SUBFR * PITCH_EST_PREVLAG_BIAS_Q15 ) ); if( prevLag > 0 ) { delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; SKP_assert( delta_lag_log2_sqr_Q7 == SKP_SAT16( delta_lag_log2_sqr_Q7 ) ); delta_lag_log2_sqr_Q7 = SKP_RSHIFT( SKP_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); prev_lag_bias_Q15 = SKP_RSHIFT( SKP_SMULBB( PITCH_EST_NB_SUBFR * PITCH_EST_PREVLAG_BIAS_Q15, ( *LTPCorr_Q15 ) ), 15 ); /* Q15 */ prev_lag_bias_Q15 = SKP_DIV32( SKP_MUL( prev_lag_bias_Q15, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + ( 1 << 6 ) ); CCmax_new_b -= prev_lag_bias_Q15; /* Q15 */ } if ( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ CCmax_new > corr_thres_Q15 && /* Correlation needs to be high enough to be voiced */ SKP_Silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */ ) { CCmax_b = CCmax_new_b; CCmax = CCmax_new; lag = d; CBimax = CBimax_new; } } if( lag == -1 ) { /* No suitable candidate found */ SKP_memset( pitch_out, 0, PITCH_EST_NB_SUBFR * sizeof( SKP_int ) ); *LTPCorr_Q15 = 0; *lagIndex = 0; *contourIndex = 0; return 1; } if( Fs_kHz > 8 ) { /****************************************************************************** ** Scale input signal down to avoid correlations measures from overflowing *******************************************************************************/ /* find scaling as max scaling for each subframe */ shift = SKP_FIX_P_Ana_find_scaling( signal, frame_length, sf_length ); if( shift > 0 ) { /* Move signal to scratch mem because the input signal should be unchanged */ /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */ input_signal_ptr = (SKP_int16*)scratch_mem; for( i = 0; i < frame_length; i++ ) { input_signal_ptr[ i ] = SKP_RSHIFT( signal[ i ], shift ); } } else { input_signal_ptr = (SKP_int16*)signal; } /*********************************************************************************/ /* Search in original signal */ CBimax_old = CBimax; /* Compensate for decimation */ SKP_assert( lag == SKP_SAT16( lag ) ); if( Fs_kHz == 12 ) { lag = SKP_RSHIFT( SKP_SMULBB( lag, 3 ), 1 ); } else if( Fs_kHz == 16 ) { lag = SKP_LSHIFT( lag, 1 ); } else { lag = SKP_SMULBB( lag, 3 ); } lag = SKP_LIMIT_int( lag, min_lag, max_lag ); start_lag = SKP_max_int( lag - 2, min_lag ); end_lag = SKP_min_int( lag + 2, max_lag ); lag_new = lag; /* to avoid undefined lag */ CBimax = 0; /* to avoid undefined lag */ SKP_assert( SKP_LSHIFT( CCmax, 13 ) >= 0 ); *LTPCorr_Q15 = (SKP_int)SKP_Silk_SQRT_APPROX( SKP_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */ CCmax = SKP_int32_MIN; /* pitch lags according to second stage */ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { pitch_out[ k ] = lag + 2 * SKP_Silk_CB_lags_stage2[ k ][ CBimax_old ]; } /* Calculate the correlations and energies needed in stage 3 */ SKP_FIX_P_Ana_calc_corr_st3( crosscorr_st3, input_signal_ptr, start_lag, sf_length, complexity ); SKP_FIX_P_Ana_calc_energy_st3( energies_st3, input_signal_ptr, start_lag, sf_length, complexity ); lag_counter = 0; SKP_assert( lag == SKP_SAT16( lag ) ); contour_bias = SKP_DIV32_16( PITCH_EST_FLATCONTOUR_BIAS_Q20, lag ); /* Setup cbk parameters acording to complexity setting */ cbk_size = (SKP_int)SKP_Silk_cbk_sizes_stage3[ complexity ]; cbk_offset = (SKP_int)SKP_Silk_cbk_offsets_stage3[ complexity ]; for( d = start_lag; d <= end_lag; d++ ) { for( j = cbk_offset; j < ( cbk_offset + cbk_size ); j++ ) { cross_corr = 0; energy = 0; for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { SKP_assert( PITCH_EST_NB_SUBFR == 4 ); energy += SKP_RSHIFT( energies_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */ SKP_assert( energy >= 0 ); cross_corr += SKP_RSHIFT( crosscorr_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */ } if( cross_corr > 0 ) { /* Divide cross_corr / energy and get result in Q15 */ lz = SKP_Silk_CLZ32( cross_corr ); /* Divide with result in Q13, cross_corr could be larger than energy */ lshift = SKP_LIMIT_32( lz - 1, 0, 13 ); CCmax_new = SKP_DIV32( SKP_LSHIFT( cross_corr, lshift ), SKP_RSHIFT( energy, 13 - lshift ) + 1 ); CCmax_new = SKP_SAT16( CCmax_new ); CCmax_new = SKP_SMULWB( cross_corr, CCmax_new ); /* Saturate */ if( CCmax_new > SKP_RSHIFT( SKP_int32_MAX, 3 ) ) { CCmax_new = SKP_int32_MAX; } else { CCmax_new = SKP_LSHIFT( CCmax_new, 3 ); } /* Reduce depending on flatness of contour */ diff = j - SKP_RSHIFT( PITCH_EST_NB_CBKS_STAGE3_MAX, 1 ); diff = SKP_MUL( diff, diff ); diff = SKP_int16_MAX - SKP_RSHIFT( SKP_MUL( contour_bias, diff ), 5 ); /* Q20 -> Q15 */ SKP_assert( diff == SKP_SAT16( diff ) ); CCmax_new = SKP_LSHIFT( SKP_SMULWB( CCmax_new, diff ), 1 ); } else { CCmax_new = 0; } if( CCmax_new > CCmax && ( d + (SKP_int)SKP_Silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { CCmax = CCmax_new; lag_new = d; CBimax = j; } } lag_counter++; } for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { pitch_out[ k ] = lag_new + SKP_Silk_CB_lags_stage3[ k ][ CBimax ]; } *lagIndex = lag_new - min_lag; *contourIndex = CBimax; } else { /* Save Lags and correlation */ CCmax = SKP_max( CCmax, 0 ); *LTPCorr_Q15 = (SKP_int)SKP_Silk_SQRT_APPROX( SKP_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { pitch_out[ k ] = lag + SKP_Silk_CB_lags_stage2[ k ][ CBimax ]; } *lagIndex = lag - min_lag_8kHz; *contourIndex = CBimax; } SKP_assert( *lagIndex >= 0 ); /* return as voiced */ return 0; } /*************************************************************************/ /* Calculates the correlations used in stage 3 search. In order to cover */ /* the whole lag codebook for all the searched offset lags (lag +- 2), */ /*************************************************************************/ void SKP_FIX_P_Ana_calc_corr_st3( SKP_int32 cross_corr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */ const SKP_int16 signal[], /* I vector to correlate */ SKP_int start_lag, /* I lag offset to search around */ SKP_int sf_length, /* I length of a 5 ms subframe */ SKP_int complexity /* I Complexity setting */ ) { const SKP_int16 *target_ptr, *basis_ptr; SKP_int32 cross_corr; SKP_int i, j, k, lag_counter; SKP_int cbk_offset, cbk_size, delta, idx; SKP_int32 scratch_mem[ SCRATCH_SIZE ]; SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX ); SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX ); cbk_offset = SKP_Silk_cbk_offsets_stage3[ complexity ]; cbk_size = SKP_Silk_cbk_sizes_stage3[ complexity ]; target_ptr = &signal[ SKP_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { lag_counter = 0; /* Calculate the correlations for each subframe */ for( j = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; j <= SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ]; j++ ) { basis_ptr = target_ptr - ( start_lag + j ); cross_corr = SKP_Silk_inner_prod_aligned( (SKP_int16*)target_ptr, (SKP_int16*)basis_ptr, sf_length ); SKP_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[ lag_counter ] = cross_corr; lag_counter++; } delta = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) { /* Fill out the 3 dim array that stores the correlations for */ /* each code_book vector for each start lag */ idx = SKP_Silk_CB_lags_stage3[ k ][ i ] - delta; for( j = 0; j < PITCH_EST_NB_STAGE3_LAGS; j++ ) { SKP_assert( idx + j < SCRATCH_SIZE ); SKP_assert( idx + j < lag_counter ); cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; } } target_ptr += sf_length; } } /********************************************************************/ /* Calculate the energies for first two subframes. The energies are */ /* calculated recursively. */ /********************************************************************/ void SKP_FIX_P_Ana_calc_energy_st3( SKP_int32 energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */ const SKP_int16 signal[], /* I vector to calc energy in */ SKP_int start_lag, /* I lag offset to search around */ SKP_int sf_length, /* I length of one 5 ms subframe */ SKP_int complexity /* I Complexity setting */ ) { const SKP_int16 *target_ptr, *basis_ptr; SKP_int32 energy; SKP_int k, i, j, lag_counter; SKP_int cbk_offset, cbk_size, delta, idx; SKP_int32 scratch_mem[ SCRATCH_SIZE ]; SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX ); SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX ); cbk_offset = SKP_Silk_cbk_offsets_stage3[ complexity ]; cbk_size = SKP_Silk_cbk_sizes_stage3[ complexity ]; target_ptr = &signal[ SKP_LSHIFT( sf_length, 2 ) ]; for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) { lag_counter = 0; /* Calculate the energy for first lag */ basis_ptr = target_ptr - ( start_lag + SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] ); energy = SKP_Silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length ); SKP_assert( energy >= 0 ); scratch_mem[ lag_counter ] = energy; lag_counter++; for( i = 1; i < ( SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ] - SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] + 1 ); i++ ) { /* remove part outside new window */ energy -= SKP_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] ); SKP_assert( energy >= 0 ); /* add part that comes into window */ energy = SKP_ADD_SAT32( energy, SKP_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) ); SKP_assert( energy >= 0 ); SKP_assert( lag_counter < SCRATCH_SIZE ); scratch_mem[ lag_counter ] = energy; lag_counter++; } delta = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) { /* Fill out the 3 dim array that stores the correlations for */ /* each code_book vector for each start lag */ idx = SKP_Silk_CB_lags_stage3[ k ][ i ] - delta; for( j = 0; j < PITCH_EST_NB_STAGE3_LAGS; j++ ) { SKP_assert( idx + j < SCRATCH_SIZE ); SKP_assert( idx + j < lag_counter ); energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; SKP_assert( energies_st3[ k ][ i ][ j ] >= 0.0f ); } } target_ptr += sf_length; } } SKP_int32 SKP_FIX_P_Ana_find_scaling( const SKP_int16 *signal, const SKP_int signal_length, const SKP_int sum_sqr_len ) { SKP_int32 nbits, x_max; x_max = SKP_Silk_int16_array_maxabs( signal, signal_length ); if( x_max < SKP_int16_MAX ) { /* Number of bits needed for the sum of the squares */ nbits = 32 - SKP_Silk_CLZ32( SKP_SMULBB( x_max, x_max ) ); } else { /* Here we don't know if x_max should have been SKP_int16_MAX + 1, so we expect the worst case */ nbits = 30; } nbits += 17 - SKP_Silk_CLZ16( sum_sqr_len ); /* Without a guarantee of saturation, we need to keep the 31st bit free */ if( nbits < 31 ) { return 0; } else { return( nbits - 30 ); } } ================================================ FILE: app/jni/SKP_Silk_pitch_est_tables.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_typedef.h" #include "SKP_Silk_common_pitch_est_defines.h" /********************************************************/ /* Auto Generated File from generate_pitch_est_tables.m */ /********************************************************/ const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT] = { {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1}, {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1} }; const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX] = { {-9,-7,-6,-5,-5,-4,-4,-3,-3,-2,-2,-2,-1,-1,-1, 0, 0, 0, 1, 1, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 5, 6, 8}, {-3,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2, 2, 2, 3}, { 3, 3, 2, 2, 2, 2, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,-1, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2}, { 9, 8, 6, 5, 6, 5, 4, 4, 3, 3, 2, 2, 2, 1, 0, 1, 1, 0, 0, 0,-1,-1,-1,-2,-2,-2,-3,-3,-4,-4,-5,-5,-6,-7} }; const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ] = { /* Lags to search for low number of stage3 cbks */ { {-2,6}, {-1,5}, {-1,5}, {-2,7} }, /* Lags to search for middle number of stage3 cbks */ { {-4,8}, {-1,6}, {-1,6}, {-4,9} }, /* Lags to search for max number of stage3 cbks */ { {-9,12}, {-3,7}, {-2,7}, {-7,13} } }; const SKP_int16 SKP_Silk_cbk_sizes_stage3[SKP_Silk_PITCH_EST_MAX_COMPLEX + 1] = { PITCH_EST_NB_CBKS_STAGE3_MIN, PITCH_EST_NB_CBKS_STAGE3_MID, PITCH_EST_NB_CBKS_STAGE3_MAX }; const SKP_int16 SKP_Silk_cbk_offsets_stage3[SKP_Silk_PITCH_EST_MAX_COMPLEX + 1] = { ((PITCH_EST_NB_CBKS_STAGE3_MAX - PITCH_EST_NB_CBKS_STAGE3_MIN) >> 1), ((PITCH_EST_NB_CBKS_STAGE3_MAX - PITCH_EST_NB_CBKS_STAGE3_MID) >> 1), 0 }; ================================================ FILE: app/jni/SKP_Silk_prefilter_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */ SKP_INLINE void SKP_Silk_prefilt_FIX( SKP_Silk_prefilter_state_FIX *P, /* I/O state */ SKP_int32 st_res_Q12[], /* I short term residual signal */ SKP_int16 xw[], /* O prefiltered signal */ SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ SKP_int Tilt_Q14, /* I Tilt shaping coeficient */ SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/ SKP_int lag, /* I Lag for harmonic shaping */ SKP_int length /* I Length of signals */ ); #if EMBEDDED_ARM<6 void SKP_Silk_warped_LPC_analysis_filter_FIX( SKP_int32 state[], /* I/O State [order + 1] */ SKP_int16 res[], /* O Residual signal [length] */ const SKP_int16 coef_Q13[], /* I Coefficients [order] */ const SKP_int16 input[], /* I Input signal [length] */ const SKP_int16 lambda_Q16, /* I Warping factor */ const SKP_int length, /* I Length of input signal */ const SKP_int order /* I Filter order (even) */ ) { SKP_int n, i; SKP_int32 acc_Q11, tmp1, tmp2; /* Order must be even */ SKP_assert( ( order & 1 ) == 0 ); for( n = 0; n < length; n++ ) { /* Output of lowpass section */ tmp2 = SKP_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); state[ 0 ] = SKP_LSHIFT( input[ n ], 14 ); /* Output of allpass section */ tmp1 = SKP_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); state[ 1 ] = tmp2; acc_Q11 = SKP_SMULWB( tmp2, coef_Q13[ 0 ] ); /* Loop over allpass sections */ for( i = 2; i < order; i += 2 ) { /* Output of allpass section */ tmp2 = SKP_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); state[ i ] = tmp1; acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); /* Output of allpass section */ tmp1 = SKP_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); state[ i + 1 ] = tmp2; acc_Q11 = SKP_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); } state[ order ] = tmp1; acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); res[ n ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )input[ n ] - SKP_RSHIFT_ROUND( acc_Q11, 11 ) ); } } #endif void SKP_Silk_prefilter_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ const SKP_Silk_encoder_control_FIX *psEncCtrl, /* I Encoder control FIX */ SKP_int16 xw[], /* O Weighted signal */ const SKP_int16 x[] /* I Speech signal */ ) { SKP_Silk_prefilter_state_FIX *P = &psEnc->sPrefilt; SKP_int j, k, lag; SKP_int32 tmp_32; const SKP_int16 *AR1_shp_Q13; const SKP_int16 *px; SKP_int16 *pxw; SKP_int HarmShapeGain_Q12, Tilt_Q14; SKP_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14; SKP_int32 x_filt_Q12[ MAX_FRAME_LENGTH / NB_SUBFR ]; SKP_int16 st_res[ ( MAX_FRAME_LENGTH / NB_SUBFR ) + MAX_SHAPE_LPC_ORDER ]; #if !defined(_SYSTEM_IS_BIG_ENDIAN) SKP_int32 B_Q12; #else SKP_int16 B_Q12[ 2 ]; #endif /* Setup pointers */ px = x; pxw = xw; lag = P->lagPrev; for( k = 0; k < NB_SUBFR; k++ ) { /* Update Variables that change per sub frame */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { lag = psEncCtrl->sCmn.pitchL[ k ]; } /* Noise shape parameters */ HarmShapeGain_Q12 = SKP_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); SKP_assert( HarmShapeGain_Q12 >= 0 ); HarmShapeFIRPacked_Q12 = SKP_RSHIFT( HarmShapeGain_Q12, 2 ); HarmShapeFIRPacked_Q12 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q12, 1 ), 16 ); Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ]; LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ]; AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Short term FIR filtering*/ SKP_Silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px, psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); /* reduce (mainly) low frequencies during harmonic emphasis */ #if !defined(_SYSTEM_IS_BIG_ENDIAN) /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */ /* SMLABB and SMLABT instructions. On a big-endian CPU the two int16 variables would be */ /* loaded in reverse order and the code will give the wrong result. In that case swapping */ /* the SMLABB and SMLABT instructions should solve the problem. */ B_Q12 = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 ); tmp_32 = SKP_SMLABB( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */ tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */ tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */ B_Q12 |= SKP_LSHIFT( SKP_SAT16( tmp_32 ), 16 ); x_filt_Q12[ 0 ] = SKP_SMLABT( SKP_SMULBB( st_res[ 0 ], B_Q12 ), P->sHarmHP, B_Q12 ); for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { x_filt_Q12[ j ] = SKP_SMLABT( SKP_SMULBB( st_res[ j ], B_Q12 ), st_res[ j - 1 ], B_Q12 ); } #else B_Q12[ 0 ] = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 ); tmp_32 = SKP_SMLABB( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */ tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */ tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */ B_Q12[ 1 ]= SKP_SAT16( tmp_32 ); x_filt_Q12[ 0 ] = SKP_SMLABB( SKP_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] ); for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { x_filt_Q12[ j ] = SKP_SMLABB( SKP_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] ); } #endif P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; SKP_Silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length ); px += psEnc->sCmn.subfr_length; pxw += psEnc->sCmn.subfr_length; } P->lagPrev = psEncCtrl->sCmn.pitchL[ NB_SUBFR - 1 ]; } /* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */ SKP_INLINE void SKP_Silk_prefilt_FIX( SKP_Silk_prefilter_state_FIX *P, /* I/O state */ SKP_int32 st_res_Q12[], /* I short term residual signal */ SKP_int16 xw[], /* O prefiltered signal */ SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ SKP_int Tilt_Q14, /* I Tilt shaping coeficient */ SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/ SKP_int lag, /* I Lag for harmonic shaping */ SKP_int length /* I Length of signals */ ) { SKP_int i, idx, LTP_shp_buf_idx; SKP_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; SKP_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12; SKP_int16 *LTP_shp_buf; /* To speed up use temp variables instead of using the struct */ LTP_shp_buf = P->sLTP_shp; LTP_shp_buf_idx = P->sLTP_shp_buf_idx; sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12; sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12; for( i = 0; i < length; i++ ) { if( lag > 0 ) { /* unrolled loop */ SKP_assert( HARM_SHAPE_FIR_TAPS == 3 ); idx = lag + LTP_shp_buf_idx; n_LTP_Q12 = SKP_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); } else { n_LTP_Q12 = 0; } n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); n_LF_Q10 = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) ); sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12, SKP_LSHIFT( n_LF_Q10, 2 ) ); LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; LTP_shp_buf[ LTP_shp_buf_idx ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); xw[i] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) ); } /* Copy temp variable back to state */ P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12; P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12; P->sLTP_shp_buf_idx = LTP_shp_buf_idx; } ================================================ FILE: app/jni/SKP_Silk_process_NLSFs_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Limit, stabilize, convert and quantize NLSFs. */ void SKP_Silk_process_NLSFs_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ SKP_int *pNLSF_Q15 /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ ) { SKP_int doInterpolate; SKP_int pNLSFW_Q6[ MAX_LPC_ORDER ]; SKP_int NLSF_mu_Q15, NLSF_mu_fluc_red_Q16; SKP_int32 i_sqr_Q15; const SKP_Silk_NLSF_CB_struct *psNLSF_CB; /* Used only for NLSF interpolation */ SKP_int pNLSF0_temp_Q15[ MAX_LPC_ORDER ]; SKP_int pNLSFW0_temp_Q6[ MAX_LPC_ORDER ]; SKP_int i; SKP_assert( psEnc->speech_activity_Q8 >= 0 ); SKP_assert( psEnc->speech_activity_Q8 <= 256 ); SKP_assert( psEncCtrl->sparseness_Q8 >= 0 ); SKP_assert( psEncCtrl->sparseness_Q8 <= 256 ); SKP_assert( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED || psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED ); /***********************/ /* Calculate mu values */ /***********************/ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /* NLSF_mu = 0.002f - 0.001f * psEnc->speech_activity; */ /* NLSF_mu_fluc_red = 0.1f - 0.05f * psEnc->speech_activity; */ NLSF_mu_Q15 = SKP_SMLAWB( 66, -8388, psEnc->speech_activity_Q8 ); NLSF_mu_fluc_red_Q16 = SKP_SMLAWB( 6554, -838848, psEnc->speech_activity_Q8 ); } else { /* NLSF_mu = 0.005f - 0.004f * psEnc->speech_activity; */ /* NLSF_mu_fluc_red = 0.2f - 0.1f * psEnc->speech_activity - 0.1f * psEncCtrl->sparseness; */ NLSF_mu_Q15 = SKP_SMLAWB( 164, -33554, psEnc->speech_activity_Q8 ); NLSF_mu_fluc_red_Q16 = SKP_SMLAWB( 13107, -1677696, psEnc->speech_activity_Q8 + psEncCtrl->sparseness_Q8 ); } SKP_assert( NLSF_mu_Q15 >= 0 ); SKP_assert( NLSF_mu_Q15 <= 164 ); SKP_assert( NLSF_mu_fluc_red_Q16 >= 0 ); SKP_assert( NLSF_mu_fluc_red_Q16 <= 13107 ); NLSF_mu_Q15 = SKP_max( NLSF_mu_Q15, 1 ); /* Calculate NLSF weights */ TIC(NLSF_weights_FIX) SKP_Silk_NLSF_VQ_weights_laroia( pNLSFW_Q6, pNLSF_Q15, psEnc->sCmn.predictLPCOrder ); TOC(NLSF_weights_FIX) /* Update NLSF weights for interpolated NLSFs */ doInterpolate = ( psEnc->sCmn.useInterpolatedNLSFs == 1 ) && ( psEncCtrl->sCmn.NLSFInterpCoef_Q2 < ( 1 << 2 ) ); if( doInterpolate ) { /* Calculate the interpolated NLSF vector for the first half */ SKP_Silk_interpolate( pNLSF0_temp_Q15, psEnc->sPred.prev_NLSFq_Q15, pNLSF_Q15, psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sCmn.predictLPCOrder ); /* Calculate first half NLSF weights for the interpolated NLSFs */ TIC(NLSF_weights_FIX) SKP_Silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_Q6, pNLSF0_temp_Q15, psEnc->sCmn.predictLPCOrder ); TOC(NLSF_weights_FIX) /* Update NLSF weights with contribution from first half */ i_sqr_Q15 = SKP_LSHIFT( SKP_SMULBB( psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->sCmn.NLSFInterpCoef_Q2 ), 11 ); for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { pNLSFW_Q6[ i ] = SKP_SMLAWB( SKP_RSHIFT( pNLSFW_Q6[ i ], 1 ), pNLSFW0_temp_Q6[ i ], i_sqr_Q15 ); SKP_assert( pNLSFW_Q6[ i ] <= SKP_int16_MAX ); SKP_assert( pNLSFW_Q6[ i ] >= 1 ); } } /* Set pointer to the NLSF codebook for the current signal type and LPC order */ psNLSF_CB = psEnc->sCmn.psNLSF_CB[ psEncCtrl->sCmn.sigtype ]; /* Quantize NLSF parameters given the trained NLSF codebooks */ TIC(MSVQ_encode_FIX) SKP_Silk_NLSF_MSVQ_encode_FIX( psEncCtrl->sCmn.NLSFIndices, pNLSF_Q15, psNLSF_CB, psEnc->sPred.prev_NLSFq_Q15, pNLSFW_Q6, NLSF_mu_Q15, NLSF_mu_fluc_red_Q16, psEnc->sCmn.NLSF_MSVQ_Survivors, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.first_frame_after_reset ); TOC(MSVQ_encode_FIX) /* Convert quantized NLSFs back to LPC coefficients */ SKP_Silk_NLSF2A_stable( psEncCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psEnc->sCmn.predictLPCOrder ); if( doInterpolate ) { /* Calculate the interpolated, quantized LSF vector for the first half */ SKP_Silk_interpolate( pNLSF0_temp_Q15, psEnc->sPred.prev_NLSFq_Q15, pNLSF_Q15, psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sCmn.predictLPCOrder ); /* Convert back to LPC coefficients */ SKP_Silk_NLSF2A_stable( psEncCtrl->PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEnc->sCmn.predictLPCOrder ); } else { /* Copy LPC coefficients for first half from second half */ SKP_memcpy( psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->PredCoef_Q12[ 1 ], psEnc->sCmn.predictLPCOrder * sizeof( SKP_int16 ) ); } } ================================================ FILE: app/jni/SKP_Silk_process_gains_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /* Processing of gains */ void SKP_Silk_process_gains_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state_FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control_FIX */ ) { SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape; SKP_int k; SKP_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; /* Gain reduction when LTP coding gain is high */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ s_Q16 = -SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SKP_FIX_CONST( 12.0, 7 ), 4 ) ); for( k = 0; k < NB_SUBFR; k++ ) { psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); } } /* Limit the quantized signal */ InvMaxSqrVal_Q16 = SKP_DIV32_16( SKP_Silk_log2lin( SKP_SMULWB( SKP_FIX_CONST( 70.0, 7 ) - psEncCtrl->current_SNR_dB_Q7, SKP_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); for( k = 0; k < NB_SUBFR; k++ ) { /* Soft limit on ratio residual energy and squared gains */ ResNrg = psEncCtrl->ResNrg[ k ]; ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); if( psEncCtrl->ResNrgQ[ k ] > 0 ) { if( psEncCtrl->ResNrgQ[ k ] < 32 ) { ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); } else { ResNrgPart = 0; } } else if( psEncCtrl->ResNrgQ[k] != 0 ) { if( ResNrgPart > SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { ResNrgPart = SKP_int32_MAX; } else { ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); } } gain = psEncCtrl->Gains_Q16[ k ]; gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) ); if( gain_squared < SKP_int16_MAX ) { /* recalculate with higher precision */ gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain ); SKP_assert( gain_squared > 0 ); gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q8 */ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 ); /* Q16 */ } else { gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q0 */ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 ); /* Q16 */ } } /* Noise shaping quantization */ SKP_Silk_gains_quant( psEncCtrl->sCmn.GainsIndices, psEncCtrl->Gains_Q16, &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesInPayloadBuf ); /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) { if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEncCtrl->input_tilt_Q15, 8 ) > SKP_FIX_CONST( 1.0, 7 ) ) { psEncCtrl->sCmn.QuantOffsetType = 0; } else { psEncCtrl->sCmn.QuantOffsetType = 1; } } /* Quantizer boundary adjustment */ quant_offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrl->sCmn.sigtype ][ psEncCtrl->sCmn.QuantOffsetType ]; psEncCtrl->Lambda_Q10 = SKP_FIX_CONST( LAMBDA_OFFSET, 10 ) + SKP_SMULBB( SKP_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->speech_activity_Q8 ) + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); SKP_assert( psEncCtrl->Lambda_Q10 > 0 ); SKP_assert( psEncCtrl->Lambda_Q10 < SKP_FIX_CONST( 2, 10 ) ); } ================================================ FILE: app/jni/SKP_Silk_quant_LTP_gains_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" void SKP_Silk_quant_LTP_gains_FIX( SKP_int16 B_Q14[], /* I/O (un)quantized LTP gains */ SKP_int cbk_index[], /* O Codebook Index */ SKP_int *periodicity_index, /* O Periodicity Index */ const SKP_int32 W_Q18[], /* I Error Weights in Q18 */ SKP_int mu_Q8, /* I Mu value (R/D tradeoff) */ SKP_int lowComplexity /* I Flag for low complexity */ ) { SKP_int j, k, temp_idx[ NB_SUBFR ], cbk_size; const SKP_int16 *cl_ptr; const SKP_int16 *cbk_ptr_Q14; const SKP_int16 *b_Q14_ptr; const SKP_int32 *W_Q18_ptr; SKP_int32 rate_dist_subfr, rate_dist, min_rate_dist; /***************************************************/ /* iterate over different codebooks with different */ /* rates/distortions, and choose best */ /***************************************************/ min_rate_dist = SKP_int32_MAX; for( k = 0; k < 3; k++ ) { cl_ptr = SKP_Silk_LTP_gain_BITS_Q6_ptrs[ k ]; cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ k ]; cbk_size = SKP_Silk_LTP_vq_sizes[ k ]; /* Setup pointer to first subframe */ W_Q18_ptr = W_Q18; b_Q14_ptr = B_Q14; rate_dist = 0; for( j = 0; j < NB_SUBFR; j++ ) { SKP_Silk_VQ_WMat_EC_FIX( &temp_idx[ j ], /* O index of best codebook vector */ &rate_dist_subfr, /* O best weighted quantization error + mu * rate */ b_Q14_ptr, /* I input vector to be quantized */ W_Q18_ptr, /* I weighting matrix */ cbk_ptr_Q14, /* I codebook */ cl_ptr, /* I code length for each codebook vector */ mu_Q8, /* I tradeoff between weighted error and rate */ cbk_size /* I number of vectors in codebook */ ); rate_dist = SKP_ADD_POS_SAT32( rate_dist, rate_dist_subfr ); b_Q14_ptr += LTP_ORDER; W_Q18_ptr += LTP_ORDER * LTP_ORDER; } /* Avoid never finding a codebook */ rate_dist = SKP_min( SKP_int32_MAX - 1, rate_dist ); if( rate_dist < min_rate_dist ) { min_rate_dist = rate_dist; SKP_memcpy( cbk_index, temp_idx, NB_SUBFR * sizeof( SKP_int ) ); *periodicity_index = k; } /* Break early in low-complexity mode if rate distortion is below threshold */ if( lowComplexity && ( rate_dist < SKP_Silk_LTP_gain_middle_avg_RD_Q14 ) ) { break; } } cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ *periodicity_index ]; for( j = 0; j < NB_SUBFR; j++ ) { for( k = 0; k < LTP_ORDER; k++ ) { B_Q14[ j * LTP_ORDER + k ] = cbk_ptr_Q14[ SKP_MLA( k, cbk_index[ j ], LTP_ORDER ) ]; } } } ================================================ FILE: app/jni/SKP_Silk_range_coder.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* Range encoder for one symbol */ void SKP_Silk_range_encoder( SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_int data, /* I uncompressed data */ const SKP_uint16 prob[] /* I cumulative density functions */ ) { SKP_uint32 low_Q16, high_Q16; SKP_uint32 base_tmp, range_Q32; /* Copy structure data */ SKP_uint32 base_Q32 = psRC->base_Q32; SKP_uint32 range_Q16 = psRC->range_Q16; SKP_int32 bufferIx = psRC->bufferIx; SKP_uint8 *buffer = psRC->buffer; if( psRC->error ) { return; } /* Update interval */ low_Q16 = prob[ data ]; high_Q16 = prob[ data + 1 ]; base_tmp = base_Q32; /* save current base, to test for carry */ base_Q32 += SKP_MUL_uint( range_Q16, low_Q16 ); range_Q32 = SKP_MUL_uint( range_Q16, high_Q16 - low_Q16 ); /* Check for carry */ if( base_Q32 < base_tmp ) { /* Propagate carry in buffer */ SKP_int bufferIx_tmp = bufferIx; while( ( ++buffer[ --bufferIx_tmp ] ) == 0 ); } /* Check normalization */ if( range_Q32 & 0xFF000000 ) { /* No normalization */ range_Q16 = SKP_RSHIFT_uint( range_Q32, 16 ); } else { if( range_Q32 & 0xFFFF0000 ) { /* Normalization of 8 bits shift */ range_Q16 = SKP_RSHIFT_uint( range_Q32, 8 ); } else { /* Normalization of 16 bits shift */ range_Q16 = range_Q32; /* Make sure not to write beyond buffer */ if( bufferIx >= psRC->bufferLength ) { psRC->error = RANGE_CODER_WRITE_BEYOND_BUFFER; return; } /* Write one byte to buffer */ buffer[ bufferIx++ ] = (SKP_uint8)( SKP_RSHIFT_uint( base_Q32, 24 ) ); base_Q32 = SKP_LSHIFT_ovflw( base_Q32, 8 ); } /* Make sure not to write beyond buffer */ if( bufferIx >= psRC->bufferLength ) { psRC->error = RANGE_CODER_WRITE_BEYOND_BUFFER; return; } /* Write one byte to buffer */ buffer[ bufferIx++ ] = (SKP_uint8)( SKP_RSHIFT_uint( base_Q32, 24 ) ); base_Q32 = SKP_LSHIFT_ovflw( base_Q32, 8 ); } /* Copy structure data back */ psRC->base_Q32 = base_Q32; psRC->range_Q16 = range_Q16; psRC->bufferIx = bufferIx; } /* Range encoder for multiple symbols */ void SKP_Silk_range_encoder_multi( SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_int data[], /* I uncompressed data [nSymbols] */ const SKP_uint16 * const prob[], /* I cumulative density functions */ const SKP_int nSymbols /* I number of data symbols */ ) { SKP_int k; for( k = 0; k < nSymbols; k++ ) { SKP_Silk_range_encoder( psRC, data[ k ], prob[ k ] ); } } /* Range decoder for one symbol */ void SKP_Silk_range_decoder( SKP_int data[], /* O uncompressed data */ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_uint16 prob[], /* I cumulative density function */ SKP_int probIx /* I initial (middle) entry of cdf */ ) { SKP_uint32 low_Q16, high_Q16; SKP_uint32 base_tmp, range_Q32; /* Copy structure data */ SKP_uint32 base_Q32 = psRC->base_Q32; SKP_uint32 range_Q16 = psRC->range_Q16; SKP_int32 bufferIx = psRC->bufferIx; SKP_uint8 *buffer = &psRC->buffer[ 4 ]; if( psRC->error ) { /* Set output to zero */ *data = 0; return; } high_Q16 = prob[ probIx ]; base_tmp = SKP_MUL_uint( range_Q16, high_Q16 ); if( base_tmp > base_Q32 ) { while( 1 ) { low_Q16 = prob[ --probIx ]; base_tmp = SKP_MUL_uint( range_Q16, low_Q16 ); if( base_tmp <= base_Q32 ) { break; } high_Q16 = low_Q16; /* Test for out of range */ if( high_Q16 == 0 ) { psRC->error = RANGE_CODER_CDF_OUT_OF_RANGE; /* Set output to zero */ *data = 0; return; } } } else { while( 1 ) { low_Q16 = high_Q16; high_Q16 = prob[ ++probIx ]; base_tmp = SKP_MUL_uint( range_Q16, high_Q16 ); if( base_tmp > base_Q32 ) { probIx--; break; } /* Test for out of range */ if( high_Q16 == 0xFFFF ) { psRC->error = RANGE_CODER_CDF_OUT_OF_RANGE; /* Set output to zero */ *data = 0; return; } } } *data = probIx; base_Q32 -= SKP_MUL_uint( range_Q16, low_Q16 ); range_Q32 = SKP_MUL_uint( range_Q16, high_Q16 - low_Q16 ); /* Check normalization */ if( range_Q32 & 0xFF000000 ) { /* No normalization */ range_Q16 = SKP_RSHIFT_uint( range_Q32, 16 ); } else { if( range_Q32 & 0xFFFF0000 ) { /* Normalization of 8 bits shift */ range_Q16 = SKP_RSHIFT_uint( range_Q32, 8 ); /* Check for errors */ if( SKP_RSHIFT_uint( base_Q32, 24 ) ) { psRC->error = RANGE_CODER_NORMALIZATION_FAILED; /* Set output to zero */ *data = 0; return; } } else { /* Normalization of 16 bits shift */ range_Q16 = range_Q32; /* Check for errors */ if( SKP_RSHIFT( base_Q32, 16 ) ) { psRC->error = RANGE_CODER_NORMALIZATION_FAILED; /* Set output to zero */ *data = 0; return; } /* Update base */ base_Q32 = SKP_LSHIFT_uint( base_Q32, 8 ); /* Make sure not to read beyond buffer */ if( bufferIx < psRC->bufferLength ) { /* Read one byte from buffer */ base_Q32 |= (SKP_uint32)buffer[ bufferIx++ ]; } } /* Update base */ base_Q32 = SKP_LSHIFT_uint( base_Q32, 8 ); /* Make sure not to read beyond buffer */ if( bufferIx < psRC->bufferLength ) { /* Read one byte from buffer */ base_Q32 |= (SKP_uint32)buffer[ bufferIx++ ]; } } /* Check for zero interval length */ if( range_Q16 == 0 ) { psRC->error = RANGE_CODER_ZERO_INTERVAL_WIDTH; /* Set output to zero */ *data = 0; return; } /* Copy structure data back */ psRC->base_Q32 = base_Q32; psRC->range_Q16 = range_Q16; psRC->bufferIx = bufferIx; } /* Range decoder for multiple symbols */ void SKP_Silk_range_decoder_multi( SKP_int data[], /* O uncompressed data [nSymbols] */ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_uint16 * const prob[], /* I cumulative density functions */ const SKP_int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */ const SKP_int nSymbols /* I number of data symbols */ ) { SKP_int k; for( k = 0; k < nSymbols; k++ ) { SKP_Silk_range_decoder( &data[ k ], psRC, prob[ k ], probStartIx[ k ] ); } } /* Initialize range encoder */ void SKP_Silk_range_enc_init( SKP_Silk_range_coder_state *psRC /* O compressor data structure */ ) { /* Initialize structure */ psRC->bufferLength = MAX_ARITHM_BYTES; psRC->range_Q16 = 0x0000FFFF; psRC->bufferIx = 0; psRC->base_Q32 = 0; psRC->error = 0; } /* Initialize range decoder */ void SKP_Silk_range_dec_init( SKP_Silk_range_coder_state *psRC, /* O compressor data structure */ const SKP_uint8 buffer[], /* I buffer for compressed data [bufferLength] */ const SKP_int32 bufferLength /* I buffer length (in bytes) */ ) { /* check input */ if( ( bufferLength > MAX_ARITHM_BYTES ) || ( bufferLength < 0 ) ) { psRC->error = RANGE_CODER_DEC_PAYLOAD_TOO_LONG; return; } /* Initialize structure */ /* Copy to internal buffer */ SKP_memcpy( psRC->buffer, buffer, bufferLength * sizeof( SKP_uint8 ) ); psRC->bufferLength = bufferLength; psRC->bufferIx = 0; psRC->base_Q32 = SKP_LSHIFT_uint( (SKP_uint32)buffer[ 0 ], 24 ) | SKP_LSHIFT_uint( (SKP_uint32)buffer[ 1 ], 16 ) | SKP_LSHIFT_uint( (SKP_uint32)buffer[ 2 ], 8 ) | (SKP_uint32)buffer[ 3 ]; psRC->range_Q16 = 0x0000FFFF; psRC->error = 0; } /* Determine length of bitstream */ SKP_int SKP_Silk_range_coder_get_length( /* O returns number of BITS in stream */ const SKP_Silk_range_coder_state *psRC, /* I compressed data structure */ SKP_int *nBytes /* O number of BYTES in stream */ ) { SKP_int nBits; /* Number of bits in stream */ nBits = SKP_LSHIFT( psRC->bufferIx, 3 ) + SKP_Silk_CLZ32( psRC->range_Q16 - 1 ) - 14; *nBytes = SKP_RSHIFT( nBits + 7, 3 ); /* Return number of bits in bitstream */ return nBits; } /* Write shortest uniquely decodable stream to buffer, and determine its length */ void SKP_Silk_range_enc_wrap_up( SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */ ) { SKP_int bufferIx_tmp, bits_to_store, bits_in_stream, nBytes, mask; SKP_uint32 base_Q24; /* Lower limit of interval, shifted 8 bits to the right */ base_Q24 = SKP_RSHIFT_uint( psRC->base_Q32, 8 ); bits_in_stream = SKP_Silk_range_coder_get_length( psRC, &nBytes ); /* Number of additional bits (1..9) required to be stored to stream */ bits_to_store = bits_in_stream - SKP_LSHIFT( psRC->bufferIx, 3 ); /* Round up to required resolution */ base_Q24 += SKP_RSHIFT_uint( 0x00800000, bits_to_store - 1 ); base_Q24 &= SKP_LSHIFT_ovflw( 0xFFFFFFFF, 24 - bits_to_store ); /* Check for carry */ if( base_Q24 & 0x01000000 ) { /* Propagate carry in buffer */ bufferIx_tmp = psRC->bufferIx; while( ( ++( psRC->buffer[ --bufferIx_tmp ] ) ) == 0 ); } /* Store to stream, making sure not to write beyond buffer */ if( psRC->bufferIx < psRC->bufferLength ) { psRC->buffer[ psRC->bufferIx++ ] = (SKP_uint8)SKP_RSHIFT_uint( base_Q24, 16 ); if( bits_to_store > 8 ) { if( psRC->bufferIx < psRC->bufferLength ) { psRC->buffer[ psRC->bufferIx++ ] = (SKP_uint8)SKP_RSHIFT_uint( base_Q24, 8 ); } } } /* Fill up any remaining bits in the last byte with 1s */ if( bits_in_stream & 7 ) { mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 ); if( nBytes - 1 < psRC->bufferLength ) { psRC->buffer[ nBytes - 1 ] |= mask; } } } /* Check that any remaining bits in the last byte are set to 1 */ void SKP_Silk_range_coder_check_after_decoding( SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */ ) { SKP_int bits_in_stream, nBytes, mask; bits_in_stream = SKP_Silk_range_coder_get_length( psRC, &nBytes ); /* Make sure not to read beyond buffer */ if( nBytes - 1 >= psRC->bufferLength ) { psRC->error = RANGE_CODER_DECODER_CHECK_FAILED; return; } /* Test any remaining bits in last byte */ if( bits_in_stream & 7 ) { mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 ); if( ( psRC->buffer[ nBytes - 1 ] & mask ) != mask ) { psRC->error = RANGE_CODER_DECODER_CHECK_FAILED; return; } } } ================================================ FILE: app/jni/SKP_Silk_regularize_correlations_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Add noise to matrix diagonal */ void SKP_Silk_regularize_correlations_FIX( SKP_int32 *XX, /* I/O Correlation matrices */ SKP_int32 *xx, /* I/O Correlation values */ SKP_int32 noise, /* I Noise to add */ SKP_int D /* I Dimension of XX */ ) { SKP_int i; for( i = 0; i < D; i++ ) { matrix_ptr( &XX[ 0 ], i, i, D ) = SKP_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); } xx[ 0 ] += noise; } ================================================ FILE: app/jni/SKP_Silk_resampler.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler.c * * * * Description: Interface to collection of resamplers * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * */ /* Matrix of resampling methods used: * Fs_out (kHz) * 8 12 16 24 32 44.1 48 * * 8 C UF U UF UF UF UF * 12 AF C UF U UF UF UF * 16 D AF C UF U UF UF * Fs_in (kHz) 24 AIF D AF C UF UF U * 32 UF AF D AF C UF UF * 44.1 AMI AMI AMI AMI AMI C UF * 48 DAF DAF AF D AF UF C * * default method: UF * * C -> Copy (no resampling) * D -> Allpass-based 2x downsampling * U -> Allpass-based 2x upsampling * DAF -> Allpass-based 2x downsampling followed by AR2 filter followed by FIR interpolation * UF -> Allpass-based 2x upsampling followed by FIR interpolation * AMI -> ARMA4 filter followed by FIR interpolation * AF -> AR2 filter followed by FIR interpolation * * Input signals sampled above 48 kHz are first downsampled to at most 48 kHz. * Output signals sampled above 48 kHz are upsampled from at most 48 kHz. */ #include "SKP_Silk_resampler_private.h" /* Greatest common divisor */ static SKP_int32 gcd( SKP_int32 a, SKP_int32 b ) { SKP_int32 tmp; while( b > 0 ) { tmp = a - b * SKP_DIV32( a, b ); a = b; b = tmp; } return a; } /* Initialize/reset the resampler state for a given pair of input/output sampling rates */ SKP_int SKP_Silk_resampler_init( SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */ SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */ SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */ ) { SKP_int32 cycleLen, cyclesPerBatch, up2 = 0, down2 = 0; /* Clear state */ SKP_memset( S, 0, sizeof( SKP_Silk_resampler_state_struct ) ); /* Input checking */ #if RESAMPLER_SUPPORT_ABOVE_48KHZ if( Fs_Hz_in < 8000 || Fs_Hz_in > 192000 || Fs_Hz_out < 8000 || Fs_Hz_out > 192000 ) { #else if( Fs_Hz_in < 8000 || Fs_Hz_in > 48000 || Fs_Hz_out < 8000 || Fs_Hz_out > 48000 ) { #endif SKP_assert( 0 ); return -1; } #if RESAMPLER_SUPPORT_ABOVE_48KHZ /* Determine pre downsampling and post upsampling */ if( Fs_Hz_in > 96000 ) { S->nPreDownsamplers = 2; S->down_pre_function = SKP_Silk_resampler_private_down4; } else if( Fs_Hz_in > 48000 ) { S->nPreDownsamplers = 1; S->down_pre_function = SKP_Silk_resampler_down2; } else { S->nPreDownsamplers = 0; S->down_pre_function = NULL; } if( Fs_Hz_out > 96000 ) { S->nPostUpsamplers = 2; S->up_post_function = SKP_Silk_resampler_private_up4; } else if( Fs_Hz_out > 48000 ) { S->nPostUpsamplers = 1; S->up_post_function = SKP_Silk_resampler_up2; } else { S->nPostUpsamplers = 0; S->up_post_function = NULL; } if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) { /* Ratio of output/input samples */ S->ratio_Q16 = SKP_LSHIFT32( SKP_DIV32( SKP_LSHIFT32( Fs_Hz_out, 13 ), Fs_Hz_in ), 3 ); /* Make sure the ratio is rounded up */ while( SKP_SMULWW( S->ratio_Q16, Fs_Hz_in ) < Fs_Hz_out ) S->ratio_Q16++; /* Batch size is 10 ms */ S->batchSizePrePost = SKP_DIV32_16( Fs_Hz_in, 100 ); /* Convert sampling rate to those after pre-downsampling and before post-upsampling */ Fs_Hz_in = SKP_RSHIFT( Fs_Hz_in, S->nPreDownsamplers ); Fs_Hz_out = SKP_RSHIFT( Fs_Hz_out, S->nPostUpsamplers ); } #endif /* Number of samples processed per batch */ /* First, try 10 ms frames */ S->batchSize = SKP_DIV32_16( Fs_Hz_in, 100 ); if( ( SKP_MUL( S->batchSize, 100 ) != Fs_Hz_in ) || ( Fs_Hz_in % 100 != 0 ) ) { /* No integer number of input or output samples with 10 ms frames, use greatest common divisor */ cycleLen = SKP_DIV32( Fs_Hz_in, gcd( Fs_Hz_in, Fs_Hz_out ) ); cyclesPerBatch = SKP_DIV32( RESAMPLER_MAX_BATCH_SIZE_IN, cycleLen ); if( cyclesPerBatch == 0 ) { /* cycleLen too big, let's just use the maximum batch size. Some distortion will result. */ S->batchSize = RESAMPLER_MAX_BATCH_SIZE_IN; SKP_assert( 0 ); } else { S->batchSize = SKP_MUL( cyclesPerBatch, cycleLen ); } } /* Find resampler with the right sampling ratio */ if( Fs_Hz_out > Fs_Hz_in ) { /* Upsample */ if( Fs_Hz_out == SKP_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */ /* Special case: directly use 2x upsampler */ S->resampler_function = SKP_Silk_resampler_private_up2_HQ_wrapper; } else { /* Default resampler */ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; up2 = 1; if( Fs_Hz_in > 24000 ) { /* Low-quality all-pass upsampler */ S->up2_function = SKP_Silk_resampler_up2; } else { /* High-quality all-pass upsampler */ S->up2_function = SKP_Silk_resampler_private_up2_HQ; } } } else if ( Fs_Hz_out < Fs_Hz_in ) { /* Downsample */ if( SKP_MUL( Fs_Hz_out, 4 ) == SKP_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */ S->FIR_Fracs = 3; S->Coefs = SKP_Silk_Resampler_3_4_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 3 ) == SKP_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */ S->FIR_Fracs = 2; S->Coefs = SKP_Silk_Resampler_2_3_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */ S->FIR_Fracs = 1; S->Coefs = SKP_Silk_Resampler_1_2_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 8 ) == SKP_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 8 */ S->FIR_Fracs = 3; S->Coefs = SKP_Silk_Resampler_3_8_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */ S->FIR_Fracs = 1; S->Coefs = SKP_Silk_Resampler_1_3_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */ S->FIR_Fracs = 1; down2 = 1; S->Coefs = SKP_Silk_Resampler_1_2_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */ S->FIR_Fracs = 1; down2 = 1; S->Coefs = SKP_Silk_Resampler_1_3_COEFS; S->resampler_function = SKP_Silk_resampler_private_down_FIR; } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 80 ) ) { /* Fs_out : Fs_in = 80 : 441 */ S->Coefs = SKP_Silk_Resampler_80_441_ARMA4_COEFS; S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 120 ) ) { /* Fs_out : Fs_in = 120 : 441 */ S->Coefs = SKP_Silk_Resampler_120_441_ARMA4_COEFS; S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 160 ) ) { /* Fs_out : Fs_in = 160 : 441 */ S->Coefs = SKP_Silk_Resampler_160_441_ARMA4_COEFS; S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 240 ) ) { /* Fs_out : Fs_in = 240 : 441 */ S->Coefs = SKP_Silk_Resampler_240_441_ARMA4_COEFS; S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 320 ) ) { /* Fs_out : Fs_in = 320 : 441 */ S->Coefs = SKP_Silk_Resampler_320_441_ARMA4_COEFS; S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; } else { /* Default resampler */ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR; up2 = 1; if( Fs_Hz_in > 24000 ) { /* Low-quality all-pass upsampler */ S->up2_function = SKP_Silk_resampler_up2; } else { /* High-quality all-pass upsampler */ S->up2_function = SKP_Silk_resampler_private_up2_HQ; } } } else { /* Input and output sampling rates are equal: copy */ S->resampler_function = SKP_Silk_resampler_private_copy; } S->input2x = up2 | down2; /* Ratio of input/output samples */ S->invRatio_Q16 = SKP_LSHIFT32( SKP_DIV32( SKP_LSHIFT32( Fs_Hz_in, 14 + up2 - down2 ), Fs_Hz_out ), 2 ); /* Make sure the ratio is rounded up */ while( SKP_SMULWW( S->invRatio_Q16, SKP_LSHIFT32( Fs_Hz_out, down2 ) ) < SKP_LSHIFT32( Fs_Hz_in, up2 ) ) { S->invRatio_Q16++; } S->magic_number = 123456789; return 0; } /* Clear the states of all resampling filters, without resetting sampling rate ratio */ SKP_int SKP_Silk_resampler_clear( SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */ ) { /* Clear state */ SKP_memset( S->sDown2, 0, sizeof( S->sDown2 ) ); SKP_memset( S->sIIR, 0, sizeof( S->sIIR ) ); SKP_memset( S->sFIR, 0, sizeof( S->sFIR ) ); #if RESAMPLER_SUPPORT_ABOVE_48KHZ SKP_memset( S->sDownPre, 0, sizeof( S->sDownPre ) ); SKP_memset( S->sUpPost, 0, sizeof( S->sUpPost ) ); #endif return 0; } /* Resampler: convert from one sampling rate to another */ SKP_int SKP_Silk_resampler( SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ) { /* Verify that state was initialized and has not been corrupted */ if( S->magic_number != 123456789 ) { SKP_assert( 0 ); return -1; } #if RESAMPLER_SUPPORT_ABOVE_48KHZ if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) { /* The input and/or output sampling rate is above 48000 Hz */ SKP_int32 nSamplesIn, nSamplesOut; SKP_int16 in_buf[ 480 ], out_buf[ 480 ]; while( inLen > 0 ) { /* Number of input and output samples to process */ nSamplesIn = SKP_min( inLen, S->batchSizePrePost ); nSamplesOut = SKP_SMULWB( S->ratio_Q16, nSamplesIn ); SKP_assert( SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) <= 480 ); SKP_assert( SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) <= 480 ); if( S->nPreDownsamplers > 0 ) { S->down_pre_function( S->sDownPre, in_buf, in, nSamplesIn ); if( S->nPostUpsamplers > 0 ) { S->resampler_function( S, out_buf, in_buf, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) ); S->up_post_function( S->sUpPost, out, out_buf, SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) ); } else { S->resampler_function( S, out, in_buf, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) ); } } else { S->resampler_function( S, out_buf, in, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) ); S->up_post_function( S->sUpPost, out, out_buf, SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) ); } in += nSamplesIn; out += nSamplesOut; inLen -= nSamplesIn; } } else #endif { /* Input and output sampling rate are at most 48000 Hz */ S->resampler_function( S, out, in, inLen ); } return 0; } ================================================ FILE: app/jni/SKP_Silk_resampler_down2.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_down2.c * * * * Downsample by a factor 2, mediocre quality * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_rom.h" #if (EMBEDDED_ARM<5) /* Downsample by a factor 2, mediocre quality */ void SKP_Silk_resampler_down2( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ len ] */ const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_int32 k, len2 = SKP_RSHIFT32( inLen, 1 ); SKP_int32 in32, out32, Y, X; SKP_assert( SKP_Silk_resampler_down2_0 > 0 ); SKP_assert( SKP_Silk_resampler_down2_1 < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len2; k++ ) { /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 ); /* All-pass section for even input sample */ Y = SKP_SUB32( in32, S[ 0 ] ); X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 ); out32 = SKP_ADD32( S[ 0 ], X ); S[ 0 ] = SKP_ADD32( in32, X ); /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 ); /* All-pass section for odd input sample, and add to output of previous section */ Y = SKP_SUB32( in32, S[ 1 ] ); X = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 ); out32 = SKP_ADD32( out32, S[ 1 ] ); out32 = SKP_ADD32( out32, X ); S[ 1 ] = SKP_ADD32( in32, X ); /* Add, convert back to int16 and store to output */ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) ); } } #endif ================================================ FILE: app/jni/SKP_Silk_resampler_down2_3.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_down2_3.c * * * * Downsample by a factor 2/3, low quality * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" #define ORDER_FIR 4 /* Downsample by a factor 2/3, low quality */ void SKP_Silk_resampler_down2_3( SKP_int32 *S, /* I/O: State vector [ 6 ] */ SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */ const SKP_int16 *in, /* I: Input signal [ inLen ] */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_int32 nSamplesIn, counter, res_Q6; SKP_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; SKP_int32 *buf_ptr; /* Copy buffered samples to start of buffer */ SKP_memcpy( buf, S, ORDER_FIR * sizeof( SKP_int32 ) ); /* Iterate over blocks of frameSizeIn input samples */ while( 1 ) { nSamplesIn = SKP_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); /* Second-order AR filter (output in Q8) */ SKP_Silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, SKP_Silk_Resampler_2_3_COEFS_LQ, nSamplesIn ); /* Interpolate filtered signal */ buf_ptr = buf; counter = nSamplesIn; while( counter > 2 ) { /* Inner product */ res_Q6 = SKP_SMULWB( buf_ptr[ 0 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 1 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] ); /* Scale down, saturate and store in output array */ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); res_Q6 = SKP_SMULWB( buf_ptr[ 1 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 4 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] ); /* Scale down, saturate and store in output array */ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); buf_ptr += 3; counter -= 3; } in += nSamplesIn; inLen -= nSamplesIn; if( inLen > 0 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ SKP_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ SKP_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); } ================================================ FILE: app/jni/SKP_Silk_resampler_down3.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_down3.c * * * * Downsample by a factor 3, low quality * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" #define ORDER_FIR 6 /* Downsample by a factor 3, low quality */ void SKP_Silk_resampler_down3( SKP_int32 *S, /* I/O: State vector [ 8 ] */ SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */ const SKP_int16 *in, /* I: Input signal [ inLen ] */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_int32 nSamplesIn, counter, res_Q6; SKP_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; SKP_int32 *buf_ptr; /* Copy buffered samples to start of buffer */ SKP_memcpy( buf, S, ORDER_FIR * sizeof( SKP_int32 ) ); /* Iterate over blocks of frameSizeIn input samples */ while( 1 ) { nSamplesIn = SKP_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); /* Second-order AR filter (output in Q8) */ SKP_Silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, SKP_Silk_Resampler_1_3_COEFS_LQ, nSamplesIn ); /* Interpolate filtered signal */ buf_ptr = buf; counter = nSamplesIn; while( counter > 2 ) { /* Inner product */ res_Q6 = SKP_SMULWB( SKP_ADD32( buf_ptr[ 0 ], buf_ptr[ 5 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 1 ], buf_ptr[ 4 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 3 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 2 ], buf_ptr[ 3 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 4 ] ); /* Scale down, saturate and store in output array */ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); buf_ptr += 3; counter -= 3; } in += nSamplesIn; inLen -= nSamplesIn; if( inLen > 0 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ SKP_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ SKP_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) ); } ================================================ FILE: app/jni/SKP_Silk_resampler_private_AR2.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_private_AR2. c * * * * Second order AR filter with single delay elements * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" #if (EMBEDDED_ARM<5) /* Second order AR filter with single delay elements */ void SKP_Silk_resampler_private_AR2( SKP_int32 S[], /* I/O: State vector [ 2 ] */ SKP_int32 out_Q8[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ const SKP_int16 A_Q14[], /* I: AR coefficients, Q14 */ SKP_int32 len /* I: Signal length */ ) { SKP_int32 k; SKP_int32 out32; for( k = 0; k < len; k++ ) { out32 = SKP_ADD_LSHIFT32( S[ 0 ], (SKP_int32)in[ k ], 8 ); out_Q8[ k ] = out32; out32 = SKP_LSHIFT( out32, 2 ); S[ 0 ] = SKP_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] ); S[ 1 ] = SKP_SMULWB( out32, A_Q14[ 1 ] ); } } #endif ================================================ FILE: app/jni/SKP_Silk_resampler_private_ARMA4.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_private_ARMA4.c * * * * Fourth order ARMA filter, applies 64x gain * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" /* Fourth order ARMA filter */ /* Internally operates as two biquad filters in sequence. */ /* Coeffients are stored in a packed format: */ /* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */ /* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */ #if (EMBEDDED_ARM<5) void SKP_Silk_resampler_private_ARMA4( SKP_int32 S[], /* I/O: State vector [ 4 ] */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ const SKP_int16 Coef[], /* I: ARMA coefficients [ 7 ] */ SKP_int32 len /* I: Signal length */ ) { SKP_int32 k; SKP_int32 in_Q8, out1_Q8, out2_Q8, X; for( k = 0; k < len; k++ ) { in_Q8 = SKP_LSHIFT32( (SKP_int32)in[ k ], 8 ); /* Outputs of first and second biquad */ out1_Q8 = SKP_ADD_LSHIFT32( in_Q8, S[ 0 ], 2 ); out2_Q8 = SKP_ADD_LSHIFT32( out1_Q8, S[ 2 ], 2 ); /* Update states, which are stored in Q6. Coefficients are in Q14 here */ X = SKP_SMLAWB( S[ 1 ], in_Q8, Coef[ 0 ] ); S[ 0 ] = SKP_SMLAWB( X, out1_Q8, Coef[ 2 ] ); X = SKP_SMLAWB( S[ 3 ], out1_Q8, Coef[ 1 ] ); S[ 2 ] = SKP_SMLAWB( X, out2_Q8, Coef[ 4 ] ); S[ 1 ] = SKP_SMLAWB( SKP_RSHIFT32( in_Q8, 2 ), out1_Q8, Coef[ 3 ] ); S[ 3 ] = SKP_SMLAWB( SKP_RSHIFT32( out1_Q8, 2 ), out2_Q8, Coef[ 5 ] ); /* Apply gain and store to output. The coefficient is in Q16 */ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( SKP_SMLAWB( 128, out2_Q8, Coef[ 6 ] ), 8 ) ); } } #endif ================================================ FILE: app/jni/SKP_Silk_resampler_private_IIR_FIR.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler_private_IIR_FIR.c * * * * Description: Hybrid IIR/FIR polyphase implementation of resampling * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" #if EMBEDDED_ARM<5 SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_IIR_FIR_INTERPOL( SKP_int16 * out, SKP_int16 * buf, SKP_int32 max_index_Q16 , SKP_int32 index_increment_Q16 ){ SKP_int32 index_Q16, res_Q15; SKP_int16 *buf_ptr; SKP_int32 table_index; /* Interpolate upsampled signal and store in output array */ for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { table_index = SKP_SMULWB( index_Q16 & 0xFFFF, 144 ); buf_ptr = &buf[ index_Q16 >> 16 ]; res_Q15 = SKP_SMULBB( buf_ptr[ 0 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 0 ] ); res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 1 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 1 ] ); res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 2 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 2 ] ); res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 3 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] ); res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 4 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] ); res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 5 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] ); *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q15, 15 ) ); } return out; } #else extern SKP_int16 *SKP_Silk_resampler_private_IIR_FIR_INTERPOL( SKP_int16 * out, SKP_int16 * buf, SKP_int32 max_index_Q16 , SKP_int32 index_increment_Q16 ); #endif /* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ void SKP_Silk_resampler_private_IIR_FIR( void *SS, /* I/O: Resampler state */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS; SKP_int32 nSamplesIn; SKP_int32 max_index_Q16, index_increment_Q16; SKP_int16 buf[ 2 * RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_144 ]; /* Copy buffered samples to start of buffer */ SKP_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); /* Iterate over blocks of frameSizeIn input samples */ index_increment_Q16 = S->invRatio_Q16; while( 1 ) { nSamplesIn = SKP_min( inLen, S->batchSize ); if( S->input2x == 1 ) { /* Upsample 2x */ S->up2_function( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, nSamplesIn ); } else { /* Fourth-order ARMA filter */ SKP_Silk_resampler_private_ARMA4( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, S->Coefs, nSamplesIn ); } max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 + S->input2x ); /* +1 if 2x upsampling */ out = SKP_Silk_resampler_private_IIR_FIR_INTERPOL(out, buf, max_index_Q16, index_increment_Q16); in += nSamplesIn; inLen -= nSamplesIn; if( inLen > 0 ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ SKP_memcpy( buf, &buf[ nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ SKP_memcpy( S->sFIR, &buf[nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) ); } ================================================ FILE: app/jni/SKP_Silk_resampler_private_copy.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler_private_copy.c * * * * Description: Copy. * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" /* Copy */ void SKP_Silk_resampler_private_copy( void *SS, /* I/O: Resampler state (unused) */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_memcpy( out, in, inLen * sizeof( SKP_int16 ) ); } ================================================ FILE: app/jni/SKP_Silk_resampler_private_down4.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_private_down4.c * * * * Downsample by a factor 4 * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" /* Downsample by a factor 4. Note: very low quality, only use with input sampling rates above 96 kHz. */ void SKP_Silk_resampler_private_down4( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ floor(len/2) ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_int32 k, len4 = SKP_RSHIFT32( inLen, 2 ); SKP_int32 in32, out32, Y, X; SKP_assert( SKP_Silk_resampler_down2_0 > 0 ); SKP_assert( SKP_Silk_resampler_down2_1 < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len4; k++ ) { /* Add two input samples and convert to Q10 */ in32 = SKP_LSHIFT( SKP_ADD32( (SKP_int32)in[ 4 * k ], (SKP_int32)in[ 4 * k + 1 ] ), 9 ); /* All-pass section for even input sample */ Y = SKP_SUB32( in32, S[ 0 ] ); X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 ); out32 = SKP_ADD32( S[ 0 ], X ); S[ 0 ] = SKP_ADD32( in32, X ); /* Add two input samples and convert to Q10 */ in32 = SKP_LSHIFT( SKP_ADD32( (SKP_int32)in[ 4 * k + 2 ], (SKP_int32)in[ 4 * k + 3 ] ), 9 ); /* All-pass section for odd input sample */ Y = SKP_SUB32( in32, S[ 1 ] ); X = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 ); out32 = SKP_ADD32( out32, S[ 1 ] ); out32 = SKP_ADD32( out32, X ); S[ 1 ] = SKP_ADD32( in32, X ); /* Add, convert back to int16 and store to output */ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) ); } } ================================================ FILE: app/jni/SKP_Silk_resampler_private_down_FIR.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler_private_down_FIR.c * * * * Description: Hybrid IIR/FIR polyphase implementation of resampling * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" #if EMBEDDED_ARM<5 SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL0( SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16){ SKP_int32 index_Q16, res_Q6; SKP_int32 *buf_ptr; for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { /* Integer part gives pointer to buffered input */ buf_ptr = buf2 + SKP_RSHIFT( index_Q16, 16 ); /* Inner product */ res_Q6 = SKP_SMULWB( SKP_ADD32( buf_ptr[ 0 ], buf_ptr[ 11 ] ), FIR_Coefs[ 0 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 1 ], buf_ptr[ 10 ] ), FIR_Coefs[ 1 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 2 ], buf_ptr[ 9 ] ), FIR_Coefs[ 2 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 3 ], buf_ptr[ 8 ] ), FIR_Coefs[ 3 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 4 ], buf_ptr[ 7 ] ), FIR_Coefs[ 4 ] ); res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 5 ], buf_ptr[ 6 ] ), FIR_Coefs[ 5 ] ); /* Scale down, saturate and store in output array */ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); } return out; } SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL1( SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16, SKP_int32 FIR_Fracs){ SKP_int32 index_Q16, res_Q6; SKP_int32 *buf_ptr; SKP_int32 interpol_ind; const SKP_int16 *interpol_ptr; for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { /* Integer part gives pointer to buffered input */ buf_ptr = buf2 + SKP_RSHIFT( index_Q16, 16 ); /* Fractional part gives interpolation coefficients */ interpol_ind = SKP_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs ); /* Inner product */ interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * interpol_ind ]; res_Q6 = SKP_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] ); interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * ( FIR_Fracs - 1 - interpol_ind ) ]; res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 0 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 1 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 2 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 3 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 4 ] ); res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 5 ] ); /* Scale down, saturate and store in output array */ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) ); } return out; } #else extern SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL0( SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16); extern SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL1( SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16, SKP_int32 FIR_Fracs); #endif /* Resample with a 2x downsampler (optional), a 2nd order AR filter followed by FIR interpolation */ void SKP_Silk_resampler_private_down_FIR( void *SS, /* I/O: Resampler state */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ) { SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS; SKP_int32 nSamplesIn; SKP_int32 max_index_Q16, index_increment_Q16; SKP_int16 buf1[ RESAMPLER_MAX_BATCH_SIZE_IN / 2 ]; SKP_int32 buf2[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_DOWN_ORDER_FIR ]; const SKP_int16 *FIR_Coefs; /* Copy buffered samples to start of buffer */ SKP_memcpy( buf2, S->sFIR, RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); FIR_Coefs = &S->Coefs[ 2 ]; /* Iterate over blocks of frameSizeIn input samples */ index_increment_Q16 = S->invRatio_Q16; while( 1 ) { nSamplesIn = SKP_min( inLen, S->batchSize ); if( S->input2x == 1 ) { /* Downsample 2x */ SKP_Silk_resampler_down2( S->sDown2, buf1, in, nSamplesIn ); nSamplesIn = SKP_RSHIFT32( nSamplesIn, 1 ); /* Second-order AR filter (output in Q8) */ SKP_Silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], buf1, S->Coefs, nSamplesIn ); } else { /* Second-order AR filter (output in Q8) */ SKP_Silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], in, S->Coefs, nSamplesIn ); } max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 ); /* Interpolate filtered signal */ if( S->FIR_Fracs == 1 ) { out = SKP_Silk_resampler_private_down_FIR_INTERPOL0(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16); } else { out = SKP_Silk_resampler_private_down_FIR_INTERPOL1(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16, S->FIR_Fracs); } in += nSamplesIn << S->input2x; inLen -= nSamplesIn << S->input2x; if( inLen > S->input2x ) { /* More iterations to do; copy last part of filtered signal to beginning of buffer */ SKP_memcpy( buf2, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); } else { break; } } /* Copy last part of filtered signal to the state for the next call */ SKP_memcpy( S->sFIR, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) ); } ================================================ FILE: app/jni/SKP_Silk_resampler_private_up2_HQ.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_private_up2_HQ.c * * * * Upsample by a factor 2, high quality * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" /* Upsample by a factor 2, high quality */ /* Uses 2nd order allpass filters for the 2x upsampling, followed by a */ /* notch filter just above Nyquist. */ #if (EMBEDDED_ARM<5) void SKP_Silk_resampler_private_up2_HQ( SKP_int32 *S, /* I/O: Resampler state [ 6 ] */ SKP_int16 *out, /* O: Output signal [ 2 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of INPUT samples */ ) { SKP_int32 k; SKP_int32 in32, out32_1, out32_2, Y, X; SKP_assert( SKP_Silk_resampler_up2_hq_0[ 0 ] > 0 ); SKP_assert( SKP_Silk_resampler_up2_hq_0[ 1 ] < 0 ); SKP_assert( SKP_Silk_resampler_up2_hq_1[ 0 ] > 0 ); SKP_assert( SKP_Silk_resampler_up2_hq_1[ 1 ] < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len; k++ ) { /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 ); /* First all-pass section for even output sample */ Y = SKP_SUB32( in32, S[ 0 ] ); X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_hq_0[ 0 ] ); out32_1 = SKP_ADD32( S[ 0 ], X ); S[ 0 ] = SKP_ADD32( in32, X ); /* Second all-pass section for even output sample */ Y = SKP_SUB32( out32_1, S[ 1 ] ); X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_hq_0[ 1 ] ); out32_2 = SKP_ADD32( S[ 1 ], X ); S[ 1 ] = SKP_ADD32( out32_1, X ); /* Biquad notch filter */ out32_2 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 2 ] ); out32_2 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 1 ] ); out32_1 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 0 ] ); S[ 5 ] = SKP_SUB32( out32_2, S[ 5 ] ); /* Apply gain in Q15, convert back to int16 and store to output */ out[ 2 * k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( SKP_SMLAWB( 256, out32_1, SKP_Silk_resampler_up2_hq_notch[ 3 ] ), 9 ) ); /* First all-pass section for odd output sample */ Y = SKP_SUB32( in32, S[ 2 ] ); X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_hq_1[ 0 ] ); out32_1 = SKP_ADD32( S[ 2 ], X ); S[ 2 ] = SKP_ADD32( in32, X ); /* Second all-pass section for odd output sample */ Y = SKP_SUB32( out32_1, S[ 3 ] ); X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_hq_1[ 1 ] ); out32_2 = SKP_ADD32( S[ 3 ], X ); S[ 3 ] = SKP_ADD32( out32_1, X ); /* Biquad notch filter */ out32_2 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 2 ] ); out32_2 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 1 ] ); out32_1 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 0 ] ); S[ 4 ] = SKP_SUB32( out32_2, S[ 4 ] ); /* Apply gain in Q15, convert back to int16 and store to output */ out[ 2 * k + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( SKP_SMLAWB( 256, out32_1, SKP_Silk_resampler_up2_hq_notch[ 3 ] ), 9 ) ); } } #endif void SKP_Silk_resampler_private_up2_HQ_wrapper( void *SS, /* I/O: Resampler state (unused) */ SKP_int16 *out, /* O: Output signal [ 2 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of input samples */ ) { SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS; SKP_Silk_resampler_private_up2_HQ( S->sIIR, out, in, len ); } ================================================ FILE: app/jni/SKP_Silk_resampler_private_up4.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_private_up4.c * * * * Upsample by a factor 4, low quality * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_private.h" /* Upsample by a factor 4, Note: very low quality, only use with output sampling rates above 96 kHz. */ void SKP_Silk_resampler_private_up4( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ 4 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of INPUT samples */ ) { SKP_int32 k; SKP_int32 in32, out32, Y, X; SKP_int16 out16; SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 ); SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len; k++ ) { /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 ); /* All-pass section for even output sample */ Y = SKP_SUB32( in32, S[ 0 ] ); X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 ); out32 = SKP_ADD32( S[ 0 ], X ); S[ 0 ] = SKP_ADD32( in32, X ); /* Convert back to int16 and store to output */ out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); out[ 4 * k ] = out16; out[ 4 * k + 1 ] = out16; /* All-pass section for odd output sample */ Y = SKP_SUB32( in32, S[ 1 ] ); X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 ); out32 = SKP_ADD32( S[ 1 ], X ); S[ 1 ] = SKP_ADD32( in32, X ); /* Convert back to int16 and store to output */ out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); out[ 4 * k + 2 ] = out16; out[ 4 * k + 3 ] = out16; } } ================================================ FILE: app/jni/SKP_Silk_resampler_rom.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler_rom.c * * * * Description: Filter coefficients for IIR/FIR polyphase resampling * * Total size: 550 Words (1.1 kB) * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * */ #include "SKP_Silk_resampler_private.h" /* Tables for 2x downsampler */ const SKP_int16 SKP_Silk_resampler_down2_0 = 9872; const SKP_int16 SKP_Silk_resampler_down2_1 = 39809 - 65536; /* Tables for 2x upsampler, low quality */ const SKP_int16 SKP_Silk_resampler_up2_lq_0 = 8102; const SKP_int16 SKP_Silk_resampler_up2_lq_1 = 36783 - 65536; /* Tables for 2x upsampler, high quality */ const SKP_int16 SKP_Silk_resampler_up2_hq_0[ 2 ] = { 4280, 33727 - 65536 }; const SKP_int16 SKP_Silk_resampler_up2_hq_1[ 2 ] = { 16295, 54015 - 65536 }; /* Matlab code for the notch filter coefficients: */ /* B = [1, 0.12, 1]; A = [1, 0.055, 0.8]; G = 0.87; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]); */ /* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ const SKP_int16 SKP_Silk_resampler_up2_hq_notch[ 4 ] = { 7864, -3604, 13107, 28508 }; /* Tables with IIR and FIR coefficients for fractional downsamplers (70 Words) */ SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = { -18249, -12532, -97, 284, -495, 309, 10268, 20317, -94, 156, -48, -720, 5984, 18278, -45, -4, 237, -847, 2540, 14662, }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = { -11891, -12486, 20, 211, -657, 688, 8423, 15911, -44, 197, -152, -653, 3855, 13015, }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = { 2415, -13101, 158, -295, -400, 1265, 4832, 7968, }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_3_8_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = { 13270, -13738, -294, -123, 747, 2043, 3339, 3995, -151, -311, 414, 1583, 2947, 3877, -33, -389, 143, 1141, 2503, 3653, }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = { 16643, -14000, -331, 19, 581, 1421, 2290, 2845, }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { -2797, -6507, 4697, 10739, 1567, 8276, }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 + 3 ] = { 16777, -9792, 890, 1614, 2148, }; /* Tables with coefficients for 4th order ARMA filter (35 Words), in a packed format: */ /* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */ /* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */ SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_320_441_ARMA4_COEFS[ 7 ] = { 31454, 24746, -9706, -3386, -17911, -13243, 24797 }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_240_441_ARMA4_COEFS[ 7 ] = { 28721, 11254, 3189, -2546, -1495, -12618, 11562 }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_160_441_ARMA4_COEFS[ 7 ] = { 23492, -6457, 14358, -4856, 14654, -13008, 4456 }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_120_441_ARMA4_COEFS[ 7 ] = { 19311, -15569, 19489, -6950, 21441, -13559, 2370 }; SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_80_441_ARMA4_COEFS[ 7 ] = { 13248, -23849, 24126, -9486, 26806, -14286, 1065 }; /* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */ SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ] = { { -647, 1884, 30078}, { -625, 1736, 30044}, { -603, 1591, 30005}, { -581, 1448, 29963}, { -559, 1308, 29917}, { -537, 1169, 29867}, { -515, 1032, 29813}, { -494, 898, 29755}, { -473, 766, 29693}, { -452, 636, 29627}, { -431, 508, 29558}, { -410, 383, 29484}, { -390, 260, 29407}, { -369, 139, 29327}, { -349, 20, 29242}, { -330, -97, 29154}, { -310, -211, 29062}, { -291, -324, 28967}, { -271, -434, 28868}, { -253, -542, 28765}, { -234, -647, 28659}, { -215, -751, 28550}, { -197, -852, 28436}, { -179, -951, 28320}, { -162, -1048, 28200}, { -144, -1143, 28077}, { -127, -1235, 27950}, { -110, -1326, 27820}, { -94, -1414, 27687}, { -77, -1500, 27550}, { -61, -1584, 27410}, { -45, -1665, 27268}, { -30, -1745, 27122}, { -15, -1822, 26972}, { 0, -1897, 26820}, { 15, -1970, 26665}, { 29, -2041, 26507}, { 44, -2110, 26346}, { 57, -2177, 26182}, { 71, -2242, 26015}, { 84, -2305, 25845}, { 97, -2365, 25673}, { 110, -2424, 25498}, { 122, -2480, 25320}, { 134, -2534, 25140}, { 146, -2587, 24956}, { 157, -2637, 24771}, { 168, -2685, 24583}, { 179, -2732, 24392}, { 190, -2776, 24199}, { 200, -2819, 24003}, { 210, -2859, 23805}, { 220, -2898, 23605}, { 229, -2934, 23403}, { 238, -2969, 23198}, { 247, -3002, 22992}, { 255, -3033, 22783}, { 263, -3062, 22572}, { 271, -3089, 22359}, { 279, -3114, 22144}, { 286, -3138, 21927}, { 293, -3160, 21709}, { 300, -3180, 21488}, { 306, -3198, 21266}, { 312, -3215, 21042}, { 318, -3229, 20816}, { 323, -3242, 20589}, { 328, -3254, 20360}, { 333, -3263, 20130}, { 338, -3272, 19898}, { 342, -3278, 19665}, { 346, -3283, 19430}, { 350, -3286, 19194}, { 353, -3288, 18957}, { 356, -3288, 18718}, { 359, -3286, 18478}, { 362, -3283, 18238}, { 364, -3279, 17996}, { 366, -3273, 17753}, { 368, -3266, 17509}, { 369, -3257, 17264}, { 371, -3247, 17018}, { 372, -3235, 16772}, { 372, -3222, 16525}, { 373, -3208, 16277}, { 373, -3192, 16028}, { 373, -3175, 15779}, { 373, -3157, 15529}, { 372, -3138, 15279}, { 371, -3117, 15028}, { 370, -3095, 14777}, { 369, -3072, 14526}, { 368, -3048, 14274}, { 366, -3022, 14022}, { 364, -2996, 13770}, { 362, -2968, 13517}, { 359, -2940, 13265}, { 357, -2910, 13012}, { 354, -2880, 12760}, { 351, -2848, 12508}, { 348, -2815, 12255}, { 344, -2782, 12003}, { 341, -2747, 11751}, { 337, -2712, 11500}, { 333, -2676, 11248}, { 328, -2639, 10997}, { 324, -2601, 10747}, { 320, -2562, 10497}, { 315, -2523, 10247}, { 310, -2482, 9998}, { 305, -2442, 9750}, { 300, -2400, 9502}, { 294, -2358, 9255}, { 289, -2315, 9009}, { 283, -2271, 8763}, { 277, -2227, 8519}, { 271, -2182, 8275}, { 265, -2137, 8032}, { 259, -2091, 7791}, { 252, -2045, 7550}, { 246, -1998, 7311}, { 239, -1951, 7072}, { 232, -1904, 6835}, { 226, -1856, 6599}, { 219, -1807, 6364}, { 212, -1758, 6131}, { 204, -1709, 5899}, { 197, -1660, 5668}, { 190, -1611, 5439}, { 183, -1561, 5212}, { 175, -1511, 4986}, { 168, -1460, 4761}, { 160, -1410, 4538}, { 152, -1359, 4317}, { 145, -1309, 4098}, { 137, -1258, 3880}, { 129, -1207, 3664}, { 121, -1156, 3450}, { 113, -1105, 3238}, { 105, -1054, 3028}, { 97, -1003, 2820}, { 89, -952, 2614}, { 81, -901, 2409}, { 73, -851, 2207}, }; ================================================ FILE: app/jni/SKP_Silk_resampler_up2.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_resampler_up2.c * * * * Upsample by a factor 2, low quality * * * * Copyright 2010 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_rom.h" /* Upsample by a factor 2, low quality */ #if EMBEDDED_ARM<5 void SKP_Silk_resampler_up2( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ 2 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of input samples */ ) { SKP_int32 k; SKP_int32 in32, out32, Y, X; SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 ); SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 ); /* Internal variables and state are in Q10 format */ for( k = 0; k < len; k++ ) { /* Convert to Q10 */ in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 ); /* All-pass section for even output sample */ Y = SKP_SUB32( in32, S[ 0 ] ); X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 ); out32 = SKP_ADD32( S[ 0 ], X ); S[ 0 ] = SKP_ADD32( in32, X ); /* Convert back to int16 and store to output */ out[ 2 * k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); /* All-pass section for odd output sample */ Y = SKP_SUB32( in32, S[ 1 ] ); X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 ); out32 = SKP_ADD32( S[ 1 ], X ); S[ 1 ] = SKP_ADD32( in32, X ); /* Convert back to int16 and store to output */ out[ 2 * k + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) ); } } #endif ================================================ FILE: app/jni/SKP_Silk_residual_energy16_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ SKP_int32 SKP_Silk_residual_energy16_covar_FIX( const SKP_int16 *c, /* I Prediction vector */ const SKP_int32 *wXX, /* I Correlation matrix */ const SKP_int32 *wXx, /* I Correlation vector */ SKP_int32 wxx, /* I Signal energy */ SKP_int D, /* I Dimension */ SKP_int cQ /* I Q value for c vector 0 - 15 */ ) { SKP_int i, j, lshifts, Qxtra; SKP_int32 c_max, w_max, tmp, tmp2, nrg; SKP_int cn[ MAX_MATRIX_SIZE ]; const SKP_int32 *pRow; /* Safety checks */ SKP_assert( D >= 0 ); SKP_assert( D <= 16 ); SKP_assert( cQ > 0 ); SKP_assert( cQ < 16 ); lshifts = 16 - cQ; Qxtra = lshifts; c_max = 0; for( i = 0; i < D; i++ ) { c_max = SKP_max_32( c_max, SKP_abs( ( SKP_int32 )c[ i ] ) ); } Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( c_max ) - 17 ); w_max = SKP_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( SKP_MUL( D, SKP_RSHIFT( SKP_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); Qxtra = SKP_max_int( Qxtra, 0 ); for( i = 0; i < D; i++ ) { cn[ i ] = SKP_LSHIFT( ( SKP_int )c[ i ], Qxtra ); SKP_assert( SKP_abs(cn[i]) <= ( SKP_int16_MAX + 1 ) ); /* Check that SKP_SMLAWB can be used */ } lshifts -= Qxtra; /* Compute wxx - 2 * wXx * c */ tmp = 0; for( i = 0; i < D; i++ ) { tmp = SKP_SMLAWB( tmp, wXx[ i ], cn[ i ] ); } nrg = SKP_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ /* Add c' * wXX * c, assuming wXX is symmetric */ tmp2 = 0; for( i = 0; i < D; i++ ) { tmp = 0; pRow = &wXX[ i * D ]; for( j = i + 1; j < D; j++ ) { tmp = SKP_SMLAWB( tmp, pRow[ j ], cn[ j ] ); } tmp = SKP_SMLAWB( tmp, SKP_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); tmp2 = SKP_SMLAWB( tmp2, tmp, cn[ i ] ); } nrg = SKP_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ /* Keep one bit free always, because we add them for LSF interpolation */ if( nrg < 1 ) { nrg = 1; } else if( nrg > SKP_RSHIFT( SKP_int32_MAX, lshifts + 2 ) ) { nrg = SKP_int32_MAX >> 1; } else { nrg = SKP_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ } return nrg; } ================================================ FILE: app/jni/SKP_Silk_residual_energy_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceeding samples */ void SKP_Silk_residual_energy_FIX( SKP_int32 nrgs[ NB_SUBFR ], /* O Residual energy per subframe */ SKP_int nrgsQ[ NB_SUBFR ], /* O Q value per subframe */ const SKP_int16 x[], /* I Input signal */ SKP_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],/* I AR coefs for each frame half */ const SKP_int32 gains[ NB_SUBFR ], /* I Quantization gains */ const SKP_int subfr_length, /* I Subframe length */ const SKP_int LPC_order /* I LPC order */ ) { SKP_int offset, i, j, rshift, lz1, lz2; SKP_int16 *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; const SKP_int16 *x_ptr; SKP_int16 S[ MAX_LPC_ORDER ]; SKP_int32 tmp32; x_ptr = x; offset = LPC_order + subfr_length; /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ for( i = 0; i < 2; i++ ) { /* Calculate half frame LPC residual signal including preceeding samples */ SKP_memset( S, 0, LPC_order * sizeof( SKP_int16 ) ); SKP_Silk_LPC_analysis_filter( x_ptr, a_Q12[ i ], S, LPC_res, ( NB_SUBFR >> 1 ) * offset, LPC_order ); /* Point to first subframe of the just calculated LPC residual signal */ LPC_res_ptr = LPC_res + LPC_order; for( j = 0; j < ( NB_SUBFR >> 1 ); j++ ) { /* Measure subframe energy */ SKP_Silk_sum_sqr_shift( &nrgs[ i * ( NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); /* Set Q values for the measured energy */ nrgsQ[ i * ( NB_SUBFR >> 1 ) + j ] = -rshift; /* Move to next subframe */ LPC_res_ptr += offset; } /* Move to next frame half */ x_ptr += ( NB_SUBFR >> 1 ) * offset; } /* Apply the squared subframe gains */ for( i = 0; i < NB_SUBFR; i++ ) { /* Fully upscale gains and energies */ lz1 = SKP_Silk_CLZ32( nrgs[ i ] ) - 1; lz2 = SKP_Silk_CLZ32( gains[ i ] ) - 1; tmp32 = SKP_LSHIFT32( gains[ i ], lz2 ); /* Find squared gains */ tmp32 = SKP_SMMUL( tmp32, tmp32 ); // Q( 2 * lz2 - 32 ) /* Scale energies */ nrgs[ i ] = SKP_SMMUL( tmp32, SKP_LSHIFT32( nrgs[ i ], lz1 ) ); // Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 ) nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; } } ================================================ FILE: app/jni/SKP_Silk_scale_copy_vector16.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" /* Copy and multiply a vector by a constant */ void SKP_Silk_scale_copy_vector16( SKP_int16 *data_out, const SKP_int16 *data_in, SKP_int32 gain_Q16, /* (I): gain in Q16 */ const SKP_int dataSize /* (I): length */ ) { SKP_int i; SKP_int32 tmp32; for( i = 0; i < dataSize; i++ ) { tmp32 = SKP_SMULWB( gain_Q16, data_in[ i ] ); data_out[ i ] = (SKP_int16)SKP_CHECK_FIT16( tmp32 ); } } ================================================ FILE: app/jni/SKP_Silk_scale_vector.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_SigProc_FIX.h" /* Multiply a vector by a constant */ void SKP_Silk_scale_vector32_Q26_lshift_18( SKP_int32 *data1, /* (I/O): Q0/Q18 */ SKP_int32 gain_Q26, /* (I): Q26 */ SKP_int dataSize /* (I): length */ ) { SKP_int i; for( i = 0; i < dataSize; i++ ) { data1[ i ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_SMULL( data1[ i ], gain_Q26 ), 8 ) );// OUTPUT: Q18 } } ================================================ FILE: app/jni/SKP_Silk_schur.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_schur.c * * * * Calculates the reflection coefficients from the correlation sequence * * * * Copyright 2008 (c), Skype Limited * * Date: 080103 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Faster than schur64(), but much less accurate. */ /* uses SMLAWB(), requiring armv5E and higher. */ SKP_int32 SKP_Silk_schur( /* O: Returns residual energy */ SKP_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */ const SKP_int32 *c, /* I: correlations [order+1] */ const SKP_int32 order /* I: prediction order */ ) { SKP_int k, n, lz; SKP_int32 C[ SKP_Silk_MAX_ORDER_LPC + 1 ][ 2 ]; SKP_int32 Ctmp1, Ctmp2, rc_tmp_Q15; /* Get number of leading zeros */ lz = SKP_Silk_CLZ32( c[ 0 ] ); /* Copy correlations and adjust level to Q30 */ if( lz < 2 ) { /* lz must be 1, so shift one to the right */ for( k = 0; k < order + 1; k++ ) { C[ k ][ 0 ] = C[ k ][ 1 ] = SKP_RSHIFT( c[ k ], 1 ); } } else if( lz > 2 ) { /* Shift to the left */ lz -= 2; for( k = 0; k < order + 1; k++ ) { C[ k ][ 0 ] = C[ k ][ 1 ] = SKP_LSHIFT( c[k], lz ); } } else { /* No need to shift */ for( k = 0; k < order + 1; k++ ) { C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; } } for( k = 0; k < order; k++ ) { /* Get reflection coefficient */ rc_tmp_Q15 = -SKP_DIV32_16( C[ k + 1 ][ 0 ], SKP_max_32( SKP_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) ); /* Clip (shouldn't happen for properly conditioned inputs) */ rc_tmp_Q15 = SKP_SAT16( rc_tmp_Q15 ); /* Store */ rc_Q15[ k ] = (SKP_int16)rc_tmp_Q15; /* Update correlations */ for( n = 0; n < order - k; n++ ) { Ctmp1 = C[ n + k + 1 ][ 0 ]; Ctmp2 = C[ n ][ 1 ]; C[ n + k + 1 ][ 0 ] = SKP_SMLAWB( Ctmp1, SKP_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 ); C[ n ][ 1 ] = SKP_SMLAWB( Ctmp2, SKP_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 ); } } /* return residual energy */ return C[0][1]; } ================================================ FILE: app/jni/SKP_Silk_schur64.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_schur64.c * * * * Calculates the reflection coefficients from the correlation sequence * * using extra precision * * * * Copyright 2008 (c), Skype Limited * * Date: 080103 * * */ #include "SKP_Silk_SigProc_FIX.h" /* Slower than schur(), but more accurate. */ /* Uses SMULL(), available on armv4 */ #if EMBEDDED_ARM<6 SKP_int32 SKP_Silk_schur64( /* O: Returns residual energy */ SKP_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */ const SKP_int32 c[], /* I: Correlations [order+1] */ SKP_int32 order /* I: Prediction order */ ) { SKP_int k, n; SKP_int32 C[ SKP_Silk_MAX_ORDER_LPC + 1 ][ 2 ]; SKP_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31; /* Check for invalid input */ if( c[ 0 ] <= 0 ) { SKP_memset( rc_Q16, 0, order * sizeof( SKP_int32 ) ); return 0; } for( k = 0; k < order + 1; k++ ) { C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; } for( k = 0; k < order; k++ ) { /* Get reflection coefficient: divide two Q30 values and get result in Q31 */ rc_tmp_Q31 = SKP_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 ); /* Save the output */ rc_Q16[ k ] = SKP_RSHIFT_ROUND( rc_tmp_Q31, 15 ); /* Update correlations */ for( n = 0; n < order - k; n++ ) { Ctmp1_Q30 = C[ n + k + 1 ][ 0 ]; Ctmp2_Q30 = C[ n ][ 1 ]; /* Multiply and add the highest int32 */ C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + SKP_SMMUL( SKP_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 ); C[ n ][ 1 ] = Ctmp2_Q30 + SKP_SMMUL( SKP_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 ); } } return C[ 0 ][ 1 ]; } #endif ================================================ FILE: app/jni/SKP_Silk_shell_coder.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" /* shell coder; pulse-subframe length is hardcoded */ SKP_INLINE void combine_pulses( SKP_int *out, /* O: combined pulses vector [len] */ const SKP_int *in, /* I: input vector [2 * len] */ const SKP_int len /* I: number of OUTPUT samples */ ) { SKP_int k; for( k = 0; k < len; k++ ) { out[ k ] = in[ 2 * k ] + in[ 2 * k + 1 ]; } } SKP_INLINE void encode_split( SKP_Silk_range_coder_state *sRC, /* I/O: compressor data structure */ const SKP_int p_child1, /* I: pulse amplitude of first child subframe */ const SKP_int p, /* I: pulse amplitude of current subframe */ const SKP_uint16 *shell_table /* I: table of shell cdfs */ ) { const SKP_uint16 *cdf; if( p > 0 ) { cdf = &shell_table[ SKP_Silk_shell_code_table_offsets[ p ] ]; SKP_Silk_range_encoder( sRC, p_child1, cdf ); } } SKP_INLINE void decode_split( SKP_int *p_child1, /* O: pulse amplitude of first child subframe */ SKP_int *p_child2, /* O: pulse amplitude of second child subframe */ SKP_Silk_range_coder_state *sRC, /* I/O: compressor data structure */ const SKP_int p, /* I: pulse amplitude of current subframe */ const SKP_uint16 *shell_table /* I: table of shell cdfs */ ) { SKP_int cdf_middle; const SKP_uint16 *cdf; if( p > 0 ) { cdf_middle = SKP_RSHIFT( p, 1 ); cdf = &shell_table[ SKP_Silk_shell_code_table_offsets[ p ] ]; SKP_Silk_range_decoder( p_child1, sRC, cdf, cdf_middle ); p_child2[ 0 ] = p - p_child1[ 0 ]; } else { p_child1[ 0 ] = 0; p_child2[ 0 ] = 0; } } /* Shell encoder, operates on one shell code frame of 16 pulses */ void SKP_Silk_shell_encoder( SKP_Silk_range_coder_state *sRC, /* I/O compressor data structure */ const SKP_int *pulses0 /* I data: nonnegative pulse amplitudes */ ) { SKP_int pulses1[ 8 ], pulses2[ 4 ], pulses3[ 2 ], pulses4[ 1 ]; /* this function operates on one shell code frame of 16 pulses */ SKP_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); /* tree representation per pulse-subframe */ combine_pulses( pulses1, pulses0, 8 ); combine_pulses( pulses2, pulses1, 4 ); combine_pulses( pulses3, pulses2, 2 ); combine_pulses( pulses4, pulses3, 1 ); encode_split( sRC, pulses3[ 0 ], pulses4[ 0 ], SKP_Silk_shell_code_table3 ); encode_split( sRC, pulses2[ 0 ], pulses3[ 0 ], SKP_Silk_shell_code_table2 ); encode_split( sRC, pulses1[ 0 ], pulses2[ 0 ], SKP_Silk_shell_code_table1 ); encode_split( sRC, pulses0[ 0 ], pulses1[ 0 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses0[ 2 ], pulses1[ 1 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses1[ 2 ], pulses2[ 1 ], SKP_Silk_shell_code_table1 ); encode_split( sRC, pulses0[ 4 ], pulses1[ 2 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses0[ 6 ], pulses1[ 3 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses2[ 2 ], pulses3[ 1 ], SKP_Silk_shell_code_table2 ); encode_split( sRC, pulses1[ 4 ], pulses2[ 2 ], SKP_Silk_shell_code_table1 ); encode_split( sRC, pulses0[ 8 ], pulses1[ 4 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses0[ 10 ], pulses1[ 5 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses1[ 6 ], pulses2[ 3 ], SKP_Silk_shell_code_table1 ); encode_split( sRC, pulses0[ 12 ], pulses1[ 6 ], SKP_Silk_shell_code_table0 ); encode_split( sRC, pulses0[ 14 ], pulses1[ 7 ], SKP_Silk_shell_code_table0 ); } /* Shell decoder, operates on one shell code frame of 16 pulses */ void SKP_Silk_shell_decoder( SKP_int *pulses0, /* O data: nonnegative pulse amplitudes */ SKP_Silk_range_coder_state *sRC, /* I/O compressor data structure */ const SKP_int pulses4 /* I number of pulses per pulse-subframe */ ) { SKP_int pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ]; /* this function operates on one shell code frame of 16 pulses */ SKP_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); decode_split( &pulses3[ 0 ], &pulses3[ 1 ], sRC, pulses4, SKP_Silk_shell_code_table3 ); decode_split( &pulses2[ 0 ], &pulses2[ 1 ], sRC, pulses3[ 0 ], SKP_Silk_shell_code_table2 ); decode_split( &pulses1[ 0 ], &pulses1[ 1 ], sRC, pulses2[ 0 ], SKP_Silk_shell_code_table1 ); decode_split( &pulses0[ 0 ], &pulses0[ 1 ], sRC, pulses1[ 0 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses0[ 2 ], &pulses0[ 3 ], sRC, pulses1[ 1 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses1[ 2 ], &pulses1[ 3 ], sRC, pulses2[ 1 ], SKP_Silk_shell_code_table1 ); decode_split( &pulses0[ 4 ], &pulses0[ 5 ], sRC, pulses1[ 2 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses0[ 6 ], &pulses0[ 7 ], sRC, pulses1[ 3 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses2[ 2 ], &pulses2[ 3 ], sRC, pulses3[ 1 ], SKP_Silk_shell_code_table2 ); decode_split( &pulses1[ 4 ], &pulses1[ 5 ], sRC, pulses2[ 2 ], SKP_Silk_shell_code_table1 ); decode_split( &pulses0[ 8 ], &pulses0[ 9 ], sRC, pulses1[ 4 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses0[ 10 ], &pulses0[ 11 ], sRC, pulses1[ 5 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses1[ 6 ], &pulses1[ 7 ], sRC, pulses2[ 3 ], SKP_Silk_shell_code_table1 ); decode_split( &pulses0[ 12 ], &pulses0[ 13 ], sRC, pulses1[ 6 ], SKP_Silk_shell_code_table0 ); decode_split( &pulses0[ 14 ], &pulses0[ 15 ], sRC, pulses1[ 7 ], SKP_Silk_shell_code_table0 ); } ================================================ FILE: app/jni/SKP_Silk_sigm_Q15.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_sigm_Q15.c * * * * Approximate sigmoid function * * * * Copyright 2006 (c), Skype Limited * * Date: 060221 * * */ #include "SKP_Silk_SigProc_FIX.h" #if EMBEDDED_ARM<4 /********************************/ /* approximate sigmoid function */ /********************************/ /* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ static const SKP_int32 sigm_LUT_slope_Q10[ 6 ] = { 237, 153, 73, 30, 12, 7 }; /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ static const SKP_int32 sigm_LUT_pos_Q15[ 6 ] = { 16384, 23955, 28861, 31213, 32178, 32548 }; /* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ static const SKP_int32 sigm_LUT_neg_Q15[ 6 ] = { 16384, 8812, 3906, 1554, 589, 219 }; SKP_int SKP_Silk_sigm_Q15( SKP_int in_Q5 ) { SKP_int ind; if( in_Q5 < 0 ) { /* Negative input */ in_Q5 = -in_Q5; if( in_Q5 >= 6 * 32 ) { return 0; /* Clip */ } else { /* Linear interpolation of look up table */ ind = SKP_RSHIFT( in_Q5, 5 ); return( sigm_LUT_neg_Q15[ ind ] - SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); } } else { /* Positive input */ if( in_Q5 >= 6 * 32 ) { return 32767; /* clip */ } else { /* Linear interpolation of look up table */ ind = SKP_RSHIFT( in_Q5, 5 ); return( sigm_LUT_pos_Q15[ ind ] + SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); } } } #endif ================================================ FILE: app/jni/SKP_Silk_solve_LS_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #include "SKP_Silk_tuning_parameters.h" /*****************************/ /* Internal function headers */ /*****************************/ typedef struct { SKP_int32 Q36_part; SKP_int32 Q48_part; } inv_D_t; /* Factorize square matrix A into LDL form */ SKP_INLINE void SKP_Silk_LDL_factorize_FIX( SKP_int32 *A, /* I/O Pointer to Symetric Square Matrix */ SKP_int M, /* I Size of Matrix */ SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ ); /* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX( const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ SKP_int M, /* I Dim of Matrix equation */ const SKP_int32 *b, /* I b Vector */ SKP_int32 *x_Q16 /* O x Vector */ ); /* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ SKP_INLINE void SKP_Silk_LS_SolveLast_FIX( const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ const SKP_int M, /* I Dim of Matrix equation */ const SKP_int32 *b, /* I b Vector */ SKP_int32 *x_Q16 /* O x Vector */ ); SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX( SKP_int32 T[], /* I/O Numenator vector */ inv_D_t *inv_D, /* I 1 / D vector */ SKP_int M /* I dimension */ ); /* Solves Ax = b, assuming A is symmetric */ void SKP_Silk_solve_LDL_FIX( SKP_int32 *A, /* I Pointer to symetric square matrix A */ SKP_int M, /* I Size of matrix */ const SKP_int32 *b, /* I Pointer to b vector */ SKP_int32 *x_Q16 /* O Pointer to x solution vector */ ) { SKP_int32 L_Q16[ MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ]; SKP_int32 Y[ MAX_MATRIX_SIZE ]; inv_D_t inv_D[ MAX_MATRIX_SIZE ]; SKP_assert( M <= MAX_MATRIX_SIZE ); /*************************************************** Factorize A by LDL such that A = L*D*L', where L is lower triangular with ones on diagonal ****************************************************/ SKP_Silk_LDL_factorize_FIX( A, M, L_Q16, inv_D ); /**************************************************** * substitute D*L'*x = Y. ie: L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b ******************************************************/ SKP_Silk_LS_SolveFirst_FIX( L_Q16, M, b, Y ); /**************************************************** D*L'*x = Y <=> L'*x = inv(D)*Y, because D is diagonal just multiply with 1/d_i ****************************************************/ SKP_Silk_LS_divide_Q16_FIX( Y, inv_D, M ); /**************************************************** x = inv(L') * inv(D) * Y *****************************************************/ SKP_Silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 ); } SKP_INLINE void SKP_Silk_LDL_factorize_FIX( SKP_int32 *A, /* I Pointer to Symetric Square Matrix */ SKP_int M, /* I Size of Matrix */ SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ ) { SKP_int i, j, k, status, loop_count; const SKP_int32 *ptr1, *ptr2; SKP_int32 diag_min_value, tmp_32, err; SKP_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ]; SKP_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48; SKP_assert( M <= MAX_MATRIX_SIZE ); status = 1; diag_min_value = SKP_max_32( SKP_SMMUL( SKP_ADD_SAT32( A[ 0 ], A[ SKP_SMULBB( M, M ) - 1 ] ), SKP_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 ); for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) { status = 0; for( j = 0; j < M; j++ ) { ptr1 = matrix_adr( L_Q16, j, 0, M ); tmp_32 = 0; for( i = 0; i < j; i++ ) { v_Q0[ i ] = SKP_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */ tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */ } tmp_32 = SKP_SUB32( matrix_ptr( A, j, j, M ), tmp_32 ); if( tmp_32 < diag_min_value ) { tmp_32 = SKP_SUB32( SKP_SMULBB( loop_count + 1, diag_min_value ), tmp_32 ); /* Matrix not positive semi-definite, or ill conditioned */ for( i = 0; i < M; i++ ) { matrix_ptr( A, i, i, M ) = SKP_ADD32( matrix_ptr( A, i, i, M ), tmp_32 ); } status = 1; break; } D_Q0[ j ] = tmp_32; /* always < max(Correlation) */ /* two-step division */ one_div_diag_Q36 = SKP_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ one_div_diag_Q40 = SKP_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ err = SKP_SUB32( 1 << 24, SKP_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ one_div_diag_Q48 = SKP_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ /* Save 1/Ds */ inv_D[ j ].Q36_part = one_div_diag_Q36; inv_D[ j ].Q48_part = one_div_diag_Q48; matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */ ptr1 = matrix_adr( A, j, 0, M ); ptr2 = matrix_adr( L_Q16, j + 1, 0, M ); for( i = j + 1; i < M; i++ ) { tmp_32 = 0; for( k = 0; k < j; k++ ) { tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */ } tmp_32 = SKP_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */ /* tmp_32 / D_Q0[j] : Divide to Q16 */ matrix_ptr( L_Q16, i, j, M ) = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); /* go to next column */ ptr2 += M; } } } SKP_assert( status == 0 ); } SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX( SKP_int32 T[], /* I/O Numenator vector */ inv_D_t *inv_D, /* I 1 / D vector */ SKP_int M /* I Order */ ) { SKP_int i; SKP_int32 tmp_32; SKP_int32 one_div_diag_Q36, one_div_diag_Q48; for( i = 0; i < M; i++ ) { one_div_diag_Q36 = inv_D[ i ].Q36_part; one_div_diag_Q48 = inv_D[ i ].Q48_part; tmp_32 = T[ i ]; T[ i ] = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); } } /* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX( const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ SKP_int M, /* I Dim of Matrix equation */ const SKP_int32 *b, /* I b Vector */ SKP_int32 *x_Q16 /* O x Vector */ ) { SKP_int i, j; const SKP_int32 *ptr32; SKP_int32 tmp_32; for( i = 0; i < M; i++ ) { ptr32 = matrix_adr( L_Q16, i, 0, M ); tmp_32 = 0; for( j = 0; j < i; j++ ) { tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] ); } x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 ); } } /* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ SKP_INLINE void SKP_Silk_LS_SolveLast_FIX( const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ const SKP_int M, /* I Dim of Matrix equation */ const SKP_int32 *b, /* I b Vector */ SKP_int32 *x_Q16 /* O x Vector */ ) { SKP_int i, j; const SKP_int32 *ptr32; SKP_int32 tmp_32; for( i = M - 1; i >= 0; i-- ) { ptr32 = matrix_adr( L_Q16, 0, i, M ); tmp_32 = 0; for( j = M - 1; j > i; j-- ) { tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ SKP_SMULBB( j, M ) ], x_Q16[ j ] ); } x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 ); } } ================================================ FILE: app/jni/SKP_Silk_sort.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* Insertion sort (fast for already almost sorted arrays): */ /* Best case: O(n) for an already sorted array */ /* Worst case: O(n^2) for an inversely sorted array */ #include "SKP_Silk_SigProc_FIX.h" void SKP_Silk_insertion_sort_increasing( SKP_int32 *a, /* I/O: Unsorted / Sorted vector */ SKP_int *index, /* O: Index vector for the sorted elements */ const SKP_int L, /* I: Vector length */ const SKP_int K /* I: Number of correctly sorted output positions */ ) { SKP_int32 value; SKP_int i, j; /* Safety checks */ SKP_assert( K > 0 ); SKP_assert( L > 0 ); SKP_assert( L >= K ); /* Write start indices in index vector */ for( i = 0; i < K; i++ ) { index[ i ] = i; } /* Sort vector elements by value, increasing order */ for( i = 1; i < K; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ index[ j + 1 ] = index[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ index[ j + 1 ] = i; /* Write index */ } /* If less than L values are asked for, check the remaining values, */ /* but only spend CPU to ensure that the K first values are correct */ for( i = K; i < L; i++ ) { value = a[ i ]; if( value < a[ K - 1 ] ) { for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ index[ j + 1 ] = index[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ index[ j + 1 ] = i; /* Write index */ } } } void SKP_Silk_insertion_sort_decreasing_int16( SKP_int16 *a, /* I/O: Unsorted / Sorted vector */ SKP_int *index, /* O: Index vector for the sorted elements */ const SKP_int L, /* I: Vector length */ const SKP_int K /* I: Number of correctly sorted output positions */ ) { SKP_int i, j; SKP_int value; /* Safety checks */ SKP_assert( K > 0 ); SKP_assert( L > 0 ); SKP_assert( L >= K ); /* Write start indices in index vector */ for( i = 0; i < K; i++ ) { index[ i ] = i; } /* Sort vector elements by value, decreasing order */ for( i = 1; i < K; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ index[ j + 1 ] = index[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ index[ j + 1 ] = i; /* Write index */ } /* If less than L values are asked for, check the remaining values, */ /* but only spend CPU to ensure that the K first values are correct */ for( i = K; i < L; i++ ) { value = a[ i ]; if( value > a[ K - 1 ] ) { for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ index[ j + 1 ] = index[ j ]; /* Shift index */ } a[ j + 1 ] = value; /* Write value */ index[ j + 1 ] = i; /* Write index */ } } } void SKP_Silk_insertion_sort_increasing_all_values( SKP_int *a, /* I/O: Unsorted / Sorted vector */ const SKP_int L /* I: Vector length */ ) { SKP_int value; SKP_int i, j; /* Safety checks */ SKP_assert( L > 0 ); /* Sort vector elements by value, increasing order */ for( i = 1; i < L; i++ ) { value = a[ i ]; for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { a[ j + 1 ] = a[ j ]; /* Shift value */ } a[ j + 1 ] = value; /* Write value */ } } ================================================ FILE: app/jni/SKP_Silk_sum_sqr_shift.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * SKP_Silk_sum_sqr_shift.c * * * * compute number of bits to right shift the sum of squares of a vector * * of int16s to make it fit in an int32 * * * * Copyright 2006-2008 (c), Skype Limited * * */ #include "SKP_Silk_SigProc_FIX.h" #if (EMBEDDED_ARM<5) /* Compute number of bits to right shift the sum of squares of a vector */ /* of int16s to make it fit in an int32 */ void SKP_Silk_sum_sqr_shift( SKP_int32 *energy, /* O Energy of x, after shifting to the right */ SKP_int *shift, /* O Number of bits right shift applied to energy */ const SKP_int16 *x, /* I Input vector */ SKP_int len /* I Length of input vector */ ) { SKP_int i, shft; SKP_int32 in32, nrg_tmp, nrg; if( (SKP_int32)( (SKP_int_ptr_size)x & 2 ) != 0 ) { /* Input is not 4-byte aligned */ nrg = SKP_SMULBB( x[ 0 ], x[ 0 ] ); i = 1; } else { nrg = 0; i = 0; } shft = 0; len--; while( i < len ) { /* Load two values at once */ in32 = *( (SKP_int32 *)&x[ i ] ); nrg = SKP_SMLABB_ovflw( nrg, in32, in32 ); nrg = SKP_SMLATT_ovflw( nrg, in32, in32 ); i += 2; if( nrg < 0 ) { /* Scale down */ nrg = (SKP_int32)SKP_RSHIFT_uint( (SKP_uint32)nrg, 2 ); shft = 2; break; } } for( ; i < len; i += 2 ) { /* Load two values at once */ in32 = *( (SKP_int32 *)&x[ i ] ); nrg_tmp = SKP_SMULBB( in32, in32 ); nrg_tmp = SKP_SMLATT_ovflw( nrg_tmp, in32, in32 ); nrg = (SKP_int32)SKP_ADD_RSHIFT_uint( nrg, (SKP_uint32)nrg_tmp, shft ); if( nrg < 0 ) { /* Scale down */ nrg = (SKP_int32)SKP_RSHIFT_uint( (SKP_uint32)nrg, 2 ); shft += 2; } } if( i == len ) { /* One sample left to process */ nrg_tmp = SKP_SMULBB( x[ i ], x[ i ] ); nrg = (SKP_int32)SKP_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); } /* Make sure to have at least one extra leading zero (two leading zeros in total) */ if( nrg & 0xC0000000 ) { nrg = SKP_RSHIFT_uint( (SKP_uint32)nrg, 2 ); shft += 2; } /* Output arguments */ *shift = shft; *energy = nrg; } #endif ================================================ FILE: app/jni/SKP_Silk_tables_LTP.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_LTP_per_index_CDF[ 4 ] = { 0, 20992, 40788, 65535 }; const SKP_int SKP_Silk_LTP_per_index_CDF_offset = 1; const SKP_uint16 SKP_Silk_LTP_gain_CDF_0[ 11 ] = { 0, 49380, 54463, 56494, 58437, 60101, 61683, 62985, 64066, 64823, 65535 }; const SKP_uint16 SKP_Silk_LTP_gain_CDF_1[ 21 ] = { 0, 25290, 30654, 35710, 40386, 42937, 45250, 47459, 49411, 51348, 52974, 54517, 55976, 57423, 58865, 60285, 61667, 62895, 63827, 64724, 65535 }; const SKP_uint16 SKP_Silk_LTP_gain_CDF_2[ 41 ] = { 0, 4958, 9439, 13581, 17638, 21651, 25015, 28025, 30287, 32406, 34330, 36240, 38130, 39790, 41281, 42764, 44229, 45676, 47081, 48431, 49675, 50849, 51932, 52966, 53957, 54936, 55869, 56789, 57708, 58504, 59285, 60043, 60796, 61542, 62218, 62871, 63483, 64076, 64583, 65062, 65535 }; const SKP_int SKP_Silk_LTP_gain_CDF_offsets[ 3 ] = { 1, 3, 10 }; const SKP_int32 SKP_Silk_LTP_gain_middle_avg_RD_Q14 = 11010; const SKP_int16 SKP_Silk_LTP_gain_BITS_Q6_0[ 10 ] = { 26, 236, 321, 325, 339, 344, 362, 379, 412, 418 }; const SKP_int16 SKP_Silk_LTP_gain_BITS_Q6_1[ 20 ] = { 88, 231, 237, 244, 300, 309, 313, 324, 325, 341, 346, 351, 352, 352, 354, 356, 367, 393, 396, 406 }; const SKP_int16 SKP_Silk_LTP_gain_BITS_Q6_2[ 40 ] = { 238, 248, 255, 257, 258, 274, 284, 311, 317, 326, 326, 327, 339, 349, 350, 351, 352, 355, 358, 366, 371, 379, 383, 387, 388, 393, 394, 394, 407, 409, 412, 412, 413, 422, 426, 432, 434, 449, 454, 455 }; const SKP_uint16 * const SKP_Silk_LTP_gain_CDF_ptrs[ NB_LTP_CBKS ] = { SKP_Silk_LTP_gain_CDF_0, SKP_Silk_LTP_gain_CDF_1, SKP_Silk_LTP_gain_CDF_2 }; const SKP_int16 * const SKP_Silk_LTP_gain_BITS_Q6_ptrs[ NB_LTP_CBKS ] = { SKP_Silk_LTP_gain_BITS_Q6_0, SKP_Silk_LTP_gain_BITS_Q6_1, SKP_Silk_LTP_gain_BITS_Q6_2 }; const SKP_int16 SKP_Silk_LTP_gain_vq_0_Q14[ 10 ][ 5 ] = { { 594, 984, 2840, 1021, 669 }, { 10, 35, 304, -1, 23 }, { -694, 1923, 4603, 2975, 2335 }, { 2437, 3176, 3778, 1940, 481 }, { 214, -46, 7870, 4406, -521 }, { -896, 4818, 8501, 1623, -887 }, { -696, 3178, 6480, -302, 1081 }, { 517, 599, 1002, 567, 560 }, { -2075, -834, 4712, -340, 896 }, { 1435, -644, 3993, -612, -2063 } }; const SKP_int16 SKP_Silk_LTP_gain_vq_1_Q14[ 20 ][ 5 ] = { { 1655, 2918, 5001, 3010, 1775 }, { 113, 198, 856, 176, 178 }, { -843, 2479, 7858, 5371, 574 }, { 59, 5356, 7648, 2850, -315 }, { 3840, 4851, 6527, 1583, -1233 }, { 1620, 1760, 2330, 1876, 2045 }, { -545, 1854, 11792, 1547, -307 }, { -604, 689, 5369, 5074, 4265 }, { 521, -1331, 9829, 6209, -1211 }, { -1315, 6747, 9929, -1410, 546 }, { 117, -144, 2810, 1649, 5240 }, { 5392, 3476, 2425, -38, 633 }, { 14, -449, 5274, 3547, -171 }, { -98, 395, 9114, 1676, 844 }, { -908, 3843, 8861, -957, 1474 }, { 396, 6747, 5379, -329, 1269 }, { -335, 2830, 4281, 270, -54 }, { 1502, 5609, 8958, 6045, 2059 }, { -370, 479, 5267, 5726, 1174 }, { 5237, -1144, 6510, 455, 512 } }; const SKP_int16 SKP_Silk_LTP_gain_vq_2_Q14[ 40 ][ 5 ] = { { -278, 415, 9345, 7106, -431 }, { -1006, 3863, 9524, 4724, -871 }, { -954, 4624, 11722, 973, -300 }, { -117, 7066, 8331, 1959, -901 }, { 593, 3412, 6070, 4914, 1567 }, { 54, -51, 12618, 4228, -844 }, { 3157, 4822, 5229, 2313, 717 }, { -244, 1161, 14198, 779, 69 }, { -1218, 5603, 12894, -2301, 1001 }, { -132, 3960, 9526, 577, 1806 }, { -1633, 8815, 10484, -2452, 895 }, { 235, 450, 1243, 667, 437 }, { 959, -2630, 10897, 8772, -1852 }, { 2420, 2046, 8893, 4427, -1569 }, { 23, 7091, 8356, -1285, 1508 }, { -1133, 835, 7662, 6043, 2800 }, { 439, 391, 11016, 2253, 1362 }, { -1020, 2876, 13436, 4015, -3020 }, { 1060, -2690, 13512, 5565, -1394 }, { -1420, 8007, 11421, -152, -1672 }, { -893, 2895, 15434, -1490, 159 }, { -1054, 428, 12208, 8538, -3344 }, { 1772, -1304, 7593, 6185, 561 }, { 525, -1207, 6659, 11151, -1170 }, { 439, 2667, 4743, 2359, 5515 }, { 2951, 7432, 7909, -230, -1564 }, { -72, 2140, 5477, 1391, 1580 }, { 476, -1312, 15912, 2174, -1027 }, { 5737, 441, 2493, 2043, 2757 }, { 228, -43, 1803, 6663, 7064 }, { 4596, 9182, 1917, -200, 203 }, { -704, 12039, 5451, -1188, 542 }, { 1782, -1040, 10078, 7513, -2767 }, { -2626, 7747, 9019, 62, 1710 }, { 235, -233, 2954, 10921, 1947 }, { 10854, 2814, 1232, -111, 222 }, { 2267, 2778, 12325, 156, -1658 }, { -2950, 8095, 16330, 268, -3626 }, { 67, 2083, 7950, -80, -2432 }, { 518, -66, 1718, 415, 11435 } }; const SKP_int16 * const SKP_Silk_LTP_vq_ptrs_Q14[ NB_LTP_CBKS ] = { &SKP_Silk_LTP_gain_vq_0_Q14[ 0 ][ 0 ], &SKP_Silk_LTP_gain_vq_1_Q14[ 0 ][ 0 ], &SKP_Silk_LTP_gain_vq_2_Q14[ 0 ][ 0 ] }; const SKP_int SKP_Silk_LTP_vq_sizes[ NB_LTP_CBKS ] = { 10, 20, 40 }; ================================================ FILE: app/jni/SKP_Silk_tables_NLSF_CB0_10.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /**********************************************/ /* This file has been automatically generated */ /* */ /* ROM usage: 0.29 + 2.66 kB */ /**********************************************/ #include "SKP_Silk_structs.h" #include "SKP_Silk_tables_NLSF_CB0_10.h" #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ NLSF_MSVQ_CB0_10_VECTORS + NLSF_MSVQ_CB0_10_STAGES ] = { 0, 2658, 4420, 6107, 7757, 9408, 10955, 12502, 13983, 15432, 16882, 18331, 19750, 21108, 22409, 23709, 25010, 26256, 27501, 28747, 29965, 31158, 32351, 33544, 34736, 35904, 36997, 38091, 39185, 40232, 41280, 42327, 43308, 44290, 45271, 46232, 47192, 48132, 49032, 49913, 50775, 51618, 52462, 53287, 54095, 54885, 55675, 56449, 57222, 57979, 58688, 59382, 60076, 60726, 61363, 61946, 62505, 63052, 63543, 63983, 64396, 64766, 65023, 65279, 65535, 0, 4977, 9542, 14106, 18671, 23041, 27319, 31596, 35873, 39969, 43891, 47813, 51652, 55490, 59009, 62307, 65535, 0, 8571, 17142, 25529, 33917, 42124, 49984, 57844, 65535, 0, 8732, 17463, 25825, 34007, 42189, 50196, 58032, 65535, 0, 8948, 17704, 25733, 33762, 41791, 49821, 57678, 65535, 0, 4374, 8655, 12936, 17125, 21313, 25413, 29512, 33611, 37710, 41809, 45820, 49832, 53843, 57768, 61694, 65535 }; const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr[ NLSF_MSVQ_CB0_10_STAGES ] = { &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 0 ], &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 65 ], &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 82 ], &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 91 ], &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 100 ], &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 109 ] }; const SKP_int SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx[ NLSF_MSVQ_CB0_10_STAGES ] = { 23, 8, 5, 5, 5, 9 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ NLSF_MSVQ_CB0_10_VECTORS ] = { 148, 167, 169, 170, 170, 173, 173, 175, 176, 176, 176, 177, 179, 181, 181, 181, 183, 183, 183, 184, 185, 185, 185, 185, 186, 189, 189, 189, 191, 191, 191, 194, 194, 194, 195, 195, 196, 198, 199, 200, 201, 201, 202, 203, 204, 204, 205, 205, 206, 209, 210, 210, 213, 214, 218, 220, 221, 226, 231, 234, 239, 256, 256, 256, 119, 123, 123, 123, 125, 126, 126, 126, 128, 130, 130, 131, 131, 135, 138, 139, 94, 94, 95, 95, 96, 98, 98, 99, 93, 93, 95, 96, 96, 97, 98, 100, 92, 93, 97, 97, 97, 97, 98, 98, 125, 126, 126, 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, 130, 130, 131 }; const SKP_int SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min_Q15[ 10 + 1 ] = { 563, 3, 22, 20, 3, 3, 132, 119, 358, 86, 964 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * NLSF_MSVQ_CB0_10_VECTORS ] = { 2210, 4023, 6981, 9260, 12573, 15687, 19207, 22383, 25981, 29142, 3285, 4172, 6116, 10856, 15289, 16826, 19701, 22010, 24721, 29313, 1554, 2511, 6577, 10337, 13837, 16511, 20086, 23214, 26480, 29464, 3062, 4017, 5771, 10037, 13365, 14952, 20140, 22891, 25229, 29603, 2085, 3457, 5934, 8718, 11501, 13670, 17997, 21817, 24935, 28745, 2776, 4093, 6421, 10413, 15111, 16806, 20825, 23826, 26308, 29411, 2717, 4034, 5697, 8463, 14301, 16354, 19007, 23413, 25812, 28506, 2872, 3702, 5881, 11034, 17141, 18879, 21146, 23451, 25817, 29600, 2999, 4015, 7357, 11219, 12866, 17307, 20081, 22644, 26774, 29107, 2942, 3866, 5918, 11915, 13909, 16072, 20453, 22279, 27310, 29826, 2271, 3527, 6606, 9729, 12943, 17382, 20224, 22345, 24602, 28290, 2207, 3310, 5844, 9339, 11141, 15651, 18576, 21177, 25551, 28228, 3963, 4975, 6901, 11588, 13466, 15577, 19231, 21368, 25510, 27759, 2749, 3549, 6966, 13808, 15653, 17645, 20090, 22599, 26467, 28537, 2126, 3504, 5109, 9954, 12550, 14620, 19703, 21687, 26457, 29106, 3966, 5745, 7442, 9757, 14468, 16404, 19135, 23048, 25375, 28391, 3197, 4751, 6451, 9298, 13038, 14874, 17962, 20627, 23835, 28464, 3195, 4081, 6499, 12252, 14289, 16040, 18357, 20730, 26980, 29309, 1533, 2471, 4486, 7796, 12332, 15758, 19567, 22298, 25673, 29051, 2002, 2971, 4985, 8083, 13181, 15435, 18237, 21517, 24595, 28351, 3808, 4925, 6710, 10201, 12011, 14300, 18457, 20391, 26525, 28956, 2281, 3418, 4979, 8726, 15964, 18104, 20250, 22771, 25286, 28954, 3051, 5479, 7290, 9848, 12744, 14503, 18665, 23684, 26065, 28947, 2364, 3565, 5502, 9621, 14922, 16621, 19005, 20996, 26310, 29302, 4093, 5212, 6833, 9880, 16303, 18286, 20571, 23614, 26067, 29128, 2941, 3996, 6038, 10638, 12668, 14451, 16798, 19392, 26051, 28517, 3863, 5212, 7019, 9468, 11039, 13214, 19942, 22344, 25126, 29539, 4615, 6172, 7853, 10252, 12611, 14445, 19719, 22441, 24922, 29341, 3566, 4512, 6985, 8684, 10544, 16097, 18058, 22475, 26066, 28167, 4481, 5489, 7432, 11414, 13191, 15225, 20161, 22258, 26484, 29716, 3320, 4320, 6621, 9867, 11581, 14034, 21168, 23210, 26588, 29903, 3794, 4689, 6916, 8655, 10143, 16144, 19568, 21588, 27557, 29593, 2446, 3276, 5918, 12643, 16601, 18013, 21126, 23175, 27300, 29634, 2450, 3522, 5437, 8560, 15285, 19911, 21826, 24097, 26567, 29078, 2580, 3796, 5580, 8338, 9969, 12675, 18907, 22753, 25450, 29292, 3325, 4312, 6241, 7709, 9164, 14452, 21665, 23797, 27096, 29857, 3338, 4163, 7738, 11114, 12668, 14753, 16931, 22736, 25671, 28093, 3840, 4755, 7755, 13471, 15338, 17180, 20077, 22353, 27181, 29743, 2504, 4079, 8351, 12118, 15046, 18595, 21684, 24704, 27519, 29937, 5234, 6342, 8267, 11821, 15155, 16760, 20667, 23488, 25949, 29307, 2681, 3562, 6028, 10827, 18458, 20458, 22303, 24701, 26912, 29956, 3374, 4528, 6230, 8256, 9513, 12730, 18666, 20720, 26007, 28425, 2731, 3629, 8320, 12450, 14112, 16431, 18548, 22098, 25329, 27718, 3481, 4401, 7321, 9319, 11062, 13093, 15121, 22315, 26331, 28740, 3577, 4945, 6669, 8792, 10299, 12645, 19505, 24766, 26996, 29634, 4058, 5060, 7288, 10190, 11724, 13936, 15849, 18539, 26701, 29845, 4262, 5390, 7057, 8982, 10187, 15264, 20480, 22340, 25958, 28072, 3404, 4329, 6629, 7946, 10121, 17165, 19640, 22244, 25062, 27472, 3157, 4168, 6195, 9319, 10771, 13325, 15416, 19816, 24672, 27634, 2503, 3473, 5130, 6767, 8571, 14902, 19033, 21926, 26065, 28728, 4133, 5102, 7553, 10054, 11757, 14924, 17435, 20186, 23987, 26272, 4972, 6139, 7894, 9633, 11320, 14295, 21737, 24306, 26919, 29907, 2958, 3816, 6851, 9204, 10895, 18052, 20791, 23338, 27556, 29609, 5234, 6028, 8034, 10154, 11242, 14789, 18948, 20966, 26585, 29127, 5241, 6838, 10526, 12819, 14681, 17328, 19928, 22336, 26193, 28697, 3412, 4251, 5988, 7094, 9907, 18243, 21669, 23777, 26969, 29087, 2470, 3217, 7797, 15296, 17365, 19135, 21979, 24256, 27322, 29442, 4939, 5804, 8145, 11809, 13873, 15598, 17234, 19423, 26476, 29645, 5051, 6167, 8223, 9655, 12159, 17995, 20464, 22832, 26616, 28462, 4987, 5907, 9319, 11245, 13132, 15024, 17485, 22687, 26011, 28273, 5137, 6884, 11025, 14950, 17191, 19425, 21807, 24393, 26938, 29288, 7057, 7884, 9528, 10483, 10960, 14811, 19070, 21675, 25645, 28019, 6759, 7160, 8546, 11779, 12295, 13023, 16627, 21099, 24697, 28287, 3863, 9762, 11068, 11445, 12049, 13960, 18085, 21507, 25224, 28997, 397, 335, 651, 1168, 640, 765, 465, 331, 214, -194, -578, -647, -657, 750, 564, 613, 549, 630, 304, -52, 828, 922, 443, 111, 138, 124, 169, 14, 144, 83, 132, 58, -413, -752, 869, 336, 385, 69, 56, 830, -227, -266, -368, -440, -1195, 163, 126, -228, 802, 156, 188, 120, 376, 59, -358, -558, -1326, -254, -202, -789, 296, 92, -70, -129, -718, -1135, 292, -29, -631, 487, -157, -153, -279, 2, -419, -342, -34, -514, -799, -1571, -687, -609, -546, -130, -215, -252, -446, -574, -1337, 207, -72, 32, 103, -642, 942, 733, 187, 29, -211, -814, 143, 225, 20, 24, -268, -377, 1623, 1133, 667, 164, 307, 366, 187, 34, 62, -313, -832, -1482, -1181, 483, -42, -39, -450, -1406, -587, -52, -760, 334, 98, -60, -500, -488, -1058, 299, 131, -250, -251, -703, 1037, 568, -413, -265, 1687, 573, 345, 323, 98, 61, -102, 31, 135, 149, 617, 365, -39, 34, -611, 1201, 1421, 736, -414, -393, -492, -343, -316, -532, 528, 172, 90, 322, -294, -319, -541, 503, 639, 401, 1, -149, -73, -167, 150, 118, 308, 218, 121, 195, -143, -261, -1013, -802, 387, 436, 130, -427, -448, -681, 123, -87, -251, -113, 274, 310, 445, 501, 354, 272, 141, -285, 569, 656, 37, -49, 251, -386, -263, 1122, 604, 606, 336, 95, 34, 0, 85, 180, 207, -367, -622, 1070, -6, -79, -160, -92, -137, -276, -323, -371, -696, -1036, 407, 102, -86, -214, -482, -647, -28, -291, -97, -180, -250, -435, -18, -76, -332, 410, 407, 168, 539, 411, 254, 111, 58, -145, 200, 30, 187, 116, 131, -367, -475, 781, -559, 561, 195, -115, 8, -168, 30, 55, -122, 131, 82, -5, -273, -50, -632, 668, 4, 32, -26, -279, 315, 165, 197, 377, 155, -41, -138, -324, -109, -617, 360, 98, -53, -319, -114, -245, -82, 507, 468, 263, -137, -389, 652, 354, -18, -227, -462, -135, 317, 53, -16, 66, -72, -126, -356, -347, -328, -72, -337, 324, 152, 349, 169, -196, 179, 254, 260, 325, -74, -80, 75, -31, 270, 275, 87, 278, -446, -301, 309, 71, -25, -242, 516, 161, -162, -83, 329, 230, -311, -259, 177, -26, -462, 89, 257, 6, -130, -93, -456, -317, -221, -206, -417, -182, -74, 234, 48, 261, 359, 231, 258, 85, -282, 252, -147, -222, 251, -207, 443, 123, -417, -36, 273, -241, 240, -112, 44, -167, 126, -124, -77, 58, -401, 333, -118, 82, 126, 151, -433, 359, -130, -102, 131, -244, 86, 85, -462, 414, -240, 16, 145, 28, -205, -481, 373, 293, -72, -174, 62, 259, -8, -18, 362, 233, 185, 43, 278, 27, 193, 570, -248, 189, 92, 31, -275, -3, 243, 176, 438, 209, 206, -51, 79, 109, 168, -185, -308, -68, -618, 385, -310, -108, -164, 165, 61, -152, -101, -412, -268, -257, -40, -20, -28, -158, -301, 271, 380, -338, -367, -132, 64, 114, -131, -225, -156, -260, -63, -116, 155, -586, -202, 254, -287, 178, 227, -106, -294, 164, 298, -100, 185, 317, 193, -45, 28, 80, -87, -433, 22, -48, 48, -237, -229, -139, 120, -364, 268, -136, 396, 125, 130, -89, -272, 118, -256, -68, -451, 488, 143, -165, -48, -190, 106, 219, 47, 435, 245, 97, 75, -418, 121, -187, 570, -200, -351, 225, -21, -217, 234, -111, 194, 14, 242, 118, 140, -397, 355, 361, -45, -195 }; const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB0_10_Stage_info[ NLSF_MSVQ_CB0_10_STAGES ] = { { 64, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 0 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 0 ] }, { 16, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 64 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 64 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 80 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 80 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 88 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 88 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 96 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 96 ] }, { 16, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 104 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 104 ] } }; const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_10 = { NLSF_MSVQ_CB0_10_STAGES, SKP_Silk_NLSF_CB0_10_Stage_info, SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min_Q15, SKP_Silk_NLSF_MSVQ_CB0_10_CDF, SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr, SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx }; ================================================ FILE: app/jni/SKP_Silk_tables_NLSF_CB0_16.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /**********************************************/ /* This file has been automatically generated */ /* */ /* ROM usage: 0.51 + 7.38 kB */ /**********************************************/ #include "SKP_Silk_structs.h" #include "SKP_Silk_tables_NLSF_CB0_16.h" #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ NLSF_MSVQ_CB0_16_VECTORS + NLSF_MSVQ_CB0_16_STAGES ] = { 0, 1449, 2749, 4022, 5267, 6434, 7600, 8647, 9695, 10742, 11681, 12601, 13444, 14251, 15008, 15764, 16521, 17261, 18002, 18710, 19419, 20128, 20837, 21531, 22225, 22919, 23598, 24277, 24956, 25620, 26256, 26865, 27475, 28071, 28667, 29263, 29859, 30443, 31026, 31597, 32168, 32727, 33273, 33808, 34332, 34855, 35379, 35902, 36415, 36927, 37439, 37941, 38442, 38932, 39423, 39914, 40404, 40884, 41364, 41844, 42324, 42805, 43285, 43754, 44224, 44694, 45164, 45623, 46083, 46543, 46993, 47443, 47892, 48333, 48773, 49213, 49653, 50084, 50515, 50946, 51377, 51798, 52211, 52614, 53018, 53422, 53817, 54212, 54607, 55002, 55388, 55775, 56162, 56548, 56910, 57273, 57635, 57997, 58352, 58698, 59038, 59370, 59702, 60014, 60325, 60630, 60934, 61239, 61537, 61822, 62084, 62346, 62602, 62837, 63072, 63302, 63517, 63732, 63939, 64145, 64342, 64528, 64701, 64867, 65023, 65151, 65279, 65407, 65535, 0, 5099, 9982, 14760, 19538, 24213, 28595, 32976, 36994, 41012, 44944, 48791, 52557, 56009, 59388, 62694, 65535, 0, 9955, 19697, 28825, 36842, 44686, 52198, 58939, 65535, 0, 8949, 17335, 25720, 33926, 41957, 49987, 57845, 65535, 0, 9724, 18642, 26998, 35355, 43532, 51534, 59365, 65535, 0, 8750, 17499, 26249, 34448, 42471, 50494, 58178, 65535, 0, 8730, 17273, 25816, 34176, 42536, 50203, 57869, 65535, 0, 8769, 17538, 26307, 34525, 42742, 50784, 58319, 65535, 0, 8736, 17101, 25466, 33653, 41839, 50025, 57864, 65535, 0, 4368, 8735, 12918, 17100, 21283, 25465, 29558, 33651, 37744, 41836, 45929, 50022, 54027, 57947, 61782, 65535 }; const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr[ NLSF_MSVQ_CB0_16_STAGES ] = { &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 0 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 129 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 146 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 155 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 164 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 173 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 182 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 191 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 200 ], &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 209 ] }; const SKP_int SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx[ NLSF_MSVQ_CB0_16_STAGES ] = { 42, 8, 4, 5, 5, 5, 5, 5, 5, 9 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ NLSF_MSVQ_CB0_16_VECTORS ] = { 176, 181, 182, 183, 186, 186, 191, 191, 191, 196, 197, 201, 203, 206, 206, 206, 207, 207, 209, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 214, 216, 216, 217, 217, 217, 217, 218, 218, 219, 219, 220, 221, 222, 223, 223, 223, 223, 224, 224, 224, 225, 225, 226, 226, 226, 226, 227, 227, 227, 227, 227, 227, 228, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 231, 232, 232, 232, 232, 233, 234, 235, 235, 235, 236, 236, 236, 236, 237, 237, 237, 237, 240, 240, 240, 240, 241, 242, 243, 244, 244, 247, 247, 248, 248, 248, 249, 251, 255, 255, 256, 260, 260, 261, 264, 264, 266, 266, 268, 271, 274, 276, 279, 288, 288, 288, 288, 118, 120, 121, 121, 122, 125, 125, 129, 129, 130, 131, 132, 136, 137, 138, 145, 87, 88, 91, 97, 98, 100, 105, 106, 92, 95, 95, 96, 97, 97, 98, 99, 88, 92, 95, 95, 96, 97, 98, 109, 93, 93, 93, 96, 97, 97, 99, 101, 93, 94, 94, 95, 95, 99, 99, 99, 93, 93, 93, 96, 96, 97, 100, 102, 93, 95, 95, 96, 96, 96, 98, 99, 125, 125, 127, 127, 127, 127, 128, 128, 128, 128, 128, 128, 129, 130, 131, 132 }; const SKP_int SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min_Q15[ 16 + 1 ] = { 266, 3, 40, 3, 3, 16, 78, 89, 107, 141, 188, 146, 272, 240, 235, 215, 632 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * NLSF_MSVQ_CB0_16_VECTORS ] = { 1170, 2278, 3658, 5374, 7666, 9113, 11298, 13304, 15371, 17549, 19587, 21487, 23798, 26038, 28318, 30201, 1628, 2334, 4115, 6036, 7818, 9544, 11777, 14021, 15787, 17408, 19466, 21261, 22886, 24565, 26714, 28059, 1724, 2670, 4056, 6532, 8357, 10119, 12093, 14061, 16491, 18795, 20417, 22402, 24251, 26224, 28410, 29956, 1493, 3427, 4789, 6399, 8435, 10168, 12000, 14066, 16229, 18210, 20040, 22098, 24153, 26095, 28183, 30121, 1119, 2089, 4295, 6245, 8691, 10741, 12688, 15057, 17028, 18792, 20717, 22514, 24497, 26548, 28619, 30630, 1363, 2417, 3927, 5556, 7422, 9315, 11879, 13767, 16143, 18520, 20458, 22578, 24539, 26436, 28318, 30318, 1122, 2503, 5216, 7148, 9310, 11078, 13175, 14800, 16864, 18700, 20436, 22488, 24572, 26602, 28555, 30426, 600, 1317, 2970, 5609, 7694, 9784, 12169, 14087, 16379, 18378, 20551, 22686, 24739, 26697, 28646, 30355, 941, 1882, 4274, 5540, 8482, 9858, 11940, 14287, 16091, 18501, 20326, 22612, 24711, 26638, 28814, 30430, 635, 1699, 4376, 5948, 8097, 10115, 12274, 14178, 16111, 17813, 19695, 21773, 23927, 25866, 28022, 30134, 1408, 2222, 3524, 5615, 7345, 8849, 10989, 12772, 15352, 17026, 18919, 21062, 23329, 25215, 27209, 29023, 701, 1307, 3548, 6301, 7744, 9574, 11227, 12978, 15170, 17565, 19775, 22097, 24230, 26335, 28377, 30231, 1752, 2364, 4879, 6569, 7813, 9796, 11199, 14290, 15795, 18000, 20396, 22417, 24308, 26124, 28360, 30633, 901, 1629, 3356, 4635, 7256, 8767, 9971, 11558, 15215, 17544, 19523, 21852, 23900, 25978, 28133, 30184, 981, 1669, 3323, 4693, 6213, 8692, 10614, 12956, 15211, 17711, 19856, 22122, 24344, 26592, 28723, 30481, 1607, 2577, 4220, 5512, 8532, 10388, 11627, 13671, 15752, 17199, 19840, 21859, 23494, 25786, 28091, 30131, 811, 1471, 3144, 5041, 7430, 9389, 11174, 13255, 15157, 16741, 19583, 22167, 24115, 26142, 28383, 30395, 1543, 2144, 3629, 6347, 7333, 9339, 10710, 13596, 15099, 17340, 20102, 21886, 23732, 25637, 27818, 29917, 492, 1185, 2940, 5488, 7095, 8751, 11596, 13579, 16045, 18015, 20178, 22127, 24265, 26406, 28484, 30357, 1547, 2282, 3693, 6341, 7758, 9607, 11848, 13236, 16564, 18069, 19759, 21404, 24110, 26606, 28786, 30655, 685, 1338, 3409, 5262, 6950, 9222, 11414, 14523, 16337, 17893, 19436, 21298, 23293, 25181, 27973, 30520, 887, 1581, 3057, 4318, 7192, 8617, 10047, 13106, 16265, 17893, 20233, 22350, 24379, 26384, 28314, 30189, 2285, 3745, 5662, 7576, 9323, 11320, 13239, 15191, 17175, 19225, 21108, 22972, 24821, 26655, 28561, 30460, 1496, 2108, 3448, 6898, 8328, 9656, 11252, 12823, 14979, 16482, 18180, 20085, 22962, 25160, 27705, 29629, 575, 1261, 3861, 6627, 8294, 10809, 12705, 14768, 17076, 19047, 20978, 23055, 24972, 26703, 28720, 30345, 1682, 2213, 3882, 6238, 7208, 9646, 10877, 13431, 14805, 16213, 17941, 20873, 23550, 25765, 27756, 29461, 888, 1616, 3924, 5195, 7206, 8647, 9842, 11473, 16067, 18221, 20343, 22774, 24503, 26412, 28054, 29731, 805, 1454, 2683, 4472, 7936, 9360, 11398, 14345, 16205, 17832, 19453, 21646, 23899, 25928, 28387, 30463, 1640, 2383, 3484, 5082, 6032, 8606, 11640, 12966, 15842, 17368, 19346, 21182, 23638, 25889, 28368, 30299, 1632, 2204, 4510, 7580, 8718, 10512, 11962, 14096, 15640, 17194, 19143, 22247, 24563, 26561, 28604, 30509, 2043, 2612, 3985, 6851, 8038, 9514, 10979, 12789, 15426, 16728, 18899, 20277, 22902, 26209, 28711, 30618, 2224, 2798, 4465, 5320, 7108, 9436, 10986, 13222, 14599, 18317, 20141, 21843, 23601, 25700, 28184, 30582, 835, 1541, 4083, 5769, 7386, 9399, 10971, 12456, 15021, 18642, 20843, 23100, 25292, 26966, 28952, 30422, 1795, 2343, 4809, 5896, 7178, 8545, 10223, 13370, 14606, 16469, 18273, 20736, 23645, 26257, 28224, 30390, 1734, 2254, 4031, 5188, 6506, 7872, 9651, 13025, 14419, 17305, 19495, 22190, 24403, 26302, 28195, 30177, 1841, 2349, 3968, 4764, 6376, 9825, 11048, 13345, 14682, 16252, 18183, 21363, 23918, 26156, 28031, 29935, 1432, 2047, 5631, 6927, 8198, 9675, 11358, 13506, 14802, 16419, 18339, 22019, 24124, 26177, 28130, 30586, 1730, 2320, 3744, 4808, 6007, 9666, 10997, 13622, 15234, 17495, 20088, 22002, 23603, 25400, 27379, 29254, 1267, 1915, 5483, 6812, 8229, 9919, 11589, 13337, 14747, 17965, 20552, 22167, 24519, 26819, 28883, 30642, 1526, 2229, 4240, 7388, 8953, 10450, 11899, 13718, 16861, 18323, 20379, 22672, 24797, 26906, 28906, 30622, 2175, 2791, 4104, 6875, 8612, 9798, 12152, 13536, 15623, 17682, 19213, 21060, 24382, 26760, 28633, 30248, 454, 1231, 4339, 5738, 7550, 9006, 10320, 13525, 16005, 17849, 20071, 21992, 23949, 26043, 28245, 30175, 2250, 2791, 4230, 5283, 6762, 10607, 11879, 13821, 15797, 17264, 20029, 22266, 24588, 26437, 28244, 30419, 1696, 2216, 4308, 8385, 9766, 11030, 12556, 14099, 16322, 17640, 19166, 20590, 23967, 26858, 28798, 30562, 2452, 3236, 4369, 6118, 7156, 9003, 11509, 12796, 15749, 17291, 19491, 22241, 24530, 26474, 28273, 30073, 1811, 2541, 3555, 5480, 9123, 10527, 11894, 13659, 15262, 16899, 19366, 21069, 22694, 24314, 27256, 29983, 1553, 2246, 4559, 5500, 6754, 7874, 11739, 13571, 15188, 17879, 20281, 22510, 24614, 26649, 28786, 30755, 1982, 2768, 3834, 5964, 8732, 9908, 11797, 14813, 16311, 17946, 21097, 22851, 24456, 26304, 28166, 29755, 1824, 2529, 3817, 5449, 6854, 8714, 10381, 12286, 14194, 15774, 19524, 21374, 23695, 26069, 28096, 30212, 2212, 2854, 3947, 5898, 9930, 11556, 12854, 14788, 16328, 17700, 20321, 22098, 23672, 25291, 26976, 28586, 2023, 2599, 4024, 4916, 6613, 11149, 12457, 14626, 16320, 17822, 19673, 21172, 23115, 26051, 28825, 30758, 1628, 2206, 3467, 4364, 8679, 10173, 11864, 13679, 14998, 16938, 19207, 21364, 23850, 26115, 28124, 30273, 2014, 2603, 4114, 7254, 8516, 10043, 11822, 13503, 16329, 17826, 19697, 21280, 23151, 24661, 26807, 30161, 2376, 2980, 4422, 5770, 7016, 9723, 11125, 13516, 15485, 16985, 19160, 20587, 24401, 27180, 29046, 30647, 2454, 3502, 4624, 6019, 7632, 8849, 10792, 13964, 15523, 17085, 19611, 21238, 22856, 25108, 28106, 29890, 1573, 2274, 3308, 5999, 8977, 10104, 12457, 14258, 15749, 18180, 19974, 21253, 23045, 25058, 27741, 30315, 1943, 2730, 4140, 6160, 7491, 8986, 11309, 12775, 14820, 16558, 17909, 19757, 21512, 23605, 27274, 29527, 2021, 2582, 4494, 5835, 6993, 8245, 9827, 14733, 16462, 17894, 19647, 21083, 23764, 26667, 29072, 30990, 1052, 1775, 3218, 4378, 7666, 9403, 11248, 13327, 14972, 17962, 20758, 22354, 25071, 27209, 29001, 30609, 2218, 2866, 4223, 5352, 6581, 9980, 11587, 13121, 15193, 16583, 18386, 20080, 22013, 25317, 28127, 29880, 2146, 2840, 4397, 5840, 7449, 8721, 10512, 11936, 13595, 17253, 19310, 20891, 23417, 25627, 27749, 30231, 1972, 2619, 3756, 6367, 7641, 8814, 12286, 13768, 15309, 18036, 19557, 20904, 22582, 24876, 27800, 30440, 2005, 2577, 4272, 7373, 8558, 10223, 11770, 13402, 16502, 18000, 19645, 21104, 22990, 26806, 29505, 30942, 1153, 1822, 3724, 5443, 6990, 8702, 10289, 11899, 13856, 15315, 17601, 21064, 23692, 26083, 28586, 30639, 1304, 1869, 3318, 7195, 9613, 10733, 12393, 13728, 15822, 17474, 18882, 20692, 23114, 25540, 27684, 29244, 2093, 2691, 4018, 6658, 7947, 9147, 10497, 11881, 15888, 17821, 19333, 21233, 23371, 25234, 27553, 29998, 575, 1331, 5304, 6910, 8425, 10086, 11577, 13498, 16444, 18527, 20565, 22847, 24914, 26692, 28759, 30157, 1435, 2024, 3283, 4156, 7611, 10592, 12049, 13927, 15459, 18413, 20495, 22270, 24222, 26093, 28065, 30099, 1632, 2168, 5540, 7478, 8630, 10391, 11644, 14321, 15741, 17357, 18756, 20434, 22799, 26060, 28542, 30696, 1407, 2245, 3405, 5639, 9419, 10685, 12104, 13495, 15535, 18357, 19996, 21689, 24351, 26550, 28853, 30564, 1675, 2226, 4005, 8223, 9975, 11155, 12822, 14316, 16504, 18137, 19574, 21050, 22759, 24912, 28296, 30634, 1080, 1614, 3622, 7565, 8748, 10303, 11713, 13848, 15633, 17434, 19761, 21825, 23571, 25393, 27406, 29063, 1693, 2229, 3456, 4354, 5670, 10890, 12563, 14167, 15879, 17377, 19817, 21971, 24094, 26131, 28298, 30099, 2042, 2959, 4195, 5740, 7106, 8267, 11126, 14973, 16914, 18295, 20532, 21982, 23711, 25769, 27609, 29351, 984, 1612, 3808, 5265, 6885, 8411, 9547, 10889, 12522, 16520, 19549, 21639, 23746, 26058, 28310, 30374, 2036, 2538, 4166, 7761, 9146, 10412, 12144, 13609, 15588, 17169, 18559, 20113, 21820, 24313, 28029, 30612, 1871, 2355, 4061, 5143, 7464, 10129, 11941, 15001, 16680, 18354, 19957, 22279, 24861, 26872, 28988, 30615, 2566, 3161, 4643, 6227, 7406, 9970, 11618, 13416, 15889, 17364, 19121, 20817, 22592, 24720, 28733, 31082, 1700, 2327, 4828, 5939, 7567, 9154, 11087, 12771, 14209, 16121, 20222, 22671, 24648, 26656, 28696, 30745, 3169, 3873, 5046, 6868, 8184, 9480, 12335, 14068, 15774, 17971, 20231, 21711, 23520, 25245, 27026, 28730, 1564, 2391, 4229, 6730, 8905, 10459, 13026, 15033, 17265, 19809, 21849, 23741, 25490, 27312, 29061, 30527, 2864, 3559, 4719, 6441, 9592, 11055, 12763, 14784, 16428, 18164, 20486, 22262, 24183, 26263, 28383, 30224, 2673, 3449, 4581, 5983, 6863, 8311, 12464, 13911, 15738, 17791, 19416, 21182, 24025, 26561, 28723, 30440, 2419, 3049, 4274, 6384, 8564, 9661, 11288, 12676, 14447, 17578, 19816, 21231, 23099, 25270, 26899, 28926, 1278, 2001, 3000, 5353, 9995, 11777, 13018, 14570, 16050, 17762, 19982, 21617, 23371, 25083, 27656, 30172, 932, 1624, 2798, 4570, 8592, 9988, 11552, 13050, 16921, 18677, 20415, 22810, 24817, 26819, 28804, 30385, 2324, 2973, 4156, 5702, 6919, 8806, 10259, 12503, 15015, 16567, 19418, 21375, 22943, 24550, 27024, 29849, 1564, 2373, 3455, 4907, 5975, 7436, 11786, 14505, 16107, 18148, 20019, 21653, 23740, 25814, 28578, 30372, 3025, 3729, 4866, 6520, 9487, 10943, 12358, 14258, 16174, 17501, 19476, 21408, 23227, 24906, 27347, 29407, 1270, 1965, 6802, 7995, 9204, 10828, 12507, 14230, 15759, 17860, 20369, 22502, 24633, 26514, 28535, 30525, 2210, 2749, 4266, 7487, 9878, 11018, 12823, 14431, 16247, 18626, 20450, 22054, 23739, 25291, 27074, 29169, 1275, 1926, 4330, 6573, 8441, 10920, 13260, 15008, 16927, 18573, 20644, 22217, 23983, 25474, 27372, 28645, 3015, 3670, 5086, 6372, 7888, 9309, 10966, 12642, 14495, 16172, 18080, 19972, 22454, 24899, 27362, 29975, 2882, 3733, 5113, 6482, 8125, 9685, 11598, 13288, 15405, 17192, 20178, 22426, 24801, 27014, 29212, 30811, 2300, 2968, 4101, 5442, 6327, 7910, 12455, 13862, 15747, 17505, 19053, 20679, 22615, 24658, 27499, 30065, 2257, 2940, 4430, 5991, 7042, 8364, 9414, 11224, 15723, 17420, 19253, 21469, 23915, 26053, 28430, 30384, 1227, 2045, 3818, 5011, 6990, 9231, 11024, 13011, 17341, 19017, 20583, 22799, 25195, 26876, 29351, 30805, 1354, 1924, 3789, 8077, 10453, 11639, 13352, 14817, 16743, 18189, 20095, 22014, 24593, 26677, 28647, 30256, 3142, 4049, 6197, 7417, 8753, 10156, 11533, 13181, 15947, 17655, 19606, 21402, 23487, 25659, 28123, 30304, 1317, 2263, 4725, 7611, 9667, 11634, 14143, 16258, 18724, 20698, 22379, 24007, 25775, 27251, 28930, 30593, 1570, 2323, 3818, 6215, 9893, 11556, 13070, 14631, 16152, 18290, 21386, 23346, 25114, 26923, 28712, 30168, 2297, 3905, 6287, 8558, 10668, 12766, 15019, 17102, 19036, 20677, 22341, 23871, 25478, 27085, 28851, 30520, 1915, 2507, 4033, 5749, 7059, 8871, 10659, 12198, 13937, 15383, 16869, 18707, 23175, 25818, 28514, 30501, 2404, 2918, 5190, 6252, 7426, 9887, 12387, 14795, 16754, 18368, 20338, 22003, 24236, 26456, 28490, 30397, 1621, 2227, 3479, 5085, 9425, 12892, 14246, 15652, 17205, 18674, 20446, 22209, 23778, 25867, 27931, 30093, 1869, 2390, 4105, 7021, 11221, 12775, 14059, 15590, 17024, 18608, 20595, 22075, 23649, 25154, 26914, 28671, 2551, 3252, 4688, 6562, 7869, 9125, 10475, 11800, 15402, 18780, 20992, 22555, 24289, 25968, 27465, 29232, 2705, 3493, 4735, 6360, 7905, 9352, 11538, 13430, 15239, 16919, 18619, 20094, 21800, 23342, 25200, 29257, 2166, 2791, 4011, 5081, 5896, 9038, 13407, 14703, 16543, 18189, 19896, 21857, 24872, 26971, 28955, 30514, 1865, 3021, 4696, 6534, 8343, 9914, 12789, 14103, 16533, 17729, 21340, 22439, 24873, 26330, 28428, 30154, 3369, 4345, 6573, 8763, 10309, 11713, 13367, 14784, 16483, 18145, 19839, 21247, 23292, 25477, 27555, 29447, 1265, 2184, 5443, 7893, 10591, 13139, 15105, 16639, 18402, 19826, 21419, 22995, 24719, 26437, 28363, 30125, 1584, 2004, 3535, 4450, 8662, 10764, 12832, 14978, 16972, 18794, 20932, 22547, 24636, 26521, 28701, 30567, 3419, 4528, 6602, 7890, 9508, 10875, 12771, 14357, 16051, 18330, 20630, 22490, 25070, 26936, 28946, 30542, 1726, 2252, 4597, 6950, 8379, 9823, 11363, 12794, 14306, 15476, 16798, 18018, 21671, 25550, 28148, 30367, 3385, 3870, 5307, 6388, 7141, 8684, 12695, 14939, 16480, 18277, 20537, 22048, 23947, 25965, 28214, 29956, 2771, 3306, 4450, 5560, 6453, 9493, 13548, 14754, 16743, 18447, 20028, 21736, 23746, 25353, 27141, 29066, 3028, 3900, 6617, 7893, 9211, 10480, 12047, 13583, 15182, 16662, 18502, 20092, 22190, 24358, 26302, 28957, 2000, 2550, 4067, 6837, 9628, 11002, 12594, 14098, 15589, 17195, 18679, 20099, 21530, 23085, 24641, 29022, 2844, 3302, 5103, 6107, 6911, 8598, 12416, 14054, 16026, 18567, 20672, 22270, 23952, 25771, 27658, 30026, 4043, 5150, 7268, 9056, 10916, 12638, 14543, 16184, 17948, 19691, 21357, 22981, 24825, 26591, 28479, 30233, 2109, 2625, 4320, 5525, 7454, 10220, 12980, 14698, 17627, 19263, 20485, 22381, 24279, 25777, 27847, 30458, 1550, 2667, 6473, 9496, 10985, 12352, 13795, 15233, 17099, 18642, 20461, 22116, 24197, 26291, 28403, 30132, 2411, 3084, 4145, 5394, 6367, 8154, 13125, 16049, 17561, 19125, 21258, 22762, 24459, 26317, 28255, 29702, 4159, 4516, 5956, 7635, 8254, 8980, 11208, 14133, 16210, 17875, 20196, 21864, 23840, 25747, 28058, 30012, 2026, 2431, 2845, 3618, 7950, 9802, 12721, 14460, 16576, 18984, 21376, 23319, 24961, 26718, 28971, 30640, 3429, 3833, 4472, 4912, 7723, 10386, 12981, 15322, 16699, 18807, 20778, 22551, 24627, 26494, 28334, 30482, 4740, 5169, 5796, 6485, 6998, 8830, 11777, 14414, 16831, 18413, 20789, 22369, 24236, 25835, 27807, 30021, 150, 168, -17, -107, -142, -229, -320, -406, -503, -620, -867, -935, -902, -680, -398, -114, -398, -355, 49, 255, 114, 260, 399, 264, 317, 431, 514, 531, 435, 356, 238, 106, -43, -36, -169, -224, -391, -633, -776, -970, -844, -455, -181, -12, 85, 85, 164, 195, 122, 85, -158, -640, -903, 9, 7, -124, 149, 32, 220, 369, 242, 115, 79, 84, -146, -216, -70, 1024, 751, 574, 440, 377, 352, 203, 30, 16, -3, 81, 161, 100, -148, -176, 933, 750, 404, 171, -2, -146, -411, -442, -541, -552, -442, -269, -240, -52, 603, 635, 405, 178, 215, 19, -153, -167, -290, -219, 151, 271, 151, 119, 303, 266, 100, 69, -293, -657, 939, 659, 442, 351, 132, 98, -16, -1, -135, -200, -223, -89, 167, 154, 172, 237, -45, -183, -228, -486, 263, 608, 158, -125, -390, -227, -118, 43, -457, -392, -769, -840, 20, -117, -194, -189, -173, -173, -33, 32, 174, 144, 115, 167, 57, 44, 14, 147, 96, -54, -142, -129, -254, -331, 304, 310, -52, -419, -846, -1060, -88, -123, -202, -343, -554, -961, -951, 327, 159, 81, 255, 227, 120, 203, 256, 192, 164, 224, 290, 195, 216, 209, 128, 832, 1028, 889, 698, 504, 408, 355, 218, 32, -115, -84, -276, -100, -312, -484, 899, 682, 465, 456, 241, -12, -275, -425, -461, -367, -33, -28, -102, -194, -527, 863, 906, 463, 245, 13, -212, -305, -105, 163, 279, 176, 93, 67, 115, 192, 61, -50, -132, -175, -224, -271, -629, -252, 1158, 972, 638, 280, 300, 326, 143, -152, -214, -287, 53, -42, -236, -352, -423, -248, -129, -163, -178, -119, 85, 57, 514, 382, 374, 402, 424, 423, 271, 197, 97, 40, 39, -97, -191, -164, -230, -256, -410, 396, 327, 127, 10, -119, -167, -291, -274, -141, -99, -226, -218, -139, -224, -209, -268, -442, -413, 222, 58, 521, 344, 258, 76, -42, -142, -165, -123, -92, 47, 8, -3, -191, -11, -164, -167, -351, -740, 311, 538, 291, 184, 29, -105, 9, -30, -54, -17, -77, -271, -412, -622, -648, 476, 186, -66, -197, -73, -94, -15, 47, 28, 112, -58, -33, 65, 19, 84, 86, 276, 114, 472, 786, 799, 625, 415, 178, -35, -26, 5, 9, 83, 39, 37, 39, -184, -374, -265, -362, -501, 337, 716, 478, -60, -125, -163, 362, 17, -122, -233, 279, 138, 157, 318, 193, 189, 209, 266, 252, -46, -56, -277, -429, 464, 386, 142, 44, -43, 66, 264, 182, 47, 14, -26, -79, 49, 15, -128, -203, -400, -478, 325, 27, 234, 411, 205, 129, 12, 58, 123, 57, 171, 137, 96, 128, -32, 134, -12, 57, 119, 26, -22, -165, -500, -701, -528, -116, 64, -8, 97, -9, -162, -66, -156, -194, -303, -546, -341, 546, 358, 95, 45, 76, 270, 403, 205, 100, 123, 50, -53, -144, -110, -13, 32, -228, -130, 353, 296, 56, -372, -253, 365, 73, 10, -34, -139, -191, -96, 5, 44, -85, -179, -129, -192, -246, -85, -110, -155, -44, -27, 145, 138, 79, 32, -148, -577, -634, 191, 94, -9, -35, -77, -84, -56, -171, -298, -271, -243, -156, -328, -235, -76, -128, -121, 129, 13, -22, 32, 45, -248, -65, 193, -81, 299, 57, -147, 192, -165, -354, -334, -106, -156, -40, -3, -68, 124, -257, 78, 124, 170, 412, 227, 105, -104, 12, 154, 250, 274, 258, 4, -27, 235, 152, 51, 338, 300, 7, -314, -411, 215, 170, -9, -93, -77, 76, 67, 54, 200, 315, 163, 72, -91, -402, 158, 187, -156, -91, 290, 267, 167, 91, 140, 171, 112, 9, -42, -177, -440, 385, 80, 15, 172, 129, 41, -129, -372, -24, -75, -30, -170, 10, -118, 57, 78, -101, 232, 161, 123, 256, 277, 101, -192, -629, -100, -60, -232, 66, 13, -13, -80, -239, 239, 37, 32, 89, -319, -579, 450, 360, 3, -29, -299, -89, -54, -110, -246, -164, 6, -188, 338, 176, -92, 197, 137, 134, 12, -2, 56, -183, 114, -36, -131, -204, 75, -25, -174, 191, -15, -290, -429, -267, 79, 37, 106, 23, -384, 425, 70, -14, 212, 105, 15, -2, -42, -37, -123, 108, 28, -48, 193, 197, 173, -33, 37, 73, -57, 256, 137, -58, -430, -228, 217, -51, -10, -58, -6, 22, 104, 61, -119, 169, 144, 16, -46, -394, 60, 454, -80, -298, -65, 25, 0, -24, -65, -417, 465, 276, -3, -194, -13, 130, 19, -6, -21, -24, -180, -53, -85, 20, 118, 147, 113, -75, -289, 226, -122, 227, 270, 125, 109, 197, 125, 138, 44, 60, 25, -55, -167, -32, -139, -193, -173, -316, 287, -208, 253, 239, 27, -80, -188, -28, -182, -235, 156, -117, 128, -48, -58, -226, 172, 181, 167, 19, 62, 10, 2, 181, 151, 108, -16, -11, -78, -331, 411, 133, 17, 104, 64, -184, 24, -30, -3, -283, 121, 204, -8, -199, -21, -80, -169, -157, -191, -136, 81, 155, 14, -131, 244, 74, -57, -47, -280, 347, 111, -77, -128, -142, -194, -125, -6, -68, 91, 1, 23, 14, -154, -34, 23, -38, -343, 503, 146, -38, -46, -41, 58, 31, 63, -48, -117, 45, 28, 1, -89, -5, -44, -29, -448, 487, 204, 81, 46, -106, -302, 380, 120, -38, -12, -39, 70, -3, 25, -65, 30, -11, 34, -15, 22, -115, 0, -79, -83, 45, 114, 43, 150, 36, 233, 149, 195, 5, 25, -52, -475, 274, 28, -39, -8, -66, -255, 258, 56, 143, -45, -190, 165, -60, 20, 2, 125, -129, 51, -8, -335, 288, 38, 59, 25, -42, 23, -118, -112, 11, -55, -133, -109, 24, -105, 78, -64, -245, 202, -65, -127, 162, 40, -94, 89, -85, -119, -103, 97, 9, -70, -28, 194, 86, -112, -92, -114, 74, -49, 46, -84, -178, 113, 52, -205, 333, 88, 222, 56, -55, 13, 86, 4, -77, 224, 114, -105, 112, 125, -29, -18, -144, 22, -58, -99, 28, 114, -66, -32, -169, -314, 285, 72, -74, 179, 28, -79, -182, 13, -55, 147, 13, 12, -54, 31, -84, -17, -75, -228, 83, -375, 436, 110, -63, -27, -136, 169, -56, -8, -171, 184, -42, 148, 68, 204, 235, 110, -229, 91, 171, -43, -3, -26, -99, -111, 71, -170, 202, -67, 181, -37, 109, -120, 3, -55, -260, -16, 152, 91, 142, 42, 44, 134, 47, 17, -35, 22, 79, -169, 41, 46, 277, -93, -49, -126, 37, -103, -34, -22, -90, -134, -205, 92, -9, 1, -195, -239, 45, 54, 18, -23, -1, -80, -98, -20, -261, 306, 72, 20, -89, -217, 11, 6, -82, 89, 13, -129, -89, 83, -71, -55, 130, -98, -146, -27, -57, 53, 275, 17, 170, -5, -54, 132, -64, 72, 160, -125, -168, 72, 40, 170, 78, 248, 116, 20, 84, 31, -34, 190, 38, 13, -106, 225, 27, -168, 24, -157, -122, 165, 11, -161, -213, -12, -51, -101, 42, 101, 27, 55, 111, 75, 71, -96, -1, 65, -277, 393, -26, -44, -68, -84, -66, -95, 235, 179, -25, -41, 27, -91, -128, -222, 146, -72, -30, -24, 55, -126, -68, -58, -127, 13, -97, -106, 174, -100, 155, 101, -146, -21, 261, 22, 38, -66, 65, 4, 70, 64, 144, 59, 213, 71, -337, 303, -52, 51, -56, 1, 10, -15, -5, 34, 52, 228, 131, 161, -127, -214, 238, 123, 64, -147, -50, -34, -127, 204, 162, 85, 41, 5, -140, 73, -150, 56, -96, -66, -20, 2, -235, 59, -22, -107, 150, -16, -47, -4, 81, -67, 167, 149, 149, -157, 288, -156, -27, -8, 18, 83, -24, -41, -167, 158, -100, 93, 53, 201, 15, 42, 266, 278, -12, -6, -37, 85, 6, 20, -188, -271, 107, -13, -80, 51, 202, 173, -69, 78, -188, 46, 4, 153, 12, -138, 169, 5, -58, -123, -108, -243, 150, 10, -191, 246, -15, 38, 25, -10, 14, 61, 50, -206, -215, -220, 90, 5, -149, -219, 56, 142, 24, -376, 77, -80, 75, 6, 42, -101, 16, 56, 14, -57, 3, -17, 80, 57, -36, 88, -59, -97, -19, -148, 46, -219, 226, 114, -4, -72, -15, 37, -49, -28, 247, 44, 123, 47, -122, -38, 17, 4, -113, -32, -224, 154, -134, 196, 71, -267, -85, 28, -70, 89, -120, 99, -2, 64, 76, -166, -48, 189, -35, -92, -169, -123, 339, 38, -25, 38, -35, 225, -139, -50, -63, 246, 60, -185, -109, -49, -53, -167, 51, 149, 60, -101, -33, 25, -76, 120, 32, -30, -83, 102, 91, -186, -261, 131, -197 }; const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB0_16_Stage_info[ NLSF_MSVQ_CB0_16_STAGES ] = { { 128, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 0 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 0 ] }, { 16, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 128 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 128 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 144 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 144 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 152 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 152 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 160 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 160 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 168 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 168 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 176 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 176 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 184 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 184 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 192 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 192 ] }, { 16, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 200 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 200 ] } }; const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_16 = { NLSF_MSVQ_CB0_16_STAGES, SKP_Silk_NLSF_CB0_16_Stage_info, SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min_Q15, SKP_Silk_NLSF_MSVQ_CB0_16_CDF, SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr, SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx }; ================================================ FILE: app/jni/SKP_Silk_tables_NLSF_CB1_10.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /**********************************************/ /* This file has been automatically generated */ /* */ /* ROM usage: 0.19 + 1.61 kB */ /**********************************************/ #include "SKP_Silk_structs.h" #include "SKP_Silk_tables_NLSF_CB1_10.h" #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ NLSF_MSVQ_CB1_10_VECTORS + NLSF_MSVQ_CB1_10_STAGES ] = { 0, 17096, 24130, 28997, 33179, 36696, 40213, 42493, 44252, 45973, 47551, 49095, 50542, 51898, 53196, 54495, 55685, 56851, 57749, 58628, 59435, 60207, 60741, 61220, 61700, 62179, 62659, 63138, 63617, 64097, 64576, 65056, 65535, 0, 20378, 33032, 40395, 46721, 51707, 56585, 61157, 65535, 0, 15055, 25472, 35447, 42501, 48969, 54773, 60212, 65535, 0, 12069, 22440, 32812, 40145, 46870, 53595, 59630, 65535, 0, 10839, 19954, 27957, 35961, 43965, 51465, 58805, 65535, 0, 8933, 17674, 26415, 34785, 42977, 50820, 58496, 65535 }; const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr[ NLSF_MSVQ_CB1_10_STAGES ] = { &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 0 ], &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 33 ], &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 42 ], &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 51 ], &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 60 ], &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 69 ] }; const SKP_int SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx[ NLSF_MSVQ_CB1_10_STAGES ] = { 5, 3, 4, 4, 5, 5 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ NLSF_MSVQ_CB1_10_VECTORS ] = { 62, 103, 120, 127, 135, 135, 155, 167, 168, 172, 173, 176, 179, 181, 181, 185, 186, 198, 199, 203, 205, 222, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 54, 76, 101, 108, 119, 120, 123, 125, 68, 85, 87, 103, 107, 112, 115, 116, 78, 85, 85, 101, 105, 105, 110, 111, 83, 91, 97, 97, 97, 100, 101, 105, 92, 93, 93, 95, 96, 98, 99, 103 }; const SKP_int SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min_Q15[ 10 + 1 ] = { 462, 3, 64, 74, 98, 50, 97, 68, 120, 53, 639 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * NLSF_MSVQ_CB1_10_VECTORS ] = { 1877, 4646, 7712, 10745, 13964, 17028, 20239, 23182, 26471, 29287, 1612, 3278, 7086, 9975, 13228, 16264, 19596, 22690, 26037, 28965, 2169, 3830, 6460, 8958, 11960, 14750, 18408, 21659, 25018, 28043, 3680, 6024, 8986, 12256, 15201, 18188, 21741, 24460, 27484, 30059, 2584, 5187, 7799, 10902, 13179, 15765, 19017, 22431, 25891, 28698, 3731, 5751, 8650, 11742, 15090, 17407, 20391, 23421, 26228, 29247, 2107, 6323, 8915, 12226, 14775, 17791, 20664, 23679, 26829, 29353, 1677, 2870, 5386, 8077, 11817, 15176, 18657, 22006, 25513, 28689, 2111, 3625, 7027, 10588, 14059, 17193, 21137, 24260, 27577, 30036, 2428, 4010, 5765, 9376, 13805, 15821, 19444, 22389, 25295, 29310, 2256, 4628, 8377, 12441, 15283, 19462, 22257, 25551, 28432, 30304, 2352, 3675, 6129, 11868, 14551, 16655, 19624, 21883, 26526, 28849, 5243, 7248, 10558, 13269, 15651, 17919, 21141, 23827, 27102, 29519, 4422, 6725, 10449, 13273, 16124, 19921, 22826, 26061, 28763, 30583, 4508, 6291, 9504, 11809, 13827, 15950, 19077, 22084, 25740, 28658, 2540, 4297, 8579, 13578, 16634, 19101, 21547, 23887, 26777, 29146, 3377, 6358, 10224, 14518, 17905, 21056, 23637, 25784, 28161, 30109, 4177, 5942, 8159, 10108, 12130, 15470, 20191, 23326, 26782, 29359, 2492, 3801, 6144, 9825, 16000, 18671, 20893, 23663, 25899, 28974, 3011, 4727, 6834, 10505, 12465, 14496, 17065, 20052, 25265, 28057, 4149, 7197, 12338, 15076, 18002, 20190, 22187, 24723, 27083, 29125, 2975, 4578, 6448, 8378, 9671, 13225, 19502, 22277, 26058, 28850, 4102, 5760, 7744, 9484, 10744, 12308, 14677, 19607, 24841, 28381, 4931, 9287, 12477, 13395, 13712, 14351, 16048, 19867, 24188, 28994, 4141, 7867, 13140, 17720, 20064, 21108, 21692, 22722, 23736, 27449, 4011, 8720, 13234, 16206, 17601, 18289, 18524, 19689, 23234, 27882, 3420, 5995, 11230, 15117, 15907, 16783, 17762, 23347, 26898, 29946, 3080, 6786, 10465, 13676, 18059, 23615, 27058, 29082, 29563, 29905, 3038, 5620, 9266, 12870, 18803, 19610, 20010, 20802, 23882, 29306, 3314, 6420, 9046, 13262, 15869, 23117, 23667, 24215, 24487, 25915, 3469, 6963, 10103, 15282, 20531, 23240, 25024, 26021, 26736, 27255, 3041, 6459, 9777, 12896, 16315, 19410, 24070, 29353, 31795, 32075, -200, -134, -113, -204, -347, -440, -352, -211, -418, -172, -313, 59, 495, 772, 721, 614, 334, 444, 225, 242, 161, 16, 274, 564, -73, -188, -395, -171, 777, 508, 1340, 1145, 699, 196, 223, 173, 90, 25, -26, 18, 133, -105, -360, -277, 859, 634, 41, -557, -768, -926, -601, -1021, -1189, -365, 225, 107, 374, -50, 433, 417, 156, 39, -597, -1397, -1594, -592, -485, -292, 253, 87, -0, -6, -25, -345, -240, 120, 1261, 946, 166, -277, 241, 167, 170, 429, 518, 714, 602, 254, 134, 92, -152, -324, -394, 49, -151, -304, -724, -657, -162, -369, -35, 3, -2, -312, -200, -92, -227, 242, 628, 565, -124, 1056, 770, 101, -84, -33, 4, -192, -272, 5, -627, -977, 419, 472, 53, -103, 145, 322, -95, -31, -100, -303, -560, -1067, -413, 714, 283, 2, -223, -367, 523, 360, -38, -115, 378, -591, -718, 448, -481, -274, 180, -88, -581, -157, -696, -1265, 394, -479, -23, 124, -43, 19, -113, -236, -412, -659, -200, 2, -69, -342, 199, 55, 58, -36, -51, -62, 507, 507, 427, 442, 36, 601, -141, 68, 274, 274, 68, -12, -4, 71, -193, -464, -425, -383, 408, 203, -337, 236, 410, -59, -25, -341, -449, 28, -9, 90, 332, -14, -905, 96, -540, -242, 679, -59, 192, -24, 60, -217, 5, -37, 179, -20, 311, 519, 274, 72, -326, -1030, -262, 213, 380, 82, 328, 411, -540, 574, -283, 151, 181, -402, -278, -240, -110, -227, -264, -89, -250, -259, -27, 106, -239, -98, -390, 118, 61, 104, 294, 532, 92, -13, 60, -233, 335, 541, 307, -26, -110, -91, -231, -460, 170, 201, 96, -372, 132, 435, -302, 216, -279, -41, 74, 190, 368, 273, -186, -608, -157, 159, 12, 278, 245, 307, 25, -187, -16, 55, 30, -163, 548, -307, 106, -5, 27, 330, -416, 475, 438, -235, 104, 137, 21, -5, -300, -468, 521, -347, 170, -200, -219, 308, -122, -133, 219, -16, 359, 412, -89, -111, 48, 322, 142, 177, -286, -127, -39, -63, -42, -451, 160, 308, -57, 193, -48, 74, -346, 59, -27, 27, -469, -277, -344, 282, 262, 122, 171, -249, 27, 258, 188, -3, 67, -206, -284, 291, -117, -88, -477, 375, 50, 106, 99, -182, 438, -376, -401, -49, 119, -23, -10, -48, -116, -200, -310, 121, 73, 7, 237, -226, 139, -456, 397, 35, 3, -108, 323, -75, 332, 198, -99, -21 }; const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB1_10_Stage_info[ NLSF_MSVQ_CB1_10_STAGES ] = { { 32, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 0 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 0 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 32 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 32 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 40 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 40 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 48 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 48 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 56 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 56 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 64 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 64 ] } }; const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB1_10 = { NLSF_MSVQ_CB1_10_STAGES, SKP_Silk_NLSF_CB1_10_Stage_info, SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min_Q15, SKP_Silk_NLSF_MSVQ_CB1_10_CDF, SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr, SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx }; ================================================ FILE: app/jni/SKP_Silk_tables_NLSF_CB1_16.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /**********************************************/ /* This file has been automatically generated */ /* */ /* ROM usage: 0.29 + 3.57 kB */ /**********************************************/ #include "SKP_Silk_structs.h" #include "SKP_Silk_tables_NLSF_CB1_16.h" #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ NLSF_MSVQ_CB1_16_VECTORS + NLSF_MSVQ_CB1_16_STAGES ] = { 0, 19099, 26957, 30639, 34242, 37546, 40447, 43287, 46005, 48445, 49865, 51284, 52673, 53975, 55221, 56441, 57267, 58025, 58648, 59232, 59768, 60248, 60729, 61210, 61690, 62171, 62651, 63132, 63613, 64093, 64574, 65054, 65535, 0, 28808, 38775, 46801, 51785, 55886, 59410, 62572, 65535, 0, 27376, 38639, 45052, 51465, 55448, 59021, 62594, 65535, 0, 33403, 39569, 45102, 49961, 54047, 57959, 61788, 65535, 0, 25851, 43356, 47828, 52204, 55964, 59413, 62507, 65535, 0, 34277, 40337, 45432, 50311, 54326, 58171, 61853, 65535, 0, 33538, 39865, 45302, 50076, 54549, 58478, 62159, 65535, 0, 27445, 35258, 40665, 46072, 51362, 56540, 61086, 65535, 0, 22080, 30779, 37065, 43085, 48849, 54613, 60133, 65535, 0, 13417, 21748, 30078, 38231, 46383, 53091, 59515, 65535 }; const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr[ NLSF_MSVQ_CB1_16_STAGES ] = { &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 0 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 33 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 42 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 51 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 60 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 69 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 78 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 87 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 96 ], &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 105 ] }; const SKP_int SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx[ NLSF_MSVQ_CB1_16_STAGES ] = { 5, 2, 2, 2, 2, 2, 2, 3, 3, 4 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ NLSF_MSVQ_CB1_16_VECTORS ] = { 57, 98, 133, 134, 138, 144, 145, 147, 152, 177, 177, 178, 181, 183, 184, 202, 206, 215, 218, 222, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 38, 87, 97, 119, 128, 135, 140, 143, 40, 81, 107, 107, 129, 134, 134, 143, 31, 109, 114, 120, 128, 130, 131, 132, 43, 61, 124, 125, 132, 136, 141, 142, 30, 110, 118, 120, 129, 131, 133, 133, 31, 108, 115, 121, 124, 130, 133, 137, 40, 98, 115, 115, 116, 117, 123, 124, 50, 93, 108, 110, 112, 112, 114, 115, 73, 95, 95, 96, 96, 105, 107, 110 }; const SKP_int SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min_Q15[ 16 + 1 ] = { 148, 3, 60, 68, 117, 86, 121, 124, 152, 153, 207, 151, 225, 239, 126, 183, 792 }; const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * NLSF_MSVQ_CB1_16_VECTORS ] = { 1309, 3060, 5071, 6996, 9028, 10938, 12934, 14891, 16933, 18854, 20792, 22764, 24753, 26659, 28626, 30501, 1264, 2745, 4610, 6408, 8286, 10043, 12084, 14108, 16118, 18163, 20095, 22164, 24264, 26316, 28329, 30251, 1044, 2080, 3672, 5179, 7140, 9100, 11070, 13065, 15423, 17790, 19931, 22101, 24290, 26361, 28499, 30418, 1131, 2476, 4478, 6149, 7902, 9875, 11938, 13809, 15869, 17730, 19948, 21707, 23761, 25535, 27426, 28917, 1040, 2004, 4026, 6100, 8432, 10494, 12610, 14694, 16797, 18775, 20799, 22782, 24772, 26682, 28631, 30516, 2310, 3812, 5913, 7933, 10033, 11881, 13885, 15798, 17751, 19576, 21482, 23276, 25157, 27010, 28833, 30623, 1254, 2847, 5013, 6781, 8626, 10370, 12726, 14633, 16281, 17852, 19870, 21472, 23002, 24629, 26710, 27960, 1468, 3059, 4987, 7026, 8741, 10412, 12281, 14020, 15970, 17723, 19640, 21522, 23472, 25661, 27986, 30225, 2171, 3566, 5605, 7384, 9404, 11220, 13030, 14758, 16687, 18417, 20346, 22091, 24055, 26212, 28356, 30397, 2409, 4676, 7543, 9786, 11419, 12935, 14368, 15653, 17366, 18943, 20762, 22477, 24440, 26327, 28284, 30242, 2354, 4222, 6820, 9107, 11596, 13934, 15973, 17682, 19158, 20517, 21991, 23420, 25178, 26936, 28794, 30527, 1323, 2414, 4184, 6039, 7534, 9398, 11099, 13097, 14799, 16451, 18434, 20887, 23490, 25838, 28046, 30225, 1361, 3243, 6048, 8511, 11001, 13145, 15073, 16608, 18126, 19381, 20912, 22607, 24660, 26668, 28663, 30566, 1216, 2648, 5901, 8422, 10037, 11425, 12973, 14603, 16686, 18600, 20555, 22415, 24450, 26280, 28206, 30077, 2417, 4048, 6316, 8433, 10510, 12757, 15072, 17295, 19573, 21503, 23329, 24782, 26235, 27689, 29214, 30819, 1012, 2345, 4991, 7377, 9465, 11916, 14296, 16566, 18672, 20544, 22292, 23838, 25415, 27050, 28848, 30551, 1937, 3693, 6267, 8019, 10372, 12194, 14287, 15657, 17431, 18864, 20769, 22206, 24037, 25463, 27383, 28602, 1969, 3305, 5017, 6726, 8375, 9993, 11634, 13280, 15078, 16751, 18464, 20119, 21959, 23858, 26224, 29298, 1198, 2647, 5428, 7423, 9775, 12155, 14665, 16344, 18121, 19790, 21557, 22847, 24484, 25742, 27639, 28711, 1636, 3353, 5447, 7597, 9837, 11647, 13964, 16019, 17862, 20116, 22319, 24037, 25966, 28086, 29914, 31294, 2676, 4105, 6378, 8223, 10058, 11549, 13072, 14453, 15956, 17355, 18931, 20402, 22183, 23884, 25717, 27723, 1373, 2593, 4449, 5633, 7300, 8425, 9474, 10818, 12769, 15722, 19002, 21429, 23682, 25924, 28135, 30333, 1596, 3183, 5378, 7164, 8670, 10105, 11470, 12834, 13991, 15042, 16642, 17903, 20759, 25283, 27770, 30240, 2037, 3987, 6237, 8117, 9954, 12245, 14217, 15892, 17775, 20114, 22314, 25942, 26305, 26483, 26796, 28561, 2181, 3858, 5760, 7924, 10041, 11577, 13769, 15700, 17429, 19879, 23583, 24538, 25212, 25693, 28688, 30507, 1992, 3882, 6474, 7883, 9381, 12672, 14340, 15701, 16658, 17832, 20850, 22885, 24677, 26457, 28491, 30460, 2391, 3988, 5448, 7432, 11014, 12579, 13140, 14146, 15898, 18592, 21104, 22993, 24673, 27186, 28142, 29612, 1713, 5102, 6989, 7798, 8670, 10110, 12746, 14881, 16709, 18407, 20126, 22107, 24181, 26198, 28237, 30137, 1612, 3617, 6148, 8359, 9576, 11528, 14936, 17809, 18287, 18729, 19001, 21111, 24631, 26596, 28740, 30643, 2266, 4168, 7862, 9546, 9618, 9703, 10134, 13897, 16265, 18432, 20587, 22605, 24754, 26994, 29125, 30840, 1840, 3917, 6272, 7809, 9714, 11438, 13767, 15799, 19244, 21972, 22980, 23180, 23723, 25650, 29117, 31085, 1458, 3612, 6008, 7488, 9827, 11893, 14086, 15734, 17440, 19535, 22424, 24767, 29246, 29928, 30516, 30947, -102, -121, -31, -6, 5, -2, 8, -18, -4, 6, 14, -2, -12, -16, -12, -60, -126, -353, -574, -677, -657, -617, -498, -393, -348, -277, -225, -164, -102, -70, -31, 33, 4, 379, 387, 551, 605, 620, 532, 482, 442, 454, 385, 347, 322, 299, 266, 200, 1168, 951, 672, 246, 60, -161, -259, -234, -253, -282, -203, -187, -155, -176, -198, -178, 10, 170, 393, 609, 555, 208, -330, -571, -769, -633, -319, -43, 95, 105, 106, 116, -152, -140, -125, 5, 173, 274, 264, 331, -37, -293, -609, -786, -959, -814, -645, -238, -91, 36, -11, -101, -279, -227, -40, 90, 530, 677, 890, 1104, 999, 835, 564, 295, -280, -364, -340, -331, -284, 288, 761, 880, 988, 627, 146, -226, -203, -181, -142, 39, 24, -26, -107, -92, -161, -135, -131, -88, -160, -156, -75, -43, -36, -6, -33, 33, -324, -415, -108, 124, 157, 191, 203, 197, 144, 109, 152, 176, 190, 122, 101, 159, 663, 668, 480, 400, 379, 444, 446, 458, 343, 351, 310, 228, 133, 44, 75, 63, -84, 39, -29, 35, -94, -233, -261, -354, 77, 262, -24, -145, -333, -409, -404, -597, -488, -300, 910, 592, 412, 120, 130, -51, -37, -77, -172, -181, -159, -148, -72, -62, 510, 516, 113, -585, -1075, -957, -417, -195, 9, 7, -88, -173, -91, 54, 98, 95, -28, 197, -527, -621, 157, 122, -168, 147, 309, 300, 336, 315, 396, 408, 376, 106, -162, -170, -315, 98, 821, 908, 570, -33, -312, -568, -572, -378, -107, 23, 156, 93, -129, -87, 20, -72, -37, 40, 21, 27, 48, 75, 77, 65, 46, 71, 66, 47, 136, 344, 236, 322, 170, 283, 269, 291, 162, -43, -204, -259, -240, -305, -350, -312, 447, 348, 345, 257, 71, -131, -77, -190, -202, -40, 35, 133, 261, 365, 438, 303, -8, 22, 140, 137, -300, -641, -764, -268, -23, -25, 73, -162, -150, -212, -72, 6, 39, 78, 104, -93, -308, -136, 117, -71, -513, -820, -700, -450, -161, -23, 29, 78, 337, 106, -406, -782, -112, 233, 383, 62, -126, 6, -77, -29, -146, -123, -51, -27, -27, -381, -641, 402, 539, 8, -207, -366, -36, -27, -204, -227, -237, -189, -64, 51, -92, -137, -281, 62, 233, 92, 148, 294, 363, 416, 564, 625, 370, -36, -469, -462, 102, 168, 32, 117, -21, 97, 139, 89, 104, 35, 4, 82, 66, 58, 73, 93, -76, -320, -236, -189, -203, -142, -27, -73, 9, -9, -25, 12, -15, 4, 4, -50, 314, 180, 162, -49, 199, -108, -227, -66, -447, -67, -264, -394, 5, 55, -133, -176, -116, -241, 272, 109, 282, 262, 192, -64, -392, -514, 156, 203, 154, 72, -34, -160, -73, 3, -33, -431, 321, 18, -567, -590, -108, 88, 66, 51, -31, -193, -46, 65, -29, -23, 215, -31, 101, -113, 32, 304, 88, 320, 448, 5, -439, -562, -508, -135, -13, -171, -8, 182, -99, -181, -149, 376, 476, 64, -396, -652, -150, 176, 222, 65, -590, 719, 271, 399, 245, 72, -156, -152, -176, 59, 94, 125, -9, -7, 9, 1, -61, -116, -82, 1, 79, 22, -44, -15, -48, -65, -62, -101, -102, -54, -70, -78, -80, -25, 398, 71, 139, 38, 90, 194, 222, 249, 165, 94, 221, 262, 163, 91, -206, 573, 200, -287, -147, 5, -18, -85, -74, -125, -87, 85, 141, 4, -4, 28, 234, 48, -150, -111, -506, 237, -209, 345, 94, -124, 77, 121, 143, 12, -80, -48, 191, 144, -93, -65, -151, -643, 435, 106, 87, 7, 65, 102, 94, 68, 5, 99, 222, 93, 94, 355, -13, -89, -228, -503, 287, 109, 108, 449, 253, -29, -109, -116, 15, -73, -20, 131, -147, 72, 59, -150, -594, 273, 316, 132, 199, 106, 198, 212, 220, 82, 45, -13, 223, 137, 270, 38, 252, 135, -177, -207, -360, -102, 403, 406, -14, 83, 64, 51, -7, -99, -97, -88, -124, -65, 42, 32, 28, 29, 12, 20, 119, -26, -212, -201, 373, 251, 141, 103, 36, -52, 66, 18, -6, -95, -196, 5, 98, -85, -108, 218, -164, 20, 356, 172, 37, 266, 23, 112, -24, -99, -92, -178, 29, -278, 388, -60, -220, 300, -13, 154, 191, 15, -37, -110, -153, -150, -114, -7, -94, -31, -62, -177, 4, -70, 35, 453, 147, -247, -328, 101, 20, -114, 147, 108, -119, -109, -102, -238, 55, -102, 173, -89, 129, 138, -330, -160, 485, 154, -59, -170, -20, -34, -261, -40, -129, 77, -84, 69, 83, 160, 169, 63, -516, 30, 336, 52, -0, -52, -124, 158, 19, 197, -10, -375, 405, 285, 114, -395, -47, 196, 62, 87, -106, -65, -75, -69, -13, 34, 99, 59, 83, 98, 44, 0, 24, 18, 17, 70, -22, 194, 208, 144, -79, -15, 32, -104, -28, -105, -186, -212, -228, -79, -76, 51, -71, 72, 118, -34, -3, -171, 5, 2, -108, -125, 62, -58, 58, -121, 73, -466, 92, 63, -94, -78, -76, 212, 36, -225, -71, -354, 152, 143, -79, -246, -51, -31, -6, -270, 240, 210, 30, -157, -231, 74, -146, 88, -273, 156, 92, 56, 71, 2, 318, 164, 32, -110, -35, -41, -95, -106, 11, 132, -68, 55, 123, -83, -149, 212, 132, 0, -194, 55, 206, -108, -353, 289, -195, 1, 233, -22, -60, 20, 26, 68, 166, 27, -58, 130, 112, 107, 27, -165, 115, -93, -37, 38, 83, 483, 65, -229, -13, 157, 85, 50, 136, 10, 32, 83, 82, 55, 5, -9, -52, -78, -81, -51, 40, 18, -127, -224, -41, 53, -210, -113, 24, -17, -187, -89, 8, 121, 83, 77, 91, -74, -35, -112, -161, -173, 102, 132, -125, -61, 103, -260, 52, 166, -32, -156, -87, -56, 60, -70, -124, 242, 114, -251, -166, 201, 127, 28, -11, 23, -80, -115, -20, -51, -348, 340, -34, 133, 13, 92, -124, -136, -120, -26, -6, 17, 28, 21, 120, -168, 160, -35, 115, 28, 9, 7, -56, 39, 156, 256, -18, 1, 277, 82, -70, -144, -88, -13, -59, -157, 8, -134, 21, -40, 58, -21, 194, -276, 97, 279, -56, -140, 125, 57, -184, -204, -70, -2, 128, -202, -78, 230, -23, 161, -102, 1, 1, 180, -31, -86, -167, -57, -60, 27, -13, 99, 108, 111, 76, 69, 34, -21, 53, 38, 34, 78, 73, 219, 51, 15, -72, -103, -207, 30, 213, -14, 31, -94, -40, -144, 67, 4, 105, 59, -240, 25, 244, 69, 58, 23, -24, -5, -15, -133, -71, -67, 181, 29, -45, 121, 96, 51, -72, -53, 56, -153, -27, 85, 183, 211, 105, -34, -46, 43, -72, -93, 36, -128, 29, 111, -95, -156, -179, -235, 21, -39, -71, -33, -61, -252, 230, -131, 157, -21, -85, -28, -123, 80, -160, 63, 47, -6, -49, -96, -19, 17, -58, 17, -0, -13, -170, 25, -35, 59, 10, -31, -413, 81, 62, 18, -164, 245, 92, -165, 42, 26, 126, -248, 193, -55, 16, 39, 14, 50 }; const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB1_16_Stage_info[ NLSF_MSVQ_CB1_16_STAGES ] = { { 32, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 0 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 0 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 32 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 32 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 40 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 40 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 48 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 48 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 56 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 56 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 64 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 64 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 72 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 72 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 80 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 80 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 88 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 88 ] }, { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 96 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 96 ] } }; const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB1_16 = { NLSF_MSVQ_CB1_16_STAGES, SKP_Silk_NLSF_CB1_16_Stage_info, SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min_Q15, SKP_Silk_NLSF_MSVQ_CB1_16_CDF, SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr, SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx }; ================================================ FILE: app/jni/SKP_Silk_tables_gain.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_tables.h" #ifdef __cplusplus extern "C" { #endif const SKP_uint16 SKP_Silk_gain_CDF[ 2 ][ 65 ] = { { 0, 18, 45, 94, 181, 320, 519, 777, 1093, 1468, 1909, 2417, 2997, 3657, 4404, 5245, 6185, 7228, 8384, 9664, 11069, 12596, 14244, 16022, 17937, 19979, 22121, 24345, 26646, 29021, 31454, 33927, 36438, 38982, 41538, 44068, 46532, 48904, 51160, 53265, 55184, 56904, 58422, 59739, 60858, 61793, 62568, 63210, 63738, 64165, 64504, 64769, 64976, 65133, 65249, 65330, 65386, 65424, 65451, 65471, 65487, 65501, 65513, 65524, 65535 }, { 0, 214, 581, 1261, 2376, 3920, 5742, 7632, 9449, 11157, 12780, 14352, 15897, 17427, 18949, 20462, 21957, 23430, 24889, 26342, 27780, 29191, 30575, 31952, 33345, 34763, 36200, 37642, 39083, 40519, 41930, 43291, 44602, 45885, 47154, 48402, 49619, 50805, 51959, 53069, 54127, 55140, 56128, 57101, 58056, 58979, 59859, 60692, 61468, 62177, 62812, 63368, 63845, 64242, 64563, 64818, 65023, 65184, 65306, 65391, 65447, 65482, 65505, 65521, 65535 } }; const SKP_int SKP_Silk_gain_CDF_offset = 32; const SKP_uint16 SKP_Silk_delta_gain_CDF[ 46 ] = { 0, 2358, 3856, 7023, 15376, 53058, 59135, 61555, 62784, 63498, 63949, 64265, 64478, 64647, 64783, 64894, 64986, 65052, 65113, 65169, 65213, 65252, 65284, 65314, 65338, 65359, 65377, 65392, 65403, 65415, 65424, 65432, 65440, 65448, 65455, 65462, 65470, 65477, 65484, 65491, 65499, 65506, 65513, 65521, 65528, 65535 }; const SKP_int SKP_Silk_delta_gain_CDF_offset = 5; #ifdef __cplusplus } #endif ================================================ FILE: app/jni/SKP_Silk_tables_other.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_structs.h" #include "SKP_Silk_define.h" #include "SKP_Silk_tables.h" #ifdef __cplusplus extern "C" { #endif /* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ const SKP_int32 TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = { 0, 8000, 9000, 11000, 13000, 16000, 22000, MAX_TARGET_RATE_BPS }; const SKP_int32 TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = { 0, 10000, 12000, 14000, 17000, 21000, 28000, MAX_TARGET_RATE_BPS }; const SKP_int32 TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = { 0, 11000, 14000, 17000, 21000, 26000, 36000, MAX_TARGET_RATE_BPS }; const SKP_int32 TargetRate_table_SWB[ TARGET_RATE_TAB_SZ ] = { 0, 13000, 16000, 19000, 25000, 32000, 46000, MAX_TARGET_RATE_BPS }; const SKP_int32 SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = { 19, 31, 35, 39, 43, 47, 54, 64 }; const SKP_int32 SNR_table_one_bit_per_sample_Q7[ 4 ] = { 1984, 2240, 2408, 2708 }; /* Filter coeficicnts for HP filter: 4. Order filter implementad as two biquad filters */ const SKP_int16 SKP_Silk_SWB_detect_B_HP_Q13[ NB_SOS ][ 3 ] = { //{400, -550, 400}, {400, 130, 400}, {400, 390, 400} {575, -948, 575}, {575, -221, 575}, {575, 104, 575} }; const SKP_int16 SKP_Silk_SWB_detect_A_HP_Q13[ NB_SOS ][ 2 ] = { {14613, 6868}, {12883, 7337}, {11586, 7911} //{14880, 6900}, {14400, 7300}, {13700, 7800} }; /* Decoder high-pass filter coefficients for 24 kHz sampling, -6 dB @ 44 Hz */ const SKP_int16 SKP_Silk_Dec_A_HP_24[ DEC_HP_ORDER ] = {-16220, 8030}; // second order AR coefs, Q13 const SKP_int16 SKP_Silk_Dec_B_HP_24[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13 /* Decoder high-pass filter coefficients for 16 kHz sampling, - 6 dB @ 46 Hz */ const SKP_int16 SKP_Silk_Dec_A_HP_16[ DEC_HP_ORDER ] = {-16127, 7940}; // second order AR coefs, Q13 const SKP_int16 SKP_Silk_Dec_B_HP_16[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13 /* Decoder high-pass filter coefficients for 12 kHz sampling, -6 dB @ 44 Hz */ const SKP_int16 SKP_Silk_Dec_A_HP_12[ DEC_HP_ORDER ] = {-16043, 7859}; // second order AR coefs, Q13 const SKP_int16 SKP_Silk_Dec_B_HP_12[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13 /* Decoder high-pass filter coefficients for 8 kHz sampling, -6 dB @ 43 Hz */ const SKP_int16 SKP_Silk_Dec_A_HP_8[ DEC_HP_ORDER ] = {-15885, 7710}; // second order AR coefs, Q13 const SKP_int16 SKP_Silk_Dec_B_HP_8[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13 /* table for LSB coding */ const SKP_uint16 SKP_Silk_lsb_CDF[ 3 ] = {0, 40000, 65535}; /* tables for LTPScale */ const SKP_uint16 SKP_Silk_LTPscale_CDF[ 4 ] = {0, 32000, 48000, 65535}; const SKP_int SKP_Silk_LTPscale_offset = 2; /* tables for VAD flag */ const SKP_uint16 SKP_Silk_vadflag_CDF[ 3 ] = {0, 22000, 65535}; // 66% for speech, 33% for no speech const SKP_int SKP_Silk_vadflag_offset = 1; /* tables for sampling rate */ const SKP_int SKP_Silk_SamplingRates_table[ 4 ] = {8, 12, 16, 24}; const SKP_uint16 SKP_Silk_SamplingRates_CDF[ 5 ] = {0, 16000, 32000, 48000, 65535}; const SKP_int SKP_Silk_SamplingRates_offset = 2; /* tables for NLSF interpolation factor */ const SKP_uint16 SKP_Silk_NLSF_interpolation_factor_CDF[ 6 ] = {0, 3706, 8703, 19226, 30926, 65535}; const SKP_int SKP_Silk_NLSF_interpolation_factor_offset = 4; /* Table for frame termination indication */ const SKP_uint16 SKP_Silk_FrameTermination_CDF[ 5 ] = {0, 20000, 45000, 56000, 65535}; const SKP_int SKP_Silk_FrameTermination_offset = 2; /* Table for random seed */ const SKP_uint16 SKP_Silk_Seed_CDF[ 5 ] = {0, 16384, 32768, 49152, 65535}; const SKP_int SKP_Silk_Seed_offset = 2; /* Quantization offsets */ const SKP_int16 SKP_Silk_Quantization_Offsets_Q10[ 2 ][ 2 ] = { { OFFSET_VL_Q10, OFFSET_VH_Q10 }, { OFFSET_UVL_Q10, OFFSET_UVH_Q10 } }; /* Table for LTPScale */ const SKP_int16 SKP_Silk_LTPScales_table_Q14[ 3 ] = { 15565, 11469, 8192 }; #if SWITCH_TRANSITION_FILTERING /* Elliptic/Cauer filters designed with 0.1 dB passband ripple, 80 dB minimum stopband attenuation, and [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ const SKP_int32 SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ] = { { 250767114, 501534038, 250767114 }, { 209867381, 419732057, 209867381 }, { 170987846, 341967853, 170987846 }, { 131531482, 263046905, 131531482 }, { 89306658, 178584282, 89306658 } }; /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ const SKP_int32 SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ] = { { 506393414, 239854379 }, { 411067935, 169683996 }, { 306733530, 116694253 }, { 185807084, 77959395 }, { 35497197, 57401098 } }; #endif #ifdef __cplusplus } #endif ================================================ FILE: app/jni/SKP_Silk_tables_pitch_lag.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_pitch_lag_NB_CDF[ 8 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = { 0, 194, 395, 608, 841, 1099, 1391, 1724, 2105, 2544, 3047, 3624, 4282, 5027, 5865, 6799, 7833, 8965, 10193, 11510, 12910, 14379, 15905, 17473, 19065, 20664, 22252, 23814, 25335, 26802, 28206, 29541, 30803, 31992, 33110, 34163, 35156, 36098, 36997, 37861, 38698, 39515, 40319, 41115, 41906, 42696, 43485, 44273, 45061, 45847, 46630, 47406, 48175, 48933, 49679, 50411, 51126, 51824, 52502, 53161, 53799, 54416, 55011, 55584, 56136, 56666, 57174, 57661, 58126, 58570, 58993, 59394, 59775, 60134, 60472, 60790, 61087, 61363, 61620, 61856, 62075, 62275, 62458, 62625, 62778, 62918, 63045, 63162, 63269, 63368, 63459, 63544, 63623, 63698, 63769, 63836, 63901, 63963, 64023, 64081, 64138, 64194, 64248, 64301, 64354, 64406, 64457, 64508, 64558, 64608, 64657, 64706, 64754, 64803, 64851, 64899, 64946, 64994, 65041, 65088, 65135, 65181, 65227, 65272, 65317, 65361, 65405, 65449, 65492, 65535 }; const SKP_int SKP_Silk_pitch_lag_NB_CDF_offset = 43; const SKP_uint16 SKP_Silk_pitch_contour_NB_CDF[ 12 ] = { 0, 14445, 18587, 25628, 30013, 34859, 40597, 48426, 54460, 59033, 62990, 65535 }; const SKP_int SKP_Silk_pitch_contour_NB_CDF_offset = 5; const SKP_uint16 SKP_Silk_pitch_lag_MB_CDF[ 12 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = { 0, 132, 266, 402, 542, 686, 838, 997, 1167, 1349, 1546, 1760, 1993, 2248, 2528, 2835, 3173, 3544, 3951, 4397, 4882, 5411, 5984, 6604, 7270, 7984, 8745, 9552, 10405, 11300, 12235, 13206, 14209, 15239, 16289, 17355, 18430, 19507, 20579, 21642, 22688, 23712, 24710, 25677, 26610, 27507, 28366, 29188, 29971, 30717, 31427, 32104, 32751, 33370, 33964, 34537, 35091, 35630, 36157, 36675, 37186, 37692, 38195, 38697, 39199, 39701, 40206, 40713, 41222, 41733, 42247, 42761, 43277, 43793, 44309, 44824, 45336, 45845, 46351, 46851, 47347, 47836, 48319, 48795, 49264, 49724, 50177, 50621, 51057, 51484, 51902, 52312, 52714, 53106, 53490, 53866, 54233, 54592, 54942, 55284, 55618, 55944, 56261, 56571, 56873, 57167, 57453, 57731, 58001, 58263, 58516, 58762, 58998, 59226, 59446, 59656, 59857, 60050, 60233, 60408, 60574, 60732, 60882, 61024, 61159, 61288, 61410, 61526, 61636, 61742, 61843, 61940, 62033, 62123, 62210, 62293, 62374, 62452, 62528, 62602, 62674, 62744, 62812, 62879, 62945, 63009, 63072, 63135, 63196, 63256, 63316, 63375, 63434, 63491, 63549, 63605, 63661, 63717, 63772, 63827, 63881, 63935, 63988, 64041, 64094, 64147, 64199, 64252, 64304, 64356, 64409, 64461, 64513, 64565, 64617, 64669, 64721, 64773, 64824, 64875, 64925, 64975, 65024, 65072, 65121, 65168, 65215, 65262, 65308, 65354, 65399, 65445, 65490, 65535 }; const SKP_int SKP_Silk_pitch_lag_MB_CDF_offset = 64; const SKP_uint16 SKP_Silk_pitch_lag_WB_CDF[ 16 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = { 0, 106, 213, 321, 429, 539, 651, 766, 884, 1005, 1132, 1264, 1403, 1549, 1705, 1870, 2047, 2236, 2439, 2658, 2893, 3147, 3420, 3714, 4030, 4370, 4736, 5127, 5546, 5993, 6470, 6978, 7516, 8086, 8687, 9320, 9985, 10680, 11405, 12158, 12938, 13744, 14572, 15420, 16286, 17166, 18057, 18955, 19857, 20759, 21657, 22547, 23427, 24293, 25141, 25969, 26774, 27555, 28310, 29037, 29736, 30406, 31048, 31662, 32248, 32808, 33343, 33855, 34345, 34815, 35268, 35704, 36127, 36537, 36938, 37330, 37715, 38095, 38471, 38844, 39216, 39588, 39959, 40332, 40707, 41084, 41463, 41844, 42229, 42615, 43005, 43397, 43791, 44186, 44583, 44982, 45381, 45780, 46179, 46578, 46975, 47371, 47765, 48156, 48545, 48930, 49312, 49690, 50064, 50433, 50798, 51158, 51513, 51862, 52206, 52544, 52877, 53204, 53526, 53842, 54152, 54457, 54756, 55050, 55338, 55621, 55898, 56170, 56436, 56697, 56953, 57204, 57449, 57689, 57924, 58154, 58378, 58598, 58812, 59022, 59226, 59426, 59620, 59810, 59994, 60173, 60348, 60517, 60681, 60840, 60993, 61141, 61284, 61421, 61553, 61679, 61800, 61916, 62026, 62131, 62231, 62326, 62417, 62503, 62585, 62663, 62737, 62807, 62874, 62938, 62999, 63057, 63113, 63166, 63217, 63266, 63314, 63359, 63404, 63446, 63488, 63528, 63567, 63605, 63642, 63678, 63713, 63748, 63781, 63815, 63847, 63879, 63911, 63942, 63973, 64003, 64033, 64063, 64092, 64121, 64150, 64179, 64207, 64235, 64263, 64291, 64319, 64347, 64374, 64401, 64428, 64455, 64481, 64508, 64534, 64560, 64585, 64610, 64635, 64660, 64685, 64710, 64734, 64758, 64782, 64807, 64831, 64855, 64878, 64902, 64926, 64950, 64974, 64998, 65022, 65045, 65069, 65093, 65116, 65139, 65163, 65186, 65209, 65231, 65254, 65276, 65299, 65321, 65343, 65364, 65386, 65408, 65429, 65450, 65471, 65493, 65514, 65535 }; const SKP_int SKP_Silk_pitch_lag_WB_CDF_offset = 86; const SKP_uint16 SKP_Silk_pitch_lag_SWB_CDF[ 24 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = { 0, 253, 505, 757, 1008, 1258, 1507, 1755, 2003, 2249, 2494, 2738, 2982, 3225, 3469, 3713, 3957, 4202, 4449, 4698, 4949, 5203, 5460, 5720, 5983, 6251, 6522, 6798, 7077, 7361, 7650, 7942, 8238, 8539, 8843, 9150, 9461, 9775, 10092, 10411, 10733, 11057, 11383, 11710, 12039, 12370, 12701, 13034, 13368, 13703, 14040, 14377, 14716, 15056, 15398, 15742, 16087, 16435, 16785, 17137, 17492, 17850, 18212, 18577, 18946, 19318, 19695, 20075, 20460, 20849, 21243, 21640, 22041, 22447, 22856, 23269, 23684, 24103, 24524, 24947, 25372, 25798, 26225, 26652, 27079, 27504, 27929, 28352, 28773, 29191, 29606, 30018, 30427, 30831, 31231, 31627, 32018, 32404, 32786, 33163, 33535, 33902, 34264, 34621, 34973, 35320, 35663, 36000, 36333, 36662, 36985, 37304, 37619, 37929, 38234, 38535, 38831, 39122, 39409, 39692, 39970, 40244, 40513, 40778, 41039, 41295, 41548, 41796, 42041, 42282, 42520, 42754, 42985, 43213, 43438, 43660, 43880, 44097, 44312, 44525, 44736, 44945, 45153, 45359, 45565, 45769, 45972, 46175, 46377, 46578, 46780, 46981, 47182, 47383, 47585, 47787, 47989, 48192, 48395, 48599, 48804, 49009, 49215, 49422, 49630, 49839, 50049, 50259, 50470, 50682, 50894, 51107, 51320, 51533, 51747, 51961, 52175, 52388, 52601, 52813, 53025, 53236, 53446, 53655, 53863, 54069, 54274, 54477, 54679, 54879, 55078, 55274, 55469, 55662, 55853, 56042, 56230, 56415, 56598, 56779, 56959, 57136, 57311, 57484, 57654, 57823, 57989, 58152, 58314, 58473, 58629, 58783, 58935, 59084, 59230, 59373, 59514, 59652, 59787, 59919, 60048, 60174, 60297, 60417, 60533, 60647, 60757, 60865, 60969, 61070, 61167, 61262, 61353, 61442, 61527, 61609, 61689, 61765, 61839, 61910, 61979, 62045, 62109, 62170, 62230, 62287, 62343, 62396, 62448, 62498, 62547, 62594, 62640, 62685, 62728, 62770, 62811, 62852, 62891, 62929, 62967, 63004, 63040, 63075, 63110, 63145, 63178, 63212, 63244, 63277, 63308, 63340, 63371, 63402, 63432, 63462, 63491, 63521, 63550, 63578, 63607, 63635, 63663, 63690, 63718, 63744, 63771, 63798, 63824, 63850, 63875, 63900, 63925, 63950, 63975, 63999, 64023, 64046, 64069, 64092, 64115, 64138, 64160, 64182, 64204, 64225, 64247, 64268, 64289, 64310, 64330, 64351, 64371, 64391, 64411, 64431, 64450, 64470, 64489, 64508, 64527, 64545, 64564, 64582, 64600, 64617, 64635, 64652, 64669, 64686, 64702, 64719, 64735, 64750, 64766, 64782, 64797, 64812, 64827, 64842, 64857, 64872, 64886, 64901, 64915, 64930, 64944, 64959, 64974, 64988, 65003, 65018, 65033, 65048, 65063, 65078, 65094, 65109, 65125, 65141, 65157, 65172, 65188, 65204, 65220, 65236, 65252, 65268, 65283, 65299, 65314, 65330, 65345, 65360, 65375, 65390, 65405, 65419, 65434, 65449, 65463, 65477, 65492, 65506, 65521, 65535 }; const SKP_int SKP_Silk_pitch_lag_SWB_CDF_offset = 128; const SKP_uint16 SKP_Silk_pitch_contour_CDF[ 35 ] = { 0, 372, 843, 1315, 1836, 2644, 3576, 4719, 6088, 7621, 9396, 11509, 14245, 17618, 20777, 24294, 27992, 33116, 40100, 44329, 47558, 50679, 53130, 55557, 57510, 59022, 60285, 61345, 62316, 63140, 63762, 64321, 64729, 65099, 65535 }; const SKP_int SKP_Silk_pitch_contour_CDF_offset = 17; const SKP_uint16 SKP_Silk_pitch_delta_CDF[23] = { 0, 343, 740, 1249, 1889, 2733, 3861, 5396, 7552, 10890, 16053, 24152, 30220, 34680, 37973, 40405, 42243, 43708, 44823, 45773, 46462, 47055, 65535 }; const SKP_int SKP_Silk_pitch_delta_CDF_offset = 11; ================================================ FILE: app/jni/SKP_Silk_tables_pulses_per_block.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_tables.h" const SKP_int SKP_Silk_max_pulses_table[ 4 ] = { 6, 8, 12, 18 }; const SKP_uint16 SKP_Silk_pulses_per_block_CDF[ 10 ][ 21 ] = { { 0, 47113, 61501, 64590, 65125, 65277, 65352, 65407, 65450, 65474, 65488, 65501, 65508, 65514, 65516, 65520, 65521, 65523, 65524, 65526, 65535 }, { 0, 26368, 47760, 58803, 63085, 64567, 65113, 65333, 65424, 65474, 65498, 65511, 65517, 65520, 65523, 65525, 65526, 65528, 65529, 65530, 65535 }, { 0, 9601, 28014, 45877, 57210, 62560, 64611, 65260, 65447, 65500, 65511, 65519, 65521, 65525, 65526, 65529, 65530, 65531, 65532, 65534, 65535 }, { 0, 3351, 12462, 25972, 39782, 50686, 57644, 61525, 63521, 64506, 65009, 65255, 65375, 65441, 65471, 65488, 65497, 65505, 65509, 65512, 65535 }, { 0, 488, 2944, 9295, 19712, 32160, 43976, 53121, 59144, 62518, 64213, 65016, 65346, 65470, 65511, 65515, 65525, 65529, 65531, 65534, 65535 }, { 0, 17013, 30405, 40812, 48142, 53466, 57166, 59845, 61650, 62873, 63684, 64223, 64575, 64811, 64959, 65051, 65111, 65143, 65165, 65183, 65535 }, { 0, 2994, 8323, 15845, 24196, 32300, 39340, 45140, 49813, 53474, 56349, 58518, 60167, 61397, 62313, 62969, 63410, 63715, 63906, 64056, 65535 }, { 0, 88, 721, 2795, 7542, 14888, 24420, 34593, 43912, 51484, 56962, 60558, 62760, 64037, 64716, 65069, 65262, 65358, 65398, 65420, 65535 }, { 0, 287, 789, 2064, 4398, 8174, 13534, 20151, 27347, 34533, 41295, 47242, 52070, 55772, 58458, 60381, 61679, 62533, 63109, 63519, 65535 }, { 0, 1, 3, 91, 4521, 14708, 28329, 41955, 52116, 58375, 61729, 63534, 64459, 64924, 65092, 65164, 65182, 65198, 65203, 65211, 65535 } }; const SKP_int SKP_Silk_pulses_per_block_CDF_offset = 6; const SKP_int16 SKP_Silk_pulses_per_block_BITS_Q6[ 9 ][ 20 ] = { { 30, 140, 282, 444, 560, 625, 654, 677, 731, 780, 787, 844, 859, 960, 896, 1024, 960, 1024, 960, 821 }, { 84, 103, 164, 252, 350, 442, 526, 607, 663, 731, 787, 859, 923, 923, 960, 1024, 960, 1024, 1024, 875 }, { 177, 117, 120, 162, 231, 320, 426, 541, 657, 803, 832, 960, 896, 1024, 923, 1024, 1024, 1024, 960, 1024 }, { 275, 182, 146, 144, 166, 207, 261, 322, 388, 450, 516, 582, 637, 710, 762, 821, 832, 896, 923, 734 }, { 452, 303, 216, 170, 153, 158, 182, 220, 274, 337, 406, 489, 579, 681, 896, 811, 896, 960, 923, 1024 }, { 125, 147, 170, 202, 232, 265, 295, 332, 368, 406, 443, 483, 520, 563, 606, 646, 704, 739, 757, 483 }, { 285, 232, 200, 190, 193, 206, 224, 244, 266, 289, 315, 340, 367, 394, 425, 462, 496, 539, 561, 350 }, { 611, 428, 319, 242, 202, 178, 172, 180, 199, 229, 268, 313, 364, 422, 482, 538, 603, 683, 739, 586 }, { 501, 450, 364, 308, 264, 231, 212, 204, 204, 210, 222, 241, 265, 295, 326, 362, 401, 437, 469, 321 } }; const SKP_uint16 SKP_Silk_rate_levels_CDF[ 2 ][ 10 ] = { { 0, 2005, 12717, 20281, 31328, 36234, 45816, 57753, 63104, 65535 }, { 0, 8553, 23489, 36031, 46295, 53519, 56519, 59151, 64185, 65535 } }; const SKP_int SKP_Silk_rate_levels_CDF_offset = 4; const SKP_int16 SKP_Silk_rate_levels_BITS_Q6[ 2 ][ 9 ] = { { 322, 167, 199, 164, 239, 178, 157, 231, 304 }, { 188, 137, 153, 171, 204, 285, 297, 237, 358 } }; const SKP_uint16 SKP_Silk_shell_code_table0[ 33 ] = { 0, 32748, 65535, 0, 9505, 56230, 65535, 0, 4093, 32204, 61720, 65535, 0, 2285, 16207, 48750, 63424, 65535, 0, 1709, 9446, 32026, 55752, 63876, 65535, 0, 1623, 6986, 21845, 45381, 59147, 64186, 65535 }; const SKP_uint16 SKP_Silk_shell_code_table1[ 52 ] = { 0, 32691, 65535, 0, 12782, 52752, 65535, 0, 4847, 32665, 60899, 65535, 0, 2500, 17305, 47989, 63369, 65535, 0, 1843, 10329, 32419, 55433, 64277, 65535, 0, 1485, 7062, 21465, 43414, 59079, 64623, 65535, 0, 0, 4841, 14797, 31799, 49667, 61309, 65535, 65535, 0, 0, 0, 8032, 21695, 41078, 56317, 65535, 65535, 65535 }; const SKP_uint16 SKP_Silk_shell_code_table2[ 102 ] = { 0, 32615, 65535, 0, 14447, 50912, 65535, 0, 6301, 32587, 59361, 65535, 0, 3038, 18640, 46809, 62852, 65535, 0, 1746, 10524, 32509, 55273, 64278, 65535, 0, 1234, 6360, 21259, 43712, 59651, 64805, 65535, 0, 1020, 4461, 14030, 32286, 51249, 61904, 65100, 65535, 0, 851, 3435, 10006, 23241, 40797, 55444, 63009, 65252, 65535, 0, 0, 2075, 7137, 17119, 31499, 46982, 58723, 63976, 65535, 65535, 0, 0, 0, 3820, 11572, 23038, 37789, 51969, 61243, 65535, 65535, 65535, 0, 0, 0, 0, 6882, 16828, 30444, 44844, 57365, 65535, 65535, 65535, 65535, 0, 0, 0, 0, 0, 10093, 22963, 38779, 54426, 65535, 65535, 65535, 65535, 65535 }; const SKP_uint16 SKP_Silk_shell_code_table3[ 207 ] = { 0, 32324, 65535, 0, 15328, 49505, 65535, 0, 7474, 32344, 57955, 65535, 0, 3944, 19450, 45364, 61873, 65535, 0, 2338, 11698, 32435, 53915, 63734, 65535, 0, 1506, 7074, 21778, 42972, 58861, 64590, 65535, 0, 1027, 4490, 14383, 32264, 50980, 61712, 65043, 65535, 0, 760, 3022, 9696, 23264, 41465, 56181, 63253, 65251, 65535, 0, 579, 2256, 6873, 16661, 31951, 48250, 59403, 64198, 65360, 65535, 0, 464, 1783, 5181, 12269, 24247, 39877, 53490, 61502, 64591, 65410, 65535, 0, 366, 1332, 3880, 9273, 18585, 32014, 45928, 56659, 62616, 64899, 65483, 65535, 0, 286, 1065, 3089, 6969, 14148, 24859, 38274, 50715, 59078, 63448, 65091, 65481, 65535, 0, 0, 482, 2010, 5302, 10408, 18988, 30698, 43634, 54233, 60828, 64119, 65288, 65535, 65535, 0, 0, 0, 1006, 3531, 7857, 14832, 24543, 36272, 47547, 56883, 62327, 64746, 65535, 65535, 65535, 0, 0, 0, 0, 1863, 4950, 10730, 19284, 29397, 41382, 52335, 59755, 63834, 65535, 65535, 65535, 65535, 0, 0, 0, 0, 0, 2513, 7290, 14487, 24275, 35312, 46240, 55841, 62007, 65535, 65535, 65535, 65535, 65535, 0, 0, 0, 0, 0, 0, 3606, 9573, 18764, 28667, 40220, 51290, 59924, 65535, 65535, 65535, 65535, 65535, 65535, 0, 0, 0, 0, 0, 0, 0, 4879, 13091, 23376, 36061, 49395, 59315, 65535, 65535, 65535, 65535, 65535, 65535, 65535 }; const SKP_uint16 SKP_Silk_shell_code_table_offsets[ 19 ] = { 0, 0, 3, 7, 12, 18, 25, 33, 42, 52, 63, 75, 88, 102, 117, 133, 150, 168, 187 }; ================================================ FILE: app/jni/SKP_Silk_tables_sign.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_sign_CDF[ 36 ] = { 37840, 36944, 36251, 35304, 34715, 35503, 34529, 34296, 34016, 47659, 44945, 42503, 40235, 38569, 40254, 37851, 37243, 36595, 43410, 44121, 43127, 40978, 38845, 40433, 38252, 37795, 36637, 59159, 55630, 51806, 48073, 45036, 48416, 43857, 42678, 41146, }; ================================================ FILE: app/jni/SKP_Silk_tables_type_offset.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_tables.h" const SKP_uint16 SKP_Silk_type_offset_CDF[ 5 ] = { 0, 37522, 41030, 44212, 65535 }; const SKP_int SKP_Silk_type_offset_CDF_offset = 2; const SKP_uint16 SKP_Silk_type_offset_joint_CDF[ 4 ][ 5 ] = { { 0, 57686, 61230, 62358, 65535 }, { 0, 18346, 40067, 43659, 65535 }, { 0, 22694, 24279, 35507, 65535 }, { 0, 6067, 7215, 13010, 65535 } }; ================================================ FILE: app/jni/SKP_Silk_warped_autocorrelation_FIX.c ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main_FIX.h" #define QC 10 #define QS 14 #if EMBEDDED_ARM<6 /* Autocorrelations for a warped frequency axis */ void SKP_Silk_warped_autocorrelation_FIX( SKP_int32 *corr, /* O Result [order + 1] */ SKP_int *scale, /* O Scaling of the correlation vector */ const SKP_int16 *input, /* I Input data to correlate */ const SKP_int16 warping_Q16, /* I Warping coefficient */ const SKP_int length, /* I Length of input */ const SKP_int order /* I Correlation order (even) */ ) { SKP_int n, i, lsh; SKP_int32 tmp1_QS, tmp2_QS; SKP_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; SKP_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* Order must be even */ SKP_assert( ( order & 1 ) == 0 ); SKP_assert( 2 * QS - QC >= 0 ); /* Loop over samples */ for( n = 0; n < length; n++ ) { tmp1_QS = SKP_LSHIFT32( ( SKP_int32 )input[ n ], QS ); /* Loop over allpass sections */ for( i = 0; i < order; i += 2 ) { /* Output of allpass section */ tmp2_QS = SKP_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); state_QS[ i ] = tmp1_QS; corr_QC[ i ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); /* Output of allpass section */ tmp1_QS = SKP_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); state_QS[ i + 1 ] = tmp2_QS; corr_QC[ i + 1 ] += SKP_RSHIFT64( SKP_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); } state_QS[ order ] = tmp1_QS; corr_QC[ order ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); } lsh = SKP_Silk_CLZ64( corr_QC[ 0 ] ) - 35; lsh = SKP_LIMIT( lsh, -12 - QC, 30 - QC ); *scale = -( QC + lsh ); SKP_assert( *scale >= -30 && *scale <= 12 ); if( lsh >= 0 ) { for( i = 0; i < order + 1; i++ ) { corr[ i ] = ( SKP_int32 )SKP_CHECK_FIT32( SKP_LSHIFT64( corr_QC[ i ], lsh ) ); } } else { for( i = 0; i < order + 1; i++ ) { corr[ i ] = ( SKP_int32 )SKP_CHECK_FIT32( SKP_RSHIFT64( corr_QC[ i ], -lsh ) ); } } SKP_assert( corr_QC[ 0 ] >= 0 ); // If breaking, decrease QC } #endif ================================================ FILE: app/jni/decoder.c ================================================ #include "silk.h" #include "lame.h" #include static void print_usage(char* argv[]) { printf( "\nusage: %s in.bit out.pcm [settings]\n", argv[ 0 ] ); printf( "\nin.bit : Bitstream input to decoder" ); printf( "\nout.pcm : Speech output from decoder" ); printf( "\n settings:" ); printf( "\n-Fs_API : Sampling rate of output signal in Hz; default: 24000" ); printf( "\n-loss : Simulated packet loss percentage (0-100); default: 0" ); printf( "\n-quiet : Print out just some basic values" ); printf( "\n" ); } int main( int argc, char* argv[] ) { // print_usage(argv); const char *src = "/home/ketian/silk_project/silk/msg_3910190915165fe46499e0f103.amr"; const char *dest = "/home/ketian/silk_project/silk/out2.pcm"; FILE *tempFile = fopen(dest, "wb+"); if (tempFile == 0) { LOGD("open tempFile %s failed", tempFile); return -1; } return convertSilk2PCM(src, tempFile); } ================================================ FILE: app/jni/decoder.cpp ================================================ // // Created by ketian on 16-9-23. // #include #include #ifdef __cplusplus extern "C" { #endif #include "silk.h" #include "lame.h" JNIEXPORT jint JNICALL Java_com_ketian_android_silkv3_jni_JNI_convert(JNIEnv *env, jobject thiz, jstring src, jstring dest, jstring tmpfile) { if (src == nullptr){ return NULL; } if (dest == nullptr){ return NULL; } if (tmpfile == nullptr){ return NULL; } const char *str_c = env->GetStringUTFChars(src, nullptr); const char *dest_c = env->GetStringUTFChars(dest, nullptr); const char *tmp = env->GetStringUTFChars(tmpfile, nullptr); LOGE("libsilkx is developed by tian.ke, any question, please email to ketn4391@gmail.com"); LOGE("convert %s to %s", str_c, dest_c); FILE *tempFile = fopen(tmp, "wb+e"); if (tempFile == nullptr) { LOGE("open tempFile %s failed", tmp); return -1; } if (convertSilk2PCM(str_c, tempFile) != 0) { LOGE("convert silk to pcm failed"); fclose(tempFile); return -1; } lame_t lame = lame_init(); lame_set_in_samplerate(lame, 24000); lame_set_num_channels(lame, 1); lame_set_mode(lame, MONO); lame_set_quality(lame, 5); lame_init_params(lame); FILE *pcm = tempFile; fseek(pcm, 0, SEEK_SET); FILE *mp3 = fopen(dest_c, "wbe"); int read, write; const int PCM_SIZE = 8192; const int MP3_SIZE = 8192; short int pcm_buffer[PCM_SIZE]; unsigned char mp3_buffer[MP3_SIZE]; do { read = static_cast(fread(pcm_buffer, sizeof(short int), PCM_SIZE, pcm)); if (read == 0) { write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE); } else { write = lame_encode_buffer(lame, pcm_buffer, nullptr, read, mp3_buffer, MP3_SIZE); } fwrite(mp3_buffer, 1, static_cast(write), mp3); } while (read != 0); lame_close(lame); fclose(mp3); fclose(pcm); return 1; } #ifdef __cplusplus } #endif ================================================ FILE: app/jni/include/SKP_Silk_AsmHelper.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * SKP_Silk_AsmHelper.h * * * * */ #ifndef _SKP_ASM_HELPER_H_ #define _SKP_ASM_HELPER_H_ // Register bank #define _REG 0 #define _DREG 1 // Arg registers #define _R0 0 #define _R1 1 #define _R2 2 #define _R3 3 #define _R4 4 // GP registers #define _R5 5 #define _R6 6 #define _R7 7 #define _R8 8 #define _SB 9 #define _SL 10 // fp and ip registers #define _FP 11 #define _IP 12 // lr and sp registers #define _SP 13 #define _LR 14 // Extension register bank #define _numDReg #define _Q0 0 #define _Q1 1 #define _Q2 2 #define _Q3 3 #define _Q4 4 #define _Q5 5 #define _Q6 6 #define _Q7 7 #define _Q8 8 #define _Q9 9 #define _Q10 10 #define _Q11 11 #define _Q12 12 #define _Q13 13 #define _Q14 14 #define _Q15 15 #if defined (_WINRT) #else #if defined (IPHONE) #define MACRO .macro #define END_MACRO .endmacro #define ARG0_in #define ARG1_in #define ARG2_in #define ARG3_in #define ARG4_in #define ARG5_in #define ARG6_in #define ARG7_in #define ARG0 $0 #define ARG1 $1 #define ARG2 $2 #define ARG3 $3 #define ARG4 $4 #define ARG5 $5 #define ARG6 $6 #define ARG7 $7 #define RARG0 r$0 #define RARG1 r$1 #define QARG0 q$0 #define QARG1 q$1 MACRO CHECK_ABS ARG0_in, ARG1_in .abs is_abs, ARG1 .if is_abs==1 .set ARG0, ARG1 .else .set ARG0, -1 .endif END_MACRO #else #define MACRO .macro #define END_MACRO .endm #define ARG0_in arg0=-1 #define ARG1_in arg1=-1 #define ARG2_in arg2=-1 #define ARG3_in arg3=-1 #define ARG4_in arg4=-1 #define ARG5_in arg5=-1 #define ARG6_in arg6=-1 #define ARG7_in arg7=-1 #define ARG0 \arg0 #define ARG1 \arg1 #define ARG2 \arg2 #define ARG3 \arg3 #define ARG4 \arg4 #define ARG5 \arg5 #define ARG6 \arg6 #define ARG7 \arg7 #define RARG0 r\arg0 #define RARG1 r\arg1 #define QARG0 q\arg0 #define QARG1 q\arg1 MACRO CHECK_ABS ARG0_in, ARG1_in .set ARG0, ARG1 END_MACRO #endif MACRO VARDEF ARG0_in, ARG1_in ARG0 .req ARG1 END_MACRO MACRO VARDEFD ARG0_in, ARG1_in ARG0 .req ARG1 END_MACRO MACRO VARDEFQ ARG0_in, ARG1_in ARG0 .req ARG1 END_MACRO MACRO END END_MACRO MACRO EXTERN ARG0_in END_MACRO MACRO ALIGN ARG0_in .align ARG0 END_MACRO MACRO DATA .data END_MACRO MACRO EXPORT ARG0_in .globl ARG0 END_MACRO #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_AsmPreproc.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* SKP_Silk_AsmPreProc.h * * General header for all ARM asms uses SigProcLib. * It contains C preprocessor part and asm preprocessor part. * C preprocessor part: * * Interfacing makefile, arch, fpu and neon support * * Interfacing different symbol styles and asm directives. * * Interfacing compiling time standard output * ASM preprocessor part: * * Defining general asm header/footer for stack/return value * * Allocating stack for local variables and nasted function * * Defining simple syntax checking and debugging routines */ /* * C preprocessor part */ #ifndef _SKP_ASM_PREPROC_H_ #define _SKP_ASM_PREPROC_H_ #include "SKP_Silk_AsmHelper.h" /* Checking compilier __ARMEL__ defines */ #if !__ARMEL__ && (!defined(NO_ASM)) && (!defined(_WINRT)) #error Currently SKP_Silk_AsmPreProc only supports little endian. // above line can be replaced by // #warning __ARMEL__=0 // #define NOASM #endif /* Defining macro for different user label prefix. */ #ifndef __USER_LABEL_PREFIX__ #define __USER_LABEL_PREFIX__ #endif #define CONCAT1(a, b) CONCAT2(a, b) #define CONCAT2(a, b) a ## b #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) /* Remapping register for iphone. */ #ifdef IPHONE # define _fp r7 # define _r7 r11 #else # define _fp fp # define _r7 r7 #endif /* Checking compiler __ARM_EABI__ defines */ #if __ARMEB__ #define NO_ASM //remove asm optimization for ARM big endian. #else #define ARM_LITTLE_ENDIAN #endif /* Interfacing some asm directives to macros*/ #define GBL .globl /* Legacy definition wrapper */ #ifndef NO_ASM #if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__) #define EMBEDDED_ARM 4 #define EMBEDDED_ARMv4 #elif defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__) #define EMBEDDED_ARM 5 #define EMBEDDED_ARMv5 #elif defined (__ARM_ARCH_6__) ||defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) #define EMBEDDED_ARM 6 #define EMBEDDED_ARMv6 #elif defined (__ARM_ARCH_7A__) && defined (__ARM_NEON__) #define EMBEDDED_ARM 7 #define EMBEDDED_ARMv6 #elif defined (__ARM_ARCH_7A__) #define EMBEDDED_ARM 6 #define EMBEDDED_ARMv6 #endif #endif #ifdef _WINRT #define L(a) a #define LR(a,d) %##d##a #define TABLE(L, symbol) symbol #else #define L(a) a: #define LR(a,d) a##d #define DCD .long #define DCW .short #define TABLE(L, symbol) L #endif #ifdef _WINRT #define streqh strheq #define strneh strhne #define strgth strhgt #define strlth strhlt #define ldrgtsh ldrshgt #define ldmgtia ldmiagt #define ldmgtdb ldmdbgt #define ldrneh ldrhne #define ldmltia ldmialt #endif /* * ASM preprocessor part: */ #ifdef _WINRT #else // AT&T Format #if EMBEDDED_ARM >= 7 .set _ARCH, 7 #elif EMBEDDED_ARM >= 6 .set _ARCH, 6 #elif EMBEDDED_ARM >= 5 // Should be re-considerred as ARMv5 != ARMv5E .set _ARCH, 5 #elif EMBEDDED_ARM >= 4 .set _ARCH, 4 #else .set _ARCH, 0 #endif #if NEON .set _NEON, 1 #else .set _NEON, 0 #endif MACRO SKP_TABLE ARG0_in, ARG1_in SYM(ARG0): END_MACRO MACRO SKP_SMLAD ARG0_in, ARG1_in, ARG2_in, ARG3_in #if EMBEDDED_ARM>=6 smlad ARG0, ARG1, ARG2, ARG3 #elif EMBEDDED_ARM>=5 smlabb ARG0, ARG1, ARG2, ARG3 smlatt ARG0, ARG1, ARG2, ARG0 #else .abort "SKP_SMUAD can't be used for armv4 or lower device.." #endif END_MACRO MACRO SKP_SMUAD ARG0_in, ARG1_in, ARG2_in #if EMBEDDED_ARM>=6 smuad ARG0, ARG1, ARG2 #elif EMBEDDED_ARM>=5 smulbb ARG0, ARG1, ARG2 smlatt ARG0, ARG1, ARG2, ARG0 #else .abort "SKP_SMUAD can't be used for armv4 or lower device.." #endif END_MACRO MACRO SKP_SMLALD ARG0_in, ARG1_in, ARG2_in, ARG3_in #if EMBEDDED_ARM>=6 smlald ARG0, ARG1, ARG2, ARG3 #elif EMBEDDED_ARM>=5 smlalbb ARG0, ARG1, ARG2, ARG3 smlaltt ARG0, ARG1, ARG2, ARG3 #else .abort "SKP_SMLALD can't be used for armv4 or lower device.." #endif END_MACRO MACRO SKP_RSHIFT_ROUND ARG0_in, ARG1_in, ARG2_in #if EMBEDDED_ARM>=4 mov ARG0, ARG1, asr #(ARG2-1) add ARG0, ARG0, #1 mov ARG0, ARG0, asr #1 #else .abort "SKP_RSHIFT_ROUND can't be used for armv3 or lower device.." #endif END_MACRO MACRO ADD_SHIFT ARG0_in, ARG1_in, ARG2_in, ARG3_in, ARG4_in add ARG0, ARG1, ARG2, ARG3 ARG4 END_MACRO MACRO POST_IR ARG0_in, ARG1_in, ARG2_in, ARG3_in ARG0 ARG1, [ARG2], ARG3 END_MACRO #endif #endif //_SKP_ASM_PREPROC_H_ ================================================ FILE: app/jni/include/SKP_Silk_Inlines.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /*! \file SKP_Silk_Inlines.h * \brief SKP_Silk_Inlines.h defines inline signal processing functions. */ #ifndef _SKP_SILK_FIX_INLINES_H_ #define _SKP_SILK_FIX_INLINES_H_ #include #ifdef __cplusplus extern "C" { #endif /* count leading zeros of SKP_int64 */ SKP_INLINE SKP_int32 SKP_Silk_CLZ64(SKP_int64 in) { SKP_int32 in_upper; in_upper = (SKP_int32)SKP_RSHIFT64(in, 32); if (in_upper == 0) { /* Search in the lower 32 bits */ return 32 + SKP_Silk_CLZ32( (SKP_int32) in ); } else { /* Search in the upper 32 bits */ return SKP_Silk_CLZ32( in_upper ); } } /* get number of leading zeros and fractional part (the bits right after the leading one */ SKP_INLINE void SKP_Silk_CLZ_FRAC(SKP_int32 in, /* I: input */ SKP_int32 *lz, /* O: number of leading zeros */ SKP_int32 *frac_Q7) /* O: the 7 bits right after the leading one */ { SKP_int32 lzeros = SKP_Silk_CLZ32(in); * lz = lzeros; * frac_Q7 = SKP_ROR32(in, 24 - lzeros) & 0x7f; } /* Approximation of square root */ /* Accuracy: < +/- 10% for output values > 15 */ /* < +/- 2.5% for output values > 120 */ SKP_INLINE SKP_int32 SKP_Silk_SQRT_APPROX(SKP_int32 x) { SKP_int32 y, lz, frac_Q7; if( x <= 0 ) { return 0; } SKP_Silk_CLZ_FRAC(x, &lz, &frac_Q7); if( lz & 1 ) { y = 32768; } else { y = 46214; /* 46214 = sqrt(2) * 32768 */ } /* get scaling right */ y >>= SKP_RSHIFT(lz, 1); /* increment using fractional part of input */ y = SKP_SMLAWB(y, y, SKP_SMULBB(213, frac_Q7)); return y; } /* returns the number of left shifts before overflow for a 16 bit number (ITU definition with norm(0)=0) */ SKP_INLINE SKP_int32 SKP_Silk_norm16(SKP_int16 a) { SKP_int32 a32; /* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */ if ((a << 1) == 0) return(0); a32 = a; /* if (a32 < 0) a32 = -a32 - 1; */ a32 ^= SKP_RSHIFT(a32, 31); return SKP_Silk_CLZ32(a32) - 17; } /* returns the number of left shifts before overflow for a 32 bit number (ITU definition with norm(0)=0) */ SKP_INLINE SKP_int32 SKP_Silk_norm32(SKP_int32 a) { /* if ((a == 0) || (a == SKP_int32_MIN)) return(0); */ if ((a << 1) == 0) return(0); /* if (a < 0) a = -a - 1; */ a ^= SKP_RSHIFT(a, 31); return SKP_Silk_CLZ32(a) - 1; } /* Divide two int32 values and return result as int32 in a given Q-domain */ SKP_INLINE SKP_int32 SKP_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */ const SKP_int32 a32, /* I numerator (Q0) */ const SKP_int32 b32, /* I denominator (Q0) */ const SKP_int Qres /* I Q-domain of result (>= 0) */ ) { SKP_int a_headrm, b_headrm, lshift; SKP_int32 b32_inv, a32_nrm, b32_nrm, result; SKP_assert( b32 != 0 ); SKP_assert( Qres >= 0 ); /* Compute number of bits head room and normalize inputs */ a_headrm = SKP_Silk_CLZ32( SKP_abs(a32) ) - 1; a32_nrm = SKP_LSHIFT(a32, a_headrm); /* Q: a_headrm */ b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1; b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */ /* Inverse of b32, with 14 bits of precision */ b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ /* First approximation */ result = SKP_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ /* Compute residual by subtracting product of denominator and first approximation */ a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 ); /* Q: a_headrm */ /* Refinement */ result = SKP_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ /* Convert to Qres domain */ lshift = 29 + a_headrm - b_headrm - Qres; if( lshift <= 0 ) { return SKP_LSHIFT_SAT32(result, -lshift); } else { if( lshift < 32){ return SKP_RSHIFT(result, lshift); } else { /* Avoid undefined result */ return 0; } } } /* Invert int32 value and return result as int32 in a given Q-domain */ SKP_INLINE SKP_int32 SKP_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */ const SKP_int32 b32, /* I denominator (Q0) */ const SKP_int Qres /* I Q-domain of result (> 0) */ ) { SKP_int b_headrm, lshift; SKP_int32 b32_inv, b32_nrm, err_Q32, result; SKP_assert( b32 != 0 ); SKP_assert( b32 != SKP_int32_MIN ); /* SKP_int32_MIN is not handled by SKP_abs */ SKP_assert( Qres > 0 ); /* Compute number of bits head room and normalize input */ b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1; b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */ /* Inverse of b32, with 14 bits of precision */ b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ /* First approximation */ result = SKP_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */ /* Compute residual by subtracting product of denominator and first approximation from one */ err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */ /* Refinement */ result = SKP_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */ /* Convert to Qres domain */ lshift = 61 - b_headrm - Qres; if( lshift <= 0 ) { return SKP_LSHIFT_SAT32(result, -lshift); } else { if( lshift < 32){ return SKP_RSHIFT(result, lshift); }else{ /* Avoid undefined result */ return 0; } } } #define SKP_SIN_APPROX_CONST0 (1073735400) #define SKP_SIN_APPROX_CONST1 (-82778932) #define SKP_SIN_APPROX_CONST2 (1059577) #define SKP_SIN_APPROX_CONST3 (-5013) /* Sine approximation; an input of 65536 corresponds to 2 * pi */ /* Uses polynomial expansion of the input to the power 0, 2, 4 and 6 */ /* The relative error is below 1e-5 */ SKP_INLINE SKP_int32 SKP_Silk_SIN_APPROX_Q24( /* O returns approximately 2^24 * sin(x * 2 * pi / 65536) */ SKP_int32 x ) { SKP_int y_Q30; /* Keep only bottom 16 bits (the function repeats itself with period 65536) */ x &= 65535; /* Split range in four quadrants */ if( x <= 32768 ) { if( x < 16384 ) { /* Return cos(pi/2 - x) */ x = 16384 - x; } else { /* Return cos(x - pi/2) */ x -= 16384; } if( x < 1100 ) { /* Special case: high accuracy */ return SKP_SMLAWB( 1 << 24, SKP_MUL( x, x ), -5053 ); } x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */ y_Q30 = SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 ); y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 ); y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 ); } else { if( x < 49152 ) { /* Return -cos(3*pi/2 - x) */ x = 49152 - x; } else { /* Return -cos(x - 3*pi/2) */ x -= 49152; } if( x < 1100 ) { /* Special case: high accuracy */ return SKP_SMLAWB( -1u << 24, SKP_MUL( x, x ), 5053 ); } x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */ y_Q30 = SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 ); y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 ); y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 ); } return SKP_RSHIFT_ROUND( y_Q30, 6 ); } /* Cosine approximation; an input of 65536 corresponds to 2 * pi */ /* The relative error is below 1e-5 */ SKP_INLINE SKP_int32 SKP_Silk_COS_APPROX_Q24( /* O returns approximately 2^24 * cos(x * 2 * pi / 65536) */ SKP_int32 x ) { return SKP_Silk_SIN_APPROX_Q24( x + 16384 ); } #ifdef __cplusplus } #endif #endif /*_SKP_SILK_FIX_INLINES_H_*/ ================================================ FILE: app/jni/include/SKP_Silk_PLC.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_PLC_FIX_H #define SKP_SILK_PLC_FIX_H #include "SKP_Silk_main.h" #define BWE_COEF_Q16 64880 /* 0.99 in Q16 */ #define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */ #define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */ #define MAX_PITCH_LAG_MS 18 #define SA_THRES_Q8 50 #define USE_SINGLE_TAP 1 #define RAND_BUF_SIZE 128 #define RAND_BUF_MASK (RAND_BUF_SIZE - 1) #define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */ #define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */ #define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */ void SKP_Silk_PLC_Reset( SKP_Silk_decoder_state *psDec /* I/O Decoder state */ ); void SKP_Silk_PLC( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* I/O signal */ SKP_int length, /* I length of residual */ SKP_int lost /* I Loss flag */ ); void SKP_Silk_PLC_update( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], SKP_int length ); void SKP_Silk_PLC_conceal( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* O LPC residual signal */ SKP_int length /* I length of signal */ ); void SKP_Silk_PLC_glue_frames( SKP_Silk_decoder_state *psDec, /* I/O decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* I/O signal */ SKP_int length /* I length of signal */ ); #endif ================================================ FILE: app/jni/include/SKP_Silk_SDK_API.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_SDK_API_H #define SKP_SILK_SDK_API_H #include "SKP_Silk_control.h" #include "SKP_Silk_typedef.h" #include "SKP_Silk_errors.h" #ifdef __cplusplus extern "C" { #endif #define SILK_MAX_FRAMES_PER_PACKET 5 /* Struct for TOC (Table of Contents) */ typedef struct { SKP_int framesInPacket; /* Number of 20 ms frames in packet */ SKP_int fs_kHz; /* Sampling frequency in packet */ SKP_int inbandLBRR; /* Does packet contain LBRR information */ SKP_int corrupt; /* Packet is corrupt */ SKP_int vadFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet */ SKP_int sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */ } SKP_Silk_TOC_struct; /****************************************/ /* Encoder functions */ /****************************************/ /***********************************************/ /* Get size in bytes of the Silk encoder state */ /***********************************************/ SKP_int SKP_Silk_SDK_Get_Encoder_Size( SKP_int32 *encSizeBytes /* O: Number of bytes in SILK encoder state */ ); /*************************/ /* Init or reset encoder */ /*************************/ SKP_int SKP_Silk_SDK_InitEncoder( void *encState, /* I/O: State */ SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */ ); /***************************************/ /* Read control structure from encoder */ /***************************************/ SKP_int SKP_Silk_SDK_QueryEncoder( const void *encState, /* I: State */ SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */ ); /**************************/ /* Encode frame with Silk */ /**************************/ SKP_int SKP_Silk_SDK_Encode( void *encState, /* I/O: State */ const SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control status */ const SKP_int16 *samplesIn, /* I: Speech sample input vector */ SKP_int nSamplesIn, /* I: Number of samples in input vector */ SKP_uint8 *outData, /* O: Encoded output vector */ SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */ ); /****************************************/ /* Decoder functions */ /****************************************/ /***********************************************/ /* Get size in bytes of the Silk decoder state */ /***********************************************/ SKP_int SKP_Silk_SDK_Get_Decoder_Size( SKP_int32 *decSizeBytes /* O: Number of bytes in SILK decoder state */ ); /*************************/ /* Init or Reset decoder */ /*************************/ SKP_int SKP_Silk_SDK_InitDecoder( void *decState /* I/O: State */ ); /******************/ /* Decode a frame */ /******************/ SKP_int SKP_Silk_SDK_Decode( void* decState, /* I/O: State */ SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control Structure */ SKP_int lostFlag, /* I: 0: no loss, 1 loss */ const SKP_uint8 *inData, /* I: Encoded input vector */ const SKP_int nBytesIn, /* I: Number of input bytes */ SKP_int16 *samplesOut, /* O: Decoded output speech vector */ SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */ ); /***************************************************************/ /* Find Low Bit Rate Redundancy (LBRR) information in a packet */ /***************************************************************/ void SKP_Silk_SDK_search_for_LBRR( const SKP_uint8 *inData, /* I: Encoded input vector */ const SKP_int nBytesIn, /* I: Number of input Bytes */ SKP_int lost_offset, /* I: Offset from lost packet */ SKP_uint8 *LBRRData, /* O: LBRR payload */ SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */ ); /**************************************/ /* Get table of contents for a packet */ /**************************************/ void SKP_Silk_SDK_get_TOC( const SKP_uint8 *inData, /* I: Encoded input vector */ const SKP_int nBytesIn, /* I: Number of input bytes */ SKP_Silk_TOC_struct *Silk_TOC /* O: Table of contents */ ); /**************************/ /* Get the version number */ /**************************/ /* Return a pointer to string specifying the version */ const char *SKP_Silk_SDK_get_version(); #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_SigProc_FIX.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef _SKP_SILK_SIGPROC_FIX_H_ #define _SKP_SILK_SIGPROC_FIX_H_ #ifdef __cplusplus extern "C" { #endif #define SKP_Silk_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ #define SKP_Silk_MAX_CORRELATION_LENGTH 640 /* max input length to the correlation */ #include "SKP_Silk_typedef.h" #include #include /* for abs() */ #include "SKP_Silk_resampler_structs.h" #include "SKP_Silk_macros.h" /********************************************************************/ /* SIGNAL PROCESSING FUNCTIONS */ /********************************************************************/ /*! * Initialize/reset the resampler state for a given pair of input/output sampling rates */ SKP_int SKP_Silk_resampler_init( SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */ SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */ SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */ ); /*! * Clear the states of all resampling filters, without resetting sampling rate ratio */ SKP_int SKP_Silk_resampler_clear( SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */ ); /*! * Resampler: convert from one sampling rate to another */ SKP_int SKP_Silk_resampler( SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ); /*! Upsample 2x, low quality */ void SKP_Silk_resampler_up2( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ 2 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of input samples */ ); /*! * Downsample 2x, mediocre quality */ void SKP_Silk_resampler_down2( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ len ] */ const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */ SKP_int32 inLen /* I: Number of input samples */ ); /*! * Downsample by a factor 2/3, low quality */ void SKP_Silk_resampler_down2_3( SKP_int32 *S, /* I/O: State vector [ 6 ] */ SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */ const SKP_int16 *in, /* I: Input signal [ inLen ] */ SKP_int32 inLen /* I: Number of input samples */ ); /*! * Downsample by a factor 3, low quality */ void SKP_Silk_resampler_down3( SKP_int32 *S, /* I/O: State vector [ 8 ] */ SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */ const SKP_int16 *in, /* I: Input signal [ inLen ] */ SKP_int32 inLen /* I: Number of input samples */ ); /*! * second order ARMA filter * can handle (slowly) varying coefficients */ void SKP_Silk_biquad( const SKP_int16 *in, /* I: input signal */ const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */ const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */ SKP_int32 *S, /* I/O: state vector [2] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len /* I: signal length */ ); /*! * Second order ARMA filter; * slower than biquad() but uses more precise coefficients * can handle (slowly) varying coefficients */ void SKP_Silk_biquad_alt( const SKP_int16 *in, /* I: Input signal */ const SKP_int32 *B_Q28, /* I: MA coefficients [3] */ const SKP_int32 *A_Q28, /* I: AR coefficients [2] */ SKP_int32 *S, /* I/O: State vector [2] */ SKP_int16 *out, /* O: Output signal */ const SKP_int32 len /* I: Signal length (must be even) */ ); /*! * variable order MA filter. Prediction error filter implementation. Coeficients negated and starting with coef to x[n - 1] */ void SKP_Silk_MA_Prediction( const SKP_int16 *in, /* I: Input signal */ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */ SKP_int32 *S, /* I/O: State vector [order] */ SKP_int16 *out, /* O: Output signal */ const SKP_int32 len, /* I: Signal length */ const SKP_int32 order /* I: Filter order */ ); /*! * 16th order AR filter for LPC synthesis, coefficients are in Q12 */ void SKP_Silk_LPC_synthesis_order16( const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [16] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len /* I: signal length, must be multiple of 16 */ ); /* variable order MA prediction error filter. */ /* Inverse filter of SKP_Silk_LPC_synthesis_filter */ void SKP_Silk_LPC_analysis_filter( const SKP_int16 *in, /* I: Input signal */ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */ SKP_int16 *S, /* I/O: State vector [order] */ SKP_int16 *out, /* O: Output signal */ const SKP_int32 len, /* I: Signal length */ const SKP_int32 Order /* I: Filter order */ ); /* even order AR filter */ void SKP_Silk_LPC_synthesis_filter( const SKP_int16 *in, /* I: excitation signal */ const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */ const SKP_int32 Gain_Q26, /* I: gain */ SKP_int32 *S, /* I/O: state vector [Order] */ SKP_int16 *out, /* O: output signal */ const SKP_int32 len, /* I: signal length */ const SKP_int Order /* I: filter order, must be even */ ); /* Chirp (bandwidth expand) LP AR filter */ void SKP_Silk_bwexpander( SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ const SKP_int d, /* I Length of ar */ SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ ); /* Chirp (bandwidth expand) LP AR filter */ void SKP_Silk_bwexpander_32( SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ const SKP_int d, /* I Length of ar */ SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */ ); /* Compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */ const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */ const SKP_int order /* I: Prediction order */ ); SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */ const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */ const SKP_int order /* I: Prediction order */ ); /* split signal in two decimated bands using first-order allpass filters */ void SKP_Silk_ana_filt_bank_1( const SKP_int16 *in, /* I: Input signal [N] */ SKP_int32 *S, /* I/O: State vector [2] */ SKP_int16 *outL, /* O: Low band [N/2] */ SKP_int16 *outH, /* O: High band [N/2] */ SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */ const SKP_int32 N /* I: Number of input samples */ ); /********************************************************************/ /* SCALAR FUNCTIONS */ /********************************************************************/ /* Approximation of 128 * log2() (very close inverse of approx 2^() below) */ /* Convert input to a log scale */ SKP_int32 SKP_Silk_lin2log(const SKP_int32 inLin); /* I: Input in linear scale */ /* Approximation of a sigmoid function */ SKP_int SKP_Silk_sigm_Q15(SKP_int in_Q5); /* approximation of 2^() (exact inverse of approx log2() above) */ /* convert input to a linear scale */ SKP_int32 SKP_Silk_log2lin(const SKP_int32 inLog_Q7); /* I: input on log scale */ /* Function that returns the maximum absolut value of the input vector */ SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ const SKP_int16 *vec, /* I Input vector [len] */ const SKP_int32 len /* I Length of input vector */ ); /* Compute number of bits to right shift the sum of squares of a vector */ /* of int16s to make it fit in an int32 */ void SKP_Silk_sum_sqr_shift( SKP_int32 *energy, /* O Energy of x, after shifting to the right */ SKP_int *shift, /* O Number of bits right shift applied to energy */ const SKP_int16 *x, /* I Input vector */ SKP_int len /* I Length of input vector */ ); /* Calculates the reflection coefficients from the correlation sequence */ /* Faster than schur64(), but much less accurate. */ /* Uses SMLAWB(), requiring armv5E and higher. */ SKP_int32 SKP_Silk_schur( /* O: Returns residual energy */ SKP_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */ const SKP_int32 *c, /* I: correlations [order+1] */ const SKP_int32 order /* I: prediction order */ ); /* Calculates the reflection coefficients from the correlation sequence */ /* Slower than schur(), but more accurate. */ /* Uses SMULL(), available on armv4 */ SKP_int32 SKP_Silk_schur64( /* O: returns residual energy */ SKP_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */ const SKP_int32 c[], /* I: Correlations [order+1] */ SKP_int32 order /* I: Prediction order */ ); /* Step up function, converts reflection coefficients to prediction coefficients */ void SKP_Silk_k2a( SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */ const SKP_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */ const SKP_int32 order /* I: Prediction order */ ); /* Step up function, converts reflection coefficients to prediction coefficients */ void SKP_Silk_k2a_Q16( SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */ const SKP_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */ const SKP_int32 order /* I: Prediction order */ ); /* Apply sine window to signal vector. */ /* Window types: */ /* 1 -> sine window from 0 to pi/2 */ /* 2 -> sine window from pi/2 to pi */ /* Every other sample is linearly interpolated, for speed. */ void SKP_Silk_apply_sine_window( SKP_int16 px_win[], /* O Pointer to windowed signal */ const SKP_int16 px[], /* I Pointer to input signal */ const SKP_int win_type, /* I Selects a window type */ const SKP_int length /* I Window length, multiple of 4 */ ); /* Compute autocorrelation */ void SKP_Silk_autocorr( SKP_int32 *results, /* O Result (length correlationCount) */ SKP_int *scale, /* O Scaling of the correlation vector */ const SKP_int16 *inputData, /* I Input data to correlate */ const SKP_int inputDataSize, /* I Length of input */ const SKP_int correlationCount /* I Number of correlation taps to compute */ ); /* Pitch estimator */ #define SKP_Silk_PITCH_EST_MIN_COMPLEX 0 #define SKP_Silk_PITCH_EST_MID_COMPLEX 1 #define SKP_Silk_PITCH_EST_MAX_COMPLEX 2 void SKP_Silk_decode_pitch( SKP_int lagIndex, /* I */ SKP_int contourIndex, /* O */ SKP_int pitch_lags[], /* O 4 pitch values */ SKP_int Fs_kHz /* I sampling frequency (kHz) */ ); SKP_int SKP_Silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ const SKP_int16 *signal, /* I Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */ SKP_int *pitch_out, /* O 4 pitch lag values */ SKP_int *lagIndex, /* O Lag Index */ SKP_int *contourIndex, /* O Pitch contour Index */ SKP_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ SKP_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ const SKP_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ const SKP_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ const SKP_int Fs_kHz, /* I Sample frequency (kHz) */ const SKP_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ const SKP_int forLJC /* I 1 if this function is called from LJC code, 0 otherwise. */ ); /* parameter defining the size and accuracy of the piecewise linear */ /* cosine approximatin table. */ #define LSF_COS_TAB_SZ_FIX 128 /* rom table with cosine values */ extern const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ]; /* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ /* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ void SKP_Silk_A2NLSF( SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */ SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ const SKP_int d /* I Filter order (must be even) */ ); /* compute whitening filter coefficients from normalized line spectral frequencies */ void SKP_Silk_NLSF2A( SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */ const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */ const SKP_int d /* i filter order (should be even) */ ); void SKP_Silk_insertion_sort_increasing( SKP_int32 *a, /* I/O Unsorted / Sorted vector */ SKP_int *index, /* O: Index vector for the sorted elements */ const SKP_int L, /* I: Vector length */ const SKP_int K /* I: Number of correctly sorted positions */ ); void SKP_Silk_insertion_sort_decreasing_int16( SKP_int16 *a, /* I/O: Unsorted / Sorted vector */ SKP_int *index, /* O: Index vector for the sorted elements */ const SKP_int L, /* I: Vector length */ const SKP_int K /* I: Number of correctly sorted positions */ ); void SKP_Silk_insertion_sort_increasing_all_values( SKP_int *a, /* I/O: Unsorted / Sorted vector */ const SKP_int L /* I: Vector length */ ); /* NLSF stabilizer, for a single input data vector */ void SKP_Silk_NLSF_stabilize( SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */ const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */ const SKP_int L /* I: Number of NLSF parameters in the input vector */ ); /* Laroia low complexity NLSF weights */ void SKP_Silk_NLSF_VQ_weights_laroia( SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */ const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */ const SKP_int D /* I: Input vector dimension (even) */ ); /* Compute reflection coefficients from input signal */ void SKP_Silk_burg_modified( SKP_int32 *res_nrg, /* O residual energy */ SKP_int *res_nrgQ, /* O residual energy Q value */ SKP_int32 A_Q16[], /* O prediction coefficients (length order) */ const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */ const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */ const SKP_int nb_subfr, /* I number of subframes stacked in x */ const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */ const SKP_int D /* I order */ ); /* Copy and multiply a vector by a constant */ void SKP_Silk_scale_copy_vector16( SKP_int16 *data_out, const SKP_int16 *data_in, SKP_int32 gain_Q16, /* I: gain in Q16 */ const SKP_int dataSize /* I: length */ ); /* Some for the LTP related function requires Q26 to work.*/ void SKP_Silk_scale_vector32_Q26_lshift_18( SKP_int32 *data1, /* I/O: Q0/Q18 */ SKP_int32 gain_Q26, /* I: Q26 */ SKP_int dataSize /* I: length */ ); /********************************************************************/ /* INLINE ARM MATH */ /********************************************************************/ /* return sum(inVec1[i]*inVec2[i]) */ /* inVec1 and inVec2 should be increasing ordered, and starting address should be 4 byte aligned. (a factor of 4)*/ SKP_int32 SKP_Silk_inner_prod_aligned( const SKP_int16* const inVec1, /* I input vector 1 */ const SKP_int16* const inVec2, /* I input vector 2 */ const SKP_int len /* I vector lengths */ ); SKP_int64 SKP_Silk_inner_prod16_aligned_64( const SKP_int16 *inVec1, /* I input vector 1 */ const SKP_int16 *inVec2, /* I input vector 2 */ const SKP_int len /* I vector lengths */ ); /********************************************************************/ /* MACROS */ /********************************************************************/ /* Rotate a32 right by 'rot' bits. Negative rot values result in rotating left. Output is 32bit int. Note: contemporary compilers recognize the C expressions below and compile them into 'ror' instructions if available. No need for inline ASM! */ #if defined(EMBEDDED_MIPS) /* For MIPS (and most likely for ARM! and >=i486) we don't have to handle negative rot's as only 5 bits of rot are encoded into ROR instructions. */ SKP_INLINE SKP_int32 SKP_ROR32(SKP_int32 a32, SKP_int rot) { SKP_uint32 _x = (SKP_uint32) a32; SKP_uint32 _r = (SKP_uint32) rot; return (SKP_int32) ((_x << (32 - _r)) | (_x >> _r)); } #else /* PPC must use this generic implementation. */ SKP_INLINE SKP_int32 SKP_ROR32( SKP_int32 a32, SKP_int rot ) { SKP_uint32 x = (SKP_uint32) a32; SKP_uint32 r = (SKP_uint32) rot; SKP_uint32 m = (SKP_uint32) -rot; if(rot <= 0) return (SKP_int32) ((x << m) | (x >> (32 - m))); else return (SKP_int32) ((x << (32 - r)) | (x >> r)); } #endif /* Allocate SKP_int16 alligned to 4-byte memory address */ #if EMBEDDED_ARM #if defined(_WIN32) && defined(_M_ARM) #define SKP_DWORD_ALIGN __declspec(align(4)) #else #define SKP_DWORD_ALIGN __attribute__((aligned(4))) #endif #else #define SKP_DWORD_ALIGN #endif /* Useful Macros that can be adjusted to other platforms */ #define SKP_memcpy(a, b, c) memcpy((a), (b), (c)) /* Dest, Src, ByteCount */ #define SKP_memset(a, b, c) memset((a), (b), (c)) /* Dest, value, ByteCount */ #define SKP_memmove(a, b, c) memmove((a), (b), (c)) /* Dest, Src, ByteCount */ /* fixed point macros */ // (a32 * b32) output have to be 32bit int #define SKP_MUL(a32, b32) ((a32) * (b32)) // (a32 * b32) output have to be 32bit uint #define SKP_MUL_uint(a32, b32) SKP_MUL(a32, b32) // a32 + (b32 * c32) output have to be 32bit int #define SKP_MLA(a32, b32, c32) SKP_ADD32((a32),((b32) * (c32))) /* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ #define SKP_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16)) /* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ #define SKP_SMLATT(a32, b32, c32) SKP_ADD32((a32),((b32) >> 16) * ((c32) >> 16)) #define SKP_SMLALBB(a64, b16, c16) SKP_ADD64((a64),(SKP_int64)((SKP_int32)(b16) * (SKP_int32)(c16))) // (a32 * b32) #define SKP_SMULL(a32, b32) ((SKP_int64)(a32) * /*(SKP_int64)*/(b32)) /* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour (just standard two's complement implementation-specific behaviour) */ #define SKP_ADD32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) + (SKP_uint32)(b))) /* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour (just standard two's complement implementation-specific behaviour) */ #define SKP_SUB32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) - (SKP_uint32)(b))) /* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ #define SKP_MLA_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), (SKP_uint32)(b32) * (SKP_uint32)(c32)) #ifndef SKP_SMLABB_ovflw #define SKP_SMLABB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULBB((b32),(c32))) #endif #define SKP_SMLATT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULTT((b32),(c32))) #define SKP_SMLAWB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWB((b32),(c32))) #define SKP_SMLAWT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWT((b32),(c32))) #define SKP_DIV32_16(a32, b16) ((SKP_int32)((a32) / (b16))) #define SKP_DIV32(a32, b32) ((SKP_int32)((a32) / (b32))) #define SKP_ADD32(a, b) ((a) + (b)) #define SKP_ADD64(a, b) ((a) + (b)) #define SKP_SUB32(a, b) ((a) - (b)) #define SKP_SAT16(a) ((a) > SKP_int16_MAX ? SKP_int16_MAX : \ ((a) < SKP_int16_MIN ? SKP_int16_MIN : (a))) #define SKP_SAT32(a) ((a) > SKP_int32_MAX ? SKP_int32_MAX : \ ((a) < SKP_int32_MIN ? SKP_int32_MIN : (a))) #define SKP_CHECK_FIT16(a) (a) #define SKP_CHECK_FIT32(a) (a) #define SKP_ADD_SAT16(a, b) (SKP_int16)SKP_SAT16( SKP_ADD32( (SKP_int32)(a), (b) ) ) /* Add with saturation for positive input values */ #define SKP_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? SKP_int32_MAX : ((a)+(b))) #define SKP_LSHIFT32(a, shift) ((a)<<(shift)) // shift >= 0, shift < 32 #define SKP_LSHIFT64(a, shift) ((a)<<(shift)) // shift >= 0, shift < 64 #define SKP_LSHIFT(a, shift) SKP_LSHIFT32(a, shift) // shift >= 0, shift < 32 #define SKP_RSHIFT32(a, shift) ((a)>>(shift)) // shift >= 0, shift < 32 #define SKP_RSHIFT64(a, shift) ((a)>>(shift)) // shift >= 0, shift < 64 #define SKP_RSHIFT(a, shift) SKP_RSHIFT32(a, shift) // shift >= 0, shift < 32 /* saturates before shifting */ #define SKP_LSHIFT_SAT32(a, shift) (SKP_LSHIFT32( SKP_LIMIT_32( (a), SKP_RSHIFT32( SKP_int32_MIN, (shift) ), \ SKP_RSHIFT32( SKP_int32_MAX, (shift) ) ), (shift) )) #define SKP_LSHIFT_ovflw(a, shift) ((a)<<(shift)) // shift >= 0, allowed to overflow #define SKP_LSHIFT_uint(a, shift) ((a)<<(shift)) // shift >= 0 #define SKP_RSHIFT_uint(a, shift) ((a)>>(shift)) // shift >= 0 #define SKP_ADD_LSHIFT(a, b, shift) ((a) + SKP_LSHIFT((b), (shift))) // shift >= 0 #define SKP_ADD_LSHIFT32(a, b, shift) SKP_ADD32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0 #define SKP_ADD_RSHIFT(a, b, shift) ((a) + SKP_RSHIFT((b), (shift))) // shift >= 0 #define SKP_ADD_RSHIFT32(a, b, shift) SKP_ADD32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0 #define SKP_ADD_RSHIFT_uint(a, b, shift) ((a) + SKP_RSHIFT_uint((b), (shift))) // shift >= 0 #define SKP_SUB_LSHIFT32(a, b, shift) SKP_SUB32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0 #define SKP_SUB_RSHIFT32(a, b, shift) SKP_SUB32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0 /* Requires that shift > 0 */ #define SKP_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) #define SKP_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) /* Number of rightshift required to fit the multiplication */ #define SKP_NSHIFT_MUL_32_32(a, b) ( -(31- (32-SKP_Silk_CLZ32(SKP_abs(a)) + (32-SKP_Silk_CLZ32(SKP_abs(b))))) ) #define SKP_min(a, b) (((a) < (b)) ? (a) : (b)) #define SKP_max(a, b) (((a) > (b)) ? (a) : (b)) /* Macro to convert floating-point constants to fixed-point */ #define SKP_FIX_CONST( C, Q ) ((SKP_int32)((C) * ((SKP_int64)1 << (Q)) + 0.5)) /* SKP_min() versions with typecast in the function call */ SKP_INLINE SKP_int SKP_min_int(SKP_int a, SKP_int b) { return (((a) < (b)) ? (a) : (b)); } SKP_INLINE SKP_int32 SKP_min_32(SKP_int32 a, SKP_int32 b) { return (((a) < (b)) ? (a) : (b)); } /* SKP_min() versions with typecast in the function call */ SKP_INLINE SKP_int SKP_max_int(SKP_int a, SKP_int b) { return (((a) > (b)) ? (a) : (b)); } SKP_INLINE SKP_int16 SKP_max_16(SKP_int16 a, SKP_int16 b) { return (((a) > (b)) ? (a) : (b)); } SKP_INLINE SKP_int32 SKP_max_32(SKP_int32 a, SKP_int32 b) { return (((a) > (b)) ? (a) : (b)); } #define SKP_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) #define SKP_LIMIT_int SKP_LIMIT #define SKP_LIMIT_32 SKP_LIMIT //#define SKP_non_neg(a) ((a) & ((-(a)) >> (8 * sizeof(a) - 1))) /* doesn't seem faster than SKP_max(0, a); #define SKP_abs(a) (((a) > 0) ? (a) : -(a)) // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN #define SKP_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) /* PSEUDO-RANDOM GENERATOR */ /* Make sure to store the result as the seed for the next call (also in between */ /* frames), otherwise result won't be random at all. When only using some of the */ /* bits, take the most significant bits by right-shifting. Do not just mask off */ /* the lowest bits. */ #define SKP_RAND(seed) (SKP_MLA_ovflw(907633515, (seed), 196314165)) // Add some multiplication functions that can be easily mapped to ARM. // SKP_SMMUL: Signed top word multiply. // ARMv6 2 instruction cycles. // ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM) //#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT(SKP_SMLAL(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)), 16) // the following seems faster on x86 //#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32) #include "SKP_Silk_Inlines.h" #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_common_pitch_est_defines.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SIGPROC_COMMON_PITCH_EST_DEFINES_H #define SIGPROC_COMMON_PITCH_EST_DEFINES_H #include "SKP_Silk_SigProc_FIX.h" /************************************************************/ /* Definitions For Fix pitch estimator */ /************************************************************/ #define PITCH_EST_MAX_FS_KHZ 24 /* Maximum sampling frequency used */ #define PITCH_EST_FRAME_LENGTH_MS 40 /* 40 ms */ #define PITCH_EST_MAX_FRAME_LENGTH (PITCH_EST_FRAME_LENGTH_MS * PITCH_EST_MAX_FS_KHZ) #define PITCH_EST_MAX_FRAME_LENGTH_ST_1 (PITCH_EST_MAX_FRAME_LENGTH >> 2) #define PITCH_EST_MAX_FRAME_LENGTH_ST_2 (PITCH_EST_MAX_FRAME_LENGTH >> 1) #define PITCH_EST_MAX_SF_FRAME_LENGTH (PITCH_EST_SUB_FRAME * PITCH_EST_MAX_FS_KHZ) #define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ #define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ #define PITCH_EST_MAX_LAG (PITCH_EST_MAX_LAG_MS * PITCH_EST_MAX_FS_KHZ) #define PITCH_EST_MIN_LAG (PITCH_EST_MIN_LAG_MS * PITCH_EST_MAX_FS_KHZ) #define PITCH_EST_NB_SUBFR 4 #define PITCH_EST_D_SRCH_LENGTH 24 #define PITCH_EST_MAX_DECIMATE_STATE_LENGTH 7 #define PITCH_EST_NB_STAGE3_LAGS 5 #define PITCH_EST_NB_CBKS_STAGE2 3 #define PITCH_EST_NB_CBKS_STAGE2_EXT 11 #define PITCH_EST_CB_mn2 1 #define PITCH_EST_CB_mx2 2 #define PITCH_EST_NB_CBKS_STAGE3_MAX 34 #define PITCH_EST_NB_CBKS_STAGE3_MID 24 #define PITCH_EST_NB_CBKS_STAGE3_MIN 16 extern const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT]; extern const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX]; extern const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ]; extern const SKP_int16 SKP_Silk_cbk_sizes_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ]; extern const SKP_int16 SKP_Silk_cbk_offsets_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ]; #endif ================================================ FILE: app/jni/include/SKP_Silk_control.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_CONTROL_H #define SKP_SILK_CONTROL_H #include "SKP_Silk_typedef.h" #ifdef __cplusplus extern "C" { #endif /***********************************************/ /* Structure for controlling encoder operation */ /***********************************************/ typedef struct { /* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000 */ SKP_int32 API_sampleRate; /* I: Maximum internal sampling rate in Hertz; 8000/12000/16000/24000 */ SKP_int32 maxInternalSampleRate; /* I: Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms */ SKP_int packetSize; /* I: Bitrate during active speech in bits/second; internally limited */ SKP_int32 bitRate; /* I: Uplink packet loss in percent (0-100) */ SKP_int packetLossPercentage; /* I: Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity */ SKP_int complexity; /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ SKP_int useInBandFEC; /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ SKP_int useDTX; } SKP_SILK_SDK_EncControlStruct; /**************************************************************************/ /* Structure for controlling decoder operation and reading decoder status */ /**************************************************************************/ typedef struct { /* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000 */ SKP_int32 API_sampleRate; /* O: Number of samples per frame */ SKP_int frameSize; /* O: Frames per packet 1, 2, 3, 4, 5 */ SKP_int framesPerPacket; /* O: Flag to indicate that the decoder has remaining payloads internally */ SKP_int moreInternalDecoderFrames; /* O: Distance between main payload and redundant payload in packets */ SKP_int inBandFECOffset; } SKP_SILK_SDK_DecControlStruct; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_define.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_DEFINE_H #define SKP_SILK_DEFINE_H #include "SKP_Silk_errors.h" #include "SKP_Silk_typedef.h" #ifdef __cplusplus extern "C" { #endif #define MAX_FRAMES_PER_PACKET 5 /* Limits on bitrate */ #define MIN_TARGET_RATE_BPS 5000 #define MAX_TARGET_RATE_BPS 100000 /* Transition bitrates between modes */ #define SWB2WB_BITRATE_BPS 25000 #define WB2SWB_BITRATE_BPS 30000 #define WB2MB_BITRATE_BPS 14000 #define MB2WB_BITRATE_BPS 18000 #define MB2NB_BITRATE_BPS 10000 #define NB2MB_BITRATE_BPS 14000 /* Integration/hysteresis threshold for lowering internal sample frequency */ /* 30000000 -> 6 sec if bitrate is 5000 bps below limit; 3 sec if bitrate is 10000 bps below limit */ #define ACCUM_BITS_DIFF_THRESHOLD 30000000 #define TARGET_RATE_TAB_SZ 8 /* DTX settings */ #define NO_SPEECH_FRAMES_BEFORE_DTX 5 /* eq 100 ms */ #define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ #define USE_LBRR 1 /* Amount of concecutive no FEC packets before telling JB */ #define NO_LBRR_THRES 10 /* Maximum delay between real packet and LBRR packet */ #define MAX_LBRR_DELAY 2 #define LBRR_IDX_MASK 1 #define INBAND_FEC_MIN_RATE_BPS 18000 /* Dont use inband FEC below this total target rate */ #define LBRR_LOSS_THRES 1 /* Start adding LBRR at this loss rate */ /* LBRR usage defines */ #define SKP_SILK_NO_LBRR 0 /* No LBRR information for this packet */ #define SKP_SILK_ADD_LBRR_TO_PLUS1 1 /* Add LBRR for this packet to packet n + 1 */ #define SKP_SILK_ADD_LBRR_TO_PLUS2 2 /* Add LBRR for this packet to packet n + 2 */ /* Frame termination indicator defines */ #define SKP_SILK_LAST_FRAME 0 /* Last frames in packet */ #define SKP_SILK_MORE_FRAMES 1 /* More frames to follow this one */ #define SKP_SILK_LBRR_VER1 2 /* LBRR information from packet n - 1 */ #define SKP_SILK_LBRR_VER2 3 /* LBRR information from packet n - 2 */ #define SKP_SILK_EXT_LAYER 4 /* Extension layers added */ /* Number of Second order Sections for SWB detection HP filter */ #define NB_SOS 3 #define HP_8_KHZ_THRES 10 /* average energy per sample, above 8 kHz */ #define CONCEC_SWB_SMPLS_THRES 480 * 15 /* 300 ms */ #define WB_DETECT_ACTIVE_SPEECH_MS_THRES 15000 /* ms of active speech needed for WB detection */ /* Low complexity setting */ #define LOW_COMPLEXITY_ONLY 0 /* Activate bandwidth transition filtering for mode switching */ #define SWITCH_TRANSITION_FILTERING 1 /* Decoder Parameters */ #define DEC_HP_ORDER 2 /* Maximum sampling frequency, should be 16 for some embedded platforms */ #define MAX_FS_KHZ 24 #define MAX_API_FS_KHZ 48 /* Signal Types used by silk */ #define SIG_TYPE_VOICED 0 #define SIG_TYPE_UNVOICED 1 /* VAD Types used by silk */ #define NO_VOICE_ACTIVITY 0 #define VOICE_ACTIVITY 1 /* Number of samples per frame */ #define FRAME_LENGTH_MS 20 #define MAX_FRAME_LENGTH ( FRAME_LENGTH_MS * MAX_FS_KHZ ) /* Milliseconds of lookahead for pitch analysis */ #define LA_PITCH_MS 2 #define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ ) /* Length of LPC window used in find pitch */ #define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) ) #define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ ) /* Order of LPC used in find pitch */ #define MAX_FIND_PITCH_LPC_ORDER 16 #define PITCH_EST_COMPLEXITY_HC_MODE SKP_Silk_PITCH_EST_MAX_COMPLEX #define PITCH_EST_COMPLEXITY_MC_MODE SKP_Silk_PITCH_EST_MID_COMPLEX #define PITCH_EST_COMPLEXITY_LC_MODE SKP_Silk_PITCH_EST_MIN_COMPLEX /* Milliseconds of lookahead for noise shape analysis */ #define LA_SHAPE_MS 5 #define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ ) /* Max length of LPC window used in noise shape analysis */ #define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ ) /* Max number of bytes in payload output buffer (may contain multiple frames) */ #define MAX_ARITHM_BYTES 1024 #define RANGE_CODER_WRITE_BEYOND_BUFFER -1 #define RANGE_CODER_CDF_OUT_OF_RANGE -2 #define RANGE_CODER_NORMALIZATION_FAILED -3 #define RANGE_CODER_ZERO_INTERVAL_WIDTH -4 #define RANGE_CODER_DECODER_CHECK_FAILED -5 #define RANGE_CODER_READ_BEYOND_BUFFER -6 #define RANGE_CODER_ILLEGAL_SAMPLING_RATE -7 #define RANGE_CODER_DEC_PAYLOAD_TOO_LONG -8 /* dB level of lowest gain quantization level */ #define MIN_QGAIN_DB 6 /* dB level of highest gain quantization level */ #define MAX_QGAIN_DB 86 /* Number of gain quantization levels */ #define N_LEVELS_QGAIN 64 /* Max increase in gain quantization index */ #define MAX_DELTA_GAIN_QUANT 40 /* Max decrease in gain quantization index */ #define MIN_DELTA_GAIN_QUANT -4 /* Quantization offsets (multiples of 4) */ #define OFFSET_VL_Q10 32 #define OFFSET_VH_Q10 100 #define OFFSET_UVL_Q10 100 #define OFFSET_UVH_Q10 256 /* Maximum numbers of iterations used to stabilize a LPC vector */ #define MAX_LPC_STABILIZE_ITERATIONS 20 #define MAX_LPC_ORDER 16 #define MIN_LPC_ORDER 10 /* Find Pred Coef defines */ #define LTP_ORDER 5 /* LTP quantization settings */ #define NB_LTP_CBKS 3 /* Number of subframes */ #define NB_SUBFR 4 /* Flag to use harmonic noise shaping */ #define USE_HARM_SHAPING 1 /* Max LPC order of noise shaping filters */ #define MAX_SHAPE_LPC_ORDER 16 #define HARM_SHAPE_FIR_TAPS 3 /* Maximum number of delayed decision states */ #define MAX_DEL_DEC_STATES 4 #define LTP_BUF_LENGTH 512 #define LTP_MASK (LTP_BUF_LENGTH - 1) #define DECISION_DELAY 32 #define DECISION_DELAY_MASK (DECISION_DELAY - 1) /* number of subframes for excitation entropy coding */ #define SHELL_CODEC_FRAME_LENGTH 16 #define MAX_NB_SHELL_BLOCKS (MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH) /* number of rate levels, for entropy coding of excitation */ #define N_RATE_LEVELS 10 /* maximum sum of pulses per shell coding frame */ #define MAX_PULSES 18 #define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ #if( MAX_LPC_ORDER > DECISION_DELAY ) # define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER #else # define NSQ_LPC_BUF_LENGTH DECISION_DELAY #endif /***********************/ /* High pass filtering */ /***********************/ #define HIGH_PASS_INPUT 1 /***************************/ /* Voice activity detector */ /***************************/ #define VAD_N_BANDS 4 #define VAD_INTERNAL_SUBFRAMES_LOG2 2 #define VAD_INTERNAL_SUBFRAMES (1 << VAD_INTERNAL_SUBFRAMES_LOG2) #define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */ #define VAD_NOISE_LEVELS_BIAS 50 /* Sigmoid settings */ #define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */ #define VAD_SNR_FACTOR_Q16 45000 /* smoothing for SNR measurement */ #define VAD_SNR_SMOOTH_COEF_Q18 4096 /******************/ /* NLSF quantizer */ /******************/ # define NLSF_MSVQ_MAX_CB_STAGES 10 /* Update manually when changing codebooks */ # define NLSF_MSVQ_MAX_VECTORS_IN_STAGE 128 /* Update manually when changing codebooks */ # define NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END 16 /* Update manually when changing codebooks */ #define NLSF_MSVQ_FLUCTUATION_REDUCTION 1 #define MAX_NLSF_MSVQ_SURVIVORS 16 #define MAX_NLSF_MSVQ_SURVIVORS_LC_MODE 2 #define MAX_NLSF_MSVQ_SURVIVORS_MC_MODE 4 /* Based on above defines, calculate how much memory is necessary to allocate */ #if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) ) # define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE NLSF_MSVQ_MAX_VECTORS_IN_STAGE #else # define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END #endif #if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) ) # define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED NLSF_MSVQ_MAX_VECTORS_IN_STAGE #else # define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END #endif #define NLSF_MSVQ_SURV_MAX_REL_RD 0.1f /* Must be < 0.5 */ /* Transition filtering for mode switching */ #if SWITCH_TRANSITION_FILTERING # define TRANSITION_TIME_UP_MS 5120 // 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4) # define TRANSITION_TIME_DOWN_MS 2560 // 2560 = 32 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 32*(20*4) # define TRANSITION_NB 3 /* Hardcoded in tables */ # define TRANSITION_NA 2 /* Hardcoded in tables */ # define TRANSITION_INT_NUM 5 /* Hardcoded in tables */ # define TRANSITION_FRAMES_UP ( TRANSITION_TIME_UP_MS / FRAME_LENGTH_MS ) # define TRANSITION_FRAMES_DOWN ( TRANSITION_TIME_DOWN_MS / FRAME_LENGTH_MS ) # define TRANSITION_INT_STEPS_UP ( TRANSITION_FRAMES_UP / ( TRANSITION_INT_NUM - 1 ) ) # define TRANSITION_INT_STEPS_DOWN ( TRANSITION_FRAMES_DOWN / ( TRANSITION_INT_NUM - 1 ) ) #endif /* Row based */ #define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column))) #define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column))) /* Column based */ #ifndef matrix_c_ptr # define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column))) #endif #define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column))) /* BWE factors to apply after packet loss */ #define BWE_AFTER_LOSS_Q16 63570 /* Defines for CN generation */ #define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */ #define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */ #define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */ #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_errors.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_ERRORS_H #define SKP_SILK_ERRORS_H #ifdef __cplusplus extern "C" { #endif /******************/ /* Error messages */ /******************/ #define SKP_SILK_NO_ERROR 0 /**************************/ /* Encoder error messages */ /**************************/ /* Input length is not a multiplum of 10 ms, or length is longer than the packet length */ #define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1 /* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */ #define SKP_SILK_ENC_FS_NOT_SUPPORTED -2 /* Packet size not 20, 40, 60, 80 or 100 ms */ #define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3 /* Allocated payload buffer too short */ #define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4 /* Loss rate not between 0 and 100 percent */ #define SKP_SILK_ENC_INVALID_LOSS_RATE -5 /* Complexity setting not valid, use 0, 1 or 2 */ #define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING -6 /* Inband FEC setting not valid, use 0 or 1 */ #define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING -7 /* DTX setting not valid, use 0 or 1 */ #define SKP_SILK_ENC_INVALID_DTX_SETTING -8 /* Internal encoder error */ #define SKP_SILK_ENC_INTERNAL_ERROR -9 /**************************/ /* Decoder error messages */ /**************************/ /* Output sampling frequency lower than internal decoded sampling frequency */ #define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY -10 /* Payload size exceeded the maximum allowed 1024 bytes */ #define SKP_SILK_DEC_PAYLOAD_TOO_LARGE -11 /* Payload has bit errors */ #define SKP_SILK_DEC_PAYLOAD_ERROR -12 #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_macros.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef _SKP_SILK_API_C_H_ #define _SKP_SILK_API_C_H_ // This is an inline header file for general platform. // (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16 output have to be 32bit int #define SKP_SMULWB(a32, b32) ((((a32) >> 16) * (SKP_int32)((SKP_int16)(b32))) + ((((a32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(b32))) >> 16)) // a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16 output have to be 32bit int #define SKP_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16))) // (a32 * (b32 >> 16)) >> 16 #define SKP_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) // a32 + (b32 * (c32 >> 16)) >> 16 #define SKP_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) // (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32)) output have to be 32bit int #define SKP_SMULBB(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * (SKP_int32)((SKP_int16)(b32))) // a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) output have to be 32bit int #define SKP_SMLABB(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32))) // (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16) #define SKP_SMULBT(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * ((b32) >> 16)) // a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16) #define SKP_SMLABT(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16)) // a64 + (b32 * c32) #define SKP_SMLAL(a64, b32, c32) (SKP_ADD64((a64), ((SKP_int64)(b32) * (SKP_int64)(c32)))) // (a32 * b32) >> 16 #define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)) // a32 + ((b32 * c32) >> 16) #define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16)) // (SKP_int32)(((SKP_int64)a32 * b32) >> 32) #define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32) /* add/subtract with output saturated */ #define SKP_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \ ((((a) & (b)) & 0x80000000) != 0 ? SKP_int32_MIN : (a)+(b)) : \ ((((a) | (b)) & 0x80000000) == 0 ? SKP_int32_MAX : (a)+(b)) ) #define SKP_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \ (( (a) & ((b)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a)-(b)) : \ ((((a)^0x80000000) & (b) & 0x80000000) ? SKP_int32_MAX : (a)-(b)) ) SKP_INLINE SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16) { SKP_int32 out32 = 0; if( in16 == 0 ) { return 16; } /* test nibbles */ if( in16 & 0xFF00 ) { if( in16 & 0xF000 ) { in16 >>= 12; } else { out32 += 4; in16 >>= 8; } } else { if( in16 & 0xFFF0 ) { out32 += 8; in16 >>= 4; } else { out32 += 12; } } /* test bits and return */ if( in16 & 0xC ) { if( in16 & 0x8 ) return out32 + 0; else return out32 + 1; } else { if( in16 & 0xE ) return out32 + 2; else return out32 + 3; } } SKP_INLINE SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32) { /* test highest 16 bits and convert to SKP_int16 */ if( in32 & 0xFFFF0000 ) { return SKP_Silk_CLZ16((SKP_int16)(in32 >> 16)); } else { return SKP_Silk_CLZ16((SKP_int16)in32) + 16; } } #endif //_SKP_SILK_API_C_H_ ================================================ FILE: app/jni/include/SKP_Silk_macros_arm.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef _SKP_SILK_API_ARM_H_ #define _SKP_SILK_API_ARM_H_ // This is an inline header file for embedded arm platform. #if EMBEDDED_ARM==4 extern SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16); extern SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32); // (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16 #define SKP_SMULWB(a32, b32) ((((a32) >> 16) * (SKP_int32)((SKP_int16)(b32))) + ((((a32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(b32))) >> 16)) // a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16 #define SKP_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16))) /*SKP_INLINE SKP_int32 SKP_SMULWT(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32, tmp; SKP_int32 tmp32=0xFFFF0000; asm volatile("and %1, %3, %4 \n\t smull %3, %0, %2, %1" : "=&r" (out32), "=&r" (tmp) : "r" (a32), "r" (b32), "r" (tmp32)); return(out32); }*/ // (a32 * (b32 >> 16)) >> 16 #define SKP_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) // a32 + (b32 * (c32 >> 16)) >> 16 #define SKP_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) // (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32)) #define SKP_SMULBB(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * (SKP_int32)((SKP_int16)(b32))) // a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) #define SKP_SMLABB(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32))) // a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) #define SKP_SMLABB_ovflw(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32))) // (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16) #define SKP_SMULBT(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * ((b32) >> 16)) // a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16) #define SKP_SMLABT(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16)) SKP_INLINE SKP_int64 SKP_SMLAL(SKP_int64 a64, SKP_int32 b32, SKP_int32 c32) { #ifdef IPHONE // IPHONE LLVM compiler doesn't understand Q/R representation. a64 = (SKP_int64)b32 * c32; return(a64); #else __asm__ __volatile__ ("smlal %Q0, %R0, %2, %3" : "=r" (a64) : "0" (a64), "r" (b32), "r" (c32)); return(a64); #endif } // (a32 * b32) >> 16 #define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)) // a32 + ((b32 * c32) >> 16) #define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16)) /* add/subtract with output saturated */ #define SKP_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \ ((((a) & (b)) & 0x80000000) != 0 ? SKP_int32_MIN : (a)+(b)) : \ ((((a) | (b)) & 0x80000000) == 0 ? SKP_int32_MAX : (a)+(b)) ) #define SKP_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \ (( (a) & ((b)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a)-(b)) : \ ((((a)^0x80000000) & (b) & 0x80000000) ? SKP_int32_MAX : (a)-(b)) ) #define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32) #else SKP_INLINE SKP_int32 SKP_SMULWB(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("smulwb %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMLAWB(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) { SKP_int32 out32; __asm__ __volatile__ ("smlawb %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMULWT(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("smulwt %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMLAWT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) { SKP_int32 out32; __asm__ __volatile__ ("smlawt %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMULBB(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("smulbb %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMLABB(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) { SKP_int32 out32; __asm__ __volatile__ ("smlabb %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMLABB_ovflw(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) { SKP_int32 out32; __asm__ __volatile__ ("smlabb %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMULBT(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("smulbt %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMLABT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) { SKP_int32 out32; __asm__ __volatile__ ("smlabt %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32)); return(out32); } SKP_INLINE SKP_int64 SKP_SMLAL(SKP_int64 a64, SKP_int32 b32, SKP_int32 c32) { #ifdef IPHONE // IPHONE LLVM compiler doesn't understand Q/R representation. a64 = (SKP_int64)b32 * c32; return(a64); #else __asm__ __volatile__ ("smlal %Q0, %R0, %2, %3" : "=r" (a64) : "0" (a64), "r" (b32), "r" (c32)); return(a64); #endif } #define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)) /*SKP_INLINE SKP_int32 SKP_SMULWW(SKP_int32 a32, SKP_int32 b32) { SKP_int64 tmp; SKP_int32 out32; __asm__ __volatile__ ("smull %Q1, %R1, %2, %3 \n\t mov %0, %R1, lsl #16 \n\t add %0, %0, %Q1, lsr #16" : "=&r" (out32), "=&r" (tmp) : "r" (a32), "r" (b32)); return(out32); }*/ #define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16)) /*SKP_INLINE SKP_int32 SKP_SMLAWW(a32, b32, c32){ SKP_int64 tmp; SKP_int32 out32; __asm__ __volatile__ ("smull %Q1, %R1, %3, %4 \n\t add %0, %2, %R1, lsl #16 \n\t add %0, %0, %Q1, lsr #16" : "=&r" (out32), "=&r" (tmp) : "r" (a32), "r" (b32), "r" (c32)); return(out32); }*/ SKP_INLINE SKP_int32 SKP_ADD_SAT32(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("qadd %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SUB_SAT32(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("qsub %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16) { SKP_int32 out32; __asm__ __volatile__ ("movs %0, %1, lsl #16 \n\tclz %0, %0 \n\t it eq \n\t moveq %0, #16" : "=r" (out32) : "r" (in16) : "cc"); return(out32); } SKP_INLINE SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32) { SKP_int32 out32; __asm__ __volatile__ ("clz %0, %1" : "=r" (out32) : "r" (in32)); return(out32); } #if EMBEDDED_ARM < 6 #define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32) #endif #endif // Some ARMv6 specific instructions: #if EMBEDDED_ARM>=6 SKP_INLINE SKP_int32 SKP_SMMUL(SKP_int32 a32, SKP_int32 b32){ SKP_int32 out32; __asm__ __volatile__ ("smmul %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMUAD(SKP_int32 a32, SKP_int32 b32) { SKP_int32 out32; __asm__ __volatile__ ("smuad %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32)); return(out32); } SKP_INLINE SKP_int32 SKP_SMLAD(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) { SKP_int32 out32; __asm__ __volatile__ ("smlad %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32)); return(out32); } #endif #endif // _SKP_SILK_API_ARM_H_ ================================================ FILE: app/jni/include/SKP_Silk_main.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_MAIN_H #define SKP_SILK_MAIN_H #include "SKP_Silk_SigProc_FIX.h" #ifdef __cplusplus extern "C" { #endif #include "SKP_Silk_define.h" #include "SKP_Silk_structs.h" #include "SKP_Silk_tables.h" #include "SKP_Silk_PLC.h" /* Encodes signs of excitation */ void SKP_Silk_encode_signs( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ const SKP_int8 q[], /* I pulse signal */ const SKP_int length, /* I length of input */ const SKP_int sigtype, /* I Signal type */ const SKP_int QuantOffsetType, /* I Quantization offset type */ const SKP_int RateLevelIndex /* I Rate Level Index */ ); /* Decodes signs of excitation */ void SKP_Silk_decode_signs( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ SKP_int q[], /* I/O pulse signal */ const SKP_int length, /* I length of output */ const SKP_int sigtype, /* I Signal type */ const SKP_int QuantOffsetType, /* I Quantization offset type */ const SKP_int RateLevelIndex /* I Rate Level Index */ ); /* Control internal sampling rate */ SKP_int SKP_Silk_control_audio_bandwidth( SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */ ); /***************/ /* Shell coder */ /***************/ /* Encode quantization indices of excitation */ void SKP_Silk_encode_pulses( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ const SKP_int sigtype, /* I Sigtype */ const SKP_int QuantOffsetType, /* I QuantOffsetType */ const SKP_int8 q[], /* I quantization indices */ const SKP_int frame_length /* I Frame length */ ); /* Shell encoder, operates on one shell code frame of 16 pulses */ void SKP_Silk_shell_encoder( SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_int *pulses0 /* I data: nonnegative pulse amplitudes */ ); /* Shell decoder, operates on one shell code frame of 16 pulses */ void SKP_Silk_shell_decoder( SKP_int *pulses0, /* O data: nonnegative pulse amplitudes */ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_int pulses4 /* I number of pulses per pulse-subframe */ ); /***************/ /* Range coder */ /***************/ /* Range encoder for one symbol */ void SKP_Silk_range_encoder( SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_int data, /* I uncompressed data */ const SKP_uint16 prob[] /* I cumulative density functions */ ); /* Range encoder for multiple symbols */ void SKP_Silk_range_encoder_multi( SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_int data[], /* I uncompressed data [nSymbols] */ const SKP_uint16 * const prob[], /* I cumulative density functions */ const SKP_int nSymbols /* I number of data symbols */ ); /* Range decoder for one symbol */ void SKP_Silk_range_decoder( SKP_int data[], /* O uncompressed data */ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_uint16 prob[], /* I cumulative density function */ SKP_int probIx /* I initial (middle) entry of cdf */ ); /* Range decoder for multiple symbols */ void SKP_Silk_range_decoder_multi( SKP_int data[], /* O uncompressed data [nSymbols] */ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */ const SKP_uint16 * const prob[], /* I cumulative density functions */ const SKP_int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */ const SKP_int nSymbols /* I number of data symbols */ ); /* Initialize range coder structure for encoder */ void SKP_Silk_range_enc_init( SKP_Silk_range_coder_state *psRC /* O compressor data structure */ ); /* Initialize range coder structure for decoder */ void SKP_Silk_range_dec_init( SKP_Silk_range_coder_state *psRC, /* O compressor data structure */ const SKP_uint8 buffer[], /* I buffer for compressed data [bufferLength] */ const SKP_int32 bufferLength /* I buffer length (in bytes) */ ); /* Determine length of bitstream */ SKP_int SKP_Silk_range_coder_get_length( /* O returns number of BITS in stream */ const SKP_Silk_range_coder_state *psRC, /* I compressed data structure */ SKP_int *nBytes /* O number of BYTES in stream */ ); /* Write decodable stream to buffer, and determine its length */ void SKP_Silk_range_enc_wrap_up( SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */ ); /* Check that any remaining bits in the last byte are set to 1 */ void SKP_Silk_range_coder_check_after_decoding( SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */ ); /* Gain scalar quantization with hysteresis, uniform on log scale */ void SKP_Silk_gains_quant( SKP_int ind[ NB_SUBFR ], /* O gain indices */ SKP_int32 gain_Q16[ NB_SUBFR ], /* I/O gains (quantized out) */ SKP_int *prev_ind, /* I/O last index in previous frame */ const SKP_int conditional /* I first gain is delta coded if 1 */ ); /* Gains scalar dequantization, uniform on log scale */ void SKP_Silk_gains_dequant( SKP_int32 gain_Q16[ NB_SUBFR ], /* O quantized gains */ const SKP_int ind[ NB_SUBFR ], /* I gain indices */ SKP_int *prev_ind, /* I/O last index in previous frame */ const SKP_int conditional /* I first gain is delta coded if 1 */ ); /* Convert NLSF parameters to stable AR prediction filter coefficients */ void SKP_Silk_NLSF2A_stable( SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */ const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */ const SKP_int LPC_order /* I LPC/LSF order */ ); /* Interpolate two vectors */ void SKP_Silk_interpolate( SKP_int xi[ MAX_LPC_ORDER ], /* O interpolated vector */ const SKP_int x0[ MAX_LPC_ORDER ], /* I first vector */ const SKP_int x1[ MAX_LPC_ORDER ], /* I second vector */ const SKP_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ const SKP_int d /* I number of parameters */ ); /***********************************/ /* Noise shaping quantization (NSQ)*/ /***********************************/ void SKP_Silk_NSQ( SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ const SKP_int16 x[], /* I prefiltered input signal */ SKP_int8 q[], /* O quantized qulse signal */ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int Lambda_Q10, /* I */ const SKP_int LTP_scale_Q14 /* I LTP state scaling */ ); /* Noise shaping using delayed decision */ void SKP_Silk_NSQ_del_dec( SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */ const SKP_int16 x[], /* I Prefiltered input signal */ SKP_int8 q[], /* O Quantized pulse signal */ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */ const SKP_int Lambda_Q10, /* I */ const SKP_int LTP_scale_Q14 /* I LTP state scaling */ ); /************/ /* Silk VAD */ /************/ /* Initialize the Silk VAD */ SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ); /* Silk VAD noise level estimation */ void SKP_Silk_VAD_GetNoiseLevels( const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ); /* Get speech activity level in Q8 */ SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */ SKP_int *pSA_Q8, /* O Speech activity level in Q8 */ SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */ SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */ SKP_int *pTilt_Q15, /* O current frame's frequency tilt */ const SKP_int16 pIn[], /* I PCM input [framelength] */ const SKP_int framelength /* I Input frame length */ ); /* Detect signal in 8 - 12 khz range */ void SKP_Silk_detect_SWB_input( SKP_Silk_detect_SWB_state *psSWBdetect, /* I/O Encoder state */ const SKP_int16 samplesIn[], /* I Input to encoder */ SKP_int nSamplesIn /* I Length of input */ ); #if SWITCH_TRANSITION_FILTERING /* Low-pass filter with variable cutoff frequency based on */ /* piece-wise linear interpolation between elliptic filters */ /* Start by setting transition_frame_no = 1; */ void SKP_Silk_LP_variable_cutoff( SKP_Silk_LP_state *psLP, /* I/O LP filter state */ SKP_int16 *out, /* O Low-pass filtered output signal */ const SKP_int16 *in, /* I Input signal */ const SKP_int frame_length /* I Frame length */ ); #endif /****************************************************/ /* Decoder Functions */ /****************************************************/ SKP_int SKP_Silk_create_decoder( SKP_Silk_decoder_state **ppsDec /* I/O Decoder state pointer pointer */ ); SKP_int SKP_Silk_free_decoder( SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */ ); SKP_int SKP_Silk_init_decoder( SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */ ); /* Set decoder sampling rate */ void SKP_Silk_decoder_set_fs( SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */ SKP_int fs_kHz /* I Sampling frequency (kHz) */ ); /****************/ /* Decode frame */ /****************/ SKP_int SKP_Silk_decode_frame( SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ SKP_int16 pOut[], /* O Pointer to output speech frame */ SKP_int16 *pN, /* O Pointer to size of output frame */ const SKP_uint8 pCode[], /* I Pointer to payload */ const SKP_int nBytes, /* I Payload length */ SKP_int action, /* I Action from Jitter Buffer */ SKP_int *decBytes /* O Used bytes to decode this frame */ ); /* Decode parameters from payload */ void SKP_Silk_decode_parameters( SKP_Silk_decoder_state *psDec, /* I/O State */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int q[], /* O Excitation signal */ const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */ ); /* Core decoder. Performs inverse NSQ operation LTP + LPC */ void SKP_Silk_decode_core( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */ SKP_int16 xq[], /* O Decoded speech */ const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */ ); /* NLSF vector decoder */ void SKP_Silk_NLSF_MSVQ_decode( SKP_int *pNLSF_Q15, /* O Pointer to decoded output [LPC_ORDER x 1] */ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */ const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */ const SKP_int LPC_order /* I LPC order */ ); /**********************/ /* Arithmetic coding */ /*********************/ /* Decode quantization indices of excitation (Shell coding) */ void SKP_Silk_decode_pulses( SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int q[], /* O Excitation signal */ const SKP_int frame_length /* I Frame length (preliminary) */ ); /******************/ /* CNG */ /******************/ /* Reset CNG */ void SKP_Silk_CNG_Reset( SKP_Silk_decoder_state *psDec /* I/O Decoder state */ ); /* Updates CNG estimate, and applies the CNG when packet was lost */ void SKP_Silk_CNG( SKP_Silk_decoder_state *psDec, /* I/O Decoder state */ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */ SKP_int16 signal[], /* I/O Signal */ SKP_int length /* I Length of residual */ ); /* Encoding of various parameters */ void SKP_Silk_encode_parameters( SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */ SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */ const SKP_int8 *q /* I Quantization indices */ ); /* Extract lowest layer encoding */ void SKP_Silk_get_low_layer_internal( const SKP_uint8 *indata, /* I: Encoded input vector */ const SKP_int16 nBytesIn, /* I: Number of input Bytes */ SKP_uint8 *Layer0data, /* O: Layer0 payload */ SKP_int16 *nLayer0Bytes /* O: Number of FEC Bytes */ ); /* Resets LBRR buffer, used if packet size changes */ void SKP_Silk_LBRR_reset( SKP_Silk_encoder_state *psEncC /* I/O Pointer to Silk encoder state */ ); #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_main_FIX.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_MAIN_FIX_H #define SKP_SILK_MAIN_FIX_H #include #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_structs_FIX.h" #include "SKP_Silk_main.h" #include "SKP_Silk_PLC.h" #define TIC(TAG_NAME) #define TOC(TAG_NAME) #ifndef FORCE_CPP_BUILD #ifdef __cplusplus extern "C" { #endif #endif /*********************/ /* Encoder Functions */ /*********************/ /* Initializes the Silk encoder state */ SKP_int SKP_Silk_init_encoder_FIX( SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ ); /* Control the Silk encoder */ SKP_int SKP_Silk_control_encoder_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */ const SKP_int PacketSize_ms, /* I Packet length (ms) */ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */ const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */ const SKP_int DTX_enabled, /* I Enable / disable DTX */ const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ ); /* Encoder main function */ SKP_int SKP_Silk_encode_frame_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ SKP_uint8 *pCode, /* O Pointer to payload */ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes; */ /* input: max length; output: used */ const SKP_int16 *pIn /* I Pointer to input speech frame */ ); /* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode with lower bitrate */ void SKP_Silk_LBRR_encode_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ SKP_uint8 *pCode, /* O Pointer to payload */ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */ SKP_int16 xfw[] /* I Input signal */ ); /* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ void SKP_Silk_HP_variable_cutoff_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ SKP_int16 *out, /* O high-pass filtered output signal */ const SKP_int16 *in /* I input signal */ ); /****************/ /* Prefiltering */ /****************/ void SKP_Silk_prefilter_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ const SKP_Silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */ SKP_int16 xw[], /* O Weighted signal */ const SKP_int16 x[] /* I Speech signal */ ); /**************************************************************/ /* Compute noise shaping coefficients and initial gain values */ /**************************************************************/ void SKP_Silk_noise_shape_analysis_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ const SKP_int16 *pitch_res, /* I LPC residual from pitch analysis */ const SKP_int16 *x /* I Input signal [ frame_length + la_shape ] */ ); /* Autocorrelations for a warped frequency axis */ void SKP_Silk_warped_autocorrelation_FIX( SKP_int32 *corr, /* O Result [order + 1] */ SKP_int *scale, /* O Scaling of the correlation vector */ const SKP_int16 *input, /* I Input data to correlate */ const SKP_int16 warping_Q16, /* I Warping coefficient */ const SKP_int length, /* I Length of input */ const SKP_int order /* I Correlation order (even) */ ); /* Processing of gains */ void SKP_Silk_process_gains_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control */ ); /* Control low bitrate redundancy usage */ void SKP_Silk_LBRR_ctrl_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control *psEncCtrlC /* I/O encoder control */ ); /* Calculation of LTP state scaling */ void SKP_Silk_LTP_scale_ctrl_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control */ ); /**********************************************/ /* Prediction Analysis */ /**********************************************/ /* Find pitch lags */ void SKP_Silk_find_pitch_lags_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ SKP_int16 res[], /* O residual */ const SKP_int16 x[] /* I Speech signal */ ); void SKP_Silk_find_pred_coefs_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ const SKP_int16 res_pitch[] /* I Residual from pitch analysis */ ); void SKP_Silk_find_LPC_FIX( SKP_int NLSF_Q15[], /* O NLSFs */ SKP_int *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */ const SKP_int prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */ const SKP_int useInterpolatedLSFs, /* I Flag */ const SKP_int LPC_order, /* I LPC order */ const SKP_int16 x[], /* I Input signal */ const SKP_int subfr_length /* I Input signal subframe length including preceeding samples */ ); void SKP_Silk_warped_LPC_analysis_filter_FIX( SKP_int32 state[], /* I/O State [order + 1] */ SKP_int16 res[], /* O Residual signal [length] */ const SKP_int16 coef_Q13[], /* I Coefficients [order] */ const SKP_int16 input[], /* I Input signal [length] */ const SKP_int16 lambda_Q16, /* I Warping factor */ const SKP_int length, /* I Length of input signal */ const SKP_int order /* I Filter order (even) */ ); void SKP_Silk_LTP_analysis_filter_FIX( SKP_int16 *LTP_res, /* O: LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length ) */ const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each NB_SUBFR subframe */ const SKP_int pitchL[ NB_SUBFR ], /* I: Pitch lag, one for each subframe */ const SKP_int32 invGains_Q16[ NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */ const SKP_int subfr_length, /* I: Length of each subframe */ const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */ ); /* Finds LTP vector from correlations */ void SKP_Silk_find_LTP_FIX( SKP_int16 b_Q14[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */ const SKP_int16 r_first[], /* I residual signal after LPC signal + state for first 10 ms */ const SKP_int16 r_last[], /* I residual signal after LPC signal + state for last 10 ms */ const SKP_int lag[ NB_SUBFR ], /* I LTP lags */ const SKP_int32 Wght_Q15[ NB_SUBFR ], /* I weights */ const SKP_int subfr_length, /* I subframe length */ const SKP_int mem_offset, /* I number of samples in LTP memory */ SKP_int corr_rshifts[ NB_SUBFR ] /* O right shifts applied to correlations */ ); /* LTP tap quantizer */ void SKP_Silk_quant_LTP_gains_FIX( SKP_int16 B_Q14[], /* I/O (un)quantized LTP gains */ SKP_int cbk_index[], /* O Codebook Index */ SKP_int *periodicity_index, /* O Periodicity Index */ const SKP_int32 W_Q18[], /* I Error Weights in Q18 */ SKP_int mu_Q8, /* I Mu value (R/D tradeoff) */ SKP_int lowComplexity /* I Flag for low complexity */ ); /******************/ /* NLSF Quantizer */ /******************/ /* Limit, stabilize, convert and quantize NLSFs. */ void SKP_Silk_process_NLSFs_FIX( SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ SKP_int *pNLSF_Q15 /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ ); /* NLSF vector encoder */ void SKP_Silk_NLSF_MSVQ_encode_FIX( SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */ SKP_int *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ const SKP_int *pNLSF_q_Q15_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */ const SKP_int *pW_Q6, /* I NLSF weight vector [ LPC_ORDER ] */ const SKP_int NLSF_mu_Q15, /* I Rate weight for the RD optimization */ const SKP_int NLSF_mu_fluc_red_Q16, /* I Fluctuation reduction error weight */ const SKP_int NLSF_MSVQ_Survivors, /* I Max survivors from each stage */ const SKP_int LPC_order, /* I LPC order */ const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */ ); /* Rate-Distortion calculations for multiple input data vectors */ void SKP_Silk_NLSF_VQ_rate_distortion_FIX( SKP_int32 *pRD_Q20, /* O Rate-distortion values [psNLSF_CBS->nVectors*N] */ const SKP_Silk_NLSF_CBS *psNLSF_CBS, /* I NLSF codebook stage struct */ const SKP_int *in_Q15, /* I Input vectors to be quantized */ const SKP_int *w_Q6, /* I Weight vector */ const SKP_int32 *rate_acc_Q5, /* I Accumulated rates from previous stage */ const SKP_int mu_Q15, /* I Weight between weighted error and rate */ const SKP_int N, /* I Number of input vectors to be quantized */ const SKP_int LPC_order /* I LPC order */ ); /* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */ void SKP_Silk_NLSF_VQ_sum_error_FIX( SKP_int32 *err_Q20, /* O Weighted quantization errors [N*K] */ const SKP_int *in_Q15, /* I Input vectors to be quantized [N*LPC_order] */ const SKP_int *w_Q6, /* I Weighting vectors [N*LPC_order] */ const SKP_int16 *pCB_Q15, /* I Codebook vectors [K*LPC_order] */ const SKP_int N, /* I Number of input vectors */ const SKP_int K, /* I Number of codebook vectors */ const SKP_int LPC_order /* I Number of LPCs */ ); /* Entropy constrained MATRIX-weighted VQ, for a single input data vector */ void SKP_Silk_VQ_WMat_EC_FIX( SKP_int *ind, /* O index of best codebook vector */ SKP_int32 *rate_dist_Q14, /* O best weighted quantization error + mu * rate*/ const SKP_int16 *in_Q14, /* I input vector to be quantized */ const SKP_int32 *W_Q18, /* I weighting matrix */ const SKP_int16 *cb_Q14, /* I codebook */ const SKP_int16 *cl_Q6, /* I code length for each codebook vector */ const SKP_int mu_Q8, /* I tradeoff between weighted error and rate */ SKP_int L /* I number of vectors in codebook */ ); /******************/ /* Linear Algebra */ /******************/ /* Calculates correlation matrix X'*X */ void SKP_Silk_corrMatrix_FIX( const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const SKP_int L, /* I Length of vectors */ const SKP_int order, /* I Max lag for correlation */ const SKP_int head_room, /* I Desired headroom */ SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/ SKP_int *rshifts /* I/O Right shifts of correlations */ ); /* Calculates correlation vector X'*t */ void SKP_Silk_corrVector_FIX( const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ const SKP_int16 *t, /* I Target vector [L] */ const SKP_int L, /* I Length of vectors */ const SKP_int order, /* I Max lag for correlation */ SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ const SKP_int rshifts /* I Right shifts of correlations */ ); /* Add noise to matrix diagonal */ void SKP_Silk_regularize_correlations_FIX( SKP_int32 *XX, /* I/O Correlation matrices */ SKP_int32 *xx, /* I/O Correlation values */ SKP_int32 noise, /* I Noise to add */ SKP_int D /* I Dimension of XX */ ); /* Solves Ax = b, assuming A is symmetric */ void SKP_Silk_solve_LDL_FIX( SKP_int32 *A, /* I Pointer to symetric square matrix A */ SKP_int M, /* I Size of matrix */ const SKP_int32 *b, /* I Pointer to b vector */ SKP_int32 *x_Q16 /* O Pointer to x solution vector */ ); /* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ SKP_int32 SKP_Silk_residual_energy16_covar_FIX( const SKP_int16 *c, /* I Prediction vector */ const SKP_int32 *wXX, /* I Correlation matrix */ const SKP_int32 *wXx, /* I Correlation vector */ SKP_int32 wxx, /* I Signal energy */ SKP_int D, /* I Dimension */ SKP_int cQ /* I Q value for c vector 0 - 15 */ ); /* Calculates residual energies of input subframes where all subframes have LPC_order */ /* of preceeding samples */ void SKP_Silk_residual_energy_FIX( SKP_int32 nrgs[ NB_SUBFR ], /* O Residual energy per subframe */ SKP_int nrgsQ[ NB_SUBFR ], /* O Q value per subframe */ const SKP_int16 x[], /* I Input signal */ SKP_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],/* I AR coefs for each frame half */ const SKP_int32 gains[ NB_SUBFR ], /* I Quantization gains */ const SKP_int subfr_length, /* I Subframe length */ const SKP_int LPC_order /* I LPC order */ ); #ifndef FORCE_CPP_BUILD #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* FORCE_CPP_BUILD */ #endif /* SKP_SILK_MAIN_FIX_H */ ================================================ FILE: app/jni/include/SKP_Silk_pitch_est_defines.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SIGPROCFIX_PITCH_EST_DEFINES_H #define SIGPROCFIX_PITCH_EST_DEFINES_H /************************************************************/ /* Definitions For Fix pitch estimator */ /************************************************************/ #define PITCH_EST_SHORTLAG_BIAS_Q15 6554 /* 0.2f. for logarithmic weighting */ #define PITCH_EST_PREVLAG_BIAS_Q15 6554 /* Prev lag bias */ #define PITCH_EST_FLATCONTOUR_BIAS_Q20 52429 /* 0.05f */ #endif ================================================ FILE: app/jni/include/SKP_Silk_resampler_private.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler_structs.h * * * * Description: Structs for IIR/FIR resamplers * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * * * */ #ifndef SKP_Silk_RESAMPLER_H #define SKP_Silk_RESAMPLER_H #ifdef __cplusplus extern "C" { #endif #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_resampler_structs.h" #include "SKP_Silk_resampler_rom.h" /* Number of input samples to process in the inner loop */ #define RESAMPLER_MAX_BATCH_SIZE_IN 480 /* Description: Hybrid IIR/FIR polyphase implementation of resampling */ void SKP_Silk_resampler_private_IIR_FIR( void *SS, /* I/O: Resampler state */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ); /* Description: Hybrid IIR/FIR polyphase implementation of resampling */ void SKP_Silk_resampler_private_down_FIR( void *SS, /* I/O: Resampler state */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ); /* Copy */ void SKP_Silk_resampler_private_copy( void *SS, /* I/O: Resampler state (unused) */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ SKP_int32 inLen /* I: Number of input samples */ ); /* Upsample by a factor 2, high quality */ void SKP_Silk_resampler_private_up2_HQ_wrapper( void *SS, /* I/O: Resampler state (unused) */ SKP_int16 *out, /* O: Output signal [ 2 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of input samples */ ); /* Upsample by a factor 2, high quality */ void SKP_Silk_resampler_private_up2_HQ( SKP_int32 *S, /* I/O: Resampler state [ 6 ] */ SKP_int16 *out, /* O: Output signal [ 2 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of input samples */ ); /* Upsample 4x, low quality */ void SKP_Silk_resampler_private_up4( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ 4 * len ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 len /* I: Number of input samples */ ); /* Downsample 4x, low quality */ void SKP_Silk_resampler_private_down4( SKP_int32 *S, /* I/O: State vector [ 2 ] */ SKP_int16 *out, /* O: Output signal [ floor(len/2) ] */ const SKP_int16 *in, /* I: Input signal [ len ] */ SKP_int32 inLen /* I: Number of input samples */ ); /* Second order AR filter */ void SKP_Silk_resampler_private_AR2( SKP_int32 S[], /* I/O: State vector [ 2 ] */ SKP_int32 out_Q8[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ const SKP_int16 A_Q14[], /* I: AR coefficients, Q14 */ SKP_int32 len /* I: Signal length */ ); /* Fourth order ARMA filter */ void SKP_Silk_resampler_private_ARMA4( SKP_int32 S[], /* I/O: State vector [ 4 ] */ SKP_int16 out[], /* O: Output signal */ const SKP_int16 in[], /* I: Input signal */ const SKP_int16 Coef[], /* I: ARMA coefficients [ 7 ] */ SKP_int32 len /* I: Signal length */ ); #ifdef __cplusplus } #endif #endif // SKP_Silk_RESAMPLER_H ================================================ FILE: app/jni/include/SKP_Silk_resampler_rom.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resample_rom.h * * * * Description: Header file for FIR resampling of * * 32 and 44 kHz input * * * * Copyright 2007 (c), Skype Limited * * All rights reserved. * * * * Date: 070807 * * */ #ifndef _SKP_SILK_FIX_RESAMPLER_ROM_H_ #define _SKP_SILK_FIX_RESAMPLER_ROM_H_ #ifdef __cplusplus extern "C" { #endif #include "SKP_Silk_typedef.h" #include "SKP_Silk_resampler_structs.h" #define RESAMPLER_DOWN_ORDER_FIR 12 #define RESAMPLER_ORDER_FIR_144 6 /* Tables for 2x downsampler. Values above 32767 intentionally wrap to a negative value. */ extern const SKP_int16 SKP_Silk_resampler_down2_0; extern const SKP_int16 SKP_Silk_resampler_down2_1; /* Tables for 2x upsampler, low quality. Values above 32767 intentionally wrap to a negative value. */ extern const SKP_int16 SKP_Silk_resampler_up2_lq_0; extern const SKP_int16 SKP_Silk_resampler_up2_lq_1; /* Tables for 2x upsampler, high quality. Values above 32767 intentionally wrap to a negative value. */ extern const SKP_int16 SKP_Silk_resampler_up2_hq_0[ 2 ]; extern const SKP_int16 SKP_Silk_resampler_up2_hq_1[ 2 ]; extern const SKP_int16 SKP_Silk_resampler_up2_hq_notch[ 4 ]; /* Tables with IIR and FIR coefficients for fractional downsamplers */ extern const SKP_int16 SKP_Silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ]; extern const SKP_int16 SKP_Silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ]; extern const SKP_int16 SKP_Silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ]; extern const SKP_int16 SKP_Silk_Resampler_3_8_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ]; extern const SKP_int16 SKP_Silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ]; extern const SKP_int16 SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ]; extern const SKP_int16 SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 + 3 ]; /* Tables with coefficients for 4th order ARMA filter */ extern const SKP_int16 SKP_Silk_Resampler_320_441_ARMA4_COEFS[ 7 ]; extern const SKP_int16 SKP_Silk_Resampler_240_441_ARMA4_COEFS[ 7 ]; extern const SKP_int16 SKP_Silk_Resampler_160_441_ARMA4_COEFS[ 7 ]; extern const SKP_int16 SKP_Silk_Resampler_120_441_ARMA4_COEFS[ 7 ]; extern const SKP_int16 SKP_Silk_Resampler_80_441_ARMA4_COEFS[ 7 ]; /* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */ extern const SKP_int16 SKP_Silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ]; #ifdef __cplusplus } #endif #endif // _SKP_SILK_FIX_RESAMPLER_ROM_H_ ================================================ FILE: app/jni/include/SKP_Silk_resampler_structs.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ /* * * File Name: SKP_Silk_resampler_structs.h * * * * Description: Structs for IIR/FIR resamplers * * * * Copyright 2010 (c), Skype Limited * * All rights reserved. * * * * */ #ifndef SKP_Silk_RESAMPLER_STRUCTS_H #define SKP_Silk_RESAMPLER_STRUCTS_H #ifdef __cplusplus extern "C" { #endif /* Flag to enable support for input/output sampling rates above 48 kHz. Turn off for embedded devices */ #define RESAMPLER_SUPPORT_ABOVE_48KHZ 1 #define SKP_Silk_RESAMPLER_MAX_FIR_ORDER 16 #define SKP_Silk_RESAMPLER_MAX_IIR_ORDER 6 typedef struct _SKP_Silk_resampler_state_struct{ SKP_int32 sIIR[ SKP_Silk_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ SKP_int32 sFIR[ SKP_Silk_RESAMPLER_MAX_FIR_ORDER ]; SKP_int32 sDown2[ 2 ]; void (*resampler_function)( void *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); void (*up2_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); SKP_int32 batchSize; SKP_int32 invRatio_Q16; SKP_int32 FIR_Fracs; SKP_int32 input2x; const SKP_int16 *Coefs; #if RESAMPLER_SUPPORT_ABOVE_48KHZ SKP_int32 sDownPre[ 2 ]; SKP_int32 sUpPost[ 2 ]; void (*down_pre_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); void (*up_post_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 ); SKP_int32 batchSizePrePost; SKP_int32 ratio_Q16; SKP_int32 nPreDownsamplers; SKP_int32 nPostUpsamplers; #endif SKP_int32 magic_number; } SKP_Silk_resampler_state_struct; #ifdef __cplusplus } #endif #endif /* SKP_Silk_RESAMPLER_STRUCTS_H */ ================================================ FILE: app/jni/include/SKP_Silk_setup_complexity.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #include "SKP_Silk_main.h" #include "SKP_Silk_tuning_parameters.h" SKP_INLINE SKP_int SKP_Silk_setup_complexity( SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */ ) { SKP_int ret = SKP_SILK_NO_ERROR; /* Check that settings are valid */ if( LOW_COMPLEXITY_ONLY && Complexity != 0 ) { ret = SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING; } /* Set encoding complexity */ if( Complexity == 0 || LOW_COMPLEXITY_ONLY ) { /* Low complexity */ psEncC->Complexity = 0; psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_LC_MODE; psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE, 16 ); psEncC->pitchEstimationLPCOrder = 6; psEncC->shapingLPCOrder = 8; psEncC->la_shape = 3 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 1; psEncC->useInterpolatedNLSFs = 0; psEncC->LTPQuantLowComplexity = 1; psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_LC_MODE; psEncC->warping_Q16 = 0; } else if( Complexity == 1 ) { /* Medium complexity */ psEncC->Complexity = 1; psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_MC_MODE; psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE, 16 ); psEncC->pitchEstimationLPCOrder = 12; psEncC->shapingLPCOrder = 12; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = 2; psEncC->useInterpolatedNLSFs = 0; psEncC->LTPQuantLowComplexity = 0; psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_MC_MODE; psEncC->warping_Q16 = psEncC->fs_kHz * SKP_FIX_CONST( WARPING_MULTIPLIER, 16 ); } else if( Complexity == 2 ) { /* High complexity */ psEncC->Complexity = 2; psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_HC_MODE; psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE, 16 ); psEncC->pitchEstimationLPCOrder = 16; psEncC->shapingLPCOrder = 16; psEncC->la_shape = 5 * psEncC->fs_kHz; psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES; psEncC->useInterpolatedNLSFs = 1; psEncC->LTPQuantLowComplexity = 0; psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS; psEncC->warping_Q16 = psEncC->fs_kHz * SKP_FIX_CONST( WARPING_MULTIPLIER, 16 ); } else { ret = SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING; } /* Do not allow higher pitch estimation LPC order than predict LPC order */ psEncC->pitchEstimationLPCOrder = SKP_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder ); psEncC->shapeWinLength = 5 * psEncC->fs_kHz + 2 * psEncC->la_shape; SKP_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER ); SKP_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER ); SKP_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES ); SKP_assert( psEncC->warping_Q16 <= 32767 ); SKP_assert( psEncC->la_shape <= LA_SHAPE_MAX ); SKP_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX ); return( ret ); } ================================================ FILE: app/jni/include/SKP_Silk_structs.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_STRUCTS_H #define SKP_SILK_STRUCTS_H #include "SKP_Silk_typedef.h" #include "SKP_Silk_SigProc_FIX.h" #include "SKP_Silk_define.h" #ifdef __cplusplus extern "C" { #endif /************************************/ /* Noise shaping quantization state */ /************************************/ typedef struct { SKP_int16 xq[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for quantized output signal */ SKP_int32 sLTP_shp_Q10[ 2 * MAX_FRAME_LENGTH ]; SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ]; SKP_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; SKP_int32 sLF_AR_shp_Q12; SKP_int lagPrev; SKP_int sLTP_buf_idx; SKP_int sLTP_shp_buf_idx; SKP_int32 rand_seed; SKP_int32 prev_inv_gain_Q16; SKP_int rewhite_flag; } SKP_Silk_nsq_state; /* FIX*/ /* Struct for Low BitRate Redundant (LBRR) information */ typedef struct { SKP_uint8 payload[ MAX_ARITHM_BYTES ]; SKP_int nBytes; /* Number of bytes in payload */ SKP_int usage; /* Tells how the payload should be used as FEC */ } SKP_SILK_LBRR_struct; /********************************/ /* VAD state */ /********************************/ typedef struct { SKP_int32 AnaState[ 2 ]; /* Analysis filterbank state: 0-8 kHz */ SKP_int32 AnaState1[ 2 ]; /* Analysis filterbank state: 0-4 kHz */ SKP_int32 AnaState2[ 2 ]; /* Analysis filterbank state: 0-2 kHz */ SKP_int32 XnrgSubfr[ VAD_N_BANDS ]; /* Subframe energies */ SKP_int32 NrgRatioSmth_Q8[ VAD_N_BANDS ]; /* Smoothed energy level in each band */ SKP_int16 HPstate; /* State of differentiator in the lowest band */ SKP_int32 NL[ VAD_N_BANDS ]; /* Noise energy level in each band */ SKP_int32 inv_NL[ VAD_N_BANDS ]; /* Inverse noise energy level in each band */ SKP_int32 NoiseLevelBias[ VAD_N_BANDS ]; /* Noise level estimator bias/offset */ SKP_int32 counter; /* Frame counter used in the initial phase */ } SKP_Silk_VAD_state; /*******************************/ /* Range encoder/decoder state */ /*******************************/ typedef struct { SKP_int32 bufferLength; SKP_int32 bufferIx; SKP_uint32 base_Q32; SKP_uint32 range_Q16; SKP_int32 error; SKP_uint8 buffer[ MAX_ARITHM_BYTES ]; /* Buffer containing payload */ } SKP_Silk_range_coder_state; /* Input frequency range detection struct */ typedef struct { SKP_int32 S_HP_8_kHz[ NB_SOS ][ 2 ]; /* HP filter State */ SKP_int32 ConsecSmplsAboveThres; SKP_int32 ActiveSpeech_ms; /* Accumulated time with active speech */ SKP_int SWB_detected; /* Flag to indicate SWB input */ SKP_int WB_detected; /* Flag to indicate WB input */ } SKP_Silk_detect_SWB_state; #if SWITCH_TRANSITION_FILTERING /* Variable cut-off low-pass filter state */ typedef struct { SKP_int32 In_LP_State[ 2 ]; /* Low pass filter state */ SKP_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ SKP_int mode; /* Operating mode, 0: switch down, 1: switch up */ } SKP_Silk_LP_state; #endif /* Structure for one stage of MSVQ */ typedef struct { const SKP_int32 nVectors; const SKP_int16 *CB_NLSF_Q15; const SKP_int16 *Rates_Q5; } SKP_Silk_NLSF_CBS; /* Structure containing NLSF MSVQ codebook */ typedef struct { const SKP_int32 nStages; /* Fields for (de)quantizing */ const SKP_Silk_NLSF_CBS *CBStages; const SKP_int *NDeltaMin_Q15; /* Fields for arithmetic (de)coding */ const SKP_uint16 *CDF; const SKP_uint16 * const *StartPtr; const SKP_int *MiddleIx; } SKP_Silk_NLSF_CB_struct; /********************************/ /* Encoder state */ /********************************/ typedef struct { SKP_Silk_range_coder_state sRC; /* Range coder state */ SKP_Silk_range_coder_state sRC_LBRR; /* Range coder state (for low bitrate redundancy) */ SKP_Silk_nsq_state sNSQ; /* Noise Shape Quantizer State */ SKP_Silk_nsq_state sNSQ_LBRR; /* Noise Shape Quantizer State ( for low bitrate redundancy ) */ #if HIGH_PASS_INPUT SKP_int32 In_HP_State[ 2 ]; /* High pass filter state */ #endif #if SWITCH_TRANSITION_FILTERING SKP_Silk_LP_state sLP; /* Low pass filter state */ #endif SKP_Silk_VAD_state sVAD; /* Voice activity detector state */ SKP_int LBRRprevLastGainIndex; SKP_int prev_sigtype; SKP_int typeOffsetPrev; /* Previous signal type and quantization offset */ SKP_int prevLag; SKP_int prev_lagIndex; SKP_int32 API_fs_Hz; /* API sampling frequency (Hz) */ SKP_int32 prev_API_fs_Hz; /* Previous API sampling frequency (Hz) */ SKP_int maxInternal_fs_kHz; /* Maximum internal sampling frequency (kHz) */ SKP_int fs_kHz; /* Internal sampling frequency (kHz) */ SKP_int fs_kHz_changed; /* Did we switch yet? */ SKP_int frame_length; /* Frame length (samples) */ SKP_int subfr_length; /* Subframe length (samples) */ SKP_int la_pitch; /* Look-ahead for pitch analysis (samples) */ SKP_int la_shape; /* Look-ahead for noise shape analysis (samples) */ SKP_int shapeWinLength; /* Window length for noise shape analysis (samples) */ SKP_int32 TargetRate_bps; /* Target bitrate (bps) */ SKP_int PacketSize_ms; /* Number of milliseconds to put in each packet */ SKP_int PacketLoss_perc; /* Packet loss rate measured by farend */ SKP_int32 frameCounter; SKP_int Complexity; /* Complexity setting: 0-> low; 1-> medium; 2->high */ SKP_int nStatesDelayedDecision; /* Number of states in delayed decision quantization */ SKP_int useInterpolatedNLSFs; /* Flag for using NLSF interpolation */ SKP_int shapingLPCOrder; /* Filter order for noise shaping filters */ SKP_int predictLPCOrder; /* Filter order for prediction filters */ SKP_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ SKP_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ SKP_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ SKP_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ SKP_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ SKP_int first_frame_after_reset; /* Flag for deactivating NLSF interp. and fluc. reduction after resets */ SKP_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ SKP_int warping_Q16; /* Warping parameter for warped noise shaping */ /* Input/output buffering */ SKP_int16 inputBuf[ MAX_FRAME_LENGTH ]; /* buffer containin input signal */ SKP_int inputBufIx; SKP_int nFramesInPayloadBuf; /* number of frames sitting in outputBuf */ SKP_int nBytesInPayloadBuf; /* number of bytes sitting in outputBuf */ /* Parameters For LTP scaling Control */ SKP_int frames_since_onset; const SKP_Silk_NLSF_CB_struct *psNLSF_CB[ 2 ]; /* Pointers to voiced/unvoiced NLSF codebooks */ /* Struct for Inband LBRR */ SKP_SILK_LBRR_struct LBRR_buffer[ MAX_LBRR_DELAY ]; SKP_int oldest_LBRR_idx; SKP_int useInBandFEC; /* Saves the API setting for query */ SKP_int LBRR_enabled; SKP_int LBRR_GainIncreases; /* Number of shifts to Gains to get LBRR rate Voiced frames */ /* Bitrate control */ SKP_int32 bitrateDiff; /* Accumulated diff. between the target bitrate and the switch bitrates */ SKP_int32 bitrate_threshold_up; /* Threshold for switching to a higher internal sample frequency */ SKP_int32 bitrate_threshold_down; /* Threshold for switching to a lower internal sample frequency */ SKP_Silk_resampler_state_struct resampler_state; /* DTX */ SKP_int noSpeechCounter; /* Counts concecutive nonactive frames, used by DTX */ SKP_int useDTX; /* Flag to enable DTX */ SKP_int inDTX; /* Flag to signal DTX period */ SKP_int vadFlag; /* Flag to indicate Voice Activity */ /* Struct for detecting SWB input */ SKP_Silk_detect_SWB_state sSWBdetect; /* Buffers */ SKP_int8 q[ MAX_FRAME_LENGTH ]; /* pulse signal buffer */ SKP_int8 q_LBRR[ MAX_FRAME_LENGTH ]; /* pulse signal buffer */ } SKP_Silk_encoder_state; /************************/ /* Encoder control */ /************************/ typedef struct { /* Quantization indices */ SKP_int lagIndex; SKP_int contourIndex; SKP_int PERIndex; SKP_int LTPIndex[ NB_SUBFR ]; SKP_int NLSFIndices[ NLSF_MSVQ_MAX_CB_STAGES ]; /* NLSF path of quantized LSF vector */ SKP_int NLSFInterpCoef_Q2; SKP_int GainsIndices[ NB_SUBFR ]; SKP_int32 Seed; SKP_int LTP_scaleIndex; SKP_int RateLevelIndex; SKP_int QuantOffsetType; SKP_int sigtype; /* Prediction and coding parameters */ SKP_int pitchL[ NB_SUBFR ]; SKP_int LBRR_usage; /* Low bitrate redundancy usage */ } SKP_Silk_encoder_control; /* Struct for Packet Loss Concealment */ typedef struct { SKP_int32 pitchL_Q8; /* Pitch lag to use for voiced concealment */ SKP_int16 LTPCoef_Q14[ LTP_ORDER ]; /* LTP coeficients to use for voiced concealment */ SKP_int16 prevLPC_Q12[ MAX_LPC_ORDER ]; SKP_int last_frame_lost; /* Was previous frame lost */ SKP_int32 rand_seed; /* Seed for unvoiced signal generation */ SKP_int16 randScale_Q14; /* Scaling of unvoiced random signal */ SKP_int32 conc_energy; SKP_int conc_energy_shift; SKP_int16 prevLTP_scale_Q14; SKP_int32 prevGain_Q16[ NB_SUBFR ]; SKP_int fs_kHz; } SKP_Silk_PLC_struct; /* Struct for CNG */ typedef struct { SKP_int32 CNG_exc_buf_Q10[ MAX_FRAME_LENGTH ]; SKP_int CNG_smth_NLSF_Q15[ MAX_LPC_ORDER ]; SKP_int32 CNG_synth_state[ MAX_LPC_ORDER ]; SKP_int32 CNG_smth_Gain_Q16; SKP_int32 rand_seed; SKP_int fs_kHz; } SKP_Silk_CNG_struct; /********************************/ /* Decoder state */ /********************************/ typedef struct { SKP_Silk_range_coder_state sRC; /* Range coder state */ SKP_int32 prev_inv_gain_Q16; SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ]; SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + MAX_LPC_ORDER ]; SKP_int32 exc_Q10[ MAX_FRAME_LENGTH ]; SKP_int32 res_Q10[ MAX_FRAME_LENGTH ]; SKP_int16 outBuf[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for output signal */ SKP_int lagPrev; /* Previous Lag */ SKP_int LastGainIndex; /* Previous gain index */ SKP_int LastGainIndex_EnhLayer; /* Previous gain index */ SKP_int typeOffsetPrev; /* Previous signal type and quantization offset */ SKP_int32 HPState[ DEC_HP_ORDER ]; /* HP filter state */ const SKP_int16 *HP_A; /* HP filter AR coefficients */ const SKP_int16 *HP_B; /* HP filter MA coefficients */ SKP_int fs_kHz; /* Sampling frequency in kHz */ SKP_int32 prev_API_sampleRate; /* Previous API sample frequency (Hz) */ SKP_int frame_length; /* Frame length (samples) */ SKP_int subfr_length; /* Subframe length (samples) */ SKP_int LPC_order; /* LPC order */ SKP_int prevNLSF_Q15[ MAX_LPC_ORDER ]; /* Used to interpolate LSFs */ SKP_int first_frame_after_reset; /* Flag for deactivating NLSF interp. and fluc. reduction after resets */ /* For buffering payload in case of more frames per packet */ SKP_int nBytesLeft; SKP_int nFramesDecoded; SKP_int nFramesInPacket; SKP_int moreInternalDecoderFrames; SKP_int FrameTermination; SKP_Silk_resampler_state_struct resampler_state; const SKP_Silk_NLSF_CB_struct *psNLSF_CB[ 2 ]; /* Pointers to voiced/unvoiced NLSF codebooks */ /* Parameters used to investigate if inband FEC is used */ SKP_int vadFlag; SKP_int no_FEC_counter; /* Counts number of frames wo inband FEC */ SKP_int inband_FEC_offset; /* 0: no FEC, 1: FEC with 1 packet offset, 2: FEC w 2 packets offset */ /* CNG state */ SKP_Silk_CNG_struct sCNG; /* Stuff used for PLC */ SKP_int lossCnt; SKP_int prev_sigtype; /* Previous sigtype */ SKP_Silk_PLC_struct sPLC; } SKP_Silk_decoder_state; /************************/ /* Decoder control */ /************************/ typedef struct { /* prediction and coding parameters */ SKP_int pitchL[ NB_SUBFR ]; SKP_int32 Gains_Q16[ NB_SUBFR ]; SKP_int32 Seed; /* holds interpolated and final coefficients, 4-byte aligned */ SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ]; SKP_int LTP_scale_Q14; /* quantization indices */ SKP_int PERIndex; SKP_int RateLevelIndex; SKP_int QuantOffsetType; SKP_int sigtype; SKP_int NLSFInterpCoef_Q2; } SKP_Silk_decoder_control; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_structs_FIX.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_STRUCTS_FIX_H #define SKP_SILK_STRUCTS_FIX_H #include "SKP_Silk_typedef.h" #include "SKP_Silk_main.h" #include "SKP_Silk_structs.h" #ifdef __cplusplus extern "C" { #endif /********************************/ /* Noise shaping analysis state */ /********************************/ typedef struct { SKP_int LastGainIndex; SKP_int32 HarmBoost_smth_Q16; SKP_int32 HarmShapeGain_smth_Q16; SKP_int32 Tilt_smth_Q16; } SKP_Silk_shape_state_FIX; /********************************/ /* Prefilter state */ /********************************/ typedef struct { SKP_int16 sLTP_shp[ LTP_BUF_LENGTH ]; SKP_int32 sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ]; // Q14 SKP_int sLTP_shp_buf_idx; SKP_int32 sLF_AR_shp_Q12; SKP_int32 sLF_MA_shp_Q12; SKP_int sHarmHP; SKP_int32 rand_seed; SKP_int lagPrev; } SKP_Silk_prefilter_state_FIX; /*****************************/ /* Prediction analysis state */ /*****************************/ typedef struct { SKP_int pitch_LPC_win_length; SKP_int min_pitch_lag; /* Lowest possible pitch lag (samples) */ SKP_int max_pitch_lag; /* Highest possible pitch lag (samples) */ SKP_int prev_NLSFq_Q15[ MAX_LPC_ORDER ]; /* Previously quantized NLSF vector */ } SKP_Silk_predict_state_FIX; /********************************/ /* Encoder state FIX */ /********************************/ typedef struct { SKP_Silk_encoder_state sCmn; /* Common struct, shared with floating-point code */ #if HIGH_PASS_INPUT SKP_int32 variable_HP_smth1_Q15; /* State of first smoother */ SKP_int32 variable_HP_smth2_Q15; /* State of second smoother */ #endif SKP_Silk_shape_state_FIX sShape; /* Shape state */ SKP_Silk_prefilter_state_FIX sPrefilt; /* Prefilter State */ SKP_Silk_predict_state_FIX sPred; /* Prediction state */ /* Buffer for find pitch and noise shape analysis */ SKP_DWORD_ALIGN SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; SKP_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator, approx Q15 */ SKP_int mu_LTP_Q8; /* Rate-distortion tradeoff in LTP quantization */ SKP_int32 SNR_dB_Q7; /* Quality setting */ SKP_int32 avgGain_Q16; /* average gain during active speech */ SKP_int32 avgGain_Q16_one_bit_per_sample; /* average gain during active speech */ SKP_int BufferedInChannel_ms; /* Simulated number of ms buffer because of exceeded TargetRate_bps */ SKP_int speech_activity_Q8; /* Speech activity in Q8 */ /* Parameters For LTP scaling Control */ SKP_int prevLTPredCodGain_Q7; SKP_int HPLTPredCodGain_Q7; SKP_int32 inBandFEC_SNR_comp_Q8; /* Compensation to SNR_dB when using inband FEC Voiced */ } SKP_Silk_encoder_state_FIX; /************************/ /* Encoder control FIX */ /************************/ typedef struct { SKP_Silk_encoder_control sCmn; /* Common struct, shared with floating-point code */ /* Prediction and coding parameters */ SKP_int32 Gains_Q16[ NB_SUBFR ]; SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ]; SKP_int LTP_scale_Q14; /* Noise shaping parameters */ /* Testing */ SKP_DWORD_ALIGN SKP_int16 AR1_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; SKP_DWORD_ALIGN SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; SKP_int32 LF_shp_Q14[ NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ SKP_int GainsPre_Q14[ NB_SUBFR ]; SKP_int HarmBoost_Q14[ NB_SUBFR ]; SKP_int Tilt_Q14[ NB_SUBFR ]; SKP_int HarmShapeGain_Q14[ NB_SUBFR ]; SKP_int Lambda_Q10; SKP_int input_quality_Q14; SKP_int coding_quality_Q14; SKP_int32 pitch_freq_low_Hz; SKP_int current_SNR_dB_Q7; /* measures */ SKP_int sparseness_Q8; SKP_int32 predGain_Q16; SKP_int LTPredCodGain_Q7; SKP_int input_quality_bands_Q15[ VAD_N_BANDS ]; SKP_int input_tilt_Q15; SKP_int32 ResNrg[ NB_SUBFR ]; /* Residual energy per subframe */ SKP_int ResNrgQ[ NB_SUBFR ]; /* Q domain for the residual energy > 0 */ } SKP_Silk_encoder_control_FIX; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_tables.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_TABLES_H #define SKP_SILK_TABLES_H #include "SKP_Silk_define.h" #include "SKP_Silk_structs.h" #define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ #define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ #ifdef __cplusplus extern "C" { #endif /* entropy coding tables */ extern const SKP_uint16 SKP_Silk_type_offset_CDF[ 5 ]; /* 5 */ extern const SKP_uint16 SKP_Silk_type_offset_joint_CDF[ 4 ][ 5 ]; /* 20 */ extern const SKP_int SKP_Silk_type_offset_CDF_offset; extern const SKP_uint16 SKP_Silk_gain_CDF[ 2 ][ N_LEVELS_QGAIN + 1 ]; /* 130 */ extern const SKP_int SKP_Silk_gain_CDF_offset; extern const SKP_uint16 SKP_Silk_delta_gain_CDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 2 ]; /* 46 */ extern const SKP_int SKP_Silk_delta_gain_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_lag_NB_CDF[ 8 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 130 */ extern const SKP_int SKP_Silk_pitch_lag_NB_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_lag_MB_CDF[ 12 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 194 */ extern const SKP_int SKP_Silk_pitch_lag_MB_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_lag_WB_CDF[ 16 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 258 */ extern const SKP_int SKP_Silk_pitch_lag_WB_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_lag_SWB_CDF[ 24 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 386 */ extern const SKP_int SKP_Silk_pitch_lag_SWB_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_contour_CDF[ 35 ]; /* 35 */ extern const SKP_int SKP_Silk_pitch_contour_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_contour_NB_CDF[ 12 ]; /* 12 */ extern const SKP_int SKP_Silk_pitch_contour_NB_CDF_offset; extern const SKP_uint16 SKP_Silk_pitch_delta_CDF[23]; /* 23 */ extern const SKP_int SKP_Silk_pitch_delta_CDF_offset; extern const SKP_uint16 SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS ][ MAX_PULSES + 3 ]; /* 210 */ extern const SKP_int SKP_Silk_pulses_per_block_CDF_offset; extern const SKP_int16 SKP_Silk_pulses_per_block_BITS_Q6[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 180 */ extern const SKP_uint16 SKP_Silk_rate_levels_CDF[ 2 ][ N_RATE_LEVELS ]; /* 20 */ extern const SKP_int SKP_Silk_rate_levels_CDF_offset; extern const SKP_int16 SKP_Silk_rate_levels_BITS_Q6[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ extern const SKP_int SKP_Silk_max_pulses_table[ 4 ]; /* 4 */ extern const SKP_uint16 SKP_Silk_shell_code_table0[ 33 ]; /* 33 */ extern const SKP_uint16 SKP_Silk_shell_code_table1[ 52 ]; /* 52 */ extern const SKP_uint16 SKP_Silk_shell_code_table2[ 102 ]; /* 102 */ extern const SKP_uint16 SKP_Silk_shell_code_table3[ 207 ]; /* 207 */ extern const SKP_uint16 SKP_Silk_shell_code_table_offsets[ 19 ]; /* 19 */ extern const SKP_uint16 SKP_Silk_lsb_CDF[ 3 ]; /* 3 */ extern const SKP_uint16 SKP_Silk_sign_CDF[ 36 ]; /* 36 */ extern const SKP_uint16 SKP_Silk_LTP_per_index_CDF[ 4 ]; /* 4 */ extern const SKP_int SKP_Silk_LTP_per_index_CDF_offset; extern const SKP_int16 * const SKP_Silk_LTP_gain_BITS_Q6_ptrs[ NB_LTP_CBKS ]; /* 3 */ extern const SKP_uint16 * const SKP_Silk_LTP_gain_CDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ extern const SKP_int SKP_Silk_LTP_gain_CDF_offsets[ NB_LTP_CBKS ]; /* 3 */ extern const SKP_int32 SKP_Silk_LTP_gain_middle_avg_RD_Q14; extern const SKP_uint16 SKP_Silk_LTPscale_CDF[ 4 ]; /* 4 */ extern const SKP_int SKP_Silk_LTPscale_offset; /* Tables for LTPScale */ extern const SKP_int16 SKP_Silk_LTPScales_table_Q14[ 3 ]; extern const SKP_uint16 SKP_Silk_vadflag_CDF[ 3 ]; /* 3 */ extern const SKP_int SKP_Silk_vadflag_offset; extern const SKP_int SKP_Silk_SamplingRates_table[ 4 ]; /* 4 */ extern const SKP_uint16 SKP_Silk_SamplingRates_CDF[ 5 ]; /* 5 */ extern const SKP_int SKP_Silk_SamplingRates_offset; extern const SKP_uint16 SKP_Silk_NLSF_interpolation_factor_CDF[ 6 ]; extern const SKP_int SKP_Silk_NLSF_interpolation_factor_offset; /* NLSF codebooks */ extern const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_16, SKP_Silk_NLSF_CB1_16; extern const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_10, SKP_Silk_NLSF_CB1_10; /* quantization tables */ extern const SKP_int16 * const SKP_Silk_LTP_vq_ptrs_Q14[ NB_LTP_CBKS ]; /* 168 */ extern const SKP_int SKP_Silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ /* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ extern const SKP_int32 TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; extern const SKP_int32 TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; extern const SKP_int32 TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; extern const SKP_int32 TargetRate_table_SWB[ TARGET_RATE_TAB_SZ ]; extern const SKP_int32 SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; extern const SKP_int32 SNR_table_one_bit_per_sample_Q7[ 4 ]; /* Filter coeficicnts for HP filter: 4. Order filter implementad as two biquad filters */ extern const SKP_int16 SKP_Silk_SWB_detect_B_HP_Q13[ NB_SOS ][ 3 ]; extern const SKP_int16 SKP_Silk_SWB_detect_A_HP_Q13[ NB_SOS ][ 2 ]; /* Decoder high-pass filter coefficients for 24 kHz sampling */ extern const SKP_int16 SKP_Silk_Dec_A_HP_24[ DEC_HP_ORDER ]; /* 2 */ extern const SKP_int16 SKP_Silk_Dec_B_HP_24[ DEC_HP_ORDER + 1 ]; /* 3 */ /* Decoder high-pass filter coefficients for 16 kHz sampling */ extern const SKP_int16 SKP_Silk_Dec_A_HP_16[ DEC_HP_ORDER ]; /* 2 */ extern const SKP_int16 SKP_Silk_Dec_B_HP_16[ DEC_HP_ORDER + 1 ]; /* 3 */ /* Decoder high-pass filter coefficients for 12 kHz sampling */ extern const SKP_int16 SKP_Silk_Dec_A_HP_12[ DEC_HP_ORDER ]; /* 2 */ extern const SKP_int16 SKP_Silk_Dec_B_HP_12[ DEC_HP_ORDER + 1 ]; /* 3 */ /* Decoder high-pass filter coefficients for 8 kHz sampling */ extern const SKP_int16 SKP_Silk_Dec_A_HP_8[ DEC_HP_ORDER ]; /* 2 */ extern const SKP_int16 SKP_Silk_Dec_B_HP_8[ DEC_HP_ORDER + 1 ]; /* 3 */ /* Table for frame termination indication */ extern const SKP_uint16 SKP_Silk_FrameTermination_CDF[ 5 ]; extern const SKP_int SKP_Silk_FrameTermination_offset; /* Table for random seed */ extern const SKP_uint16 SKP_Silk_Seed_CDF[ 5 ]; extern const SKP_int SKP_Silk_Seed_offset; /* Quantization offsets */ extern const SKP_int16 SKP_Silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; #if SWITCH_TRANSITION_FILTERING /* Interpolation points for filter coefficients used in the bandwidth transition smoother */ extern const SKP_int32 SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ]; extern const SKP_int32 SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ]; #endif #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_tables_NLSF_CB0_10.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_TABLES_NLSF_CB0_10_H #define SKP_SILK_TABLES_NLSF_CB0_10_H #include "SKP_Silk_define.h" #ifdef __cplusplus extern "C" { #endif #define NLSF_MSVQ_CB0_10_STAGES 6 #define NLSF_MSVQ_CB0_10_VECTORS 120 /* NLSF codebook entropy coding tables */ extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ NLSF_MSVQ_CB0_10_VECTORS + NLSF_MSVQ_CB0_10_STAGES ]; extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr[ NLSF_MSVQ_CB0_10_STAGES ]; extern const SKP_int SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx[ NLSF_MSVQ_CB0_10_STAGES ]; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_tables_NLSF_CB0_16.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_TABLES_NLSF_CB0_16_H #define SKP_SILK_TABLES_NLSF_CB0_16_H #include "SKP_Silk_define.h" #ifdef __cplusplus extern "C" { #endif #define NLSF_MSVQ_CB0_16_STAGES 10 #define NLSF_MSVQ_CB0_16_VECTORS 216 /* NLSF codebook entropy coding tables */ extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ NLSF_MSVQ_CB0_16_VECTORS + NLSF_MSVQ_CB0_16_STAGES ]; extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr[ NLSF_MSVQ_CB0_16_STAGES ]; extern const SKP_int SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx[ NLSF_MSVQ_CB0_16_STAGES ]; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_tables_NLSF_CB1_10.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_TABLES_NLSF_CB1_10_H #define SKP_SILK_TABLES_NLSF_CB1_10_H #include "SKP_Silk_define.h" #ifdef __cplusplus extern "C" { #endif #define NLSF_MSVQ_CB1_10_STAGES 6 #define NLSF_MSVQ_CB1_10_VECTORS 72 /* NLSF codebook entropy coding tables */ extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ NLSF_MSVQ_CB1_10_VECTORS + NLSF_MSVQ_CB1_10_STAGES ]; extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr[ NLSF_MSVQ_CB1_10_STAGES ]; extern const SKP_int SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx[ NLSF_MSVQ_CB1_10_STAGES ]; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_tables_NLSF_CB1_16.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_TABLES_NLSF_CB1_16_H #define SKP_SILK_TABLES_NLSF_CB1_16_H #include "SKP_Silk_define.h" #ifdef __cplusplus extern "C" { #endif #define NLSF_MSVQ_CB1_16_STAGES 10 #define NLSF_MSVQ_CB1_16_VECTORS 104 /* NLSF codebook entropy coding tables */ extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ NLSF_MSVQ_CB1_16_VECTORS + NLSF_MSVQ_CB1_16_STAGES ]; extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr[ NLSF_MSVQ_CB1_16_STAGES ]; extern const SKP_int SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx[ NLSF_MSVQ_CB1_16_STAGES ]; #ifdef __cplusplus } #endif #endif ================================================ FILE: app/jni/include/SKP_Silk_tuning_parameters.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef SKP_SILK_TUNING_PARAMETERS_H #define SKP_SILK_TUNING_PARAMETERS_H #ifdef __cplusplus extern "C" { #endif /*******************/ /* Pitch estimator */ /*******************/ /* Level of noise floor for whitening filter LPC analysis in pitch analysis */ #define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f /* Bandwidth expansion for whitening filter in pitch analysis */ #define FIND_PITCH_BANDWITH_EXPANSION 0.99f /* Threshold used by pitch estimator for early escape */ #define FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE 0.7f #define FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE 0.75f #define FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE 0.8f /*********************/ /* Linear prediction */ /*********************/ /* LPC analysis defines: regularization and bandwidth expansion */ #define FIND_LPC_COND_FAC 2.5e-5f #define FIND_LPC_CHIRP 0.99995f /* LTP analysis defines */ #define FIND_LTP_COND_FAC 1e-5f #define LTP_DAMPING 0.01f #define LTP_SMOOTHING 0.1f /* LTP quantization settings */ #define MU_LTP_QUANT_NB 0.03f #define MU_LTP_QUANT_MB 0.025f #define MU_LTP_QUANT_WB 0.02f #define MU_LTP_QUANT_SWB 0.016f /***********************/ /* High pass filtering */ /***********************/ /* Smoothing parameters for low end of pitch frequency range estimation */ #define VARIABLE_HP_SMTH_COEF1 0.1f #define VARIABLE_HP_SMTH_COEF2 0.015f /* Min and max values for low end of pitch frequency range estimation */ #define VARIABLE_HP_MIN_FREQ 80.0f #define VARIABLE_HP_MAX_FREQ 150.0f /* Max absolute difference between log2 of pitch frequency and smoother state, to enter the smoother */ #define VARIABLE_HP_MAX_DELTA_FREQ 0.4f /***********/ /* Various */ /***********/ /* Required speech activity for counting frame as active */ #define WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES 0.7f #define SPEECH_ACTIVITY_DTX_THRES 0.1f /* Speech Activity LBRR enable threshold (needs tuning) */ #define LBRR_SPEECH_ACTIVITY_THRES 0.5f /*************************/ /* Perceptual parameters */ /*************************/ /* reduction in coding SNR during low speech activity */ #define BG_SNR_DECR_dB 4.0f /* factor for reducing quantization noise during voiced speech */ #define HARM_SNR_INCR_dB 2.0f /* factor for reducing quantization noise for unvoiced sparse signals */ #define SPARSE_SNR_INCR_dB 2.0f /* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ #define SPARSENESS_THRESHOLD_QNT_OFFSET 0.75f /* warping control */ #define WARPING_MULTIPLIER 0.015f /* fraction added to first autocorrelation value */ #define SHAPE_WHITE_NOISE_FRACTION 1e-5f /* noise shaping filter chirp factor */ #define BANDWIDTH_EXPANSION 0.95f /* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */ #define LOW_RATE_BANDWIDTH_EXPANSION_DELTA 0.01f /* gain reduction for fricatives */ #define DE_ESSER_COEF_SWB_dB 2.0f #define DE_ESSER_COEF_WB_dB 1.0f /* extra harmonic boosting (signal shaping) at low bitrates */ #define LOW_RATE_HARMONIC_BOOST 0.1f /* extra harmonic boosting (signal shaping) for noisy input signals */ #define LOW_INPUT_QUALITY_HARMONIC_BOOST 0.1f /* harmonic noise shaping */ #define HARMONIC_SHAPING 0.3f /* extra harmonic noise shaping for high bitrates or noisy input */ #define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f /* parameter for shaping noise towards higher frequencies */ #define HP_NOISE_COEF 0.3f /* parameter for shaping noise even more towards higher frequencies during voiced speech */ #define HARM_HP_NOISE_COEF 0.35f /* parameter for applying a high-pass tilt to the input signal */ #define INPUT_TILT 0.05f /* parameter for extra high-pass tilt to the input signal at high rates */ #define HIGH_RATE_INPUT_TILT 0.1f /* parameter for reducing noise at the very low frequencies */ #define LOW_FREQ_SHAPING 3.0f /* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ #define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f /* noise floor to put a lower limit on the quantization step size */ #define NOISE_FLOOR_dB 4.0f /* noise floor relative to active speech gain level */ #define RELATIVE_MIN_GAIN_dB -50.0f /* subframe smoothing coefficient for determining active speech gain level (lower -> more smoothing) */ #define GAIN_SMOOTHING_COEF 1e-3f /* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ #define SUBFR_SMTH_COEF 0.4f /* parameters defining the R/D tradeoff in the residual quantizer */ #define LAMBDA_OFFSET 1.2f #define LAMBDA_SPEECH_ACT -0.3f #define LAMBDA_DELAYED_DECISIONS -0.05f #define LAMBDA_INPUT_QUALITY -0.2f #define LAMBDA_CODING_QUALITY -0.1f #define LAMBDA_QUANT_OFFSET 1.5f #ifdef __cplusplus } #endif #endif // SKP_SILK_TUNING_PARAMETERS_H ================================================ FILE: app/jni/include/SKP_Silk_typedef.h ================================================ /*********************************************************************** Copyright (c) 2006-2012, Skype Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, (subject to the limitations in the disclaimer below) 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 Skype Limited, nor the names of specific contributors, may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 COPYRIGHT OWNER 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. ***********************************************************************/ #ifndef _SKP_SILK_API_TYPDEF_H_ #define _SKP_SILK_API_TYPDEF_H_ #ifndef SKP_USE_DOUBLE_PRECISION_FLOATS #define SKP_USE_DOUBLE_PRECISION_FLOATS 0 #endif #include #if defined( __GNUC__ ) #include #endif #define SKP_int int /* used for counters etc; at least 16 bits */ #ifdef __GNUC__ # define SKP_int64 int64_t #else # define SKP_int64 long long #endif #define SKP_int32 int #define SKP_int16 short #define SKP_int8 signed char #define SKP_uint unsigned int /* used for counters etc; at least 16 bits */ #ifdef __GNUC__ # define SKP_uint64 uint64_t #else # define SKP_uint64 unsigned long long #endif #define SKP_uint32 unsigned int #define SKP_uint16 unsigned short #define SKP_uint8 unsigned char #define SKP_int_ptr_size intptr_t #if SKP_USE_DOUBLE_PRECISION_FLOATS # define SKP_float double # define SKP_float_MAX DBL_MAX #else # define SKP_float float # define SKP_float_MAX FLT_MAX #endif #define SKP_INLINE static __inline #ifdef _WIN32 # define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y) #else # define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y) #endif #define SKP_int64_MAX ((SKP_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */ #define SKP_int64_MIN ((SKP_int64)0x8000000000000000LL) /* -2^63 */ #define SKP_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647*/ #define SKP_int32_MIN ((SKP_int32)0x80000000) /* -2^31 = -2147483648*/ #define SKP_int16_MAX 0x7FFF /* 2^15 - 1 = 32767*/ #define SKP_int16_MIN ((SKP_int16)0x8000) /* -2^15 = -32768*/ #define SKP_int8_MAX 0x7F /* 2^7 - 1 = 127*/ #define SKP_int8_MIN ((SKP_int8)0x80) /* -2^7 = -128*/ #define SKP_uint32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4294967295 */ #define SKP_uint32_MIN 0x00000000 #define SKP_uint16_MAX 0xFFFF /* 2^16 - 1 = 65535 */ #define SKP_uint16_MIN 0x0000 #define SKP_uint8_MAX 0xFF /* 2^8 - 1 = 255 */ #define SKP_uint8_MIN 0x00 #define SKP_TRUE 1 #define SKP_FALSE 0 /* assertions */ #if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS)) # ifndef SKP_assert # include /* ASSERTE() */ # define SKP_assert(COND) _ASSERTE(COND) # endif #else # define SKP_assert(COND) #endif #endif ================================================ FILE: app/jni/include/lame.h ================================================ /* * Interface to MP3 LAME encoding engine * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: lame.h,v 1.189.2.1 2012/01/08 23:49:58 robert Exp $ */ #ifndef LAME_LAME_H #define LAME_LAME_H /* for size_t typedef */ #include /* for va_list typedef */ #include /* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */ #include //#if defined(__cplusplus) //extern "C" { //#endif #ifdef __cplusplus extern "C" { #endif #include "stdlib.h" typedef void (*lame_report_function)(const char *format, va_list ap); #if defined(WIN32) || defined(_WIN32) #undef CDECL #define CDECL __cdecl #else #define CDECL #endif #define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1 typedef enum vbr_mode_e { vbr_off=0, vbr_mt, /* obsolete, same as vbr_mtrh */ vbr_rh, vbr_abr, vbr_mtrh, vbr_max_indicator, /* Don't use this! It's used for sanity checks. */ vbr_default=vbr_mtrh /* change this to change the default VBR mode of LAME */ } vbr_mode; /* MPEG modes */ typedef enum MPEG_mode_e { STEREO = 0, JOINT_STEREO, DUAL_CHANNEL, /* LAME doesn't supports this! */ MONO, NOT_SET, MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ } MPEG_mode; /* Padding types */ typedef enum Padding_type_e { PAD_NO = 0, PAD_ALL, PAD_ADJUST, PAD_MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ } Padding_type; /*presets*/ typedef enum preset_mode_e { /*values from 8 to 320 should be reserved for abr bitrates*/ /*for abr I'd suggest to directly use the targeted bitrate as a value*/ ABR_8 = 8, ABR_320 = 320, V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/ VBR_10 = 410, V8 = 420, VBR_20 = 420, V7 = 430, VBR_30 = 430, V6 = 440, VBR_40 = 440, V5 = 450, VBR_50 = 450, V4 = 460, VBR_60 = 460, V3 = 470, VBR_70 = 470, V2 = 480, VBR_80 = 480, V1 = 490, VBR_90 = 490, V0 = 500, VBR_100 = 500, /*still there for compatibility*/ R3MIX = 1000, STANDARD = 1001, EXTREME = 1002, INSANE = 1003, STANDARD_FAST = 1004, EXTREME_FAST = 1005, MEDIUM = 1006, MEDIUM_FAST = 1007 } preset_mode; /*asm optimizations*/ typedef enum asm_optimizations_e { MMX = 1, AMD_3DNOW = 2, SSE = 3 } asm_optimizations; /* psychoacoustic model */ typedef enum Psy_model_e { PSY_GPSYCHO = 1, PSY_NSPSYTUNE = 2 } Psy_model; /* buffer considerations */ typedef enum buffer_constraint_e { MDB_DEFAULT=0, MDB_STRICT_ISO=1, MDB_MAXIMUM=2 } buffer_constraint; struct lame_global_struct; typedef struct lame_global_struct lame_global_flags; typedef lame_global_flags *lame_t; /*********************************************************************** * * The LAME API * These functions should be called, in this order, for each * MP3 file to be encoded. See the file "API" for more documentation * ***********************************************************************/ /* * REQUIRED: * initialize the encoder. sets default for all encoder parameters, * returns NULL if some malloc()'s failed * otherwise returns pointer to structure needed for all future * API calls. */ lame_global_flags * CDECL lame_init(void); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* obsolete version */ int CDECL lame_init_old(lame_global_flags *); #endif /* * OPTIONAL: * set as needed to override defaults */ /******************************************************************** * input stream description ***********************************************************************/ /* number of samples. default = 2^32-1 */ int CDECL lame_set_num_samples(lame_global_flags *, unsigned long); unsigned long CDECL lame_get_num_samples(const lame_global_flags *); /* input sample rate in Hz. default = 44100hz */ int CDECL lame_set_in_samplerate(lame_global_flags *, int); int CDECL lame_get_in_samplerate(const lame_global_flags *); /* number of channels in input stream. default=2 */ int CDECL lame_set_num_channels(lame_global_flags *, int); int CDECL lame_get_num_channels(const lame_global_flags *); /* scale the input by this amount before encoding. default=1 (not used by decoding routines) */ int CDECL lame_set_scale(lame_global_flags *, float); float CDECL lame_get_scale(const lame_global_flags *); /* scale the channel 0 (left) input by this amount before encoding. default=1 (not used by decoding routines) */ int CDECL lame_set_scale_left(lame_global_flags *, float); float CDECL lame_get_scale_left(const lame_global_flags *); /* scale the channel 1 (right) input by this amount before encoding. default=1 (not used by decoding routines) */ int CDECL lame_set_scale_right(lame_global_flags *, float); float CDECL lame_get_scale_right(const lame_global_flags *); /* output sample rate in Hz. default = 0, which means LAME picks best value based on the amount of compression. MPEG only allows: MPEG1 32, 44.1, 48khz MPEG2 16, 22.05, 24 MPEG2.5 8, 11.025, 12 (not used by decoding routines) */ int CDECL lame_set_out_samplerate(lame_global_flags *, int); int CDECL lame_get_out_samplerate(const lame_global_flags *); /******************************************************************** * general control parameters ***********************************************************************/ /* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */ int CDECL lame_set_analysis(lame_global_flags *, int); int CDECL lame_get_analysis(const lame_global_flags *); /* 1 = write a Xing VBR header frame. default = 1 this variable must have been added by a Hungarian notation Windows programmer :-) */ int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int); int CDECL lame_get_bWriteVbrTag(const lame_global_flags *); /* 1=decode only. use lame/mpglib to convert mp3/ogg to wav. default=0 */ int CDECL lame_set_decode_only(lame_global_flags *, int); int CDECL lame_get_decode_only(const lame_global_flags *); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* 1=encode a Vorbis .ogg file. default=0 */ /* DEPRECATED */ int CDECL lame_set_ogg(lame_global_flags *, int); int CDECL lame_get_ogg(const lame_global_flags *); #endif /* internal algorithm selection. True quality is determined by the bitrate but this variable will effect quality by selecting expensive or cheap algorithms. quality=0..9. 0=best (very slow). 9=worst. recommended: 2 near-best quality, not too slow 5 good quality, fast 7 ok quality, really fast */ int CDECL lame_set_quality(lame_global_flags *, int); int CDECL lame_get_quality(const lame_global_flags *); /* mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono default: lame picks based on compression ration and input channels */ int CDECL lame_set_mode(lame_global_flags *, MPEG_mode); MPEG_mode CDECL lame_get_mode(const lame_global_flags *); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* mode_automs. Use a M/S mode with a switching threshold based on compression ratio DEPRECATED */ int CDECL lame_set_mode_automs(lame_global_flags *, int); int CDECL lame_get_mode_automs(const lame_global_flags *); #endif /* force_ms. Force M/S for all frames. For testing only. default = 0 (disabled) */ int CDECL lame_set_force_ms(lame_global_flags *, int); int CDECL lame_get_force_ms(const lame_global_flags *); /* use free_format? default = 0 (disabled) */ int CDECL lame_set_free_format(lame_global_flags *, int); int CDECL lame_get_free_format(const lame_global_flags *); /* perform ReplayGain analysis? default = 0 (disabled) */ int CDECL lame_set_findReplayGain(lame_global_flags *, int); int CDECL lame_get_findReplayGain(const lame_global_flags *); /* decode on the fly. Search for the peak sample. If the ReplayGain * analysis is enabled then perform the analysis on the decoded data * stream. default = 0 (disabled) * NOTE: if this option is set the build-in decoder should not be used */ int CDECL lame_set_decode_on_the_fly(lame_global_flags *, int); int CDECL lame_get_decode_on_the_fly(const lame_global_flags *); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* DEPRECATED: now does the same as lame_set_findReplayGain() default = 0 (disabled) */ int CDECL lame_set_ReplayGain_input(lame_global_flags *, int); int CDECL lame_get_ReplayGain_input(const lame_global_flags *); /* DEPRECATED: now does the same as lame_set_decode_on_the_fly() && lame_set_findReplayGain() default = 0 (disabled) */ int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int); int CDECL lame_get_ReplayGain_decode(const lame_global_flags *); /* DEPRECATED: now does the same as lame_set_decode_on_the_fly() default = 0 (disabled) */ int CDECL lame_set_findPeakSample(lame_global_flags *, int); int CDECL lame_get_findPeakSample(const lame_global_flags *); #endif /* counters for gapless encoding */ int CDECL lame_set_nogap_total(lame_global_flags*, int); int CDECL lame_get_nogap_total(const lame_global_flags*); int CDECL lame_set_nogap_currentindex(lame_global_flags* , int); int CDECL lame_get_nogap_currentindex(const lame_global_flags*); /* * OPTIONAL: * Set printf like error/debug/message reporting functions. * The second argument has to be a pointer to a function which looks like * void my_debugf(const char *format, va_list ap) * { * (void) vfprintf(stdout, format, ap); * } * If you use NULL as the value of the pointer in the set function, the * lame buildin function will be used (prints to stderr). * To quiet any output you have to replace the body of the example function * with just "return;" and use it in the set function. */ int CDECL lame_set_errorf(lame_global_flags *, lame_report_function); int CDECL lame_set_debugf(lame_global_flags *, lame_report_function); int CDECL lame_set_msgf (lame_global_flags *, lame_report_function); /* set one of brate compression ratio. default is compression ratio of 11. */ int CDECL lame_set_brate(lame_global_flags *, int); int CDECL lame_get_brate(const lame_global_flags *); int CDECL lame_set_compression_ratio(lame_global_flags *, float); float CDECL lame_get_compression_ratio(const lame_global_flags *); int CDECL lame_set_preset( lame_global_flags* gfp, int ); int CDECL lame_set_asm_optimizations( lame_global_flags* gfp, int, int ); /******************************************************************** * frame params ***********************************************************************/ /* mark as copyright. default=0 */ int CDECL lame_set_copyright(lame_global_flags *, int); int CDECL lame_get_copyright(const lame_global_flags *); /* mark as original. default=1 */ int CDECL lame_set_original(lame_global_flags *, int); int CDECL lame_get_original(const lame_global_flags *); /* error_protection. Use 2 bytes from each frame for CRC checksum. default=0 */ int CDECL lame_set_error_protection(lame_global_flags *, int); int CDECL lame_get_error_protection(const lame_global_flags *); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */ int CDECL lame_set_padding_type(lame_global_flags *, Padding_type); Padding_type CDECL lame_get_padding_type(const lame_global_flags *); #endif /* MP3 'private extension' bit Meaningless. default=0 */ int CDECL lame_set_extension(lame_global_flags *, int); int CDECL lame_get_extension(const lame_global_flags *); /* enforce strict ISO compliance. default=0 */ int CDECL lame_set_strict_ISO(lame_global_flags *, int); int CDECL lame_get_strict_ISO(const lame_global_flags *); /******************************************************************** * quantization/noise shaping ***********************************************************************/ /* disable the bit reservoir. For testing only. default=0 */ int CDECL lame_set_disable_reservoir(lame_global_flags *, int); int CDECL lame_get_disable_reservoir(const lame_global_flags *); /* select a different "best quantization" function. default=0 */ int CDECL lame_set_quant_comp(lame_global_flags *, int); int CDECL lame_get_quant_comp(const lame_global_flags *); int CDECL lame_set_quant_comp_short(lame_global_flags *, int); int CDECL lame_get_quant_comp_short(const lame_global_flags *); int CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/ int CDECL lame_get_experimentalX(const lame_global_flags *); /* another experimental option. for testing only */ int CDECL lame_set_experimentalY(lame_global_flags *, int); int CDECL lame_get_experimentalY(const lame_global_flags *); /* another experimental option. for testing only */ int CDECL lame_set_experimentalZ(lame_global_flags *, int); int CDECL lame_get_experimentalZ(const lame_global_flags *); /* Naoki's psycho acoustic model. default=0 */ int CDECL lame_set_exp_nspsytune(lame_global_flags *, int); int CDECL lame_get_exp_nspsytune(const lame_global_flags *); void CDECL lame_set_msfix(lame_global_flags *, double); float CDECL lame_get_msfix(const lame_global_flags *); /******************************************************************** * VBR control ***********************************************************************/ /* Types of VBR. default = vbr_off = CBR */ int CDECL lame_set_VBR(lame_global_flags *, vbr_mode); vbr_mode CDECL lame_get_VBR(const lame_global_flags *); /* VBR quality level. 0=highest 9=lowest */ int CDECL lame_set_VBR_q(lame_global_flags *, int); int CDECL lame_get_VBR_q(const lame_global_flags *); /* VBR quality level. 0=highest 9=lowest, Range [0,...,10[ */ int CDECL lame_set_VBR_quality(lame_global_flags *, float); float CDECL lame_get_VBR_quality(const lame_global_flags *); /* Ignored except for VBR=vbr_abr (ABR mode) */ int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int); int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *); int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int); int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *); int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int); int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *); /* 1=strictly enforce VBR_min_bitrate. Normally it will be violated for analog silence */ int CDECL lame_set_VBR_hard_min(lame_global_flags *, int); int CDECL lame_get_VBR_hard_min(const lame_global_flags *); /* for preset */ #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else int CDECL lame_set_preset_expopts(lame_global_flags *, int); #endif /******************************************************************** * Filtering control ***********************************************************************/ /* freq in Hz to apply lowpass. Default = 0 = lame chooses. -1 = disabled */ int CDECL lame_set_lowpassfreq(lame_global_flags *, int); int CDECL lame_get_lowpassfreq(const lame_global_flags *); /* width of transition band, in Hz. Default = one polyphase filter band */ int CDECL lame_set_lowpasswidth(lame_global_flags *, int); int CDECL lame_get_lowpasswidth(const lame_global_flags *); /* freq in Hz to apply highpass. Default = 0 = lame chooses. -1 = disabled */ int CDECL lame_set_highpassfreq(lame_global_flags *, int); int CDECL lame_get_highpassfreq(const lame_global_flags *); /* width of transition band, in Hz. Default = one polyphase filter band */ int CDECL lame_set_highpasswidth(lame_global_flags *, int); int CDECL lame_get_highpasswidth(const lame_global_flags *); /******************************************************************** * psycho acoustics and other arguments which you should not change * unless you know what you are doing ***********************************************************************/ /* only use ATH for masking */ int CDECL lame_set_ATHonly(lame_global_flags *, int); int CDECL lame_get_ATHonly(const lame_global_flags *); /* only use ATH for short blocks */ int CDECL lame_set_ATHshort(lame_global_flags *, int); int CDECL lame_get_ATHshort(const lame_global_flags *); /* disable ATH */ int CDECL lame_set_noATH(lame_global_flags *, int); int CDECL lame_get_noATH(const lame_global_flags *); /* select ATH formula */ int CDECL lame_set_ATHtype(lame_global_flags *, int); int CDECL lame_get_ATHtype(const lame_global_flags *); /* lower ATH by this many db */ int CDECL lame_set_ATHlower(lame_global_flags *, float); float CDECL lame_get_ATHlower(const lame_global_flags *); /* select ATH adaptive adjustment type */ int CDECL lame_set_athaa_type( lame_global_flags *, int); int CDECL lame_get_athaa_type( const lame_global_flags *); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* select the loudness approximation used by the ATH adaptive auto-leveling */ int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int); int CDECL lame_get_athaa_loudapprox( const lame_global_flags *); #endif /* adjust (in dB) the point below which adaptive ATH level adjustment occurs */ int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float); float CDECL lame_get_athaa_sensitivity( const lame_global_flags* ); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* OBSOLETE: predictability limit (ISO tonality formula) */ int CDECL lame_set_cwlimit(lame_global_flags *, int); int CDECL lame_get_cwlimit(const lame_global_flags *); #endif /* allow blocktypes to differ between channels? default: 0 for jstereo, 1 for stereo */ int CDECL lame_set_allow_diff_short(lame_global_flags *, int); int CDECL lame_get_allow_diff_short(const lame_global_flags *); /* use temporal masking effect (default = 1) */ int CDECL lame_set_useTemporal(lame_global_flags *, int); int CDECL lame_get_useTemporal(const lame_global_flags *); /* use temporal masking effect (default = 1) */ int CDECL lame_set_interChRatio(lame_global_flags *, float); float CDECL lame_get_interChRatio(const lame_global_flags *); /* disable short blocks */ int CDECL lame_set_no_short_blocks(lame_global_flags *, int); int CDECL lame_get_no_short_blocks(const lame_global_flags *); /* force short blocks */ int CDECL lame_set_force_short_blocks(lame_global_flags *, int); int CDECL lame_get_force_short_blocks(const lame_global_flags *); /* Input PCM is emphased PCM (for instance from one of the rarely emphased CDs), it is STRONGLY not recommended to use this, because psycho does not take it into account, and last but not least many decoders ignore these bits */ int CDECL lame_set_emphasis(lame_global_flags *, int); int CDECL lame_get_emphasis(const lame_global_flags *); /************************************************************************/ /* internal variables, cannot be set... */ /* provided because they may be of use to calling application */ /************************************************************************/ /* version 0=MPEG-2 1=MPEG-1 (2=MPEG-2.5) */ int CDECL lame_get_version(const lame_global_flags *); /* encoder delay */ int CDECL lame_get_encoder_delay(const lame_global_flags *); /* padding appended to the input to make sure decoder can fully decode all input. Note that this value can only be calculated during the call to lame_encoder_flush(). Before lame_encoder_flush() has been called, the value of encoder_padding = 0. */ int CDECL lame_get_encoder_padding(const lame_global_flags *); /* size of MPEG frame */ int CDECL lame_get_framesize(const lame_global_flags *); /* number of PCM samples buffered, but not yet encoded to mp3 data. */ int CDECL lame_get_mf_samples_to_encode( const lame_global_flags* gfp ); /* size (bytes) of mp3 data buffered, but not yet encoded. this is the number of bytes which would be output by a call to lame_encode_flush_nogap. NOTE: lame_encode_flush() will return more bytes than this because it will encode the reamining buffered PCM samples before flushing the mp3 buffers. */ int CDECL lame_get_size_mp3buffer( const lame_global_flags* gfp ); /* number of frames encoded so far */ int CDECL lame_get_frameNum(const lame_global_flags *); /* lame's estimate of the total number of frames to be encoded only valid if calling program set num_samples */ int CDECL lame_get_totalframes(const lame_global_flags *); /* RadioGain value. Multiplied by 10 and rounded to the nearest. */ int CDECL lame_get_RadioGain(const lame_global_flags *); /* AudiophileGain value. Multipled by 10 and rounded to the nearest. */ int CDECL lame_get_AudiophileGain(const lame_global_flags *); /* the peak sample */ float CDECL lame_get_PeakSample(const lame_global_flags *); /* Gain change required for preventing clipping. The value is correct only if peak sample searching was enabled. If negative then the waveform already does not clip. The value is multiplied by 10 and rounded up. */ int CDECL lame_get_noclipGainChange(const lame_global_flags *); /* user-specified scale factor required for preventing clipping. Value is correct only if peak sample searching was enabled and no user-specified scaling was performed. If negative then either the waveform already does not clip or the value cannot be determined */ float CDECL lame_get_noclipScale(const lame_global_flags *); /* * REQUIRED: * sets more internal configuration based on data provided above. * returns -1 if something failed. */ int CDECL lame_init_params(lame_global_flags *); /* * OPTIONAL: * get the version number, in a string. of the form: * "3.63 (beta)" or just "3.63". */ const char* CDECL get_lame_version ( void ); const char* CDECL get_lame_short_version ( void ); const char* CDECL get_lame_very_short_version ( void ); const char* CDECL get_psy_version ( void ); const char* CDECL get_lame_url ( void ); const char* CDECL get_lame_os_bitness ( void ); /* * OPTIONAL: * get the version numbers in numerical form. */ typedef struct { /* generic LAME version */ int major; int minor; int alpha; /* 0 if not an alpha version */ int beta; /* 0 if not a beta version */ /* version of the psy model */ int psy_major; int psy_minor; int psy_alpha; /* 0 if not an alpha version */ int psy_beta; /* 0 if not a beta version */ /* compile time features */ const char *features; /* Don't make assumptions about the contents! */ } lame_version_t; void CDECL get_lame_version_numerical(lame_version_t *); /* * OPTIONAL: * print internal lame configuration to message handler */ void CDECL lame_print_config(const lame_global_flags* gfp); void CDECL lame_print_internals( const lame_global_flags *gfp); /* * input pcm data, output (maybe) mp3 frames. * This routine handles all buffering, resampling and filtering for you. * * return code number of bytes output in mp3buf. Can be 0 * -1: mp3buf was too small * -2: malloc() problem * -3: lame_init_params() not called * -4: psycho acoustic problems * * The required mp3buf_size can be computed from num_samples, * samplerate and encoding rate, but here is a worst case estimate: * * mp3buf_size in bytes = 1.25*num_samples + 7200 * * I think a tighter bound could be: (mt, March 2000) * MPEG1: * num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512 * MPEG2: * num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256 * * but test first if you use that! * * set mp3buf_size = 0 and LAME will not check if mp3buf_size is * large enough. * * NOTE: * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels * will be averaged into the L channel before encoding only the L channel * This will overwrite the data in buffer_l[] and buffer_r[]. * */ int CDECL lame_encode_buffer ( lame_global_flags* gfp, /* global context handle */ const short int buffer_l [], /* PCM data for left channel */ const short int buffer_r [], /* PCM data for right channel */ const int nsamples, /* number of samples per channel */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ const int mp3buf_size ); /* number of valid octets in this stream */ /* * as above, but input has L & R channel data interleaved. * NOTE: * num_samples = number of samples in the L (or R) * channel, not the total number of samples in pcm[] */ int CDECL lame_encode_buffer_interleaved( lame_global_flags* gfp, /* global context handlei */ short int pcm[], /* PCM data for left and right channel, interleaved */ int num_samples, /* number of samples per channel, _not_ number of samples in pcm[] */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ int mp3buf_size ); /* number of valid octets in this stream */ /* as lame_encode_buffer, but for 'float's. * !! NOTE: !! data must still be scaled to be in the same range as * short int, +/- 32768 */ int CDECL lame_encode_buffer_float( lame_global_flags* gfp, /* global context handle */ const float pcm_l [], /* PCM data for left channel */ const float pcm_r [], /* PCM data for right channel */ const int nsamples, /* number of samples per channel */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ const int mp3buf_size ); /* number of valid octets in this stream */ /* as lame_encode_buffer, but for 'float's. * !! NOTE: !! data must be scaled to +/- 1 full scale */ int CDECL lame_encode_buffer_ieee_float( lame_t gfp, const float pcm_l [], /* PCM data for left channel */ const float pcm_r [], /* PCM data for right channel */ const int nsamples, unsigned char * mp3buf, const int mp3buf_size); int CDECL lame_encode_buffer_interleaved_ieee_float( lame_t gfp, const float pcm[], /* PCM data for left and right channel, interleaved */ const int nsamples, unsigned char * mp3buf, const int mp3buf_size); /* as lame_encode_buffer, but for 'double's. * !! NOTE: !! data must be scaled to +/- 1 full scale */ int CDECL lame_encode_buffer_ieee_double( lame_t gfp, const double pcm_l [], /* PCM data for left channel */ const double pcm_r [], /* PCM data for right channel */ const int nsamples, unsigned char * mp3buf, const int mp3buf_size); int CDECL lame_encode_buffer_interleaved_ieee_double( lame_t gfp, const double pcm[], /* PCM data for left and right channel, interleaved */ const int nsamples, unsigned char * mp3buf, const int mp3buf_size); /* as lame_encode_buffer, but for long's * !! NOTE: !! data must still be scaled to be in the same range as * short int, +/- 32768 * * This scaling was a mistake (doesn't allow one to exploit full * precision of type 'long'. Use lame_encode_buffer_long2() instead. * */ int CDECL lame_encode_buffer_long( lame_global_flags* gfp, /* global context handle */ const long buffer_l [], /* PCM data for left channel */ const long buffer_r [], /* PCM data for right channel */ const int nsamples, /* number of samples per channel */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ const int mp3buf_size ); /* number of valid octets in this stream */ /* Same as lame_encode_buffer_long(), but with correct scaling. * !! NOTE: !! data must still be scaled to be in the same range as * type 'long'. Data should be in the range: +/- 2^(8*size(long)-1) * */ int CDECL lame_encode_buffer_long2( lame_global_flags* gfp, /* global context handle */ const long buffer_l [], /* PCM data for left channel */ const long buffer_r [], /* PCM data for right channel */ const int nsamples, /* number of samples per channel */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ const int mp3buf_size ); /* number of valid octets in this stream */ /* as lame_encode_buffer, but for int's * !! NOTE: !! input should be scaled to the maximum range of 'int' * If int is 4 bytes, then the values should range from * +/- 2147483648. * * This routine does not (and cannot, without loosing precision) use * the same scaling as the rest of the lame_encode_buffer() routines. * */ int CDECL lame_encode_buffer_int( lame_global_flags* gfp, /* global context handle */ const int buffer_l [], /* PCM data for left channel */ const int buffer_r [], /* PCM data for right channel */ const int nsamples, /* number of samples per channel */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ const int mp3buf_size ); /* number of valid octets in this stream */ /* * REQUIRED: * lame_encode_flush will flush the intenal PCM buffers, padding with * 0's to make sure the final frame is complete, and then flush * the internal MP3 buffers, and thus may return a * final few mp3 frames. 'mp3buf' should be at least 7200 bytes long * to hold all possible emitted data. * * will also write id3v1 tags (if any) into the bitstream * * return code = number of bytes output to mp3buf. Can be 0 */ int CDECL lame_encode_flush( lame_global_flags * gfp, /* global context handle */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ int size); /* number of valid octets in this stream */ /* * OPTIONAL: * lame_encode_flush_nogap will flush the internal mp3 buffers and pad * the last frame with ancillary data so it is a complete mp3 frame. * * 'mp3buf' should be at least 7200 bytes long * to hold all possible emitted data. * * After a call to this routine, the outputed mp3 data is complete, but * you may continue to encode new PCM samples and write future mp3 data * to a different file. The two mp3 files will play back with no gaps * if they are concatenated together. * * This routine will NOT write id3v1 tags into the bitstream. * * return code = number of bytes output to mp3buf. Can be 0 */ int CDECL lame_encode_flush_nogap( lame_global_flags * gfp, /* global context handle */ unsigned char* mp3buf, /* pointer to encoded MP3 stream */ int size); /* number of valid octets in this stream */ /* * OPTIONAL: * Normally, this is called by lame_init_params(). It writes id3v2 and * Xing headers into the front of the bitstream, and sets frame counters * and bitrate histogram data to 0. You can also call this after * lame_encode_flush_nogap(). */ int CDECL lame_init_bitstream( lame_global_flags * gfp); /* global context handle */ /* * OPTIONAL: some simple statistics * a bitrate histogram to visualize the distribution of used frame sizes * a stereo mode histogram to visualize the distribution of used stereo * modes, useful in joint-stereo mode only * 0: LR left-right encoded * 1: LR-I left-right and intensity encoded (currently not supported) * 2: MS mid-side encoded * 3: MS-I mid-side and intensity encoded (currently not supported) * * attention: don't call them after lame_encode_finish * suggested: lame_encode_flush -> lame_*_hist -> lame_close */ void CDECL lame_bitrate_hist( const lame_global_flags * gfp, int bitrate_count[14] ); void CDECL lame_bitrate_kbps( const lame_global_flags * gfp, int bitrate_kbps [14] ); void CDECL lame_stereo_mode_hist( const lame_global_flags * gfp, int stereo_mode_count[4] ); void CDECL lame_bitrate_stereo_mode_hist ( const lame_global_flags * gfp, int bitrate_stmode_count[14][4] ); void CDECL lame_block_type_hist ( const lame_global_flags * gfp, int btype_count[6] ); void CDECL lame_bitrate_block_type_hist ( const lame_global_flags * gfp, int bitrate_btype_count[14][6] ); #if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0) #else /* * OPTIONAL: * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file * pointer fid. These calls perform forward and backwards seeks, so make * sure fid is a real file. Make sure lame_encode_flush has been called, * and all mp3 data has been written to the file before calling this * function. * NOTE: * if VBR tags are turned off by the user, or turned off by LAME because * the output is not a regular file, this call does nothing * NOTE: * LAME wants to read from the file to skip an optional ID3v2 tag, so * make sure you opened the file for writing and reading. * NOTE: * You can call lame_get_lametag_frame instead, if you want to insert * the lametag yourself. */ void CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid); #endif /* * OPTIONAL: * lame_get_lametag_frame copies the final LAME-tag into 'buffer'. * The function returns the number of bytes copied into buffer, or * the required buffer size, if the provided buffer is too small. * Function failed, if the return value is larger than 'size'! * Make sure lame_encode flush has been called before calling this function. * NOTE: * if VBR tags are turned off by the user, or turned off by LAME, * this call does nothing and returns 0. * NOTE: * LAME inserted an empty frame in the beginning of mp3 audio data, * which you have to replace by the final LAME-tag frame after encoding. * In case there is no ID3v2 tag, usually this frame will be the very first * data in your mp3 file. If you put some other leading data into your * file, you'll have to do some bookkeeping about where to write this buffer. */ size_t CDECL lame_get_lametag_frame( const lame_global_flags *, unsigned char* buffer, size_t size); /* * REQUIRED: * final call to free all remaining buffers */ int CDECL lame_close (lame_global_flags *); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* * OBSOLETE: * lame_encode_finish combines lame_encode_flush() and lame_close() in * one call. However, once this call is made, the statistics routines * will no longer work because the data will have been cleared, and * lame_mp3_tags_fid() cannot be called to add data to the VBR header */ int CDECL lame_encode_finish( lame_global_flags* gfp, unsigned char* mp3buf, int size ); #endif /********************************************************************* * * decoding * * a simple interface to mpglib, part of mpg123, is also included if * libmp3lame is compiled with HAVE_MPGLIB * *********************************************************************/ struct hip_global_struct; typedef struct hip_global_struct hip_global_flags; typedef hip_global_flags *hip_t; typedef struct { int header_parsed; /* 1 if header was parsed and following data was computed */ int stereo; /* number of channels */ int samplerate; /* sample rate */ int bitrate; /* bitrate */ int mode; /* mp3 frame type */ int mode_ext; /* mp3 frame type */ int framesize; /* number of samples per mp3 frame */ /* this data is only computed if mpglib detects a Xing VBR header */ unsigned long nsamp; /* number of samples in mp3 file. */ int totalframes; /* total number of frames in mp3 file */ /* this data is not currently computed by the mpglib routines */ int framenum; /* frames decoded counter */ } mp3data_struct; /* required call to initialize decoder */ hip_t CDECL hip_decode_init(void); /* cleanup call to exit decoder */ int CDECL hip_decode_exit(hip_t gfp); /* HIP reporting functions */ void CDECL hip_set_errorf(hip_t gfp, lame_report_function f); void CDECL hip_set_debugf(hip_t gfp, lame_report_function f); void CDECL hip_set_msgf (hip_t gfp, lame_report_function f); /********************************************************************* * input 1 mp3 frame, output (maybe) pcm data. * * nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r); * * input: * len : number of bytes of mp3 data in mp3buf * mp3buf[len] : mp3 data to be decoded * * output: * nout: -1 : decoding error * 0 : need more data before we can complete the decode * >0 : returned 'nout' samples worth of data in pcm_l,pcm_r * pcm_l[nout] : left channel data * pcm_r[nout] : right channel data * *********************************************************************/ int CDECL hip_decode( hip_t gfp , unsigned char * mp3buf , size_t len , short pcm_l[] , short pcm_r[] ); /* same as hip_decode, and also returns mp3 header data */ int CDECL hip_decode_headers( hip_t gfp , unsigned char* mp3buf , size_t len , short pcm_l[] , short pcm_r[] , mp3data_struct* mp3data ); /* same as hip_decode, but returns at most one frame */ int CDECL hip_decode1( hip_t gfp , unsigned char* mp3buf , size_t len , short pcm_l[] , short pcm_r[] ); /* same as hip_decode1, but returns at most one frame and mp3 header data */ int CDECL hip_decode1_headers( hip_t gfp , unsigned char* mp3buf , size_t len , short pcm_l[] , short pcm_r[] , mp3data_struct* mp3data ); /* same as hip_decode1_headers, but also returns enc_delay and enc_padding from VBR Info tag, (-1 if no info tag was found) */ int CDECL hip_decode1_headersB( hip_t gfp , unsigned char* mp3buf , size_t len , short pcm_l[] , short pcm_r[] , mp3data_struct* mp3data , int *enc_delay , int *enc_padding ); /* OBSOLETE: * lame_decode... functions are there to keep old code working * but it is strongly recommended to replace calls by hip_decode... * function calls, see above. */ #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else int CDECL lame_decode_init(void); int CDECL lame_decode( unsigned char * mp3buf, int len, short pcm_l[], short pcm_r[] ); int CDECL lame_decode_headers( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[], mp3data_struct* mp3data ); int CDECL lame_decode1( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[] ); int CDECL lame_decode1_headers( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[], mp3data_struct* mp3data ); int CDECL lame_decode1_headersB( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[], mp3data_struct* mp3data, int *enc_delay, int *enc_padding ); int CDECL lame_decode_exit(void); #endif /* obsolete lame_decode API calls */ /********************************************************************* * * id3tag stuff * *********************************************************************/ /* * id3tag.h -- Interface to write ID3 version 1 and 2 tags. * * Copyright (C) 2000 Don Melton. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* utility to obtain alphabetically sorted list of genre names with numbers */ void CDECL id3tag_genre_list( void (*handler)(int, const char *, void *), void* cookie); void CDECL id3tag_init (lame_t gfp); /* force addition of version 2 tag */ void CDECL id3tag_add_v2 (lame_t gfp); /* add only a version 1 tag */ void CDECL id3tag_v1_only (lame_t gfp); /* add only a version 2 tag */ void CDECL id3tag_v2_only (lame_t gfp); /* pad version 1 tag with spaces instead of nulls */ void CDECL id3tag_space_v1 (lame_t gfp); /* pad version 2 tag with extra 128 bytes */ void CDECL id3tag_pad_v2 (lame_t gfp); /* pad version 2 tag with extra n bytes */ void CDECL id3tag_set_pad (lame_t gfp, size_t n); void CDECL id3tag_set_title(lame_t gfp, const char* title); void CDECL id3tag_set_artist(lame_t gfp, const char* artist); void CDECL id3tag_set_album(lame_t gfp, const char* album); void CDECL id3tag_set_year(lame_t gfp, const char* year); void CDECL id3tag_set_comment(lame_t gfp, const char* comment); /* return -1 result if track number is out of ID3v1 range and ignored for ID3v1 */ int CDECL id3tag_set_track(lame_t gfp, const char* track); /* return non-zero result if genre name or number is invalid result 0: OK result -1: genre number out of range result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other' but taken as-is for ID3v2 genre tag */ int CDECL id3tag_set_genre(lame_t gfp, const char* genre); /* return non-zero result if field name is invalid */ int CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue); /* return non-zero result if image type is invalid */ int CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size); /* lame_get_id3v1_tag copies ID3v1 tag into buffer. * Function returns number of bytes copied into buffer, or number * of bytes rquired if buffer 'size' is too small. * Function fails, if returned value is larger than 'size'. * NOTE: * This functions does nothing, if user/LAME disabled ID3v1 tag. */ size_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size); /* lame_get_id3v2_tag copies ID3v2 tag into buffer. * Function returns number of bytes copied into buffer, or number * of bytes rquired if buffer 'size' is too small. * Function fails, if returned value is larger than 'size'. * NOTE: * This functions does nothing, if user/LAME disabled ID3v2 tag. */ size_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size); /* normaly lame_init_param writes ID3v2 tags into the audio stream * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param * to turn off this behaviour and get ID3v2 tag with above function * write it yourself into your file. */ void CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int); int CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp); /* experimental */ int CDECL id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text); /* experimental */ int CDECL id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text); #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED #else /* experimental */ int CDECL id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text); /* experimental */ int CDECL id3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text); /* experimental */ int CDECL id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue); #endif /* experimental */ int CDECL id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue); /* experimental */ int CDECL id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text); /* experimental */ int CDECL id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text); /*********************************************************************** * * list of valid bitrates [kbps] & sample frequencies [Hz]. * first index: 0: MPEG-2 values (sample frequencies 16...24 kHz) * 1: MPEG-1 values (sample frequencies 32...48 kHz) * 2: MPEG-2.5 values (sample frequencies 8...12 kHz) ***********************************************************************/ extern const int bitrate_table [3][16]; extern const int samplerate_table [3][ 4]; /* access functions for use in DLL, global vars are not exported */ int CDECL lame_get_bitrate(int mpeg_version, int table_index); int CDECL lame_get_samplerate(int mpeg_version, int table_index); /* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER as well since lame_encode_buffer() also returns ID3v2 tag data */ #define LAME_MAXALBUMART (128 * 1024) /* maximum size of mp3buffer needed if you encode at most 1152 samples for each call to lame_encode_buffer. see lame_encode_buffer() below (LAME_MAXMP3BUFFER is now obsolete) */ #define LAME_MAXMP3BUFFER (16384 + LAME_MAXALBUMART) typedef enum { LAME_OKAY = 0, LAME_NOERROR = 0, LAME_GENERICERROR = -1, LAME_NOMEM = -10, LAME_BADBITRATE = -11, LAME_BADSAMPFREQ = -12, LAME_INTERNALERROR = -13, FRONTEND_READERROR = -80, FRONTEND_WRITEERROR = -81, FRONTEND_FILETOOLARGE = -82 } lame_errorcodes_t; #ifdef __cplusplus } #endif //#if defined(__cplusplus) //} //#endif #endif /* LAME_LAME_H */ ================================================ FILE: app/jni/include/silk.h ================================================ // // Created by ketian on 16-9-23. // #ifndef JNI_SILK_H #define JNI_SILK_H #include #include int convertSilk2PCM(const char *src, const FILE *dest); #define LOG_TAG "tian.ke" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #endif //JNI_SILK_H ================================================ FILE: app/jni/libmp3lame/VbrTag.c ================================================ /* * Xing VBR tagging for LAME. * * Copyright (c) 1999 A.L. Faber * Copyright (c) 2001 Jonathan Dee * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: VbrTag.c,v 1.103.2.1 2011/11/18 09:18:28 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include //#include <__clang_cuda_math_forward_declares.h> #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "bitstream.h" #include "VbrTag.h" #include "lame_global_flags.h" #include "tables.h" #ifdef __sun__ /* woraround for SunOS 4.x, it has SEEK_* defined here */ #include #endif #ifdef _DEBUG /* #define DEBUG_VBRTAG */ #endif /* * 4 bytes for Header Tag * 4 bytes for Header Flags * 100 bytes for entry (NUMTOCENTRIES) * 4 bytes for FRAME SIZE * 4 bytes for STREAM_SIZE * 4 bytes for VBR SCALE. a VBR quality indicator: 0=best 100=worst * 20 bytes for LAME tag. for example, "LAME3.12 (beta 6)" * ___________ * 140 bytes */ #define VBRHEADERSIZE (NUMTOCENTRIES+4+4+4+4+4) #define LAMEHEADERSIZE (VBRHEADERSIZE + 9 + 1 + 1 + 8 + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2) /* the size of the Xing header (MPEG1 and MPEG2) in kbps */ #define XING_BITRATE1 128 #define XING_BITRATE2 64 #define XING_BITRATE25 32 extern const char* get_lame_tag_encoder_short_version(void); static const char VBRTag0[] = { "Xing" }; static const char VBRTag1[] = { "Info" }; /* Lookup table for fast CRC computation * See 'CRC_update_lookup' * Uses the polynomial x^16+x^15+x^2+1 */ static const unsigned int crc16_lookup[256] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; /*********************************************************************** * Robert Hegemann 2001-01-17 ***********************************************************************/ static void addVbr(VBR_seek_info_t * v, int bitrate) { int i; v->nVbrNumFrames++; v->sum += bitrate; v->seen++; if (v->seen < v->want) { return; } if (v->pos < v->size) { v->bag[v->pos] = v->sum; v->pos++; v->seen = 0; } if (v->pos == v->size) { for (i = 1; i < v->size; i += 2) { v->bag[i / 2] = v->bag[i]; } v->want *= 2; v->pos /= 2; } } static void Xing_seek_table(VBR_seek_info_t const* v, unsigned char *t) { int i, indx; int seek_point; if (v->pos <= 0) return; for (i = 1; i < NUMTOCENTRIES; ++i) { float j = i / (float) NUMTOCENTRIES, act, sum; indx = (int) (floor(j * v->pos)); if (indx > v->pos - 1) indx = v->pos - 1; act = v->bag[indx]; sum = v->sum; seek_point = (int) (256. * act / sum); if (seek_point > 255) seek_point = 255; t[i] = seek_point; } } #ifdef DEBUG_VBR_SEEKING_TABLE static void print_seeking(unsigned char *t) { int i; printf("seeking table "); for (i = 0; i < NUMTOCENTRIES; ++i) { printf(" %d ", t[i]); } printf("\n"); } #endif /**************************************************************************** * AddVbrFrame: Add VBR entry, used to fill the VBR the TOC entries * Paramters: * nStreamPos: how many bytes did we write to the bitstream so far * (in Bytes NOT Bits) **************************************************************************** */ void AddVbrFrame(lame_internal_flags * gfc) { int kbps = bitrate_table[gfc->cfg.version][gfc->ov_enc.bitrate_index]; assert(gfc->VBR_seek_table.bag); addVbr(&gfc->VBR_seek_table, kbps); } /*-------------------------------------------------------------*/ static int ExtractI4(const unsigned char *buf) { int x; /* big endian extract */ x = buf[0]; x <<= 8; x |= buf[1]; x <<= 8; x |= buf[2]; x <<= 8; x |= buf[3]; return x; } static void CreateI4(unsigned char *buf, uint32_t nValue) { /* big endian create */ buf[0] = (nValue >> 24) & 0xff; buf[1] = (nValue >> 16) & 0xff; buf[2] = (nValue >> 8) & 0xff; buf[3] = (nValue) & 0xff; } static void CreateI2(unsigned char *buf, int nValue) { /* big endian create */ buf[0] = (nValue >> 8) & 0xff; buf[1] = (nValue) & 0xff; } /* check for magic strings*/ static int IsVbrTag(const unsigned char *buf) { int isTag0, isTag1; isTag0 = ((buf[0] == VBRTag0[0]) && (buf[1] == VBRTag0[1]) && (buf[2] == VBRTag0[2]) && (buf[3] == VBRTag0[3])); isTag1 = ((buf[0] == VBRTag1[0]) && (buf[1] == VBRTag1[1]) && (buf[2] == VBRTag1[2]) && (buf[3] == VBRTag1[3])); return (isTag0 || isTag1); } #define SHIFT_IN_BITS_VALUE(x,n,v) ( x = (x << (n)) | ( (v) & ~(-1u << (n)) ) ) static void setLameTagFrameHeader(lame_internal_flags const *gfc, unsigned char *buffer) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t const *const eov = &gfc->ov_enc; char abyte, bbyte; SHIFT_IN_BITS_VALUE(buffer[0], 8u, 0xffu); SHIFT_IN_BITS_VALUE(buffer[1], 3u, 7); SHIFT_IN_BITS_VALUE(buffer[1], 1u, (cfg->samplerate_out < 16000) ? 0 : 1); SHIFT_IN_BITS_VALUE(buffer[1], 1u, cfg->version); SHIFT_IN_BITS_VALUE(buffer[1], 2u, 4 - 3); SHIFT_IN_BITS_VALUE(buffer[1], 1u, (!cfg->error_protection) ? 1 : 0); SHIFT_IN_BITS_VALUE(buffer[2], 4u, eov->bitrate_index); SHIFT_IN_BITS_VALUE(buffer[2], 2u, cfg->samplerate_index); SHIFT_IN_BITS_VALUE(buffer[2], 1u, 0); SHIFT_IN_BITS_VALUE(buffer[2], 1u, cfg->extension); SHIFT_IN_BITS_VALUE(buffer[3], 2u, cfg->mode); SHIFT_IN_BITS_VALUE(buffer[3], 2u, eov->mode_ext); SHIFT_IN_BITS_VALUE(buffer[3], 1u, cfg->copyright); SHIFT_IN_BITS_VALUE(buffer[3], 1u, cfg->original); SHIFT_IN_BITS_VALUE(buffer[3], 2u, cfg->emphasis); /* the default VBR header. 48 kbps layer III, no padding, no crc */ /* but sampling freq, mode andy copyright/copy protection taken */ /* from first valid frame */ buffer[0] = (uint8_t) 0xff; abyte = (buffer[1] & (unsigned char) 0xf1); { int bitrate; if (1 == cfg->version) { bitrate = XING_BITRATE1; } else { if (cfg->samplerate_out < 16000) bitrate = XING_BITRATE25; else bitrate = XING_BITRATE2; } if (cfg->vbr == vbr_off) bitrate = cfg->avg_bitrate; if (cfg->free_format) bbyte = 0x00; else bbyte = 16 * BitrateIndex(bitrate, cfg->version, cfg->samplerate_out); } /* Use as much of the info from the real frames in the * Xing header: samplerate, channels, crc, etc... */ if (cfg->version == 1) { /* MPEG1 */ buffer[1] = abyte | (char) 0x0a; /* was 0x0b; */ abyte = buffer[2] & (char) 0x0d; /* AF keep also private bit */ buffer[2] = (char) bbyte | abyte; /* 64kbs MPEG1 frame */ } else { /* MPEG2 */ buffer[1] = abyte | (char) 0x02; /* was 0x03; */ abyte = buffer[2] & (char) 0x0d; /* AF keep also private bit */ buffer[2] = (char) bbyte | abyte; /* 64kbs MPEG2 frame */ } } #if 0 static int CheckVbrTag(unsigned char *buf); /*-------------------------------------------------------------*/ /* Same as GetVbrTag below, but only checks for the Xing tag. requires buf to contain only 40 bytes */ /*-------------------------------------------------------------*/ int CheckVbrTag(unsigned char *buf) { int h_id, h_mode; /* get selected MPEG header data */ h_id = (buf[1] >> 3) & 1; h_mode = (buf[3] >> 6) & 3; /* determine offset of header */ if (h_id) { /* mpeg1 */ if (h_mode != 3) buf += (32 + 4); else buf += (17 + 4); } else { /* mpeg2 */ if (h_mode != 3) buf += (17 + 4); else buf += (9 + 4); } return IsVbrTag(buf); } #endif int GetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf) { int i, head_flags; int h_bitrate, h_id, h_mode, h_sr_index, h_layer; int enc_delay, enc_padding; /* get Vbr header data */ pTagData->flags = 0; /* get selected MPEG header data */ h_layer = (buf[1] >> 1) & 3; if ( h_layer != 0x01 ) { /* the following code assumes Layer-3, so give up here */ return 0; } h_id = (buf[1] >> 3) & 1; h_sr_index = (buf[2] >> 2) & 3; h_mode = (buf[3] >> 6) & 3; h_bitrate = ((buf[2] >> 4) & 0xf); h_bitrate = bitrate_table[h_id][h_bitrate]; /* check for FFE syncword */ if ((buf[1] >> 4) == 0xE) pTagData->samprate = samplerate_table[2][h_sr_index]; else pTagData->samprate = samplerate_table[h_id][h_sr_index]; /* if( h_id == 0 ) */ /* pTagData->samprate >>= 1; */ /* determine offset of header */ if (h_id) { /* mpeg1 */ if (h_mode != 3) buf += (32 + 4); else buf += (17 + 4); } else { /* mpeg2 */ if (h_mode != 3) buf += (17 + 4); else buf += (9 + 4); } if (!IsVbrTag(buf)) return 0; buf += 4; pTagData->h_id = h_id; head_flags = pTagData->flags = ExtractI4(buf); buf += 4; /* get flags */ if (head_flags & FRAMES_FLAG) { pTagData->frames = ExtractI4(buf); buf += 4; } if (head_flags & BYTES_FLAG) { pTagData->bytes = ExtractI4(buf); buf += 4; } if (head_flags & TOC_FLAG) { if (&(pTagData->toc) != NULL) { //todo 不确定是否解决 for (i = 0; i < NUMTOCENTRIES; i++) pTagData->toc[i] = buf[i]; } buf += NUMTOCENTRIES; } pTagData->vbr_scale = -1; if (head_flags & VBR_SCALE_FLAG) { pTagData->vbr_scale = ExtractI4(buf); buf += 4; } pTagData->headersize = ((h_id + 1) * 72000 * h_bitrate) / pTagData->samprate; buf += 21; enc_delay = buf[0] << 4; enc_delay += buf[1] >> 4; enc_padding = (buf[1] & 0x0F) << 8; enc_padding += buf[2]; /* check for reasonable values (this may be an old Xing header, */ /* not a INFO tag) */ if (enc_delay < 0 || enc_delay > 3000) enc_delay = -1; if (enc_padding < 0 || enc_padding > 3000) enc_padding = -1; pTagData->enc_delay = enc_delay; pTagData->enc_padding = enc_padding; #ifdef DEBUG_VBRTAG fprintf(stderr, "\n\n********************* VBR TAG INFO *****************\n"); fprintf(stderr, "tag :%s\n", VBRTag); fprintf(stderr, "head_flags :%d\n", head_flags); fprintf(stderr, "bytes :%d\n", pTagData->bytes); fprintf(stderr, "frames :%d\n", pTagData->frames); fprintf(stderr, "VBR Scale :%d\n", pTagData->vbr_scale); fprintf(stderr, "enc_delay = %i \n", enc_delay); fprintf(stderr, "enc_padding= %i \n", enc_padding); fprintf(stderr, "toc:\n"); if (pTagData->toc != NULL) { for (i = 0; i < NUMTOCENTRIES; i++) { if ((i % 10) == 0) fprintf(stderr, "\n"); fprintf(stderr, " %3d", (int) (pTagData->toc[i])); } } fprintf(stderr, "\n***************** END OF VBR TAG INFO ***************\n"); #endif return 1; /* success */ } /**************************************************************************** * InitVbrTag: Initializes the header, and write empty frame to stream * Paramters: * fpStream: pointer to output file stream * nMode : Channel Mode: 0=STEREO 1=JS 2=DS 3=MONO **************************************************************************** */ int InitVbrTag(lame_global_flags * gfp) { lame_internal_flags *gfc = gfp->internal_flags; SessionConfig_t const *const cfg = &gfc->cfg; int kbps_header; #define MAXFRAMESIZE 2880 /* or 0xB40, the max freeformat 640 32kHz framesize */ /* * Xing VBR pretends to be a 48kbs layer III frame. (at 44.1kHz). * (at 48kHz they use 56kbs since 48kbs frame not big enough for * table of contents) * let's always embed Xing header inside a 64kbs layer III frame. * this gives us enough room for a LAME version string too. * size determined by sampling frequency (MPEG1) * 32kHz: 216 bytes@48kbs 288bytes@ 64kbs * 44.1kHz: 156 bytes 208bytes@64kbs (+1 if padding = 1) * 48kHz: 144 bytes 192 * * MPEG 2 values are the same since the framesize and samplerate * are each reduced by a factor of 2. */ if (1 == cfg->version) { kbps_header = XING_BITRATE1; } else { if (cfg->samplerate_out < 16000) kbps_header = XING_BITRATE25; else kbps_header = XING_BITRATE2; } if (cfg->vbr == vbr_off) kbps_header = cfg->avg_bitrate; /** make sure LAME Header fits into Frame */ { int total_frame_size = ((cfg->version + 1) * 72000 * kbps_header) / cfg->samplerate_out; int header_size = (cfg->sideinfo_len + LAMEHEADERSIZE); gfc->VBR_seek_table.TotalFrameSize = total_frame_size; if (total_frame_size < header_size || total_frame_size > MAXFRAMESIZE) { /* disable tag, it wont fit */ gfc->cfg.write_lame_tag = 0; return 0; } } gfc->VBR_seek_table.nVbrNumFrames = 0; gfc->VBR_seek_table.nBytesWritten = 0; gfc->VBR_seek_table.sum = 0; gfc->VBR_seek_table.seen = 0; gfc->VBR_seek_table.want = 1; gfc->VBR_seek_table.pos = 0; if (gfc->VBR_seek_table.bag == NULL) { gfc->VBR_seek_table.bag = malloc(400 * sizeof(int)); if (gfc->VBR_seek_table.bag != NULL) { gfc->VBR_seek_table.size = 400; } else { gfc->VBR_seek_table.size = 0; ERRORF(gfc, "Error: can't allocate VbrFrames buffer\n"); gfc->cfg.write_lame_tag = 0; return -1; } } /* write dummy VBR tag of all 0's into bitstream */ { uint8_t buffer[MAXFRAMESIZE]; size_t i, n; memset(buffer, 0, sizeof(buffer)); setLameTagFrameHeader(gfc, buffer); n = gfc->VBR_seek_table.TotalFrameSize; for (i = 0; i < n; ++i) { add_dummy_byte(gfc, buffer[i], 1); } } /* Success */ return 0; } /* fast CRC-16 computation - uses table crc16_lookup 8*/ static uint16_t CRC_update_lookup(uint16_t value, uint16_t crc) { uint16_t tmp; tmp = crc ^ value; crc = (crc >> 8) ^ crc16_lookup[tmp & 0xff]; return crc; } void UpdateMusicCRC(uint16_t * crc, unsigned char const *buffer, int size) { int i; for (i = 0; i < size; ++i) *crc = CRC_update_lookup(buffer[i], *crc); } /**************************************************************************** * Jonathan Dee 2001/08/31 * * PutLameVBR: Write LAME info: mini version + info on various switches used * Paramters: * pbtStreamBuffer : pointer to output buffer * id3v2size : size of id3v2 tag in bytes * crc : computation of crc-16 of Lame Tag so far (starting at frame sync) * **************************************************************************** */ static int PutLameVBR(lame_global_flags const *gfp, size_t nMusicLength, uint8_t * pbtStreamBuffer, uint16_t crc) { lame_internal_flags const *gfc = gfp->internal_flags; SessionConfig_t const *const cfg = &gfc->cfg; int nBytesWritten = 0; int i; int enc_delay = gfc->ov_enc.encoder_delay; /* encoder delay */ int enc_padding = gfc->ov_enc.encoder_padding; /* encoder padding */ /*recall: cfg->vbr_q is for example set by the switch -V */ /* gfp->quality by -q, -h, -f, etc */ int nQuality = (100 - 10 * gfp->VBR_q - gfp->quality); /* NOTE: Even though the specification for the LAME VBR tag did explicitly mention other encoders than LAME, many SW/HW decoder seem to be able to make use of this tag only, if the encoder version starts with LAME. To be compatible with such decoders, ANY encoder will be forced to write a fake LAME version string! As a result, the encoder version info becomes worthless. */ const char *szVersion = get_lame_tag_encoder_short_version(); uint8_t nVBR; uint8_t nRevision = 0x00; uint8_t nRevMethod; uint8_t vbr_type_translator[] = { 1, 5, 3, 2, 4, 0, 3 }; /*numbering different in vbr_mode vs. Lame tag */ uint8_t nLowpass = (((cfg->lowpassfreq / 100.0) + .5) > 255 ? 255 : (cfg->lowpassfreq / 100.0) + .5); uint32_t nPeakSignalAmplitude = 0; uint16_t nRadioReplayGain = 0; uint16_t nAudiophileReplayGain = 0; uint8_t nNoiseShaping = cfg->noise_shaping; uint8_t nStereoMode = 0; int bNonOptimal = 0; uint8_t nSourceFreq = 0; uint8_t nMisc = 0; uint16_t nMusicCRC = 0; /*psy model type: Gpsycho or NsPsytune */ unsigned char bExpNPsyTune = 1; /* only NsPsytune */ unsigned char bSafeJoint = (cfg->use_safe_joint_stereo) != 0; unsigned char bNoGapMore = 0; unsigned char bNoGapPrevious = 0; int nNoGapCount = gfp->nogap_total; int nNoGapCurr = gfp->nogap_current; uint8_t nAthType = cfg->ATHtype; /*4 bits. */ uint8_t nFlags = 0; /* if ABR, {store bitrate <=255} else { store "-b"} */ int nABRBitrate; switch (cfg->vbr) { case vbr_abr:{ nABRBitrate = cfg->vbr_avg_bitrate_kbps; break; } case vbr_off:{ nABRBitrate = cfg->avg_bitrate; break; } default:{ /*vbr modes */ nABRBitrate = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index];; } } /*revision and vbr method */ if (cfg->vbr < sizeof(vbr_type_translator)) nVBR = vbr_type_translator[cfg->vbr]; else nVBR = 0x00; /*unknown. */ nRevMethod = 0x10 * nRevision + nVBR; /* ReplayGain */ if (cfg->findReplayGain) { int RadioGain = gfc->ov_rpg.RadioGain; if (RadioGain > 0x1FE) RadioGain = 0x1FE; if (RadioGain < -0x1FE) RadioGain = -0x1FE; nRadioReplayGain = 0x2000; /* set name code */ nRadioReplayGain |= 0xC00; /* set originator code to `determined automatically' */ if (RadioGain >= 0) nRadioReplayGain |= RadioGain; /* set gain adjustment */ else { nRadioReplayGain |= 0x200; /* set the sign bit */ nRadioReplayGain |= -RadioGain; /* set gain adjustment */ } } /* peak sample */ if (cfg->findPeakSample) nPeakSignalAmplitude = abs((int) ((((FLOAT) gfc->ov_rpg.PeakSample) / 32767.0) * pow(2, 23) + .5)); /*nogap */ if (nNoGapCount != -1) { if (nNoGapCurr > 0) bNoGapPrevious = 1; if (nNoGapCurr < nNoGapCount - 1) bNoGapMore = 1; } /*flags */ nFlags = nAthType + (bExpNPsyTune << 4) + (bSafeJoint << 5) + (bNoGapMore << 6) + (bNoGapPrevious << 7); if (nQuality < 0) nQuality = 0; /*stereo mode field... a bit ugly. */ switch (cfg->mode) { case MONO: nStereoMode = 0; break; case STEREO: nStereoMode = 1; break; case DUAL_CHANNEL: nStereoMode = 2; break; case JOINT_STEREO: if (cfg->force_ms) nStereoMode = 4; else nStereoMode = 3; break; case NOT_SET: /* FALLTHROUGH */ default: nStereoMode = 7; break; } /*Intensity stereo : nStereoMode = 6. IS is not implemented */ if (cfg->samplerate_in <= 32000) nSourceFreq = 0x00; else if (cfg->samplerate_in == 48000) nSourceFreq = 0x02; else if (cfg->samplerate_in > 48000) nSourceFreq = 0x03; else nSourceFreq = 0x01; /*default is 44100Hz. */ /*Check if the user overrided the default LAME behaviour with some nasty options */ if (cfg->short_blocks == short_block_forced || cfg->short_blocks == short_block_dispensed || ((cfg->lowpassfreq == -1) && (cfg->highpassfreq == -1)) || /* "-k" */ (cfg->disable_reservoir && cfg->avg_bitrate < 320) || cfg->noATH || cfg->ATHonly || (nAthType == 0) || cfg->samplerate_in <= 32000) bNonOptimal = 1; nMisc = nNoiseShaping + (nStereoMode << 2) + (bNonOptimal << 5) + (nSourceFreq << 6); nMusicCRC = gfc->nMusicCRC; /*Write all this information into the stream */ CreateI4(&pbtStreamBuffer[nBytesWritten], nQuality); nBytesWritten += 4; strncpy((char *) &pbtStreamBuffer[nBytesWritten], szVersion, 9); nBytesWritten += 9; pbtStreamBuffer[nBytesWritten] = nRevMethod; nBytesWritten++; pbtStreamBuffer[nBytesWritten] = nLowpass; nBytesWritten++; CreateI4(&pbtStreamBuffer[nBytesWritten], nPeakSignalAmplitude); nBytesWritten += 4; CreateI2(&pbtStreamBuffer[nBytesWritten], nRadioReplayGain); nBytesWritten += 2; CreateI2(&pbtStreamBuffer[nBytesWritten], nAudiophileReplayGain); nBytesWritten += 2; pbtStreamBuffer[nBytesWritten] = nFlags; nBytesWritten++; if (nABRBitrate >= 255) pbtStreamBuffer[nBytesWritten] = 0xFF; else pbtStreamBuffer[nBytesWritten] = nABRBitrate; nBytesWritten++; pbtStreamBuffer[nBytesWritten] = enc_delay >> 4; /* works for win32, does it for unix? */ pbtStreamBuffer[nBytesWritten + 1] = (enc_delay << 4) + (enc_padding >> 8); pbtStreamBuffer[nBytesWritten + 2] = enc_padding; nBytesWritten += 3; pbtStreamBuffer[nBytesWritten] = nMisc; nBytesWritten++; pbtStreamBuffer[nBytesWritten++] = 0; /*unused in rev0 */ CreateI2(&pbtStreamBuffer[nBytesWritten], cfg->preset); nBytesWritten += 2; CreateI4(&pbtStreamBuffer[nBytesWritten], (int) nMusicLength); nBytesWritten += 4; CreateI2(&pbtStreamBuffer[nBytesWritten], nMusicCRC); nBytesWritten += 2; /*Calculate tag CRC.... must be done here, since it includes *previous information*/ for (i = 0; i < nBytesWritten; i++) crc = CRC_update_lookup(pbtStreamBuffer[i], crc); CreateI2(&pbtStreamBuffer[nBytesWritten], crc); nBytesWritten += 2; return nBytesWritten; } static long skipId3v2(FILE * fpStream) { size_t nbytes; long id3v2TagSize; unsigned char id3v2Header[10]; /* seek to the beginning of the stream */ if (fseek(fpStream, 0, SEEK_SET) != 0) { return -2; /* not seekable, abort */ } /* read 10 bytes in case there's an ID3 version 2 header here */ nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream); if (nbytes != sizeof(id3v2Header)) { return -3; /* not readable, maybe opened Write-Only */ } /* does the stream begin with the ID3 version 2 file identifier? */ if (!strncmp((char *) id3v2Header, "ID3", 3)) { /* the tag size (minus the 10-byte header) is encoded into four * bytes where the most significant bit is clear in each byte */ id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) | ((id3v2Header[7] & 0x7f) << 14) | ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f)) + sizeof id3v2Header; } else { /* no ID3 version 2 tag in this stream */ id3v2TagSize = 0; } return id3v2TagSize; } size_t lame_get_lametag_frame(lame_global_flags const *gfp, unsigned char *buffer, size_t size) { lame_internal_flags *gfc; SessionConfig_t const *cfg; unsigned long stream_size; unsigned int nStreamIndex; uint8_t btToc[NUMTOCENTRIES]; if (gfp == 0) { return 0; } gfc = gfp->internal_flags; if (gfc == 0) { return 0; } if (gfc->class_id != LAME_ID) { return 0; } cfg = &gfc->cfg; if (cfg->write_lame_tag == 0) { return 0; } if (gfc->VBR_seek_table.pos <= 0) { return 0; } if (size < gfc->VBR_seek_table.TotalFrameSize) { return gfc->VBR_seek_table.TotalFrameSize; } if (buffer == 0) { return 0; } memset(buffer, 0, gfc->VBR_seek_table.TotalFrameSize); /* 4 bytes frame header */ setLameTagFrameHeader(gfc, buffer); /* Clear all TOC entries */ memset(btToc, 0, sizeof(btToc)); if (cfg->free_format) { int i; for (i = 1; i < NUMTOCENTRIES; ++i) btToc[i] = 255 * i / 100; } else { Xing_seek_table(&gfc->VBR_seek_table, btToc); } #ifdef DEBUG_VBR_SEEKING_TABLE print_seeking(btToc); #endif /* Start writing the tag after the zero frame */ nStreamIndex = cfg->sideinfo_len; /* note! Xing header specifies that Xing data goes in the * ancillary data with NO ERROR PROTECTION. If error protecton * in enabled, the Xing data still starts at the same offset, * and now it is in sideinfo data block, and thus will not * decode correctly by non-Xing tag aware players */ if (cfg->error_protection) nStreamIndex -= 2; /* Put Vbr tag */ if (cfg->vbr == vbr_off) { buffer[nStreamIndex++] = VBRTag1[0]; buffer[nStreamIndex++] = VBRTag1[1]; buffer[nStreamIndex++] = VBRTag1[2]; buffer[nStreamIndex++] = VBRTag1[3]; } else { buffer[nStreamIndex++] = VBRTag0[0]; buffer[nStreamIndex++] = VBRTag0[1]; buffer[nStreamIndex++] = VBRTag0[2]; buffer[nStreamIndex++] = VBRTag0[3]; } /* Put header flags */ CreateI4(&buffer[nStreamIndex], FRAMES_FLAG + BYTES_FLAG + TOC_FLAG + VBR_SCALE_FLAG); nStreamIndex += 4; /* Put Total Number of frames */ CreateI4(&buffer[nStreamIndex], gfc->VBR_seek_table.nVbrNumFrames); nStreamIndex += 4; /* Put total audio stream size, including Xing/LAME Header */ stream_size = gfc->VBR_seek_table.nBytesWritten + gfc->VBR_seek_table.TotalFrameSize; CreateI4(&buffer[nStreamIndex], stream_size); nStreamIndex += 4; /* Put TOC */ memcpy(&buffer[nStreamIndex], btToc, sizeof(btToc)); nStreamIndex += sizeof(btToc); if (cfg->error_protection) { /* (jo) error_protection: add crc16 information to header */ CRC_writeheader(gfc, (char *) buffer); } { /*work out CRC so far: initially crc = 0 */ uint16_t crc = 0x00; unsigned int i; for (i = 0; i < nStreamIndex; i++) crc = CRC_update_lookup(buffer[i], crc); /*Put LAME VBR info */ nStreamIndex += PutLameVBR(gfp, stream_size, buffer + nStreamIndex, crc); } #ifdef DEBUG_VBRTAG { VBRTAGDATA TestHeader; GetVbrTag(&TestHeader, buffer); } #endif return gfc->VBR_seek_table.TotalFrameSize; } /*********************************************************************** * * PutVbrTag: Write final VBR tag to the file * Paramters: * lpszFileName: filename of MP3 bit stream * nVbrScale : encoder quality indicator (0..100) **************************************************************************** */ int PutVbrTag(lame_global_flags const *gfp, FILE * fpStream) { lame_internal_flags *gfc = gfp->internal_flags; long lFileSize; long id3v2TagSize; size_t nbytes; uint8_t buffer[MAXFRAMESIZE]; if (gfc->VBR_seek_table.pos <= 0) return -1; /* Seek to end of file */ fseek(fpStream, 0, SEEK_END); /* Get file size */ lFileSize = ftell(fpStream); /* Abort if file has zero length. Yes, it can happen :) */ if (lFileSize == 0) return -1; /* * The VBR tag may NOT be located at the beginning of the stream. * If an ID3 version 2 tag was added, then it must be skipped to write * the VBR tag data. */ id3v2TagSize = skipId3v2(fpStream); if (id3v2TagSize < 0) { return id3v2TagSize; } /*Seek to the beginning of the stream */ fseek(fpStream, id3v2TagSize, SEEK_SET); nbytes = lame_get_lametag_frame(gfp, buffer, sizeof(buffer)); if (nbytes > sizeof(buffer)) { return -1; } if (nbytes < 1) { return 0; } /* Put it all to disk again */ if (fwrite(buffer, nbytes, 1, fpStream) != 1) { return -1; } return 0; /* success */ } ================================================ FILE: app/jni/libmp3lame/VbrTag.h ================================================ /* * Xing VBR tagging for LAME. * * Copyright (c) 1999 A.L. Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_VRBTAG_H #define LAME_VRBTAG_H /* ----------------------------------------------------------- * A Vbr header may be present in the ancillary * data field of the first frame of an mp3 bitstream * The Vbr header (optionally) contains * frames total number of audio frames in the bitstream * bytes total number of bytes in the bitstream * toc table of contents * toc (table of contents) gives seek points * for random access * the ith entry determines the seek point for * i-percent duration * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes */ #define FRAMES_FLAG 0x0001 #define BYTES_FLAG 0x0002 #define TOC_FLAG 0x0004 #define VBR_SCALE_FLAG 0x0008 #define NUMTOCENTRIES 100 #ifndef lame_internal_flags_defined #define lame_internal_flags_defined struct lame_internal_flags; typedef struct lame_internal_flags lame_internal_flags; #endif /*structure to receive extracted header */ /* toc may be NULL*/ typedef struct { int h_id; /* from MPEG header, 0=MPEG2, 1=MPEG1 */ int samprate; /* determined from MPEG header */ int flags; /* from Vbr header data */ int frames; /* total bit stream frames from Vbr header data */ int bytes; /* total bit stream bytes from Vbr header data */ int vbr_scale; /* encoded vbr scale from Vbr header data */ unsigned char toc[NUMTOCENTRIES]; /* may be NULL if toc not desired */ int headersize; /* size of VBR header, in bytes */ int enc_delay; /* encoder delay */ int enc_padding; /* encoder paddign added at end of stream */ } VBRTAGDATA; int GetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf); int InitVbrTag(lame_global_flags * gfp); int PutVbrTag(lame_global_flags const *gfp, FILE * fid); void AddVbrFrame(lame_internal_flags * gfc); void UpdateMusicCRC(uint16_t * crc, const unsigned char *buffer, int size); #endif ================================================ FILE: app/jni/libmp3lame/bitstream.c ================================================ /* * MP3 bitstream Output interface for LAME * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 1999-2002 Takehiro Tominaga * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: bitstream.c,v 1.97 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "tables.h" #include "quantize_pvt.h" #include "lame_global_flags.h" #include "gain_analysis.h" #include "VbrTag.h" #include "bitstream.h" #include "tables.h" /* unsigned int is at least this large: */ /* we work with ints, so when doing bit manipulation, we limit * ourselves to MAX_LENGTH-2 just to be on the safe side */ #define MAX_LENGTH 32 #ifdef DEBUG static int hogege; #endif static int calcFrameLength(SessionConfig_t const *const cfg, int kbps, int pad) { return 8 * ((cfg->version + 1) * 72000 * kbps / cfg->samplerate_out + pad); } /*********************************************************************** * compute bitsperframe and mean_bits for a layer III frame **********************************************************************/ int getframebits(const lame_internal_flags * gfc) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t const *const eov = &gfc->ov_enc; int bit_rate; /* get bitrate in kbps [?] */ if (eov->bitrate_index) bit_rate = bitrate_table[cfg->version][eov->bitrate_index]; else bit_rate = cfg->avg_bitrate; /*assert(bit_rate <= 550); */ assert(8 <= bit_rate && bit_rate <= 640); /* main encoding routine toggles padding on and off */ /* one Layer3 Slot consists of 8 bits */ return calcFrameLength(cfg, bit_rate, eov->padding); } int get_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint) { int maxmp3buf = 0; if (cfg->avg_bitrate > 320) { /* in freeformat the buffer is constant */ if (constraint == MDB_STRICT_ISO) { maxmp3buf = calcFrameLength(cfg, cfg->avg_bitrate, 0); } else { /* maximum allowed bits per granule are 7680 */ maxmp3buf = 7680 * (cfg->version + 1); } } else { int max_kbps; if (cfg->samplerate_out < 16000) { max_kbps = bitrate_table[cfg->version][8]; /* default: allow 64 kbps (MPEG-2.5) */ } else { max_kbps = bitrate_table[cfg->version][14]; } switch (constraint) { default: case MDB_DEFAULT: /* Bouvigne suggests this more lax interpretation of the ISO doc instead of using 8*960. */ /* All mp3 decoders should have enough buffer to handle this value: size of a 320kbps 32kHz frame */ maxmp3buf = 8 * 1440; break; case MDB_STRICT_ISO: maxmp3buf = calcFrameLength(cfg, max_kbps, 0); break; case MDB_MAXIMUM: maxmp3buf = 7680 * (cfg->version + 1); break; } } return maxmp3buf; } static void putheader_bits(lame_internal_flags * gfc) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; Bit_stream_struc *bs = &gfc->bs; #ifdef DEBUG hogege += cfg->sideinfo_len * 8; #endif memcpy(&bs->buf[bs->buf_byte_idx], esv->header[esv->w_ptr].buf, cfg->sideinfo_len); bs->buf_byte_idx += cfg->sideinfo_len; bs->totbit += cfg->sideinfo_len * 8; esv->w_ptr = (esv->w_ptr + 1) & (MAX_HEADER_BUF - 1); } /*write j bits into the bit stream */ inline static void putbits2(lame_internal_flags * gfc, int val, int j) { EncStateVar_t const *const esv = &gfc->sv_enc; Bit_stream_struc *bs; bs = &gfc->bs; assert(j < MAX_LENGTH - 2); while (j > 0) { int k; if (bs->buf_bit_idx == 0) { bs->buf_bit_idx = 8; bs->buf_byte_idx++; assert(bs->buf_byte_idx < BUFFER_SIZE); assert(esv->header[esv->w_ptr].write_timing >= bs->totbit); if (esv->header[esv->w_ptr].write_timing == bs->totbit) { putheader_bits(gfc); } bs->buf[bs->buf_byte_idx] = 0; } k = Min(j, bs->buf_bit_idx); j -= k; bs->buf_bit_idx -= k; assert(j < MAX_LENGTH); /* 32 too large on 32 bit machines */ assert(bs->buf_bit_idx < MAX_LENGTH); bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx); bs->totbit += k; } } /*write j bits into the bit stream, ignoring frame headers */ inline static void putbits_noheaders(lame_internal_flags * gfc, int val, int j) { Bit_stream_struc *bs; bs = &gfc->bs; assert(j < MAX_LENGTH - 2); while (j > 0) { int k; if (bs->buf_bit_idx == 0) { bs->buf_bit_idx = 8; bs->buf_byte_idx++; assert(bs->buf_byte_idx < BUFFER_SIZE); bs->buf[bs->buf_byte_idx] = 0; } k = Min(j, bs->buf_bit_idx); j -= k; bs->buf_bit_idx -= k; assert(j < MAX_LENGTH); /* 32 too large on 32 bit machines */ assert(bs->buf_bit_idx < MAX_LENGTH); bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx); bs->totbit += k; } } /* Some combinations of bitrate, Fs, and stereo make it impossible to stuff out a frame using just main_data, due to the limited number of bits to indicate main_data_length. In these situations, we put stuffing bits into the ancillary data... */ inline static void drain_into_ancillary(lame_internal_flags * gfc, int remainingBits) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int i; assert(remainingBits >= 0); if (remainingBits >= 8) { putbits2(gfc, 0x4c, 8); remainingBits -= 8; } if (remainingBits >= 8) { putbits2(gfc, 0x41, 8); remainingBits -= 8; } if (remainingBits >= 8) { putbits2(gfc, 0x4d, 8); remainingBits -= 8; } if (remainingBits >= 8) { putbits2(gfc, 0x45, 8); remainingBits -= 8; } if (remainingBits >= 32) { const char *const version = get_lame_short_version(); if (remainingBits >= 32) for (i = 0; i < (int) strlen(version) && remainingBits >= 8; ++i) { remainingBits -= 8; putbits2(gfc, version[i], 8); } } for (; remainingBits >= 1; remainingBits -= 1) { putbits2(gfc, esv->ancillary_flag, 1); esv->ancillary_flag ^= !cfg->disable_reservoir; } assert(remainingBits == 0); } /*write N bits into the header */ inline static void writeheader(lame_internal_flags * gfc, int val, int j) { EncStateVar_t *const esv = &gfc->sv_enc; int ptr = esv->header[esv->h_ptr].ptr; while (j > 0) { int const k = Min(j, 8 - (ptr & 7)); j -= k; assert(j < MAX_LENGTH); /* >> 32 too large for 32 bit machines */ esv->header[esv->h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k); ptr += k; } esv->header[esv->h_ptr].ptr = ptr; } static int CRC_update(int value, int crc) { int i; value <<= 8; for (i = 0; i < 8; i++) { value <<= 1; crc <<= 1; if (((crc ^ value) & 0x10000)) crc ^= CRC16_POLYNOMIAL; } return crc; } void CRC_writeheader(lame_internal_flags const *gfc, char *header) { SessionConfig_t const *const cfg = &gfc->cfg; int crc = 0xffff; /* (jo) init crc16 for error_protection */ int i; crc = CRC_update(((unsigned char *) header)[2], crc); crc = CRC_update(((unsigned char *) header)[3], crc); for (i = 6; i < cfg->sideinfo_len; i++) { crc = CRC_update(((unsigned char *) header)[i], crc); } header[4] = crc >> 8; header[5] = crc & 255; } inline static void encodeSideInfo2(lame_internal_flags * gfc, int bitsPerFrame) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t const *const eov = &gfc->ov_enc; EncStateVar_t *const esv = &gfc->sv_enc; III_side_info_t *l3_side; int gr, ch; l3_side = &gfc->l3_side; esv->header[esv->h_ptr].ptr = 0; memset(esv->header[esv->h_ptr].buf, 0, cfg->sideinfo_len); if (cfg->samplerate_out < 16000) writeheader(gfc, 0xffe, 12); else writeheader(gfc, 0xfff, 12); writeheader(gfc, (cfg->version), 1); writeheader(gfc, 4 - 3, 2); writeheader(gfc, (!cfg->error_protection), 1); writeheader(gfc, (eov->bitrate_index), 4); writeheader(gfc, (cfg->samplerate_index), 2); writeheader(gfc, (eov->padding), 1); writeheader(gfc, (cfg->extension), 1); writeheader(gfc, (cfg->mode), 2); writeheader(gfc, (eov->mode_ext), 2); writeheader(gfc, (cfg->copyright), 1); writeheader(gfc, (cfg->original), 1); writeheader(gfc, (cfg->emphasis), 2); if (cfg->error_protection) { writeheader(gfc, 0, 16); /* dummy */ } if (cfg->version == 1) { /* MPEG1 */ assert(l3_side->main_data_begin >= 0); writeheader(gfc, (l3_side->main_data_begin), 9); if (cfg->channels_out == 2) writeheader(gfc, l3_side->private_bits, 3); else writeheader(gfc, l3_side->private_bits, 5); for (ch = 0; ch < cfg->channels_out; ch++) { int band; for (band = 0; band < 4; band++) { writeheader(gfc, l3_side->scfsi[ch][band], 1); } } for (gr = 0; gr < 2; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gr_info *const gi = &l3_side->tt[gr][ch]; writeheader(gfc, gi->part2_3_length + gi->part2_length, 12); writeheader(gfc, gi->big_values / 2, 9); writeheader(gfc, gi->global_gain, 8); writeheader(gfc, gi->scalefac_compress, 4); if (gi->block_type != NORM_TYPE) { writeheader(gfc, 1, 1); /* window_switching_flag */ writeheader(gfc, gi->block_type, 2); writeheader(gfc, gi->mixed_block_flag, 1); if (gi->table_select[0] == 14) gi->table_select[0] = 16; writeheader(gfc, gi->table_select[0], 5); if (gi->table_select[1] == 14) gi->table_select[1] = 16; writeheader(gfc, gi->table_select[1], 5); writeheader(gfc, gi->subblock_gain[0], 3); writeheader(gfc, gi->subblock_gain[1], 3); writeheader(gfc, gi->subblock_gain[2], 3); } else { writeheader(gfc, 0, 1); /* window_switching_flag */ if (gi->table_select[0] == 14) gi->table_select[0] = 16; writeheader(gfc, gi->table_select[0], 5); if (gi->table_select[1] == 14) gi->table_select[1] = 16; writeheader(gfc, gi->table_select[1], 5); if (gi->table_select[2] == 14) gi->table_select[2] = 16; writeheader(gfc, gi->table_select[2], 5); assert(0 <= gi->region0_count && gi->region0_count < 16); assert(0 <= gi->region1_count && gi->region1_count < 8); writeheader(gfc, gi->region0_count, 4); writeheader(gfc, gi->region1_count, 3); } writeheader(gfc, gi->preflag, 1); writeheader(gfc, gi->scalefac_scale, 1); writeheader(gfc, gi->count1table_select, 1); } } } else { /* MPEG2 */ assert(l3_side->main_data_begin >= 0); writeheader(gfc, (l3_side->main_data_begin), 8); writeheader(gfc, l3_side->private_bits, cfg->channels_out); gr = 0; for (ch = 0; ch < cfg->channels_out; ch++) { gr_info *const gi = &l3_side->tt[gr][ch]; writeheader(gfc, gi->part2_3_length + gi->part2_length, 12); writeheader(gfc, gi->big_values / 2, 9); writeheader(gfc, gi->global_gain, 8); writeheader(gfc, gi->scalefac_compress, 9); if (gi->block_type != NORM_TYPE) { writeheader(gfc, 1, 1); /* window_switching_flag */ writeheader(gfc, gi->block_type, 2); writeheader(gfc, gi->mixed_block_flag, 1); if (gi->table_select[0] == 14) gi->table_select[0] = 16; writeheader(gfc, gi->table_select[0], 5); if (gi->table_select[1] == 14) gi->table_select[1] = 16; writeheader(gfc, gi->table_select[1], 5); writeheader(gfc, gi->subblock_gain[0], 3); writeheader(gfc, gi->subblock_gain[1], 3); writeheader(gfc, gi->subblock_gain[2], 3); } else { writeheader(gfc, 0, 1); /* window_switching_flag */ if (gi->table_select[0] == 14) gi->table_select[0] = 16; writeheader(gfc, gi->table_select[0], 5); if (gi->table_select[1] == 14) gi->table_select[1] = 16; writeheader(gfc, gi->table_select[1], 5); if (gi->table_select[2] == 14) gi->table_select[2] = 16; writeheader(gfc, gi->table_select[2], 5); assert(0 <= gi->region0_count && gi->region0_count < 16); assert(0 <= gi->region1_count && gi->region1_count < 8); writeheader(gfc, gi->region0_count, 4); writeheader(gfc, gi->region1_count, 3); } writeheader(gfc, gi->scalefac_scale, 1); writeheader(gfc, gi->count1table_select, 1); } } if (cfg->error_protection) { /* (jo) error_protection: add crc16 information to header */ CRC_writeheader(gfc, esv->header[esv->h_ptr].buf); } { int const old = esv->h_ptr; assert(esv->header[old].ptr == cfg->sideinfo_len * 8); esv->h_ptr = (old + 1) & (MAX_HEADER_BUF - 1); esv->header[esv->h_ptr].write_timing = esv->header[old].write_timing + bitsPerFrame; if (esv->h_ptr == esv->w_ptr) { /* yikes! we are out of header buffer space */ ERRORF(gfc, "Error: MAX_HEADER_BUF too small in bitstream.c \n"); } } } inline static int huffman_coder_count1(lame_internal_flags * gfc, gr_info const *gi) { /* Write count1 area */ struct huffcodetab const *const h = &ht[gi->count1table_select + 32]; int i, bits = 0; #ifdef DEBUG int gegebo = gfc->bs.totbit; #endif int const *ix = &gi->l3_enc[gi->big_values]; FLOAT const *xr = &gi->xr[gi->big_values]; assert(gi->count1table_select < 2); for (i = (gi->count1 - gi->big_values) / 4; i > 0; --i) { int huffbits = 0; int p = 0, v; v = ix[0]; if (v) { p += 8; if (xr[0] < 0.0f) huffbits++; assert(v <= 1); } v = ix[1]; if (v) { p += 4; huffbits *= 2; if (xr[1] < 0.0f) huffbits++; assert(v <= 1); } v = ix[2]; if (v) { p += 2; huffbits *= 2; if (xr[2] < 0.0f) huffbits++; assert(v <= 1); } v = ix[3]; if (v) { p++; huffbits *= 2; if (xr[3] < 0.0f) huffbits++; assert(v <= 1); } ix += 4; xr += 4; putbits2(gfc, huffbits + h->table[p], h->hlen[p]); bits += h->hlen[p]; } #ifdef DEBUG DEBUGF(gfc, "count1: real: %ld counted:%d (bigv %d count1len %d)\n", gfc->bs.totbit - gegebo, gi->count1bits, gi->big_values, gi->count1); #endif return bits; } /* Implements the pseudocode of page 98 of the IS */ inline static int Huffmancode(lame_internal_flags * const gfc, const unsigned int tableindex, int start, int end, gr_info const *gi) { struct huffcodetab const *const h = &ht[tableindex]; unsigned int const linbits = h->xlen; int i, bits = 0; assert(tableindex < 32u); if (!tableindex) return bits; for (i = start; i < end; i += 2) { int16_t cbits = 0; uint16_t xbits = 0; unsigned int xlen = h->xlen; unsigned int ext = 0; unsigned int x1 = gi->l3_enc[i]; unsigned int x2 = gi->l3_enc[i + 1]; assert(gi->l3_enc[i] >= 0); assert(gi->l3_enc[i+1] >= 0); if (x1 != 0u) { if (gi->xr[i] < 0.0f) ext++; cbits--; } if (tableindex > 15u) { /* use ESC-words */ if (x1 >= 15u) { uint16_t const linbits_x1 = x1 - 15u; assert(linbits_x1 <= h->linmax); ext |= linbits_x1 << 1u; xbits = linbits; x1 = 15u; } if (x2 >= 15u) { uint16_t const linbits_x2 = x2 - 15u; assert(linbits_x2 <= h->linmax); ext <<= linbits; ext |= linbits_x2; xbits += linbits; x2 = 15u; } xlen = 16; } if (x2 != 0u) { ext <<= 1; if (gi->xr[i + 1] < 0.0f) ext++; cbits--; } assert((x1 | x2) < 16u); x1 = x1 * xlen + x2; xbits -= cbits; cbits += h->hlen[x1]; assert(cbits <= MAX_LENGTH); assert(xbits <= MAX_LENGTH); putbits2(gfc, h->table[x1], cbits); putbits2(gfc, (int)ext, xbits); bits += cbits + xbits; } return bits; } /* Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as well as the definitions of the side information on pages 26 and 27. */ static int ShortHuffmancodebits(lame_internal_flags * gfc, gr_info const *gi) { int bits; int region1Start; region1Start = 3 * gfc->scalefac_band.s[3]; if (region1Start > gi->big_values) region1Start = gi->big_values; /* short blocks do not have a region2 */ bits = Huffmancode(gfc, gi->table_select[0], 0, region1Start, gi); bits += Huffmancode(gfc, gi->table_select[1], region1Start, gi->big_values, gi); return bits; } static int LongHuffmancodebits(lame_internal_flags * gfc, gr_info const *gi) { unsigned int i; int bigvalues, bits; int region1Start, region2Start; bigvalues = gi->big_values; assert(0 <= bigvalues && bigvalues <= 576); assert(gi->region0_count >= -1); assert(gi->region1_count >= -1); i = gi->region0_count + 1; assert((size_t) i < dimension_of(gfc->scalefac_band.l)); region1Start = gfc->scalefac_band.l[i]; i += gi->region1_count + 1; assert((size_t) i < dimension_of(gfc->scalefac_band.l)); region2Start = gfc->scalefac_band.l[i]; if (region1Start > bigvalues) region1Start = bigvalues; if (region2Start > bigvalues) region2Start = bigvalues; bits = Huffmancode(gfc, gi->table_select[0], 0, region1Start, gi); bits += Huffmancode(gfc, gi->table_select[1], region1Start, region2Start, gi); bits += Huffmancode(gfc, gi->table_select[2], region2Start, bigvalues, gi); return bits; } inline static int writeMainData(lame_internal_flags * const gfc) { SessionConfig_t const *const cfg = &gfc->cfg; III_side_info_t const *const l3_side = &gfc->l3_side; int gr, ch, sfb, data_bits, tot_bits = 0; if (cfg->version == 1) { /* MPEG 1 */ for (gr = 0; gr < 2; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gr_info const *const gi = &l3_side->tt[gr][ch]; int const slen1 = slen1_tab[gi->scalefac_compress]; int const slen2 = slen2_tab[gi->scalefac_compress]; data_bits = 0; #ifdef DEBUG hogege = gfc->bs.totbit; #endif for (sfb = 0; sfb < gi->sfbdivide; sfb++) { if (gi->scalefac[sfb] == -1) continue; /* scfsi is used */ putbits2(gfc, gi->scalefac[sfb], slen1); data_bits += slen1; } for (; sfb < gi->sfbmax; sfb++) { if (gi->scalefac[sfb] == -1) continue; /* scfsi is used */ putbits2(gfc, gi->scalefac[sfb], slen2); data_bits += slen2; } assert(data_bits == gi->part2_length); if (gi->block_type == SHORT_TYPE) { data_bits += ShortHuffmancodebits(gfc, gi); } else { data_bits += LongHuffmancodebits(gfc, gi); } data_bits += huffman_coder_count1(gfc, gi); #ifdef DEBUG DEBUGF(gfc, "<%ld> ", gfc->bs.totbit - hogege); #endif /* does bitcount in quantize.c agree with actual bit count? */ assert(data_bits == gi->part2_3_length + gi->part2_length); tot_bits += data_bits; } /* for ch */ } /* for gr */ } else { /* MPEG 2 */ gr = 0; for (ch = 0; ch < cfg->channels_out; ch++) { gr_info const *const gi = &l3_side->tt[gr][ch]; int i, sfb_partition, scale_bits = 0; assert(gi->sfb_partition_table); data_bits = 0; #ifdef DEBUG hogege = gfc->bs.totbit; #endif sfb = 0; sfb_partition = 0; if (gi->block_type == SHORT_TYPE) { for (; sfb_partition < 4; sfb_partition++) { int const sfbs = gi->sfb_partition_table[sfb_partition] / 3; int const slen = gi->slen[sfb_partition]; for (i = 0; i < sfbs; i++, sfb++) { putbits2(gfc, Max(gi->scalefac[sfb * 3 + 0], 0), slen); putbits2(gfc, Max(gi->scalefac[sfb * 3 + 1], 0), slen); putbits2(gfc, Max(gi->scalefac[sfb * 3 + 2], 0), slen); scale_bits += 3 * slen; } } data_bits += ShortHuffmancodebits(gfc, gi); } else { for (; sfb_partition < 4; sfb_partition++) { int const sfbs = gi->sfb_partition_table[sfb_partition]; int const slen = gi->slen[sfb_partition]; for (i = 0; i < sfbs; i++, sfb++) { putbits2(gfc, Max(gi->scalefac[sfb], 0), slen); scale_bits += slen; } } data_bits += LongHuffmancodebits(gfc, gi); } data_bits += huffman_coder_count1(gfc, gi); #ifdef DEBUG DEBUGF(gfc, "<%ld> ", gfc->bs.totbit - hogege); #endif /* does bitcount in quantize.c agree with actual bit count? */ assert(data_bits == gi->part2_3_length); assert(scale_bits == gi->part2_length); tot_bits += scale_bits + data_bits; } /* for ch */ } /* for gf */ return tot_bits; } /* main_data */ /* compute the number of bits required to flush all mp3 frames currently in the buffer. This should be the same as the reservoir size. Only call this routine between frames - i.e. only after all headers and data have been added to the buffer by format_bitstream(). Also compute total_bits_output = size of mp3 buffer (including frame headers which may not have yet been send to the mp3 buffer) + number of bits needed to flush all mp3 frames. total_bytes_output is the size of the mp3 output buffer if lame_encode_flush_nogap() was called right now. */ int compute_flushbits(const lame_internal_flags * gfc, int *total_bytes_output) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t const *const esv = &gfc->sv_enc; int flushbits, remaining_headers; int bitsPerFrame; int last_ptr, first_ptr; first_ptr = esv->w_ptr; /* first header to add to bitstream */ last_ptr = esv->h_ptr - 1; /* last header to add to bitstream */ if (last_ptr == -1) last_ptr = MAX_HEADER_BUF - 1; /* add this many bits to bitstream so we can flush all headers */ flushbits = esv->header[last_ptr].write_timing - gfc->bs.totbit; *total_bytes_output = flushbits; if (flushbits >= 0) { /* if flushbits >= 0, some headers have not yet been written */ /* reduce flushbits by the size of the headers */ remaining_headers = 1 + last_ptr - first_ptr; if (last_ptr < first_ptr) remaining_headers = 1 + last_ptr - first_ptr + MAX_HEADER_BUF; flushbits -= remaining_headers * 8 * cfg->sideinfo_len; } /* finally, add some bits so that the last frame is complete * these bits are not necessary to decode the last frame, but * some decoders will ignore last frame if these bits are missing */ bitsPerFrame = getframebits(gfc); flushbits += bitsPerFrame; *total_bytes_output += bitsPerFrame; /* round up: */ if (*total_bytes_output % 8) *total_bytes_output = 1 + (*total_bytes_output / 8); else *total_bytes_output = (*total_bytes_output / 8); *total_bytes_output += gfc->bs.buf_byte_idx + 1; if (flushbits < 0) { #if 0 /* if flushbits < 0, this would mean that the buffer looks like: * (data...) last_header (data...) (extra data that should not be here...) */ DEBUGF(gfc, "last header write_timing = %i \n", esv->header[last_ptr].write_timing); DEBUGF(gfc, "first header write_timing = %i \n", esv->header[first_ptr].write_timing); DEBUGF(gfc, "bs.totbit: %i \n", gfc->bs.totbit); DEBUGF(gfc, "first_ptr, last_ptr %i %i \n", first_ptr, last_ptr); DEBUGF(gfc, "remaining_headers = %i \n", remaining_headers); DEBUGF(gfc, "bitsperframe: %i \n", bitsPerFrame); DEBUGF(gfc, "sidelen: %i \n", cfg->sideinfo_len); #endif ERRORF(gfc, "strange error flushing buffer ... \n"); } return flushbits; } void flush_bitstream(lame_internal_flags * gfc) { EncStateVar_t *const esv = &gfc->sv_enc; III_side_info_t *l3_side; int nbytes; int flushbits; int last_ptr = esv->h_ptr - 1; /* last header to add to bitstream */ if (last_ptr == -1) last_ptr = MAX_HEADER_BUF - 1; l3_side = &gfc->l3_side; if ((flushbits = compute_flushbits(gfc, &nbytes)) < 0) return; drain_into_ancillary(gfc, flushbits); /* check that the 100% of the last frame has been written to bitstream */ assert(esv->header[last_ptr].write_timing + getframebits(gfc) == gfc->bs.totbit); /* we have padded out all frames with ancillary data, which is the same as filling the bitreservoir with ancillary data, so : */ esv->ResvSize = 0; l3_side->main_data_begin = 0; } void add_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n) { EncStateVar_t *const esv = &gfc->sv_enc; int i; while (n-- > 0u) { putbits_noheaders(gfc, val, 8); for (i = 0; i < MAX_HEADER_BUF; ++i) esv->header[i].write_timing += 8; } } /* format_bitstream() This is called after a frame of audio has been quantized and coded. It will write the encoded audio to the bitstream. Note that from a layer3 encoder's perspective the bit stream is primarily a series of main_data() blocks, with header and side information inserted at the proper locations to maintain framing. (See Figure A.7 in the IS). */ int format_bitstream(lame_internal_flags * gfc) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int bits, nbytes; III_side_info_t *l3_side; int bitsPerFrame; l3_side = &gfc->l3_side; bitsPerFrame = getframebits(gfc); drain_into_ancillary(gfc, l3_side->resvDrain_pre); encodeSideInfo2(gfc, bitsPerFrame); bits = 8 * cfg->sideinfo_len; bits += writeMainData(gfc); drain_into_ancillary(gfc, l3_side->resvDrain_post); bits += l3_side->resvDrain_post; l3_side->main_data_begin += (bitsPerFrame - bits) / 8; /* compare number of bits needed to clear all buffered mp3 frames * with what we think the resvsize is: */ if (compute_flushbits(gfc, &nbytes) != esv->ResvSize) { ERRORF(gfc, "Internal buffer inconsistency. flushbits <> ResvSize"); } /* compare main_data_begin for the next frame with what we * think the resvsize is: */ if ((l3_side->main_data_begin * 8) != esv->ResvSize) { ERRORF(gfc, "bit reservoir error: \n" "l3_side->main_data_begin: %i \n" "Resvoir size: %i \n" "resv drain (post) %i \n" "resv drain (pre) %i \n" "header and sideinfo: %i \n" "data bits: %i \n" "total bits: %i (remainder: %i) \n" "bitsperframe: %i \n", 8 * l3_side->main_data_begin, esv->ResvSize, l3_side->resvDrain_post, l3_side->resvDrain_pre, 8 * cfg->sideinfo_len, bits - l3_side->resvDrain_post - 8 * cfg->sideinfo_len, bits, bits % 8, bitsPerFrame); ERRORF(gfc, "This is a fatal error. It has several possible causes:"); ERRORF(gfc, "90%% LAME compiled with buggy version of gcc using advanced optimizations"); ERRORF(gfc, " 9%% Your system is overclocked"); ERRORF(gfc, " 1%% bug in LAME encoding library"); esv->ResvSize = l3_side->main_data_begin * 8; }; assert(gfc->bs.totbit % 8 == 0); if (gfc->bs.totbit > 1000000000) { /* to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset bit counter */ int i; for (i = 0; i < MAX_HEADER_BUF; ++i) esv->header[i].write_timing -= gfc->bs.totbit; gfc->bs.totbit = 0; } return 0; } static int do_gain_analysis(lame_internal_flags * gfc, unsigned char* buffer, int minimum) { SessionConfig_t const *const cfg = &gfc->cfg; RpgStateVar_t const *const rsv = &gfc->sv_rpg; RpgResult_t *const rov = &gfc->ov_rpg; #ifdef DECODE_ON_THE_FLY if (cfg->decode_on_the_fly) { /* decode the frame */ sample_t pcm_buf[2][1152]; int mp3_in = minimum; int samples_out = -1; /* re-synthesis to pcm. Repeat until we get a samples_out=0 */ while (samples_out != 0) { samples_out = hip_decode1_unclipped(gfc->hip, buffer, mp3_in, pcm_buf[0], pcm_buf[1]); /* samples_out = 0: need more data to decode * samples_out = -1: error. Lets assume 0 pcm output * samples_out = number of samples output */ /* set the lenght of the mp3 input buffer to zero, so that in the * next iteration of the loop we will be querying mpglib about * buffered data */ mp3_in = 0; if (samples_out == -1) { /* error decoding. Not fatal, but might screw up * the ReplayGain tag. What should we do? Ignore for now */ samples_out = 0; } if (samples_out > 0) { /* process the PCM data */ /* this should not be possible, and indicates we have * overflown the pcm_buf buffer */ assert(samples_out <= 1152); if (cfg->findPeakSample) { int i; /* FIXME: is this correct? maybe Max(fabs(pcm),PeakSample) */ for (i = 0; i < samples_out; i++) { if (pcm_buf[0][i] > rov->PeakSample) rov->PeakSample = pcm_buf[0][i]; else if (-pcm_buf[0][i] > rov->PeakSample) rov->PeakSample = -pcm_buf[0][i]; } if (cfg->channels_out > 1) for (i = 0; i < samples_out; i++) { if (pcm_buf[1][i] > rov->PeakSample) rov->PeakSample = pcm_buf[1][i]; else if (-pcm_buf[1][i] > rov->PeakSample) rov->PeakSample = -pcm_buf[1][i]; } } if (cfg->findReplayGain) if (AnalyzeSamples (rsv->rgdata, pcm_buf[0], pcm_buf[1], samples_out, cfg->channels_out) == GAIN_ANALYSIS_ERROR) return -6; } /* if (samples_out>0) */ } /* while (samples_out!=0) */ } /* if (gfc->decode_on_the_fly) */ #endif return minimum; } static int do_copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int size) { Bit_stream_struc *const bs = &gfc->bs; int const minimum = bs->buf_byte_idx + 1; if (minimum <= 0) return 0; if (size != 0 && minimum > size) return -1; /* buffer is too small */ memcpy(buffer, bs->buf, minimum); // bcopy(buffer, bs->buf, minimum); bs->buf_byte_idx = -1; bs->buf_bit_idx = 0; return minimum; } /* copy data out of the internal MP3 bit buffer into a user supplied unsigned char buffer. mp3data=0 indicates data in buffer is an id3tags and VBR tags mp3data=1 data is real mp3 frame data. */ int copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int size, int mp3data) { int const minimum = do_copy_buffer(gfc, buffer, size); if (minimum > 0 && mp3data) { UpdateMusicCRC(&gfc->nMusicCRC, buffer, minimum); /** sum number of bytes belonging to the mp3 stream * this info will be written into the Xing/LAME header for seeking */ gfc->VBR_seek_table.nBytesWritten += minimum; return do_gain_analysis(gfc, buffer, minimum); } /* if (mp3data) */ return minimum; } void init_bit_stream_w(lame_internal_flags * gfc) { EncStateVar_t *const esv = &gfc->sv_enc; esv->h_ptr = esv->w_ptr = 0; esv->header[esv->h_ptr].write_timing = 0; gfc->bs.buf = (unsigned char *) malloc(BUFFER_SIZE); gfc->bs.buf_size = BUFFER_SIZE; gfc->bs.buf_byte_idx = -1; gfc->bs.buf_bit_idx = 0; gfc->bs.totbit = 0; } /* end of bitstream.c */ ================================================ FILE: app/jni/libmp3lame/bitstream.h ================================================ /* * MP3 bitstream Output interface for LAME * * Copyright (c) 1999 Takehiro TOMINAGA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_BITSTREAM_H #define LAME_BITSTREAM_H int getframebits(const lame_internal_flags * gfc); int format_bitstream(lame_internal_flags * gfc); void flush_bitstream(lame_internal_flags * gfc); void add_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n); int copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int buffer_size, int update_crc); void init_bit_stream_w(lame_internal_flags * gfc); void CRC_writeheader(lame_internal_flags const *gfc, char *buffer); int compute_flushbits(const lame_internal_flags * gfp, int *nbytes); int get_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint); #endif ================================================ FILE: app/jni/libmp3lame/encoder.c ================================================ /* * LAME MP3 encoding engine * * Copyright (c) 1999 Mark Taylor * Copyright (c) 2000-2002 Takehiro Tominaga * Copyright (c) 2000-2011 Robert Hegemann * Copyright (c) 2001 Gabriel Bouvigne * Copyright (c) 2001 John Dahlstrom * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: encoder.c,v 1.111 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "lame_global_flags.h" #include "newmdct.h" #include "psymodel.h" #include "lame-analysis.h" #include "bitstream.h" #include "VbrTag.h" #include "quantize_pvt.h" /* * auto-adjust of ATH, useful for low volume * Gabriel Bouvigne 3 feb 2001 * * modifies some values in * gfp->internal_flags->ATH * (gfc->ATH) */ static void adjust_ATH(lame_internal_flags const *const gfc) { SessionConfig_t const *const cfg = &gfc->cfg; FLOAT gr2_max, max_pow; if (gfc->ATH->use_adjust == 0) { gfc->ATH->adjust_factor = 1.0; /* no adjustment */ return; } /* jd - 2001 mar 12, 27, jun 30 */ /* loudness based on equal loudness curve; */ /* use granule with maximum combined loudness */ max_pow = gfc->ov_psy.loudness_sq[0][0]; gr2_max = gfc->ov_psy.loudness_sq[1][0]; if (cfg->channels_out == 2) { max_pow += gfc->ov_psy.loudness_sq[0][1]; gr2_max += gfc->ov_psy.loudness_sq[1][1]; } else { max_pow += max_pow; gr2_max += gr2_max; } if (cfg->mode_gr == 2) { max_pow = Max(max_pow, gr2_max); } max_pow *= 0.5; /* max_pow approaches 1.0 for full band noise */ /* jd - 2001 mar 31, jun 30 */ /* user tuning of ATH adjustment region */ max_pow *= gfc->ATH->aa_sensitivity_p; /* adjust ATH depending on range of maximum value */ /* jd - 2001 feb27, mar12,20, jun30, jul22 */ /* continuous curves based on approximation */ /* to GB's original values. */ /* For an increase in approximate loudness, */ /* set ATH adjust to adjust_limit immediately */ /* after a delay of one frame. */ /* For a loudness decrease, reduce ATH adjust */ /* towards adjust_limit gradually. */ /* max_pow is a loudness squared or a power. */ if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */ if (gfc->ATH->adjust_factor >= 1.0) { gfc->ATH->adjust_factor = 1.0; } else { /* preceding frame has lower ATH adjust; */ /* ascend only to the preceding adjust_limit */ /* in case there is leading low volume */ if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) { gfc->ATH->adjust_factor = gfc->ATH->adjust_limit; } } gfc->ATH->adjust_limit = 1.0; } else { /* adjustment curve */ /* about 32 dB maximum adjust (0.000625) */ FLOAT const adj_lim_new = 31.98 * max_pow + 0.000625; if (gfc->ATH->adjust_factor >= adj_lim_new) { /* descend gradually */ gfc->ATH->adjust_factor *= adj_lim_new * 0.075 + 0.925; if (gfc->ATH->adjust_factor < adj_lim_new) { /* stop descent */ gfc->ATH->adjust_factor = adj_lim_new; } } else { /* ascend */ if (gfc->ATH->adjust_limit >= adj_lim_new) { gfc->ATH->adjust_factor = adj_lim_new; } else { /* preceding frame has lower ATH adjust; */ /* ascend only to the preceding adjust_limit */ if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) { gfc->ATH->adjust_factor = gfc->ATH->adjust_limit; } } } gfc->ATH->adjust_limit = adj_lim_new; } } /*********************************************************************** * * some simple statistics * * bitrate index 0: free bitrate -> not allowed in VBR mode * : bitrates, kbps depending on MPEG version * bitrate index 15: forbidden * * mode_ext: * 0: LR * 1: LR-i * 2: MS * 3: MS-i * ***********************************************************************/ static void updateStats(lame_internal_flags * const gfc) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *eov = &gfc->ov_enc; int gr, ch; assert(0 <= eov->bitrate_index && eov->bitrate_index < 16); assert(0 <= eov->mode_ext && eov->mode_ext < 4); /* count bitrate indices */ eov->bitrate_channelmode_hist[eov->bitrate_index][4]++; eov->bitrate_channelmode_hist[15][4]++; /* count 'em for every mode extension in case of 2 channel encoding */ if (cfg->channels_out == 2) { eov->bitrate_channelmode_hist[eov->bitrate_index][eov->mode_ext]++; eov->bitrate_channelmode_hist[15][eov->mode_ext]++; } for (gr = 0; gr < cfg->mode_gr; ++gr) { for (ch = 0; ch < cfg->channels_out; ++ch) { int bt = gfc->l3_side.tt[gr][ch].block_type; if (gfc->l3_side.tt[gr][ch].mixed_block_flag) bt = 4; eov->bitrate_blocktype_hist[eov->bitrate_index][bt]++; eov->bitrate_blocktype_hist[eov->bitrate_index][5]++; eov->bitrate_blocktype_hist[15][bt]++; eov->bitrate_blocktype_hist[15][5]++; } } } static void lame_encode_frame_init(lame_internal_flags * gfc, const sample_t *const inbuf[2]) { SessionConfig_t const *const cfg = &gfc->cfg; int ch, gr; if (gfc->lame_encode_frame_init == 0) { sample_t primebuff0[286 + 1152 + 576]; sample_t primebuff1[286 + 1152 + 576]; int const framesize = 576 * cfg->mode_gr; /* prime the MDCT/polyphase filterbank with a short block */ int i, j; gfc->lame_encode_frame_init = 1; memset(primebuff0, 0, sizeof(primebuff0)); memset(primebuff1, 0, sizeof(primebuff1)); for (i = 0, j = 0; i < 286 + 576 * (1 + cfg->mode_gr); ++i) { if (i < framesize) { primebuff0[i] = 0; if (cfg->channels_out == 2) primebuff1[i] = 0; } else { primebuff0[i] = inbuf[0][j]; if (cfg->channels_out == 2) primebuff1[i] = inbuf[1][j]; ++j; } } /* polyphase filtering / mdct */ for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE; } } mdct_sub48(gfc, primebuff0, primebuff1); /* check FFT will not use a negative starting offset */ #if 576 < FFTOFFSET # error FFTOFFSET greater than 576: FFT uses a negative offset #endif /* check if we have enough data for FFT */ assert(gfc->sv_enc.mf_size >= (BLKSIZE + framesize - FFTOFFSET)); /* check if we have enough data for polyphase filterbank */ assert(gfc->sv_enc.mf_size >= (512 + framesize - 32)); } } /************************************************************************ * * encodeframe() Layer 3 * * encode a single frame * ************************************************************************ lame_encode_frame() gr 0 gr 1 inbuf: |--------------|--------------|--------------| Polyphase (18 windows, each shifted 32) gr 0: window1 <----512----> window18 <----512----> gr 1: window1 <----512----> window18 <----512----> MDCT output: |--------------|--------------|--------------| FFT's <---------1024----------> <---------1024--------> inbuf = buffer of PCM data size=MP3 framesize encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY so the MDCT coefficints are from inbuf[ch][-MDCTDELAY] psy-model FFT has a 1 granule delay, so we feed it data for the next granule. FFT is centered over granule: 224+576+224 So FFT starts at: 576-224-MDCTDELAY MPEG2: FFT ends at: BLKSIZE+576-224-MDCTDELAY (1328) MPEG1: FFT ends at: BLKSIZE+2*576-224-MDCTDELAY (1904) MPEG2: polyphase first window: [0..511] 18th window: [544..1055] (1056) MPEG1: 36th window: [1120..1631] (1632) data needed: 512+framesize-32 A close look newmdct.c shows that the polyphase filterbank only uses data from [0..510] for each window. Perhaps because the window used by the filterbank is zero for the last point, so Takehiro's code doesn't bother to compute with it. FFT starts at 576-224-MDCTDELAY (304) = 576-FFTOFFSET */ typedef FLOAT chgrdata[2][2]; int lame_encode_mp3_frame( /* Output */ lame_internal_flags * gfc, /* Context */ sample_t const *inbuf_l, /* Input */ sample_t const *inbuf_r, /* Input */ unsigned char *mp3buf, /* Output */ int mp3buf_size) { /* Output */ SessionConfig_t const *const cfg = &gfc->cfg; int mp3count; III_psy_ratio masking_LR[2][2]; /*LR masking & energy */ III_psy_ratio masking_MS[2][2]; /*MS masking & energy */ const III_psy_ratio (*masking)[2]; /*pointer to selected maskings */ const sample_t *inbuf[2]; FLOAT tot_ener[2][4]; FLOAT ms_ener_ratio[2] = { .5, .5 }; FLOAT pe[2][2] = { {0., 0.}, {0., 0.} }, pe_MS[2][2] = { { 0., 0.}, { 0., 0.}}; FLOAT (*pe_use)[2]; int ch, gr; inbuf[0] = inbuf_l; inbuf[1] = inbuf_r; if (gfc->lame_encode_frame_init == 0) { /*first run? */ lame_encode_frame_init(gfc, inbuf); } /********************** padding *****************************/ /* padding method as described in * "MPEG-Layer3 / Bitstream Syntax and Decoding" * by Martin Sieler, Ralph Sperschneider * * note: there is no padding for the very first frame * * Robert Hegemann 2000-06-22 */ gfc->ov_enc.padding = FALSE; if ((gfc->sv_enc.slot_lag -= gfc->sv_enc.frac_SpF) < 0) { gfc->sv_enc.slot_lag += cfg->samplerate_out; gfc->ov_enc.padding = TRUE; } /**************************************** * Stage 1: psychoacoustic model * ****************************************/ { /* psychoacoustic model * psy model has a 1 granule (576) delay that we must compensate for * (mt 6/99). */ int ret; const sample_t *bufp[2] = {0, 0}; /* address of beginning of left & right granule */ int blocktype[2]; for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET]; } ret = L3psycho_anal_vbr(gfc, bufp, gr, masking_LR, masking_MS, pe[gr], pe_MS[gr], tot_ener[gr], blocktype); if (ret != 0) return -4; if (cfg->mode == JOINT_STEREO) { ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3]; if (ms_ener_ratio[gr] > 0) ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr]; } /* block type flags */ for (ch = 0; ch < cfg->channels_out; ch++) { gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; cod_info->block_type = blocktype[ch]; cod_info->mixed_block_flag = 0; } } } /* auto-adjust of ATH, useful for low volume */ adjust_ATH(gfc); /**************************************** * Stage 2: MDCT * ****************************************/ /* polyphase filtering / mdct */ mdct_sub48(gfc, inbuf[0], inbuf[1]); /**************************************** * Stage 3: MS/LR decision * ****************************************/ /* Here will be selected MS or LR coding of the 2 stereo channels */ gfc->ov_enc.mode_ext = MPG_MD_LR_LR; if (cfg->force_ms) { gfc->ov_enc.mode_ext = MPG_MD_MS_LR; } else if (cfg->mode == JOINT_STEREO) { /* ms_ratio = is scaled, for historical reasons, to look like a ratio of side_channel / total. 0 = signal is 100% mono .5 = L & R uncorrelated */ /* [0] and [1] are the results for the two granules in MPEG-1, * in MPEG-2 it's only a faked averaging of the same value * _prev is the value of the last granule of the previous frame * _next is the value of the first granule of the next frame */ FLOAT sum_pe_MS = 0; FLOAT sum_pe_LR = 0; for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { sum_pe_MS += pe_MS[gr][ch]; sum_pe_LR += pe[gr][ch]; } } /* based on PE: M/S coding would not use much more bits than L/R */ if (sum_pe_MS <= 1.00 * sum_pe_LR) { gr_info const *const gi0 = &gfc->l3_side.tt[0][0]; gr_info const *const gi1 = &gfc->l3_side.tt[cfg->mode_gr - 1][0]; if (gi0[0].block_type == gi0[1].block_type && gi1[0].block_type == gi1[1].block_type) { gfc->ov_enc.mode_ext = MPG_MD_MS_LR; } } } /* bit and noise allocation */ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { masking = (const III_psy_ratio (*)[2])masking_MS; /* use MS masking */ pe_use = pe_MS; } else { masking = (const III_psy_ratio (*)[2])masking_LR; /* use LR masking */ pe_use = pe; } /* copy data for MP3 frame analyzer */ if (cfg->analysis && gfc->pinfo != NULL) { for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gfc->pinfo->ms_ratio[gr] = 0; gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr]; gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type; gfc->pinfo->pe[gr][ch] = pe_use[gr][ch]; memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr[0], sizeof(FLOAT) * 576); /* in psymodel, LR and MS data was stored in pinfo. switch to MS data: */ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2]; memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2], sizeof(gfc->pinfo->energy[gr][ch])); } } } } /**************************************** * Stage 4: quantization loop * ****************************************/ if (cfg->vbr == vbr_off || cfg->vbr == vbr_abr) { static FLOAT const fircoef[9] = { -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5, 7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5, 0.187098 * 5 }; int i; FLOAT f; for (i = 0; i < 18; i++) gfc->sv_enc.pefirbuf[i] = gfc->sv_enc.pefirbuf[i + 1]; f = 0.0; for (gr = 0; gr < cfg->mode_gr; gr++) for (ch = 0; ch < cfg->channels_out; ch++) f += pe_use[gr][ch]; gfc->sv_enc.pefirbuf[18] = f; f = gfc->sv_enc.pefirbuf[9]; for (i = 0; i < 9; i++) f += (gfc->sv_enc.pefirbuf[i] + gfc->sv_enc.pefirbuf[18 - i]) * fircoef[i]; f = (670 * 5 * cfg->mode_gr * cfg->channels_out) / f; for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { pe_use[gr][ch] *= f; } } } gfc->iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking); /**************************************** * Stage 5: bitstream formatting * ****************************************/ /* write the frame to the bitstream */ (void) format_bitstream(gfc); /* copy mp3 bit buffer into array */ mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1); if (cfg->write_lame_tag) { AddVbrFrame(gfc); } if (cfg->analysis && gfc->pinfo != NULL) { int framesize = 576 * cfg->mode_gr; for (ch = 0; ch < cfg->channels_out; ch++) { int j; for (j = 0; j < FFTOFFSET; j++) gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + framesize]; for (j = FFTOFFSET; j < 1600; j++) { gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET]; } } gfc->sv_qnt.masking_lower = 1.0; set_frame_pinfo(gfc, masking); } ++gfc->ov_enc.frame_number; updateStats(gfc); return mp3count; } ================================================ FILE: app/jni/libmp3lame/encoder.h ================================================ /* * encoder.h include file * * Copyright (c) 2000 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_ENCODER_H #define LAME_ENCODER_H /*********************************************************************** * * encoder and decoder delays * ***********************************************************************/ /* * layer III enc->dec delay: 1056 (1057?) (observed) * layer II enc->dec delay: 480 (481?) (observed) * * polyphase 256-16 (dec or enc) = 240 * mdct 256+32 (9*32) (dec or enc) = 288 * total: 512+16 * * My guess is that delay of polyphase filterbank is actualy 240.5 * (there are technical reasons for this, see postings in mp3encoder). * So total Encode+Decode delay = ENCDELAY + 528 + 1 */ /* * ENCDELAY The encoder delay. * * Minimum allowed is MDCTDELAY (see below) * * The first 96 samples will be attenuated, so using a value less than 96 * will result in corrupt data for the first 96-ENCDELAY samples. * * suggested: 576 * set to 1160 to sync with FhG. */ #define ENCDELAY 576 /* * make sure there is at least one complete frame after the * last frame containing real data * * Using a value of 288 would be sufficient for a * a very sophisticated decoder that can decode granule-by-granule instead * of frame by frame. But lets not assume this, and assume the decoder * will not decode frame N unless it also has data for frame N+1 * */ /*#define POSTDELAY 288*/ #define POSTDELAY 1152 /* * delay of the MDCT used in mdct.c * original ISO routines had a delay of 528! * Takehiro's routines: */ #define MDCTDELAY 48 #define FFTOFFSET (224+MDCTDELAY) /* * Most decoders, including the one we use, have a delay of 528 samples. */ #define DECDELAY 528 /* number of subbands */ #define SBLIMIT 32 /* parition bands bands */ #define CBANDS 64 /* number of critical bands/scale factor bands where masking is computed*/ #define SBPSY_l 21 #define SBPSY_s 12 /* total number of scalefactor bands encoded */ #define SBMAX_l 22 #define SBMAX_s 13 #define PSFB21 6 #define PSFB12 6 /* FFT sizes */ #define BLKSIZE 1024 #define HBLKSIZE (BLKSIZE/2 + 1) #define BLKSIZE_s 256 #define HBLKSIZE_s (BLKSIZE_s/2 + 1) /* #define switch_pe 1800 */ #define NORM_TYPE 0 #define START_TYPE 1 #define SHORT_TYPE 2 #define STOP_TYPE 3 /* * Mode Extention: * When we are in stereo mode, there are 4 possible methods to store these * two channels. The stereo modes -m? are using a subset of them. * * -ms: MPG_MD_LR_LR * -mj: MPG_MD_LR_LR and MPG_MD_MS_LR * -mf: MPG_MD_MS_LR * -mi: all */ #if 0 #define MPG_MD_LR_LR 0 #define MPG_MD_LR_I 1 #define MPG_MD_MS_LR 2 #define MPG_MD_MS_I 3 #endif enum MPEGChannelMode { MPG_MD_LR_LR = 0 , MPG_MD_LR_I = 1 , MPG_MD_MS_LR = 2 , MPG_MD_MS_I = 3 }; #ifndef lame_internal_flags_defined #define lame_internal_flags_defined struct lame_internal_flags; typedef struct lame_internal_flags lame_internal_flags; #endif int lame_encode_mp3_frame(lame_internal_flags * gfc, sample_t const *inbuf_l, sample_t const *inbuf_r, unsigned char *mp3buf, int mp3buf_size); #endif /* LAME_ENCODER_H */ ================================================ FILE: app/jni/libmp3lame/fft.c ================================================ /* ** FFT and FHT routines ** Copyright 1988, 1993; Ron Mayer ** Copyright (c) 1999-2000 Takehiro Tominaga ** ** fht(fz,n); ** Does a hartley transform of "n" points in the array "fz". ** ** NOTE: This routine uses at least 2 patented algorithms, and may be ** under the restrictions of a bunch of different organizations. ** Although I wrote it completely myself; it is kind of a derivative ** of a routine I once authored and released under the GPL, so it ** may fall under the free software foundation's restrictions; ** it was worked on as a Stanford Univ project, so they claim ** some rights to it; it was further optimized at work here, so ** I think this company claims parts of it. The patents are ** held by R. Bracewell (the FHT algorithm) and O. Buneman (the ** trig generator), both at Stanford Univ. ** If it were up to me, I'd say go do whatever you want with it; ** but it would be polite to give credit to the following people ** if you use this anywhere: ** Euler - probable inventor of the fourier transform. ** Gauss - probable inventor of the FFT. ** Hartley - probable inventor of the hartley transform. ** Buneman - for a really cool trig generator ** Mayer(me) - for authoring this particular version and ** including all the optimizations in one package. ** Thanks, ** Ron Mayer; mayer@acuson.com ** and added some optimization by ** Mather - idea of using lookup table ** Takehiro - some dirty hack for speed up */ /* $Id: fft.c,v 1.38 2009/04/20 21:48:00 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "fft.h" #include "vector/lame_intrin.h" #define TRI_SIZE (5-1) /* 1024 = 4**5 */ /* fft.c */ static FLOAT window[BLKSIZE], window_s[BLKSIZE_s / 2]; static const FLOAT costab[TRI_SIZE * 2] = { 9.238795325112867e-01, 3.826834323650898e-01, 9.951847266721969e-01, 9.801714032956060e-02, 9.996988186962042e-01, 2.454122852291229e-02, 9.999811752826011e-01, 6.135884649154475e-03 }; static void fht(FLOAT * fz, int n) { const FLOAT *tri = costab; int k4; FLOAT *fi, *gi; FLOAT const *fn; n <<= 1; /* to get BLKSIZE, because of 3DNow! ASM routine */ fn = fz + n; k4 = 4; do { FLOAT s1, c1; int i, k1, k2, k3, kx; kx = k4 >> 1; k1 = k4; k2 = k4 << 1; k3 = k2 + k1; k4 = k2 << 1; fi = fz; gi = fi + kx; do { FLOAT f0, f1, f2, f3; f1 = fi[0] - fi[k1]; f0 = fi[0] + fi[k1]; f3 = fi[k2] - fi[k3]; f2 = fi[k2] + fi[k3]; fi[k2] = f0 - f2; fi[0] = f0 + f2; fi[k3] = f1 - f3; fi[k1] = f1 + f3; f1 = gi[0] - gi[k1]; f0 = gi[0] + gi[k1]; f3 = SQRT2 * gi[k3]; f2 = SQRT2 * gi[k2]; gi[k2] = f0 - f2; gi[0] = f0 + f2; gi[k3] = f1 - f3; gi[k1] = f1 + f3; gi += k4; fi += k4; } while (fi < fn); c1 = tri[0]; s1 = tri[1]; for (i = 1; i < kx; i++) { FLOAT c2, s2; c2 = 1 - (2 * s1) * s1; s2 = (2 * s1) * c1; fi = fz + i; gi = fz + k1 - i; do { FLOAT a, b, g0, f0, f1, g1, f2, g2, f3, g3; b = s2 * fi[k1] - c2 * gi[k1]; a = c2 * fi[k1] + s2 * gi[k1]; f1 = fi[0] - a; f0 = fi[0] + a; g1 = gi[0] - b; g0 = gi[0] + b; b = s2 * fi[k3] - c2 * gi[k3]; a = c2 * fi[k3] + s2 * gi[k3]; f3 = fi[k2] - a; f2 = fi[k2] + a; g3 = gi[k2] - b; g2 = gi[k2] + b; b = s1 * f2 - c1 * g3; a = c1 * f2 + s1 * g3; fi[k2] = f0 - a; fi[0] = f0 + a; gi[k3] = g1 - b; gi[k1] = g1 + b; b = c1 * g2 - s1 * f3; a = s1 * g2 + c1 * f3; gi[k2] = g0 - a; gi[0] = g0 + a; fi[k3] = f1 - b; fi[k1] = f1 + b; gi += k4; fi += k4; } while (fi < fn); c2 = c1; c1 = c2 * tri[0] - s1 * tri[1]; s1 = c2 * tri[1] + s1 * tri[0]; } tri += 2; } while (k4 < n); } static const unsigned char rv_tbl[] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe }; #define ch01(index) (buffer[chn][index]) #define ml00(f) (window[i ] * f(i)) #define ml10(f) (window[i + 0x200] * f(i + 0x200)) #define ml20(f) (window[i + 0x100] * f(i + 0x100)) #define ml30(f) (window[i + 0x300] * f(i + 0x300)) #define ml01(f) (window[i + 0x001] * f(i + 0x001)) #define ml11(f) (window[i + 0x201] * f(i + 0x201)) #define ml21(f) (window[i + 0x101] * f(i + 0x101)) #define ml31(f) (window[i + 0x301] * f(i + 0x301)) #define ms00(f) (window_s[i ] * f(i + k)) #define ms10(f) (window_s[0x7f - i] * f(i + k + 0x80)) #define ms20(f) (window_s[i + 0x40] * f(i + k + 0x40)) #define ms30(f) (window_s[0x3f - i] * f(i + k + 0xc0)) #define ms01(f) (window_s[i + 0x01] * f(i + k + 0x01)) #define ms11(f) (window_s[0x7e - i] * f(i + k + 0x81)) #define ms21(f) (window_s[i + 0x41] * f(i + k + 0x41)) #define ms31(f) (window_s[0x3e - i] * f(i + k + 0xc1)) void fft_short(lame_internal_flags const *const gfc, FLOAT x_real[3][BLKSIZE_s], int chn, const sample_t *const buffer[2]) { int i; int j; int b; for (b = 0; b < 3; b++) { FLOAT *x = &x_real[b][BLKSIZE_s / 2]; short const k = (576 / 3) * (b + 1); j = BLKSIZE_s / 8 - 1; do { FLOAT f0, f1, f2, f3, w; i = rv_tbl[j << 2]; f0 = ms00(ch01); w = ms10(ch01); f1 = f0 - w; f0 = f0 + w; f2 = ms20(ch01); w = ms30(ch01); f3 = f2 - w; f2 = f2 + w; x -= 4; x[0] = f0 + f2; x[2] = f0 - f2; x[1] = f1 + f3; x[3] = f1 - f3; f0 = ms01(ch01); w = ms11(ch01); f1 = f0 - w; f0 = f0 + w; f2 = ms21(ch01); w = ms31(ch01); f3 = f2 - w; f2 = f2 + w; x[BLKSIZE_s / 2 + 0] = f0 + f2; x[BLKSIZE_s / 2 + 2] = f0 - f2; x[BLKSIZE_s / 2 + 1] = f1 + f3; x[BLKSIZE_s / 2 + 3] = f1 - f3; } while (--j >= 0); gfc->fft_fht(x, BLKSIZE_s / 2); /* BLKSIZE_s/2 because of 3DNow! ASM routine */ } } void fft_long(lame_internal_flags const *const gfc, FLOAT x[BLKSIZE], int chn, const sample_t *const buffer[2]) { int i; int jj = BLKSIZE / 8 - 1; x += BLKSIZE / 2; do { FLOAT f0, f1, f2, f3, w; i = rv_tbl[jj]; f0 = ml00(ch01); w = ml10(ch01); f1 = f0 - w; f0 = f0 + w; f2 = ml20(ch01); w = ml30(ch01); f3 = f2 - w; f2 = f2 + w; x -= 4; x[0] = f0 + f2; x[2] = f0 - f2; x[1] = f1 + f3; x[3] = f1 - f3; f0 = ml01(ch01); w = ml11(ch01); f1 = f0 - w; f0 = f0 + w; f2 = ml21(ch01); w = ml31(ch01); f3 = f2 - w; f2 = f2 + w; x[BLKSIZE / 2 + 0] = f0 + f2; x[BLKSIZE / 2 + 2] = f0 - f2; x[BLKSIZE / 2 + 1] = f1 + f3; x[BLKSIZE / 2 + 3] = f1 - f3; } while (--jj >= 0); gfc->fft_fht(x, BLKSIZE / 2); /* BLKSIZE/2 because of 3DNow! ASM routine */ } #ifdef HAVE_NASM extern void fht_3DN(FLOAT * fz, int n); extern void fht_SSE(FLOAT * fz, int n); #endif void init_fft(lame_internal_flags * const gfc) { int i; /* The type of window used here will make no real difference, but */ /* in the interest of merging nspsytune stuff - switch to blackman window */ for (i = 0; i < BLKSIZE; i++) /* blackman window */ window[i] = 0.42 - 0.5 * cos(2 * PI * (i + .5) / BLKSIZE) + 0.08 * cos(4 * PI * (i + .5) / BLKSIZE); for (i = 0; i < BLKSIZE_s / 2; i++) window_s[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE_s)); gfc->fft_fht = fht; #ifdef HAVE_NASM if (gfc->CPU_features.AMD_3DNow) { gfc->fft_fht = fht_3DN; } else if (gfc->CPU_features.SSE) { gfc->fft_fht = fht_SSE; } else { gfc->fft_fht = fht; } #else #ifdef HAVE_XMMINTRIN_H #ifdef MIN_ARCH_SSE gfc->fft_fht = fht_SSE2; #endif #endif #endif } ================================================ FILE: app/jni/libmp3lame/fft.h ================================================ /* * Fast Fourier Transform include file * * Copyright (c) 2000 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_FFT_H #define LAME_FFT_H void fft_long(lame_internal_flags const *const gfc, FLOAT x_real[BLKSIZE], int chn, const sample_t *const data[2]); void fft_short(lame_internal_flags const *const gfc, FLOAT x_real[3][BLKSIZE_s], int chn, const sample_t *const data[2]); void init_fft(lame_internal_flags * const gfc); #endif /* End of fft.h */ ================================================ FILE: app/jni/libmp3lame/gain_analysis.c ================================================ /* * ReplayGainAnalysis - analyzes input samples and give the recommended dB change * Copyright (C) 2001 David Robinson and Glen Sawyer * Improvements and optimizations added by Frank Klemm, and by Marcel Muller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * concept and filter values by David Robinson (David@Robinson.org) * -- blame him if you think the idea is flawed * original coding by Glen Sawyer (mp3gain@hotmail.com) * -- blame him if you think this runs too slowly, or the coding is otherwise flawed * * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) * -- credit him for all the _good_ programming ;) * * * For an explanation of the concepts and the basic algorithms involved, go to: * http://www.replaygain.org/ */ /* * Here's the deal. Call * * InitGainAnalysis ( long samplefreq ); * * to initialize everything. Call * * AnalyzeSamples ( const Float_t* left_samples, * const Float_t* right_samples, * size_t num_samples, * int num_channels ); * * as many times as you want, with as many or as few samples as you want. * If mono, pass the sample buffer in through left_samples, leave * right_samples NULL, and make sure num_channels = 1. * * GetTitleGain() * * will return the recommended dB level change for all samples analyzed * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). * * GetAlbumGain() * * will return the recommended dB level change for all samples analyzed * since InitGainAnalysis() was called and finalized with GetTitleGain(). * * Pseudo-code to process an album: * * Float_t l_samples [4096]; * Float_t r_samples [4096]; * size_t num_samples; * unsigned int num_songs; * unsigned int i; * * InitGainAnalysis ( 44100 ); * for ( i = 1; i <= num_songs; i++ ) { * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); * fprintf ("Recommended dB change for song %2d: %+6.2f dB\n", i, GetTitleGain() ); * } * fprintf ("Recommended dB change for whole album: %+6.2f dB\n", GetAlbumGain() ); */ /* * So here's the main source of potential code confusion: * * The filters applied to the incoming samples are IIR filters, * meaning they rely on up to number of previous samples * AND up to number of previous filtered samples. * * I set up the AnalyzeSamples routine to minimize memory usage and interface * complexity. The speed isn't compromised too much (I don't think), but the * internal complexity is higher than it should be for such a relatively * simple routine. * * Optimization/clarity suggestions are welcome. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "lame.h" #include "machine.h" #include "gain_analysis.h" /* for each filter: */ /* [0] 48 kHz, [1] 44.1 kHz, [2] 32 kHz, [3] 24 kHz, [4] 22050 Hz, [5] 16 kHz, [6] 12 kHz, [7] is 11025 Hz, [8] 8 kHz */ #ifdef WIN32 #pragma warning ( disable : 4305 ) #endif /*lint -save -e736 loss of precision */ static const Float_t ABYule[9][2 * YULE_ORDER + 1] = { {0.03857599435200, -3.84664617118067, -0.02160367184185, 7.81501653005538, -0.00123395316851, -11.34170355132042, -0.00009291677959, 13.05504219327545, -0.01655260341619, -12.28759895145294, 0.02161526843274, 9.48293806319790, -0.02074045215285, -5.87257861775999, 0.00594298065125, 2.75465861874613, 0.00306428023191, -0.86984376593551, 0.00012025322027, 0.13919314567432, 0.00288463683916}, {0.05418656406430, -3.47845948550071, -0.02911007808948, 6.36317777566148, -0.00848709379851, -8.54751527471874, -0.00851165645469, 9.47693607801280, -0.00834990904936, -8.81498681370155, 0.02245293253339, 6.85401540936998, -0.02596338512915, -4.39470996079559, 0.01624864962975, 2.19611684890774, -0.00240879051584, -0.75104302451432, 0.00674613682247, 0.13149317958808, -0.00187763777362}, {0.15457299681924, -2.37898834973084, -0.09331049056315, 2.84868151156327, -0.06247880153653, -2.64577170229825, 0.02163541888798, 2.23697657451713, -0.05588393329856, -1.67148153367602, 0.04781476674921, 1.00595954808547, 0.00222312597743, -0.45953458054983, 0.03174092540049, 0.16378164858596, -0.01390589421898, -0.05032077717131, 0.00651420667831, 0.02347897407020, -0.00881362733839}, {0.30296907319327, -1.61273165137247, -0.22613988682123, 1.07977492259970, -0.08587323730772, -0.25656257754070, 0.03282930172664, -0.16276719120440, -0.00915702933434, -0.22638893773906, -0.02364141202522, 0.39120800788284, -0.00584456039913, -0.22138138954925, 0.06276101321749, 0.04500235387352, -0.00000828086748, 0.02005851806501, 0.00205861885564, 0.00302439095741, -0.02950134983287}, {0.33642304856132, -1.49858979367799, -0.25572241425570, 0.87350271418188, -0.11828570177555, 0.12205022308084, 0.11921148675203, -0.80774944671438, -0.07834489609479, 0.47854794562326, -0.00469977914380, -0.12453458140019, -0.00589500224440, -0.04067510197014, 0.05724228140351, 0.08333755284107, 0.00832043980773, -0.04237348025746, -0.01635381384540, 0.02977207319925, -0.01760176568150}, {0.44915256608450, -0.62820619233671, -0.14351757464547, 0.29661783706366, -0.22784394429749, -0.37256372942400, -0.01419140100551, 0.00213767857124, 0.04078262797139, -0.42029820170918, -0.12398163381748, 0.22199650564824, 0.04097565135648, 0.00613424350682, 0.10478503600251, 0.06747620744683, -0.01863887810927, 0.05784820375801, -0.03193428438915, 0.03222754072173, 0.00541907748707}, {0.56619470757641, -1.04800335126349, -0.75464456939302, 0.29156311971249, 0.16242137742230, -0.26806001042947, 0.16744243493672, 0.00819999645858, -0.18901604199609, 0.45054734505008, 0.30931782841830, -0.33032403314006, -0.27562961986224, 0.06739368333110, 0.00647310677246, -0.04784254229033, 0.08647503780351, 0.01639907836189, -0.03788984554840, 0.01807364323573, -0.00588215443421}, {0.58100494960553, -0.51035327095184, -0.53174909058578, -0.31863563325245, -0.14289799034253, -0.20256413484477, 0.17520704835522, 0.14728154134330, 0.02377945217615, 0.38952639978999, 0.15558449135573, -0.23313271880868, -0.25344790059353, -0.05246019024463, 0.01628462406333, -0.02505961724053, 0.06920467763959, 0.02442357316099, -0.03721611395801, 0.01818801111503, -0.00749618797172}, {0.53648789255105, -0.25049871956020, -0.42163034350696, -0.43193942311114, -0.00275953611929, -0.03424681017675, 0.04267842219415, -0.04678328784242, -0.10214864179676, 0.26408300200955, 0.14590772289388, 0.15113130533216, -0.02459864859345, -0.17556493366449, -0.11202315195388, -0.18823009262115, -0.04060034127000, 0.05477720428674, 0.04788665548180, 0.04704409688120, -0.02217936801134} }; static const Float_t ABButter[9][2 * BUTTER_ORDER + 1] = { {0.98621192462708, -1.97223372919527, -1.97242384925416, 0.97261396931306, 0.98621192462708}, {0.98500175787242, -1.96977855582618, -1.97000351574484, 0.97022847566350, 0.98500175787242}, {0.97938932735214, -1.95835380975398, -1.95877865470428, 0.95920349965459, 0.97938932735214}, {0.97531843204928, -1.95002759149878, -1.95063686409857, 0.95124613669835, 0.97531843204928}, {0.97316523498161, -1.94561023566527, -1.94633046996323, 0.94705070426118, 0.97316523498161}, {0.96454515552826, -1.92783286977036, -1.92909031105652, 0.93034775234268, 0.96454515552826}, {0.96009142950541, -1.91858953033784, -1.92018285901082, 0.92177618768381, 0.96009142950541}, {0.95856916599601, -1.91542108074780, -1.91713833199203, 0.91885558323625, 0.95856916599601}, {0.94597685600279, -1.88903307939452, -1.89195371200558, 0.89487434461664, 0.94597685600279} }; /*lint -restore */ #ifdef WIN32 #pragma warning ( default : 4305 ) #endif /* When calling this procedure, make sure that ip[-order] and op[-order] point to real data! */ static void filterYule(const Float_t * input, Float_t * output, size_t nSamples, const Float_t * const kernel) { /*register double y; */ while (nSamples--) { *output = 1e-10 /* 1e-10 is a hack to avoid slowdown because of denormals */ + input[0] * kernel[0] - output[-1] * kernel[1] + input[-1] * kernel[2] - output[-2] * kernel[3] + input[-2] * kernel[4] - output[-3] * kernel[5] + input[-3] * kernel[6] - output[-4] * kernel[7] + input[-4] * kernel[8] - output[-5] * kernel[9] + input[-5] * kernel[10] - output[-6] * kernel[11] + input[-6] * kernel[12] - output[-7] * kernel[13] + input[-7] * kernel[14] - output[-8] * kernel[15] + input[-8] * kernel[16] - output[-9] * kernel[17] + input[-9] * kernel[18] - output[-10] * kernel[19] + input[-10] * kernel[20]; ++output; ++input; /* *output++ = (Float_t)y; */ } } static void filterButter(const Float_t * input, Float_t * output, size_t nSamples, const Float_t * const kernel) { /*register double y; */ while (nSamples--) { *output = input[0] * kernel[0] - output[-1] * kernel[1] + input[-1] * kernel[2] - output[-2] * kernel[3] + input[-2] * kernel[4]; ++output; ++input; /* *output++ = (Float_t)y; */ } } static int ResetSampleFrequency(replaygain_t * rgData, long samplefreq); /* returns a INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if not */ int ResetSampleFrequency(replaygain_t * rgData, long samplefreq) { int i; /* zero out initial values */ for (i = 0; i < MAX_ORDER; i++) rgData->linprebuf[i] = rgData->lstepbuf[i] = rgData->loutbuf[i] = rgData->rinprebuf[i] = rgData->rstepbuf[i] = rgData->routbuf[i] = 0.; switch ((int) (samplefreq)) { case 48000: rgData->freqindex = 0; break; case 44100: rgData->freqindex = 1; break; case 32000: rgData->freqindex = 2; break; case 24000: rgData->freqindex = 3; break; case 22050: rgData->freqindex = 4; break; case 16000: rgData->freqindex = 5; break; case 12000: rgData->freqindex = 6; break; case 11025: rgData->freqindex = 7; break; case 8000: rgData->freqindex = 8; break; default: return INIT_GAIN_ANALYSIS_ERROR; } rgData->sampleWindow = (samplefreq * RMS_WINDOW_TIME_NUMERATOR + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR; rgData->lsum = 0.; rgData->rsum = 0.; rgData->totsamp = 0; memset(rgData->A, 0, sizeof(rgData->A)); return INIT_GAIN_ANALYSIS_OK; } int InitGainAnalysis(replaygain_t * rgData, long samplefreq) { if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { return INIT_GAIN_ANALYSIS_ERROR; } rgData->linpre = rgData->linprebuf + MAX_ORDER; rgData->rinpre = rgData->rinprebuf + MAX_ORDER; rgData->lstep = rgData->lstepbuf + MAX_ORDER; rgData->rstep = rgData->rstepbuf + MAX_ORDER; rgData->lout = rgData->loutbuf + MAX_ORDER; rgData->rout = rgData->routbuf + MAX_ORDER; memset(rgData->B, 0, sizeof(rgData->B)); return INIT_GAIN_ANALYSIS_OK; } /* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */ static inline double fsqr(const double d) { return d * d; } int AnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples, const Float_t * right_samples, size_t num_samples, int num_channels) { const Float_t *curleft; const Float_t *curright; long batchsamples; long cursamples; long cursamplepos; int i; if (num_samples == 0) return GAIN_ANALYSIS_OK; cursamplepos = 0; batchsamples = (long) num_samples; switch (num_channels) { case 1: right_samples = left_samples; break; case 2: break; default: return GAIN_ANALYSIS_ERROR; } if (num_samples < MAX_ORDER) { memcpy(rgData->linprebuf + MAX_ORDER, left_samples, num_samples * sizeof(Float_t)); memcpy(rgData->rinprebuf + MAX_ORDER, right_samples, num_samples * sizeof(Float_t)); } else { memcpy(rgData->linprebuf + MAX_ORDER, left_samples, MAX_ORDER * sizeof(Float_t)); memcpy(rgData->rinprebuf + MAX_ORDER, right_samples, MAX_ORDER * sizeof(Float_t)); } while (batchsamples > 0) { cursamples = batchsamples > rgData->sampleWindow - rgData->totsamp ? rgData->sampleWindow - rgData->totsamp : batchsamples; if (cursamplepos < MAX_ORDER) { curleft = rgData->linpre + cursamplepos; curright = rgData->rinpre + cursamplepos; if (cursamples > MAX_ORDER - cursamplepos) cursamples = MAX_ORDER - cursamplepos; } else { curleft = left_samples + cursamplepos; curright = right_samples + cursamplepos; } YULE_FILTER(curleft, rgData->lstep + rgData->totsamp, cursamples, ABYule[rgData->freqindex]); YULE_FILTER(curright, rgData->rstep + rgData->totsamp, cursamples, ABYule[rgData->freqindex]); BUTTER_FILTER(rgData->lstep + rgData->totsamp, rgData->lout + rgData->totsamp, cursamples, ABButter[rgData->freqindex]); BUTTER_FILTER(rgData->rstep + rgData->totsamp, rgData->rout + rgData->totsamp, cursamples, ABButter[rgData->freqindex]); curleft = rgData->lout + rgData->totsamp; /* Get the squared values */ curright = rgData->rout + rgData->totsamp; i = cursamples % 8; while (i--) { rgData->lsum += fsqr(*curleft++); rgData->rsum += fsqr(*curright++); } i = cursamples / 8; while (i--) { rgData->lsum += fsqr(curleft[0]) + fsqr(curleft[1]) + fsqr(curleft[2]) + fsqr(curleft[3]) + fsqr(curleft[4]) + fsqr(curleft[5]) + fsqr(curleft[6]) + fsqr(curleft[7]); curleft += 8; rgData->rsum += fsqr(curright[0]) + fsqr(curright[1]) + fsqr(curright[2]) + fsqr(curright[3]) + fsqr(curright[4]) + fsqr(curright[5]) + fsqr(curright[6]) + fsqr(curright[7]); curright += 8; } batchsamples -= cursamples; cursamplepos += cursamples; rgData->totsamp += cursamples; if (rgData->totsamp == rgData->sampleWindow) { /* Get the Root Mean Square (RMS) for this set of samples */ double const val = STEPS_per_dB * 10. * log10((rgData->lsum + rgData->rsum) / rgData->totsamp * 0.5 + 1.e-37); size_t ival = (val <= 0) ? 0 : (size_t) val; if (ival >= sizeof(rgData->A) / sizeof(*(rgData->A))) ival = sizeof(rgData->A) / sizeof(*(rgData->A)) - 1; rgData->A[ival]++; rgData->lsum = rgData->rsum = 0.; memmove(rgData->loutbuf, rgData->loutbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t)); memmove(rgData->routbuf, rgData->routbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t)); memmove(rgData->lstepbuf, rgData->lstepbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t)); memmove(rgData->rstepbuf, rgData->rstepbuf + rgData->totsamp, MAX_ORDER * sizeof(Float_t)); rgData->totsamp = 0; } if (rgData->totsamp > rgData->sampleWindow) /* somehow I really screwed up: Error in programming! Contact author about totsamp > sampleWindow */ return GAIN_ANALYSIS_ERROR; } if (num_samples < MAX_ORDER) { memmove(rgData->linprebuf, rgData->linprebuf + num_samples, (MAX_ORDER - num_samples) * sizeof(Float_t)); memmove(rgData->rinprebuf, rgData->rinprebuf + num_samples, (MAX_ORDER - num_samples) * sizeof(Float_t)); memcpy(rgData->linprebuf + MAX_ORDER - num_samples, left_samples, num_samples * sizeof(Float_t)); memcpy(rgData->rinprebuf + MAX_ORDER - num_samples, right_samples, num_samples * sizeof(Float_t)); } else { memcpy(rgData->linprebuf, left_samples + num_samples - MAX_ORDER, MAX_ORDER * sizeof(Float_t)); memcpy(rgData->rinprebuf, right_samples + num_samples - MAX_ORDER, MAX_ORDER * sizeof(Float_t)); } return GAIN_ANALYSIS_OK; } static Float_t analyzeResult(uint32_t const *Array, size_t len) { uint32_t elems; uint32_t upper; uint32_t sum; size_t i; elems = 0; for (i = 0; i < len; i++) elems += Array[i]; if (elems == 0) return GAIN_NOT_ENOUGH_SAMPLES; upper = (uint32_t) ceil(elems * (1. - RMS_PERCENTILE)); sum = 0; for (i = len; i-- > 0;) { sum += Array[i]; if (sum >= upper) { break; } } return (Float_t) ((Float_t) PINK_REF - (Float_t) i / (Float_t) STEPS_per_dB); } Float_t GetTitleGain(replaygain_t * rgData) { Float_t retval; unsigned int i; retval = analyzeResult(rgData->A, sizeof(rgData->A) / sizeof(*(rgData->A))); for (i = 0; i < sizeof(rgData->A) / sizeof(*(rgData->A)); i++) { rgData->B[i] += rgData->A[i]; rgData->A[i] = 0; } for (i = 0; i < MAX_ORDER; i++) rgData->linprebuf[i] = rgData->lstepbuf[i] = rgData->loutbuf[i] = rgData->rinprebuf[i] = rgData->rstepbuf[i] = rgData->routbuf[i] = 0.f; rgData->totsamp = 0; rgData->lsum = rgData->rsum = 0.; return retval; } #if 0 static Float_t GetAlbumGain(replaygain_t const* rgData); Float_t GetAlbumGain(replaygain_t const* rgData) { return analyzeResult(rgData->B, sizeof(rgData->B) / sizeof(*(rgData->B))); } #endif /* end of gain_analysis.c */ ================================================ FILE: app/jni/libmp3lame/gain_analysis.h ================================================ /* * ReplayGainAnalysis - analyzes input samples and give the recommended dB change * Copyright (C) 2001 David Robinson and Glen Sawyer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * concept and filter values by David Robinson (David@Robinson.org) * -- blame him if you think the idea is flawed * coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA * -- blame him if you think this runs too slowly, or the coding is otherwise flawed * * For an explanation of the concepts and the basic algorithms involved, go to: * http://www.replaygain.org/ */ #ifndef GAIN_ANALYSIS_H #define GAIN_ANALYSIS_H #ifdef HAVE_INTTYPES_H # include #else # ifdef HAVE_STDINT_H # include # endif #endif #ifdef __cplusplus extern "C" { #endif typedef sample_t Float_t; /* Type used for filtering */ #define PINK_REF 64.82 /* 298640883795 */ /* calibration value for 89dB */ #define YULE_ORDER 10 #define BUTTER_ORDER 2 #define YULE_FILTER filterYule #define BUTTER_FILTER filterButter #define RMS_PERCENTILE 0.95 /* percentile which is louder than the proposed level */ #define MAX_SAMP_FREQ 48000L /* maximum allowed sample frequency [Hz] */ #define RMS_WINDOW_TIME_NUMERATOR 1L #define RMS_WINDOW_TIME_DENOMINATOR 20L /* numerator / denominator = time slice size [s] */ #define STEPS_per_dB 100 /* Table entries per dB */ #define MAX_dB 120 /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */ enum { GAIN_NOT_ENOUGH_SAMPLES = -24601, GAIN_ANALYSIS_ERROR = 0, GAIN_ANALYSIS_OK = 1, INIT_GAIN_ANALYSIS_ERROR = 0, INIT_GAIN_ANALYSIS_OK = 1 }; enum { MAX_ORDER = (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER) , MAX_SAMPLES_PER_WINDOW = ((MAX_SAMP_FREQ * RMS_WINDOW_TIME_NUMERATOR) / RMS_WINDOW_TIME_DENOMINATOR + 1) /* max. Samples per Time slice */ }; struct replaygain_data { Float_t linprebuf[MAX_ORDER * 2]; Float_t *linpre; /* left input samples, with pre-buffer */ Float_t lstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; Float_t *lstep; /* left "first step" (i.e. post first filter) samples */ Float_t loutbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; Float_t *lout; /* left "out" (i.e. post second filter) samples */ Float_t rinprebuf[MAX_ORDER * 2]; Float_t *rinpre; /* right input samples ... */ Float_t rstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; Float_t *rstep; Float_t routbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; Float_t *rout; long sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */ long totsamp; double lsum; double rsum; int freqindex; int first; uint32_t A[STEPS_per_dB * MAX_dB]; uint32_t B[STEPS_per_dB * MAX_dB]; }; #ifndef replaygain_data_defined #define replaygain_data_defined typedef struct replaygain_data replaygain_t; #endif int InitGainAnalysis(replaygain_t * rgData, long samplefreq); int AnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples, const Float_t * right_samples, size_t num_samples, int num_channels); Float_t GetTitleGain(replaygain_t * rgData); #ifdef __cplusplus } #endif #endif /* GAIN_ANALYSIS_H */ ================================================ FILE: app/jni/libmp3lame/id3tag.c ================================================ /* * id3tag.c -- Write ID3 version 1 and 2 tags. * * Copyright (C) 2000 Don Melton * Copyright (C) 2011-2012 Robert Hegemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * HISTORY: This source file is part of LAME (see http://www.mp3dev.org) * and was originally adapted by Conrad Sanderson * from mp3info by Ricardo Cerqueira to write only ID3 version 1 * tags. Don Melton COMPLETELY rewrote it to support version * 2 tags and be more conformant to other standards while remaining flexible. * * NOTE: See http://id3.org/ for more information about ID3 tag formats. */ /* $Id: id3tag.c,v 1.75.2.2 2012/01/08 23:49:58 robert Exp $ */ #ifdef HAVE_CONFIG_H #include #endif #ifdef STDC_HEADERS # include # include # include # include #else # ifndef HAVE_STRCHR # define strchr index # define strrchr rindex # endif char *strchr(), *strrchr(); # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # endif #endif #include #include #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "id3tag.h" #include "lame_global_flags.h" #include "util.h" #include "bitstream.h" #define lame_calloc(TYPE, COUNT) ((TYPE*)calloc(COUNT, sizeof(TYPE))) static const char *const genre_names[] = { /* * NOTE: The spelling of these genre names is identical to those found in * Winamp and mp3info. */ "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alternative Rock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native US", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Cappella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "SynthPop" }; #define GENRE_NAME_COUNT \ ((int)(sizeof genre_names / sizeof (const char *const))) static const int genre_alpha_map[] = { 123, 34, 74, 73, 99, 20, 40, 26, 145, 90, 116, 41, 135, 85, 96, 138, 89, 0, 107, 132, 65, 88, 104, 102, 97, 136, 61, 141, 32, 1, 112, 128, 57, 140, 2, 139, 58, 3, 125, 50, 22, 4, 55, 127, 122, 120, 98, 52, 48, 54, 124, 25, 84, 80, 115, 81, 119, 5, 30, 36, 59, 126, 38, 49, 91, 6, 129, 79, 137, 7, 35, 100, 131, 19, 33, 46, 47, 8, 29, 146, 63, 86, 71, 45, 142, 9, 77, 82, 64, 133, 10, 66, 39, 11, 103, 12, 75, 134, 13, 53, 62, 109, 117, 23, 108, 92, 67, 93, 43, 121, 15, 68, 14, 16, 76, 87, 118, 17, 78, 143, 114, 110, 69, 21, 111, 95, 105, 42, 37, 24, 56, 44, 101, 83, 94, 106, 147, 113, 18, 51, 130, 144, 60, 70, 31, 72, 27, 28 }; #define GENRE_ALPHA_COUNT ((int)(sizeof genre_alpha_map / sizeof (int))) #define GENRE_INDEX_OTHER 12 #define FRAME_ID(a, b, c, d) \ ( ((unsigned long)(a) << 24) \ | ((unsigned long)(b) << 16) \ | ((unsigned long)(c) << 8) \ | ((unsigned long)(d) << 0) ) typedef enum UsualStringIDs { ID_TITLE = FRAME_ID('T', 'I', 'T', '2') , ID_ARTIST = FRAME_ID('T', 'P', 'E', '1') , ID_ALBUM = FRAME_ID('T', 'A', 'L', 'B') , ID_GENRE = FRAME_ID('T', 'C', 'O', 'N') , ID_ENCODER = FRAME_ID('T', 'S', 'S', 'E') , ID_PLAYLENGTH = FRAME_ID('T', 'L', 'E', 'N') , ID_COMMENT = FRAME_ID('C', 'O', 'M', 'M') /* full text string */ } UsualStringIDs; typedef enum NumericStringIDs { ID_DATE = FRAME_ID('T', 'D', 'A', 'T') /* "ddMM" */ , ID_TIME = FRAME_ID('T', 'I', 'M', 'E') /* "hhmm" */ , ID_TPOS = FRAME_ID('T', 'P', 'O', 'S') /* '0'-'9' and '/' allowed */ , ID_TRACK = FRAME_ID('T', 'R', 'C', 'K') /* '0'-'9' and '/' allowed */ , ID_YEAR = FRAME_ID('T', 'Y', 'E', 'R') /* "yyyy" */ } NumericStringIDs; typedef enum MiscIDs { ID_TXXX = FRAME_ID('T', 'X', 'X', 'X') , ID_WXXX = FRAME_ID('W', 'X', 'X', 'X') , ID_SYLT = FRAME_ID('S', 'Y', 'L', 'T') , ID_APIC = FRAME_ID('A', 'P', 'I', 'C') , ID_GEOB = FRAME_ID('G', 'E', 'O', 'B') , ID_PCNT = FRAME_ID('P', 'C', 'N', 'T') , ID_AENC = FRAME_ID('A', 'E', 'N', 'C') , ID_LINK = FRAME_ID('L', 'I', 'N', 'K') , ID_ENCR = FRAME_ID('E', 'N', 'C', 'R') , ID_GRID = FRAME_ID('G', 'R', 'I', 'D') , ID_PRIV = FRAME_ID('P', 'R', 'I', 'V') , ID_VSLT = FRAME_ID('V', 'S', 'L', 'T') /* full text string */ , ID_USER = FRAME_ID('U', 'S', 'E', 'R') /* full text string */ , ID_PCST = FRAME_ID('P', 'C', 'S', 'T') /* iTunes Podcast indicator, only presence important */ , ID_WFED = FRAME_ID('W', 'F', 'E', 'D') /* iTunes Podcast URL as TEXT FRAME !!! violates standard */ } MiscIDs; static int frame_id_matches(int id, int mask) { int result = 0, i, window = 0xff; for (i = 0; i < 4; ++i, window <<= 8) { int const mw = (mask & window); int const iw = (id & window); if (mw != 0 && mw != iw) { result |= iw; } } return result; } static int isFrameIdMatching(int id, int mask) { return frame_id_matches(id, mask) == 0 ? 1 : 0; } static int test_tag_spec_flags(lame_internal_flags const *gfc, unsigned int tst) { return (gfc->tag_spec.flags & tst) != 0u ? 1 : 0; } #if 0 static void debug_tag_spec_flags(lame_internal_flags * gfc, const char* info) { MSGF(gfc, "%s\n", info); MSGF(gfc, "CHANGED_FLAG : %d\n", test_tag_spec_flags(gfc, CHANGED_FLAG )); MSGF(gfc, "ADD_V2_FLAG : %d\n", test_tag_spec_flags(gfc, ADD_V2_FLAG )); MSGF(gfc, "V1_ONLY_FLAG : %d\n", test_tag_spec_flags(gfc, V1_ONLY_FLAG )); MSGF(gfc, "V2_ONLY_FLAG : %d\n", test_tag_spec_flags(gfc, V2_ONLY_FLAG )); MSGF(gfc, "SPACE_V1_FLAG : %d\n", test_tag_spec_flags(gfc, SPACE_V1_FLAG)); MSGF(gfc, "PAD_V2_FLAG : %d\n", test_tag_spec_flags(gfc, PAD_V2_FLAG )); } #endif static int id3v2_add_ucs2(lame_t gfp, uint32_t frame_id, char const *lang, unsigned short const *desc, unsigned short const *text); static int id3v2_add_latin1(lame_t gfp, uint32_t frame_id, char const *lang, char const *desc, char const *text); static void copyV1ToV2(lame_t gfp, int frame_id, char const *s) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc != 0) { unsigned int flags = gfc->tag_spec.flags; id3v2_add_latin1(gfp, frame_id, "XXX", 0, s); gfc->tag_spec.flags = flags; #if 0 debug_tag_spec_flags(gfc, "copyV1ToV2"); #endif } } static void id3v2AddLameVersion(lame_t gfp) { char buffer[1024]; const char *b = get_lame_os_bitness(); const char *v = get_lame_version(); const char *u = get_lame_url(); const size_t lenb = strlen(b); if (lenb > 0) { sprintf(buffer, "LAME %s version %s (%s)", b, v, u); } else { sprintf(buffer, "LAME version %s (%s)", v, u); } copyV1ToV2(gfp, ID_ENCODER, buffer); } static void id3v2AddAudioDuration(lame_t gfp, double ms) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; SessionConfig_t const *const cfg = &gfc->cfg; char buffer[1024]; double const max_ulong = MAX_U_32_NUM; unsigned long playlength_ms; ms *= 1000; ms /= cfg->samplerate_in; if (ms > max_ulong) { playlength_ms = max_ulong; } else if (ms < 0) { playlength_ms = 0; } else { playlength_ms = ms; } sprintf(buffer, "%lu", playlength_ms); copyV1ToV2(gfp, ID_PLAYLENGTH, buffer); } void id3tag_genre_list(void (*handler) (int, const char *, void *), void *cookie) { if (handler) { int i; for (i = 0; i < GENRE_NAME_COUNT; ++i) { if (i < GENRE_ALPHA_COUNT) { int j = genre_alpha_map[i]; handler(j, genre_names[j], cookie); } } } } #define GENRE_NUM_UNKNOWN 255 void id3tag_init(lame_t gfp) { lame_internal_flags *gfc = gfp->internal_flags; free_id3tag(gfc); memset(&gfc->tag_spec, 0, sizeof gfc->tag_spec); gfc->tag_spec.genre_id3v1 = GENRE_NUM_UNKNOWN; gfc->tag_spec.padding_size = 128; id3v2AddLameVersion(gfp); } void id3tag_add_v2(lame_t gfp) { lame_internal_flags *gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V1_ONLY_FLAG; gfc->tag_spec.flags |= ADD_V2_FLAG; } void id3tag_v1_only(lame_t gfp) { lame_internal_flags *gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG); gfc->tag_spec.flags |= V1_ONLY_FLAG; } void id3tag_v2_only(lame_t gfp) { lame_internal_flags *gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V1_ONLY_FLAG; gfc->tag_spec.flags |= V2_ONLY_FLAG; } void id3tag_space_v1(lame_t gfp) { lame_internal_flags *gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V2_ONLY_FLAG; gfc->tag_spec.flags |= SPACE_V1_FLAG; } void id3tag_pad_v2(lame_t gfp) { id3tag_set_pad(gfp, 128); } void id3tag_set_pad(lame_t gfp, size_t n) { lame_internal_flags *gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V1_ONLY_FLAG; gfc->tag_spec.flags |= PAD_V2_FLAG; gfc->tag_spec.flags |= ADD_V2_FLAG; gfc->tag_spec.padding_size = (unsigned int)n; } static int hasUcs2ByteOrderMarker(unsigned short bom) { if (bom == 0xFFFEu || bom == 0xFEFFu) { return 1; } return 0; } static unsigned short swap_bytes(unsigned short w) { return (0xff00u & (w << 8)) | (0x00ffu & (w >> 8)); } static unsigned short toLittleEndian(unsigned short bom, unsigned short c) { if (bom == 0xFFFEu) { return swap_bytes(c); } return c; } static unsigned short fromLatin1Char(const unsigned short* s, unsigned short c) { if (s[0] == 0xFFFEu) { return swap_bytes(c); } return c; } static size_t local_strdup(char **dst, const char *src) { if (dst == 0) { return 0; } free(*dst); *dst = 0; if (src != 0) { size_t n; for (n = 0; src[n] != 0; ++n) { /* calc src string length */ } if (n > 0) { /* string length without zero termination */ assert(sizeof(*src) == sizeof(**dst)); *dst = lame_calloc(char, n + 1); if (*dst != 0) { memcpy(*dst, src, n * sizeof(**dst)); (*dst)[n] = 0; return n; } } } return 0; } static size_t local_ucs2_strdup(unsigned short **dst, unsigned short const *src) { if (dst == 0) { return 0; } free(*dst); /* free old string pointer */ *dst = 0; if (src != 0) { size_t n; for (n = 0; src[n] != 0; ++n) { /* calc src string length */ } if (n > 0) { /* string length without zero termination */ assert(sizeof(*src) >= 2); assert(sizeof(*src) == sizeof(**dst)); *dst = lame_calloc(unsigned short, n + 1); if (*dst != 0) { memcpy(*dst, src, n * sizeof(**dst)); (*dst)[n] = 0; return n; } } } return 0; } static size_t local_ucs2_strlen(unsigned short const *s) { size_t n = 0; if (s != 0) { while (*s++) { ++n; } } return n; } static size_t local_ucs2_substr(unsigned short** dst, unsigned short const* src, size_t start, size_t end) { size_t const len = 1 + 1 + ((start < end) ? (end - start) : 0); size_t n = 0; unsigned short *ptr = lame_calloc(unsigned short, len); *dst = ptr; if (ptr == 0 || src == 0) { return 0; } if (hasUcs2ByteOrderMarker(src[0])) { ptr[n++] = src[0]; if (start == 0) { ++start; } } while (start < end) { ptr[n++] = src[start++]; } ptr[n] = 0; return n; } static int local_ucs2_pos(unsigned short const* str, unsigned short c) { int i; for (i = 0; str != 0 && str[i] != 0; ++i) { if (str[i] == c) { return i; } } return -1; } static int local_char_pos(char const* str, char c) { int i; for (i = 0; str != 0 && str[i] != 0; ++i) { if (str[i] == c) { return i; } } return -1; } static int maybeLatin1(unsigned short const* text) { if (text) { unsigned short bom = *text++; while (*text) { unsigned short c = toLittleEndian(bom, *text++); if (c > 0x00fe) return 0; } } return 1; } static int searchGenre(char const* genre); static int sloppySearchGenre(char const* genre); static int lookupGenre(char const* genre) { char *str; int num = strtol(genre, &str, 10); /* is the input a string or a valid number? */ if (*str) { num = searchGenre(genre); if (num == GENRE_NAME_COUNT) { num = sloppySearchGenre(genre); } if (num == GENRE_NAME_COUNT) { return -2; /* no common genre text found */ } } else { if ((num < 0) || (num >= GENRE_NAME_COUNT)) { return -1; /* number unknown */ } } return num; } static unsigned char * writeLoBytes(unsigned char *frame, unsigned short const *str, size_t n); static char* local_strdup_utf16_to_latin1(unsigned short const* utf16) { size_t len = local_ucs2_strlen(utf16); unsigned char* latin1 = lame_calloc(unsigned char, len+1); writeLoBytes(latin1, utf16, len); return (char*)latin1; } static int id3tag_set_genre_utf16(lame_t gfp, unsigned short const* text) { lame_internal_flags* gfc = gfp->internal_flags; int ret; if (text == 0) { return -3; } if (!hasUcs2ByteOrderMarker(text[0])) { return -3; } if (maybeLatin1(text)) { char* latin1 = local_strdup_utf16_to_latin1(text); int num = lookupGenre(latin1); free(latin1); if (num == -1) return -1; /* number out of range */ if (num >= 0) { /* common genre found */ gfc->tag_spec.flags |= CHANGED_FLAG; gfc->tag_spec.genre_id3v1 = num; copyV1ToV2(gfp, ID_GENRE, genre_names[num]); return 0; } } ret = id3v2_add_ucs2(gfp, ID_GENRE, 0, 0, text); if (ret == 0) { gfc->tag_spec.flags |= CHANGED_FLAG; gfc->tag_spec.genre_id3v1 = GENRE_INDEX_OTHER; } return ret; } /* Some existing options for ID3 tag can be specified by --tv option as follows. --tt , --tv TIT2=value --ta , --tv TPE1=value --tl , --tv TALB=value --ty , --tv TYER=value --tn , --tv TRCK=value --tg , --tv TCON=value (although some are not exactly same)*/ int id3tag_set_albumart(lame_t gfp, const char *image, size_t size) { int mimetype = 0; unsigned char const *data = (unsigned char const *) image; lame_internal_flags *gfc = gfp->internal_flags; /* determine MIME type from the actual image data */ if (2 < size && data[0] == 0xFF && data[1] == 0xD8) { mimetype = MIMETYPE_JPEG; } else if (4 < size && data[0] == 0x89 && strncmp((const char *) &data[1], "PNG", 3) == 0) { mimetype = MIMETYPE_PNG; } else if (4 < size && strncmp((const char *) data, "GIF8", 4) == 0) { mimetype = MIMETYPE_GIF; } else { return -1; } if (gfc->tag_spec.albumart != 0) { free(gfc->tag_spec.albumart); gfc->tag_spec.albumart = 0; gfc->tag_spec.albumart_size = 0; gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE; } if (size < 1) { return 0; } gfc->tag_spec.albumart = lame_calloc(unsigned char, size); if (gfc->tag_spec.albumart != 0) { memcpy(gfc->tag_spec.albumart, image, size); gfc->tag_spec.albumart_size = (unsigned int)size; gfc->tag_spec.albumart_mimetype = mimetype; gfc->tag_spec.flags |= CHANGED_FLAG; id3tag_add_v2(gfp); } return 0; } static unsigned char * set_4_byte_value(unsigned char *bytes, uint32_t value) { int i; for (i = 3; i >= 0; --i) { bytes[i] = value & 0xffUL; value >>= 8; } return bytes + 4; } static uint32_t toID3v2TagId(char const *s) { unsigned int i, x = 0; if (s == 0) { return 0; } for (i = 0; i < 4 && s[i] != 0; ++i) { char const c = s[i]; unsigned int const u = 0x0ff & c; x <<= 8; x |= u; if (c < 'A' || 'Z' < c) { if (c < '0' || '9' < c) { return 0; } } } return x; } static uint32_t toID3v2TagId_ucs2(unsigned short const *s) { unsigned int i, x = 0; unsigned short bom = 0; if (s == 0) { return 0; } bom = s[0]; if (hasUcs2ByteOrderMarker(bom)) { ++s; } for (i = 0; i < 4 && s[i] != 0; ++i) { unsigned short const c = toLittleEndian(bom, s[i]); if (c < 'A' || 'Z' < c) { if (c < '0' || '9' < c) { return 0; } } x <<= 8; x |= c; } return x; } #if 0 static int isNumericString(uint32_t frame_id) { switch (frame_id) { case ID_DATE: case ID_TIME: case ID_TPOS: case ID_TRACK: case ID_YEAR: return 1; } return 0; } #endif static int isMultiFrame(uint32_t frame_id) { switch (frame_id) { case ID_TXXX: case ID_WXXX: case ID_COMMENT: case ID_SYLT: case ID_APIC: case ID_GEOB: case ID_PCNT: case ID_AENC: case ID_LINK: case ID_ENCR: case ID_GRID: case ID_PRIV: return 1; } return 0; } #if 0 static int isFullTextString(int frame_id) { switch (frame_id) { case ID_VSLT: case ID_COMMENT: return 1; } return 0; } #endif static FrameDataNode * findNode(id3tag_spec const *tag, uint32_t frame_id, FrameDataNode const *last) { FrameDataNode *node = last ? last->nxt : tag->v2_head; while (node != 0) { if (node->fid == frame_id) { return node; } node = node->nxt; } return 0; } static void appendNode(id3tag_spec * tag, FrameDataNode * node) { if (tag->v2_tail == 0 || tag->v2_head == 0) { tag->v2_head = node; tag->v2_tail = node; } else { tag->v2_tail->nxt = node; tag->v2_tail = node; } } static void setLang(char *dst, char const *src) { int i; if (src == 0 || src[0] == 0) { dst[0] = 'X'; dst[1] = 'X'; dst[2] = 'X'; } else { for (i = 0; i < 3 && src && *src; ++i) { dst[i] = src[i]; } for (; i < 3; ++i) { dst[i] = ' '; } } } static int isSameLang(char const *l1, char const *l2) { char d[3]; int i; setLang(d, l2); for (i = 0; i < 3; ++i) { char a = tolower(l1[i]); char b = tolower(d[i]); if (a < ' ') a = ' '; if (b < ' ') b = ' '; if (a != b) { return 0; } } return 1; } static int isSameDescriptor(FrameDataNode const *node, char const *dsc) { size_t i; if (node->dsc.enc == 1 && node->dsc.dim > 0) { return 0; } for (i = 0; i < node->dsc.dim; ++i) { if (!dsc || node->dsc.ptr.l[i] != dsc[i]) { return 0; } } return 1; } static int isSameDescriptorUcs2(FrameDataNode const *node, unsigned short const *dsc) { size_t i; if (node->dsc.enc != 1 && node->dsc.dim > 0) { return 0; } for (i = 0; i < node->dsc.dim; ++i) { if (!dsc || node->dsc.ptr.u[i] != dsc[i]) { return 0; } } return 1; } static int id3v2_add_ucs2(lame_t gfp, uint32_t frame_id, char const *lang, unsigned short const *desc, unsigned short const *text) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc != 0) { FrameDataNode *node = findNode(&gfc->tag_spec, frame_id, 0); if (isMultiFrame(frame_id)) { while (node) { if (isSameLang(node->lng, lang)) { if (isSameDescriptorUcs2(node, desc)) { break; } } node = findNode(&gfc->tag_spec, frame_id, node); } } if (node == 0) { node = lame_calloc(FrameDataNode, 1); if (node == 0) { return -254; /* memory problem */ } appendNode(&gfc->tag_spec, node); } node->fid = frame_id; setLang(node->lng, lang); node->dsc.dim = local_ucs2_strdup(&node->dsc.ptr.u, desc); node->dsc.enc = 1; node->txt.dim = local_ucs2_strdup(&node->txt.ptr.u, text); node->txt.enc = 1; gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); return 0; } return -255; } static int id3v2_add_latin1(lame_t gfp, uint32_t frame_id, char const *lang, char const *desc, char const *text) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc != 0) { FrameDataNode *node = findNode(&gfc->tag_spec, frame_id, 0); if (isMultiFrame(frame_id)) { while (node) { if (isSameLang(node->lng, lang)) { if (isSameDescriptor(node, desc)) { break; } } node = findNode(&gfc->tag_spec, frame_id, node); } } if (node == 0) { node = lame_calloc(FrameDataNode, 1); if (node == 0) { return -254; /* memory problem */ } appendNode(&gfc->tag_spec, node); } node->fid = frame_id; setLang(node->lng, lang); node->dsc.dim = local_strdup(&node->dsc.ptr.l, desc); node->dsc.enc = 0; node->txt.dim = local_strdup(&node->txt.ptr.l, text); node->txt.enc = 0; gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); return 0; } return -255; } static int id3tag_set_userinfo_latin1(lame_t gfp, uint32_t id, char const *fieldvalue) { char const separator = '='; int rc = -7; int a = local_char_pos(fieldvalue, separator); if (a >= 0) { char* dup = 0; local_strdup(&dup, fieldvalue); dup[a] = 0; rc = id3v2_add_latin1(gfp, id, "XXX", dup, dup+a+1); free(dup); } return rc; } static int id3tag_set_userinfo_ucs2(lame_t gfp, uint32_t id, unsigned short const *fieldvalue) { unsigned short const separator = fromLatin1Char(fieldvalue,'='); int rc = -7; size_t b = local_ucs2_strlen(fieldvalue); int a = local_ucs2_pos(fieldvalue, separator); if (a >= 0) { unsigned short* dsc = 0, *val = 0; local_ucs2_substr(&dsc, fieldvalue, 0, a); local_ucs2_substr(&val, fieldvalue, a+1, b); rc = id3v2_add_ucs2(gfp, id, "XXX", dsc, val); free(dsc); free(val); } return rc; } int id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text) { uint32_t const frame_id = toID3v2TagId(id); if (frame_id == 0) { return -1; } if (text == 0) { return 0; } if (!hasUcs2ByteOrderMarker(text[0])) { return -3; /* BOM missing */ } if (frame_id == ID_TXXX || frame_id == ID_WXXX || frame_id == ID_COMMENT) { return id3tag_set_userinfo_ucs2(gfp, frame_id, text); } if (frame_id == ID_GENRE) { return id3tag_set_genre_utf16(gfp, text); } if (frame_id == ID_PCST) { return id3v2_add_ucs2(gfp, frame_id, 0, 0, text); } if (frame_id == ID_USER) { return id3v2_add_ucs2(gfp, frame_id, "XXX", text, 0); } if (frame_id == ID_WFED) { return id3v2_add_ucs2(gfp, frame_id, 0, text, 0); /* iTunes expects WFED to be a text frame */ } if (isFrameIdMatching(frame_id, FRAME_ID('T', 0, 0, 0)) ||isFrameIdMatching(frame_id, FRAME_ID('W', 0, 0, 0))) { #if 0 if (isNumericString(frame_id)) { return -2; /* must be Latin-1 encoded */ } #endif return id3v2_add_ucs2(gfp, frame_id, 0, 0, text); } return -255; /* not supported by now */ } extern int id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text); int id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text) { return id3tag_set_textinfo_utf16(gfp, id, text); } int id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text) { uint32_t const frame_id = toID3v2TagId(id); if (frame_id == 0) { return -1; } if (text == 0) { return 0; } if (frame_id == ID_TXXX || frame_id == ID_WXXX || frame_id == ID_COMMENT) { return id3tag_set_userinfo_latin1(gfp, frame_id, text); } if (frame_id == ID_GENRE) { return id3tag_set_genre(gfp, text); } if (frame_id == ID_PCST) { return id3v2_add_latin1(gfp, frame_id, 0, 0, text); } if (frame_id == ID_USER) { return id3v2_add_latin1(gfp, frame_id, "XXX", text, 0); } if (frame_id == ID_WFED) { return id3v2_add_latin1(gfp, frame_id, 0, text, 0); /* iTunes expects WFED to be a text frame */ } if (isFrameIdMatching(frame_id, FRAME_ID('T', 0, 0, 0)) ||isFrameIdMatching(frame_id, FRAME_ID('W', 0, 0, 0))) { return id3v2_add_latin1(gfp, frame_id, 0, 0, text); } return -255; /* not supported by now */ } int id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text) { return id3v2_add_latin1(gfp, ID_COMMENT, lang, desc, text); } int id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text) { return id3v2_add_ucs2(gfp, ID_COMMENT, lang, desc, text); } extern int id3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text); int id3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text) { return id3tag_set_comment_utf16(gfp, lang, desc, text); } void id3tag_set_title(lame_t gfp, const char *title) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc && title && *title) { local_strdup(&gfc->tag_spec.title, title); gfc->tag_spec.flags |= CHANGED_FLAG; copyV1ToV2(gfp, ID_TITLE, title); } } void id3tag_set_artist(lame_t gfp, const char *artist) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc && artist && *artist) { local_strdup(&gfc->tag_spec.artist, artist); gfc->tag_spec.flags |= CHANGED_FLAG; copyV1ToV2(gfp, ID_ARTIST, artist); } } void id3tag_set_album(lame_t gfp, const char *album) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc && album && *album) { local_strdup(&gfc->tag_spec.album, album); gfc->tag_spec.flags |= CHANGED_FLAG; copyV1ToV2(gfp, ID_ALBUM, album); } } void id3tag_set_year(lame_t gfp, const char *year) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc && year && *year) { int num = atoi(year); if (num < 0) { num = 0; } /* limit a year to 4 digits so it fits in a version 1 tag */ if (num > 9999) { num = 9999; } if (num) { gfc->tag_spec.year = num; gfc->tag_spec.flags |= CHANGED_FLAG; } copyV1ToV2(gfp, ID_YEAR, year); } } void id3tag_set_comment(lame_t gfp, const char *comment) { lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; if (gfc && comment && *comment) { local_strdup(&gfc->tag_spec.comment, comment); gfc->tag_spec.flags |= CHANGED_FLAG; { uint32_t const flags = gfc->tag_spec.flags; id3v2_add_latin1(gfp, ID_COMMENT, "XXX", "", comment); gfc->tag_spec.flags = flags; } } } int id3tag_set_track(lame_t gfp, const char *track) { char const *trackcount; lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; int ret = 0; if (gfc && track && *track) { int num = atoi(track); /* check for valid ID3v1 track number range */ if (num < 1 || num > 255) { num = 0; ret = -1; /* track number out of ID3v1 range, ignored for ID3v1 */ gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); } if (num) { gfc->tag_spec.track_id3v1 = num; gfc->tag_spec.flags |= CHANGED_FLAG; } /* Look for the total track count after a "/", same restrictions */ trackcount = strchr(track, '/'); if (trackcount && *trackcount) { gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); } copyV1ToV2(gfp, ID_TRACK, track); } return ret; } /* would use real "strcasecmp" but it isn't portable */ static int local_strcasecmp(const char *s1, const char *s2) { unsigned char c1; unsigned char c2; do { c1 = tolower(*s1); c2 = tolower(*s2); if (!c1) { break; } ++s1; ++s2; } while (c1 == c2); return c1 - c2; } static const char* nextUpperAlpha(const char* p, char x) { char c; for(c = toupper(*p); *p != 0; c = toupper(*++p)) { if ('A' <= c && c <= 'Z') { if (c != x) { return p; } } } return p; } static int sloppyCompared(const char* p, const char* q) { char cp, cq; p = nextUpperAlpha(p, 0); q = nextUpperAlpha(q, 0); cp = toupper(*p); cq = toupper(*q); while (cp == cq) { if (cp == 0) { return 1; } if (p[1] == '.') { /* some abbrevation */ while (*q && *q++ != ' ') { } } p = nextUpperAlpha(p, cp); q = nextUpperAlpha(q, cq); cp = toupper(*p); cq = toupper(*q); } return 0; } static int sloppySearchGenre(const char *genre) { int i; for (i = 0; i < GENRE_NAME_COUNT; ++i) { if (sloppyCompared(genre, genre_names[i])) { return i; } } return GENRE_NAME_COUNT; } static int searchGenre(const char* genre) { int i; for (i = 0; i < GENRE_NAME_COUNT; ++i) { if (!local_strcasecmp(genre, genre_names[i])) { return i; } } return GENRE_NAME_COUNT; } int id3tag_set_genre(lame_t gfp, const char *genre) { lame_internal_flags *gfc = gfp->internal_flags; int ret = 0; if (genre && *genre) { int const num = lookupGenre(genre); if (num == -1) return num; gfc->tag_spec.flags |= CHANGED_FLAG; if (num >= 0) { gfc->tag_spec.genre_id3v1 = num; genre = genre_names[num]; } else { gfc->tag_spec.genre_id3v1 = GENRE_INDEX_OTHER; gfc->tag_spec.flags |= ADD_V2_FLAG; } copyV1ToV2(gfp, ID_GENRE, genre); } return ret; } static size_t sizeOfNode(FrameDataNode const *node) { size_t n = 0; if (node) { n = 10; /* header size */ n += 1; /* text encoding flag */ switch (node->txt.enc) { default: case 0: if (node->dsc.dim > 0) { n += node->dsc.dim + 1; } n += node->txt.dim; break; case 1: if (node->dsc.dim > 0) { n += (node->dsc.dim+1) * 2; } n += node->txt.dim * 2; break; } } return n; } static size_t sizeOfCommentNode(FrameDataNode const *node) { size_t n = 0; if (node) { n = 10; /* header size */ n += 1; /* text encoding flag */ n += 3; /* language */ switch (node->dsc.enc) { default: case 0: n += 1 + node->dsc.dim; break; case 1: n += 2 + node->dsc.dim * 2; break; } switch (node->txt.enc) { default: case 0: n += node->txt.dim; break; case 1: n += node->txt.dim * 2; break; } } return n; } static size_t sizeOfWxxxNode(FrameDataNode const *node) { size_t n = 0; if (node) { n = 10; /* header size */ if (node->dsc.dim > 0) { n += 1; /* text encoding flag */ switch (node->dsc.enc) { default: case 0: n += 1 + node->dsc.dim; break; case 1: n += 2 + node->dsc.dim * 2; break; } } if (node->txt.dim > 0) { switch (node->txt.enc) { default: case 0: n += node->txt.dim; break; case 1: n += node->txt.dim - 1; /* UCS2 -> Latin1, skip BOM */ break; } } } return n; } static unsigned char * writeChars(unsigned char *frame, char const *str, size_t n) { while (n--) { *frame++ = *str++; } return frame; } static unsigned char * writeUcs2s(unsigned char *frame, unsigned short const *str, size_t n) { if (n > 0) { unsigned short const bom = *str; while (n--) { unsigned short const c = toLittleEndian(bom, *str++); *frame++ = 0x00ffu & c; *frame++ = 0x00ffu & (c >> 8); } } return frame; } static unsigned char * writeLoBytes(unsigned char *frame, unsigned short const *str, size_t n) { if (n > 0) { unsigned short const bom = *str; if (hasUcs2ByteOrderMarker(bom)) { str++; n--; /* skip BOM */ } while (n--) { unsigned short const c = toLittleEndian(bom, *str++); if (c < 0x0020u || 0x00ffu < c) { *frame++ = 0x0020; /* blank */ } else { *frame++ = c; } } } return frame; } static unsigned char * set_frame_comment(unsigned char *frame, FrameDataNode const *node) { size_t const n = sizeOfCommentNode(node); if (n > 10) { frame = set_4_byte_value(frame, node->fid); frame = set_4_byte_value(frame, (uint32_t) (n - 10)); /* clear 2-byte header flags */ *frame++ = 0; *frame++ = 0; /* encoding descriptor byte */ *frame++ = node->txt.enc == 1 ? 1 : 0; /* 3 bytes language */ *frame++ = node->lng[0]; *frame++ = node->lng[1]; *frame++ = node->lng[2]; /* descriptor with zero byte(s) separator */ if (node->dsc.enc != 1) { frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim); *frame++ = 0; } else { frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim); *frame++ = 0; *frame++ = 0; } /* comment full text */ if (node->txt.enc != 1) { frame = writeChars(frame, node->txt.ptr.l, node->txt.dim); } else { frame = writeUcs2s(frame, node->txt.ptr.u, node->txt.dim); } } return frame; } static unsigned char * set_frame_custom2(unsigned char *frame, FrameDataNode const *node) { size_t const n = sizeOfNode(node); if (n > 10) { frame = set_4_byte_value(frame, node->fid); frame = set_4_byte_value(frame, (unsigned long) (n - 10)); /* clear 2-byte header flags */ *frame++ = 0; *frame++ = 0; /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */ *frame++ = node->txt.enc == 1 ? 1 : 0; if (node->dsc.dim > 0) { if (node->dsc.enc != 1) { frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim); *frame++ = 0; } else { frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim); *frame++ = 0; *frame++ = 0; } } if (node->txt.enc != 1) { frame = writeChars(frame, node->txt.ptr.l, node->txt.dim); } else { frame = writeUcs2s(frame, node->txt.ptr.u, node->txt.dim); } } return frame; } static unsigned char * set_frame_wxxx(unsigned char *frame, FrameDataNode const *node) { size_t const n = sizeOfWxxxNode(node); if (n > 10) { frame = set_4_byte_value(frame, node->fid); frame = set_4_byte_value(frame, (unsigned long) (n - 10)); /* clear 2-byte header flags */ *frame++ = 0; *frame++ = 0; if (node->dsc.dim > 0) { /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */ *frame++ = node->dsc.enc == 1 ? 1 : 0; if (node->dsc.enc != 1) { frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim); *frame++ = 0; } else { frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim); *frame++ = 0; *frame++ = 0; } } if (node->txt.enc != 1) { frame = writeChars(frame, node->txt.ptr.l, node->txt.dim); } else { frame = writeLoBytes(frame, node->txt.ptr.u, node->txt.dim); } } return frame; } static unsigned char * set_frame_apic(unsigned char *frame, const char *mimetype, const unsigned char *data, size_t size) { /* ID3v2.3 standard APIC frame: *
* Text encoding $xx * MIME type $00 * Picture type $xx * Description $00 (00) * Picture data */ if (mimetype && data && size) { frame = set_4_byte_value(frame, FRAME_ID('A', 'P', 'I', 'C')); frame = set_4_byte_value(frame, (unsigned long) (4 + strlen(mimetype) + size)); /* clear 2-byte header flags */ *frame++ = 0; *frame++ = 0; /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */ *frame++ = 0; /* copy mime_type */ while (*mimetype) { *frame++ = *mimetype++; } *frame++ = 0; /* set picture type to 0 */ *frame++ = 0; /* empty description field */ *frame++ = 0; /* copy the image data */ while (size--) { *frame++ = *data++; } } return frame; } int id3tag_set_fieldvalue(lame_t gfp, const char *fieldvalue) { if (fieldvalue && *fieldvalue) { if (strlen(fieldvalue) < 5 || fieldvalue[4] != '=') { return -1; } return id3tag_set_textinfo_latin1(gfp, fieldvalue, &fieldvalue[5]); } return 0; } int id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue) { if (fieldvalue && *fieldvalue) { size_t dx = hasUcs2ByteOrderMarker(fieldvalue[0]); unsigned short const separator = fromLatin1Char(fieldvalue, '='); char fid[5] = {0,0,0,0,0}; uint32_t const frame_id = toID3v2TagId_ucs2(fieldvalue); if (local_ucs2_strlen(fieldvalue) < (5+dx) || fieldvalue[4+dx] != separator) { return -1; } fid[0] = (frame_id >> 24) & 0x0ff; fid[1] = (frame_id >> 16) & 0x0ff; fid[2] = (frame_id >> 8) & 0x0ff; fid[3] = frame_id & 0x0ff; if (frame_id != 0) { unsigned short* txt = 0; int rc; local_ucs2_substr(&txt, fieldvalue, dx+5, local_ucs2_strlen(fieldvalue)); rc = id3tag_set_textinfo_utf16(gfp, fid, txt); free(txt); return rc; } } return -1; } extern int id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue); int id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue) { return id3tag_set_fieldvalue_utf16(gfp, fieldvalue); } size_t lame_get_id3v2_tag(lame_t gfp, unsigned char *buffer, size_t size) { lame_internal_flags *gfc; if (gfp == 0) { return 0; } gfc = gfp->internal_flags; if (gfc == 0) { return 0; } if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) { return 0; } #if 0 debug_tag_spec_flags(gfc, "lame_get_id3v2_tag"); #endif { int usev2 = test_tag_spec_flags(gfc, ADD_V2_FLAG | V2_ONLY_FLAG); /* calculate length of four fields which may not fit in verion 1 tag */ size_t title_length = gfc->tag_spec.title ? strlen(gfc->tag_spec.title) : 0; size_t artist_length = gfc->tag_spec.artist ? strlen(gfc->tag_spec.artist) : 0; size_t album_length = gfc->tag_spec.album ? strlen(gfc->tag_spec.album) : 0; size_t comment_length = gfc->tag_spec.comment ? strlen(gfc->tag_spec.comment) : 0; /* write tag if explicitly requested or if fields overflow */ if ((title_length > 30) || (artist_length > 30) || (album_length > 30) || (comment_length > 30) || (gfc->tag_spec.track_id3v1 && (comment_length > 28))) { usev2 = 1; } if (usev2) { size_t tag_size; unsigned char *p; size_t adjusted_tag_size; const char *albumart_mime = NULL; static const char *mime_jpeg = "image/jpeg"; static const char *mime_png = "image/png"; static const char *mime_gif = "image/gif"; if (gfp->num_samples != MAX_U_32_NUM) { id3v2AddAudioDuration(gfp, gfp->num_samples); } /* calulate size of tag starting with 10-byte tag header */ tag_size = 10; if (gfc->tag_spec.albumart && gfc->tag_spec.albumart_size) { switch (gfc->tag_spec.albumart_mimetype) { case MIMETYPE_JPEG: albumart_mime = mime_jpeg; break; case MIMETYPE_PNG: albumart_mime = mime_png; break; case MIMETYPE_GIF: albumart_mime = mime_gif; break; } if (albumart_mime) { tag_size += 10 + 4 + strlen(albumart_mime) + gfc->tag_spec.albumart_size; } } { id3tag_spec *tag = &gfc->tag_spec; if (tag->v2_head != 0) { FrameDataNode *node; for (node = tag->v2_head; node != 0; node = node->nxt) { if (node->fid == ID_COMMENT || node->fid == ID_USER) { tag_size += sizeOfCommentNode(node); } else if (isFrameIdMatching(node->fid, FRAME_ID('W',0,0,0))) { tag_size += sizeOfWxxxNode(node); } else { tag_size += sizeOfNode(node); } } } } if (test_tag_spec_flags(gfc, PAD_V2_FLAG)) { /* add some bytes of padding */ tag_size += gfc->tag_spec.padding_size; } if (size < tag_size) { return tag_size; } if (buffer == 0) { return 0; } p = buffer; /* set tag header starting with file identifier */ *p++ = 'I'; *p++ = 'D'; *p++ = '3'; /* set version number word */ *p++ = 3; *p++ = 0; /* clear flags byte */ *p++ = 0; /* calculate and set tag size = total size - header size */ adjusted_tag_size = tag_size - 10; /* encode adjusted size into four bytes where most significant * bit is clear in each byte, for 28-bit total */ *p++ = (unsigned char) ((adjusted_tag_size >> 21) & 0x7fu); *p++ = (unsigned char) ((adjusted_tag_size >> 14) & 0x7fu); *p++ = (unsigned char) ((adjusted_tag_size >> 7) & 0x7fu); *p++ = (unsigned char) (adjusted_tag_size & 0x7fu); /* * NOTE: The remainder of the tag (frames and padding, if any) * are not "unsynchronized" to prevent false MPEG audio headers * from appearing in the bitstream. Why? Well, most players * and utilities know how to skip the ID3 version 2 tag by now * even if they don't read its contents, and it's actually * very unlikely that such a false "sync" pattern would occur * in just the simple text frames added here. */ /* set each frame in tag */ { id3tag_spec *tag = &gfc->tag_spec; if (tag->v2_head != 0) { FrameDataNode *node; for (node = tag->v2_head; node != 0; node = node->nxt) { if (node->fid == ID_COMMENT || node->fid == ID_USER) { p = set_frame_comment(p, node); } else if (isFrameIdMatching(node->fid,FRAME_ID('W',0,0,0))) { p = set_frame_wxxx(p, node); } else { p = set_frame_custom2(p, node); } } } } if (albumart_mime) { p = set_frame_apic(p, albumart_mime, gfc->tag_spec.albumart, gfc->tag_spec.albumart_size); } /* clear any padding bytes */ memset(p, 0, tag_size - (p - buffer)); return tag_size; } } return 0; } int id3tag_write_v2(lame_t gfp) { lame_internal_flags *gfc = gfp->internal_flags; #if 0 debug_tag_spec_flags(gfc, "write v2"); #endif if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) { return 0; } if (test_tag_spec_flags(gfc, CHANGED_FLAG)) { unsigned char *tag = 0; size_t tag_size, n; n = lame_get_id3v2_tag(gfp, 0, 0); tag = lame_calloc(unsigned char, n); if (tag == 0) { return -1; } tag_size = lame_get_id3v2_tag(gfp, tag, n); if (tag_size > n) { free(tag); return -1; } else { size_t i; /* write tag directly into bitstream at current position */ for (i = 0; i < tag_size; ++i) { add_dummy_byte(gfc, tag[i], 1); } } free(tag); return (int) tag_size; /* ok, tag should not exceed 2GB */ } return 0; } static unsigned char * set_text_field(unsigned char *field, const char *text, size_t size, int pad) { while (size--) { if (text && *text) { *field++ = *text++; } else { *field++ = pad; } } return field; } size_t lame_get_id3v1_tag(lame_t gfp, unsigned char *buffer, size_t size) { size_t const tag_size = 128; lame_internal_flags *gfc; if (gfp == 0) { return 0; } if (size < tag_size) { return tag_size; } gfc = gfp->internal_flags; if (gfc == 0) { return 0; } if (buffer == 0) { return 0; } if (test_tag_spec_flags(gfc, V2_ONLY_FLAG)) { return 0; } if (test_tag_spec_flags(gfc, CHANGED_FLAG)) { unsigned char *p = buffer; int pad = test_tag_spec_flags(gfc, SPACE_V1_FLAG) ? ' ' : 0; char year[5]; /* set tag identifier */ *p++ = 'T'; *p++ = 'A'; *p++ = 'G'; /* set each field in tag */ p = set_text_field(p, gfc->tag_spec.title, 30, pad); p = set_text_field(p, gfc->tag_spec.artist, 30, pad); p = set_text_field(p, gfc->tag_spec.album, 30, pad); sprintf(year, "%d", gfc->tag_spec.year); p = set_text_field(p, gfc->tag_spec.year ? year : NULL, 4, pad); /* limit comment field to 28 bytes if a track is specified */ p = set_text_field(p, gfc->tag_spec.comment, gfc->tag_spec.track_id3v1 ? 28 : 30, pad); if (gfc->tag_spec.track_id3v1) { /* clear the next byte to indicate a version 1.1 tag */ *p++ = 0; *p++ = gfc->tag_spec.track_id3v1; } *p++ = gfc->tag_spec.genre_id3v1; return tag_size; } return 0; } int id3tag_write_v1(lame_t gfp) { lame_internal_flags *const gfc = gfp->internal_flags; size_t i, n, m; unsigned char tag[128]; m = sizeof(tag); n = lame_get_id3v1_tag(gfp, tag, m); if (n > m) { return 0; } /* write tag directly into bitstream at current position */ for (i = 0; i < n; ++i) { add_dummy_byte(gfc, tag[i], 1); } return (int) n; /* ok, tag has fixed size of 128 bytes, well below 2GB */ } ================================================ FILE: app/jni/libmp3lame/id3tag.h ================================================ #ifndef LAME_ID3_H #define LAME_ID3_H #define CHANGED_FLAG (1U << 0) #define ADD_V2_FLAG (1U << 1) #define V1_ONLY_FLAG (1U << 2) #define V2_ONLY_FLAG (1U << 3) #define SPACE_V1_FLAG (1U << 4) #define PAD_V2_FLAG (1U << 5) enum { MIMETYPE_NONE = 0, MIMETYPE_JPEG, MIMETYPE_PNG, MIMETYPE_GIF, }; typedef struct FrameDataNode { struct FrameDataNode *nxt; uint32_t fid; /* Frame Identifier */ char lng[4]; /* 3-character language descriptor */ struct { union { char *l; /* ptr to Latin-1 chars */ unsigned short *u; /* ptr to UCS-2 text */ unsigned char *b; /* ptr to raw bytes */ } ptr; size_t dim; int enc; /* 0:Latin-1, 1:UCS-2, 2:RAW */ } dsc , txt; } FrameDataNode; typedef struct id3tag_spec { /* private data members */ unsigned int flags; int year; char *title; char *artist; char *album; char *comment; int track_id3v1; int genre_id3v1; unsigned char *albumart; unsigned int albumart_size; unsigned int padding_size; int albumart_mimetype; FrameDataNode *v2_head, *v2_tail; } id3tag_spec; /* write tag into stream at current position */ extern int id3tag_write_v2(lame_global_flags * gfp); extern int id3tag_write_v1(lame_global_flags * gfp); /* * NOTE: A version 2 tag will NOT be added unless one of the text fields won't * fit in a version 1 tag (e.g. the title string is longer than 30 characters), * or the "id3tag_add_v2" or "id3tag_v2_only" functions are used. */ #endif ================================================ FILE: app/jni/libmp3lame/l3side.h ================================================ /* * Layer 3 side include file * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_L3SIDE_H #define LAME_L3SIDE_H /* max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) */ #define SFBMAX (SBMAX_s*3) /* Layer III side information. */ typedef struct { int l[1 + SBMAX_l]; int s[1 + SBMAX_s]; int psfb21[1 + PSFB21]; int psfb12[1 + PSFB12]; } scalefac_struct; typedef struct { FLOAT l[SBMAX_l]; FLOAT s[SBMAX_s][3]; } III_psy_xmin; typedef struct { III_psy_xmin thm; III_psy_xmin en; } III_psy_ratio; typedef struct { FLOAT xr[576]; int l3_enc[576]; int scalefac[SFBMAX]; FLOAT xrpow_max; int part2_3_length; int big_values; int count1; int global_gain; int scalefac_compress; int block_type; int mixed_block_flag; int table_select[3]; int subblock_gain[3 + 1]; int region0_count; int region1_count; int preflag; int scalefac_scale; int count1table_select; int part2_length; int sfb_lmax; int sfb_smin; int psy_lmax; int sfbmax; int psymax; int sfbdivide; int width[SFBMAX]; int window[SFBMAX]; int count1bits; /* added for LSF */ const int *sfb_partition_table; int slen[4]; int max_nonzero_coeff; char energy_above_cutoff[SFBMAX]; } gr_info; typedef struct { gr_info tt[2][2]; int main_data_begin; int private_bits; int resvDrain_pre; int resvDrain_post; int scfsi[2][4]; } III_side_info_t; #endif ================================================ FILE: app/jni/libmp3lame/lame-analysis.h ================================================ /* * GTK plotting routines source file * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_GTKANAL_H #define LAME_GTKANAL_H #define READ_AHEAD 40 /* number of frames to read ahead */ #define MAXMPGLAG READ_AHEAD /* if the mpg123 lag becomes bigger than this we have to stop */ #define NUMBACK 6 /* number of frames we can back up */ #define NUMPINFO (NUMBACK+READ_AHEAD+1) struct plotting_data { int frameNum; /* current frame number */ int frameNum123; int num_samples; /* number of pcm samples read for this frame */ double frametime; /* starting time of frame, in seconds */ double pcmdata[2][1600]; double pcmdata2[2][1152 + 1152 - DECDELAY]; double xr[2][2][576]; double mpg123xr[2][2][576]; double ms_ratio[2]; double ms_ener_ratio[2]; /* L,R, M and S values */ double energy_save[4][BLKSIZE]; /* psymodel is one ahead */ double energy[2][4][BLKSIZE]; double pe[2][4]; double thr[2][4][SBMAX_l]; double en[2][4][SBMAX_l]; double thr_s[2][4][3 * SBMAX_s]; double en_s[2][4][3 * SBMAX_s]; double ers_save[4]; /* psymodel is one ahead */ double ers[2][4]; double sfb[2][2][SBMAX_l]; double sfb_s[2][2][3 * SBMAX_s]; double LAMEsfb[2][2][SBMAX_l]; double LAMEsfb_s[2][2][3 * SBMAX_s]; int LAMEqss[2][2]; int qss[2][2]; int big_values[2][2]; int sub_gain[2][2][3]; double xfsf[2][2][SBMAX_l]; double xfsf_s[2][2][3 * SBMAX_s]; int over[2][2]; double tot_noise[2][2]; double max_noise[2][2]; double over_noise[2][2]; int over_SSD[2][2]; int blocktype[2][2]; int scalefac_scale[2][2]; int preflag[2][2]; int mpg123blocktype[2][2]; int mixed[2][2]; int mainbits[2][2]; int sfbits[2][2]; int LAMEmainbits[2][2]; int LAMEsfbits[2][2]; int framesize, stereo, js, ms_stereo, i_stereo, emph, bitrate, sampfreq, maindata; int crc, padding; int scfsi[2], mean_bits, resvsize; int totbits; }; #ifndef plotting_data_defined #define plotting_data_defined typedef struct plotting_data plotting_data; #endif #if 0 extern plotting_data *pinfo; #endif #endif ================================================ FILE: app/jni/libmp3lame/lame.c ================================================ /* -*- mode: C; mode: fold -*- */ /* * LAME MP3 encoding engine * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 2000-2005 Takehiro Tominaga * Copyright (c) 2000-2011 Robert Hegemann * Copyright (c) 2000-2005 Gabriel Bouvigne * Copyright (c) 2000-2004 Alexander Leidinger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: lame.c,v 1.365 2011/10/18 21:51:20 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "lame_global_flags.h" #include "gain_analysis.h" #include "bitstream.h" #include "quantize_pvt.h" #include "set_get.h" #include "quantize.h" #include "psymodel.h" #include "version.h" #include "VbrTag.h" #include "tables.h" #if defined(__FreeBSD__) && !defined(__alpha__) #include #endif #ifdef __riscos__ #include "asmstuff.h" #endif #ifdef __sun__ /* woraround for SunOS 4.x, it has SEEK_* defined here */ #include #endif #define LAME_DEFAULT_QUALITY 3 int is_lame_global_flags_valid(const lame_global_flags * gfp) { if (gfp == NULL) return 0; if (gfp->class_id != LAME_ID) return 0; return 1; } int is_lame_internal_flags_valid(const lame_internal_flags * gfc) { if (gfc == NULL) return 0; if (gfc->class_id != LAME_ID) return 0; return 1; } static FLOAT filter_coef(FLOAT x) { if (x > 1.0) return 0.0; if (x <= 0.0) return 1.0; return cos(PI / 2 * x); } static void lame_init_params_ppflt(lame_internal_flags * gfc) { SessionConfig_t *const cfg = &gfc->cfg; /***************************************************************/ /* compute info needed for polyphase filter (filter type==0, default) */ /***************************************************************/ int band, maxband, minband; FLOAT freq; int lowpass_band = 32; int highpass_band = -1; if (cfg->lowpass1 > 0) { minband = 999; for (band = 0; band <= 31; band++) { freq = band / 31.0; /* this band and above will be zeroed: */ if (freq >= cfg->lowpass2) { lowpass_band = Min(lowpass_band, band); } if (cfg->lowpass1 < freq && freq < cfg->lowpass2) { minband = Min(minband, band); } } /* compute the *actual* transition band implemented by * the polyphase filter */ if (minband == 999) { cfg->lowpass1 = (lowpass_band - .75) / 31.0; } else { cfg->lowpass1 = (minband - .75) / 31.0; } cfg->lowpass2 = lowpass_band / 31.0; } /* make sure highpass filter is within 90% of what the effective * highpass frequency will be */ if (cfg->highpass2 > 0) { if (cfg->highpass2 < .9 * (.75 / 31.0)) { cfg->highpass1 = 0; cfg->highpass2 = 0; MSGF(gfc, "Warning: highpass filter disabled. " "highpass frequency too small\n"); } } if (cfg->highpass2 > 0) { maxband = -1; for (band = 0; band <= 31; band++) { freq = band / 31.0; /* this band and below will be zereod */ if (freq <= cfg->highpass1) { highpass_band = Max(highpass_band, band); } if (cfg->highpass1 < freq && freq < cfg->highpass2) { maxband = Max(maxband, band); } } /* compute the *actual* transition band implemented by * the polyphase filter */ cfg->highpass1 = highpass_band / 31.0; if (maxband == -1) { cfg->highpass2 = (highpass_band + .75) / 31.0; } else { cfg->highpass2 = (maxband + .75) / 31.0; } } for (band = 0; band < 32; band++) { FLOAT fc1, fc2; freq = band / 31.0f; if (cfg->highpass2 > cfg->highpass1) { fc1 = filter_coef((cfg->highpass2 - freq) / (cfg->highpass2 - cfg->highpass1 + 1e-20)); } else { fc1 = 1.0f; } if (cfg->lowpass2 > cfg->lowpass1) { fc2 = filter_coef((freq - cfg->lowpass1) / (cfg->lowpass2 - cfg->lowpass1 + 1e-20)); } else { fc2 = 1.0f; } gfc->sv_enc.amp_filter[band] = fc1 * fc2; } } static void optimum_bandwidth(double *const lowerlimit, double *const upperlimit, const unsigned bitrate) { /* * Input: * bitrate total bitrate in kbps * * Output: * lowerlimit: best lowpass frequency limit for input filter in Hz * upperlimit: best highpass frequency limit for input filter in Hz */ int table_index; typedef struct { int bitrate; /* only indicative value */ int lowpass; } band_pass_t; const band_pass_t freq_map[] = { {8, 2000}, {16, 3700}, {24, 3900}, {32, 5500}, {40, 7000}, {48, 7500}, {56, 10000}, {64, 11000}, {80, 13500}, {96, 15100}, {112, 15600}, {128, 17000}, {160, 17500}, {192, 18600}, {224, 19400}, {256, 19700}, {320, 20500} }; table_index = nearestBitrateFullIndex(bitrate); (void) freq_map[table_index].bitrate; *lowerlimit = freq_map[table_index].lowpass; /* * Now we try to choose a good high pass filtering frequency. * This value is currently not used. * For fu < 16 kHz: sqrt(fu*fl) = 560 Hz * For fu = 18 kHz: no high pass filtering * This gives: * * 2 kHz => 160 Hz * 3 kHz => 107 Hz * 4 kHz => 80 Hz * 8 kHz => 40 Hz * 16 kHz => 20 Hz * 17 kHz => 10 Hz * 18 kHz => 0 Hz * * These are ad hoc values and these can be optimized if a high pass is available. */ /* if (f_low <= 16000) f_high = 16000. * 20. / f_low; else if (f_low <= 18000) f_high = 180. - 0.01 * f_low; else f_high = 0.;*/ /* * When we sometimes have a good highpass filter, we can add the highpass * frequency to the lowpass frequency */ /*if (upperlimit != NULL) *upperlimit = f_high;*/ (void) upperlimit; } static int optimum_samplefreq(int lowpassfreq, int input_samplefreq) { /* * Rules: * - if possible, sfb21 should NOT be used * */ int suggested_samplefreq = 44100; if (input_samplefreq >= 48000) suggested_samplefreq = 48000; else if (input_samplefreq >= 44100) suggested_samplefreq = 44100; else if (input_samplefreq >= 32000) suggested_samplefreq = 32000; else if (input_samplefreq >= 24000) suggested_samplefreq = 24000; else if (input_samplefreq >= 22050) suggested_samplefreq = 22050; else if (input_samplefreq >= 16000) suggested_samplefreq = 16000; else if (input_samplefreq >= 12000) suggested_samplefreq = 12000; else if (input_samplefreq >= 11025) suggested_samplefreq = 11025; else if (input_samplefreq >= 8000) suggested_samplefreq = 8000; if (lowpassfreq == -1) return suggested_samplefreq; if (lowpassfreq <= 15960) suggested_samplefreq = 44100; if (lowpassfreq <= 15250) suggested_samplefreq = 32000; if (lowpassfreq <= 11220) suggested_samplefreq = 24000; if (lowpassfreq <= 9970) suggested_samplefreq = 22050; if (lowpassfreq <= 7230) suggested_samplefreq = 16000; if (lowpassfreq <= 5420) suggested_samplefreq = 12000; if (lowpassfreq <= 4510) suggested_samplefreq = 11025; if (lowpassfreq <= 3970) suggested_samplefreq = 8000; if (input_samplefreq < suggested_samplefreq) { /* choose a valid MPEG sample frequency above the input sample frequency to avoid SFB21/12 bitrate bloat rh 061115 */ if (input_samplefreq > 44100) { return 48000; } if (input_samplefreq > 32000) { return 44100; } if (input_samplefreq > 24000) { return 32000; } if (input_samplefreq > 22050) { return 24000; } if (input_samplefreq > 16000) { return 22050; } if (input_samplefreq > 12000) { return 16000; } if (input_samplefreq > 11025) { return 12000; } if (input_samplefreq > 8000) { return 11025; } return 8000; } return suggested_samplefreq; } /* set internal feature flags. USER should not access these since * some combinations will produce strange results */ static void lame_init_qval(lame_global_flags * gfp) { lame_internal_flags *const gfc = gfp->internal_flags; SessionConfig_t *const cfg = &gfc->cfg; switch (gfp->quality) { default: case 9: /* no psymodel, no noise shaping */ cfg->noise_shaping = 0; cfg->noise_shaping_amp = 0; cfg->noise_shaping_stop = 0; cfg->use_best_huffman = 0; cfg->full_outer_loop = 0; break; case 8: gfp->quality = 7; /*lint --fallthrough */ case 7: /* use psymodel (for short block and m/s switching), but no noise shapping */ cfg->noise_shaping = 0; cfg->noise_shaping_amp = 0; cfg->noise_shaping_stop = 0; cfg->use_best_huffman = 0; cfg->full_outer_loop = 0; if (gfp->VBR == vbr_mt || gfp->VBR == vbr_mtrh) { cfg->full_outer_loop = -1; } break; case 6: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; cfg->noise_shaping_amp = 0; cfg->noise_shaping_stop = 0; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 0; cfg->full_outer_loop = 0; break; case 5: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; cfg->noise_shaping_amp = 0; cfg->noise_shaping_stop = 0; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 0; cfg->full_outer_loop = 0; break; case 4: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; cfg->noise_shaping_amp = 0; cfg->noise_shaping_stop = 0; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 1; cfg->full_outer_loop = 0; break; case 3: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; cfg->noise_shaping_amp = 1; cfg->noise_shaping_stop = 1; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 1; cfg->full_outer_loop = 0; break; case 2: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; if (gfc->sv_qnt.substep_shaping == 0) gfc->sv_qnt.substep_shaping = 2; cfg->noise_shaping_amp = 1; cfg->noise_shaping_stop = 1; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 1; /* inner loop */ cfg->full_outer_loop = 0; break; case 1: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; if (gfc->sv_qnt.substep_shaping == 0) gfc->sv_qnt.substep_shaping = 2; cfg->noise_shaping_amp = 2; cfg->noise_shaping_stop = 1; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 1; cfg->full_outer_loop = 0; break; case 0: if (cfg->noise_shaping == 0) cfg->noise_shaping = 1; if (gfc->sv_qnt.substep_shaping == 0) gfc->sv_qnt.substep_shaping = 2; cfg->noise_shaping_amp = 2; cfg->noise_shaping_stop = 1; if (cfg->subblock_gain == -1) cfg->subblock_gain = 1; cfg->use_best_huffman = 1; /*type 2 disabled because of it slowness, in favor of full outer loop search */ cfg->full_outer_loop = 1; break; } } static double linear_int(double a, double b, double m) { return a + m * (b - a); } /******************************************************************** * initialize internal params based on data in gf * (globalflags struct filled in by calling program) * * OUTLINE: * * We first have some complex code to determine bitrate, * output samplerate and mode. It is complicated by the fact * that we allow the user to set some or all of these parameters, * and need to determine best possible values for the rest of them: * * 1. set some CPU related flags * 2. check if we are mono->mono, stereo->mono or stereo->stereo * 3. compute bitrate and output samplerate: * user may have set compression ratio * user may have set a bitrate * user may have set a output samplerate * 4. set some options which depend on output samplerate * 5. compute the actual compression ratio * 6. set mode based on compression ratio * * The remaining code is much simpler - it just sets options * based on the mode & compression ratio: * * set allow_diff_short based on mode * select lowpass filter based on compression ratio & mode * set the bitrate index, and min/max bitrates for VBR modes * disable VBR tag if it is not appropriate * initialize the bitstream * initialize scalefac_band data * set sideinfo_len (based on channels, CRC, out_samplerate) * write an id3v2 tag into the bitstream * write VBR tag into the bitstream * set mpeg1/2 flag * estimate the number of frames (based on a lot of data) * * now we set more flags: * nspsytune: * see code * VBR modes * see code * CBR/ABR * see code * * Finally, we set the algorithm flags based on the gfp->quality value * lame_init_qval(gfp); * ********************************************************************/ int lame_init_params(lame_global_flags * gfp) { int i; int j; lame_internal_flags *const gfc = gfp->internal_flags; SessionConfig_t *const cfg = &gfc->cfg; gfc->class_id = 0; cfg->enforce_min_bitrate = gfp->VBR_hard_min; cfg->analysis = gfp->analysis; if (cfg->analysis) gfp->write_lame_tag = 0; /* some file options not allowed if output is: not specified or stdout */ if (gfc->pinfo != NULL) gfp->write_lame_tag = 0; /* disable Xing VBR tag */ /* report functions */ gfc->report_msg = gfp->report.msgf; gfc->report_dbg = gfp->report.debugf; gfc->report_err = gfp->report.errorf; if (gfp->asm_optimizations.amd3dnow) gfc->CPU_features.AMD_3DNow = has_3DNow(); else gfc->CPU_features.AMD_3DNow = 0; if (gfp->asm_optimizations.mmx) gfc->CPU_features.MMX = has_MMX(); else gfc->CPU_features.MMX = 0; if (gfp->asm_optimizations.sse) { gfc->CPU_features.SSE = has_SSE(); gfc->CPU_features.SSE2 = has_SSE2(); } else { gfc->CPU_features.SSE = 0; gfc->CPU_features.SSE2 = 0; } if (NULL == gfc->ATH) gfc->ATH = calloc(1, sizeof(ATH_t)); if (NULL == gfc->ATH) return -2; /* maybe error codes should be enumerated in lame.h ?? */ if (NULL == gfc->sv_rpg.rgdata) gfc->sv_rpg.rgdata = calloc(1, sizeof(replaygain_t)); if (NULL == gfc->sv_rpg.rgdata) { freegfc(gfc); gfp->internal_flags = NULL; return -2; } cfg->error_protection = gfp->error_protection; cfg->copyright = gfp->copyright; cfg->original = gfp->original; cfg->extension = gfp->extension; cfg->emphasis = gfp->emphasis; cfg->channels_in = gfp->num_channels; if (cfg->channels_in == 1) gfp->mode = MONO; cfg->channels_out = (gfp->mode == MONO) ? 1 : 2; if (gfp->mode == MONO) gfp->force_ms = 0; /* don't allow forced mid/side stereo for mono output */ cfg->force_ms = gfp->force_ms; if (gfp->VBR == vbr_off && gfp->VBR_mean_bitrate_kbps != 128 && gfp->brate == 0) gfp->brate = gfp->VBR_mean_bitrate_kbps; switch (gfp->VBR) { case vbr_off: case vbr_mtrh: case vbr_mt: /* these modes can handle free format condition */ break; default: gfp->free_format = 0; /* mode can't be mixed with free format */ break; } cfg->free_format = gfp->free_format; if (gfp->VBR == vbr_off && gfp->brate == 0) { /* no bitrate or compression ratio specified, use 11.025 */ if (EQ(gfp->compression_ratio, 0)) gfp->compression_ratio = 11.025; /* rate to compress a CD down to exactly 128000 bps */ } /* find bitrate if user specify a compression ratio */ if (gfp->VBR == vbr_off && gfp->compression_ratio > 0) { if (gfp->samplerate_out == 0) gfp->samplerate_out = map2MP3Frequency((int) (0.97 * gfp->samplerate_in)); /* round up with a margin of 3% */ /* choose a bitrate for the output samplerate which achieves * specified compression ratio */ gfp->brate = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->compression_ratio); /* we need the version for the bitrate table look up */ cfg->samplerate_index = SmpFrqIndex(gfp->samplerate_out, &cfg->version); if (!cfg->free_format) /* for non Free Format find the nearest allowed bitrate */ gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, gfp->samplerate_out); } if (gfp->samplerate_out) { if (gfp->samplerate_out < 16000) { gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8); gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 64); } else if (gfp->samplerate_out < 32000) { gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8); gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 160); } else { gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 32); gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 320); } } /* WORK IN PROGRESS */ /* mapping VBR scale to internal VBR quality settings */ if (gfp->samplerate_out == 0 && (gfp->VBR == vbr_mt || gfp->VBR == vbr_mtrh)) { float const qval = gfp->VBR_q + gfp->VBR_q_frac; struct q_map { int sr_a; float qa, qb, ta, tb; int lp; }; struct q_map const m[9] = { {48000, 0.0,6.5, 0.0,6.5, 23700} , {44100, 0.0,6.5, 0.0,6.5, 21780} , {32000, 6.5,8.0, 5.2,6.5, 15800} , {24000, 8.0,8.5, 5.2,6.0, 11850} , {22050, 8.5,9.01, 5.2,6.5, 10892} , {16000, 9.01,9.4, 4.9,6.5, 7903} , {12000, 9.4,9.6, 4.5,6.0, 5928} , {11025, 9.6,9.9, 5.1,6.5, 5446} , { 8000, 9.9,10., 4.9,6.5, 3952} }; for (i = 2; i < 9; ++i) { if (gfp->samplerate_in == m[i].sr_a) { if (qval < m[i].qa) { double d = qval / m[i].qa; d = d * m[i].ta; gfp->VBR_q = (int)d; gfp->VBR_q_frac = d - gfp->VBR_q; } } if (gfp->samplerate_in >= m[i].sr_a) { if (m[i].qa <= qval && qval < m[i].qb) { float const q_ = m[i].qb-m[i].qa; float const t_ = m[i].tb-m[i].ta; double d = m[i].ta + t_ * (qval-m[i].qa) / q_; gfp->VBR_q = (int)d; gfp->VBR_q_frac = d - gfp->VBR_q; gfp->samplerate_out = m[i].sr_a; if (gfp->lowpassfreq == 0) { gfp->lowpassfreq = -1; } break; } } } } /****************************************************************/ /* if a filter has not been enabled, see if we should add one: */ /****************************************************************/ if (gfp->lowpassfreq == 0) { double lowpass = 16000; double highpass; switch (gfp->VBR) { case vbr_off:{ optimum_bandwidth(&lowpass, &highpass, gfp->brate); break; } case vbr_abr:{ optimum_bandwidth(&lowpass, &highpass, gfp->VBR_mean_bitrate_kbps); break; } case vbr_rh:{ int const x[11] = { 19500, 19000, 18600, 18000, 17500, 16000, 15600, 14900, 12500, 10000, 3950 }; if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) { double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac; lowpass = linear_int(a, b, m); } else { lowpass = 19500; } break; } case vbr_mtrh: case vbr_mt:{ int const x[11] = { 24000, 19500, 18500, 18000, 17500, 17000, 16500, 15600, 15200, 7230, 3950 }; if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) { double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac; lowpass = linear_int(a, b, m); } else { lowpass = 21500; } break; } default:{ int const x[11] = { 19500, 19000, 18500, 18000, 17500, 16500, 15500, 14500, 12500, 9500, 3950 }; if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) { double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac; lowpass = linear_int(a, b, m); } else { lowpass = 19500; } } } if (gfp->mode == MONO && (gfp->VBR == vbr_off || gfp->VBR == vbr_abr)) lowpass *= 1.5; gfp->lowpassfreq = lowpass; } if (gfp->samplerate_out == 0) { if (2 * gfp->lowpassfreq > gfp->samplerate_in) { gfp->lowpassfreq = gfp->samplerate_in / 2; } gfp->samplerate_out = optimum_samplefreq((int) gfp->lowpassfreq, gfp->samplerate_in); } if (gfp->VBR == vbr_mt || gfp->VBR == vbr_mtrh) { gfp->lowpassfreq = Min(24000, gfp->lowpassfreq); } else { gfp->lowpassfreq = Min(20500, gfp->lowpassfreq); } gfp->lowpassfreq = Min(gfp->samplerate_out / 2, gfp->lowpassfreq); if (gfp->VBR == vbr_off) { gfp->compression_ratio = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate); } if (gfp->VBR == vbr_abr) { gfp->compression_ratio = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps); } /* do not compute ReplayGain values and do not find the peak sample if we can't store them */ if (!gfp->write_lame_tag) { gfp->findReplayGain = 0; gfp->decode_on_the_fly = 0; cfg->findPeakSample = 0; } cfg->findReplayGain = gfp->findReplayGain; cfg->decode_on_the_fly = gfp->decode_on_the_fly; if (cfg->decode_on_the_fly) cfg->findPeakSample = 1; if (cfg->findReplayGain) { if (InitGainAnalysis(gfc->sv_rpg.rgdata, gfp->samplerate_out) == INIT_GAIN_ANALYSIS_ERROR) { freegfc(gfc); gfp->internal_flags = NULL; return -6; } } #ifdef DECODE_ON_THE_FLY if (cfg->decode_on_the_fly && !gfp->decode_only) { if (gfc->hip) { hip_decode_exit(gfc->hip); } gfc->hip = hip_decode_init(); /* report functions */ hip_set_errorf(gfc->hip, gfp->report.errorf); hip_set_debugf(gfc->hip, gfp->report.debugf); hip_set_msgf(gfc->hip, gfp->report.msgf); } #endif cfg->disable_reservoir = gfp->disable_reservoir; cfg->lowpassfreq = gfp->lowpassfreq; cfg->highpassfreq = gfp->highpassfreq; cfg->samplerate_in = gfp->samplerate_in; cfg->samplerate_out = gfp->samplerate_out; cfg->mode_gr = cfg->samplerate_out <= 24000 ? 1 : 2; /* Number of granules per frame */ gfc->ov_enc.encoder_delay = ENCDELAY; /* * sample freq bitrate compression ratio * [kHz] [kbps/channel] for 16 bit input * 44.1 56 12.6 * 44.1 64 11.025 * 44.1 80 8.82 * 22.05 24 14.7 * 22.05 32 11.025 * 22.05 40 8.82 * 16 16 16.0 * 16 24 10.667 * */ /* * For VBR, take a guess at the compression_ratio. * For example: * * VBR_q compression like * - 4.4 320 kbps/44 kHz * 0...1 5.5 256 kbps/44 kHz * 2 7.3 192 kbps/44 kHz * 4 8.8 160 kbps/44 kHz * 6 11 128 kbps/44 kHz * 9 14.7 96 kbps * * for lower bitrates, downsample with --resample */ switch (gfp->VBR) { case vbr_mt: case vbr_rh: case vbr_mtrh: { /*numbers are a bit strange, but they determine the lowpass value */ FLOAT const cmp[] = { 5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, 15, 16.5 }; gfp->compression_ratio = cmp[gfp->VBR_q]; } break; case vbr_abr: gfp->compression_ratio = cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps); break; default: gfp->compression_ratio = cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate); break; } /* mode = -1 (not set by user) or * mode = MONO (because of only 1 input channel). * If mode has not been set, then select J-STEREO */ if (gfp->mode == NOT_SET) { gfp->mode = JOINT_STEREO; } cfg->mode = gfp->mode; /* apply user driven high pass filter */ if (cfg->highpassfreq > 0) { cfg->highpass1 = 2. * cfg->highpassfreq; if (gfp->highpasswidth >= 0) cfg->highpass2 = 2. * (cfg->highpassfreq + gfp->highpasswidth); else /* 0% above on default */ cfg->highpass2 = (1 + 0.00) * 2. * cfg->highpassfreq; cfg->highpass1 /= cfg->samplerate_out; cfg->highpass2 /= cfg->samplerate_out; } else { cfg->highpass1 = 0; cfg->highpass2 = 0; } /* apply user driven low pass filter */ cfg->lowpass1 = 0; cfg->lowpass2 = 0; if (cfg->lowpassfreq > 0 && cfg->lowpassfreq < (cfg->samplerate_out / 2) ) { cfg->lowpass2 = 2. * cfg->lowpassfreq; if (gfp->lowpasswidth >= 0) { cfg->lowpass1 = 2. * (cfg->lowpassfreq - gfp->lowpasswidth); if (cfg->lowpass1 < 0) /* has to be >= 0 */ cfg->lowpass1 = 0; } else { /* 0% below on default */ cfg->lowpass1 = (1 - 0.00) * 2. * cfg->lowpassfreq; } cfg->lowpass1 /= cfg->samplerate_out; cfg->lowpass2 /= cfg->samplerate_out; } /**********************************************************************/ /* compute info needed for polyphase filter (filter type==0, default) */ /**********************************************************************/ lame_init_params_ppflt(gfc); /******************************************************* * samplerate and bitrate index *******************************************************/ cfg->samplerate_index = SmpFrqIndex(cfg->samplerate_out, &cfg->version); if (cfg->samplerate_index < 0) { freegfc(gfc); gfp->internal_flags = NULL; return -1; } if (gfp->VBR == vbr_off) { if (cfg->free_format) { gfc->ov_enc.bitrate_index = 0; } else { gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, cfg->samplerate_out); gfc->ov_enc.bitrate_index = BitrateIndex(gfp->brate, cfg->version, cfg->samplerate_out); if (gfc->ov_enc.bitrate_index <= 0) { freegfc(gfc); gfp->internal_flags = NULL; return -1; } } } else { gfc->ov_enc.bitrate_index = 1; } init_bit_stream_w(gfc); j = cfg->samplerate_index + (3 * cfg->version) + 6 * (cfg->samplerate_out < 16000); for (i = 0; i < SBMAX_l + 1; i++) gfc->scalefac_band.l[i] = sfBandIndex[j].l[i]; for (i = 0; i < PSFB21 + 1; i++) { int const size = (gfc->scalefac_band.l[22] - gfc->scalefac_band.l[21]) / PSFB21; int const start = gfc->scalefac_band.l[21] + i * size; gfc->scalefac_band.psfb21[i] = start; } gfc->scalefac_band.psfb21[PSFB21] = 576; for (i = 0; i < SBMAX_s + 1; i++) gfc->scalefac_band.s[i] = sfBandIndex[j].s[i]; for (i = 0; i < PSFB12 + 1; i++) { int const size = (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) / PSFB12; int const start = gfc->scalefac_band.s[12] + i * size; gfc->scalefac_band.psfb12[i] = start; } gfc->scalefac_band.psfb12[PSFB12] = 192; /* determine the mean bitrate for main data */ if (cfg->mode_gr == 2) /* MPEG 1 */ cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 17 : 4 + 32; else /* MPEG 2 */ cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 9 : 4 + 17; if (cfg->error_protection) cfg->sideinfo_len += 2; gfc->class_id = LAME_ID; { int k; for (k = 0; k < 19; k++) gfc->sv_enc.pefirbuf[k] = 700 * cfg->mode_gr * cfg->channels_out; if (gfp->ATHtype == -1) gfp->ATHtype = 4; } assert(gfp->VBR_q <= 9); assert(gfp->VBR_q >= 0); switch (gfp->VBR) { case vbr_mt: case vbr_mtrh:{ if (gfp->strict_ISO < 0) { gfp->strict_ISO = MDB_MAXIMUM; } if (gfp->useTemporal < 0) { gfp->useTemporal = 0; /* off by default for this VBR mode */ } (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0); /* The newer VBR code supports only a limited subset of quality levels: 9-5=5 are the same, uses x^3/4 quantization 4-0=0 are the same 5 plus best huffman divide code */ if (gfp->quality < 0) gfp->quality = LAME_DEFAULT_QUALITY; if (gfp->quality < 5) gfp->quality = 0; if (gfp->quality > 7) gfp->quality = 7; /* sfb21 extra only with MPEG-1 at higher sampling rates */ if (gfp->experimentalY) gfc->sv_qnt.sfb21_extra = 0; else gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000); gfc->iteration_loop = VBR_new_iteration_loop; break; } case vbr_rh:{ (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0); /* sfb21 extra only with MPEG-1 at higher sampling rates */ if (gfp->experimentalY) gfc->sv_qnt.sfb21_extra = 0; else gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000); /* VBR needs at least the output of GPSYCHO, * so we have to garantee that by setting a minimum * quality level, actually level 6 does it. * down to level 6 */ if (gfp->quality > 6) gfp->quality = 6; if (gfp->quality < 0) gfp->quality = LAME_DEFAULT_QUALITY; gfc->iteration_loop = VBR_old_iteration_loop; break; } default: /* cbr/abr */ { vbr_mode vbrmode; /* no sfb21 extra with CBR code */ gfc->sv_qnt.sfb21_extra = 0; if (gfp->quality < 0) gfp->quality = LAME_DEFAULT_QUALITY; vbrmode = gfp->VBR; if (vbrmode == vbr_off) (void) lame_set_VBR_mean_bitrate_kbps(gfp, gfp->brate); /* second, set parameters depending on bitrate */ (void) apply_preset(gfp, gfp->VBR_mean_bitrate_kbps, 0); gfp->VBR = vbrmode; if (vbrmode == vbr_off) { gfc->iteration_loop = CBR_iteration_loop; } else { gfc->iteration_loop = ABR_iteration_loop; } break; } } /*initialize default values common for all modes */ gfc->sv_qnt.mask_adjust = gfp->maskingadjust; gfc->sv_qnt.mask_adjust_short = gfp->maskingadjust_short; /* just another daily changing developer switch */ if (gfp->tune) { gfc->sv_qnt.mask_adjust += gfp->tune_value_a; gfc->sv_qnt.mask_adjust_short += gfp->tune_value_a; } if (gfp->VBR != vbr_off) { /* choose a min/max bitrate for VBR */ /* if the user didn't specify VBR_max_bitrate: */ cfg->vbr_min_bitrate_index = 1; /* default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1) */ cfg->vbr_max_bitrate_index = 14; /* default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) */ if (cfg->samplerate_out < 16000) cfg->vbr_max_bitrate_index = 8; /* default: allow 64 kbps (MPEG-2.5) */ if (gfp->VBR_min_bitrate_kbps) { gfp->VBR_min_bitrate_kbps = FindNearestBitrate(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out); cfg->vbr_min_bitrate_index = BitrateIndex(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out); if (cfg->vbr_min_bitrate_index < 0) return -1; } if (gfp->VBR_max_bitrate_kbps) { gfp->VBR_max_bitrate_kbps = FindNearestBitrate(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out); cfg->vbr_max_bitrate_index = BitrateIndex(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out); if (cfg->vbr_max_bitrate_index < 0) return -1; } gfp->VBR_min_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index]; gfp->VBR_max_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_max_bitrate_index]; gfp->VBR_mean_bitrate_kbps = Min(bitrate_table[cfg->version][cfg->vbr_max_bitrate_index], gfp->VBR_mean_bitrate_kbps); gfp->VBR_mean_bitrate_kbps = Max(bitrate_table[cfg->version][cfg->vbr_min_bitrate_index], gfp->VBR_mean_bitrate_kbps); } cfg->preset = gfp->preset; cfg->write_lame_tag = gfp->write_lame_tag; cfg->vbr = gfp->VBR; gfc->sv_qnt.substep_shaping = gfp->substep_shaping; cfg->noise_shaping = gfp->noise_shaping; cfg->subblock_gain = gfp->subblock_gain; cfg->use_best_huffman = gfp->use_best_huffman; cfg->avg_bitrate = gfp->brate; cfg->vbr_avg_bitrate_kbps = gfp->VBR_mean_bitrate_kbps; cfg->compression_ratio = gfp->compression_ratio; /* initialize internal qval settings */ lame_init_qval(gfp); /* automatic ATH adjustment on */ if (gfp->athaa_type < 0) gfc->ATH->use_adjust = 3; else gfc->ATH->use_adjust = gfp->athaa_type; /* initialize internal adaptive ATH settings -jd */ gfc->ATH->aa_sensitivity_p = pow(10.0, gfp->athaa_sensitivity / -10.0); if (gfp->short_blocks == short_block_not_set) { gfp->short_blocks = short_block_allowed; } /*Note Jan/2003: Many hardware decoders cannot handle short blocks in regular stereo mode unless they are coupled (same type in both channels) it is a rare event (1 frame per min. or so) that LAME would use uncoupled short blocks, so lets turn them off until we decide how to handle this. No other encoders allow uncoupled short blocks, even though it is in the standard. */ /* rh 20040217: coupling makes no sense for mono and dual-mono streams */ if (gfp->short_blocks == short_block_allowed && (cfg->mode == JOINT_STEREO || cfg->mode == STEREO)) { gfp->short_blocks = short_block_coupled; } cfg->short_blocks = gfp->short_blocks; if (lame_get_quant_comp(gfp) < 0) (void) lame_set_quant_comp(gfp, 1); if (lame_get_quant_comp_short(gfp) < 0) (void) lame_set_quant_comp_short(gfp, 0); if (lame_get_msfix(gfp) < 0) lame_set_msfix(gfp, 0); /* select psychoacoustic model */ (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1); if (gfp->ATHtype < 0) gfp->ATHtype = 4; if (gfp->ATHcurve < 0) gfp->ATHcurve = 4; if (gfp->interChRatio < 0) gfp->interChRatio = 0; if (gfp->useTemporal < 0) gfp->useTemporal = 1; /* on by default */ cfg->interChRatio = gfp->interChRatio; cfg->msfix = gfp->msfix; cfg->ATH_offset_db = 0-gfp->ATH_lower_db; cfg->ATH_offset_factor = powf(10.f, cfg->ATH_offset_db * 0.1f); cfg->ATHcurve = gfp->ATHcurve; cfg->ATHtype = gfp->ATHtype; cfg->ATHonly = gfp->ATHonly; cfg->ATHshort = gfp->ATHshort; cfg->noATH = gfp->noATH; cfg->quant_comp = gfp->quant_comp; cfg->quant_comp_short = gfp->quant_comp_short; cfg->use_temporal_masking_effect = gfp->useTemporal; cfg->use_safe_joint_stereo = gfp->exp_nspsytune & 2; { cfg->adjust_bass_db = (gfp->exp_nspsytune >> 2) & 63; if (cfg->adjust_bass_db >= 32.f) cfg->adjust_bass_db -= 64.f; cfg->adjust_bass_db *= 0.25f; cfg->adjust_alto_db = (gfp->exp_nspsytune >> 8) & 63; if (cfg->adjust_alto_db >= 32.f) cfg->adjust_alto_db -= 64.f; cfg->adjust_alto_db *= 0.25f; cfg->adjust_treble_db = (gfp->exp_nspsytune >> 14) & 63; if (cfg->adjust_treble_db >= 32.f) cfg->adjust_treble_db -= 64.f; cfg->adjust_treble_db *= 0.25f; /* to be compatible with Naoki's original code, the next 6 bits * define only the amount of changing treble for sfb21 */ cfg->adjust_sfb21_db = (gfp->exp_nspsytune >> 20) & 63; if (cfg->adjust_sfb21_db >= 32.f) cfg->adjust_sfb21_db -= 64.f; cfg->adjust_sfb21_db *= 0.25f; cfg->adjust_sfb21_db += cfg->adjust_treble_db; } /* Setting up the PCM input data transform matrix, to apply * user defined re-scaling, and or two-to-one channel downmix. */ { FLOAT m[2][2] = { {1.0f, 0.0f}, {0.0f, 1.0f} }; /* user selected scaling of the samples */ m[0][0] *= gfp->scale; m[0][1] *= gfp->scale; m[1][0] *= gfp->scale; m[1][1] *= gfp->scale; /* user selected scaling of the channel 0 (left) samples */ m[0][0] *= gfp->scale_left; m[0][1] *= gfp->scale_left; /* user selected scaling of the channel 1 (right) samples */ m[1][0] *= gfp->scale_right; m[1][1] *= gfp->scale_right; /* Downsample to Mono if 2 channels in and 1 channel out */ if (cfg->channels_in == 2 && cfg->channels_out == 1) { m[0][0] = 0.5f * (m[0][0] + m[1][0]); m[0][1] = 0.5f * (m[0][1] + m[1][1]); m[1][0] = 0; m[1][1] = 0; } cfg->pcm_transform[0][0] = m[0][0]; cfg->pcm_transform[0][1] = m[0][1]; cfg->pcm_transform[1][0] = m[1][0]; cfg->pcm_transform[1][1] = m[1][1]; } /* padding method as described in * "MPEG-Layer3 / Bitstream Syntax and Decoding" * by Martin Sieler, Ralph Sperschneider * * note: there is no padding for the very first frame * * Robert Hegemann 2000-06-22 */ gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF = 0; if (cfg->vbr == vbr_off) gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF = ((cfg->version + 1) * 72000L * cfg->avg_bitrate) % cfg->samplerate_out; (void) lame_init_bitstream(gfp); iteration_init(gfc); (void) psymodel_init(gfp); cfg->buffer_constraint = get_max_frame_buffer_size_by_constraint(cfg, gfp->strict_ISO); return 0; } static void concatSep(char* dest, char const* sep, char const* str) { if (*dest != 0) strcat(dest, sep); strcat(dest, str); } /* * print_config * * Prints some selected information about the coding parameters via * the macro command MSGF(), which is currently mapped to lame_errorf * (reports via a error function?), which is a printf-like function * for . */ void lame_print_config(const lame_global_flags * gfp) { lame_internal_flags const *const gfc = gfp->internal_flags; SessionConfig_t const *const cfg = &gfc->cfg; double const out_samplerate = cfg->samplerate_out; double const in_samplerate = cfg->samplerate_in; MSGF(gfc, "LAME %s %s (%s)\n", get_lame_version(), get_lame_os_bitness(), get_lame_url()); #if (LAME_ALPHA_VERSION) MSGF(gfc, "warning: alpha versions should be used for testing only\n"); #endif if (gfc->CPU_features.MMX || gfc->CPU_features.AMD_3DNow || gfc->CPU_features.SSE || gfc->CPU_features.SSE2) { char text[256] = { 0 }; int fft_asm_used = 0; #ifdef HAVE_NASM if (gfc->CPU_features.AMD_3DNow) { fft_asm_used = 1; } else if (gfc->CPU_features.SSE) { fft_asm_used = 2; } #else # if defined( HAVE_XMMINTRIN_H ) && defined( MIN_ARCH_SSE ) { fft_asm_used = 3; } # endif #endif if (gfc->CPU_features.MMX) { #ifdef MMX_choose_table concatSep(text, ", ", "MMX (ASM used)"); #else concatSep(text, ", ", "MMX"); #endif } if (gfc->CPU_features.AMD_3DNow) { concatSep(text, ", ", (fft_asm_used == 1) ? "3DNow! (ASM used)" : "3DNow!"); } if (gfc->CPU_features.SSE) { #if defined(HAVE_XMMINTRIN_H) concatSep(text, ", ", "SSE (ASM used)"); #else concatSep(text, ", ", (fft_asm_used == 2) ? "SSE (ASM used)" : "SSE"); #endif } if (gfc->CPU_features.SSE2) { concatSep(text, ", ", (fft_asm_used == 3) ? "SSE2 (ASM used)" : "SSE2"); } MSGF(gfc, "CPU features: %s\n", text); } if (cfg->channels_in == 2 && cfg->channels_out == 1 /* mono */ ) { MSGF(gfc, "Autoconverting from stereo to mono. Setting encoding to mono mode.\n"); } if (isResamplingNecessary(cfg)) { MSGF(gfc, "Resampling: input %g kHz output %g kHz\n", 1.e-3 * in_samplerate, 1.e-3 * out_samplerate); } if (cfg->highpass2 > 0.) MSGF(gfc, "Using polyphase highpass filter, transition band: %5.0f Hz - %5.0f Hz\n", 0.5 * cfg->highpass1 * out_samplerate, 0.5 * cfg->highpass2 * out_samplerate); if (0. < cfg->lowpass1 || 0. < cfg->lowpass2) { MSGF(gfc, "Using polyphase lowpass filter, transition band: %5.0f Hz - %5.0f Hz\n", 0.5 * cfg->lowpass1 * out_samplerate, 0.5 * cfg->lowpass2 * out_samplerate); } else { MSGF(gfc, "polyphase lowpass filter disabled\n"); } if (cfg->free_format) { MSGF(gfc, "Warning: many decoders cannot handle free format bitstreams\n"); if (cfg->avg_bitrate > 320) { MSGF(gfc, "Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)\n"); } } } /** rh: * some pretty printing is very welcome at this point! * so, if someone is willing to do so, please do it! * add more, if you see more... */ void lame_print_internals(const lame_global_flags * gfp) { lame_internal_flags const *const gfc = gfp->internal_flags; SessionConfig_t const *const cfg = &gfc->cfg; const char *pc = ""; /* compiler/processor optimizations, operational, etc. */ MSGF(gfc, "\nmisc:\n\n"); MSGF(gfc, "\tscaling: %g\n", gfp->scale); MSGF(gfc, "\tch0 (left) scaling: %g\n", gfp->scale_left); MSGF(gfc, "\tch1 (right) scaling: %g\n", gfp->scale_right); switch (cfg->use_best_huffman) { default: pc = "normal"; break; case 1: pc = "best (outside loop)"; break; case 2: pc = "best (inside loop, slow)"; break; } MSGF(gfc, "\thuffman search: %s\n", pc); MSGF(gfc, "\texperimental Y=%d\n", gfp->experimentalY); MSGF(gfc, "\t...\n"); /* everything controlling the stream format */ MSGF(gfc, "\nstream format:\n\n"); switch (cfg->version) { case 0: pc = "2.5"; break; case 1: pc = "1"; break; case 2: pc = "2"; break; default: pc = "?"; break; } MSGF(gfc, "\tMPEG-%s Layer 3\n", pc); switch (cfg->mode) { case JOINT_STEREO: pc = "joint stereo"; break; case STEREO: pc = "stereo"; break; case DUAL_CHANNEL: pc = "dual channel"; break; case MONO: pc = "mono"; break; case NOT_SET: pc = "not set (error)"; break; default: pc = "unknown (error)"; break; } MSGF(gfc, "\t%d channel - %s\n", cfg->channels_out, pc); switch (cfg->vbr) { case vbr_off: pc = "off"; break; default: pc = "all"; break; } MSGF(gfc, "\tpadding: %s\n", pc); if (vbr_default == cfg->vbr) pc = "(default)"; else if (cfg->free_format) pc = "(free format)"; else pc = ""; switch (cfg->vbr) { case vbr_off: MSGF(gfc, "\tconstant bitrate - CBR %s\n", pc); break; case vbr_abr: MSGF(gfc, "\tvariable bitrate - ABR %s\n", pc); break; case vbr_rh: MSGF(gfc, "\tvariable bitrate - VBR rh %s\n", pc); break; case vbr_mt: MSGF(gfc, "\tvariable bitrate - VBR mt %s\n", pc); break; case vbr_mtrh: MSGF(gfc, "\tvariable bitrate - VBR mtrh %s\n", pc); break; default: MSGF(gfc, "\t ?? oops, some new one ?? \n"); break; } if (cfg->write_lame_tag) MSGF(gfc, "\tusing LAME Tag\n"); MSGF(gfc, "\t...\n"); /* everything controlling psychoacoustic settings, like ATH, etc. */ MSGF(gfc, "\npsychoacoustic:\n\n"); switch (cfg->short_blocks) { default: case short_block_not_set: pc = "?"; break; case short_block_allowed: pc = "allowed"; break; case short_block_coupled: pc = "channel coupled"; break; case short_block_dispensed: pc = "dispensed"; break; case short_block_forced: pc = "forced"; break; } MSGF(gfc, "\tusing short blocks: %s\n", pc); MSGF(gfc, "\tsubblock gain: %d\n", cfg->subblock_gain); MSGF(gfc, "\tadjust masking: %g dB\n", gfc->sv_qnt.mask_adjust); MSGF(gfc, "\tadjust masking short: %g dB\n", gfc->sv_qnt.mask_adjust_short); MSGF(gfc, "\tquantization comparison: %d\n", cfg->quant_comp); MSGF(gfc, "\t ^ comparison short blocks: %d\n", cfg->quant_comp_short); MSGF(gfc, "\tnoise shaping: %d\n", cfg->noise_shaping); MSGF(gfc, "\t ^ amplification: %d\n", cfg->noise_shaping_amp); MSGF(gfc, "\t ^ stopping: %d\n", cfg->noise_shaping_stop); pc = "using"; if (cfg->ATHshort) pc = "the only masking for short blocks"; if (cfg->ATHonly) pc = "the only masking"; if (cfg->noATH) pc = "not used"; MSGF(gfc, "\tATH: %s\n", pc); MSGF(gfc, "\t ^ type: %d\n", cfg->ATHtype); MSGF(gfc, "\t ^ shape: %g%s\n", cfg->ATHcurve, " (only for type 4)"); MSGF(gfc, "\t ^ level adjustement: %g dB\n", cfg->ATH_offset_db); MSGF(gfc, "\t ^ adjust type: %d\n", gfc->ATH->use_adjust); MSGF(gfc, "\t ^ adjust sensitivity power: %f\n", gfc->ATH->aa_sensitivity_p); MSGF(gfc, "\texperimental psy tunings by Naoki Shibata\n"); MSGF(gfc, "\t adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\n", 10 * log10(gfc->sv_qnt.longfact[0]), 10 * log10(gfc->sv_qnt.longfact[7]), 10 * log10(gfc->sv_qnt.longfact[14]), 10 * log10(gfc->sv_qnt.longfact[21])); pc = cfg->use_temporal_masking_effect ? "yes" : "no"; MSGF(gfc, "\tusing temporal masking effect: %s\n", pc); MSGF(gfc, "\tinterchannel masking ratio: %g\n", cfg->interChRatio); MSGF(gfc, "\t...\n"); /* that's all ? */ MSGF(gfc, "\n"); return; } static void save_gain_values(lame_internal_flags * gfc) { SessionConfig_t const *const cfg = &gfc->cfg; RpgStateVar_t const *const rsv = &gfc->sv_rpg; RpgResult_t *const rov = &gfc->ov_rpg; /* save the ReplayGain value */ if (cfg->findReplayGain) { FLOAT const RadioGain = (FLOAT) GetTitleGain(rsv->rgdata); if (NEQ(RadioGain, GAIN_NOT_ENOUGH_SAMPLES)) { rov->RadioGain = (int) floor(RadioGain * 10.0 + 0.5); /* round to nearest */ } else { rov->RadioGain = 0; } } /* find the gain and scale change required for no clipping */ if (cfg->findPeakSample) { rov->noclipGainChange = (int) ceil(log10(rov->PeakSample / 32767.0) * 20.0 * 10.0); /* round up */ if (rov->noclipGainChange > 0) { /* clipping occurs */ rov->noclipScale = floor((32767.0f / rov->PeakSample) * 100.0f) / 100.0f; /* round down */ } else /* no clipping */ rov->noclipScale = -1.0f; } } static int update_inbuffer_size(lame_internal_flags * gfc, const int nsamples) { EncStateVar_t *const esv = &gfc->sv_enc; if (esv->in_buffer_0 == 0 || esv->in_buffer_nsamples < nsamples) { if (esv->in_buffer_0) { free(esv->in_buffer_0); } if (esv->in_buffer_1) { free(esv->in_buffer_1); } esv->in_buffer_0 = calloc(nsamples, sizeof(sample_t)); esv->in_buffer_1 = calloc(nsamples, sizeof(sample_t)); esv->in_buffer_nsamples = nsamples; } if (esv->in_buffer_0 == NULL || esv->in_buffer_1 == NULL) { if (esv->in_buffer_0) { free(esv->in_buffer_0); } if (esv->in_buffer_1) { free(esv->in_buffer_1); } esv->in_buffer_0 = 0; esv->in_buffer_1 = 0; esv->in_buffer_nsamples = 0; ERRORF(gfc, "Error: can't allocate in_buffer buffer\n"); return -2; } return 0; } static int calcNeeded(SessionConfig_t const * cfg) { int mf_needed; int pcm_samples_per_frame = 576 * cfg->mode_gr; /* some sanity checks */ #if ENCDELAY < MDCTDELAY # error ENCDELAY is less than MDCTDELAY, see encoder.h #endif #if FFTOFFSET > BLKSIZE # error FFTOFFSET is greater than BLKSIZE, see encoder.h #endif mf_needed = BLKSIZE + pcm_samples_per_frame - FFTOFFSET; /* amount needed for FFT */ /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */ mf_needed = Max(mf_needed, 512 + pcm_samples_per_frame - 32); assert(MFSIZE >= mf_needed); return mf_needed; } /* * THE MAIN LAME ENCODING INTERFACE * mt 3/00 * * input pcm data, output (maybe) mp3 frames. * This routine handles all buffering, resampling and filtering for you. * The required mp3buffer_size can be computed from num_samples, * samplerate and encoding rate, but here is a worst case estimate: * * mp3buffer_size in bytes = 1.25*num_samples + 7200 * * return code = number of bytes output in mp3buffer. can be 0 * * NOTE: this routine uses LAME's internal PCM data representation, * 'sample_t'. It should not be used by any application. * applications should use lame_encode_buffer(), * lame_encode_buffer_float() * lame_encode_buffer_int() * etc... depending on what type of data they are working with. */ static int lame_encode_buffer_sample_t(lame_internal_flags * gfc, int nsamples, unsigned char *mp3buf, const int mp3buf_size) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int pcm_samples_per_frame = 576 * cfg->mode_gr; int mp3size = 0, ret, i, ch, mf_needed; int mp3out; sample_t *mfbuf[2]; sample_t *in_buffer[2]; if (gfc->class_id != LAME_ID) return -3; if (nsamples == 0) return 0; /* copy out any tags that may have been written into bitstream */ mp3out = copy_buffer(gfc, mp3buf, mp3buf_size, 0); if (mp3out < 0) return mp3out; /* not enough buffer space */ mp3buf += mp3out; mp3size += mp3out; in_buffer[0] = esv->in_buffer_0; in_buffer[1] = esv->in_buffer_1; mf_needed = calcNeeded(cfg); mfbuf[0] = esv->mfbuf[0]; mfbuf[1] = esv->mfbuf[1]; while (nsamples > 0) { sample_t const *in_buffer_ptr[2]; int n_in = 0; /* number of input samples processed with fill_buffer */ int n_out = 0; /* number of samples output with fill_buffer */ /* n_in <> n_out if we are resampling */ in_buffer_ptr[0] = in_buffer[0]; in_buffer_ptr[1] = in_buffer[1]; /* copy in new samples into mfbuf, with resampling */ fill_buffer(gfc, mfbuf, &in_buffer_ptr[0], nsamples, &n_in, &n_out); /* compute ReplayGain of resampled input if requested */ if (cfg->findReplayGain && !cfg->decode_on_the_fly) if (AnalyzeSamples (gfc->sv_rpg.rgdata, &mfbuf[0][esv->mf_size], &mfbuf[1][esv->mf_size], n_out, cfg->channels_out) == GAIN_ANALYSIS_ERROR) return -6; /* update in_buffer counters */ nsamples -= n_in; in_buffer[0] += n_in; if (cfg->channels_out == 2) in_buffer[1] += n_in; /* update mfbuf[] counters */ esv->mf_size += n_out; assert(esv->mf_size <= MFSIZE); /* lame_encode_flush may have set gfc->mf_sample_to_encode to 0 * so we have to reinitialize it here when that happened. */ if (esv->mf_samples_to_encode < 1) { esv->mf_samples_to_encode = ENCDELAY + POSTDELAY; } esv->mf_samples_to_encode += n_out; if (esv->mf_size >= mf_needed) { /* encode the frame. */ /* mp3buf = pointer to current location in buffer */ /* mp3buf_size = size of original mp3 output buffer */ /* = 0 if we should not worry about the */ /* buffer size because calling program is */ /* to lazy to compute it */ /* mp3size = size of data written to buffer so far */ /* mp3buf_size-mp3size = amount of space avalable */ int buf_size = mp3buf_size - mp3size; if (mp3buf_size == 0) buf_size = 0; ret = lame_encode_mp3_frame(gfc, mfbuf[0], mfbuf[1], mp3buf, buf_size); if (ret < 0) return ret; mp3buf += ret; mp3size += ret; /* shift out old samples */ esv->mf_size -= pcm_samples_per_frame; esv->mf_samples_to_encode -= pcm_samples_per_frame; for (ch = 0; ch < cfg->channels_out; ch++) for (i = 0; i < esv->mf_size; i++) mfbuf[ch][i] = mfbuf[ch][i + pcm_samples_per_frame]; } } assert(nsamples == 0); return mp3size; } enum PCMSampleType { pcm_short_type , pcm_int_type , pcm_long_type , pcm_float_type , pcm_double_type }; static void lame_copy_inbuffer(lame_internal_flags* gfc, void const* l, void const* r, int nsamples, enum PCMSampleType pcm_type, int jump, FLOAT s) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; sample_t* ib0 = esv->in_buffer_0; sample_t* ib1 = esv->in_buffer_1; FLOAT m[2][2]; /* Apply user defined re-scaling */ m[0][0] = s * cfg->pcm_transform[0][0]; m[0][1] = s * cfg->pcm_transform[0][1]; m[1][0] = s * cfg->pcm_transform[1][0]; m[1][1] = s * cfg->pcm_transform[1][1]; /* make a copy of input buffer, changing type to sample_t */ #define COPY_AND_TRANSFORM(T) \ { \ T const *bl = l, *br = r; \ int i; \ for (i = 0; i < nsamples; i++) { \ sample_t const xl = *bl; \ sample_t const xr = *br; \ sample_t const u = xl * m[0][0] + xr * m[0][1]; \ sample_t const v = xl * m[1][0] + xr * m[1][1]; \ ib0[i] = u; \ ib1[i] = v; \ bl += jump; \ br += jump; \ } \ } switch ( pcm_type ) { case pcm_short_type: COPY_AND_TRANSFORM(short int); break; case pcm_int_type: COPY_AND_TRANSFORM(int); break; case pcm_long_type: COPY_AND_TRANSFORM(long int); break; case pcm_float_type: COPY_AND_TRANSFORM(float); break; case pcm_double_type: COPY_AND_TRANSFORM(double); break; } } static int lame_encode_buffer_template(lame_global_flags * gfp, void const* buffer_l, void const* buffer_r, const int nsamples, unsigned char *mp3buf, const int mp3buf_size, enum PCMSampleType pcm_type, int aa, FLOAT norm) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; if (nsamples == 0) return 0; if (update_inbuffer_size(gfc, nsamples) != 0) { return -2; } /* make a copy of input buffer, changing type to sample_t */ if (cfg->channels_in > 1) { if (buffer_l == 0 || buffer_r == 0) { return 0; } lame_copy_inbuffer(gfc, buffer_l, buffer_r, nsamples, pcm_type, aa, norm); } else { if (buffer_l == 0) { return 0; } lame_copy_inbuffer(gfc, buffer_l, buffer_l, nsamples, pcm_type, aa, norm); } return lame_encode_buffer_sample_t(gfc, nsamples, mp3buf, mp3buf_size); } } return -3; } int lame_encode_buffer(lame_global_flags * gfp, const short int pcm_l[], const short int pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_short_type, 1, 1.0); } int lame_encode_buffer_float(lame_global_flags * gfp, const float pcm_l[], const float pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- 32768 for full scale */ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 1.0); } int lame_encode_buffer_ieee_float(lame_t gfp, const float pcm_l[], const float pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- 1.0 for full scale */ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 32767.0); } int lame_encode_buffer_interleaved_ieee_float(lame_t gfp, const float pcm[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- 1.0 for full scale */ return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_float_type, 2, 32767.0); } int lame_encode_buffer_ieee_double(lame_t gfp, const double pcm_l[], const double pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- 1.0 for full scale */ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_double_type, 1, 32767.0); } int lame_encode_buffer_interleaved_ieee_double(lame_t gfp, const double pcm[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- 1.0 for full scale */ return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_double_type, 2, 32767.0); } int lame_encode_buffer_int(lame_global_flags * gfp, const int pcm_l[], const int pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- MAX_INT for full scale */ FLOAT const norm = (1.0 / (1L << (8 * sizeof(int) - 16))); return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_int_type, 1, norm); } int lame_encode_buffer_long2(lame_global_flags * gfp, const long pcm_l[], const long pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- MAX_LONG for full scale */ FLOAT const norm = (1.0 / (1L << (8 * sizeof(long) - 16))); return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, norm); } int lame_encode_buffer_long(lame_global_flags * gfp, const long pcm_l[], const long pcm_r[], const int nsamples, unsigned char *mp3buf, const int mp3buf_size) { /* input is assumed to be normalized to +/- 32768 for full scale */ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, 1.0); } int lame_encode_buffer_interleaved(lame_global_flags * gfp, short int pcm[], int nsamples, unsigned char *mp3buf, int mp3buf_size) { /* input is assumed to be normalized to +/- MAX_SHORT for full scale */ return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_short_type, 2, 1.0); } /***************************************************************** Flush mp3 buffer, pad with ancillary data so last frame is complete. Reset reservoir size to 0 but keep all PCM samples and MDCT data in memory This option is used to break a large file into several mp3 files that when concatenated together will decode with no gaps Because we set the reservoir=0, they will also decode seperately with no errors. *********************************************************************/ int lame_encode_flush_nogap(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size) { int rc = -3; if (is_lame_global_flags_valid(gfp)) { lame_internal_flags *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { flush_bitstream(gfc); rc = copy_buffer(gfc, mp3buffer, mp3buffer_size, 1); save_gain_values(gfc); } } return rc; } /* called by lame_init_params. You can also call this after flush_nogap if you want to write new id3v2 and Xing VBR tags into the bitstream */ int lame_init_bitstream(lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags *const gfc = gfp->internal_flags; if (gfc != 0) { gfc->ov_enc.frame_number = 0; if (gfp->write_id3tag_automatic) { (void) id3tag_write_v2(gfp); } /* initialize histogram data optionally used by frontend */ memset(gfc->ov_enc.bitrate_channelmode_hist, 0, sizeof(gfc->ov_enc.bitrate_channelmode_hist)); memset(gfc->ov_enc.bitrate_blocktype_hist, 0, sizeof(gfc->ov_enc.bitrate_blocktype_hist)); gfc->ov_rpg.PeakSample = 0.0; /* Write initial VBR Header to bitstream and init VBR data */ if (gfc->cfg.write_lame_tag) (void) InitVbrTag(gfp); return 0; } } return -3; } /*****************************************************************/ /* flush internal PCM sample buffers, then mp3 buffers */ /* then write id3 v1 tags into bitstream. */ /*****************************************************************/ int lame_encode_flush(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size) { lame_internal_flags *gfc; SessionConfig_t const *cfg; EncStateVar_t *esv; short int buffer[2][1152]; int imp3 = 0, mp3count, mp3buffer_size_remaining; /* we always add POSTDELAY=288 padding to make sure granule with real * data can be complety decoded (because of 50% overlap with next granule */ int end_padding; int frames_left; int samples_to_encode; int pcm_samples_per_frame; int mf_needed; int is_resampling_necessary; double resample_ratio = 1; if (!is_lame_global_flags_valid(gfp)) { return -3; } gfc = gfp->internal_flags; if (!is_lame_internal_flags_valid(gfc)) { return -3; } cfg = &gfc->cfg; esv = &gfc->sv_enc; /* Was flush already called? */ if (esv->mf_samples_to_encode < 1) { return 0; } pcm_samples_per_frame = 576 * cfg->mode_gr; mf_needed = calcNeeded(cfg); samples_to_encode = esv->mf_samples_to_encode - POSTDELAY; memset(buffer, 0, sizeof(buffer)); mp3count = 0; is_resampling_necessary = isResamplingNecessary(cfg); if (is_resampling_necessary) { resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out; /* delay due to resampling; needs to be fixed, if resampling code gets changed */ samples_to_encode += 16. / resample_ratio; } end_padding = pcm_samples_per_frame - (samples_to_encode % pcm_samples_per_frame); if (end_padding < 576) end_padding += pcm_samples_per_frame; gfc->ov_enc.encoder_padding = end_padding; frames_left = (samples_to_encode + end_padding) / pcm_samples_per_frame; while (frames_left > 0 && imp3 >= 0) { int const frame_num = gfc->ov_enc.frame_number; int bunch = mf_needed - esv->mf_size; bunch *= resample_ratio; if (bunch > 1152) bunch = 1152; if (bunch < 1) bunch = 1; mp3buffer_size_remaining = mp3buffer_size - mp3count; /* if user specifed buffer size = 0, dont check size */ if (mp3buffer_size == 0) mp3buffer_size_remaining = 0; /* send in a frame of 0 padding until all internal sample buffers * are flushed */ imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], bunch, mp3buffer, mp3buffer_size_remaining); mp3buffer += imp3; mp3count += imp3; frames_left -= ((frame_num != gfc->ov_enc.frame_number) ? 1 : 0); } /* Set esv->mf_samples_to_encode to 0, so we may detect * and break loops calling it more than once in a row. */ esv->mf_samples_to_encode = 0; if (imp3 < 0) { /* some type of fatal error */ return imp3; } mp3buffer_size_remaining = mp3buffer_size - mp3count; /* if user specifed buffer size = 0, dont check size */ if (mp3buffer_size == 0) mp3buffer_size_remaining = 0; /* mp3 related stuff. bit buffer might still contain some mp3 data */ flush_bitstream(gfc); imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 1); save_gain_values(gfc); if (imp3 < 0) { /* some type of fatal error */ return imp3; } mp3buffer += imp3; mp3count += imp3; mp3buffer_size_remaining = mp3buffer_size - mp3count; /* if user specifed buffer size = 0, dont check size */ if (mp3buffer_size == 0) mp3buffer_size_remaining = 0; if (gfp->write_id3tag_automatic) { /* write a id3 tag to the bitstream */ (void) id3tag_write_v1(gfp); imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 0); if (imp3 < 0) { return imp3; } mp3count += imp3; } #if 0 { int const ed = gfc->ov_enc.encoder_delay; int const ep = gfc->ov_enc.encoder_padding; int const ns = (gfc->ov_enc.frame_number * pcm_samples_per_frame) - (ed + ep); double duration = ns; duration /= cfg->samplerate_out; MSGF(gfc, "frames=%d\n", gfc->ov_enc.frame_number); MSGF(gfc, "pcm_samples_per_frame=%d\n", pcm_samples_per_frame); MSGF(gfc, "encoder delay=%d\n", ed); MSGF(gfc, "encoder padding=%d\n", ep); MSGF(gfc, "sample count=%d (%g)\n", ns, cfg->samplerate_in * duration); MSGF(gfc, "duration=%g sec\n", duration); } #endif return mp3count; } /*********************************************************************** * * lame_close () * * frees internal buffers * ***********************************************************************/ int lame_close(lame_global_flags * gfp) { int ret = 0; if (gfp && gfp->class_id == LAME_ID) { lame_internal_flags *const gfc = gfp->internal_flags; gfp->class_id = 0; if (NULL == gfc || gfc->class_id != LAME_ID) { ret = -3; } if (NULL != gfc) { gfc->class_id = 0; /* this routine will free all malloc'd data in gfc, and then free gfc: */ freegfc(gfc); gfp->internal_flags = NULL; } if (gfp->lame_allocated_gfp) { gfp->lame_allocated_gfp = 0; free(gfp); } } return ret; } /*****************************************************************/ /* flush internal mp3 buffers, and free internal buffers */ /*****************************************************************/ #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED int CDECL lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size); #else #endif int lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size) { int const ret = lame_encode_flush(gfp, mp3buffer, mp3buffer_size); (void) lame_close(gfp); return ret; } /*****************************************************************/ /* write VBR Xing header, and ID3 version 1 tag, if asked for */ /*****************************************************************/ void lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream); void lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream) { lame_internal_flags *gfc; SessionConfig_t const *cfg; if (!is_lame_global_flags_valid(gfp)) { return; } gfc = gfp->internal_flags; if (!is_lame_internal_flags_valid(gfc)) { return; } cfg = &gfc->cfg; if (!cfg->write_lame_tag) { return; } /* Write Xing header again */ if (fpStream && !fseek(fpStream, 0, SEEK_SET)) { int rc = PutVbrTag(gfp, fpStream); switch (rc) { default: /* OK */ break; case -1: ERRORF(gfc, "Error: could not update LAME tag.\n"); break; case -2: ERRORF(gfc, "Error: could not update LAME tag, file not seekable.\n"); break; case -3: ERRORF(gfc, "Error: could not update LAME tag, file not readable.\n"); break; } } } /* initialize mp3 encoder */ #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED static #else #endif int lame_init_old(lame_global_flags * gfp) { lame_internal_flags *gfc; SessionConfig_t *cfg; disable_FPE(); /* disable floating point exceptions */ memset(gfp, 0, sizeof(lame_global_flags)); gfp->class_id = LAME_ID; if (NULL == (gfc = gfp->internal_flags = calloc(1, sizeof(lame_internal_flags)))) return -1; cfg = &gfc->cfg; /* Global flags. set defaults here for non-zero values */ /* see lame.h for description */ /* set integer values to -1 to mean that LAME will compute the * best value, UNLESS the calling program as set it * (and the value is no longer -1) */ gfp->strict_ISO = MDB_MAXIMUM; gfp->mode = NOT_SET; gfp->original = 1; gfp->samplerate_in = 44100; gfp->num_channels = 2; gfp->num_samples = MAX_U_32_NUM; gfp->write_lame_tag = 1; gfp->quality = -1; gfp->short_blocks = short_block_not_set; gfp->subblock_gain = -1; gfp->lowpassfreq = 0; gfp->highpassfreq = 0; gfp->lowpasswidth = -1; gfp->highpasswidth = -1; gfp->VBR = vbr_off; gfp->VBR_q = 4; gfp->ATHcurve = -1; gfp->VBR_mean_bitrate_kbps = 128; gfp->VBR_min_bitrate_kbps = 0; gfp->VBR_max_bitrate_kbps = 0; gfp->VBR_hard_min = 0; cfg->vbr_min_bitrate_index = 1; /* not 0 ????? */ cfg->vbr_max_bitrate_index = 13; /* not 14 ????? */ gfp->quant_comp = -1; gfp->quant_comp_short = -1; gfp->msfix = -1; gfc->sv_qnt.OldValue[0] = 180; gfc->sv_qnt.OldValue[1] = 180; gfc->sv_qnt.CurrentStep[0] = 4; gfc->sv_qnt.CurrentStep[1] = 4; gfc->sv_qnt.masking_lower = 1; gfp->attackthre = -1; gfp->attackthre_s = -1; gfp->scale = 1; gfp->scale_left = 1; gfp->scale_right = 1; gfp->athaa_type = -1; gfp->ATHtype = -1; /* default = -1 = set in lame_init_params */ /* 2 = equal loudness curve */ gfp->athaa_sensitivity = 0.0; /* no offset */ gfp->useTemporal = -1; gfp->interChRatio = -1; /* The reason for * int mf_samples_to_encode = ENCDELAY + POSTDELAY; * ENCDELAY = internal encoder delay. And then we have to add POSTDELAY=288 * because of the 50% MDCT overlap. A 576 MDCT granule decodes to * 1152 samples. To synthesize the 576 samples centered under this granule * we need the previous granule for the first 288 samples (no problem), and * the next granule for the next 288 samples (not possible if this is last * granule). So we need to pad with 288 samples to make sure we can * encode the 576 samples we are interested in. */ gfc->sv_enc.mf_samples_to_encode = ENCDELAY + POSTDELAY; gfc->ov_enc.encoder_padding = 0; gfc->sv_enc.mf_size = ENCDELAY - MDCTDELAY; /* we pad input with this many 0's */ gfp->findReplayGain = 0; gfp->decode_on_the_fly = 0; gfc->cfg.decode_on_the_fly = 0; gfc->cfg.findReplayGain = 0; gfc->cfg.findPeakSample = 0; gfc->ov_rpg.RadioGain = 0; gfc->ov_rpg.noclipGainChange = 0; gfc->ov_rpg.noclipScale = -1.0; gfp->asm_optimizations.mmx = 1; gfp->asm_optimizations.amd3dnow = 1; gfp->asm_optimizations.sse = 1; gfp->preset = 0; gfp->write_id3tag_automatic = 1; gfp->report.debugf = &lame_report_def; gfp->report.errorf = &lame_report_def; gfp->report.msgf = &lame_report_def; return 0; } lame_global_flags * lame_init(void) { lame_global_flags *gfp; int ret; init_log_table(); gfp = calloc(1, sizeof(lame_global_flags)); if (gfp == NULL) return NULL; ret = lame_init_old(gfp); if (ret != 0) { free(gfp); return NULL; } gfp->lame_allocated_gfp = 1; return gfp; } /*********************************************************************** * * some simple statistics * * Robert Hegemann 2000-10-11 * ***********************************************************************/ /* histogram of used bitrate indexes: * One has to weight them to calculate the average bitrate in kbps * * bitrate indices: * there are 14 possible bitrate indices, 0 has the special meaning * "free format" which is not possible to mix with VBR and 15 is forbidden * anyway. * * stereo modes: * 0: LR number of left-right encoded frames * 1: LR-I number of left-right and intensity encoded frames * 2: MS number of mid-side encoded frames * 3: MS-I number of mid-side and intensity encoded frames * * 4: number of encoded frames * */ void lame_bitrate_kbps(const lame_global_flags * gfp, int bitrate_kbps[14]) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; int i; if (cfg->free_format) { for (i = 0; i < 14; i++) bitrate_kbps[i] = -1; bitrate_kbps[0] = cfg->avg_bitrate; } else { for (i = 0; i < 14; i++) bitrate_kbps[i] = bitrate_table[cfg->version][i + 1]; } } } } void lame_bitrate_hist(const lame_global_flags * gfp, int bitrate_count[14]) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t const *const eov = &gfc->ov_enc; int i; if (cfg->free_format) { for (i = 0; i < 14; i++) { bitrate_count[i] = 0; } bitrate_count[0] = eov->bitrate_channelmode_hist[0][4]; } else { for (i = 0; i < 14; i++) { bitrate_count[i] = eov->bitrate_channelmode_hist[i + 1][4]; } } } } } void lame_stereo_mode_hist(const lame_global_flags * gfp, int stmode_count[4]) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { EncResult_t const *const eov = &gfc->ov_enc; int i; for (i = 0; i < 4; i++) { stmode_count[i] = eov->bitrate_channelmode_hist[15][i]; } } } } void lame_bitrate_stereo_mode_hist(const lame_global_flags * gfp, int bitrate_stmode_count[14][4]) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t const *const eov = &gfc->ov_enc; int i; int j; if (cfg->free_format) { for (j = 0; j < 14; j++) for (i = 0; i < 4; i++) { bitrate_stmode_count[j][i] = 0; } for (i = 0; i < 4; i++) { bitrate_stmode_count[0][i] = eov->bitrate_channelmode_hist[0][i]; } } else { for (j = 0; j < 14; j++) { for (i = 0; i < 4; i++) { bitrate_stmode_count[j][i] = eov->bitrate_channelmode_hist[j + 1][i]; } } } } } } void lame_block_type_hist(const lame_global_flags * gfp, int btype_count[6]) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { EncResult_t const *const eov = &gfc->ov_enc; int i; for (i = 0; i < 6; ++i) { btype_count[i] = eov->bitrate_blocktype_hist[15][i]; } } } } void lame_bitrate_block_type_hist(const lame_global_flags * gfp, int bitrate_btype_count[14][6]) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t const *const eov = &gfc->ov_enc; int i, j; if (cfg->free_format) { for (j = 0; j < 14; ++j) { for (i = 0; i < 6; ++i) { bitrate_btype_count[j][i] = 0; } } for (i = 0; i < 6; ++i) { bitrate_btype_count[0][i] = eov->bitrate_blocktype_hist[0][i]; } } else { for (j = 0; j < 14; ++j) { for (i = 0; i < 6; ++i) { bitrate_btype_count[j][i] = eov->bitrate_blocktype_hist[j + 1][i]; } } } } } } /* end of lame.c */ ================================================ FILE: app/jni/libmp3lame/lame_global_flags.h ================================================ #ifndef LAME_GLOBAL_FLAGS_H #define LAME_GLOBAL_FLAGS_H #ifndef lame_internal_flags_defined #define lame_internal_flags_defined struct lame_internal_flags; typedef struct lame_internal_flags lame_internal_flags; #endif typedef enum short_block_e { short_block_not_set = -1, /* allow LAME to decide */ short_block_allowed = 0, /* LAME may use them, even different block types for L/R */ short_block_coupled, /* LAME may use them, but always same block types in L/R */ short_block_dispensed, /* LAME will not use short blocks, long blocks only */ short_block_forced /* LAME will not use long blocks, short blocks only */ } short_block_t; /*********************************************************************** * * Control Parameters set by User. These parameters are here for * backwards compatibility with the old, non-shared lib API. * Please use the lame_set_variablename() functions below * * ***********************************************************************/ struct lame_global_struct { unsigned int class_id; /* input description */ unsigned long num_samples; /* number of samples. default=2^32-1 */ int num_channels; /* input number of channels. default=2 */ int samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz */ int samplerate_out; /* output_samp_rate. default: LAME picks best value at least not used for MP3 decoding: Remember 44.1 kHz MP3s and AC97 */ float scale; /* scale input by this amount before encoding at least not used for MP3 decoding */ float scale_left; /* scale input of channel 0 (left) by this amount before encoding */ float scale_right; /* scale input of channel 1 (right) by this amount before encoding */ /* general control params */ int analysis; /* collect data for a MP3 frame analyzer? */ int write_lame_tag; /* add Xing VBR tag? */ int decode_only; /* use lame/mpglib to convert mp3 to wav */ int quality; /* quality setting 0=best, 9=worst default=5 */ MPEG_mode mode; /* see enum in lame.h default = LAME picks best value */ int force_ms; /* force M/S mode. requires mode=1 */ int free_format; /* use free format? default=0 */ int findReplayGain; /* find the RG value? default=0 */ int decode_on_the_fly; /* decode on the fly? default=0 */ int write_id3tag_automatic; /* 1 (default) writes ID3 tags, 0 not */ int nogap_total; int nogap_current; int substep_shaping; int noise_shaping; int subblock_gain; /* 0 = no, 1 = yes */ int use_best_huffman; /* 0 = no. 1=outside loop 2=inside loop(slow) */ /* * set either brate>0 or compression_ratio>0, LAME will compute * the value of the variable not set. * Default is compression_ratio = 11.025 */ int brate; /* bitrate */ float compression_ratio; /* sizeof(wav file)/sizeof(mp3 file) */ /* frame params */ int copyright; /* mark as copyright. default=0 */ int original; /* mark as original. default=1 */ int extension; /* the MP3 'private extension' bit. Meaningless */ int emphasis; /* Input PCM is emphased PCM (for instance from one of the rarely emphased CDs), it is STRONGLY not recommended to use this, because psycho does not take it into account, and last but not least many decoders don't care about these bits */ int error_protection; /* use 2 bytes per frame for a CRC checksum. default=0 */ int strict_ISO; /* enforce ISO spec as much as possible */ int disable_reservoir; /* use bit reservoir? */ /* quantization/noise shaping */ int quant_comp; int quant_comp_short; int experimentalY; int experimentalZ; int exp_nspsytune; int preset; /* VBR control */ vbr_mode VBR; float VBR_q_frac; /* Range [0,...,1[ */ int VBR_q; /* Range [0,...,9] */ int VBR_mean_bitrate_kbps; int VBR_min_bitrate_kbps; int VBR_max_bitrate_kbps; int VBR_hard_min; /* strictly enforce VBR_min_bitrate normaly, it will be violated for analog silence */ /* resampling and filtering */ int lowpassfreq; /* freq in Hz. 0=lame choses. -1=no filter */ int highpassfreq; /* freq in Hz. 0=lame choses. -1=no filter */ int lowpasswidth; /* freq width of filter, in Hz (default=15%) */ int highpasswidth; /* freq width of filter, in Hz (default=15%) */ /* * psycho acoustics and other arguments which you should not change * unless you know what you are doing */ float maskingadjust; float maskingadjust_short; int ATHonly; /* only use ATH */ int ATHshort; /* only use ATH for short blocks */ int noATH; /* disable ATH */ int ATHtype; /* select ATH formula */ float ATHcurve; /* change ATH formula 4 shape */ float ATH_lower_db; /* lower ATH by this many db */ int athaa_type; /* select ATH auto-adjust scheme */ float athaa_sensitivity; /* dB, tune active region of auto-level */ short_block_t short_blocks; int useTemporal; /* use temporal masking effect */ float interChRatio; float msfix; /* Naoki's adjustment of Mid/Side maskings */ int tune; /* 0 off, 1 on */ float tune_value_a; /* used to pass values for debugging and stuff */ float attackthre; /* attack threshold for L/R/M channel */ float attackthre_s; /* attack threshold for S channel */ struct { void (*msgf) (const char *format, va_list ap); void (*debugf) (const char *format, va_list ap); void (*errorf) (const char *format, va_list ap); } report; /************************************************************************/ /* internal variables, do not set... */ /* provided because they may be of use to calling application */ /************************************************************************/ int lame_allocated_gfp; /* is this struct owned by calling program or lame? */ /**************************************************************************/ /* more internal variables are stored in this structure: */ /**************************************************************************/ lame_internal_flags *internal_flags; struct { int mmx; int amd3dnow; int sse; } asm_optimizations; }; int is_lame_global_flags_valid(const lame_global_flags * gfp); #endif /* LAME_GLOBAL_FLAGS_H */ ================================================ FILE: app/jni/libmp3lame/lameerror.h ================================================ /* * A collection of LAME Error Codes * * Please use the constants defined here instead of some arbitrary * values. Currently the values starting at -10 to avoid intersection * with the -1, -2, -3 and -4 used in the current code. * * May be this should be a part of the include/lame.h. */ typedef enum { LAME_OKAY = 0, LAME_NOERROR = 0, LAME_GENERICERROR = -1, LAME_NOMEM = -10, LAME_BADBITRATE = -11, LAME_BADSAMPFREQ = -12, LAME_INTERNALERROR = -13, FRONTEND_READERROR = -80, FRONTEND_WRITEERROR = -81, FRONTEND_FILETOOLARGE = -82, } lame_errorcodes_t; /* end of lameerror.h */ ================================================ FILE: app/jni/libmp3lame/machine.h ================================================ /* * Machine dependent defines/includes for LAME. * * Copyright (c) 1999 A.L. Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_MACHINE_H #define LAME_MACHINE_H #include "version.h" #if (LAME_RELEASE_VERSION == 0) #undef NDEBUG #endif #include #include #include #ifdef STDC_HEADERS # include # include #else # ifndef HAVE_STRCHR # define strchr index # define strrchr rindex # endif char *strchr(), *strrchr(); # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # define memmove(d, s, n) bcopy ((s), (d), (n)) # endif #endif #if defined(__riscos__) && defined(FPA10) # include "ymath.h" #else # include #endif #include #include #ifdef HAVE_ERRNO_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #if defined(macintosh) # include # include #else # include # include #endif #ifdef HAVE_INTTYPES_H # include #else # ifdef HAVE_STDINT_H # include # endif #endif #ifdef WITH_DMALLOC #include #endif /* * 3 different types of pow() functions: * - table lookup * - pow() * - exp() on some machines this is claimed to be faster than pow() */ #define POW20(x) (assert(0 <= (x+Q_MAX2) && x < Q_MAX), pow20[x+Q_MAX2]) /*#define POW20(x) pow(2.0,((double)(x)-210)*.25) */ /*#define POW20(x) exp( ((double)(x)-210)*(.25*LOG2) ) */ #define IPOW20(x) (assert(0 <= x && x < Q_MAX), ipow20[x]) /*#define IPOW20(x) exp( -((double)(x)-210)*.1875*LOG2 ) */ /*#define IPOW20(x) pow(2.0,-((double)(x)-210)*.1875) */ /* in case this is used without configure */ #ifndef inline # define inline #endif #if defined(_MSC_VER) # undef inline # define inline _inline #elif defined(__SASC) || defined(__GNUC__) || defined(__ICC) || defined(__ECC) /* if __GNUC__ we always want to inline, not only if the user requests it */ # undef inline # define inline __inline #endif #if defined(_MSC_VER) # pragma warning( disable : 4244 ) /*# pragma warning( disable : 4305 ) */ #endif /* * FLOAT for variables which require at least 32 bits * FLOAT8 for variables which require at least 64 bits * * On some machines, 64 bit will be faster than 32 bit. Also, some math * routines require 64 bit float, so setting FLOAT=float will result in a * lot of conversions. */ #if ( defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) ) # define WIN32_LEAN_AND_MEAN # include # include # define FLOAT_MAX FLT_MAX #else # ifndef FLOAT typedef float FLOAT; # ifdef FLT_MAX # define FLOAT_MAX FLT_MAX # else # define FLOAT_MAX 1e37 /* approx */ # endif # endif #endif #ifndef FLOAT8 typedef double FLOAT8; # ifdef DBL_MAX # define FLOAT8_MAX DBL_MAX # else # define FLOAT8_MAX 1e99 /* approx */ # endif #else # ifdef FLT_MAX # define FLOAT8_MAX FLT_MAX # else # define FLOAT8_MAX 1e37 /* approx */ # endif #endif /* sample_t must be floating point, at least 32 bits */ typedef FLOAT sample_t; #define dimension_of(array) (sizeof(array)/sizeof(array[0])) #define beyond(array) (array+dimension_of(array)) #define compiletime_assert(expression) extern char static_assert_##FILE##_##LINE[expression?1:0] #if 1 #define EQ(a,b) (\ (fabs(a) > fabs((float)b)) \ ? (fabs((float)((a)-(b))) <= (fabs((float)a) * 1e-6f)) \ : (fabs((float)((a)-(b))) <= (fabs((float)b) * 1e-6f))) #else #define EQ(a,b) (fabs((a)-(b))<1E-37) #endif #define NEQ(a,b) (!EQ(a,b)) #endif #ifdef _MSC_VER # if _MSC_VER < 1400 # define fabsf fabs # define powf pow # define log10f log10 # endif #endif /* end of machine.h */ ================================================ FILE: app/jni/libmp3lame/mpglib_interface.c ================================================ /* -*- mode: C; mode: fold -*- */ /* * LAME MP3 encoding engine * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 2003 Olcios * Copyright (c) 2008 Robert Hegemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: mpglib_interface.c,v 1.42 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_MPGLIB #define hip_global_struct mpstr_tag #include "lame.h" #include "machine.h" #include "encoder.h" #include "interface.h" #include "util.h" #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED /* * OBSOLETE: * - kept to let it link * - forward declaration to silence compiler */ int CDECL lame_decode_init(void); int CDECL lame_decode( unsigned char * mp3buf, int len, short pcm_l[], short pcm_r[] ); int CDECL lame_decode_headers( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[], mp3data_struct* mp3data ); int CDECL lame_decode1( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[] ); int CDECL lame_decode1_headers( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[], mp3data_struct* mp3data ); int CDECL lame_decode1_headersB( unsigned char* mp3buf, int len, short pcm_l[], short pcm_r[], mp3data_struct* mp3data, int *enc_delay, int *enc_padding ); int CDECL lame_decode_exit(void); #endif static MPSTR mp; int lame_decode_exit(void) { ExitMP3(&mp); return 0; } int lame_decode_init(void) { (void) InitMP3(&mp); return 0; } /* copy mono samples */ #define COPY_MONO(DST_TYPE, SRC_TYPE) \ DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw; \ SRC_TYPE const *p_samples = (SRC_TYPE const *)p; \ for (i = 0; i < processed_samples; i++) \ *pcm_l++ = (DST_TYPE)(*p_samples++); /* copy stereo samples */ #define COPY_STEREO(DST_TYPE, SRC_TYPE) \ DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw, *pcm_r = (DST_TYPE *)pcm_r_raw; \ SRC_TYPE const *p_samples = (SRC_TYPE const *)p; \ for (i = 0; i < processed_samples; i++) { \ *pcm_l++ = (DST_TYPE)(*p_samples++); \ *pcm_r++ = (DST_TYPE)(*p_samples++); \ } /* * For lame_decode: return code * -1 error * 0 ok, but need more data before outputing any samples * n number of samples output. either 576 or 1152 depending on MP3 file. */ static int decode1_headersB_clipchoice(PMPSTR pmp, unsigned char *buffer, int len, char pcm_l_raw[], char pcm_r_raw[], mp3data_struct * mp3data, int *enc_delay, int *enc_padding, char *p, size_t psize, int decoded_sample_size, int (*decodeMP3_ptr) (PMPSTR, unsigned char *, int, char *, int, int *)) { static const int smpls[2][4] = { /* Layer I II III */ {0, 384, 1152, 1152}, /* MPEG-1 */ {0, 384, 1152, 576} /* MPEG-2(.5) */ }; int processed_bytes; int processed_samples; /* processed samples per channel */ int ret; int i; mp3data->header_parsed = 0; ret = (*decodeMP3_ptr) (pmp, buffer, len, p, (int) psize, &processed_bytes); /* three cases: * 1. headers parsed, but data not complete * pmp->header_parsed==1 * pmp->framesize=0 * pmp->fsizeold=size of last frame, or 0 if this is first frame * * 2. headers, data parsed, but ancillary data not complete * pmp->header_parsed==1 * pmp->framesize=size of frame * pmp->fsizeold=size of last frame, or 0 if this is first frame * * 3. frame fully decoded: * pmp->header_parsed==0 * pmp->framesize=0 * pmp->fsizeold=size of frame (which is now the last frame) * */ if (pmp->header_parsed || pmp->fsizeold > 0 || pmp->framesize > 0) { mp3data->header_parsed = 1; mp3data->stereo = pmp->fr.stereo; mp3data->samplerate = freqs[pmp->fr.sampling_frequency]; mp3data->mode = pmp->fr.mode; mp3data->mode_ext = pmp->fr.mode_ext; mp3data->framesize = smpls[pmp->fr.lsf][pmp->fr.lay]; /* free format, we need the entire frame before we can determine * the bitrate. If we haven't gotten the entire frame, bitrate=0 */ if (pmp->fsizeold > 0) /* works for free format and fixed, no overrun, temporal results are < 400.e6 */ mp3data->bitrate = 8 * (4 + pmp->fsizeold) * mp3data->samplerate / (1.e3 * mp3data->framesize) + 0.5; else if (pmp->framesize > 0) mp3data->bitrate = 8 * (4 + pmp->framesize) * mp3data->samplerate / (1.e3 * mp3data->framesize) + 0.5; else mp3data->bitrate = tabsel_123[pmp->fr.lsf][pmp->fr.lay - 1][pmp->fr.bitrate_index]; if (pmp->num_frames > 0) { /* Xing VBR header found and num_frames was set */ mp3data->totalframes = pmp->num_frames; mp3data->nsamp = mp3data->framesize * pmp->num_frames; *enc_delay = pmp->enc_delay; *enc_padding = pmp->enc_padding; } } switch (ret) { case MP3_OK: switch (pmp->fr.stereo) { case 1: processed_samples = processed_bytes / decoded_sample_size; if (decoded_sample_size == sizeof(short)) { COPY_MONO(short, short) } else { COPY_MONO(sample_t, FLOAT) } break; case 2: processed_samples = (processed_bytes / decoded_sample_size) >> 1; if (decoded_sample_size == sizeof(short)) { COPY_STEREO(short, short) } else { COPY_STEREO(sample_t, FLOAT) } break; default: processed_samples = -1; assert(0); break; } break; case MP3_NEED_MORE: processed_samples = 0; break; case MP3_ERR: processed_samples = -1; break; default: processed_samples = -1; assert(0); break; } /*fprintf(stderr,"ok, more, err: %i %i %i\n", MP3_OK, MP3_NEED_MORE, MP3_ERR ); */ /*fprintf(stderr,"ret = %i out=%i\n", ret, processed_samples ); */ return processed_samples; } #define OUTSIZE_CLIPPED (4096*sizeof(short)) int lame_decode1_headersB(unsigned char *buffer, int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data, int *enc_delay, int *enc_padding) { static char out[OUTSIZE_CLIPPED]; return decode1_headersB_clipchoice(&mp, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data, enc_delay, enc_padding, out, OUTSIZE_CLIPPED, sizeof(short), decodeMP3); } /* * For lame_decode: return code * -1 error * 0 ok, but need more data before outputing any samples * n number of samples output. Will be at most one frame of * MPEG data. */ int lame_decode1_headers(unsigned char *buffer, int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) { int enc_delay, enc_padding; return lame_decode1_headersB(buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding); } int lame_decode1(unsigned char *buffer, int len, short pcm_l[], short pcm_r[]) { mp3data_struct mp3data; return lame_decode1_headers(buffer, len, pcm_l, pcm_r, &mp3data); } /* * For lame_decode: return code * -1 error * 0 ok, but need more data before outputing any samples * n number of samples output. a multiple of 576 or 1152 depending on MP3 file. */ int lame_decode_headers(unsigned char *buffer, int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) { int ret; int totsize = 0; /* number of decoded samples per channel */ for (;;) { switch (ret = lame_decode1_headers(buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) { case -1: return ret; case 0: return totsize; default: totsize += ret; len = 0; /* future calls to decodeMP3 are just to flush buffers */ break; } } } int lame_decode(unsigned char *buffer, int len, short pcm_l[], short pcm_r[]) { mp3data_struct mp3data; return lame_decode_headers(buffer, len, pcm_l, pcm_r, &mp3data); } hip_t hip_decode_init(void) { hip_t hip = calloc(1, sizeof(hip_global_flags)); InitMP3(hip); return hip; } int hip_decode_exit(hip_t hip) { if (hip) { ExitMP3(hip); free(hip); } return 0; } /* we forbid input with more than 1152 samples per channel for output in the unclipped mode */ #define OUTSIZE_UNCLIPPED (1152*2*sizeof(FLOAT)) int hip_decode1_unclipped(hip_t hip, unsigned char *buffer, size_t len, sample_t pcm_l[], sample_t pcm_r[]) { static char out[OUTSIZE_UNCLIPPED]; mp3data_struct mp3data; int enc_delay, enc_padding; if (hip) { return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, &mp3data, &enc_delay, &enc_padding, out, OUTSIZE_UNCLIPPED, sizeof(FLOAT), decodeMP3_unclipped); } return 0; } /* * For hip_decode: return code * -1 error * 0 ok, but need more data before outputing any samples * n number of samples output. Will be at most one frame of * MPEG data. */ int hip_decode1_headers(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) { int enc_delay, enc_padding; return hip_decode1_headersB(hip, buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding); } int hip_decode1(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[]) { mp3data_struct mp3data; return hip_decode1_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data); } /* * For hip_decode: return code * -1 error * 0 ok, but need more data before outputing any samples * n number of samples output. a multiple of 576 or 1152 depending on MP3 file. */ int hip_decode_headers(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) { int ret; int totsize = 0; /* number of decoded samples per channel */ for (;;) { switch (ret = hip_decode1_headers(hip, buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) { case -1: return ret; case 0: return totsize; default: totsize += ret; len = 0; /* future calls to decodeMP3 are just to flush buffers */ break; } } } int hip_decode(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[]) { mp3data_struct mp3data; return hip_decode_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data); } int hip_decode1_headersB(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data, int *enc_delay, int *enc_padding) { static char out[OUTSIZE_CLIPPED]; if (hip) { return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data, enc_delay, enc_padding, out, OUTSIZE_CLIPPED, sizeof(short), decodeMP3); } return -1; } void hip_set_pinfo(hip_t hip, plotting_data* pinfo) { if (hip) { hip->pinfo = pinfo; } } void hip_set_errorf(hip_t hip, lame_report_function func) { if (hip) { hip->report_err = func; } } void hip_set_debugf(hip_t hip, lame_report_function func) { if (hip) { hip->report_dbg = func; } } void hip_set_msgf (hip_t hip, lame_report_function func) { if (hip) { hip->report_msg = func; } } #endif /* end of mpglib_interface.c */ ================================================ FILE: app/jni/libmp3lame/newmdct.c ================================================ /* * MP3 window subband -> subband filtering -> mdct routine * * Copyright (c) 1999-2000 Takehiro Tominaga * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Special Thanks to Patrick De Smet for your advices. */ /* $Id: newmdct.c,v 1.39 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "newmdct.h" #ifndef USE_GOGO_SUBBAND static const FLOAT enwindow[] = { -4.77e-07 * 0.740951125354959 / 2.384e-06, 1.03951e-04 * 0.740951125354959 / 2.384e-06, 9.53674e-04 * 0.740951125354959 / 2.384e-06, 2.841473e-03 * 0.740951125354959 / 2.384e-06, 3.5758972e-02 * 0.740951125354959 / 2.384e-06, 3.401756e-03 * 0.740951125354959 / 2.384e-06, 9.83715e-04 * 0.740951125354959 / 2.384e-06, 9.9182e-05 * 0.740951125354959 / 2.384e-06, /* 15 */ 1.2398e-05 * 0.740951125354959 / 2.384e-06, 1.91212e-04 * 0.740951125354959 / 2.384e-06, 2.283096e-03 * 0.740951125354959 / 2.384e-06, 1.6994476e-02 * 0.740951125354959 / 2.384e-06, -1.8756866e-02 * 0.740951125354959 / 2.384e-06, -2.630711e-03 * 0.740951125354959 / 2.384e-06, -2.47478e-04 * 0.740951125354959 / 2.384e-06, -1.4782e-05 * 0.740951125354959 / 2.384e-06, 9.063471690191471e-01, 1.960342806591213e-01, -4.77e-07 * 0.773010453362737 / 2.384e-06, 1.05858e-04 * 0.773010453362737 / 2.384e-06, 9.30786e-04 * 0.773010453362737 / 2.384e-06, 2.521515e-03 * 0.773010453362737 / 2.384e-06, 3.5694122e-02 * 0.773010453362737 / 2.384e-06, 3.643036e-03 * 0.773010453362737 / 2.384e-06, 9.91821e-04 * 0.773010453362737 / 2.384e-06, 9.6321e-05 * 0.773010453362737 / 2.384e-06, /* 14 */ 1.1444e-05 * 0.773010453362737 / 2.384e-06, 1.65462e-04 * 0.773010453362737 / 2.384e-06, 2.110004e-03 * 0.773010453362737 / 2.384e-06, 1.6112804e-02 * 0.773010453362737 / 2.384e-06, -1.9634247e-02 * 0.773010453362737 / 2.384e-06, -2.803326e-03 * 0.773010453362737 / 2.384e-06, -2.77042e-04 * 0.773010453362737 / 2.384e-06, -1.6689e-05 * 0.773010453362737 / 2.384e-06, 8.206787908286602e-01, 3.901806440322567e-01, -4.77e-07 * 0.803207531480645 / 2.384e-06, 1.07288e-04 * 0.803207531480645 / 2.384e-06, 9.02653e-04 * 0.803207531480645 / 2.384e-06, 2.174854e-03 * 0.803207531480645 / 2.384e-06, 3.5586357e-02 * 0.803207531480645 / 2.384e-06, 3.858566e-03 * 0.803207531480645 / 2.384e-06, 9.95159e-04 * 0.803207531480645 / 2.384e-06, 9.3460e-05 * 0.803207531480645 / 2.384e-06, /* 13 */ 1.0014e-05 * 0.803207531480645 / 2.384e-06, 1.40190e-04 * 0.803207531480645 / 2.384e-06, 1.937389e-03 * 0.803207531480645 / 2.384e-06, 1.5233517e-02 * 0.803207531480645 / 2.384e-06, -2.0506859e-02 * 0.803207531480645 / 2.384e-06, -2.974033e-03 * 0.803207531480645 / 2.384e-06, -3.07560e-04 * 0.803207531480645 / 2.384e-06, -1.8120e-05 * 0.803207531480645 / 2.384e-06, 7.416505462720353e-01, 5.805693545089249e-01, -4.77e-07 * 0.831469612302545 / 2.384e-06, 1.08242e-04 * 0.831469612302545 / 2.384e-06, 8.68797e-04 * 0.831469612302545 / 2.384e-06, 1.800537e-03 * 0.831469612302545 / 2.384e-06, 3.5435200e-02 * 0.831469612302545 / 2.384e-06, 4.049301e-03 * 0.831469612302545 / 2.384e-06, 9.94205e-04 * 0.831469612302545 / 2.384e-06, 9.0599e-05 * 0.831469612302545 / 2.384e-06, /* 12 */ 9.060e-06 * 0.831469612302545 / 2.384e-06, 1.16348e-04 * 0.831469612302545 / 2.384e-06, 1.766682e-03 * 0.831469612302545 / 2.384e-06, 1.4358521e-02 * 0.831469612302545 / 2.384e-06, -2.1372318e-02 * 0.831469612302545 / 2.384e-06, -3.14188e-03 * 0.831469612302545 / 2.384e-06, -3.39031e-04 * 0.831469612302545 / 2.384e-06, -1.9550e-05 * 0.831469612302545 / 2.384e-06, 6.681786379192989e-01, 7.653668647301797e-01, -4.77e-07 * 0.857728610000272 / 2.384e-06, 1.08719e-04 * 0.857728610000272 / 2.384e-06, 8.29220e-04 * 0.857728610000272 / 2.384e-06, 1.399517e-03 * 0.857728610000272 / 2.384e-06, 3.5242081e-02 * 0.857728610000272 / 2.384e-06, 4.215240e-03 * 0.857728610000272 / 2.384e-06, 9.89437e-04 * 0.857728610000272 / 2.384e-06, 8.7261e-05 * 0.857728610000272 / 2.384e-06, /* 11 */ 8.106e-06 * 0.857728610000272 / 2.384e-06, 9.3937e-05 * 0.857728610000272 / 2.384e-06, 1.597881e-03 * 0.857728610000272 / 2.384e-06, 1.3489246e-02 * 0.857728610000272 / 2.384e-06, -2.2228718e-02 * 0.857728610000272 / 2.384e-06, -3.306866e-03 * 0.857728610000272 / 2.384e-06, -3.71456e-04 * 0.857728610000272 / 2.384e-06, -2.1458e-05 * 0.857728610000272 / 2.384e-06, 5.993769336819237e-01, 9.427934736519954e-01, -4.77e-07 * 0.881921264348355 / 2.384e-06, 1.08719e-04 * 0.881921264348355 / 2.384e-06, 7.8392e-04 * 0.881921264348355 / 2.384e-06, 9.71317e-04 * 0.881921264348355 / 2.384e-06, 3.5007000e-02 * 0.881921264348355 / 2.384e-06, 4.357815e-03 * 0.881921264348355 / 2.384e-06, 9.80854e-04 * 0.881921264348355 / 2.384e-06, 8.3923e-05 * 0.881921264348355 / 2.384e-06, /* 10 */ 7.629e-06 * 0.881921264348355 / 2.384e-06, 7.2956e-05 * 0.881921264348355 / 2.384e-06, 1.432419e-03 * 0.881921264348355 / 2.384e-06, 1.2627602e-02 * 0.881921264348355 / 2.384e-06, -2.3074150e-02 * 0.881921264348355 / 2.384e-06, -3.467083e-03 * 0.881921264348355 / 2.384e-06, -4.04358e-04 * 0.881921264348355 / 2.384e-06, -2.3365e-05 * 0.881921264348355 / 2.384e-06, 5.345111359507916e-01, 1.111140466039205e+00, -9.54e-07 * 0.903989293123443 / 2.384e-06, 1.08242e-04 * 0.903989293123443 / 2.384e-06, 7.31945e-04 * 0.903989293123443 / 2.384e-06, 5.15938e-04 * 0.903989293123443 / 2.384e-06, 3.4730434e-02 * 0.903989293123443 / 2.384e-06, 4.477024e-03 * 0.903989293123443 / 2.384e-06, 9.68933e-04 * 0.903989293123443 / 2.384e-06, 8.0585e-05 * 0.903989293123443 / 2.384e-06, /* 9 */ 6.676e-06 * 0.903989293123443 / 2.384e-06, 5.2929e-05 * 0.903989293123443 / 2.384e-06, 1.269817e-03 * 0.903989293123443 / 2.384e-06, 1.1775017e-02 * 0.903989293123443 / 2.384e-06, -2.3907185e-02 * 0.903989293123443 / 2.384e-06, -3.622532e-03 * 0.903989293123443 / 2.384e-06, -4.38213e-04 * 0.903989293123443 / 2.384e-06, -2.5272e-05 * 0.903989293123443 / 2.384e-06, 4.729647758913199e-01, 1.268786568327291e+00, -9.54e-07 * 0.92387953251128675613 / 2.384e-06, 1.06812e-04 * 0.92387953251128675613 / 2.384e-06, 6.74248e-04 * 0.92387953251128675613 / 2.384e-06, 3.3379e-05 * 0.92387953251128675613 / 2.384e-06, 3.4412861e-02 * 0.92387953251128675613 / 2.384e-06, 4.573822e-03 * 0.92387953251128675613 / 2.384e-06, 9.54151e-04 * 0.92387953251128675613 / 2.384e-06, 7.6771e-05 * 0.92387953251128675613 / 2.384e-06, 6.199e-06 * 0.92387953251128675613 / 2.384e-06, 3.4332e-05 * 0.92387953251128675613 / 2.384e-06, 1.111031e-03 * 0.92387953251128675613 / 2.384e-06, 1.0933399e-02 * 0.92387953251128675613 / 2.384e-06, -2.4725437e-02 * 0.92387953251128675613 / 2.384e-06, -3.771782e-03 * 0.92387953251128675613 / 2.384e-06, -4.72546e-04 * 0.92387953251128675613 / 2.384e-06, -2.7657e-05 * 0.92387953251128675613 / 2.384e-06, 4.1421356237309504879e-01, /* tan(PI/8) */ 1.414213562373095e+00, -9.54e-07 * 0.941544065183021 / 2.384e-06, 1.05381e-04 * 0.941544065183021 / 2.384e-06, 6.10352e-04 * 0.941544065183021 / 2.384e-06, -4.75883e-04 * 0.941544065183021 / 2.384e-06, 3.4055710e-02 * 0.941544065183021 / 2.384e-06, 4.649162e-03 * 0.941544065183021 / 2.384e-06, 9.35555e-04 * 0.941544065183021 / 2.384e-06, 7.3433e-05 * 0.941544065183021 / 2.384e-06, /* 7 */ 5.245e-06 * 0.941544065183021 / 2.384e-06, 1.7166e-05 * 0.941544065183021 / 2.384e-06, 9.56535e-04 * 0.941544065183021 / 2.384e-06, 1.0103703e-02 * 0.941544065183021 / 2.384e-06, -2.5527000e-02 * 0.941544065183021 / 2.384e-06, -3.914356e-03 * 0.941544065183021 / 2.384e-06, -5.07355e-04 * 0.941544065183021 / 2.384e-06, -3.0041e-05 * 0.941544065183021 / 2.384e-06, 3.578057213145241e-01, 1.546020906725474e+00, -9.54e-07 * 0.956940335732209 / 2.384e-06, 1.02520e-04 * 0.956940335732209 / 2.384e-06, 5.39303e-04 * 0.956940335732209 / 2.384e-06, -1.011848e-03 * 0.956940335732209 / 2.384e-06, 3.3659935e-02 * 0.956940335732209 / 2.384e-06, 4.703045e-03 * 0.956940335732209 / 2.384e-06, 9.15051e-04 * 0.956940335732209 / 2.384e-06, 7.0095e-05 * 0.956940335732209 / 2.384e-06, /* 6 */ 4.768e-06 * 0.956940335732209 / 2.384e-06, 9.54e-07 * 0.956940335732209 / 2.384e-06, 8.06808e-04 * 0.956940335732209 / 2.384e-06, 9.287834e-03 * 0.956940335732209 / 2.384e-06, -2.6310921e-02 * 0.956940335732209 / 2.384e-06, -4.048824e-03 * 0.956940335732209 / 2.384e-06, -5.42164e-04 * 0.956940335732209 / 2.384e-06, -3.2425e-05 * 0.956940335732209 / 2.384e-06, 3.033466836073424e-01, 1.662939224605090e+00, -1.431e-06 * 0.970031253194544 / 2.384e-06, 9.9182e-05 * 0.970031253194544 / 2.384e-06, 4.62532e-04 * 0.970031253194544 / 2.384e-06, -1.573563e-03 * 0.970031253194544 / 2.384e-06, 3.3225536e-02 * 0.970031253194544 / 2.384e-06, 4.737377e-03 * 0.970031253194544 / 2.384e-06, 8.91685e-04 * 0.970031253194544 / 2.384e-06, 6.6280e-05 * 0.970031253194544 / 2.384e-06, /* 5 */ 4.292e-06 * 0.970031253194544 / 2.384e-06, -1.3828e-05 * 0.970031253194544 / 2.384e-06, 6.61850e-04 * 0.970031253194544 / 2.384e-06, 8.487225e-03 * 0.970031253194544 / 2.384e-06, -2.7073860e-02 * 0.970031253194544 / 2.384e-06, -4.174709e-03 * 0.970031253194544 / 2.384e-06, -5.76973e-04 * 0.970031253194544 / 2.384e-06, -3.4809e-05 * 0.970031253194544 / 2.384e-06, 2.504869601913055e-01, 1.763842528696710e+00, -1.431e-06 * 0.98078528040323 / 2.384e-06, 9.5367e-05 * 0.98078528040323 / 2.384e-06, 3.78609e-04 * 0.98078528040323 / 2.384e-06, -2.161503e-03 * 0.98078528040323 / 2.384e-06, 3.2754898e-02 * 0.98078528040323 / 2.384e-06, 4.752159e-03 * 0.98078528040323 / 2.384e-06, 8.66413e-04 * 0.98078528040323 / 2.384e-06, 6.2943e-05 * 0.98078528040323 / 2.384e-06, /* 4 */ 3.815e-06 * 0.98078528040323 / 2.384e-06, -2.718e-05 * 0.98078528040323 / 2.384e-06, 5.22137e-04 * 0.98078528040323 / 2.384e-06, 7.703304e-03 * 0.98078528040323 / 2.384e-06, -2.7815342e-02 * 0.98078528040323 / 2.384e-06, -4.290581e-03 * 0.98078528040323 / 2.384e-06, -6.11782e-04 * 0.98078528040323 / 2.384e-06, -3.7670e-05 * 0.98078528040323 / 2.384e-06, 1.989123673796580e-01, 1.847759065022573e+00, -1.907e-06 * 0.989176509964781 / 2.384e-06, 9.0122e-05 * 0.989176509964781 / 2.384e-06, 2.88486e-04 * 0.989176509964781 / 2.384e-06, -2.774239e-03 * 0.989176509964781 / 2.384e-06, 3.2248020e-02 * 0.989176509964781 / 2.384e-06, 4.748821e-03 * 0.989176509964781 / 2.384e-06, 8.38757e-04 * 0.989176509964781 / 2.384e-06, 5.9605e-05 * 0.989176509964781 / 2.384e-06, /* 3 */ 3.338e-06 * 0.989176509964781 / 2.384e-06, -3.9577e-05 * 0.989176509964781 / 2.384e-06, 3.88145e-04 * 0.989176509964781 / 2.384e-06, 6.937027e-03 * 0.989176509964781 / 2.384e-06, -2.8532982e-02 * 0.989176509964781 / 2.384e-06, -4.395962e-03 * 0.989176509964781 / 2.384e-06, -6.46591e-04 * 0.989176509964781 / 2.384e-06, -4.0531e-05 * 0.989176509964781 / 2.384e-06, 1.483359875383474e-01, 1.913880671464418e+00, -1.907e-06 * 0.995184726672197 / 2.384e-06, 8.4400e-05 * 0.995184726672197 / 2.384e-06, 1.91689e-04 * 0.995184726672197 / 2.384e-06, -3.411293e-03 * 0.995184726672197 / 2.384e-06, 3.1706810e-02 * 0.995184726672197 / 2.384e-06, 4.728317e-03 * 0.995184726672197 / 2.384e-06, 8.09669e-04 * 0.995184726672197 / 2.384e-06, 5.579e-05 * 0.995184726672197 / 2.384e-06, 3.338e-06 * 0.995184726672197 / 2.384e-06, -5.0545e-05 * 0.995184726672197 / 2.384e-06, 2.59876e-04 * 0.995184726672197 / 2.384e-06, 6.189346e-03 * 0.995184726672197 / 2.384e-06, -2.9224873e-02 * 0.995184726672197 / 2.384e-06, -4.489899e-03 * 0.995184726672197 / 2.384e-06, -6.80923e-04 * 0.995184726672197 / 2.384e-06, -4.3392e-05 * 0.995184726672197 / 2.384e-06, 9.849140335716425e-02, 1.961570560806461e+00, -2.384e-06 * 0.998795456205172 / 2.384e-06, 7.7724e-05 * 0.998795456205172 / 2.384e-06, 8.8215e-05 * 0.998795456205172 / 2.384e-06, -4.072189e-03 * 0.998795456205172 / 2.384e-06, 3.1132698e-02 * 0.998795456205172 / 2.384e-06, 4.691124e-03 * 0.998795456205172 / 2.384e-06, 7.79152e-04 * 0.998795456205172 / 2.384e-06, 5.2929e-05 * 0.998795456205172 / 2.384e-06, 2.861e-06 * 0.998795456205172 / 2.384e-06, -6.0558e-05 * 0.998795456205172 / 2.384e-06, 1.37329e-04 * 0.998795456205172 / 2.384e-06, 5.462170e-03 * 0.998795456205172 / 2.384e-06, -2.9890060e-02 * 0.998795456205172 / 2.384e-06, -4.570484e-03 * 0.998795456205172 / 2.384e-06, -7.14302e-04 * 0.998795456205172 / 2.384e-06, -4.6253e-05 * 0.998795456205172 / 2.384e-06, 4.912684976946725e-02, 1.990369453344394e+00, 3.5780907e-02 * SQRT2 * 0.5 / 2.384e-06, 1.7876148e-02 * SQRT2 * 0.5 / 2.384e-06, 3.134727e-03 * SQRT2 * 0.5 / 2.384e-06, 2.457142e-03 * SQRT2 * 0.5 / 2.384e-06, 9.71317e-04 * SQRT2 * 0.5 / 2.384e-06, 2.18868e-04 * SQRT2 * 0.5 / 2.384e-06, 1.01566e-04 * SQRT2 * 0.5 / 2.384e-06, 1.3828e-05 * SQRT2 * 0.5 / 2.384e-06, 3.0526638e-02 / 2.384e-06, 4.638195e-03 / 2.384e-06, 7.47204e-04 / 2.384e-06, 4.9591e-05 / 2.384e-06, 4.756451e-03 / 2.384e-06, 2.1458e-05 / 2.384e-06, -6.9618e-05 / 2.384e-06, /* 2.384e-06/2.384e-06 */ }; #endif #define NS 12 #define NL 36 static const FLOAT win[4][NL] = { { 2.382191739347913e-13, 6.423305872147834e-13, 9.400849094049688e-13, 1.122435026096556e-12, 1.183840321267481e-12, 1.122435026096556e-12, 9.400849094049690e-13, 6.423305872147839e-13, 2.382191739347918e-13, 5.456116108943412e-12, 4.878985199565852e-12, 4.240448995017367e-12, 3.559909094758252e-12, 2.858043359288075e-12, 2.156177623817898e-12, 1.475637723558783e-12, 8.371015190102974e-13, 2.599706096327376e-13, -5.456116108943412e-12, -4.878985199565852e-12, -4.240448995017367e-12, -3.559909094758252e-12, -2.858043359288076e-12, -2.156177623817898e-12, -1.475637723558783e-12, -8.371015190102975e-13, -2.599706096327376e-13, -2.382191739347923e-13, -6.423305872147843e-13, -9.400849094049696e-13, -1.122435026096556e-12, -1.183840321267481e-12, -1.122435026096556e-12, -9.400849094049694e-13, -6.423305872147840e-13, -2.382191739347918e-13, }, { 2.382191739347913e-13, 6.423305872147834e-13, 9.400849094049688e-13, 1.122435026096556e-12, 1.183840321267481e-12, 1.122435026096556e-12, 9.400849094049688e-13, 6.423305872147841e-13, 2.382191739347918e-13, 5.456116108943413e-12, 4.878985199565852e-12, 4.240448995017367e-12, 3.559909094758253e-12, 2.858043359288075e-12, 2.156177623817898e-12, 1.475637723558782e-12, 8.371015190102975e-13, 2.599706096327376e-13, -5.461314069809755e-12, -4.921085770524055e-12, -4.343405037091838e-12, -3.732668368707687e-12, -3.093523840190885e-12, -2.430835727329465e-12, -1.734679010007751e-12, -9.748253656609281e-13, -2.797435120168326e-13, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, -2.283748241799531e-13, -4.037858874020686e-13, -2.146547464825323e-13, }, { 1.316524975873958e-01, /* win[SHORT_TYPE] */ 4.142135623730950e-01, 7.673269879789602e-01, 1.091308501069271e+00, /* tantab_l */ 1.303225372841206e+00, 1.569685577117490e+00, 1.920982126971166e+00, 2.414213562373094e+00, 3.171594802363212e+00, 4.510708503662055e+00, 7.595754112725146e+00, 2.290376554843115e+01, 0.98480775301220802032, /* cx */ 0.64278760968653936292, 0.34202014332566882393, 0.93969262078590842791, -0.17364817766693030343, -0.76604444311897790243, 0.86602540378443870761, 0.500000000000000e+00, -5.144957554275265e-01, /* ca */ -4.717319685649723e-01, -3.133774542039019e-01, -1.819131996109812e-01, -9.457419252642064e-02, -4.096558288530405e-02, -1.419856857247115e-02, -3.699974673760037e-03, 8.574929257125442e-01, /* cs */ 8.817419973177052e-01, 9.496286491027329e-01, 9.833145924917901e-01, 9.955178160675857e-01, 9.991605581781475e-01, 9.998991952444470e-01, 9.999931550702802e-01, }, { 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 2.283748241799531e-13, 4.037858874020686e-13, 2.146547464825323e-13, 5.461314069809755e-12, 4.921085770524055e-12, 4.343405037091838e-12, 3.732668368707687e-12, 3.093523840190885e-12, 2.430835727329466e-12, 1.734679010007751e-12, 9.748253656609281e-13, 2.797435120168326e-13, -5.456116108943413e-12, -4.878985199565852e-12, -4.240448995017367e-12, -3.559909094758253e-12, -2.858043359288075e-12, -2.156177623817898e-12, -1.475637723558782e-12, -8.371015190102975e-13, -2.599706096327376e-13, -2.382191739347913e-13, -6.423305872147834e-13, -9.400849094049688e-13, -1.122435026096556e-12, -1.183840321267481e-12, -1.122435026096556e-12, -9.400849094049688e-13, -6.423305872147841e-13, -2.382191739347918e-13, } }; #define tantab_l (win[SHORT_TYPE]+3) #define cx (win[SHORT_TYPE]+12) #define ca (win[SHORT_TYPE]+20) #define cs (win[SHORT_TYPE]+28) /************************************************************************ * * window_subband() * * PURPOSE: Overlapping window on PCM samples * * SEMANTICS: * 32 16-bit pcm samples are scaled to fractional 2's complement and * concatenated to the end of the window buffer #x#. The updated window * buffer #x# is then windowed by the analysis window #c# to produce the * windowed sample #z# * ************************************************************************/ /* * new IDCT routine written by Takehiro TOMINAGA */ static const int order[] = { 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29, 2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31 }; /* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 */ inline static void window_subband(const sample_t * x1, FLOAT a[SBLIMIT]) { int i; FLOAT const *wp = enwindow + 10; const sample_t *x2 = &x1[238 - 14 - 286]; for (i = -15; i < 0; i++) { FLOAT w, s, t; w = wp[-10]; s = x2[-224] * w; t = x1[224] * w; w = wp[-9]; s += x2[-160] * w; t += x1[160] * w; w = wp[-8]; s += x2[-96] * w; t += x1[96] * w; w = wp[-7]; s += x2[-32] * w; t += x1[32] * w; w = wp[-6]; s += x2[32] * w; t += x1[-32] * w; w = wp[-5]; s += x2[96] * w; t += x1[-96] * w; w = wp[-4]; s += x2[160] * w; t += x1[-160] * w; w = wp[-3]; s += x2[224] * w; t += x1[-224] * w; w = wp[-2]; s += x1[-256] * w; t -= x2[256] * w; w = wp[-1]; s += x1[-192] * w; t -= x2[192] * w; w = wp[0]; s += x1[-128] * w; t -= x2[128] * w; w = wp[1]; s += x1[-64] * w; t -= x2[64] * w; w = wp[2]; s += x1[0] * w; t -= x2[0] * w; w = wp[3]; s += x1[64] * w; t -= x2[-64] * w; w = wp[4]; s += x1[128] * w; t -= x2[-128] * w; w = wp[5]; s += x1[192] * w; t -= x2[-192] * w; /* * this multiplyer could be removed, but it needs more 256 FLOAT data. * thinking about the data cache performance, I think we should not * use such a huge table. tt 2000/Oct/25 */ s *= wp[6]; w = t - s; a[30 + i * 2] = t + s; a[31 + i * 2] = wp[7] * w; wp += 18; x1--; x2++; } { FLOAT s, t, u, v; t = x1[-16] * wp[-10]; s = x1[-32] * wp[-2]; t += (x1[-48] - x1[16]) * wp[-9]; s += x1[-96] * wp[-1]; t += (x1[-80] + x1[48]) * wp[-8]; s += x1[-160] * wp[0]; t += (x1[-112] - x1[80]) * wp[-7]; s += x1[-224] * wp[1]; t += (x1[-144] + x1[112]) * wp[-6]; s -= x1[32] * wp[2]; t += (x1[-176] - x1[144]) * wp[-5]; s -= x1[96] * wp[3]; t += (x1[-208] + x1[176]) * wp[-4]; s -= x1[160] * wp[4]; t += (x1[-240] - x1[208]) * wp[-3]; s -= x1[224]; u = s - t; v = s + t; t = a[14]; s = a[15] - t; a[31] = v + t; /* A0 */ a[30] = u + s; /* A1 */ a[15] = u - s; /* A2 */ a[14] = v - t; /* A3 */ } { FLOAT xr; xr = a[28] - a[0]; a[0] += a[28]; a[28] = xr * wp[-2 * 18 + 7]; xr = a[29] - a[1]; a[1] += a[29]; a[29] = xr * wp[-2 * 18 + 7]; xr = a[26] - a[2]; a[2] += a[26]; a[26] = xr * wp[-4 * 18 + 7]; xr = a[27] - a[3]; a[3] += a[27]; a[27] = xr * wp[-4 * 18 + 7]; xr = a[24] - a[4]; a[4] += a[24]; a[24] = xr * wp[-6 * 18 + 7]; xr = a[25] - a[5]; a[5] += a[25]; a[25] = xr * wp[-6 * 18 + 7]; xr = a[22] - a[6]; a[6] += a[22]; a[22] = xr * SQRT2; xr = a[23] - a[7]; a[7] += a[23]; a[23] = xr * SQRT2 - a[7]; a[7] -= a[6]; a[22] -= a[7]; a[23] -= a[22]; xr = a[6]; a[6] = a[31] - xr; a[31] = a[31] + xr; xr = a[7]; a[7] = a[30] - xr; a[30] = a[30] + xr; xr = a[22]; a[22] = a[15] - xr; a[15] = a[15] + xr; xr = a[23]; a[23] = a[14] - xr; a[14] = a[14] + xr; xr = a[20] - a[8]; a[8] += a[20]; a[20] = xr * wp[-10 * 18 + 7]; xr = a[21] - a[9]; a[9] += a[21]; a[21] = xr * wp[-10 * 18 + 7]; xr = a[18] - a[10]; a[10] += a[18]; a[18] = xr * wp[-12 * 18 + 7]; xr = a[19] - a[11]; a[11] += a[19]; a[19] = xr * wp[-12 * 18 + 7]; xr = a[16] - a[12]; a[12] += a[16]; a[16] = xr * wp[-14 * 18 + 7]; xr = a[17] - a[13]; a[13] += a[17]; a[17] = xr * wp[-14 * 18 + 7]; xr = -a[20] + a[24]; a[20] += a[24]; a[24] = xr * wp[-12 * 18 + 7]; xr = -a[21] + a[25]; a[21] += a[25]; a[25] = xr * wp[-12 * 18 + 7]; xr = a[4] - a[8]; a[4] += a[8]; a[8] = xr * wp[-12 * 18 + 7]; xr = a[5] - a[9]; a[5] += a[9]; a[9] = xr * wp[-12 * 18 + 7]; xr = a[0] - a[12]; a[0] += a[12]; a[12] = xr * wp[-4 * 18 + 7]; xr = a[1] - a[13]; a[1] += a[13]; a[13] = xr * wp[-4 * 18 + 7]; xr = a[16] - a[28]; a[16] += a[28]; a[28] = xr * wp[-4 * 18 + 7]; xr = -a[17] + a[29]; a[17] += a[29]; a[29] = xr * wp[-4 * 18 + 7]; xr = SQRT2 * (a[2] - a[10]); a[2] += a[10]; a[10] = xr; xr = SQRT2 * (a[3] - a[11]); a[3] += a[11]; a[11] = xr; xr = SQRT2 * (-a[18] + a[26]); a[18] += a[26]; a[26] = xr - a[18]; xr = SQRT2 * (-a[19] + a[27]); a[19] += a[27]; a[27] = xr - a[19]; xr = a[2]; a[19] -= a[3]; a[3] -= xr; a[2] = a[31] - xr; a[31] += xr; xr = a[3]; a[11] -= a[19]; a[18] -= xr; a[3] = a[30] - xr; a[30] += xr; xr = a[18]; a[27] -= a[11]; a[19] -= xr; a[18] = a[15] - xr; a[15] += xr; xr = a[19]; a[10] -= xr; a[19] = a[14] - xr; a[14] += xr; xr = a[10]; a[11] -= xr; a[10] = a[23] - xr; a[23] += xr; xr = a[11]; a[26] -= xr; a[11] = a[22] - xr; a[22] += xr; xr = a[26]; a[27] -= xr; a[26] = a[7] - xr; a[7] += xr; xr = a[27]; a[27] = a[6] - xr; a[6] += xr; xr = SQRT2 * (a[0] - a[4]); a[0] += a[4]; a[4] = xr; xr = SQRT2 * (a[1] - a[5]); a[1] += a[5]; a[5] = xr; xr = SQRT2 * (a[16] - a[20]); a[16] += a[20]; a[20] = xr; xr = SQRT2 * (a[17] - a[21]); a[17] += a[21]; a[21] = xr; xr = -SQRT2 * (a[8] - a[12]); a[8] += a[12]; a[12] = xr - a[8]; xr = -SQRT2 * (a[9] - a[13]); a[9] += a[13]; a[13] = xr - a[9]; xr = -SQRT2 * (a[25] - a[29]); a[25] += a[29]; a[29] = xr - a[25]; xr = -SQRT2 * (a[24] + a[28]); a[24] -= a[28]; a[28] = xr - a[24]; xr = a[24] - a[16]; a[24] = xr; xr = a[20] - xr; a[20] = xr; xr = a[28] - xr; a[28] = xr; xr = a[25] - a[17]; a[25] = xr; xr = a[21] - xr; a[21] = xr; xr = a[29] - xr; a[29] = xr; xr = a[17] - a[1]; a[17] = xr; xr = a[9] - xr; a[9] = xr; xr = a[25] - xr; a[25] = xr; xr = a[5] - xr; a[5] = xr; xr = a[21] - xr; a[21] = xr; xr = a[13] - xr; a[13] = xr; xr = a[29] - xr; a[29] = xr; xr = a[1] - a[0]; a[1] = xr; xr = a[16] - xr; a[16] = xr; xr = a[17] - xr; a[17] = xr; xr = a[8] - xr; a[8] = xr; xr = a[9] - xr; a[9] = xr; xr = a[24] - xr; a[24] = xr; xr = a[25] - xr; a[25] = xr; xr = a[4] - xr; a[4] = xr; xr = a[5] - xr; a[5] = xr; xr = a[20] - xr; a[20] = xr; xr = a[21] - xr; a[21] = xr; xr = a[12] - xr; a[12] = xr; xr = a[13] - xr; a[13] = xr; xr = a[28] - xr; a[28] = xr; xr = a[29] - xr; a[29] = xr; xr = a[0]; a[0] += a[31]; a[31] -= xr; xr = a[1]; a[1] += a[30]; a[30] -= xr; xr = a[16]; a[16] += a[15]; a[15] -= xr; xr = a[17]; a[17] += a[14]; a[14] -= xr; xr = a[8]; a[8] += a[23]; a[23] -= xr; xr = a[9]; a[9] += a[22]; a[22] -= xr; xr = a[24]; a[24] += a[7]; a[7] -= xr; xr = a[25]; a[25] += a[6]; a[6] -= xr; xr = a[4]; a[4] += a[27]; a[27] -= xr; xr = a[5]; a[5] += a[26]; a[26] -= xr; xr = a[20]; a[20] += a[11]; a[11] -= xr; xr = a[21]; a[21] += a[10]; a[10] -= xr; xr = a[12]; a[12] += a[19]; a[19] -= xr; xr = a[13]; a[13] += a[18]; a[18] -= xr; xr = a[28]; a[28] += a[3]; a[3] -= xr; xr = a[29]; a[29] += a[2]; a[2] -= xr; } } /*-------------------------------------------------------------------*/ /* */ /* Function: Calculation of the MDCT */ /* In the case of long blocks (type 0,1,3) there are */ /* 36 coefficents in the time domain and 18 in the frequency */ /* domain. */ /* In the case of short blocks (type 2) there are 3 */ /* transformations with short length. This leads to 12 coefficents */ /* in the time and 6 in the frequency domain. In this case the */ /* results are stored side by side in the vector out[]. */ /* */ /* New layer3 */ /* */ /*-------------------------------------------------------------------*/ inline static void mdct_short(FLOAT * inout) { int l; for (l = 0; l < 3; l++) { FLOAT tc0, tc1, tc2, ts0, ts1, ts2; ts0 = inout[2 * 3] * win[SHORT_TYPE][0] - inout[5 * 3]; tc0 = inout[0 * 3] * win[SHORT_TYPE][2] - inout[3 * 3]; tc1 = ts0 + tc0; tc2 = ts0 - tc0; ts0 = inout[5 * 3] * win[SHORT_TYPE][0] + inout[2 * 3]; tc0 = inout[3 * 3] * win[SHORT_TYPE][2] + inout[0 * 3]; ts1 = ts0 + tc0; ts2 = -ts0 + tc0; tc0 = (inout[1 * 3] * win[SHORT_TYPE][1] - inout[4 * 3]) * 2.069978111953089e-11; /* tritab_s[1] */ ts0 = (inout[4 * 3] * win[SHORT_TYPE][1] + inout[1 * 3]) * 2.069978111953089e-11; /* tritab_s[1] */ inout[3 * 0] = tc1 * 1.907525191737280e-11 /* tritab_s[2] */ + tc0; inout[3 * 5] = -ts1 * 1.907525191737280e-11 /* tritab_s[0] */ + ts0; tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[2] */ ; ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0; inout[3 * 1] = tc2 - ts1; inout[3 * 2] = tc2 + ts1; tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0; ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[0] */ ; inout[3 * 3] = tc1 + ts2; inout[3 * 4] = tc1 - ts2; inout++; } } inline static void mdct_long(FLOAT * out, FLOAT const *in) { FLOAT ct, st; { FLOAT tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8; /* 1,2, 5,6, 9,10, 13,14, 17 */ tc1 = in[17] - in[9]; tc3 = in[15] - in[11]; tc4 = in[14] - in[12]; ts5 = in[0] + in[8]; ts6 = in[1] + in[7]; ts7 = in[2] + in[6]; ts8 = in[3] + in[5]; out[17] = (ts5 + ts7 - ts8) - (ts6 - in[4]); st = (ts5 + ts7 - ts8) * cx[7] + (ts6 - in[4]); ct = (tc1 - tc3 - tc4) * cx[6]; out[5] = ct + st; out[6] = ct - st; tc2 = (in[16] - in[10]) * cx[6]; ts6 = ts6 * cx[7] + in[4]; ct = tc1 * cx[0] + tc2 + tc3 * cx[1] + tc4 * cx[2]; st = -ts5 * cx[4] + ts6 - ts7 * cx[5] + ts8 * cx[3]; out[1] = ct + st; out[2] = ct - st; ct = tc1 * cx[1] - tc2 - tc3 * cx[2] + tc4 * cx[0]; st = -ts5 * cx[5] + ts6 - ts7 * cx[3] + ts8 * cx[4]; out[9] = ct + st; out[10] = ct - st; ct = tc1 * cx[2] - tc2 + tc3 * cx[0] - tc4 * cx[1]; st = ts5 * cx[3] - ts6 + ts7 * cx[4] - ts8 * cx[5]; out[13] = ct + st; out[14] = ct - st; } { FLOAT ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8; ts1 = in[8] - in[0]; ts3 = in[6] - in[2]; ts4 = in[5] - in[3]; tc5 = in[17] + in[9]; tc6 = in[16] + in[10]; tc7 = in[15] + in[11]; tc8 = in[14] + in[12]; out[0] = (tc5 + tc7 + tc8) + (tc6 + in[13]); ct = (tc5 + tc7 + tc8) * cx[7] - (tc6 + in[13]); st = (ts1 - ts3 + ts4) * cx[6]; out[11] = ct + st; out[12] = ct - st; ts2 = (in[7] - in[1]) * cx[6]; tc6 = in[13] - tc6 * cx[7]; ct = tc5 * cx[3] - tc6 + tc7 * cx[4] + tc8 * cx[5]; st = ts1 * cx[2] + ts2 + ts3 * cx[0] + ts4 * cx[1]; out[3] = ct + st; out[4] = ct - st; ct = -tc5 * cx[5] + tc6 - tc7 * cx[3] - tc8 * cx[4]; st = ts1 * cx[1] + ts2 - ts3 * cx[2] - ts4 * cx[0]; out[7] = ct + st; out[8] = ct - st; ct = -tc5 * cx[4] + tc6 - tc7 * cx[5] - tc8 * cx[3]; st = ts1 * cx[0] - ts2 + ts3 * cx[1] - ts4 * cx[2]; out[15] = ct + st; out[16] = ct - st; } } void mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int gr, k, ch; const sample_t *wk; wk = w0 + 286; /* thinking cache performance, ch->gr loop is better than gr->ch loop */ for (ch = 0; ch < cfg->channels_out; ch++) { for (gr = 0; gr < cfg->mode_gr; gr++) { int band; gr_info *const gi = &(gfc->l3_side.tt[gr][ch]); FLOAT *mdct_enc = gi->xr; FLOAT *samp = esv->sb_sample[ch][1 - gr][0]; for (k = 0; k < 18 / 2; k++) { window_subband(wk, samp); window_subband(wk + 32, samp + 32); samp += 64; wk += 64; /* * Compensate for inversion in the analysis filter */ for (band = 1; band < 32; band += 2) { samp[band - 32] *= -1; } } /* * Perform imdct of 18 previous subband samples * + 18 current subband samples */ for (band = 0; band < 32; band++, mdct_enc += 18) { int type = gi->block_type; FLOAT const *const band0 = esv->sb_sample[ch][gr][0] + order[band]; FLOAT *const band1 = esv->sb_sample[ch][1 - gr][0] + order[band]; if (gi->mixed_block_flag && band < 2) type = 0; if (esv->amp_filter[band] < 1e-12) { memset(mdct_enc, 0, 18 * sizeof(FLOAT)); } else { if (esv->amp_filter[band] < 1.0) { for (k = 0; k < 18; k++) band1[k * 32] *= esv->amp_filter[band]; } if (type == SHORT_TYPE) { for (k = -NS / 4; k < 0; k++) { FLOAT const w = win[SHORT_TYPE][k + 3]; mdct_enc[k * 3 + 9] = band0[(9 + k) * 32] * w - band0[(8 - k) * 32]; mdct_enc[k * 3 + 18] = band0[(14 - k) * 32] * w + band0[(15 + k) * 32]; mdct_enc[k * 3 + 10] = band0[(15 + k) * 32] * w - band0[(14 - k) * 32]; mdct_enc[k * 3 + 19] = band1[(2 - k) * 32] * w + band1[(3 + k) * 32]; mdct_enc[k * 3 + 11] = band1[(3 + k) * 32] * w - band1[(2 - k) * 32]; mdct_enc[k * 3 + 20] = band1[(8 - k) * 32] * w + band1[(9 + k) * 32]; } mdct_short(mdct_enc); } else { FLOAT work[18]; for (k = -NL / 4; k < 0; k++) { FLOAT a, b; a = win[type][k + 27] * band1[(k + 9) * 32] + win[type][k + 36] * band1[(8 - k) * 32]; b = win[type][k + 9] * band0[(k + 9) * 32] - win[type][k + 18] * band0[(8 - k) * 32]; work[k + 9] = a - b * tantab_l[k + 9]; work[k + 18] = a * tantab_l[k + 9] + b; } mdct_long(mdct_enc, work); } } /* * Perform aliasing reduction butterfly */ if (type != SHORT_TYPE && band != 0) { for (k = 7; k >= 0; --k) { FLOAT bu, bd; bu = mdct_enc[k] * ca[k] + mdct_enc[-1 - k] * cs[k]; bd = mdct_enc[k] * cs[k] - mdct_enc[-1 - k] * ca[k]; mdct_enc[-1 - k] = bu; mdct_enc[k] = bd; } } } } wk = w1 + 286; if (cfg->mode_gr == 1) { memcpy(esv->sb_sample[ch][0], esv->sb_sample[ch][1], 576 * sizeof(FLOAT)); } } } ================================================ FILE: app/jni/libmp3lame/newmdct.h ================================================ /* * New Modified DCT include file * * Copyright (c) 1999 Takehiro TOMINAGA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_NEWMDCT_H #define LAME_NEWMDCT_H void mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1); #endif /* LAME_NEWMDCT_H */ ================================================ FILE: app/jni/libmp3lame/presets.c ================================================ /* * presets.c -- Apply presets * * Copyright (c) 2002-2008 Gabriel Bouvigne * Copyright (c) 2007-2011 Robert Hegemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "set_get.h" #include "encoder.h" #include "util.h" #include "lame_global_flags.h" #define SET_OPTION(opt, val, def) if (enforce) \ (void) lame_set_##opt(gfp, val); \ else if (!(fabs((float)lame_get_##opt(gfp) - def) > 0)) \ (void) lame_set_##opt(gfp, val); #define SET__OPTION(opt, val, def) if (enforce) \ lame_set_##opt(gfp, val); \ else if (!(fabs((float)lame_get_##opt(gfp) - def) > 0)) \ lame_set_##opt(gfp, val); #undef Min #undef Max static inline int min_int(int a, int b) { if (a < b) { return a; } return b; } static inline int max_int(int a, int b) { if (a > b) { return a; } return b; } typedef struct { int vbr_q; int quant_comp; int quant_comp_s; int expY; FLOAT st_lrm; /*short threshold */ FLOAT st_s; FLOAT masking_adj; FLOAT masking_adj_short; FLOAT ath_lower; FLOAT ath_curve; FLOAT ath_sensitivity; FLOAT interch; int safejoint; int sfb21mod; FLOAT msfix; FLOAT minval; FLOAT ath_fixpoint; } vbr_presets_t; /* *INDENT-OFF* */ /* Switch mappings for VBR mode VBR_RH */ static const vbr_presets_t vbr_old_switch_map[] = { /*vbr_q qcomp_l qcomp_s expY st_lrm st_s mask adj_l adj_s ath_lower ath_curve ath_sens interChR safejoint sfb21mod msfix */ {0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97, 5, 100}, {1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35, 5, 100}, {2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49, 5, 100}, {3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64, 5, 100}, {4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79, 5, 100}, {5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95, 5, 100}, {6, 9, 9, 1, 6.60, 145.0, 0.67, 0.65, -14.7, 6.5, -19, 0.0004, 0, 0, 2.30, 5, 100}, {7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70, 5, 100}, {8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0, 5, 100}, {9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0, 5, 100}, {10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0, 5, 100} }; static const vbr_presets_t vbr_mt_psy_switch_map[] = { /*vbr_q qcomp_l qcomp_s expY st_lrm st_s mask adj_l adj_s ath_lower ath_curve ath_sens --- safejoint sfb21mod msfix */ {0, 9, 9, 0, 4.20, 25.0, -6.8, -6.8, 7.1, 1, 0, 0, 2, 31, 1.000, 5, 100}, {1, 9, 9, 0, 4.20, 25.0, -4.8, -4.8, 5.4, 1.4, -1, 0, 2, 27, 1.122, 5, 98}, {2, 9, 9, 0, 4.20, 25.0, -2.6, -2.6, 3.7, 2.0, -3, 0, 2, 23, 1.288, 5, 97}, {3, 9, 9, 1, 4.20, 25.0, -1.6, -1.6, 2.0, 2.0, -5, 0, 2, 18, 1.479, 5, 96}, {4, 9, 9, 1, 4.20, 25.0, -0.0, -0.0, 0.0, 2.0, -8, 0, 2, 12, 1.698, 5, 95}, {5, 9, 9, 1, 4.20, 25.0, 1.3, 1.3, -6, 3.5, -11, 0, 2, 8, 1.950, 5, 94.2}, #if 0 {6, 9, 9, 1, 4.50, 100.0, 1.5, 1.5, -24.0, 6.0, -14, 0, 2, 4, 2.239, 3, 93.9}, {7, 9, 9, 1, 4.80, 200.0, 1.7, 1.7, -28.0, 9.0, -20, 0, 2, 0, 2.570, 1, 93.6}, #else {6, 9, 9, 1, 4.50, 100.0, 2.2, 2.3, -12.0, 6.0, -14, 0, 2, 4, 2.239, 3, 93.9}, {7, 9, 9, 1, 4.80, 200.0, 2.7, 2.7, -18.0, 9.0, -17, 0, 2, 0, 2.570, 1, 93.6}, #endif {8, 9, 9, 1, 5.30, 300.0, 2.8, 2.8, -21.0, 10.0, -23, 0.0002, 0, 0, 2.951, 0, 93.3}, {9, 9, 9, 1, 6.60, 300.0, 2.8, 2.8, -23.0, 11.0, -25, 0.0006, 0, 0, 3.388, 0, 93.3}, {10, 9, 9, 1, 25.00, 300.0, 2.8, 2.8, -25.0, 12.0, -27, 0.0025, 0, 0, 3.500, 0, 93.3} }; /* *INDENT-ON* */ static vbr_presets_t const* get_vbr_preset(int v) { switch (v) { case vbr_mtrh: case vbr_mt: return &vbr_mt_psy_switch_map[0]; default: return &vbr_old_switch_map[0]; } } #define NOOP(m) (void)p.m #define LERP(m) (p.m = p.m + x * (q.m - p.m)) static void apply_vbr_preset(lame_global_flags * gfp, int a, int enforce) { vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR(gfp)); float x = gfp->VBR_q_frac; vbr_presets_t p = vbr_preset[a]; vbr_presets_t q = vbr_preset[a + 1]; vbr_presets_t const *set = &p; NOOP(vbr_q); NOOP(quant_comp); NOOP(quant_comp_s); NOOP(expY); LERP(st_lrm); LERP(st_s); LERP(masking_adj); LERP(masking_adj_short); LERP(ath_lower); LERP(ath_curve); LERP(ath_sensitivity); LERP(interch); NOOP(safejoint); LERP(sfb21mod); LERP(msfix); LERP(minval); LERP(ath_fixpoint); (void) lame_set_VBR_q(gfp, set->vbr_q); SET_OPTION(quant_comp, set->quant_comp, -1); //#define SET_OPTION(opt, val, def) if (enforce) \ // (void) lame_set_##opt(gfp, val); \ // else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \ // (void) lame_set_##opt(gfp, val); SET_OPTION(quant_comp_short, set->quant_comp_s, -1); if (set->expY) { (void) lame_set_experimentalY(gfp, set->expY); } SET_OPTION(short_threshold_lrm, set->st_lrm, -1); SET_OPTION(short_threshold_s, set->st_s, -1); SET_OPTION(maskingadjust, set->masking_adj, 0); SET_OPTION(maskingadjust_short, set->masking_adj_short, 0); if (lame_get_VBR(gfp) == vbr_mt || lame_get_VBR(gfp) == vbr_mtrh) { lame_set_ATHtype(gfp, 5); } SET_OPTION(ATHlower, set->ath_lower, 0); SET_OPTION(ATHcurve, set->ath_curve, -1); SET_OPTION(athaa_sensitivity, set->ath_sensitivity, 0); if (set->interch > 0) { SET_OPTION(interChRatio, set->interch, -1); } /* parameters for which there is no proper set/get interface */ if (set->safejoint > 0) { (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); } if (set->sfb21mod > 0) { int const nsp = lame_get_exp_nspsytune(gfp); int const val = (nsp >> 20) & 63; if (val == 0) { int const sf21mod = (set->sfb21mod << 20) | nsp; (void) lame_set_exp_nspsytune(gfp, sf21mod); } } SET__OPTION(msfix, set->msfix, -1); if (enforce == 0) { gfp->VBR_q = a; gfp->VBR_q_frac = x; } gfp->internal_flags->cfg.minval = set->minval; gfp->internal_flags->cfg.ATHfixpoint = set->ath_fixpoint; } static int apply_abr_preset(lame_global_flags * gfp, int preset, int enforce) { typedef struct { int abr_kbps; int quant_comp; int quant_comp_s; int safejoint; FLOAT nsmsfix; FLOAT st_lrm; /*short threshold */ FLOAT st_s; FLOAT scale; FLOAT masking_adj; FLOAT ath_lower; FLOAT ath_curve; FLOAT interch; int sfscale; } abr_presets_t; /* *INDENT-OFF* */ /* * Switch mappings for ABR mode */ const abr_presets_t abr_switch_map[] = { /* kbps quant q_s safejoint nsmsfix st_lrm st_s scale msk ath_lwr ath_curve interch , sfscale */ { 8, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -30.0, 11, 0.0012, 1}, /* 8, impossible to use in stereo */ { 16, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -25.0, 11, 0.0010, 1}, /* 16 */ { 24, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -20.0, 11, 0.0010, 1}, /* 24 */ { 32, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -15.0, 11, 0.0010, 1}, /* 32 */ { 40, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 40 */ { 48, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 48 */ { 56, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -6.0, 11, 0.0008, 1}, /* 56 */ { 64, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -2.0, 11, 0.0008, 1}, /* 64 */ { 80, 9, 9, 0, 0, 6.60, 145, 0.95, 0, .0, 8, 0.0007, 1}, /* 80 */ { 96, 9, 9, 0, 2.50, 6.60, 145, 0.95, 0, 1.0, 5.5, 0.0006, 1}, /* 96 */ {112, 9, 9, 0, 2.25, 6.60, 145, 0.95, 0, 2.0, 4.5, 0.0005, 1}, /* 112 */ {128, 9, 9, 0, 1.95, 6.40, 140, 0.95, 0, 3.0, 4, 0.0002, 1}, /* 128 */ {160, 9, 9, 1, 1.79, 6.00, 135, 0.95, -2, 5.0, 3.5, 0, 1}, /* 160 */ {192, 9, 9, 1, 1.49, 5.60, 125, 0.97, -4, 7.0, 3, 0, 0}, /* 192 */ {224, 9, 9, 1, 1.25, 5.20, 125, 0.98, -6, 9.0, 2, 0, 0}, /* 224 */ {256, 9, 9, 1, 0.97, 5.20, 125, 1.00, -8, 10.0, 1, 0, 0}, /* 256 */ {320, 9, 9, 1, 0.90, 5.20, 125, 1.00, -10, 12.0, 0, 0, 0} /* 320 */ }; /* *INDENT-ON* */ /* Variables for the ABR stuff */ int r; int actual_bitrate = preset; r = nearestBitrateFullIndex(preset); (void) lame_set_VBR(gfp, vbr_abr); (void) lame_set_VBR_mean_bitrate_kbps(gfp, (actual_bitrate)); (void) lame_set_VBR_mean_bitrate_kbps(gfp, min_int(lame_get_VBR_mean_bitrate_kbps(gfp), 320)); (void) lame_set_VBR_mean_bitrate_kbps(gfp, max_int(lame_get_VBR_mean_bitrate_kbps(gfp), 8)); (void) lame_set_brate(gfp, lame_get_VBR_mean_bitrate_kbps(gfp)); /* parameters for which there is no proper set/get interface */ if (abr_switch_map[r].safejoint > 0) (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); /* safejoint */ if (abr_switch_map[r].sfscale > 0) (void) lame_set_sfscale(gfp, 1); SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); SET__OPTION(msfix, abr_switch_map[r].nsmsfix, -1); SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); /* ABR seems to have big problems with clipping, especially at low bitrates */ /* so we compensate for that here by using a scale value depending on bitrate */ lame_set_scale(gfp, lame_get_scale(gfp) * abr_switch_map[r].scale); SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); if (abr_switch_map[r].masking_adj > 0) { SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * .9, 0); } else { SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * 1.1, 0); } SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); (void) abr_switch_map[r].abr_kbps; gfp->internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.); return preset; } int apply_preset(lame_global_flags * gfp, int preset, int enforce) { /*translate legacy presets */ switch (preset) { case R3MIX: { preset = V3; (void) lame_set_VBR(gfp, vbr_mtrh); break; } case MEDIUM: case MEDIUM_FAST: { preset = V4; (void) lame_set_VBR(gfp, vbr_mtrh); break; } case STANDARD: case STANDARD_FAST: { preset = V2; (void) lame_set_VBR(gfp, vbr_mtrh); break; } case EXTREME: case EXTREME_FAST: { preset = V0; (void) lame_set_VBR(gfp, vbr_mtrh); break; } case INSANE: { preset = 320; gfp->preset = preset; (void) apply_abr_preset(gfp, preset, enforce); lame_set_VBR(gfp, vbr_off); return preset; } } gfp->preset = preset; { switch (preset) { case V9: apply_vbr_preset(gfp, 9, enforce); return preset; case V8: apply_vbr_preset(gfp, 8, enforce); return preset; case V7: apply_vbr_preset(gfp, 7, enforce); return preset; case V6: apply_vbr_preset(gfp, 6, enforce); return preset; case V5: apply_vbr_preset(gfp, 5, enforce); return preset; case V4: apply_vbr_preset(gfp, 4, enforce); return preset; case V3: apply_vbr_preset(gfp, 3, enforce); return preset; case V2: apply_vbr_preset(gfp, 2, enforce); return preset; case V1: apply_vbr_preset(gfp, 1, enforce); return preset; case V0: apply_vbr_preset(gfp, 0, enforce); return preset; default: break; } } if (8 <= preset && preset <= 320) { return apply_abr_preset(gfp, preset, enforce); } gfp->preset = 0; /*no corresponding preset found */ return preset; } ================================================ FILE: app/jni/libmp3lame/psymodel.c ================================================ /* * psymodel.c * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 2001-2002 Naoki Shibata * Copyright (c) 2000-2003 Takehiro Tominaga * Copyright (c) 2000-2011 Robert Hegemann * Copyright (c) 2000-2005 Gabriel Bouvigne * Copyright (c) 2000-2005 Alexander Leidinger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: psymodel.c,v 1.209 2011/05/24 20:45:55 robert Exp $ */ /* PSYCHO ACOUSTICS This routine computes the psycho acoustics, delayed by one granule. Input: buffer of PCM data (1024 samples). This window should be centered over the 576 sample granule window. The routine will compute the psycho acoustics for this granule, but return the psycho acoustics computed for the *previous* granule. This is because the block type of the previous granule can only be determined after we have computed the psycho acoustics for the following granule. Output: maskings and energies for each scalefactor band. block type, PE, and some correlation measures. The PE is used by CBR modes to determine if extra bits from the bit reservoir should be used. The correlation measures are used to determine mid/side or regular stereo. */ /* Notation: barks: a non-linear frequency scale. Mapping from frequency to barks is given by freq2bark() scalefactor bands: The spectrum (frequencies) are broken into SBMAX "scalefactor bands". Thes bands are determined by the MPEG ISO spec. In the noise shaping/quantization code, we allocate bits among the partition bands to achieve the best possible quality partition bands: The spectrum is also broken into about 64 "partition bands". Each partition band is about .34 barks wide. There are about 2-5 partition bands for each scalefactor band. LAME computes all psycho acoustic information for each partition band. Then at the end of the computations, this information is mapped to scalefactor bands. The energy in each scalefactor band is taken as the sum of the energy in all partition bands which overlap the scalefactor band. The maskings can be computed in the same way (and thus represent the average masking in that band) or by taking the minmum value multiplied by the number of partition bands used (which represents a minimum masking in that band). */ /* The general outline is as follows: 1. compute the energy in each partition band 2. compute the tonality in each partition band 3. compute the strength of each partion band "masker" 4. compute the masking (via the spreading function applied to each masker) 5. Modifications for mid/side masking. Each partition band is considiered a "masker". The strength of the i'th masker in band j is given by: s3(bark(i)-bark(j))*strength(i) The strength of the masker is a function of the energy and tonality. The more tonal, the less masking. LAME uses a simple linear formula (controlled by NMT and TMN) which says the strength is given by the energy divided by a linear function of the tonality. */ /* s3() is the "spreading function". It is given by a formula determined via listening tests. The total masking in the j'th partition band is the sum over all maskings i. It is thus given by the convolution of the strength with s3(), the "spreading function." masking(j) = sum_over_i s3(i-j)*strength(i) = s3 o strength where "o" = convolution operator. s3 is given by a formula determined via listening tests. It is normalized so that s3 o 1 = 1. Note: instead of a simple convolution, LAME also has the option of using "additive masking" The most critical part is step 2, computing the tonality of each partition band. LAME has two tonality estimators. The first is based on the ISO spec, and measures how predictiable the signal is over time. The more predictable, the more tonal. The second measure is based on looking at the spectrum of a single granule. The more peaky the spectrum, the more tonal. By most indications, the latter approach is better. Finally, in step 5, the maskings for the mid and side channel are possibly increased. Under certain circumstances, noise in the mid & side channels is assumed to also be masked by strong maskers in the L or R channels. Other data computed by the psy-model: ms_ratio side-channel / mid-channel masking ratio (for previous granule) ms_ratio_next side-channel / mid-channel masking ratio for this granule percep_entropy[2] L and R values (prev granule) of PE - A measure of how much pre-echo is in the previous granule percep_entropy_MS[2] mid and side channel values (prev granule) of percep_entropy energy[4] L,R,M,S energy in each channel, prev granule blocktype_d[2] block type to use for previous granule */ #ifdef HAVE_CONFIG_H # include #endif //#include <__clang_cuda_math_forward_declares.h> #include #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "psymodel.h" #include "lame_global_flags.h" #include "fft.h" #include "lame-analysis.h" #define NSFIRLEN 21 #ifdef M_LN10 #define LN_TO_LOG10 (M_LN10/10) #else #define LN_TO_LOG10 0.2302585093 #endif /* L3psycho_anal. Compute psycho acoustics. Data returned to the calling program must be delayed by one granule. This is done in two places. If we do not need to know the blocktype, the copying can be done here at the top of the program: we copy the data for the last granule (computed during the last call) before it is overwritten with the new data. It looks like this: 0. static psymodel_data 1. calling_program_data = psymodel_data 2. compute psymodel_data For data which needs to know the blocktype, the copying must be done at the end of this loop, and the old values must be saved: 0. static psymodel_data_old 1. compute psymodel_data 2. compute possible block type of this granule 3. compute final block type of previous granule based on #2. 4. calling_program_data = psymodel_data_old 5. psymodel_data_old = psymodel_data */ /* psycho_loudness_approx jd - 2001 mar 12 in: energy - BLKSIZE/2 elements of frequency magnitudes ^ 2 gfp - uses out_samplerate, ATHtype (also needed for ATHformula) returns: loudness^2 approximation, a positive value roughly tuned for a value of 1.0 for signals near clipping. notes: When calibrated, feeding this function binary white noise at sample values +32767 or -32768 should return values that approach 3. ATHformula is used to approximate an equal loudness curve. future: Data indicates that the shape of the equal loudness curve varies with intensity. This function might be improved by using an equal loudness curve shaped for typical playback levels (instead of the ATH, that is shaped for the threshold). A flexible realization might simply bend the existing ATH curve to achieve the desired shape. However, the potential gain may not be enough to justify an effort. */ static FLOAT psycho_loudness_approx(FLOAT const *energy, FLOAT const *eql_w) { int i; FLOAT loudness_power; loudness_power = 0.0; /* apply weights to power in freq. bands */ for (i = 0; i < BLKSIZE / 2; ++i) loudness_power += energy[i] * eql_w[i]; loudness_power *= VO_SCALE; return loudness_power; } /* mask_add optimization */ /* init the limit values used to avoid computing log in mask_add when it is not necessary */ /* For example, with i = 10*log10(m2/m1)/10*16 (= log10(m2/m1)*16) * * abs(i)>8 is equivalent (as i is an integer) to * abs(i)>=9 * i>=9 || i<=-9 * equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16 * or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16) * log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16 * exp10 is strictly increasing thus this is equivalent to * m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants */ #define I1LIMIT 8 /* as in if(i>8) */ #define I2LIMIT 23 /* as in if(i>24) -> changed 23 */ #define MLIMIT 15 /* as in if(m<15) */ static FLOAT ma_max_i1; static FLOAT ma_max_i2; static FLOAT ma_max_m; /*This is the masking table: According to tonality, values are going from 0dB (TMN) to 9.3dB (NMT). After additive masking computation, 8dB are added, so final values are going from 8dB to 17.3dB */ static const FLOAT tab[] = { 1.0 /*pow(10, -0) */ , 0.79433 /*pow(10, -0.1) */ , 0.63096 /*pow(10, -0.2) */ , 0.63096 /*pow(10, -0.2) */ , 0.63096 /*pow(10, -0.2) */ , 0.63096 /*pow(10, -0.2) */ , 0.63096 /*pow(10, -0.2) */ , 0.25119 /*pow(10, -0.6) */ , 0.11749 /*pow(10, -0.93) */ }; static const int tab_mask_add_delta[] = { 2, 2, 2, 1, 1, 1, 0, 0, -1 }; #define STATIC_ASSERT_EQUAL_DIMENSION(A,B) {extern char static_assert_##A[dimension_of(A) == dimension_of(B) ? 1 : -1];(void) static_assert_##A;} inline static int mask_add_delta(int i) { STATIC_ASSERT_EQUAL_DIMENSION(tab_mask_add_delta,tab); assert(i < (int)dimension_of(tab)); return tab_mask_add_delta[i]; } static void init_mask_add_max_values(void) { ma_max_i1 = pow(10, (I1LIMIT + 1) / 16.0); ma_max_i2 = pow(10, (I2LIMIT + 1) / 16.0); ma_max_m = pow(10, (MLIMIT) / 10.0); } /* addition of simultaneous masking Naoki Shibata 2000/7 */ inline static FLOAT vbrpsy_mask_add(FLOAT m1, FLOAT m2, int b, int delta) { static const FLOAT table2[] = { 1.33352 * 1.33352, 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497, 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, 1.22321 * 1.22321, 1.14758 * 1.14758, 1 }; FLOAT ratio; if (m1 < 0) { m1 = 0; } if (m2 < 0) { m2 = 0; } if (m1 <= 0) { return m2; } if (m2 <= 0) { return m1; } if (m2 > m1) { ratio = m2 / m1; } else { ratio = m1 / m2; } if (abs(b) <= delta) { /* approximately, 1 bark = 3 partitions */ /* originally 'if(i > 8)' */ if (ratio >= ma_max_i1) { return m1 + m2; } else { int i = (int) (FAST_LOG10_X(ratio, 16.0f)); return (m1 + m2) * table2[i]; } } if (ratio < ma_max_i2) { return m1 + m2; } if (m1 < m2) { m1 = m2; } return m1; } /* short block threshold calculation (part 2) partition band bo_s[sfb] is at the transition from scalefactor band sfb to the next one sfb+1; enn and thmm have to be split between them */ static void convert_partition2scalefac(PsyConst_CB2SB_t const *const gd, FLOAT const *eb, FLOAT const *thr, FLOAT enn_out[], FLOAT thm_out[]) { FLOAT enn, thmm; int sb, b, n = gd->n_sb; enn = thmm = 0.0f; for (sb = b = 0; sb < n; ++b, ++sb) { int const bo_sb = gd->bo[sb]; int const npart = gd->npart; int const b_lim = bo_sb < npart ? bo_sb : npart; while (b < b_lim) { assert(eb[b] >= 0); /* iff failed, it may indicate some index error elsewhere */ assert(thr[b] >= 0); enn += eb[b]; thmm += thr[b]; b++; } if (b >= npart) { enn_out[sb] = enn; thm_out[sb] = thmm; ++sb; break; } assert(eb[b] >= 0); /* iff failed, it may indicate some index error elsewhere */ assert(thr[b] >= 0); { /* at transition sfb -> sfb+1 */ FLOAT const w_curr = gd->bo_weight[sb]; FLOAT const w_next = 1.0f - w_curr; enn += w_curr * eb[b]; thmm += w_curr * thr[b]; enn_out[sb] = enn; thm_out[sb] = thmm; enn = w_next * eb[b]; thmm = w_next * thr[b]; } } /* zero initialize the rest */ for (; sb < n; ++sb) { enn_out[sb] = 0; thm_out[sb] = 0; } } static void convert_partition2scalefac_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn, int sblock) { PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s; FLOAT enn[SBMAX_s], thm[SBMAX_s]; int sb; convert_partition2scalefac(gds, eb, thr, enn, thm); for (sb = 0; sb < SBMAX_s; ++sb) { psv->en[chn].s[sb][sblock] = enn[sb]; psv->thm[chn].s[sb][sblock] = thm[sb]; } } /* longblock threshold calculation (part 2) */ static void convert_partition2scalefac_l(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn) { PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l; FLOAT *enn = &psv->en[chn].l[0]; FLOAT *thm = &psv->thm[chn].l[0]; convert_partition2scalefac(gdl, eb, thr, enn, thm); } static void convert_partition2scalefac_l_to_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn) { PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->l_to_s; FLOAT enn[SBMAX_s], thm[SBMAX_s]; int sb, sblock; convert_partition2scalefac(gds, eb, thr, enn, thm); for (sb = 0; sb < SBMAX_s; ++sb) { FLOAT const scale = 1. / 64.f; FLOAT const tmp_enn = enn[sb]; FLOAT const tmp_thm = thm[sb] * scale; for (sblock = 0; sblock < 3; ++sblock) { psv->en[chn].s[sb][sblock] = tmp_enn; psv->thm[chn].s[sb][sblock] = tmp_thm; } } } static inline FLOAT NS_INTERP(FLOAT x, FLOAT y, FLOAT r) { /* was pow((x),(r))*pow((y),1-(r)) */ if (r >= 1.0f) return x; /* 99.7% of the time */ if (r <= 0.0f) return y; if (y > 0.0f) return powf(x / y, r) * y; /* rest of the time */ return 0.0f; /* never happens */ } static FLOAT pecalc_s(III_psy_ratio const *mr, FLOAT masking_lower) { FLOAT pe_s; static const FLOAT regcoef_s[] = { 11.8, /* these values are tuned only for 44.1kHz... */ 13.6, 17.2, 32, 46.5, 51.3, 57.5, 67.1, 71.5, 84.6, 97.6, 130, /* 255.8 */ }; unsigned int sb, sblock; pe_s = 1236.28f / 4; for (sb = 0; sb < SBMAX_s - 1; sb++) { for (sblock = 0; sblock < 3; sblock++) { FLOAT const thm = mr->thm.s[sb][sblock]; assert(sb < dimension_of(regcoef_s)); if (thm > 0.0f) { FLOAT const x = thm * masking_lower; FLOAT const en = mr->en.s[sb][sblock]; if (en > x) { if (en > x * 1e10f) { pe_s += regcoef_s[sb] * (10.0f * LOG10); } else { assert(x > 0); pe_s += regcoef_s[sb] * FAST_LOG10(en / x); } } } } } return pe_s; } static FLOAT pecalc_l(III_psy_ratio const *mr, FLOAT masking_lower) { FLOAT pe_l; static const FLOAT regcoef_l[] = { 6.8, /* these values are tuned only for 44.1kHz... */ 5.8, 5.8, 6.4, 6.5, 9.9, 12.1, 14.4, 15, 18.9, 21.6, 26.9, 34.2, 40.2, 46.8, 56.5, 60.7, 73.9, 85.7, 93.4, 126.1, /* 241.3 */ }; unsigned int sb; pe_l = 1124.23f / 4; for (sb = 0; sb < SBMAX_l - 1; sb++) { FLOAT const thm = mr->thm.l[sb]; assert(sb < dimension_of(regcoef_l)); if (thm > 0.0f) { FLOAT const x = thm * masking_lower; FLOAT const en = mr->en.l[sb]; if (en > x) { if (en > x * 1e10f) { pe_l += regcoef_l[sb] * (10.0f * LOG10); } else { assert(x > 0); pe_l += regcoef_l[sb] * FAST_LOG10(en / x); } } } } return pe_l; } static void calc_energy(PsyConst_CB2SB_t const *l, FLOAT const *fftenergy, FLOAT * eb, FLOAT * max, FLOAT * avg) { int b, j; for (b = j = 0; b < l->npart; ++b) { FLOAT ebb = 0, m = 0; int i; for (i = 0; i < l->numlines[b]; ++i, ++j) { FLOAT const el = fftenergy[j]; assert(el >= 0); ebb += el; if (m < el) m = el; } eb[b] = ebb; max[b] = m; avg[b] = ebb * l->rnumlines[b]; assert(l->rnumlines[b] >= 0); assert(ebb >= 0); assert(eb[b] >= 0); assert(max[b] >= 0); assert(avg[b] >= 0); } } static void calc_mask_index_l(lame_internal_flags const *gfc, FLOAT const *max, FLOAT const *avg, unsigned char *mask_idx) { PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l; FLOAT m, a; int b, k; int const last_tab_entry = sizeof(tab) / sizeof(tab[0]) - 1; b = 0; a = avg[b] + avg[b + 1]; assert(a >= 0); if (a > 0.0f) { m = max[b]; if (m < max[b + 1]) m = max[b + 1]; assert((gdl->numlines[b] + gdl->numlines[b + 1] - 1) > 0); a = 20.0f * (m * 2.0f - a) / (a * (gdl->numlines[b] + gdl->numlines[b + 1] - 1)); k = (int) a; if (k > last_tab_entry) k = last_tab_entry; mask_idx[b] = k; } else { mask_idx[b] = 0; } for (b = 1; b < gdl->npart - 1; b++) { a = avg[b - 1] + avg[b] + avg[b + 1]; assert(a >= 0); if (a > 0.0f) { m = max[b - 1]; if (m < max[b]) m = max[b]; if (m < max[b + 1]) m = max[b + 1]; assert((gdl->numlines[b - 1] + gdl->numlines[b] + gdl->numlines[b + 1] - 1) > 0); a = 20.0f * (m * 3.0f - a) / (a * (gdl->numlines[b - 1] + gdl->numlines[b] + gdl->numlines[b + 1] - 1)); k = (int) a; if (k > last_tab_entry) k = last_tab_entry; mask_idx[b] = k; } else { mask_idx[b] = 0; } } assert(b > 0); assert(b == gdl->npart - 1); a = avg[b - 1] + avg[b]; assert(a >= 0); if (a > 0.0f) { m = max[b - 1]; if (m < max[b]) m = max[b]; assert((gdl->numlines[b - 1] + gdl->numlines[b] - 1) > 0); a = 20.0f * (m * 2.0f - a) / (a * (gdl->numlines[b - 1] + gdl->numlines[b] - 1)); k = (int) a; if (k > last_tab_entry) k = last_tab_entry; mask_idx[b] = k; } else { mask_idx[b] = 0; } assert(b == (gdl->npart - 1)); } static void vbrpsy_compute_fft_l(lame_internal_flags * gfc, const sample_t * const buffer[2], int chn, int gr_out, FLOAT fftenergy[HBLKSIZE], FLOAT(*wsamp_l)[BLKSIZE]) { SessionConfig_t const *const cfg = &gfc->cfg; PsyStateVar_t *psv = &gfc->sv_psy; plotting_data *plt = cfg->analysis ? gfc->pinfo : 0; int j; if (chn < 2) { fft_long(gfc, *wsamp_l, chn, buffer); } else if (chn == 2) { FLOAT const sqrt2_half = SQRT2 * 0.5f; /* FFT data for mid and side channel is derived from L & R */ for (j = BLKSIZE - 1; j >= 0; --j) { FLOAT const l = wsamp_l[0][j]; FLOAT const r = wsamp_l[1][j]; wsamp_l[0][j] = (l + r) * sqrt2_half; wsamp_l[1][j] = (l - r) * sqrt2_half; } } /********************************************************************* * compute energies *********************************************************************/ fftenergy[0] = wsamp_l[0][0]; fftenergy[0] *= fftenergy[0]; for (j = BLKSIZE / 2 - 1; j >= 0; --j) { FLOAT const re = (*wsamp_l)[BLKSIZE / 2 - j]; FLOAT const im = (*wsamp_l)[BLKSIZE / 2 + j]; fftenergy[BLKSIZE / 2 - j] = (re * re + im * im) * 0.5f; } /* total energy */ { FLOAT totalenergy = 0.0f; for (j = 11; j < HBLKSIZE; j++) totalenergy += fftenergy[j]; psv->tot_ener[chn] = totalenergy; } if (plt) { for (j = 0; j < HBLKSIZE; j++) { plt->energy[gr_out][chn][j] = plt->energy_save[chn][j]; plt->energy_save[chn][j] = fftenergy[j]; } } } static void vbrpsy_compute_fft_s(lame_internal_flags const *gfc, const sample_t * const buffer[2], int chn, int sblock, FLOAT(*fftenergy_s)[HBLKSIZE_s], FLOAT(*wsamp_s)[3][BLKSIZE_s]) { int j; if (sblock == 0 && chn < 2) { fft_short(gfc, *wsamp_s, chn, buffer); } if (chn == 2) { FLOAT const sqrt2_half = SQRT2 * 0.5f; /* FFT data for mid and side channel is derived from L & R */ for (j = BLKSIZE_s - 1; j >= 0; --j) { FLOAT const l = wsamp_s[0][sblock][j]; FLOAT const r = wsamp_s[1][sblock][j]; wsamp_s[0][sblock][j] = (l + r) * sqrt2_half; wsamp_s[1][sblock][j] = (l - r) * sqrt2_half; } } /********************************************************************* * compute energies *********************************************************************/ fftenergy_s[sblock][0] = (*wsamp_s)[sblock][0]; fftenergy_s[sblock][0] *= fftenergy_s[sblock][0]; for (j = BLKSIZE_s / 2 - 1; j >= 0; --j) { FLOAT const re = (*wsamp_s)[sblock][BLKSIZE_s / 2 - j]; FLOAT const im = (*wsamp_s)[sblock][BLKSIZE_s / 2 + j]; fftenergy_s[sblock][BLKSIZE_s / 2 - j] = (re * re + im * im) * 0.5f; } } /********************************************************************* * compute loudness approximation (used for ATH auto-level adjustment) *********************************************************************/ static void vbrpsy_compute_loudness_approximation_l(lame_internal_flags * gfc, int gr_out, int chn, const FLOAT fftenergy[HBLKSIZE]) { PsyStateVar_t *psv = &gfc->sv_psy; if (chn < 2) { /*no loudness for mid/side ch */ gfc->ov_psy.loudness_sq[gr_out][chn] = psv->loudness_sq_save[chn]; psv->loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc->ATH->eql_w); } } /********************************************************************** * Apply HPF of fs/4 to the input signal. * This is used for attack detection / handling. **********************************************************************/ static void vbrpsy_attack_detection(lame_internal_flags * gfc, const sample_t * const buffer[2], int gr_out, III_psy_ratio masking_ratio[2][2], III_psy_ratio masking_MS_ratio[2][2], FLOAT energy[4], FLOAT sub_short_factor[4][3], int ns_attacks[4][4], int uselongblock[2]) { FLOAT ns_hpfsmpl[2][576]; SessionConfig_t const *const cfg = &gfc->cfg; PsyStateVar_t *const psv = &gfc->sv_psy; plotting_data *plt = cfg->analysis ? gfc->pinfo : 0; int const n_chn_out = cfg->channels_out; /* chn=2 and 3 = Mid and Side channels */ int const n_chn_psy = (cfg->mode == JOINT_STEREO) ? 4 : n_chn_out; int chn, i, j; memset(&ns_hpfsmpl[0][0], 0, sizeof(ns_hpfsmpl)); /* Don't copy the input buffer into a temporary buffer */ /* unroll the loop 2 times */ for (chn = 0; chn < n_chn_out; chn++) { static const FLOAT fircoef[] = { -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2, -5.52212e-17 * 2, -0.313819 * 2 }; /* apply high pass filter of fs/4 */ const sample_t *const firbuf = &buffer[chn][576 - 350 - NSFIRLEN + 192]; assert(dimension_of(fircoef) == ((NSFIRLEN - 1) / 2)); for (i = 0; i < 576; i++) { FLOAT sum1, sum2; sum1 = firbuf[i + 10]; sum2 = 0.0; for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { sum1 += fircoef[j] * (firbuf[i + j] + firbuf[i + NSFIRLEN - j]); sum2 += fircoef[j + 1] * (firbuf[i + j + 1] + firbuf[i + NSFIRLEN - j - 1]); } ns_hpfsmpl[chn][i] = sum1 + sum2; } masking_ratio[gr_out][chn].en = psv->en[chn]; masking_ratio[gr_out][chn].thm = psv->thm[chn]; if (n_chn_psy > 2) { /* MS maskings */ /*percep_MS_entropy [chn-2] = gfc -> pe [chn]; */ masking_MS_ratio[gr_out][chn].en = psv->en[chn + 2]; masking_MS_ratio[gr_out][chn].thm = psv->thm[chn + 2]; } } for (chn = 0; chn < n_chn_psy; chn++) { FLOAT attack_intensity[12]; FLOAT en_subshort[12]; FLOAT en_short[4] = { 0, 0, 0, 0 }; FLOAT const *pf = ns_hpfsmpl[chn & 1]; int ns_uselongblock = 1; if (chn == 2) { for (i = 0, j = 576; j > 0; ++i, --j) { FLOAT const l = ns_hpfsmpl[0][i]; FLOAT const r = ns_hpfsmpl[1][i]; ns_hpfsmpl[0][i] = l + r; ns_hpfsmpl[1][i] = l - r; } } /*************************************************************** * determine the block type (window type) ***************************************************************/ /* calculate energies of each sub-shortblocks */ for (i = 0; i < 3; i++) { en_subshort[i] = psv->last_en_subshort[chn][i + 6]; assert(psv->last_en_subshort[chn][i + 4] > 0); attack_intensity[i] = en_subshort[i] / psv->last_en_subshort[chn][i + 4]; en_short[0] += en_subshort[i]; } for (i = 0; i < 9; i++) { FLOAT const *const pfe = pf + 576 / 9; FLOAT p = 1.; for (; pf < pfe; pf++) if (p < fabs(*pf)) p = fabs(*pf); psv->last_en_subshort[chn][i] = en_subshort[i + 3] = p; en_short[1 + i / 3] += p; if (p > en_subshort[i + 3 - 2]) { assert(en_subshort[i + 3 - 2] > 0); p = p / en_subshort[i + 3 - 2]; } else if (en_subshort[i + 3 - 2] > p * 10.0f) { assert(p > 0); p = en_subshort[i + 3 - 2] / (p * 10.0f); } else { p = 0.0; } attack_intensity[i + 3] = p; } /* pulse like signal detection for fatboy.wav and so on */ for (i = 0; i < 3; ++i) { FLOAT const enn = en_subshort[i * 3 + 3] + en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5]; FLOAT factor = 1.f; if (en_subshort[i * 3 + 5] * 6 < enn) { factor *= 0.5f; if (en_subshort[i * 3 + 4] * 6 < enn) { factor *= 0.5f; } } sub_short_factor[chn][i] = factor; } if (plt) { FLOAT x = attack_intensity[0]; for (i = 1; i < 12; i++) { if (x < attack_intensity[i]) { x = attack_intensity[i]; } } plt->ers[gr_out][chn] = plt->ers_save[chn]; plt->ers_save[chn] = x; } /* compare energies between sub-shortblocks */ { FLOAT x = gfc->cd_psy->attack_threshold[chn]; for (i = 0; i < 12; i++) { if (ns_attacks[chn][i / 3] == 0) { if (attack_intensity[i] > x) { ns_attacks[chn][i / 3] = (i % 3) + 1; } } } } /* should have energy change between short blocks, in order to avoid periodic signals */ /* Good samples to show the effect are Trumpet test songs */ /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */ /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */ for (i = 1; i < 4; i++) { FLOAT const u = en_short[i - 1]; FLOAT const v = en_short[i]; FLOAT const m = Max(u, v); if (m < 40000) { /* (2) */ if (u < 1.7f * v && v < 1.7f * u) { /* (1) */ if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) { ns_attacks[chn][0] = 0; } ns_attacks[chn][i] = 0; } } } if (ns_attacks[chn][0] <= psv->last_attacks[chn]) { ns_attacks[chn][0] = 0; } if (psv->last_attacks[chn] == 3 || ns_attacks[chn][0] + ns_attacks[chn][1] + ns_attacks[chn][2] + ns_attacks[chn][3]) { ns_uselongblock = 0; if (ns_attacks[chn][1] && ns_attacks[chn][0]) { ns_attacks[chn][1] = 0; } if (ns_attacks[chn][2] && ns_attacks[chn][1]) { ns_attacks[chn][2] = 0; } if (ns_attacks[chn][3] && ns_attacks[chn][2]) { ns_attacks[chn][3] = 0; } } if (chn < 2) { uselongblock[chn] = ns_uselongblock; } else { if (ns_uselongblock == 0) { uselongblock[0] = uselongblock[1] = 0; } } /* there is a one granule delay. Copy maskings computed last call * into masking_ratio to return to calling program. */ energy[chn] = psv->tot_ener[chn]; } } static void vbrpsy_skip_masking_s(lame_internal_flags * gfc, int chn, int sblock) { if (sblock == 0) { FLOAT *nbs2 = &gfc->sv_psy.nb_s2[chn][0]; FLOAT *nbs1 = &gfc->sv_psy.nb_s1[chn][0]; int const n = gfc->cd_psy->s.npart; int b; for (b = 0; b < n; b++) { nbs2[b] = nbs1[b]; } } } static void vbrpsy_calc_mask_index_s(lame_internal_flags const *gfc, FLOAT const *max, FLOAT const *avg, unsigned char *mask_idx) { PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s; FLOAT m, a; int b, k; int const last_tab_entry = dimension_of(tab) - 1; b = 0; a = avg[b] + avg[b + 1]; assert(a >= 0); if (a > 0.0f) { m = max[b]; if (m < max[b + 1]) m = max[b + 1]; assert((gds->numlines[b] + gds->numlines[b + 1] - 1) > 0); a = 20.0f * (m * 2.0f - a) / (a * (gds->numlines[b] + gds->numlines[b + 1] - 1)); k = (int) a; if (k > last_tab_entry) k = last_tab_entry; mask_idx[b] = k; } else { mask_idx[b] = 0; } for (b = 1; b < gds->npart - 1; b++) { a = avg[b - 1] + avg[b] + avg[b + 1]; assert(b + 1 < gds->npart); assert(a >= 0); if (a > 0.0) { m = max[b - 1]; if (m < max[b]) m = max[b]; if (m < max[b + 1]) m = max[b + 1]; assert((gds->numlines[b - 1] + gds->numlines[b] + gds->numlines[b + 1] - 1) > 0); a = 20.0f * (m * 3.0f - a) / (a * (gds->numlines[b - 1] + gds->numlines[b] + gds->numlines[b + 1] - 1)); k = (int) a; if (k > last_tab_entry) k = last_tab_entry; mask_idx[b] = k; } else { mask_idx[b] = 0; } } assert(b > 0); assert(b == gds->npart - 1); a = avg[b - 1] + avg[b]; assert(a >= 0); if (a > 0.0f) { m = max[b - 1]; if (m < max[b]) m = max[b]; assert((gds->numlines[b - 1] + gds->numlines[b] - 1) > 0); a = 20.0f * (m * 2.0f - a) / (a * (gds->numlines[b - 1] + gds->numlines[b] - 1)); k = (int) a; if (k > last_tab_entry) k = last_tab_entry; mask_idx[b] = k; } else { mask_idx[b] = 0; } assert(b == (gds->npart - 1)); } static void vbrpsy_compute_masking_s(lame_internal_flags * gfc, const FLOAT(*fftenergy_s)[HBLKSIZE_s], FLOAT * eb, FLOAT * thr, int chn, int sblock) { PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s; FLOAT max[CBANDS], avg[CBANDS]; int i, j, b; unsigned char mask_idx_s[CBANDS]; memset(max, 0, sizeof(max)); memset(avg, 0, sizeof(avg)); for (b = j = 0; b < gds->npart; ++b) { FLOAT ebb = 0, m = 0; int const n = gds->numlines[b]; for (i = 0; i < n; ++i, ++j) { FLOAT const el = fftenergy_s[sblock][j]; ebb += el; if (m < el) m = el; } eb[b] = ebb; assert(ebb >= 0); max[b] = m; assert(n > 0); avg[b] = ebb * gds->rnumlines[b]; assert(avg[b] >= 0); } assert(b == gds->npart); assert(j == 129); vbrpsy_calc_mask_index_s(gfc, max, avg, mask_idx_s); for (j = b = 0; b < gds->npart; b++) { int kk = gds->s3ind[b][0]; int const last = gds->s3ind[b][1]; int const delta = mask_add_delta(mask_idx_s[b]); int dd, dd_n; FLOAT x, ecb, avg_mask; FLOAT const masking_lower = gds->masking_lower[b] * gfc->sv_qnt.masking_lower; dd = mask_idx_s[kk]; dd_n = 1; ecb = gds->s3[j] * eb[kk] * tab[mask_idx_s[kk]]; ++j, ++kk; while (kk <= last) { dd += mask_idx_s[kk]; dd_n += 1; x = gds->s3[j] * eb[kk] * tab[mask_idx_s[kk]]; ecb = vbrpsy_mask_add(ecb, x, kk - b, delta); ++j, ++kk; } dd = (1 + 2 * dd) / (2 * dd_n); avg_mask = tab[dd] * 0.5f; ecb *= avg_mask; #if 0 /* we can do PRE ECHO control now here, or do it later */ if (psv->blocktype_old[chn & 0x01] == SHORT_TYPE) { /* limit calculated threshold by even older granule */ FLOAT const t1 = rpelev_s * psv->nb_s1[chn][b]; FLOAT const t2 = rpelev2_s * psv->nb_s2[chn][b]; FLOAT const tm = (t2 > 0) ? Min(ecb, t2) : ecb; thr[b] = (t1 > 0) ? NS_INTERP(Min(tm, t1), ecb, 0.6) : ecb; } else { /* limit calculated threshold by older granule */ FLOAT const t1 = rpelev_s * psv->nb_s1[chn][b]; thr[b] = (t1 > 0) ? NS_INTERP(Min(ecb, t1), ecb, 0.6) : ecb; } #else /* we do it later */ thr[b] = ecb; #endif psv->nb_s2[chn][b] = psv->nb_s1[chn][b]; psv->nb_s1[chn][b] = ecb; { /* if THR exceeds EB, the quantization routines will take the difference * from other bands. in case of strong tonal samples (tonaltest.wav) * this leads to heavy distortions. that's why we limit THR here. */ x = max[b]; x *= gds->minval[b]; x *= avg_mask; if (thr[b] > x) { thr[b] = x; } } if (masking_lower > 1) { thr[b] *= masking_lower; } if (thr[b] > eb[b]) { thr[b] = eb[b]; } if (masking_lower < 1) { thr[b] *= masking_lower; } assert(thr[b] >= 0); } for (; b < CBANDS; ++b) { eb[b] = 0; thr[b] = 0; } } static void vbrpsy_compute_masking_l(lame_internal_flags * gfc, const FLOAT fftenergy[HBLKSIZE], FLOAT eb_l[CBANDS], FLOAT thr[CBANDS], int chn) { PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l; FLOAT max[CBANDS], avg[CBANDS]; unsigned char mask_idx_l[CBANDS + 2]; int k, b; /********************************************************************* * Calculate the energy and the tonality of each partition. *********************************************************************/ calc_energy(gdl, fftenergy, eb_l, max, avg); calc_mask_index_l(gfc, max, avg, mask_idx_l); /********************************************************************* * convolve the partitioned energy and unpredictability * with the spreading function, s3_l[b][k] ********************************************************************/ k = 0; for (b = 0; b < gdl->npart; b++) { FLOAT x, ecb, avg_mask, t; FLOAT const masking_lower = gdl->masking_lower[b] * gfc->sv_qnt.masking_lower; /* convolve the partitioned energy with the spreading function */ int kk = gdl->s3ind[b][0]; int const last = gdl->s3ind[b][1]; int const delta = mask_add_delta(mask_idx_l[b]); int dd = 0, dd_n = 0; dd = mask_idx_l[kk]; dd_n += 1; ecb = gdl->s3[k] * eb_l[kk] * tab[mask_idx_l[kk]]; ++k, ++kk; while (kk <= last) { dd += mask_idx_l[kk]; dd_n += 1; x = gdl->s3[k] * eb_l[kk] * tab[mask_idx_l[kk]]; t = vbrpsy_mask_add(ecb, x, kk - b, delta); #if 0 ecb += eb_l[kk]; if (ecb > t) { ecb = t; } #else ecb = t; #endif ++k, ++kk; } dd = (1 + 2 * dd) / (2 * dd_n); avg_mask = tab[dd] * 0.5f; ecb *= avg_mask; /**** long block pre-echo control ****/ /* dont use long block pre-echo control if previous granule was * a short block. This is to avoid the situation: * frame0: quiet (very low masking) * frame1: surge (triggers short blocks) * frame2: regular frame. looks like pre-echo when compared to * frame0, but all pre-echo was in frame1. */ /* chn=0,1 L and R channels chn=2,3 S and M channels. */ if (psv->blocktype_old[chn & 0x01] == SHORT_TYPE) { FLOAT const ecb_limit = rpelev * psv->nb_l1[chn][b]; if (ecb_limit > 0) { thr[b] = Min(ecb, ecb_limit); } else { /* Robert 071209: Because we don't calculate long block psy when we know a granule should be of short blocks, we don't have any clue how the granule before would have looked like as a long block. So we have to guess a little bit for this END_TYPE block. Most of the time we get away with this sloppyness. (fingers crossed :) The speed increase is worth it. */ thr[b] = Min(ecb, eb_l[b] * NS_PREECHO_ATT2); } } else { FLOAT ecb_limit_2 = rpelev2 * psv->nb_l2[chn][b]; FLOAT ecb_limit_1 = rpelev * psv->nb_l1[chn][b]; FLOAT ecb_limit; if (ecb_limit_2 <= 0) { ecb_limit_2 = ecb; } if (ecb_limit_1 <= 0) { ecb_limit_1 = ecb; } if (psv->blocktype_old[chn & 0x01] == NORM_TYPE) { ecb_limit = Min(ecb_limit_1, ecb_limit_2); } else { ecb_limit = ecb_limit_1; } thr[b] = Min(ecb, ecb_limit); } psv->nb_l2[chn][b] = psv->nb_l1[chn][b]; psv->nb_l1[chn][b] = ecb; { /* if THR exceeds EB, the quantization routines will take the difference * from other bands. in case of strong tonal samples (tonaltest.wav) * this leads to heavy distortions. that's why we limit THR here. */ x = max[b]; x *= gdl->minval[b]; x *= avg_mask; if (thr[b] > x) { thr[b] = x; } } if (masking_lower > 1) { thr[b] *= masking_lower; } if (thr[b] > eb_l[b]) { thr[b] = eb_l[b]; } if (masking_lower < 1) { thr[b] *= masking_lower; } assert(thr[b] >= 0); } for (; b < CBANDS; ++b) { eb_l[b] = 0; thr[b] = 0; } } static void vbrpsy_compute_block_type(SessionConfig_t const *cfg, int *uselongblock) { int chn; if (cfg->short_blocks == short_block_coupled /* force both channels to use the same block type */ /* this is necessary if the frame is to be encoded in ms_stereo. */ /* But even without ms_stereo, FhG does this */ && !(uselongblock[0] && uselongblock[1])) uselongblock[0] = uselongblock[1] = 0; for (chn = 0; chn < cfg->channels_out; chn++) { /* disable short blocks */ if (cfg->short_blocks == short_block_dispensed) { uselongblock[chn] = 1; } if (cfg->short_blocks == short_block_forced) { uselongblock[chn] = 0; } } } static void vbrpsy_apply_block_type(PsyStateVar_t * psv, int nch, int const *uselongblock, int *blocktype_d) { int chn; /* update the blocktype of the previous granule, since it depends on what * happend in this granule */ for (chn = 0; chn < nch; chn++) { int blocktype = NORM_TYPE; /* disable short blocks */ if (uselongblock[chn]) { /* no attack : use long blocks */ assert(psv->blocktype_old[chn] != START_TYPE); if (psv->blocktype_old[chn] == SHORT_TYPE) blocktype = STOP_TYPE; } else { /* attack : use short blocks */ blocktype = SHORT_TYPE; if (psv->blocktype_old[chn] == NORM_TYPE) { psv->blocktype_old[chn] = START_TYPE; } if (psv->blocktype_old[chn] == STOP_TYPE) psv->blocktype_old[chn] = SHORT_TYPE; } blocktype_d[chn] = psv->blocktype_old[chn]; /* value returned to calling program */ psv->blocktype_old[chn] = blocktype; /* save for next call to l3psy_anal */ } } /*************************************************************** * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper ***************************************************************/ static void vbrpsy_compute_MS_thresholds(const FLOAT eb[4][CBANDS], FLOAT thr[4][CBANDS], const FLOAT cb_mld[CBANDS], const FLOAT ath_cb[CBANDS], FLOAT athlower, FLOAT msfix, int n) { FLOAT const msfix2 = msfix * 2.f; FLOAT rside, rmid; int b; for (b = 0; b < n; ++b) { FLOAT const ebM = eb[2][b]; FLOAT const ebS = eb[3][b]; FLOAT const thmL = thr[0][b]; FLOAT const thmR = thr[1][b]; FLOAT thmM = thr[2][b]; FLOAT thmS = thr[3][b]; /* use this fix if L & R masking differs by 2db or less */ /* if db = 10*log10(x2/x1) < 2 */ /* if (x2 < 1.58*x1) { */ if (thmL <= 1.58f * thmR && thmR <= 1.58f * thmL) { FLOAT const mld_m = cb_mld[b] * ebS; FLOAT const mld_s = cb_mld[b] * ebM; FLOAT const tmp_m = Min(thmS, mld_m); FLOAT const tmp_s = Min(thmM, mld_s); rmid = Max(thmM, tmp_m); rside = Max(thmS, tmp_s); } else { rmid = thmM; rside = thmS; } if (msfix > 0.f) { /***************************************************************/ /* Adjust M/S maskings if user set "msfix" */ /***************************************************************/ /* Naoki Shibata 2000 */ FLOAT thmLR, thmMS; FLOAT const ath = ath_cb[b] * athlower; FLOAT const tmp_l = Max(thmL, ath); FLOAT const tmp_r = Max(thmR, ath); thmLR = Min(tmp_l, tmp_r); thmM = Max(rmid, ath); thmS = Max(rside, ath); thmMS = thmM + thmS; if (thmMS > 0.f && (thmLR * msfix2) < thmMS) { FLOAT const f = thmLR * msfix2 / thmMS; thmM *= f; thmS *= f; assert(thmMS > 0.f); } rmid = Min(thmM, rmid); rside = Min(thmS, rside); } if (rmid > ebM) { rmid = ebM; } if (rside > ebS) { rside = ebS; } thr[2][b] = rmid; thr[3][b] = rside; } } /* * NOTE: the bitrate reduction from the inter-channel masking effect is low * compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr does * not use this feature. (Robert 071216) */ int L3psycho_anal_vbr(lame_internal_flags * gfc, const sample_t * const buffer[2], int gr_out, III_psy_ratio masking_ratio[2][2], III_psy_ratio masking_MS_ratio[2][2], FLOAT percep_entropy[2], FLOAT percep_MS_entropy[2], FLOAT energy[4], int blocktype_d[2]) { SessionConfig_t const *const cfg = &gfc->cfg; PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l; PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s; plotting_data *plt = cfg->analysis ? gfc->pinfo : 0; III_psy_xmin last_thm[4]; /* fft and energy calculation */ FLOAT(*wsamp_l)[BLKSIZE]; FLOAT(*wsamp_s)[3][BLKSIZE_s]; FLOAT fftenergy[HBLKSIZE]; FLOAT fftenergy_s[3][HBLKSIZE_s]; FLOAT wsamp_L[2][BLKSIZE]; FLOAT wsamp_S[2][3][BLKSIZE_s]; FLOAT eb[4][CBANDS], thr[4][CBANDS]; FLOAT sub_short_factor[4][3]; FLOAT thmm; FLOAT const pcfact = 0.6f; FLOAT const ath_factor = (cfg->msfix > 0.f) ? (cfg->ATH_offset_factor * gfc->ATH->adjust_factor) : 1.f; const FLOAT(*const_eb)[CBANDS] = (const FLOAT(*)[CBANDS]) eb; const FLOAT(*const_fftenergy_s)[HBLKSIZE_s] = (const FLOAT(*)[HBLKSIZE_s]) fftenergy_s; /* block type */ int ns_attacks[4][4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} }; int uselongblock[2]; /* usual variables like loop indices, etc.. */ int chn, sb, sblock; /* chn=2 and 3 = Mid and Side channels */ int const n_chn_psy = (cfg->mode == JOINT_STEREO) ? 4 : cfg->channels_out; memcpy(&last_thm[0], &psv->thm[0], sizeof(last_thm)); vbrpsy_attack_detection(gfc, buffer, gr_out, masking_ratio, masking_MS_ratio, energy, sub_short_factor, ns_attacks, uselongblock); vbrpsy_compute_block_type(cfg, uselongblock); /* LONG BLOCK CASE */ { for (chn = 0; chn < n_chn_psy; chn++) { int const ch01 = chn & 0x01; wsamp_l = wsamp_L + ch01; vbrpsy_compute_fft_l(gfc, buffer, chn, gr_out, fftenergy, wsamp_l); vbrpsy_compute_loudness_approximation_l(gfc, gr_out, chn, fftenergy); vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn], chn); } if (cfg->mode == JOINT_STEREO) { if ((uselongblock[0] + uselongblock[1]) == 2) { vbrpsy_compute_MS_thresholds(const_eb, thr, gdl->mld_cb, gfc->ATH->cb_l, ath_factor, cfg->msfix, gdl->npart); } } /* TODO: apply adaptive ATH masking here ?? */ for (chn = 0; chn < n_chn_psy; chn++) { convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn); convert_partition2scalefac_l_to_s(gfc, eb[chn], thr[chn], chn); } } /* SHORT BLOCKS CASE */ { int const force_short_block_calc = gfc->cd_psy->force_short_block_calc; for (sblock = 0; sblock < 3; sblock++) { for (chn = 0; chn < n_chn_psy; ++chn) { int const ch01 = chn & 0x01; if (uselongblock[ch01] && !force_short_block_calc) { vbrpsy_skip_masking_s(gfc, chn, sblock); } else { /* compute masking thresholds for short blocks */ wsamp_s = wsamp_S + ch01; vbrpsy_compute_fft_s(gfc, buffer, chn, sblock, fftenergy_s, wsamp_s); vbrpsy_compute_masking_s(gfc, const_fftenergy_s, eb[chn], thr[chn], chn, sblock); } } if (cfg->mode == JOINT_STEREO) { if ((uselongblock[0] + uselongblock[1]) == 0) { vbrpsy_compute_MS_thresholds(const_eb, thr, gds->mld_cb, gfc->ATH->cb_s, ath_factor, cfg->msfix, gds->npart); } } /* TODO: apply adaptive ATH masking here ?? */ for (chn = 0; chn < n_chn_psy; ++chn) { int const ch01 = chn & 0x01; if (!uselongblock[ch01] || force_short_block_calc) { convert_partition2scalefac_s(gfc, eb[chn], thr[chn], chn, sblock); } } } /**** short block pre-echo control ****/ for (chn = 0; chn < n_chn_psy; chn++) { for (sb = 0; sb < SBMAX_s; sb++) { FLOAT new_thmm[3], prev_thm, t1, t2; for (sblock = 0; sblock < 3; sblock++) { thmm = psv->thm[chn].s[sb][sblock]; thmm *= NS_PREECHO_ATT0; t1 = t2 = thmm; if (sblock > 0) { prev_thm = new_thmm[sblock - 1]; } else { prev_thm = last_thm[chn].s[sb][2]; } if (ns_attacks[chn][sblock] >= 2 || ns_attacks[chn][sblock + 1] == 1) { t1 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT1 * pcfact); } thmm = Min(t1, thmm); if (ns_attacks[chn][sblock] == 1) { t2 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT2 * pcfact); } else if ((sblock == 0 && psv->last_attacks[chn] == 3) || (sblock > 0 && ns_attacks[chn][sblock - 1] == 3)) { /* 2nd preceeding block */ switch (sblock) { case 0: prev_thm = last_thm[chn].s[sb][1]; break; case 1: prev_thm = last_thm[chn].s[sb][2]; break; case 2: prev_thm = new_thmm[0]; break; } t2 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT2 * pcfact); } thmm = Min(t1, thmm); thmm = Min(t2, thmm); /* pulse like signal detection for fatboy.wav and so on */ thmm *= sub_short_factor[chn][sblock]; new_thmm[sblock] = thmm; } for (sblock = 0; sblock < 3; sblock++) { psv->thm[chn].s[sb][sblock] = new_thmm[sblock]; } } } } for (chn = 0; chn < n_chn_psy; chn++) { psv->last_attacks[chn] = ns_attacks[chn][2]; } /*************************************************************** * determine final block type ***************************************************************/ vbrpsy_apply_block_type(psv, cfg->channels_out, uselongblock, blocktype_d); /********************************************************************* * compute the value of PE to return ... no delay and advance *********************************************************************/ for (chn = 0; chn < n_chn_psy; chn++) { FLOAT *ppe; int type; III_psy_ratio const *mr; if (chn > 1) { ppe = percep_MS_entropy - 2; type = NORM_TYPE; if (blocktype_d[0] == SHORT_TYPE || blocktype_d[1] == SHORT_TYPE) type = SHORT_TYPE; mr = &masking_MS_ratio[gr_out][chn - 2]; } else { ppe = percep_entropy; type = blocktype_d[chn]; mr = &masking_ratio[gr_out][chn]; } if (type == SHORT_TYPE) { ppe[chn] = pecalc_s(mr, gfc->sv_qnt.masking_lower); } else { ppe[chn] = pecalc_l(mr, gfc->sv_qnt.masking_lower); } if (plt) { plt->pe[gr_out][chn] = ppe[chn]; } } return 0; } /* * The spreading function. Values returned in units of energy */ static FLOAT s3_func(FLOAT bark) { FLOAT tempx, x, tempy, temp; tempx = bark; if (tempx >= 0) tempx *= 3; else tempx *= 1.5; if (tempx >= 0.5 && tempx <= 2.5) { temp = tempx - 0.5; x = 8.0 * (temp * temp - 2.0 * temp); } else x = 0.0; tempx += 0.474; tempy = 15.811389 + 7.5 * tempx - 17.5 * sqrt(1.0 + tempx * tempx); if (tempy <= -60.0) return 0.0; tempx = exp((x + tempy) * LN_TO_LOG10); /* Normalization. The spreading function should be normalized so that: +inf / | s3 [ bark ] d(bark) = 1 / -inf */ tempx /= .6609193; return tempx; } #if 0 static FLOAT norm_s3_func(void) { double lim_a = 0, lim_b = 0; double x = 0, l, h; for (x = 0; s3_func(x) > 1e-20; x -= 1); l = x; h = 0; while (fabs(h - l) > 1e-12) { x = (h + l) / 2; if (s3_func(x) > 0) { h = x; } else { l = x; } } lim_a = l; for (x = 0; s3_func(x) > 1e-20; x += 1); l = 0; h = x; while (fabs(h - l) > 1e-12) { x = (h + l) / 2; if (s3_func(x) > 0) { l = x; } else { h = x; } } lim_b = h; { double sum = 0; int const m = 1000; int i; for (i = 0; i <= m; ++i) { double x = lim_a + i * (lim_b - lim_a) / m; double y = s3_func(x); sum += y; } { double norm = (m + 1) / (sum * (lim_b - lim_a)); /*printf( "norm = %lf\n",norm); */ return norm; } } } #endif static FLOAT stereo_demask(double f) { /* setup stereo demasking thresholds */ /* formula reverse enginerred from plot in paper */ double arg = freq2bark(f); arg = (Min(arg, 15.5) / 15.5); return pow(10.0, 1.25 * (1 - cos(PI * arg)) - 2.5); } static void init_numline(PsyConst_CB2SB_t * gd, FLOAT sfreq, int fft_size, int mdct_size, int sbmax, int const *scalepos) { FLOAT b_frq[CBANDS + 1]; FLOAT const mdct_freq_frac = sfreq / (2.0f * mdct_size); FLOAT const deltafreq = fft_size / (2.0f * mdct_size); int partition[HBLKSIZE] = { 0 }; int i, j, ni; int sfb; sfreq /= fft_size; j = 0; ni = 0; /* compute numlines, the number of spectral lines in each partition band */ /* each partition band should be about DELBARK wide. */ for (i = 0; i < CBANDS; i++) { FLOAT bark1; int j2, nl; bark1 = freq2bark(sfreq * j); b_frq[i] = sfreq * j; for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK && j2 <= fft_size / 2; j2++); nl = j2 - j; gd->numlines[i] = nl; gd->rnumlines[i] = (nl > 0) ? (1.0f / nl) : 0; ni = i + 1; while (j < j2) { assert(j < HBLKSIZE); partition[j++] = i; } if (j > fft_size / 2) { j = fft_size / 2; ++i; break; } } assert(i < CBANDS); b_frq[i] = sfreq * j; gd->n_sb = sbmax; gd->npart = ni; { j = 0; for (i = 0; i < gd->npart; i++) { int const nl = gd->numlines[i]; FLOAT const freq = sfreq * (j + nl / 2); gd->mld_cb[i] = stereo_demask(freq); j += nl; } for (; i < CBANDS; ++i) { gd->mld_cb[i] = 1; } } for (sfb = 0; sfb < sbmax; sfb++) { int i1, i2, bo; int start = scalepos[sfb]; int end = scalepos[sfb + 1]; i1 = floor(.5 + deltafreq * (start - .5)); if (i1 < 0) i1 = 0; i2 = floor(.5 + deltafreq * (end - .5)); if (i2 > fft_size / 2) i2 = fft_size / 2; bo = partition[i2]; gd->bm[sfb] = (partition[i1] + partition[i2]) / 2; gd->bo[sfb] = bo; /* calculate how much of this band belongs to current scalefactor band */ { FLOAT const f_tmp = mdct_freq_frac * end; FLOAT bo_w = (f_tmp - b_frq[bo]) / (b_frq[bo + 1] - b_frq[bo]); if (bo_w < 0) { bo_w = 0; } else { if (bo_w > 1) { bo_w = 1; } } gd->bo_weight[sfb] = bo_w; } gd->mld[sfb] = stereo_demask(mdct_freq_frac * start); } } static void compute_bark_values(PsyConst_CB2SB_t const *gd, FLOAT sfreq, int fft_size, FLOAT * bval, FLOAT * bval_width) { /* compute bark values of each critical band */ int k, j = 0, ni = gd->npart; sfreq /= fft_size; for (k = 0; k < ni; k++) { int const w = gd->numlines[k]; FLOAT bark1, bark2; bark1 = freq2bark(sfreq * (j)); bark2 = freq2bark(sfreq * (j + w - 1)); bval[k] = .5 * (bark1 + bark2); bark1 = freq2bark(sfreq * (j - .5)); bark2 = freq2bark(sfreq * (j + w - .5)); bval_width[k] = bark2 - bark1; j += w; } } static int init_s3_values(FLOAT ** p, int (*s3ind)[2], int npart, FLOAT const *bval, FLOAT const *bval_width, FLOAT const *norm) { FLOAT s3[CBANDS][CBANDS]; /* The s3 array is not linear in the bark scale. * bval[x] should be used to get the bark value. */ int i, j, k; int numberOfNoneZero = 0; memset(&s3[0][0], 0, sizeof(s3)); /* s[i][j], the value of the spreading function, * centered at band j (masker), for band i (maskee) * * i.e.: sum over j to spread into signal barkval=i * NOTE: i and j are used opposite as in the ISO docs */ for (i = 0; i < npart; i++) { for (j = 0; j < npart; j++) { FLOAT v = s3_func(bval[i] - bval[j]) * bval_width[j]; s3[i][j] = v * norm[i]; } } for (i = 0; i < npart; i++) { for (j = 0; j < npart; j++) { if (s3[i][j] > 0.0f) break; } s3ind[i][0] = j; for (j = npart - 1; j > 0; j--) { if (s3[i][j] > 0.0f) break; } s3ind[i][1] = j; numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1); } *p = malloc(sizeof(FLOAT) * numberOfNoneZero); if (!*p) return -1; k = 0; for (i = 0; i < npart; i++) for (j = s3ind[i][0]; j <= s3ind[i][1]; j++) (*p)[k++] = s3[i][j]; return 0; } int psymodel_init(lame_global_flags const *gfp) { lame_internal_flags *const gfc = gfp->internal_flags; SessionConfig_t *const cfg = &gfc->cfg; PsyStateVar_t *const psv = &gfc->sv_psy; PsyConst_t *gd; int i, j, b, sb, k; FLOAT bvl_a = 13, bvl_b = 24; FLOAT snr_l_a = 0, snr_l_b = 0; FLOAT snr_s_a = -8.25, snr_s_b = -4.5; FLOAT bval[CBANDS]; FLOAT bval_width[CBANDS]; FLOAT norm[CBANDS]; FLOAT const sfreq = cfg->samplerate_out; FLOAT xav = 10, xbv = 12; FLOAT const minval_low = (0.f - cfg->minval); if (gfc->cd_psy != 0) { return 0; } memset(norm, 0, sizeof(norm)); gd = calloc(1, sizeof(PsyConst_t)); gfc->cd_psy = gd; gd->force_short_block_calc = gfp->experimentalZ; psv->blocktype_old[0] = psv->blocktype_old[1] = NORM_TYPE; /* the vbr header is long blocks */ for (i = 0; i < 4; ++i) { for (j = 0; j < CBANDS; ++j) { psv->nb_l1[i][j] = 1e20; psv->nb_l2[i][j] = 1e20; psv->nb_s1[i][j] = psv->nb_s2[i][j] = 1.0; } for (sb = 0; sb < SBMAX_l; sb++) { psv->en[i].l[sb] = 1e20; psv->thm[i].l[sb] = 1e20; } for (j = 0; j < 3; ++j) { for (sb = 0; sb < SBMAX_s; sb++) { psv->en[i].s[sb][j] = 1e20; psv->thm[i].s[sb][j] = 1e20; } psv->last_attacks[i] = 0; } for (j = 0; j < 9; j++) psv->last_en_subshort[i][j] = 10.; } /* init. for loudness approx. -jd 2001 mar 27 */ psv->loudness_sq_save[0] = psv->loudness_sq_save[1] = 0.0; /************************************************************************* * now compute the psychoacoustic model specific constants ************************************************************************/ /* compute numlines, bo, bm, bval, bval_width, mld */ init_numline(&gd->l, sfreq, BLKSIZE, 576, SBMAX_l, gfc->scalefac_band.l); assert(gd->l.npart < CBANDS); compute_bark_values(&gd->l, sfreq, BLKSIZE, bval, bval_width); /* compute the spreading function */ for (i = 0; i < gd->l.npart; i++) { double snr = snr_l_a; if (bval[i] >= bvl_a) { snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_l_a * (bvl_b - bval[i]) / (bvl_b - bvl_a); } norm[i] = pow(10.0, snr / 10.0); } i = init_s3_values(&gd->l.s3, gd->l.s3ind, gd->l.npart, bval, bval_width, norm); if (i) return i; /* compute long block specific values, ATH and MINVAL */ j = 0; for (i = 0; i < gd->l.npart; i++) { double x; /* ATH */ x = FLOAT_MAX; for (k = 0; k < gd->l.numlines[i]; k++, j++) { FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE); FLOAT level; /* freq = Min(.1,freq); *//* ATH below 100 Hz constant, not further climbing */ level = ATHformula(cfg, freq * 1000) - 20; /* scale to FFT units; returned value is in dB */ level = pow(10., 0.1 * level); /* convert from dB -> energy */ level *= gd->l.numlines[i]; if (x > level) x = level; } gfc->ATH->cb_l[i] = x; /* MINVAL. For low freq, the strength of the masking is limited by minval this is an ISO MPEG1 thing, dont know if it is really needed */ /* FIXME: it does work to reduce low-freq problems in S53-Wind-Sax and lead-voice samples, but introduces some 3 kbps bit bloat too. TODO: Further refinement of the shape of this hack. */ x = 20.0 * (bval[i] / xav - 1.0); if (x > 6) { x = 30; } if (x < minval_low) { x = minval_low; } if (cfg->samplerate_out < 44000) { x = 30; } x -= 8.; gd->l.minval[i] = pow(10.0, x / 10.) * gd->l.numlines[i]; } /************************************************************************ * do the same things for short blocks ************************************************************************/ init_numline(&gd->s, sfreq, BLKSIZE_s, 192, SBMAX_s, gfc->scalefac_band.s); assert(gd->s.npart < CBANDS); compute_bark_values(&gd->s, sfreq, BLKSIZE_s, bval, bval_width); /* SNR formula. short block is normalized by SNR. is it still right ? */ j = 0; for (i = 0; i < gd->s.npart; i++) { double x; double snr = snr_s_a; if (bval[i] >= bvl_a) { snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_s_a * (bvl_b - bval[i]) / (bvl_b - bvl_a); } norm[i] = pow(10.0, snr / 10.0); /* ATH */ x = FLOAT_MAX; for (k = 0; k < gd->s.numlines[i]; k++, j++) { FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE_s); FLOAT level; /* freq = Min(.1,freq); *//* ATH below 100 Hz constant, not further climbing */ level = ATHformula(cfg, freq * 1000) - 20; /* scale to FFT units; returned value is in dB */ level = pow(10., 0.1 * level); /* convert from dB -> energy */ level *= gd->s.numlines[i]; if (x > level) x = level; } gfc->ATH->cb_s[i] = x; /* MINVAL. For low freq, the strength of the masking is limited by minval this is an ISO MPEG1 thing, dont know if it is really needed */ x = 7.0 * (bval[i] / xbv - 1.0); if (bval[i] > xbv) { x *= 1 + log(1 + x) * 3.1; } if (bval[i] < xbv) { x *= 1 + log(1 - x) * 2.3; } if (x > 6) { x = 30; } if (x < minval_low) { x = minval_low; } if (cfg->samplerate_out < 44000) { x = 30; } x -= 8; gd->s.minval[i] = pow(10.0, x / 10) * gd->s.numlines[i]; } i = init_s3_values(&gd->s.s3, gd->s.s3ind, gd->s.npart, bval, bval_width, norm); if (i) return i; init_mask_add_max_values(); init_fft(gfc); /* setup temporal masking */ gd->decay = exp(-1.0 * LOG10 / (temporalmask_sustain_sec * sfreq / 192.0)); { FLOAT msfix; msfix = NS_MSFIX; if (cfg->use_safe_joint_stereo) msfix = 1.0; if (fabs(cfg->msfix) > 0.0) msfix = cfg->msfix; cfg->msfix = msfix; /* spread only from npart_l bands. Normally, we use the spreading * function to convolve from npart_l down to npart_l bands */ for (b = 0; b < gd->l.npart; b++) if (gd->l.s3ind[b][1] > gd->l.npart - 1) gd->l.s3ind[b][1] = gd->l.npart - 1; } /* prepare for ATH auto adjustment: * we want to decrease the ATH by 12 dB per second */ #define frame_duration (576. * cfg->mode_gr / sfreq) gfc->ATH->decay = pow(10., -12. / 10. * frame_duration); gfc->ATH->adjust_factor = 0.01; /* minimum, for leading low loudness */ gfc->ATH->adjust_limit = 1.0; /* on lead, allow adjust up to maximum */ #undef frame_duration assert(gd->l.bo[SBMAX_l - 1] <= gd->l.npart); assert(gd->s.bo[SBMAX_s - 1] <= gd->s.npart); if (cfg->ATHtype != -1) { /* compute equal loudness weights (eql_w) */ FLOAT freq; FLOAT const freq_inc = (FLOAT) cfg->samplerate_out / (FLOAT) (BLKSIZE); FLOAT eql_balance = 0.0; freq = 0.0; for (i = 0; i < BLKSIZE / 2; ++i) { /* convert ATH dB to relative power (not dB) */ /* to determine eql_w */ freq += freq_inc; gfc->ATH->eql_w[i] = 1. / pow(10, ATHformula(cfg, freq) / 10); eql_balance += gfc->ATH->eql_w[i]; } eql_balance = 1.0 / eql_balance; for (i = BLKSIZE / 2; --i >= 0;) { /* scale weights */ gfc->ATH->eql_w[i] *= eql_balance; } } { for (b = j = 0; b < gd->s.npart; ++b) { for (i = 0; i < gd->s.numlines[b]; ++i) { ++j; } } assert(j == 129); for (b = j = 0; b < gd->l.npart; ++b) { for (i = 0; i < gd->l.numlines[b]; ++i) { ++j; } } assert(j == 513); } /* short block attack threshold */ { float x = gfp->attackthre; float y = gfp->attackthre_s; if (x < 0) { x = NSATTACKTHRE; } if (y < 0) { y = NSATTACKTHRE_S; } gd->attack_threshold[0] = gd->attack_threshold[1] = gd->attack_threshold[2] = x; gd->attack_threshold[3] = y; } { float sk_s = -10.f, sk_l = -4.7f; static float const sk[] = { -7.4, -7.4, -7.4, -9.5, -7.4, -6.1, -5.5, -4.7, -4.7, -4.7, -4.7 }; if (gfp->VBR_q < 4) { sk_l = sk_s = sk[0]; } else { sk_l = sk_s = sk[gfp->VBR_q] + gfp->VBR_q_frac * (sk[gfp->VBR_q] - sk[gfp->VBR_q + 1]); } b = 0; for (; b < gd->s.npart; b++) { float m = (float) (gd->s.npart - b) / gd->s.npart; gd->s.masking_lower[b] = powf(10.f, sk_s * m * 0.1f); } for (; b < CBANDS; ++b) { gd->s.masking_lower[b] = 1.f; } b = 0; for (; b < gd->l.npart; b++) { float m = (float) (gd->l.npart - b) / gd->l.npart; gd->l.masking_lower[b] = powf(10.f, sk_l * m * 0.1f); } for (; b < CBANDS; ++b) { gd->l.masking_lower[b] = 1.f; } } memcpy(&gd->l_to_s, &gd->l, sizeof(gd->l_to_s)); init_numline(&gd->l_to_s, sfreq, BLKSIZE, 192, SBMAX_s, gfc->scalefac_band.s); return 0; } ================================================ FILE: app/jni/libmp3lame/psymodel.h ================================================ /* * psymodel.h * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_PSYMODEL_H #define LAME_PSYMODEL_H int L3psycho_anal_ns(lame_internal_flags * gfc, const sample_t *const buffer[2], int gr, III_psy_ratio ratio[2][2], III_psy_ratio MS_ratio[2][2], FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]); int L3psycho_anal_vbr(lame_internal_flags * gfc, const sample_t *const buffer[2], int gr, III_psy_ratio ratio[2][2], III_psy_ratio MS_ratio[2][2], FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]); int psymodel_init(lame_global_flags const* gfp); #define rpelev 2 #define rpelev2 16 #define rpelev_s 2 #define rpelev2_s 16 /* size of each partition band, in barks: */ #define DELBARK .34 /* tuned for output level (sensitive to energy scale) */ #define VO_SCALE (1./( 14752*14752 )/(BLKSIZE/2)) #define temporalmask_sustain_sec 0.01 #define NS_PREECHO_ATT0 0.8 #define NS_PREECHO_ATT1 0.6 #define NS_PREECHO_ATT2 0.3 #define NS_MSFIX 3.5 #define NSATTACKTHRE 4.4 #define NSATTACKTHRE_S 25 #endif /* LAME_PSYMODEL_H */ ================================================ FILE: app/jni/libmp3lame/quantize.c ================================================ /* * MP3 quantization * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 1999-2003 Takehiro Tominaga * Copyright (c) 2000-2011 Robert Hegemann * Copyright (c) 2001-2005 Gabriel Bouvigne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: quantize.c,v 1.216.2.1 2012/01/08 23:49:58 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "quantize_pvt.h" #include "reservoir.h" #include "bitstream.h" #include "vbrquantize.h" #include "quantize.h" #ifdef HAVE_XMMINTRIN_H #include "vector/lame_intrin.h" #endif /* convert from L/R <-> Mid/Side */ static void ms_convert(III_side_info_t * l3_side, int gr) { int i; for (i = 0; i < 576; ++i) { FLOAT l, r; l = l3_side->tt[gr][0].xr[i]; r = l3_side->tt[gr][1].xr[i]; l3_side->tt[gr][0].xr[i] = (l + r) * (FLOAT) (SQRT2 * 0.5); l3_side->tt[gr][1].xr[i] = (l - r) * (FLOAT) (SQRT2 * 0.5); } } /************************************************************************ * * init_outer_loop() * mt 6/99 * * initializes cod_info, scalefac and xrpow * * returns 0 if all energies in xr are zero, else 1 * ************************************************************************/ static void init_xrpow_core_c(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum) { int i; FLOAT tmp; *sum = 0; for (i = 0; i <= upper; ++i) { tmp = fabs(cod_info->xr[i]); *sum += tmp; xrpow[i] = sqrt(tmp * sqrt(tmp)); if (xrpow[i] > cod_info->xrpow_max) cod_info->xrpow_max = xrpow[i]; } } void init_xrpow_core_init(lame_internal_flags * const gfc) { gfc->init_xrpow_core = init_xrpow_core_c; #if defined(HAVE_XMMINTRIN_H) if (gfc->CPU_features.SSE) gfc->init_xrpow_core = init_xrpow_core_sse; #endif #ifndef HAVE_NASM #ifdef MIN_ARCH_SSE gfc->init_xrpow_core = init_xrpow_core_sse; #endif #endif } static int init_xrpow(lame_internal_flags * gfc, gr_info * const cod_info, FLOAT xrpow[576]) { FLOAT sum = 0; int i; int const upper = cod_info->max_nonzero_coeff; assert(xrpow != NULL); cod_info->xrpow_max = 0; /* check if there is some energy we have to quantize * and calculate xrpow matching our fresh scalefactors */ assert(0 <= upper && upper <= 575); memset(&(xrpow[upper]), 0, (576 - upper) * sizeof(xrpow[0])); gfc->init_xrpow_core(cod_info, xrpow, upper, &sum); /* return 1 if we have something to quantize, else 0 */ if (sum > (FLOAT) 1E-20) { int j = 0; if (gfc->sv_qnt.substep_shaping & 2) j = 1; for (i = 0; i < cod_info->psymax; i++) gfc->sv_qnt.pseudohalf[i] = j; return 1; } memset(&cod_info->l3_enc[0], 0, sizeof(int) * 576); return 0; } /* Gabriel Bouvigne feb/apr 2003 Analog silence detection in partitionned sfb21 or sfb12 for short blocks From top to bottom of sfb, changes to 0 coeffs which are below ath. It stops on the first coeff higher than ath. */ static void psfb21_analogsilence(lame_internal_flags const *gfc, gr_info * const cod_info) { ATH_t const *const ATH = gfc->ATH; FLOAT *const xr = cod_info->xr; if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT blocks */ int gsfb; int stop = 0; for (gsfb = PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) { int const start = gfc->scalefac_band.psfb21[gsfb]; int const end = gfc->scalefac_band.psfb21[gsfb + 1]; int j; FLOAT ath21; ath21 = athAdjust(ATH->adjust_factor, ATH->psfb21[gsfb], ATH->floor, 0); if (gfc->sv_qnt.longfact[21] > 1e-12f) ath21 *= gfc->sv_qnt.longfact[21]; for (j = end - 1; j >= start; j--) { if (fabs(xr[j]) < ath21) xr[j] = 0; else { stop = 1; break; } } } } else { /*note: short blocks coeffs are reordered */ int block; for (block = 0; block < 3; block++) { int gsfb; int stop = 0; for (gsfb = PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) { int const start = gfc->scalefac_band.s[12] * 3 + (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) * block + (gfc->scalefac_band.psfb12[gsfb] - gfc->scalefac_band.psfb12[0]); int const end = start + (gfc->scalefac_band.psfb12[gsfb + 1] - gfc->scalefac_band.psfb12[gsfb]); int j; FLOAT ath12; ath12 = athAdjust(ATH->adjust_factor, ATH->psfb12[gsfb], ATH->floor, 0); if (gfc->sv_qnt.shortfact[12] > 1e-12f) ath12 *= gfc->sv_qnt.shortfact[12]; for (j = end - 1; j >= start; j--) { if (fabs(xr[j]) < ath12) xr[j] = 0; else { stop = 1; break; } } } } } } static void init_outer_loop(lame_internal_flags const *gfc, gr_info * const cod_info) { SessionConfig_t const *const cfg = &gfc->cfg; int sfb, j; /* initialize fresh cod_info */ cod_info->part2_3_length = 0; cod_info->big_values = 0; cod_info->count1 = 0; cod_info->global_gain = 210; cod_info->scalefac_compress = 0; /* mixed_block_flag, block_type was set in psymodel.c */ cod_info->table_select[0] = 0; cod_info->table_select[1] = 0; cod_info->table_select[2] = 0; cod_info->subblock_gain[0] = 0; cod_info->subblock_gain[1] = 0; cod_info->subblock_gain[2] = 0; cod_info->subblock_gain[3] = 0; /* this one is always 0 */ cod_info->region0_count = 0; cod_info->region1_count = 0; cod_info->preflag = 0; cod_info->scalefac_scale = 0; cod_info->count1table_select = 0; cod_info->part2_length = 0; if (cfg->samplerate_out <= 8000) { cod_info->sfb_lmax = 17; cod_info->sfb_smin = 9; cod_info->psy_lmax = 17; } else { cod_info->sfb_lmax = SBPSY_l; cod_info->sfb_smin = SBPSY_s; cod_info->psy_lmax = gfc->sv_qnt.sfb21_extra ? SBMAX_l : SBPSY_l; } cod_info->psymax = cod_info->psy_lmax; cod_info->sfbmax = cod_info->sfb_lmax; cod_info->sfbdivide = 11; for (sfb = 0; sfb < SBMAX_l; sfb++) { cod_info->width[sfb] = gfc->scalefac_band.l[sfb + 1] - gfc->scalefac_band.l[sfb]; cod_info->window[sfb] = 3; /* which is always 0. */ } if (cod_info->block_type == SHORT_TYPE) { FLOAT ixwork[576]; FLOAT *ix; cod_info->sfb_smin = 0; cod_info->sfb_lmax = 0; if (cod_info->mixed_block_flag) { /* * MPEG-1: sfbs 0-7 long block, 3-12 short blocks * MPEG-2(.5): sfbs 0-5 long block, 3-12 short blocks */ cod_info->sfb_smin = 3; cod_info->sfb_lmax = cfg->mode_gr * 2 + 4; } if (cfg->samplerate_out <= 8000) { cod_info->psymax = cod_info->sfb_lmax + 3 * (9 - cod_info->sfb_smin); cod_info->sfbmax = cod_info->sfb_lmax + 3 * (9 - cod_info->sfb_smin); } else { cod_info->psymax = cod_info->sfb_lmax + 3 * ((gfc->sv_qnt.sfb21_extra ? SBMAX_s : SBPSY_s) - cod_info->sfb_smin); cod_info->sfbmax = cod_info->sfb_lmax + 3 * (SBPSY_s - cod_info->sfb_smin); } cod_info->sfbdivide = cod_info->sfbmax - 18; cod_info->psy_lmax = cod_info->sfb_lmax; /* re-order the short blocks, for more efficient encoding below */ /* By Takehiro TOMINAGA */ /* Within each scalefactor band, data is given for successive time windows, beginning with window 0 and ending with window 2. Within each window, the quantized values are then arranged in order of increasing frequency... */ ix = &cod_info->xr[gfc->scalefac_band.l[cod_info->sfb_lmax]]; memcpy(ixwork, cod_info->xr, 576 * sizeof(FLOAT)); for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) { int const start = gfc->scalefac_band.s[sfb]; int const end = gfc->scalefac_band.s[sfb + 1]; int window, l; for (window = 0; window < 3; window++) { for (l = start; l < end; l++) { *ix++ = ixwork[3 * l + window]; } } } j = cod_info->sfb_lmax; for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) { cod_info->width[j] = cod_info->width[j + 1] = cod_info->width[j + 2] = gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb]; cod_info->window[j] = 0; cod_info->window[j + 1] = 1; cod_info->window[j + 2] = 2; j += 3; } } cod_info->count1bits = 0; cod_info->sfb_partition_table = nr_of_sfb_block[0][0]; cod_info->slen[0] = 0; cod_info->slen[1] = 0; cod_info->slen[2] = 0; cod_info->slen[3] = 0; cod_info->max_nonzero_coeff = 575; /* fresh scalefactors are all zero */ memset(cod_info->scalefac, 0, sizeof(cod_info->scalefac)); if (cfg->vbr != vbr_mt && cfg->vbr != vbr_mtrh && cfg->vbr != vbr_abr && cfg->vbr != vbr_off) { psfb21_analogsilence(gfc, cod_info); } } /************************************************************************ * * bin_search_StepSize() * * author/date?? * * binary step size search * used by outer_loop to get a quantizer step size to start with * ************************************************************************/ typedef enum { BINSEARCH_NONE, BINSEARCH_UP, BINSEARCH_DOWN } binsearchDirection_t; static int bin_search_StepSize(lame_internal_flags * const gfc, gr_info * const cod_info, int desired_rate, const int ch, const FLOAT xrpow[576]) { int nBits; int CurrentStep = gfc->sv_qnt.CurrentStep[ch]; int flag_GoneOver = 0; int const start = gfc->sv_qnt.OldValue[ch]; binsearchDirection_t Direction = BINSEARCH_NONE; cod_info->global_gain = start; desired_rate -= cod_info->part2_length; assert(CurrentStep); for (;;) { int step; nBits = count_bits(gfc, xrpow, cod_info, 0); if (CurrentStep == 1 || nBits == desired_rate) break; /* nothing to adjust anymore */ if (nBits > desired_rate) { /* increase Quantize_StepSize */ if (Direction == BINSEARCH_DOWN) flag_GoneOver = 1; if (flag_GoneOver) CurrentStep /= 2; Direction = BINSEARCH_UP; step = CurrentStep; } else { /* decrease Quantize_StepSize */ if (Direction == BINSEARCH_UP) flag_GoneOver = 1; if (flag_GoneOver) CurrentStep /= 2; Direction = BINSEARCH_DOWN; step = -CurrentStep; } cod_info->global_gain += step; if (cod_info->global_gain < 0) { cod_info->global_gain = 0; flag_GoneOver = 1; } if (cod_info->global_gain > 255) { cod_info->global_gain = 255; flag_GoneOver = 1; } } assert(cod_info->global_gain >= 0); assert(cod_info->global_gain < 256); while (nBits > desired_rate && cod_info->global_gain < 255) { cod_info->global_gain++; nBits = count_bits(gfc, xrpow, cod_info, 0); } gfc->sv_qnt.CurrentStep[ch] = (start - cod_info->global_gain >= 4) ? 4 : 2; gfc->sv_qnt.OldValue[ch] = cod_info->global_gain; cod_info->part2_3_length = nBits; return nBits; } /************************************************************************ * * trancate_smallspectrums() * * Takehiro TOMINAGA 2002-07-21 * * trancate smaller nubmers into 0 as long as the noise threshold is allowed. * ************************************************************************/ static int floatcompare(const void *v1, const void *v2) { const FLOAT *const a = v1, *const b = v2; if (*a > *b) return 1; if (*a < *b) return -1; return 0; } static void trancate_smallspectrums(lame_internal_flags const *gfc, gr_info * const gi, const FLOAT * const l3_xmin, FLOAT * const work) { int sfb, j, width; FLOAT distort[SFBMAX]; calc_noise_result dummy; if ((!(gfc->sv_qnt.substep_shaping & 4) && gi->block_type == SHORT_TYPE) || gfc->sv_qnt.substep_shaping & 0x80) return; (void) calc_noise(gi, l3_xmin, distort, &dummy, 0); for (j = 0; j < 576; j++) { FLOAT xr = 0.0; if (gi->l3_enc[j] != 0) xr = fabs(gi->xr[j]); work[j] = xr; } j = 0; sfb = 8; if (gi->block_type == SHORT_TYPE) sfb = 6; do { FLOAT allowedNoise, trancateThreshold; int nsame, start; width = gi->width[sfb]; j += width; if (distort[sfb] >= 1.0) continue; qsort(&work[j - width], width, sizeof(FLOAT), floatcompare); if (EQ(work[j - 1], 0.0)) continue; /* all zero sfb */ allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb]; trancateThreshold = 0.0; start = 0; do { FLOAT noise; for (nsame = 1; start + nsame < width; nsame++) if (NEQ(work[start + j - width], work[start + j + nsame - width])) break; noise = work[start + j - width] * work[start + j - width] * nsame; if (allowedNoise < noise) { if (start != 0) trancateThreshold = work[start + j - width - 1]; break; } allowedNoise -= noise; start += nsame; } while (start < width); if (EQ(trancateThreshold, 0.0)) continue; /* printf("%e %e %e\n", */ /* trancateThreshold/l3_xmin[sfb], */ /* trancateThreshold/(l3_xmin[sfb]*start), */ /* trancateThreshold/(l3_xmin[sfb]*(start+width)) */ /* ); */ /* if (trancateThreshold > 1000*l3_xmin[sfb]*start) */ /* trancateThreshold = 1000*l3_xmin[sfb]*start; */ do { if (fabs(gi->xr[j - width]) <= trancateThreshold) gi->l3_enc[j - width] = 0; } while (--width > 0); } while (++sfb < gi->psymax); gi->part2_3_length = noquant_count_bits(gfc, gi, 0); } /************************************************************************* * * loop_break() * * author/date?? * * Function: Returns zero if there is a scalefac which has not been * amplified. Otherwise it returns one. * *************************************************************************/ inline static int loop_break(const gr_info * const cod_info) { int sfb; for (sfb = 0; sfb < cod_info->sfbmax; sfb++) if (cod_info->scalefac[sfb] + cod_info->subblock_gain[cod_info->window[sfb]] == 0) return 0; return 1; } /* mt 5/99: Function: Improved calc_noise for a single channel */ /************************************************************************* * * quant_compare() * * author/date?? * * several different codes to decide which quantization is better * *************************************************************************/ static double penalties(double noise) { return FAST_LOG10(0.368 + 0.632 * noise * noise * noise); } static double get_klemm_noise(const FLOAT * distort, const gr_info * const gi) { int sfb; double klemm_noise = 1E-37; for (sfb = 0; sfb < gi->psymax; sfb++) klemm_noise += penalties(distort[sfb]); return Max(1e-20, klemm_noise); } inline static int quant_compare(const int quant_comp, const calc_noise_result * const best, calc_noise_result * const calc, const gr_info * const gi, const FLOAT * distort) { /* noise is given in decibels (dB) relative to masking thesholds. over_noise: ??? (the previous comment is fully wrong) tot_noise: ??? (the previous comment is fully wrong) max_noise: max quantization noise */ int better; switch (quant_comp) { default: case 9:{ if (best->over_count > 0) { /* there are distorted sfb */ better = calc->over_SSD <= best->over_SSD; if (calc->over_SSD == best->over_SSD) better = calc->bits < best->bits; } else { /* no distorted sfb */ better = ((calc->max_noise < 0) && ((calc->max_noise * 10 + calc->bits) <= (best->max_noise * 10 + best->bits))); } break; } case 0: better = calc->over_count < best->over_count || (calc->over_count == best->over_count && calc->over_noise < best->over_noise) || (calc->over_count == best->over_count && EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise); break; case 8: calc->max_noise = get_klemm_noise(distort, gi); /*lint --fallthrough */ case 1: better = calc->max_noise < best->max_noise; break; case 2: better = calc->tot_noise < best->tot_noise; break; case 3: better = (calc->tot_noise < best->tot_noise) && (calc->max_noise < best->max_noise); break; case 4: better = (calc->max_noise <= 0.0 && best->max_noise > 0.2) || (calc->max_noise <= 0.0 && best->max_noise < 0.0 && best->max_noise > calc->max_noise - 0.2 && calc->tot_noise < best->tot_noise) || (calc->max_noise <= 0.0 && best->max_noise > 0.0 && best->max_noise > calc->max_noise - 0.2 && calc->tot_noise < best->tot_noise + best->over_noise) || (calc->max_noise > 0.0 && best->max_noise > -0.05 && best->max_noise > calc->max_noise - 0.1 && calc->tot_noise + calc->over_noise < best->tot_noise + best->over_noise) || (calc->max_noise > 0.0 && best->max_noise > -0.1 && best->max_noise > calc->max_noise - 0.15 && calc->tot_noise + calc->over_noise + calc->over_noise < best->tot_noise + best->over_noise + best->over_noise); break; case 5: better = calc->over_noise < best->over_noise || (EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise); break; case 6: better = calc->over_noise < best->over_noise || (EQ(calc->over_noise, best->over_noise) && (calc->max_noise < best->max_noise || (EQ(calc->max_noise, best->max_noise) && calc->tot_noise <= best->tot_noise) )); break; case 7: better = calc->over_count < best->over_count || calc->over_noise < best->over_noise; break; } if (best->over_count == 0) { /* If no distorted bands, only use this quantization if it is better, and if it uses less bits. Unfortunately, part2_3_length is sometimes a poor estimator of the final size at low bitrates. */ better = better && calc->bits < best->bits; } return better; } /************************************************************************* * * amp_scalefac_bands() * * author/date?? * * Amplify the scalefactor bands that violate the masking threshold. * See ISO 11172-3 Section C.1.5.4.3.5 * * distort[] = noise/masking * distort[] > 1 ==> noise is not masked * distort[] < 1 ==> noise is masked * max_dist = maximum value of distort[] * * Three algorithms: * noise_shaping_amp * 0 Amplify all bands with distort[]>1. * * 1 Amplify all bands with distort[] >= max_dist^(.5); * ( 50% in the db scale) * * 2 Amplify first band with distort[] >= max_dist; * * * For algorithms 0 and 1, if max_dist < 1, then amplify all bands * with distort[] >= .95*max_dist. This is to make sure we always * amplify at least one band. * * *************************************************************************/ static void amp_scalefac_bands(lame_internal_flags * gfc, gr_info * const cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine) { SessionConfig_t const *const cfg = &gfc->cfg; int j, sfb; FLOAT ifqstep34, trigger; int noise_shaping_amp; if (cod_info->scalefac_scale == 0) { ifqstep34 = 1.29683955465100964055; /* 2**(.75*.5) */ } else { ifqstep34 = 1.68179283050742922612; /* 2**(.75*1) */ } /* compute maximum value of distort[] */ trigger = 0; for (sfb = 0; sfb < cod_info->sfbmax; sfb++) { if (trigger < distort[sfb]) trigger = distort[sfb]; } noise_shaping_amp = cfg->noise_shaping_amp; if (noise_shaping_amp == 3) { if (bRefine == 1) noise_shaping_amp = 2; else noise_shaping_amp = 1; } switch (noise_shaping_amp) { case 2: /* amplify exactly 1 band */ break; case 1: /* amplify bands within 50% of max (on db scale) */ if (trigger > 1.0) trigger = pow(trigger, .5); else trigger *= .95; break; case 0: default: /* ISO algorithm. amplify all bands with distort>1 */ if (trigger > 1.0) trigger = 1.0; else trigger *= .95; break; } j = 0; for (sfb = 0; sfb < cod_info->sfbmax; sfb++) { int const width = cod_info->width[sfb]; int l; j += width; if (distort[sfb] < trigger) continue; if (gfc->sv_qnt.substep_shaping & 2) { gfc->sv_qnt.pseudohalf[sfb] = !gfc->sv_qnt.pseudohalf[sfb]; if (!gfc->sv_qnt.pseudohalf[sfb] && cfg->noise_shaping_amp == 2) return; } cod_info->scalefac[sfb]++; for (l = -width; l < 0; l++) { xrpow[j + l] *= ifqstep34; if (xrpow[j + l] > cod_info->xrpow_max) cod_info->xrpow_max = xrpow[j + l]; } if (cfg->noise_shaping_amp == 2) return; } } /************************************************************************* * * inc_scalefac_scale() * * Takehiro Tominaga 2000-xx-xx * * turns on scalefac scale and adjusts scalefactors * *************************************************************************/ static void inc_scalefac_scale(gr_info * const cod_info, FLOAT xrpow[576]) { int l, j, sfb; const FLOAT ifqstep34 = 1.29683955465100964055; j = 0; for (sfb = 0; sfb < cod_info->sfbmax; sfb++) { int const width = cod_info->width[sfb]; int s = cod_info->scalefac[sfb]; if (cod_info->preflag) s += pretab[sfb]; j += width; if (s & 1) { s++; for (l = -width; l < 0; l++) { xrpow[j + l] *= ifqstep34; if (xrpow[j + l] > cod_info->xrpow_max) cod_info->xrpow_max = xrpow[j + l]; } } cod_info->scalefac[sfb] = s >> 1; } cod_info->preflag = 0; cod_info->scalefac_scale = 1; } /************************************************************************* * * inc_subblock_gain() * * Takehiro Tominaga 2000-xx-xx * * increases the subblock gain and adjusts scalefactors * *************************************************************************/ static int inc_subblock_gain(const lame_internal_flags * const gfc, gr_info * const cod_info, FLOAT xrpow[576]) { int sfb, window; int *const scalefac = cod_info->scalefac; /* subbloc_gain can't do anything in the long block region */ for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) { if (scalefac[sfb] >= 16) return 1; } for (window = 0; window < 3; window++) { int s1, s2, l, j; s1 = s2 = 0; for (sfb = cod_info->sfb_lmax + window; sfb < cod_info->sfbdivide; sfb += 3) { if (s1 < scalefac[sfb]) s1 = scalefac[sfb]; } for (; sfb < cod_info->sfbmax; sfb += 3) { if (s2 < scalefac[sfb]) s2 = scalefac[sfb]; } if (s1 < 16 && s2 < 8) continue; if (cod_info->subblock_gain[window] >= 7) return 1; /* even though there is no scalefactor for sfb12 * subblock gain affects upper frequencies too, that's why * we have to go up to SBMAX_s */ cod_info->subblock_gain[window]++; j = gfc->scalefac_band.l[cod_info->sfb_lmax]; for (sfb = cod_info->sfb_lmax + window; sfb < cod_info->sfbmax; sfb += 3) { FLOAT amp; int const width = cod_info->width[sfb]; int s = scalefac[sfb]; assert(s >= 0); s = s - (4 >> cod_info->scalefac_scale); if (s >= 0) { scalefac[sfb] = s; j += width * 3; continue; } scalefac[sfb] = 0; { int const gain = 210 + (s << (cod_info->scalefac_scale + 1)); amp = IPOW20(gain); } j += width * (window + 1); for (l = -width; l < 0; l++) { xrpow[j + l] *= amp; if (xrpow[j + l] > cod_info->xrpow_max) cod_info->xrpow_max = xrpow[j + l]; } j += width * (3 - window - 1); } { FLOAT const amp = IPOW20(202); j += cod_info->width[sfb] * (window + 1); for (l = -cod_info->width[sfb]; l < 0; l++) { xrpow[j + l] *= amp; if (xrpow[j + l] > cod_info->xrpow_max) cod_info->xrpow_max = xrpow[j + l]; } } } return 0; } /******************************************************************** * * balance_noise() * * Takehiro Tominaga /date?? * Robert Hegemann 2000-09-06: made a function of it * * amplifies scalefactor bands, * - if all are already amplified returns 0 * - if some bands are amplified too much: * * try to increase scalefac_scale * * if already scalefac_scale was set * try on short blocks to increase subblock gain * ********************************************************************/ inline static int balance_noise(lame_internal_flags * gfc, gr_info * const cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine) { SessionConfig_t const *const cfg = &gfc->cfg; int status; amp_scalefac_bands(gfc, cod_info, distort, xrpow, bRefine); /* check to make sure we have not amplified too much * loop_break returns 0 if there is an unamplified scalefac * scale_bitcount returns 0 if no scalefactors are too large */ status = loop_break(cod_info); if (status) return 0; /* all bands amplified */ /* not all scalefactors have been amplified. so these * scalefacs are possibly valid. encode them: */ status = scale_bitcount(gfc, cod_info); if (!status) return 1; /* amplified some bands not exceeding limits */ /* some scalefactors are too large. * lets try setting scalefac_scale=1 */ if (cfg->noise_shaping > 1) { memset(&gfc->sv_qnt.pseudohalf[0], 0, sizeof(gfc->sv_qnt.pseudohalf)); if (!cod_info->scalefac_scale) { inc_scalefac_scale(cod_info, xrpow); status = 0; } else { if (cod_info->block_type == SHORT_TYPE && cfg->subblock_gain > 0) { status = inc_subblock_gain(gfc, cod_info, xrpow) || loop_break(cod_info); } } } if (!status) { status = scale_bitcount(gfc, cod_info); } return !status; } /************************************************************************ * * outer_loop () * * Function: The outer iteration loop controls the masking conditions * of all scalefactorbands. It computes the best scalefac and * global gain. This module calls the inner iteration loop * * mt 5/99 completely rewritten to allow for bit reservoir control, * mid/side channels with L/R or mid/side masking thresholds, * and chooses best quantization instead of last quantization when * no distortion free quantization can be found. * * added VBR support mt 5/99 * * some code shuffle rh 9/00 ************************************************************************/ static int outer_loop(lame_internal_flags * gfc, gr_info * const cod_info, const FLOAT * const l3_xmin, /* allowed distortion */ FLOAT xrpow[576], /* coloured magnitudes of spectral */ const int ch, const int targ_bits) { /* maximum allowed bits */ SessionConfig_t const *const cfg = &gfc->cfg; gr_info cod_info_w; FLOAT save_xrpow[576]; FLOAT distort[SFBMAX]; calc_noise_result best_noise_info; int huff_bits; int better; int age; calc_noise_data prev_noise; int best_part2_3_length = 9999999; int bEndOfSearch = 0; int bRefine = 0; int best_ggain_pass1 = 0; (void) bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow); if (!cfg->noise_shaping) /* fast mode, no noise shaping, we are ready */ return 100; /* default noise_info.over_count */ memset(&prev_noise, 0, sizeof(calc_noise_data)); /* compute the distortion in this quantization */ /* coefficients and thresholds both l/r (or both mid/side) */ (void) calc_noise(cod_info, l3_xmin, distort, &best_noise_info, &prev_noise); best_noise_info.bits = cod_info->part2_3_length; cod_info_w = *cod_info; age = 0; /* if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh) */ memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576); while (!bEndOfSearch) { /* BEGIN MAIN LOOP */ do { calc_noise_result noise_info; int search_limit; int maxggain = 255; /* When quantization with no distorted bands is found, * allow up to X new unsuccesful tries in serial. This * gives us more possibilities for different quant_compare modes. * Much more than 3 makes not a big difference, it is only slower. */ if (gfc->sv_qnt.substep_shaping & 2) { search_limit = 20; } else { search_limit = 3; } /* Check if the last scalefactor band is distorted. * in VBR mode we can't get rid of the distortion, so quit now * and VBR mode will try again with more bits. * (makes a 10% speed increase, the files I tested were * binary identical, 2000/05/20 Robert Hegemann) * distort[] > 1 means noise > allowed noise */ if (gfc->sv_qnt.sfb21_extra) { if (distort[cod_info_w.sfbmax] > 1.0) break; if (cod_info_w.block_type == SHORT_TYPE && (distort[cod_info_w.sfbmax + 1] > 1.0 || distort[cod_info_w.sfbmax + 2] > 1.0)) break; } /* try a new scalefactor conbination on cod_info_w */ if (balance_noise(gfc, &cod_info_w, distort, xrpow, bRefine) == 0) break; if (cod_info_w.scalefac_scale) maxggain = 254; /* inner_loop starts with the initial quantization step computed above * and slowly increases until the bits < huff_bits. * Thus it is important not to start with too large of an inital * quantization step. Too small is ok, but inner_loop will take longer */ huff_bits = targ_bits - cod_info_w.part2_length; if (huff_bits <= 0) break; /* increase quantizer stepsize until needed bits are below maximum */ while ((cod_info_w.part2_3_length = count_bits(gfc, xrpow, &cod_info_w, &prev_noise)) > huff_bits && cod_info_w.global_gain <= maxggain) cod_info_w.global_gain++; if (cod_info_w.global_gain > maxggain) break; if (best_noise_info.over_count == 0) { while ((cod_info_w.part2_3_length = count_bits(gfc, xrpow, &cod_info_w, &prev_noise)) > best_part2_3_length && cod_info_w.global_gain <= maxggain) cod_info_w.global_gain++; if (cod_info_w.global_gain > maxggain) break; } /* compute the distortion in this quantization */ (void) calc_noise(&cod_info_w, l3_xmin, distort, &noise_info, &prev_noise); noise_info.bits = cod_info_w.part2_3_length; /* check if this quantization is better * than our saved quantization */ if (cod_info->block_type != SHORT_TYPE) /* NORM, START or STOP type */ better = cfg->quant_comp; else better = cfg->quant_comp_short; better = quant_compare(better, &best_noise_info, &noise_info, &cod_info_w, distort); /* save data so we can restore this quantization later */ if (better) { best_part2_3_length = cod_info->part2_3_length; best_noise_info = noise_info; *cod_info = cod_info_w; age = 0; /* save data so we can restore this quantization later */ /*if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh) */ { /* store for later reuse */ memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576); } } else { /* early stop? */ if (cfg->full_outer_loop == 0) { if (++age > search_limit && best_noise_info.over_count == 0) break; if ((cfg->noise_shaping_amp == 3) && bRefine && age > 30) break; if ((cfg->noise_shaping_amp == 3) && bRefine && (cod_info_w.global_gain - best_ggain_pass1) > 15) break; } } } while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255); if (cfg->noise_shaping_amp == 3) { if (!bRefine) { /* refine search */ cod_info_w = *cod_info; memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576); age = 0; best_ggain_pass1 = cod_info_w.global_gain; bRefine = 1; } else { /* search already refined, stop */ bEndOfSearch = 1; } } else { bEndOfSearch = 1; } } assert((cod_info->global_gain + cod_info->scalefac_scale) <= 255); /* finish up */ if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh || cfg->vbr == vbr_mt) /* restore for reuse on next try */ memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576); /* do the 'substep shaping' */ else if (gfc->sv_qnt.substep_shaping & 1) trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow); return best_noise_info.over_count; } /************************************************************************ * * iteration_finish_one() * * Robert Hegemann 2000-09-06 * * update reservoir status after FINAL quantization/bitrate * ************************************************************************/ static void iteration_finish_one(lame_internal_flags * gfc, int gr, int ch) { SessionConfig_t const *const cfg = &gfc->cfg; III_side_info_t *const l3_side = &gfc->l3_side; gr_info *const cod_info = &l3_side->tt[gr][ch]; /* try some better scalefac storage */ best_scalefac_store(gfc, gr, ch, l3_side); /* best huffman_divide may save some bits too */ if (cfg->use_best_huffman == 1) best_huffman_divide(gfc, cod_info); /* update reservoir status after FINAL quantization/bitrate */ ResvAdjust(gfc, cod_info); } /********************************************************************* * * VBR_encode_granule() * * 2000-09-04 Robert Hegemann * *********************************************************************/ static void VBR_encode_granule(lame_internal_flags * gfc, gr_info * const cod_info, const FLOAT * const l3_xmin, /* allowed distortion of the scalefactor */ FLOAT xrpow[576], /* coloured magnitudes of spectral values */ const int ch, int min_bits, int max_bits) { gr_info bst_cod_info; FLOAT bst_xrpow[576]; int const Max_bits = max_bits; int real_bits = max_bits + 1; int this_bits = (max_bits + min_bits) / 2; int dbits, over, found = 0; int const sfb21_extra = gfc->sv_qnt.sfb21_extra; assert(Max_bits <= MAX_BITS_PER_CHANNEL); memset(bst_cod_info.l3_enc, 0, sizeof(bst_cod_info.l3_enc)); /* search within round about 40 bits of optimal */ do { assert(this_bits >= min_bits); assert(this_bits <= max_bits); assert(min_bits <= max_bits); if (this_bits > Max_bits - 42) gfc->sv_qnt.sfb21_extra = 0; else gfc->sv_qnt.sfb21_extra = sfb21_extra; over = outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, this_bits); /* is quantization as good as we are looking for ? * in this case: is no scalefactor band distorted? */ if (over <= 0) { found = 1; /* now we know it can be done with "real_bits" * and maybe we can skip some iterations */ real_bits = cod_info->part2_3_length; /* store best quantization so far */ bst_cod_info = *cod_info; memcpy(bst_xrpow, xrpow, sizeof(FLOAT) * 576); /* try with fewer bits */ max_bits = real_bits - 32; dbits = max_bits - min_bits; this_bits = (max_bits + min_bits) / 2; } else { /* try with more bits */ min_bits = this_bits + 32; dbits = max_bits - min_bits; this_bits = (max_bits + min_bits) / 2; if (found) { found = 2; /* start again with best quantization so far */ *cod_info = bst_cod_info; memcpy(xrpow, bst_xrpow, sizeof(FLOAT) * 576); } } } while (dbits > 12); gfc->sv_qnt.sfb21_extra = sfb21_extra; /* found=0 => nothing found, use last one * found=1 => we just found the best and left the loop * found=2 => we restored a good one and have now l3_enc to restore too */ if (found == 2) { memcpy(cod_info->l3_enc, bst_cod_info.l3_enc, sizeof(int) * 576); } assert(cod_info->part2_3_length <= Max_bits); } /************************************************************************ * * get_framebits() * * Robert Hegemann 2000-09-05 * * calculates * * how many bits are available for analog silent granules * * how many bits to use for the lowest allowed bitrate * * how many bits each bitrate would provide * ************************************************************************/ static void get_framebits(lame_internal_flags * gfc, int frameBits[15]) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; int bitsPerFrame, i; /* always use at least this many bits per granule per channel * unless we detect analog silence, see below */ eov->bitrate_index = cfg->vbr_min_bitrate_index; bitsPerFrame = getframebits(gfc); /* bits for analog silence */ eov->bitrate_index = 1; bitsPerFrame = getframebits(gfc); for (i = 1; i <= cfg->vbr_max_bitrate_index; i++) { eov->bitrate_index = i; frameBits[i] = ResvFrameBegin(gfc, &bitsPerFrame); } } /********************************************************************* * * VBR_prepare() * * 2000-09-04 Robert Hegemann * * * converts LR to MS coding when necessary * * calculates allowed/adjusted quantization noise amounts * * detects analog silent frames * * some remarks: * - lower masking depending on Quality setting * - quality control together with adjusted ATH MDCT scaling * on lower quality setting allocate more noise from * ATH masking, and on higher quality setting allocate * less noise from ATH masking. * - experiments show that going more than 2dB over GPSYCHO's * limits ends up in very annoying artefacts * *********************************************************************/ /* RH: this one needs to be overhauled sometime */ static int VBR_old_prepare(lame_internal_flags * gfc, const FLOAT pe[2][2], FLOAT const ms_ener_ratio[2], const III_psy_ratio ratio[2][2], FLOAT l3_xmin[2][2][SFBMAX], int frameBits[16], int min_bits[2][2], int max_bits[2][2], int bands[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; FLOAT masking_lower_db, adjust = 0.0; int gr, ch; int analog_silence = 1; int avg, mxb, bits = 0; eov->bitrate_index = cfg->vbr_max_bitrate_index; avg = ResvFrameBegin(gfc, &avg) / cfg->mode_gr; get_framebits(gfc, frameBits); for (gr = 0; gr < cfg->mode_gr; gr++) { mxb = on_pe(gfc, pe, max_bits[gr], avg, gr, 0); if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { ms_convert(&gfc->l3_side, gr); reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb); } for (ch = 0; ch < cfg->channels_out; ++ch) { gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */ adjust = 1.28 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.05; masking_lower_db = gfc->sv_qnt.mask_adjust - adjust; } else { adjust = 2.56 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.14; masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust; } gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1); init_outer_loop(gfc, cod_info); bands[gr][ch] = calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin[gr][ch]); if (bands[gr][ch]) analog_silence = 0; min_bits[gr][ch] = 126; bits += max_bits[gr][ch]; } } for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { if (bits > frameBits[cfg->vbr_max_bitrate_index] && bits > 0) { max_bits[gr][ch] *= frameBits[cfg->vbr_max_bitrate_index]; max_bits[gr][ch] /= bits; } if (min_bits[gr][ch] > max_bits[gr][ch]) min_bits[gr][ch] = max_bits[gr][ch]; } /* for ch */ } /* for gr */ return analog_silence; } static void bitpressure_strategy(lame_internal_flags const *gfc, FLOAT l3_xmin[2][2][SFBMAX], const int min_bits[2][2], int max_bits[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; int gr, ch, sfb; for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gr_info const *const gi = &gfc->l3_side.tt[gr][ch]; FLOAT *pxmin = l3_xmin[gr][ch]; for (sfb = 0; sfb < gi->psy_lmax; sfb++) *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_l / SBMAX_l; if (gi->block_type == SHORT_TYPE) { for (sfb = gi->sfb_smin; sfb < SBMAX_s; sfb++) { *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s; *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s; *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s; } } max_bits[gr][ch] = Max(min_bits[gr][ch], 0.9 * max_bits[gr][ch]); } } } /************************************************************************ * * VBR_iteration_loop() * * tries to find out how many bits are needed for each granule and channel * to get an acceptable quantization. An appropriate bitrate will then be * choosed for quantization. rh 8/99 * * Robert Hegemann 2000-09-06 rewrite * ************************************************************************/ void VBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; FLOAT l3_xmin[2][2][SFBMAX]; FLOAT xrpow[576]; int bands[2][2]; int frameBits[15]; int used_bits; int bits; int min_bits[2][2], max_bits[2][2]; int mean_bits; int ch, gr, analog_silence; III_side_info_t *const l3_side = &gfc->l3_side; analog_silence = VBR_old_prepare(gfc, pe, ms_ener_ratio, ratio, l3_xmin, frameBits, min_bits, max_bits, bands); /*---------------------------------*/ for (;;) { /* quantize granules with lowest possible number of bits */ used_bits = 0; for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { int ret; gr_info *const cod_info = &l3_side->tt[gr][ch]; /* init_outer_loop sets up cod_info, scalefac and xrpow */ ret = init_xrpow(gfc, cod_info, xrpow); if (ret == 0 || max_bits[gr][ch] == 0) { /* xr contains no energy * l3_enc, our encoding data, will be quantized to zero */ continue; /* with next channel */ } VBR_encode_granule(gfc, cod_info, l3_xmin[gr][ch], xrpow, ch, min_bits[gr][ch], max_bits[gr][ch]); /* do the 'substep shaping' */ if (gfc->sv_qnt.substep_shaping & 1) { trancate_smallspectrums(gfc, &l3_side->tt[gr][ch], l3_xmin[gr][ch], xrpow); } ret = cod_info->part2_3_length + cod_info->part2_length; used_bits += ret; } /* for ch */ } /* for gr */ /* find lowest bitrate able to hold used bits */ if (analog_silence && !cfg->enforce_min_bitrate) /* we detected analog silence and the user did not specify * any hard framesize limit, so start with smallest possible frame */ eov->bitrate_index = 1; else eov->bitrate_index = cfg->vbr_min_bitrate_index; for (; eov->bitrate_index < cfg->vbr_max_bitrate_index; eov->bitrate_index++) { if (used_bits <= frameBits[eov->bitrate_index]) break; } bits = ResvFrameBegin(gfc, &mean_bits); if (used_bits <= bits) break; bitpressure_strategy(gfc, l3_xmin, (const int (*)[2])min_bits, max_bits); } /* breaks adjusted */ /*--------------------------------------*/ for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { iteration_finish_one(gfc, gr, ch); } /* for ch */ } /* for gr */ ResvFrameEnd(gfc, mean_bits); } static int VBR_new_prepare(lame_internal_flags * gfc, const FLOAT pe[2][2], const III_psy_ratio ratio[2][2], FLOAT l3_xmin[2][2][SFBMAX], int frameBits[16], int max_bits[2][2], int* max_resv) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; int gr, ch; int analog_silence = 1; int avg, bits = 0; int maximum_framebits; if (!cfg->free_format) { eov->bitrate_index = cfg->vbr_max_bitrate_index; (void) ResvFrameBegin(gfc, &avg); *max_resv = gfc->sv_enc.ResvMax; get_framebits(gfc, frameBits); maximum_framebits = frameBits[cfg->vbr_max_bitrate_index]; } else { eov->bitrate_index = 0; maximum_framebits = ResvFrameBegin(gfc, &avg); frameBits[0] = maximum_framebits; *max_resv = gfc->sv_enc.ResvMax; } for (gr = 0; gr < cfg->mode_gr; gr++) { (void) on_pe(gfc, pe, max_bits[gr], avg, gr, 0); if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { ms_convert(&gfc->l3_side, gr); } for (ch = 0; ch < cfg->channels_out; ++ch) { gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; gfc->sv_qnt.masking_lower = pow(10.0, gfc->sv_qnt.mask_adjust * 0.1); init_outer_loop(gfc, cod_info); if (0 != calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin[gr][ch])) analog_silence = 0; bits += max_bits[gr][ch]; } } for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { if (bits > maximum_framebits && bits > 0) { max_bits[gr][ch] *= maximum_framebits; max_bits[gr][ch] /= bits; } } /* for ch */ } /* for gr */ if (analog_silence) { *max_resv = 0; } return analog_silence; } void VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; FLOAT l3_xmin[2][2][SFBMAX]; FLOAT xrpow[2][2][576]; int frameBits[15]; int used_bits; int max_bits[2][2]; int ch, gr, analog_silence, pad; III_side_info_t *const l3_side = &gfc->l3_side; const FLOAT (*const_l3_xmin)[2][SFBMAX] = (const FLOAT (*)[2][SFBMAX])l3_xmin; const FLOAT (*const_xrpow)[2][576] = (const FLOAT (*)[2][576])xrpow; const int (*const_max_bits)[2] = (const int (*)[2])max_bits; (void) ms_ener_ratio; /* not used */ memset(xrpow, 0, sizeof(xrpow)); analog_silence = VBR_new_prepare(gfc, pe, ratio, l3_xmin, frameBits, max_bits, &pad); for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gr_info *const cod_info = &l3_side->tt[gr][ch]; /* init_outer_loop sets up cod_info, scalefac and xrpow */ if (0 == init_xrpow(gfc, cod_info, xrpow[gr][ch])) { max_bits[gr][ch] = 0; /* silent granule needs no bits */ } } /* for ch */ } /* for gr */ /* quantize granules with lowest possible number of bits */ used_bits = VBR_encode_frame(gfc, const_xrpow, const_l3_xmin, const_max_bits); if (!cfg->free_format) { int i, j; /* find lowest bitrate able to hold used bits */ if (analog_silence && !cfg->enforce_min_bitrate) { /* we detected analog silence and the user did not specify * any hard framesize limit, so start with smallest possible frame */ i = 1; } else { i = cfg->vbr_min_bitrate_index; } for (; i < cfg->vbr_max_bitrate_index; i++) { if (used_bits <= frameBits[i]) break; } if (i > cfg->vbr_max_bitrate_index) { i = cfg->vbr_max_bitrate_index; } if (pad > 0) { for (j = cfg->vbr_max_bitrate_index; j > i; --j) { int const unused = frameBits[j] - used_bits; if (unused <= pad) break; } eov->bitrate_index = j; } else { eov->bitrate_index = i; } } else { #if 0 static int mmm = 0; int fff = getFramesize_kbps(gfc, used_bits); int hhh = getFramesize_kbps(gfc, MAX_BITS_PER_GRANULE * cfg->mode_gr); if (mmm < fff) mmm = fff; printf("demand=%3d kbps max=%3d kbps limit=%3d kbps\n", fff, mmm, hhh); #endif eov->bitrate_index = 0; } if (used_bits <= frameBits[eov->bitrate_index]) { /* update Reservoire status */ int mean_bits, fullframebits; fullframebits = ResvFrameBegin(gfc, &mean_bits); assert(used_bits <= fullframebits); for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gr_info const *const cod_info = &l3_side->tt[gr][ch]; ResvAdjust(gfc, cod_info); } } ResvFrameEnd(gfc, mean_bits); } else { /* SHOULD NOT HAPPEN INTERNAL ERROR */ ERRORF(gfc, "INTERNAL ERROR IN VBR NEW CODE, please send bug report\n"); exit(-1); } } /******************************************************************** * * calc_target_bits() * * calculates target bits for ABR encoding * * mt 2000/05/31 * ********************************************************************/ static void calc_target_bits(lame_internal_flags * gfc, const FLOAT pe[2][2], FLOAT const ms_ener_ratio[2], int targ_bits[2][2], int *analog_silence_bits, int *max_frame_bits) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; III_side_info_t const *const l3_side = &gfc->l3_side; FLOAT res_factor; int gr, ch, totbits, mean_bits; int framesize = 576 * cfg->mode_gr; eov->bitrate_index = cfg->vbr_max_bitrate_index; *max_frame_bits = ResvFrameBegin(gfc, &mean_bits); eov->bitrate_index = 1; mean_bits = getframebits(gfc) - cfg->sideinfo_len * 8; *analog_silence_bits = mean_bits / (cfg->mode_gr * cfg->channels_out); mean_bits = cfg->vbr_avg_bitrate_kbps * framesize * 1000; if (gfc->sv_qnt.substep_shaping & 1) mean_bits *= 1.09; mean_bits /= cfg->samplerate_out; mean_bits -= cfg->sideinfo_len * 8; mean_bits /= (cfg->mode_gr * cfg->channels_out); /* res_factor is the percentage of the target bitrate that should be used on average. the remaining bits are added to the bitreservoir and used for difficult to encode frames. Since we are tracking the average bitrate, we should adjust res_factor "on the fly", increasing it if the average bitrate is greater than the requested bitrate, and decreasing it otherwise. Reasonable ranges are from .9 to 1.0 Until we get the above suggestion working, we use the following tuning: compression ratio res_factor 5.5 (256kbps) 1.0 no need for bitreservoir 11 (128kbps) .93 7% held for reservoir with linear interpolation for other values. */ res_factor = .93 + .07 * (11.0 - cfg->compression_ratio) / (11.0 - 5.5); if (res_factor < .90) res_factor = .90; if (res_factor > 1.00) res_factor = 1.00; for (gr = 0; gr < cfg->mode_gr; gr++) { int sum = 0; for (ch = 0; ch < cfg->channels_out; ch++) { targ_bits[gr][ch] = res_factor * mean_bits; if (pe[gr][ch] > 700) { int add_bits = (pe[gr][ch] - 700) / 1.4; gr_info const *const cod_info = &l3_side->tt[gr][ch]; targ_bits[gr][ch] = res_factor * mean_bits; /* short blocks use a little extra, no matter what the pe */ if (cod_info->block_type == SHORT_TYPE) { if (add_bits < mean_bits / 2) add_bits = mean_bits / 2; } /* at most increase bits by 1.5*average */ if (add_bits > mean_bits * 3 / 2) add_bits = mean_bits * 3 / 2; else if (add_bits < 0) add_bits = 0; targ_bits[gr][ch] += add_bits; } if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL) { targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL; } sum += targ_bits[gr][ch]; } /* for ch */ if (sum > MAX_BITS_PER_GRANULE) { for (ch = 0; ch < cfg->channels_out; ++ch) { targ_bits[gr][ch] *= MAX_BITS_PER_GRANULE; targ_bits[gr][ch] /= sum; } } } /* for gr */ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) for (gr = 0; gr < cfg->mode_gr; gr++) { reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits * cfg->channels_out, MAX_BITS_PER_GRANULE); } /* sum target bits */ totbits = 0; for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL) targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL; totbits += targ_bits[gr][ch]; } } /* repartion target bits if needed */ if (totbits > *max_frame_bits && totbits > 0) { for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { targ_bits[gr][ch] *= *max_frame_bits; targ_bits[gr][ch] /= totbits; } } } } /******************************************************************** * * ABR_iteration_loop() * * encode a frame with a disired average bitrate * * mt 2000/05/31 * ********************************************************************/ void ABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; EncResult_t *const eov = &gfc->ov_enc; FLOAT l3_xmin[SFBMAX]; FLOAT xrpow[576]; int targ_bits[2][2]; int mean_bits, max_frame_bits; int ch, gr, ath_over; int analog_silence_bits; gr_info *cod_info; III_side_info_t *const l3_side = &gfc->l3_side; mean_bits = 0; calc_target_bits(gfc, pe, ms_ener_ratio, targ_bits, &analog_silence_bits, &max_frame_bits); /* encode granules */ for (gr = 0; gr < cfg->mode_gr; gr++) { if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { ms_convert(&gfc->l3_side, gr); } for (ch = 0; ch < cfg->channels_out; ch++) { FLOAT adjust, masking_lower_db; cod_info = &l3_side->tt[gr][ch]; if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */ /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */ adjust = 0; masking_lower_db = gfc->sv_qnt.mask_adjust - adjust; } else { /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */ adjust = 0; masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust; } gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1); /* cod_info, scalefac and xrpow get initialized in init_outer_loop */ init_outer_loop(gfc, cod_info); if (init_xrpow(gfc, cod_info, xrpow)) { /* xr contains energy we will have to encode * calculate the masking abilities * find some good quantization in outer_loop */ ath_over = calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin); if (0 == ath_over) /* analog silence */ targ_bits[gr][ch] = analog_silence_bits; (void) outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits[gr][ch]); } iteration_finish_one(gfc, gr, ch); } /* ch */ } /* gr */ /* find a bitrate which can refill the resevoir to positive size. */ for (eov->bitrate_index = cfg->vbr_min_bitrate_index; eov->bitrate_index <= cfg->vbr_max_bitrate_index; eov->bitrate_index++) { if (ResvFrameBegin(gfc, &mean_bits) >= 0) break; } assert(eov->bitrate_index <= cfg->vbr_max_bitrate_index); ResvFrameEnd(gfc, mean_bits); } /************************************************************************ * * CBR_iteration_loop() * * author/date?? * * encodes one frame of MP3 data with constant bitrate * ************************************************************************/ void CBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; FLOAT l3_xmin[SFBMAX]; FLOAT xrpow[576]; int targ_bits[2]; int mean_bits, max_bits; int gr, ch; III_side_info_t *const l3_side = &gfc->l3_side; gr_info *cod_info; (void) ResvFrameBegin(gfc, &mean_bits); /* quantize! */ for (gr = 0; gr < cfg->mode_gr; gr++) { /* calculate needed bits */ max_bits = on_pe(gfc, pe, targ_bits, mean_bits, gr, gr); if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { ms_convert(&gfc->l3_side, gr); reduce_side(targ_bits, ms_ener_ratio[gr], mean_bits, max_bits); } for (ch = 0; ch < cfg->channels_out; ch++) { FLOAT adjust, masking_lower_db; cod_info = &l3_side->tt[gr][ch]; if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */ /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */ adjust = 0; masking_lower_db = gfc->sv_qnt.mask_adjust - adjust; } else { /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */ adjust = 0; masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust; } gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1); /* init_outer_loop sets up cod_info, scalefac and xrpow */ init_outer_loop(gfc, cod_info); if (init_xrpow(gfc, cod_info, xrpow)) { /* xr contains energy we will have to encode * calculate the masking abilities * find some good quantization in outer_loop */ (void) calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin); (void) outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits[ch]); } iteration_finish_one(gfc, gr, ch); assert(cod_info->part2_3_length <= MAX_BITS_PER_CHANNEL); assert(cod_info->part2_3_length <= targ_bits[ch]); } /* for ch */ } /* for gr */ ResvFrameEnd(gfc, mean_bits); } ================================================ FILE: app/jni/libmp3lame/quantize.h ================================================ /* * MP3 quantization * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_QUANTIZE_H #define LAME_QUANTIZE_H void CBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); void VBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); void VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); void ABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); #endif /* LAME_QUANTIZE_H */ ================================================ FILE: app/jni/libmp3lame/quantize_pvt.c ================================================ /* * quantize_pvt source file * * Copyright (c) 1999-2002 Takehiro Tominaga * Copyright (c) 2000-2012 Robert Hegemann * Copyright (c) 2001 Naoki Shibata * Copyright (c) 2002-2005 Gabriel Bouvigne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: quantize_pvt.c,v 1.169.2.2 2012/02/07 13:40:37 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "quantize_pvt.h" #include "reservoir.h" #include "lame-analysis.h" #include #include #define NSATHSCALE 100 /* Assuming dynamic range=96dB, this value should be 92 */ /* The following table is used to implement the scalefactor partitioning for MPEG2 as described in section 2.4.3.2 of the IS. The indexing corresponds to the way the tables are presented in the IS: [table_number][row_in_table][column of nr_of_sfb] */ const int nr_of_sfb_block[6][3][4] = { { {6, 5, 5, 5}, {9, 9, 9, 9}, {6, 9, 9, 9} }, { {6, 5, 7, 3}, {9, 9, 12, 6}, {6, 9, 12, 6} }, { {11, 10, 0, 0}, {18, 18, 0, 0}, {15, 18, 0, 0} }, { {7, 7, 7, 0}, {12, 12, 12, 0}, {6, 15, 12, 0} }, { {6, 6, 6, 3}, {12, 9, 9, 6}, {6, 12, 9, 6} }, { {8, 8, 5, 0}, {15, 12, 9, 0}, {6, 18, 9, 0} } }; /* Table B.6: layer3 preemphasis */ const int pretab[SBMAX_l] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; /* Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor bands. Index into this using a method such as: idx = fr_ps->header->sampling_frequency + (fr_ps->header->version * 3) */ const scalefac_struct sfBandIndex[9] = { { /* Table B.2.b: 22.05 kHz */ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, {0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, 540, 576}, {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* Table B.2.a: 16 kHz */ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* Table B.8.b: 44.1 kHz */ {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576}, {0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* Table B.8.c: 48 kHz */ {0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576}, {0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* Table B.8.a: 32 kHz */ {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576}, {0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* MPEG-2.5 11.025 kHz */ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, 402 / 3, 522 / 3, 576 / 3} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* MPEG-2.5 12 kHz */ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576}, {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, 402 / 3, 522 / 3, 576 / 3} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ }, { /* MPEG-2.5 8 kHz */ {0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576}, {0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3, 492 / 3, 498 / 3, 576 / 3} , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ } }; FLOAT pow20[Q_MAX + Q_MAX2 + 1]; FLOAT ipow20[Q_MAX]; FLOAT pow43[PRECALC_SIZE]; /* initialized in first call to iteration_init */ #ifdef TAKEHIRO_IEEE754_HACK FLOAT adj43asm[PRECALC_SIZE]; #else FLOAT adj43[PRECALC_SIZE]; #endif /* compute the ATH for each scalefactor band cd range: 0..96db Input: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest = -5db) longblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db shortblocks: sfb=5 -9db 0db Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) longblocks: amp=1 sfb=12 en0/bw=-103 db max_en0 = -92db amp=32767 sfb=12 -12 db -1.4db Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) shortblocks: amp=1 sfb=5 en0/bw= -99 -86 amp=32767 sfb=5 -9 db 4db MAX energy of largest wave at 3.3kHz = 1db AVE energy of largest wave at 3.3kHz = -11db Let's take AVE: -11db = maximum signal in sfb=12. Dynamic range of CD: 96db. Therefor energy of smallest audible wave in sfb=12 = -11 - 96 = -107db = ATH at 3.3kHz. ATH formula for this wave: -5db. To adjust to LAME scaling, we need ATH = ATH_formula - 103 (db) ATH = ATH * 2.5e-10 (ener) */ static FLOAT ATHmdct(SessionConfig_t const *cfg, FLOAT f) { FLOAT ath; ath = ATHformula(cfg, f); if (cfg->ATHfixpoint > 0) { ath -= cfg->ATHfixpoint; } else { ath -= NSATHSCALE; } ath += cfg->ATH_offset_db; /* modify the MDCT scaling for the ATH and convert to energy */ ath = powf(10.0f, ath * 0.1f); return ath; } static void compute_ath(lame_internal_flags const* gfc) { SessionConfig_t const *const cfg = &gfc->cfg; FLOAT *const ATH_l = gfc->ATH->l; FLOAT *const ATH_psfb21 = gfc->ATH->psfb21; FLOAT *const ATH_s = gfc->ATH->s; FLOAT *const ATH_psfb12 = gfc->ATH->psfb12; int sfb, i, start, end; FLOAT ATH_f; FLOAT const samp_freq = cfg->samplerate_out; for (sfb = 0; sfb < SBMAX_l; sfb++) { start = gfc->scalefac_band.l[sfb]; end = gfc->scalefac_band.l[sfb + 1]; ATH_l[sfb] = FLOAT_MAX; for (i = start; i < end; i++) { FLOAT const freq = i * samp_freq / (2 * 576); ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ ATH_l[sfb] = Min(ATH_l[sfb], ATH_f); } } for (sfb = 0; sfb < PSFB21; sfb++) { start = gfc->scalefac_band.psfb21[sfb]; end = gfc->scalefac_band.psfb21[sfb + 1]; ATH_psfb21[sfb] = FLOAT_MAX; for (i = start; i < end; i++) { FLOAT const freq = i * samp_freq / (2 * 576); ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ ATH_psfb21[sfb] = Min(ATH_psfb21[sfb], ATH_f); } } for (sfb = 0; sfb < SBMAX_s; sfb++) { start = gfc->scalefac_band.s[sfb]; end = gfc->scalefac_band.s[sfb + 1]; ATH_s[sfb] = FLOAT_MAX; for (i = start; i < end; i++) { FLOAT const freq = i * samp_freq / (2 * 192); ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ ATH_s[sfb] = Min(ATH_s[sfb], ATH_f); } ATH_s[sfb] *= (gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb]); } for (sfb = 0; sfb < PSFB12; sfb++) { start = gfc->scalefac_band.psfb12[sfb]; end = gfc->scalefac_band.psfb12[sfb + 1]; ATH_psfb12[sfb] = FLOAT_MAX; for (i = start; i < end; i++) { FLOAT const freq = i * samp_freq / (2 * 192); ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ ATH_psfb12[sfb] = Min(ATH_psfb12[sfb], ATH_f); } /*not sure about the following */ ATH_psfb12[sfb] *= (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]); } /* no-ATH mode: * reduce ATH to -200 dB */ if (cfg->noATH) { for (sfb = 0; sfb < SBMAX_l; sfb++) { ATH_l[sfb] = 1E-20; } for (sfb = 0; sfb < PSFB21; sfb++) { ATH_psfb21[sfb] = 1E-20; } for (sfb = 0; sfb < SBMAX_s; sfb++) { ATH_s[sfb] = 1E-20; } for (sfb = 0; sfb < PSFB12; sfb++) { ATH_psfb12[sfb] = 1E-20; } } /* work in progress, don't rely on it too much */ gfc->ATH->floor = 10. * log10(ATHmdct(cfg, -1.)); /* { FLOAT g=10000, t=1e30, x; for ( f = 100; f < 10000; f++ ) { x = ATHmdct( cfg, f ); if ( t > x ) t = x, g = f; } printf("min=%g\n", g); } */ } static float const payload_long[2][4] = { {-0.000f, -0.000f, -0.000f, +0.000f} , {-0.500f, -0.250f, -0.025f, +0.500f} }; static float const payload_short[2][4] = { {-0.000f, -0.000f, -0.000f, +0.000f} , {-2.000f, -1.000f, -0.050f, +0.500f} }; /************************************************************************/ /* initialization for iteration_loop */ /************************************************************************/ void iteration_init(lame_internal_flags * gfc) { SessionConfig_t const *const cfg = &gfc->cfg; III_side_info_t *const l3_side = &gfc->l3_side; FLOAT adjust, db; int i, sel; if (gfc->iteration_init_init == 0) { gfc->iteration_init_init = 1; l3_side->main_data_begin = 0; compute_ath(gfc); pow43[0] = 0.0; for (i = 1; i < PRECALC_SIZE; i++) pow43[i] = pow((FLOAT) i, 4.0 / 3.0); #ifdef TAKEHIRO_IEEE754_HACK adj43asm[0] = 0.0; for (i = 1; i < PRECALC_SIZE; i++) adj43asm[i] = i - 0.5 - pow(0.5 * (pow43[i - 1] + pow43[i]), 0.75); #else for (i = 0; i < PRECALC_SIZE - 1; i++) adj43[i] = (i + 1) - pow(0.5 * (pow43[i] + pow43[i + 1]), 0.75); adj43[i] = 0.5; #endif for (i = 0; i < Q_MAX; i++) ipow20[i] = pow(2.0, (double) (i - 210) * -0.1875); for (i = 0; i <= Q_MAX + Q_MAX2; i++) pow20[i] = pow(2.0, (double) (i - 210 - Q_MAX2) * 0.25); huffman_init(gfc); init_xrpow_core_init(gfc); sel = 1;/* RH: all modes like vbr-new (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) ? 1 : 0;*/ /* long */ db = cfg->adjust_bass_db + payload_long[sel][0]; adjust = powf(10.f, db * 0.1f); for (i = 0; i <= 6; ++i) { gfc->sv_qnt.longfact[i] = adjust; } db = cfg->adjust_alto_db + payload_long[sel][1]; adjust = powf(10.f, db * 0.1f); for (; i <= 13; ++i) { gfc->sv_qnt.longfact[i] = adjust; } db = cfg->adjust_treble_db + payload_long[sel][2]; adjust = powf(10.f, db * 0.1f); for (; i <= 20; ++i) { gfc->sv_qnt.longfact[i] = adjust; } db = cfg->adjust_sfb21_db + payload_long[sel][3]; adjust = powf(10.f, db * 0.1f); for (; i < SBMAX_l; ++i) { gfc->sv_qnt.longfact[i] = adjust; } /* short */ db = cfg->adjust_bass_db + payload_short[sel][0]; adjust = powf(10.f, db * 0.1f); for (i = 0; i <= 2; ++i) { gfc->sv_qnt.shortfact[i] = adjust; } db = cfg->adjust_alto_db + payload_short[sel][1]; adjust = powf(10.f, db * 0.1f); for (; i <= 6; ++i) { gfc->sv_qnt.shortfact[i] = adjust; } db = cfg->adjust_treble_db + payload_short[sel][2]; adjust = powf(10.f, db * 0.1f); for (; i <= 11; ++i) { gfc->sv_qnt.shortfact[i] = adjust; } db = cfg->adjust_sfb21_db + payload_short[sel][3]; adjust = powf(10.f, db * 0.1f); for (; i < SBMAX_s; ++i) { gfc->sv_qnt.shortfact[i] = adjust; } } } /************************************************************************ * allocate bits among 2 channels based on PE * mt 6/99 * bugfixes rh 8/01: often allocated more than the allowed 4095 bits ************************************************************************/ int on_pe(lame_internal_flags * gfc, const FLOAT pe[][2], int targ_bits[2], int mean_bits, int gr, int cbr) { SessionConfig_t const *const cfg = &gfc->cfg; int extra_bits = 0, tbits, bits; int add_bits[2] = {0, 0}; int max_bits; /* maximum allowed bits for this granule */ int ch; /* allocate targ_bits for granule */ ResvMaxBits(gfc, mean_bits, &tbits, &extra_bits, cbr); max_bits = tbits + extra_bits; if (max_bits > MAX_BITS_PER_GRANULE) /* hard limit per granule */ max_bits = MAX_BITS_PER_GRANULE; for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) { /****************************************************************** * allocate bits for each channel ******************************************************************/ targ_bits[ch] = Min(MAX_BITS_PER_CHANNEL, tbits / cfg->channels_out); add_bits[ch] = targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]; /* at most increase bits by 1.5*average */ if (add_bits[ch] > mean_bits * 3 / 4) add_bits[ch] = mean_bits * 3 / 4; if (add_bits[ch] < 0) add_bits[ch] = 0; if (add_bits[ch] + targ_bits[ch] > MAX_BITS_PER_CHANNEL) add_bits[ch] = Max(0, MAX_BITS_PER_CHANNEL - targ_bits[ch]); bits += add_bits[ch]; } if (bits > extra_bits && bits > 0) { for (ch = 0; ch < cfg->channels_out; ++ch) { add_bits[ch] = extra_bits * add_bits[ch] / bits; } } for (ch = 0; ch < cfg->channels_out; ++ch) { targ_bits[ch] += add_bits[ch]; extra_bits -= add_bits[ch]; } for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) { bits += targ_bits[ch]; } if (bits > MAX_BITS_PER_GRANULE) { int sum = 0; for (ch = 0; ch < cfg->channels_out; ++ch) { targ_bits[ch] *= MAX_BITS_PER_GRANULE; targ_bits[ch] /= bits; sum += targ_bits[ch]; } assert(sum <= MAX_BITS_PER_GRANULE); } return max_bits; } void reduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits) { int move_bits; FLOAT fac; assert(max_bits <= MAX_BITS_PER_GRANULE); assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE); /* ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33 * ms_ener_ratio =.5: allocate 50/50 mid/side fac= 0 */ /* 75/25 split is fac=.5 */ /* float fac = .50*(.5-ms_ener_ratio[gr])/.5; */ fac = .33 * (.5 - ms_ener_ratio) / .5; if (fac < 0) fac = 0; if (fac > .5) fac = .5; /* number of bits to move from side channel to mid channel */ /* move_bits = fac*targ_bits[1]; */ move_bits = fac * .5 * (targ_bits[0] + targ_bits[1]); if (move_bits > MAX_BITS_PER_CHANNEL - targ_bits[0]) { move_bits = MAX_BITS_PER_CHANNEL - targ_bits[0]; } if (move_bits < 0) move_bits = 0; if (targ_bits[1] >= 125) { /* dont reduce side channel below 125 bits */ if (targ_bits[1] - move_bits > 125) { /* if mid channel already has 2x more than average, dont bother */ /* mean_bits = bits per granule (for both channels) */ if (targ_bits[0] < mean_bits) targ_bits[0] += move_bits; targ_bits[1] -= move_bits; } else { targ_bits[0] += targ_bits[1] - 125; targ_bits[1] = 125; } } move_bits = targ_bits[0] + targ_bits[1]; if (move_bits > max_bits) { targ_bits[0] = (max_bits * targ_bits[0]) / move_bits; targ_bits[1] = (max_bits * targ_bits[1]) / move_bits; } assert(targ_bits[0] <= MAX_BITS_PER_CHANNEL); assert(targ_bits[1] <= MAX_BITS_PER_CHANNEL); assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE); } /** * Robert Hegemann 2001-04-27: * this adjusts the ATH, keeping the original noise floor * affects the higher frequencies more than the lower ones */ FLOAT athAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint) { /* work in progress */ FLOAT const o = 90.30873362f; FLOAT const p = (ATHfixpoint < 1.f) ? 94.82444863f : ATHfixpoint; FLOAT u = FAST_LOG10_X(x, 10.0f); FLOAT const v = a * a; FLOAT w = 0.0f; u -= athFloor; /* undo scaling */ if (v > 1E-20f) w = 1.f + FAST_LOG10_X(v, 10.0f / o); if (w < 0) w = 0.f; u *= w; u += athFloor + o - p; /* redo scaling */ return powf(10.f, 0.1f * u); } /*************************************************************************/ /* calc_xmin */ /*************************************************************************/ /* Calculate the allowed distortion for each scalefactor band, as determined by the psychoacoustic model. xmin(sb) = ratio(sb) * en(sb) / bw(sb) returns number of sfb's with energy > ATH */ int calc_xmin(lame_internal_flags const *gfc, III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin) { SessionConfig_t const *const cfg = &gfc->cfg; int sfb, gsfb, j = 0, ath_over = 0, k; ATH_t const *const ATH = gfc->ATH; const FLOAT *const xr = cod_info->xr; int max_nonzero; for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) { FLOAT en0, xmin; FLOAT rh1, rh2, rh3; int width, l; xmin = athAdjust(ATH->adjust_factor, ATH->l[gsfb], ATH->floor, cfg->ATHfixpoint); xmin *= gfc->sv_qnt.longfact[gsfb]; width = cod_info->width[gsfb]; rh1 = xmin / width; #ifdef DBL_EPSILON rh2 = DBL_EPSILON; #else rh2 = 2.2204460492503131e-016; #endif en0 = 0.0; for (l = 0; l < width; ++l) { FLOAT const xa = xr[j++]; FLOAT const x2 = xa * xa; en0 += x2; rh2 += (x2 < rh1) ? x2 : rh1; } if (en0 > xmin) ath_over++; if (en0 < xmin) { rh3 = en0; } else if (rh2 < xmin) { rh3 = xmin; } else { rh3 = rh2; } xmin = rh3; { FLOAT const e = ratio->en.l[gsfb]; if (e > 1e-12f) { FLOAT x; x = en0 * ratio->thm.l[gsfb] / e; x *= gfc->sv_qnt.longfact[gsfb]; if (xmin < x) xmin = x; } } xmin = Max(xmin, DBL_EPSILON); cod_info->energy_above_cutoff[gsfb] = (en0 > xmin+1e-14f) ? 1 : 0; *pxmin++ = xmin; } /* end of long block loop */ /*use this function to determine the highest non-zero coeff */ max_nonzero = 0; for (k = 575; k > 0; --k) { if (fabs(xr[k]) > 1e-12f) { max_nonzero = k; break; } } if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */ max_nonzero |= 1; /* only odd numbers */ } else { max_nonzero /= 6; /* 3 short blocks */ max_nonzero *= 6; max_nonzero += 5; } if (gfc->sv_qnt.sfb21_extra == 0 && cfg->samplerate_out < 44000) { int const sfb_l = (cfg->samplerate_out <= 8000) ? 17 : 21; int const sfb_s = (cfg->samplerate_out <= 8000) ? 9 : 12; int limit = 575; if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */ limit = gfc->scalefac_band.l[sfb_l]-1; } else { limit = 3*gfc->scalefac_band.s[sfb_s]-1; } if (max_nonzero > limit) { max_nonzero = limit; } } cod_info->max_nonzero_coeff = max_nonzero; for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) { int width, b, l; FLOAT tmpATH; tmpATH = athAdjust(ATH->adjust_factor, ATH->s[sfb], ATH->floor, cfg->ATHfixpoint); tmpATH *= gfc->sv_qnt.shortfact[sfb]; width = cod_info->width[gsfb]; for (b = 0; b < 3; b++) { FLOAT en0 = 0.0, xmin = tmpATH; FLOAT rh1, rh2, rh3; rh1 = tmpATH / width; #ifdef DBL_EPSILON rh2 = DBL_EPSILON; #else rh2 = 2.2204460492503131e-016; #endif for (l = 0; l < width; ++l) { FLOAT const xa = xr[j++]; FLOAT const x2 = xa * xa; en0 += x2; rh2 += (x2 < rh1) ? x2 : rh1; } if (en0 > tmpATH) ath_over++; if (en0 < tmpATH) { rh3 = en0; } else if (rh2 < tmpATH) { rh3 = tmpATH; } else { rh3 = rh2; } xmin = rh3; { FLOAT const e = ratio->en.s[sfb][b]; if (e > 1e-12f) { FLOAT x; x = en0 * ratio->thm.s[sfb][b] / e; x *= gfc->sv_qnt.shortfact[sfb]; if (xmin < x) xmin = x; } } xmin = Max(xmin, DBL_EPSILON); cod_info->energy_above_cutoff[gsfb+b] = (en0 > xmin+1e-14f) ? 1 : 0; *pxmin++ = xmin; } /* b */ if (cfg->use_temporal_masking_effect) { if (pxmin[-3] > pxmin[-3 + 1]) pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay; if (pxmin[-3 + 1] > pxmin[-3 + 2]) pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay; } } /* end of short block sfb loop */ return ath_over; } static FLOAT calc_noise_core_c(const gr_info * const cod_info, int *startline, int l, FLOAT step) { FLOAT noise = 0; int j = *startline; const int *const ix = cod_info->l3_enc; if (j > cod_info->count1) { while (l--) { FLOAT temp; temp = cod_info->xr[j]; j++; noise += temp * temp; temp = cod_info->xr[j]; j++; noise += temp * temp; } } else if (j > cod_info->big_values) { FLOAT ix01[2]; ix01[0] = 0; ix01[1] = step; while (l--) { FLOAT temp; temp = fabs(cod_info->xr[j]) - ix01[ix[j]]; j++; noise += temp * temp; temp = fabs(cod_info->xr[j]) - ix01[ix[j]]; j++; noise += temp * temp; } } else { while (l--) { FLOAT temp; temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step; j++; noise += temp * temp; temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step; j++; noise += temp * temp; } } *startline = j; return noise; } /*************************************************************************/ /* calc_noise */ /*************************************************************************/ /* -oo dB => -1.00 */ /* - 6 dB => -0.97 */ /* - 3 dB => -0.80 */ /* - 2 dB => -0.64 */ /* - 1 dB => -0.38 */ /* 0 dB => 0.00 */ /* + 1 dB => +0.49 */ /* + 2 dB => +1.06 */ /* + 3 dB => +1.68 */ /* + 6 dB => +3.69 */ /* +10 dB => +6.45 */ int calc_noise(gr_info const *const cod_info, FLOAT const *l3_xmin, FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise) { int sfb, l, over = 0; FLOAT over_noise_db = 0; FLOAT tot_noise_db = 0; /* 0 dB relative to masking */ FLOAT max_noise = -20.0; /* -200 dB relative to masking */ int j = 0; const int *scalefac = cod_info->scalefac; res->over_SSD = 0; for (sfb = 0; sfb < cod_info->psymax; sfb++) { int const s = cod_info->global_gain - (((*scalefac++) + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)) - cod_info->subblock_gain[cod_info->window[sfb]] * 8; FLOAT const r_l3_xmin = 1.f / *l3_xmin++; FLOAT distort_ = 0.0f; FLOAT noise = 0.0f; if (prev_noise && (prev_noise->step[sfb] == s)) { /* use previously computed values */ j += cod_info->width[sfb]; distort_ = r_l3_xmin * prev_noise->noise[sfb]; noise = prev_noise->noise_log[sfb]; } else { FLOAT const step = POW20(s); l = cod_info->width[sfb] >> 1; if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) { int usefullsize; usefullsize = cod_info->max_nonzero_coeff - j + 1; if (usefullsize > 0) l = usefullsize >> 1; else l = 0; } noise = calc_noise_core_c(cod_info, &j, l, step); if (prev_noise) { /* save noise values */ prev_noise->step[sfb] = s; prev_noise->noise[sfb] = noise; } distort_ = r_l3_xmin * noise; /* multiplying here is adding in dB, but can overflow */ noise = FAST_LOG10(Max(distort_, 1E-20f)); if (prev_noise) { /* save noise values */ prev_noise->noise_log[sfb] = noise; } } *distort++ = distort_; if (prev_noise) { /* save noise values */ prev_noise->global_gain = cod_info->global_gain;; } /*tot_noise *= Max(noise, 1E-20); */ tot_noise_db += noise; if (noise > 0.0) { int tmp; tmp = Max((int) (noise * 10 + .5), 1); res->over_SSD += tmp * tmp; over++; /* multiplying here is adding in dB -but can overflow */ /*over_noise *= noise; */ over_noise_db += noise; } max_noise = Max(max_noise, noise); } res->over_count = over; res->tot_noise = tot_noise_db; res->over_noise = over_noise_db; res->max_noise = max_noise; return over; } /************************************************************************ * * set_pinfo() * * updates plotting data * * Mark Taylor 2000-??-?? * * Robert Hegemann: moved noise/distortion calc into it * ************************************************************************/ static void set_pinfo(lame_internal_flags const *gfc, gr_info * const cod_info, const III_psy_ratio * const ratio, const int gr, const int ch) { SessionConfig_t const *const cfg = &gfc->cfg; int sfb, sfb2; int j, i, l, start, end, bw; FLOAT en0, en1; FLOAT const ifqstep = (cod_info->scalefac_scale == 0) ? .5 : 1.0; int const *const scalefac = cod_info->scalefac; FLOAT l3_xmin[SFBMAX], xfsf[SFBMAX]; calc_noise_result noise; (void) calc_xmin(gfc, ratio, cod_info, l3_xmin); (void) calc_noise(cod_info, l3_xmin, xfsf, &noise, 0); j = 0; sfb2 = cod_info->sfb_lmax; if (cod_info->block_type != SHORT_TYPE && !cod_info->mixed_block_flag) sfb2 = 22; for (sfb = 0; sfb < sfb2; sfb++) { start = gfc->scalefac_band.l[sfb]; end = gfc->scalefac_band.l[sfb + 1]; bw = end - start; for (en0 = 0.0; j < end; j++) en0 += cod_info->xr[j] * cod_info->xr[j]; en0 /= bw; /* convert to MDCT units */ en1 = 1e15; /* scaling so it shows up on FFT plot */ gfc->pinfo->en[gr][ch][sfb] = en1 * en0; gfc->pinfo->xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw; if (ratio->en.l[sfb] > 0 && !cfg->ATHonly) en0 = en0 / ratio->en.l[sfb]; else en0 = 0.0; gfc->pinfo->thr[gr][ch][sfb] = en1 * Max(en0 * ratio->thm.l[sfb], gfc->ATH->l[sfb]); /* there is no scalefactor bands >= SBPSY_l */ gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0; if (cod_info->preflag && sfb >= 11) gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb]; if (sfb < SBPSY_l) { assert(scalefac[sfb] >= 0); /* scfsi should be decoded by caller side */ gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb]; } } /* for sfb */ if (cod_info->block_type == SHORT_TYPE) { sfb2 = sfb; for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) { start = gfc->scalefac_band.s[sfb]; end = gfc->scalefac_band.s[sfb + 1]; bw = end - start; for (i = 0; i < 3; i++) { for (en0 = 0.0, l = start; l < end; l++) { en0 += cod_info->xr[j] * cod_info->xr[j]; j++; } en0 = Max(en0 / bw, 1e-20); /* convert to MDCT units */ en1 = 1e15; /* scaling so it shows up on FFT plot */ gfc->pinfo->en_s[gr][ch][3 * sfb + i] = en1 * en0; gfc->pinfo->xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] * xfsf[sfb2] / bw; if (ratio->en.s[sfb][i] > 0) en0 = en0 / ratio->en.s[sfb][i]; else en0 = 0.0; if (cfg->ATHonly || cfg->ATHshort) en0 = 0; gfc->pinfo->thr_s[gr][ch][3 * sfb + i] = en1 * Max(en0 * ratio->thm.s[sfb][i], gfc->ATH->s[sfb]); /* there is no scalefactor bands >= SBPSY_s */ gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i] = -2.0 * cod_info->subblock_gain[i]; if (sfb < SBPSY_s) { gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep * scalefac[sfb2]; } sfb2++; } } } /* block type short */ gfc->pinfo->LAMEqss[gr][ch] = cod_info->global_gain; gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length + cod_info->part2_length; gfc->pinfo->LAMEsfbits[gr][ch] = cod_info->part2_length; gfc->pinfo->over[gr][ch] = noise.over_count; gfc->pinfo->max_noise[gr][ch] = noise.max_noise * 10.0; gfc->pinfo->over_noise[gr][ch] = noise.over_noise * 10.0; gfc->pinfo->tot_noise[gr][ch] = noise.tot_noise * 10.0; gfc->pinfo->over_SSD[gr][ch] = noise.over_SSD; } /************************************************************************ * * set_frame_pinfo() * * updates plotting data for a whole frame * * Robert Hegemann 2000-10-21 * ************************************************************************/ void set_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; int ch; int gr; /* for every granule and channel patch l3_enc and set info */ for (gr = 0; gr < cfg->mode_gr; gr++) { for (ch = 0; ch < cfg->channels_out; ch++) { gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; int scalefac_sav[SFBMAX]; memcpy(scalefac_sav, cod_info->scalefac, sizeof(scalefac_sav)); /* reconstruct the scalefactors in case SCFSI was used */ if (gr == 1) { int sfb; for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) { if (cod_info->scalefac[sfb] < 0) /* scfsi */ cod_info->scalefac[sfb] = gfc->l3_side.tt[0][ch].scalefac[sfb]; } } set_pinfo(gfc, cod_info, &ratio[gr][ch], gr, ch); memcpy(cod_info->scalefac, scalefac_sav, sizeof(scalefac_sav)); } /* for ch */ } /* for gr */ } ================================================ FILE: app/jni/libmp3lame/quantize_pvt.h ================================================ /* * quantize_pvt include file * * Copyright (c) 1999 Takehiro TOMINAGA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_QUANTIZE_PVT_H #define LAME_QUANTIZE_PVT_H #define IXMAX_VAL 8206 /* ix always <= 8191+15. see count_bits() */ /* buggy Winamp decoder cannot handle values > 8191 */ /* #define IXMAX_VAL 8191 */ #define PRECALC_SIZE (IXMAX_VAL+2) extern const int nr_of_sfb_block[6][3][4]; extern const int pretab[SBMAX_l]; extern const int slen1_tab[16]; extern const int slen2_tab[16]; extern const scalefac_struct sfBandIndex[9]; extern FLOAT pow43[PRECALC_SIZE]; #ifdef TAKEHIRO_IEEE754_HACK extern FLOAT adj43asm[PRECALC_SIZE]; #else extern FLOAT adj43[PRECALC_SIZE]; #endif #define Q_MAX (256+1) #define Q_MAX2 116 /* minimum possible number of -cod_info->global_gain + ((scalefac[] + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)) + cod_info->subblock_gain[cod_info->window[sfb]] * 8; for long block, 0+((15+3)<<2) = 18*4 = 72 for short block, 0+(15<<2)+7*8 = 15*4+56 = 116 */ extern FLOAT pow20[Q_MAX + Q_MAX2 + 1]; extern FLOAT ipow20[Q_MAX]; typedef struct calc_noise_result_t { FLOAT over_noise; /* sum of quantization noise > masking */ FLOAT tot_noise; /* sum of all quantization noise */ FLOAT max_noise; /* max quantization noise */ int over_count; /* number of quantization noise > masking */ int over_SSD; /* SSD-like cost of distorted bands */ int bits; } calc_noise_result; /** * allows re-use of previously * computed noise values */ typedef struct calc_noise_data_t { int global_gain; int sfb_count1; int step[39]; FLOAT noise[39]; FLOAT noise_log[39]; } calc_noise_data; int on_pe(lame_internal_flags * gfc, const FLOAT pe[2][2], int targ_bits[2], int mean_bits, int gr, int cbr); void reduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits); void iteration_init(lame_internal_flags * gfc); int calc_xmin(lame_internal_flags const *gfc, III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * l3_xmin); int calc_noise(const gr_info * const cod_info, const FLOAT * l3_xmin, FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise); void set_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2]); /* takehiro.c */ int count_bits(lame_internal_flags const *const gfc, const FLOAT * const xr, gr_info * const cod_info, calc_noise_data * prev_noise); int noquant_count_bits(lame_internal_flags const *const gfc, gr_info * const cod_info, calc_noise_data * prev_noise); void best_huffman_divide(const lame_internal_flags * const gfc, gr_info * const cod_info); void best_scalefac_store(const lame_internal_flags * gfc, const int gr, const int ch, III_side_info_t * const l3_side); int scale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info); void huffman_init(lame_internal_flags * const gfc); void init_xrpow_core_init(lame_internal_flags * const gfc); FLOAT athAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint); #define LARGE_BITS 100000 #endif /* LAME_QUANTIZE_PVT_H */ ================================================ FILE: app/jni/libmp3lame/reservoir.c ================================================ /* * bit reservoir source file * * Copyright (c) 1999-2000 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: reservoir.c,v 1.45 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "reservoir.h" #include "bitstream.h" #include "lame-analysis.h" #include "lame_global_flags.h" /* ResvFrameBegin: Called (repeatedly) at the beginning of a frame. Updates the maximum size of the reservoir, and checks to make sure main_data_begin was set properly by the formatter */ /* * Background information: * * This is the original text from the ISO standard. Because of * sooo many bugs and irritations correcting comments are added * in brackets []. A '^W' means you should remove the last word. * * 1) The following rule can be used to calculate the maximum * number of bits used for one granule [^W frame]: * At the highest possible bitrate of Layer III (320 kbps * per stereo signal [^W^W^W], 48 kHz) the frames must be of * [^W^W^W are designed to have] constant length, i.e. * one buffer [^W^W the frame] length is: * * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte * * This value is used as the maximum buffer per channel [^W^W] at * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit * [per granule and channel] at 48 kHz sampling frequency. * This means that there is a maximum deviation (short time buffer * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. * The actual deviation is equal to the number of bytes [with the * meaning of octets] denoted by the main_data_end offset pointer. * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. * ... The xchange of buffer bits between the left and right channel * is allowed without restrictions [exception: dual channel]. * Because of the [constructed] constraint on the buffer size * main_data_end is always set to 0 in the case of bit_rate_index==14, * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case * all data are allocated between adjacent header [^W sync] words * [, i.e. there is no buffering at all]. */ int ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int fullFrameBits; int resvLimit; int maxmp3buf; III_side_info_t *const l3_side = &gfc->l3_side; int frameLength; int meanBits; frameLength = getframebits(gfc); meanBits = (frameLength - cfg->sideinfo_len * 8) / cfg->mode_gr; /* * Meaning of the variables: * resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1)) * Number of bits can be stored in previous frame(s) due to * counter size constaints * maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5)) * Number of bits allowed to encode one frame (you can take 8*511 bit * from the bit reservoir and at most 8*1440 bit from the current * frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible * value for MPEG-1 and -2) * * maximum allowed granule/channel size times 4 = 8*2047 bits., * so this is the absolute maximum supported by the format. * * * fullFrameBits: maximum number of bits available for encoding * the current frame. * * mean_bits: target number of bits per granule. * * frameLength: * * gfc->ResvMax: maximum allowed reservoir * * gfc->ResvSize: current reservoir size * * l3_side->resvDrain_pre: * ancillary data to be added to previous frame: * (only usefull in VBR modes if it is possible to have * maxmp3buf < fullFrameBits)). Currently disabled, * see #define NEW_DRAIN * 2010-02-13: RH now enabled, it seems to be needed for CBR too, * as there exists one example, where the FhG decoder * can't decode a -b320 CBR file anymore. * * l3_side->resvDrain_post: * ancillary data to be added to this frame: * */ /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ resvLimit = (8 * 256) * cfg->mode_gr - 8; /* maximum allowed frame size. dont use more than this number of bits, even if the frame has the space for them: */ maxmp3buf = cfg->buffer_constraint; esv->ResvMax = maxmp3buf - frameLength; if (esv->ResvMax > resvLimit) esv->ResvMax = resvLimit; if (esv->ResvMax < 0 || cfg->disable_reservoir) esv->ResvMax = 0; fullFrameBits = meanBits * cfg->mode_gr + Min(esv->ResvSize, esv->ResvMax); if (fullFrameBits > maxmp3buf) fullFrameBits = maxmp3buf; assert(0 == esv->ResvMax % 8); assert(esv->ResvMax >= 0); l3_side->resvDrain_pre = 0; if (gfc->pinfo != NULL) { gfc->pinfo->mean_bits = meanBits / 2; /* expected bits per channel per granule [is this also right for mono/stereo, MPEG-1/2 ?] */ gfc->pinfo->resvsize = esv->ResvSize; } *mean_bits = meanBits; return fullFrameBits; } /* ResvMaxBits returns targ_bits: target number of bits to use for 1 granule extra_bits: amount extra available from reservoir Mark Taylor 4/99 */ void ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *extra_bits, int cbr) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; int add_bits, targBits, extraBits; int ResvSize = esv->ResvSize, ResvMax = esv->ResvMax; /* conpensate the saved bits used in the 1st granule */ if (cbr) ResvSize += mean_bits; if (gfc->sv_qnt.substep_shaping & 1) ResvMax *= 0.9; targBits = mean_bits; /* extra bits if the reservoir is almost full */ if (ResvSize * 10 > ResvMax * 9) { add_bits = ResvSize - (ResvMax * 9) / 10; targBits += add_bits; gfc->sv_qnt.substep_shaping |= 0x80; } else { add_bits = 0; gfc->sv_qnt.substep_shaping &= 0x7f; /* build up reservoir. this builds the reservoir a little slower * than FhG. It could simple be mean_bits/15, but this was rigged * to always produce 100 (the old value) at 128kbs */ /* *targ_bits -= (int) (mean_bits/15.2); */ if (!cfg->disable_reservoir && !(gfc->sv_qnt.substep_shaping & 1)) targBits -= .1 * mean_bits; } /* amount from the reservoir we are allowed to use. ISO says 6/10 */ extraBits = (ResvSize < (esv->ResvMax * 6) / 10 ? ResvSize : (esv->ResvMax * 6) / 10); extraBits -= add_bits; if (extraBits < 0) extraBits = 0; *targ_bits = targBits; *extra_bits = extraBits; } /* ResvAdjust: Called after a granule's bit allocation. Readjusts the size of the reservoir to reflect the granule's usage. */ void ResvAdjust(lame_internal_flags * gfc, gr_info const *gi) { gfc->sv_enc.ResvSize -= gi->part2_3_length + gi->part2_length; } /* ResvFrameEnd: Called after all granules in a frame have been allocated. Makes sure that the reservoir size is within limits, possibly by adding stuffing bits. */ void ResvFrameEnd(lame_internal_flags * gfc, int mean_bits) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *const esv = &gfc->sv_enc; III_side_info_t *const l3_side = &gfc->l3_side; int stuffingBits; int over_bits; esv->ResvSize += mean_bits * cfg->mode_gr; stuffingBits = 0; l3_side->resvDrain_post = 0; l3_side->resvDrain_pre = 0; /* we must be byte aligned */ if ((over_bits = esv->ResvSize % 8) != 0) stuffingBits += over_bits; over_bits = (esv->ResvSize - stuffingBits) - esv->ResvMax; if (over_bits > 0) { assert(0 == over_bits % 8); assert(over_bits >= 0); stuffingBits += over_bits; } /* NOTE: enabling the NEW_DRAIN code fixes some problems with FhG decoder shipped with MS Windows operating systems. Using this, it is even possible to use Gabriel's lax buffer consideration again, which assumes, any decoder should have a buffer large enough for a 320 kbps frame at 32 kHz sample rate. old drain code: lame -b320 BlackBird.wav ---> does not play with GraphEdit.exe using FhG decoder V1.5 Build 50 new drain code: lame -b320 BlackBird.wav ---> plays fine with GraphEdit.exe using FhG decoder V1.5 Build 50 Robert Hegemann, 2010-02-13. */ /* drain as many bits as possible into previous frame ancillary data * In particular, in VBR mode ResvMax may have changed, and we have * to make sure main_data_begin does not create a reservoir bigger * than ResvMax mt 4/00*/ { int mdb_bytes = Min(l3_side->main_data_begin * 8, stuffingBits) / 8; l3_side->resvDrain_pre += 8 * mdb_bytes; stuffingBits -= 8 * mdb_bytes; esv->ResvSize -= 8 * mdb_bytes; l3_side->main_data_begin -= mdb_bytes; } /* drain the rest into this frames ancillary data */ l3_side->resvDrain_post += stuffingBits; esv->ResvSize -= stuffingBits; } ================================================ FILE: app/jni/libmp3lame/reservoir.h ================================================ /* * bit reservoir include file * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_RESERVOIR_H #define LAME_RESERVOIR_H int ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits); void ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *max_bits, int cbr); void ResvAdjust(lame_internal_flags * gfc, gr_info const *gi); void ResvFrameEnd(lame_internal_flags * gfc, int mean_bits); #endif /* LAME_RESERVOIR_H */ ================================================ FILE: app/jni/libmp3lame/set_get.c ================================================ /* -*- mode: C; mode: fold -*- */ /* * set/get functions for lame_global_flags * * Copyright (c) 2001-2005 Alexander Leidinger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: set_get.c,v 1.98 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "bitstream.h" /* because of compute_flushbits */ #include "set_get.h" #include "lame_global_flags.h" /* * input stream description */ /* number of samples */ /* it's unlikely for this function to return an error */ int lame_set_num_samples(lame_global_flags * gfp, unsigned long num_samples) { if (is_lame_global_flags_valid(gfp)) { /* default = 2^32-1 */ gfp->num_samples = num_samples; return 0; } return -1; } unsigned long lame_get_num_samples(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->num_samples; } return 0; } /* input samplerate */ int lame_set_in_samplerate(lame_global_flags * gfp, int in_samplerate) { if (is_lame_global_flags_valid(gfp)) { /* input sample rate in Hz, default = 44100 Hz */ gfp->samplerate_in = in_samplerate; return 0; } return -1; } int lame_get_in_samplerate(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->samplerate_in; } return 0; } /* number of channels in input stream */ int lame_set_num_channels(lame_global_flags * gfp, int num_channels) { if (is_lame_global_flags_valid(gfp)) { /* default = 2 */ if (2 < num_channels || 0 == num_channels) { return -1; /* we don't support more than 2 channels */ } gfp->num_channels = num_channels; return 0; } return -1; } int lame_get_num_channels(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->num_channels; } return 0; } /* scale the input by this amount before encoding (not used for decoding) */ int lame_set_scale(lame_global_flags * gfp, float scale) { if (is_lame_global_flags_valid(gfp)) { /* default = 1 */ gfp->scale = scale; return 0; } return -1; } float lame_get_scale(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->scale; } return 0; } /* scale the channel 0 (left) input by this amount before encoding (not used for decoding) */ int lame_set_scale_left(lame_global_flags * gfp, float scale) { if (is_lame_global_flags_valid(gfp)) { /* default = 1 */ gfp->scale_left = scale; return 0; } return -1; } float lame_get_scale_left(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->scale_left; } return 0; } /* scale the channel 1 (right) input by this amount before encoding (not used for decoding) */ int lame_set_scale_right(lame_global_flags * gfp, float scale) { if (is_lame_global_flags_valid(gfp)) { /* default = 1 */ gfp->scale_right = scale; return 0; } return -1; } float lame_get_scale_right(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->scale_right; } return 0; } /* output sample rate in Hz */ int lame_set_out_samplerate(lame_global_flags * gfp, int out_samplerate) { if (is_lame_global_flags_valid(gfp)) { /* * default = 0: LAME picks best value based on the amount * of compression * MPEG only allows: * MPEG1 32, 44.1, 48khz * MPEG2 16, 22.05, 24 * MPEG2.5 8, 11.025, 12 * * (not used by decoding routines) */ gfp->samplerate_out = out_samplerate; return 0; } return -1; } int lame_get_out_samplerate(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->samplerate_out; } return 0; } /* * general control parameters */ /* collect data for an MP3 frame analzyer */ int lame_set_analysis(lame_global_flags * gfp, int analysis) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > analysis || 1 < analysis) return -1; gfp->analysis = analysis; return 0; } return -1; } int lame_get_analysis(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->analysis && 1 >= gfp->analysis); return gfp->analysis; } return 0; } /* write a Xing VBR header frame */ int lame_set_bWriteVbrTag(lame_global_flags * gfp, int bWriteVbrTag) { if (is_lame_global_flags_valid(gfp)) { /* default = 1 (on) for VBR/ABR modes, 0 (off) for CBR mode */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > bWriteVbrTag || 1 < bWriteVbrTag) return -1; gfp->write_lame_tag = bWriteVbrTag; return 0; } return -1; } int lame_get_bWriteVbrTag(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->write_lame_tag && 1 >= gfp->write_lame_tag); return gfp->write_lame_tag; } return 0; } /* decode only, use lame/mpglib to convert mp3 to wav */ int lame_set_decode_only(lame_global_flags * gfp, int decode_only) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > decode_only || 1 < decode_only) return -1; gfp->decode_only = decode_only; return 0; } return -1; } int lame_get_decode_only(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->decode_only && 1 >= gfp->decode_only); return gfp->decode_only; } return 0; } #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED /* 1=encode a Vorbis .ogg file. default=0 */ /* DEPRECATED */ int CDECL lame_set_ogg(lame_global_flags *, int); int CDECL lame_get_ogg(const lame_global_flags *); #else #endif /* encode a Vorbis .ogg file */ /* DEPRECATED */ int lame_set_ogg(lame_global_flags * gfp, int ogg) { (void) gfp; (void) ogg; return -1; } int lame_get_ogg(const lame_global_flags * gfp) { (void) gfp; return 0; } /* * Internal algorithm selection. * True quality is determined by the bitrate but this variable will effect * quality by selecting expensive or cheap algorithms. * quality=0..9. 0=best (very slow). 9=worst. * recommended: 3 near-best quality, not too slow * 5 good quality, fast * 7 ok quality, really fast */ int lame_set_quality(lame_global_flags * gfp, int quality) { if (is_lame_global_flags_valid(gfp)) { if (quality < 0) { gfp->quality = 0; } else if (quality > 9) { gfp->quality = 9; } else { gfp->quality = quality; } return 0; } return -1; } int lame_get_quality(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->quality; } return 0; } /* mode = STEREO, JOINT_STEREO, DUAL_CHANNEL (not supported), MONO */ int lame_set_mode(lame_global_flags * gfp, MPEG_mode mode) { if (is_lame_global_flags_valid(gfp)) { int mpg_mode = mode; /* default: lame chooses based on compression ratio and input channels */ if (mpg_mode < 0 || MAX_INDICATOR <= mpg_mode) return -1; /* Unknown MPEG mode! */ gfp->mode = mode; return 0; } return -1; } MPEG_mode lame_get_mode(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(gfp->mode < MAX_INDICATOR); return gfp->mode; } return NOT_SET; } #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED /* mode_automs. Use a M/S mode with a switching threshold based on compression ratio DEPRECATED */ int CDECL lame_set_mode_automs(lame_global_flags *, int); int CDECL lame_get_mode_automs(const lame_global_flags *); #else #endif /* Us a M/S mode with a switching threshold based on compression ratio */ /* DEPRECATED */ int lame_set_mode_automs(lame_global_flags * gfp, int mode_automs) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > mode_automs || 1 < mode_automs) return -1; lame_set_mode(gfp, JOINT_STEREO); return 0; } return -1; } int lame_get_mode_automs(const lame_global_flags * gfp) { (void) gfp; return 1; } /* * Force M/S for all frames. For testing only. * Requires mode = 1. */ int lame_set_force_ms(lame_global_flags * gfp, int force_ms) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > force_ms || 1 < force_ms) return -1; gfp->force_ms = force_ms; return 0; } return -1; } int lame_get_force_ms(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->force_ms && 1 >= gfp->force_ms); return gfp->force_ms; } return 0; } /* Use free_format. */ int lame_set_free_format(lame_global_flags * gfp, int free_format) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > free_format || 1 < free_format) return -1; gfp->free_format = free_format; return 0; } return -1; } int lame_get_free_format(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->free_format && 1 >= gfp->free_format); return gfp->free_format; } return 0; } /* Perform ReplayGain analysis */ int lame_set_findReplayGain(lame_global_flags * gfp, int findReplayGain) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > findReplayGain || 1 < findReplayGain) return -1; gfp->findReplayGain = findReplayGain; return 0; } return -1; } int lame_get_findReplayGain(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->findReplayGain && 1 >= gfp->findReplayGain); return gfp->findReplayGain; } return 0; } /* Decode on the fly. Find the peak sample. If ReplayGain analysis is enabled then perform it on the decoded data. */ int lame_set_decode_on_the_fly(lame_global_flags * gfp, int decode_on_the_fly) { if (is_lame_global_flags_valid(gfp)) { #ifndef DECODE_ON_THE_FLY return -1; #else /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > decode_on_the_fly || 1 < decode_on_the_fly) return -1; gfp->decode_on_the_fly = decode_on_the_fly; return 0; #endif } return -1; } int lame_get_decode_on_the_fly(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->decode_on_the_fly && 1 >= gfp->decode_on_the_fly); return gfp->decode_on_the_fly; } return 0; } #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED /* DEPRECATED: now does the same as lame_set_findReplayGain() default = 0 (disabled) */ int CDECL lame_set_ReplayGain_input(lame_global_flags *, int); int CDECL lame_get_ReplayGain_input(const lame_global_flags *); /* DEPRECATED: now does the same as lame_set_decode_on_the_fly() && lame_set_findReplayGain() default = 0 (disabled) */ int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int); int CDECL lame_get_ReplayGain_decode(const lame_global_flags *); /* DEPRECATED: now does the same as lame_set_decode_on_the_fly() default = 0 (disabled) */ int CDECL lame_set_findPeakSample(lame_global_flags *, int); int CDECL lame_get_findPeakSample(const lame_global_flags *); #else #endif /* DEPRECATED. same as lame_set_decode_on_the_fly() */ int lame_set_findPeakSample(lame_global_flags * gfp, int arg) { return lame_set_decode_on_the_fly(gfp, arg); } int lame_get_findPeakSample(const lame_global_flags * gfp) { return lame_get_decode_on_the_fly(gfp); } /* DEPRECATED. same as lame_set_findReplayGain() */ int lame_set_ReplayGain_input(lame_global_flags * gfp, int arg) { return lame_set_findReplayGain(gfp, arg); } int lame_get_ReplayGain_input(const lame_global_flags * gfp) { return lame_get_findReplayGain(gfp); } /* DEPRECATED. same as lame_set_decode_on_the_fly() && lame_set_findReplayGain() */ int lame_set_ReplayGain_decode(lame_global_flags * gfp, int arg) { if (lame_set_decode_on_the_fly(gfp, arg) < 0 || lame_set_findReplayGain(gfp, arg) < 0) return -1; else return 0; } int lame_get_ReplayGain_decode(const lame_global_flags * gfp) { if (lame_get_decode_on_the_fly(gfp) > 0 && lame_get_findReplayGain(gfp) > 0) return 1; else return 0; } /* set and get some gapless encoding flags */ int lame_set_nogap_total(lame_global_flags * gfp, int the_nogap_total) { if (is_lame_global_flags_valid(gfp)) { gfp->nogap_total = the_nogap_total; return 0; } return -1; } int lame_get_nogap_total(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->nogap_total; } return 0; } int lame_set_nogap_currentindex(lame_global_flags * gfp, int the_nogap_index) { if (is_lame_global_flags_valid(gfp)) { gfp->nogap_current = the_nogap_index; return 0; } return -1; } int lame_get_nogap_currentindex(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->nogap_current; } return 0; } /* message handlers */ int lame_set_errorf(lame_global_flags * gfp, void (*func) (const char *, va_list)) { if (is_lame_global_flags_valid(gfp)) { gfp->report.errorf = func; return 0; } return -1; } int lame_set_debugf(lame_global_flags * gfp, void (*func) (const char *, va_list)) { if (is_lame_global_flags_valid(gfp)) { gfp->report.debugf = func; return 0; } return -1; } int lame_set_msgf(lame_global_flags * gfp, void (*func) (const char *, va_list)) { if (is_lame_global_flags_valid(gfp)) { gfp->report.msgf = func; return 0; } return -1; } /* * Set one of * - brate * - compression ratio. * * Default is compression ratio of 11. */ int lame_set_brate(lame_global_flags * gfp, int brate) { if (is_lame_global_flags_valid(gfp)) { gfp->brate = brate; if (brate > 320) { gfp->disable_reservoir = 1; } return 0; } return -1; } int lame_get_brate(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->brate; } return 0; } int lame_set_compression_ratio(lame_global_flags * gfp, float compression_ratio) { if (is_lame_global_flags_valid(gfp)) { gfp->compression_ratio = compression_ratio; return 0; } return -1; } float lame_get_compression_ratio(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->compression_ratio; } return 0; } /* * frame parameters */ /* Mark as copyright protected. */ int lame_set_copyright(lame_global_flags * gfp, int copyright) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > copyright || 1 < copyright) return -1; gfp->copyright = copyright; return 0; } return -1; } int lame_get_copyright(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->copyright && 1 >= gfp->copyright); return gfp->copyright; } return 0; } /* Mark as original. */ int lame_set_original(lame_global_flags * gfp, int original) { if (is_lame_global_flags_valid(gfp)) { /* default = 1 (enabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > original || 1 < original) return -1; gfp->original = original; return 0; } return -1; } int lame_get_original(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->original && 1 >= gfp->original); return gfp->original; } return 0; } /* * error_protection. * Use 2 bytes from each frame for CRC checksum. */ int lame_set_error_protection(lame_global_flags * gfp, int error_protection) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > error_protection || 1 < error_protection) return -1; gfp->error_protection = error_protection; return 0; } return -1; } int lame_get_error_protection(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->error_protection && 1 >= gfp->error_protection); return gfp->error_protection; } return 0; } #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED /* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */ int CDECL lame_set_padding_type(lame_global_flags *, Padding_type); Padding_type CDECL lame_get_padding_type(const lame_global_flags *); #else #endif /* * padding_type. * PAD_NO = pad no frames * PAD_ALL = pad all frames * PAD_ADJUST = adjust padding */ int lame_set_padding_type(lame_global_flags * gfp, Padding_type padding_type) { (void) gfp; (void) padding_type; return 0; } Padding_type lame_get_padding_type(const lame_global_flags * gfp) { (void) gfp; return PAD_ADJUST; } /* MP3 'private extension' bit. Meaningless. */ int lame_set_extension(lame_global_flags * gfp, int extension) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > extension || 1 < extension) return -1; gfp->extension = extension; return 0; } return -1; } int lame_get_extension(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->extension && 1 >= gfp->extension); return gfp->extension; } return 0; } /* Enforce strict ISO compliance. */ int lame_set_strict_ISO(lame_global_flags * gfp, int val) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (val < MDB_DEFAULT || MDB_MAXIMUM < val) return -1; gfp->strict_ISO = val; return 0; } return -1; } int lame_get_strict_ISO(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->strict_ISO; } return 0; } /******************************************************************** * quantization/noise shaping ***********************************************************************/ /* Disable the bit reservoir. For testing only. */ int lame_set_disable_reservoir(lame_global_flags * gfp, int disable_reservoir) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > disable_reservoir || 1 < disable_reservoir) return -1; gfp->disable_reservoir = disable_reservoir; return 0; } return -1; } int lame_get_disable_reservoir(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->disable_reservoir && 1 >= gfp->disable_reservoir); return gfp->disable_reservoir; } return 0; } int lame_set_experimentalX(lame_global_flags * gfp, int experimentalX) { if (is_lame_global_flags_valid(gfp)) { lame_set_quant_comp(gfp, experimentalX); lame_set_quant_comp_short(gfp, experimentalX); return 0; } return -1; } int lame_get_experimentalX(const lame_global_flags * gfp) { return lame_get_quant_comp(gfp); } /* Select a different "best quantization" function. default = 0 */ int lame_set_quant_comp(lame_global_flags * gfp, int quant_type) { if (is_lame_global_flags_valid(gfp)) { gfp->quant_comp = quant_type; return 0; } return -1; } int lame_get_quant_comp(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->quant_comp; } return 0; } /* Select a different "best quantization" function. default = 0 */ int lame_set_quant_comp_short(lame_global_flags * gfp, int quant_type) { if (is_lame_global_flags_valid(gfp)) { gfp->quant_comp_short = quant_type; return 0; } return -1; } int lame_get_quant_comp_short(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->quant_comp_short; } return 0; } /* Another experimental option. For testing only. */ int lame_set_experimentalY(lame_global_flags * gfp, int experimentalY) { if (is_lame_global_flags_valid(gfp)) { gfp->experimentalY = experimentalY; return 0; } return -1; } int lame_get_experimentalY(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->experimentalY; } return 0; } int lame_set_experimentalZ(lame_global_flags * gfp, int experimentalZ) { if (is_lame_global_flags_valid(gfp)) { gfp->experimentalZ = experimentalZ; return 0; } return -1; } int lame_get_experimentalZ(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->experimentalZ; } return 0; } /* Naoki's psycho acoustic model. */ int lame_set_exp_nspsytune(lame_global_flags * gfp, int exp_nspsytune) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ gfp->exp_nspsytune = exp_nspsytune; return 0; } return -1; } int lame_get_exp_nspsytune(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->exp_nspsytune; } return 0; } /******************************************************************** * VBR control ***********************************************************************/ /* Types of VBR. default = vbr_off = CBR */ int lame_set_VBR(lame_global_flags * gfp, vbr_mode VBR) { if (is_lame_global_flags_valid(gfp)) { int vbr_q = VBR; if (0 > vbr_q || vbr_max_indicator <= vbr_q) return -1; /* Unknown VBR mode! */ gfp->VBR = VBR; return 0; } return -1; } vbr_mode lame_get_VBR(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(gfp->VBR < vbr_max_indicator); return gfp->VBR; } return vbr_off; } /* * VBR quality level. * 0 = highest * 9 = lowest */ int lame_set_VBR_q(lame_global_flags * gfp, int VBR_q) { if (is_lame_global_flags_valid(gfp)) { int ret = 0; if (0 > VBR_q) { ret = -1; /* Unknown VBR quality level! */ VBR_q = 0; } if (9 < VBR_q) { ret = -1; VBR_q = 9; } gfp->VBR_q = VBR_q; gfp->VBR_q_frac = 0; return ret; } return -1; } int lame_get_VBR_q(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->VBR_q && 10 > gfp->VBR_q); return gfp->VBR_q; } return 0; } int lame_set_VBR_quality(lame_global_flags * gfp, float VBR_q) { if (is_lame_global_flags_valid(gfp)) { int ret = 0; if (0 > VBR_q) { ret = -1; /* Unknown VBR quality level! */ VBR_q = 0; } if (9.999 < VBR_q) { ret = -1; VBR_q = 9.999; } gfp->VBR_q = (int) VBR_q; gfp->VBR_q_frac = VBR_q - gfp->VBR_q; return ret; } return -1; } float lame_get_VBR_quality(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->VBR_q + gfp->VBR_q_frac; } return 0; } /* Ignored except for VBR = vbr_abr (ABR mode) */ int lame_set_VBR_mean_bitrate_kbps(lame_global_flags * gfp, int VBR_mean_bitrate_kbps) { if (is_lame_global_flags_valid(gfp)) { gfp->VBR_mean_bitrate_kbps = VBR_mean_bitrate_kbps; return 0; } return -1; } int lame_get_VBR_mean_bitrate_kbps(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->VBR_mean_bitrate_kbps; } return 0; } int lame_set_VBR_min_bitrate_kbps(lame_global_flags * gfp, int VBR_min_bitrate_kbps) { if (is_lame_global_flags_valid(gfp)) { gfp->VBR_min_bitrate_kbps = VBR_min_bitrate_kbps; return 0; } return -1; } int lame_get_VBR_min_bitrate_kbps(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->VBR_min_bitrate_kbps; } return 0; } int lame_set_VBR_max_bitrate_kbps(lame_global_flags * gfp, int VBR_max_bitrate_kbps) { if (is_lame_global_flags_valid(gfp)) { gfp->VBR_max_bitrate_kbps = VBR_max_bitrate_kbps; return 0; } return -1; } int lame_get_VBR_max_bitrate_kbps(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->VBR_max_bitrate_kbps; } return 0; } /* * Strictly enforce VBR_min_bitrate. * Normally it will be violated for analog silence. */ int lame_set_VBR_hard_min(lame_global_flags * gfp, int VBR_hard_min) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 (disabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > VBR_hard_min || 1 < VBR_hard_min) return -1; gfp->VBR_hard_min = VBR_hard_min; return 0; } return -1; } int lame_get_VBR_hard_min(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->VBR_hard_min && 1 >= gfp->VBR_hard_min); return gfp->VBR_hard_min; } return 0; } /******************************************************************** * Filtering control ***********************************************************************/ /* * Freqency in Hz to apply lowpass. * 0 = default = lame chooses * -1 = disabled */ int lame_set_lowpassfreq(lame_global_flags * gfp, int lowpassfreq) { if (is_lame_global_flags_valid(gfp)) { gfp->lowpassfreq = lowpassfreq; return 0; } return -1; } int lame_get_lowpassfreq(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->lowpassfreq; } return 0; } /* * Width of transition band (in Hz). * default = one polyphase filter band */ int lame_set_lowpasswidth(lame_global_flags * gfp, int lowpasswidth) { if (is_lame_global_flags_valid(gfp)) { gfp->lowpasswidth = lowpasswidth; return 0; } return -1; } int lame_get_lowpasswidth(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->lowpasswidth; } return 0; } /* * Frequency in Hz to apply highpass. * 0 = default = lame chooses * -1 = disabled */ int lame_set_highpassfreq(lame_global_flags * gfp, int highpassfreq) { if (is_lame_global_flags_valid(gfp)) { gfp->highpassfreq = highpassfreq; return 0; } return -1; } int lame_get_highpassfreq(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->highpassfreq; } return 0; } /* * Width of transition band (in Hz). * default = one polyphase filter band */ int lame_set_highpasswidth(lame_global_flags * gfp, int highpasswidth) { if (is_lame_global_flags_valid(gfp)) { gfp->highpasswidth = highpasswidth; return 0; } return -1; } int lame_get_highpasswidth(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->highpasswidth; } return 0; } /* * psycho acoustics and other arguments which you should not change * unless you know what you are doing */ /* Adjust masking values. */ int lame_set_maskingadjust(lame_global_flags * gfp, float adjust) { if (is_lame_global_flags_valid(gfp)) { gfp->maskingadjust = adjust; return 0; } return -1; } float lame_get_maskingadjust(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->maskingadjust; } return 0; } int lame_set_maskingadjust_short(lame_global_flags * gfp, float adjust) { if (is_lame_global_flags_valid(gfp)) { gfp->maskingadjust_short = adjust; return 0; } return -1; } float lame_get_maskingadjust_short(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->maskingadjust_short; } return 0; } /* Only use ATH for masking. */ int lame_set_ATHonly(lame_global_flags * gfp, int ATHonly) { if (is_lame_global_flags_valid(gfp)) { gfp->ATHonly = ATHonly; return 0; } return -1; } int lame_get_ATHonly(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->ATHonly; } return 0; } /* Only use ATH for short blocks. */ int lame_set_ATHshort(lame_global_flags * gfp, int ATHshort) { if (is_lame_global_flags_valid(gfp)) { gfp->ATHshort = ATHshort; return 0; } return -1; } int lame_get_ATHshort(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->ATHshort; } return 0; } /* Disable ATH. */ int lame_set_noATH(lame_global_flags * gfp, int noATH) { if (is_lame_global_flags_valid(gfp)) { gfp->noATH = noATH; return 0; } return -1; } int lame_get_noATH(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->noATH; } return 0; } /* Select ATH formula. */ int lame_set_ATHtype(lame_global_flags * gfp, int ATHtype) { if (is_lame_global_flags_valid(gfp)) { /* XXX: ATHtype should be converted to an enum. */ gfp->ATHtype = ATHtype; return 0; } return -1; } int lame_get_ATHtype(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->ATHtype; } return 0; } /* Select ATH formula 4 shape. */ int lame_set_ATHcurve(lame_global_flags * gfp, float ATHcurve) { if (is_lame_global_flags_valid(gfp)) { gfp->ATHcurve = ATHcurve; return 0; } return -1; } float lame_get_ATHcurve(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->ATHcurve; } return 0; } /* Lower ATH by this many db. */ int lame_set_ATHlower(lame_global_flags * gfp, float ATHlower) { if (is_lame_global_flags_valid(gfp)) { gfp->ATH_lower_db = ATHlower; return 0; } return -1; } float lame_get_ATHlower(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->ATH_lower_db; } return 0; } /* Select ATH adaptive adjustment scheme. */ int lame_set_athaa_type(lame_global_flags * gfp, int athaa_type) { if (is_lame_global_flags_valid(gfp)) { gfp->athaa_type = athaa_type; return 0; } return -1; } int lame_get_athaa_type(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->athaa_type; } return 0; } #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED int CDECL lame_set_athaa_loudapprox(lame_global_flags * gfp, int athaa_loudapprox); int CDECL lame_get_athaa_loudapprox(const lame_global_flags * gfp); #else #endif /* Select the loudness approximation used by the ATH adaptive auto-leveling. */ int lame_set_athaa_loudapprox(lame_global_flags * gfp, int athaa_loudapprox) { (void) gfp; (void) athaa_loudapprox; return 0; } int lame_get_athaa_loudapprox(const lame_global_flags * gfp) { (void) gfp; /* obsolete, the type known under number 2 is the only survival */ return 2; } /* Adjust (in dB) the point below which adaptive ATH level adjustment occurs. */ int lame_set_athaa_sensitivity(lame_global_flags * gfp, float athaa_sensitivity) { if (is_lame_global_flags_valid(gfp)) { gfp->athaa_sensitivity = athaa_sensitivity; return 0; } return -1; } float lame_get_athaa_sensitivity(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->athaa_sensitivity; } return 0; } /* Predictability limit (ISO tonality formula) */ int lame_set_cwlimit(lame_global_flags * gfp, int cwlimit); int lame_get_cwlimit(const lame_global_flags * gfp); int lame_set_cwlimit(lame_global_flags * gfp, int cwlimit) { (void) gfp; (void) cwlimit; return 0; } int lame_get_cwlimit(const lame_global_flags * gfp) { (void) gfp; return 0; } /* * Allow blocktypes to differ between channels. * default: * 0 for jstereo => block types coupled * 1 for stereo => block types may differ */ int lame_set_allow_diff_short(lame_global_flags * gfp, int allow_diff_short) { if (is_lame_global_flags_valid(gfp)) { gfp->short_blocks = allow_diff_short ? short_block_allowed : short_block_coupled; return 0; } return -1; } int lame_get_allow_diff_short(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { if (gfp->short_blocks == short_block_allowed) return 1; /* short blocks allowed to differ */ else return 0; /* not set, dispensed, forced or coupled */ } return 0; } /* Use temporal masking effect */ int lame_set_useTemporal(lame_global_flags * gfp, int useTemporal) { if (is_lame_global_flags_valid(gfp)) { /* default = 1 (enabled) */ /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 <= useTemporal && useTemporal <= 1) { gfp->useTemporal = useTemporal; return 0; } } return -1; } int lame_get_useTemporal(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->useTemporal && 1 >= gfp->useTemporal); return gfp->useTemporal; } return 0; } /* Use inter-channel masking effect */ int lame_set_interChRatio(lame_global_flags * gfp, float ratio) { if (is_lame_global_flags_valid(gfp)) { /* default = 0.0 (no inter-channel maskin) */ if (0 <= ratio && ratio <= 1.0) { gfp->interChRatio = ratio; return 0; } } return -1; } float lame_get_interChRatio(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert((0 <= gfp->interChRatio && gfp->interChRatio <= 1.0) || EQ(gfp->interChRatio, -1)); return gfp->interChRatio; } return 0; } /* Use pseudo substep shaping method */ int lame_set_substep(lame_global_flags * gfp, int method) { if (is_lame_global_flags_valid(gfp)) { /* default = 0.0 (no substep noise shaping) */ if (0 <= method && method <= 7) { gfp->substep_shaping = method; return 0; } } return -1; } int lame_get_substep(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->substep_shaping && gfp->substep_shaping <= 7); return gfp->substep_shaping; } return 0; } /* scalefactors scale */ int lame_set_sfscale(lame_global_flags * gfp, int val) { if (is_lame_global_flags_valid(gfp)) { gfp->noise_shaping = (val != 0) ? 2 : 1; return 0; } return -1; } int lame_get_sfscale(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return (gfp->noise_shaping == 2) ? 1 : 0; } return 0; } /* subblock gain */ int lame_set_subblock_gain(lame_global_flags * gfp, int sbgain) { if (is_lame_global_flags_valid(gfp)) { gfp->subblock_gain = sbgain; return 0; } return -1; } int lame_get_subblock_gain(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->subblock_gain; } return 0; } /* Disable short blocks. */ int lame_set_no_short_blocks(lame_global_flags * gfp, int no_short_blocks) { if (is_lame_global_flags_valid(gfp)) { /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 <= no_short_blocks && no_short_blocks <= 1) { gfp->short_blocks = no_short_blocks ? short_block_dispensed : short_block_allowed; return 0; } } return -1; } int lame_get_no_short_blocks(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { switch (gfp->short_blocks) { default: case short_block_not_set: return -1; case short_block_dispensed: return 1; case short_block_allowed: case short_block_coupled: case short_block_forced: return 0; } } return -1; } /* Force short blocks. */ int lame_set_force_short_blocks(lame_global_flags * gfp, int short_blocks) { if (is_lame_global_flags_valid(gfp)) { /* enforce disable/enable meaning, if we need more than two values we need to switch to an enum to have an apropriate representation of the possible meanings of the value */ if (0 > short_blocks || 1 < short_blocks) return -1; if (short_blocks == 1) gfp->short_blocks = short_block_forced; else if (gfp->short_blocks == short_block_forced) gfp->short_blocks = short_block_allowed; return 0; } return -1; } int lame_get_force_short_blocks(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { switch (gfp->short_blocks) { default: case short_block_not_set: return -1; case short_block_dispensed: case short_block_allowed: case short_block_coupled: return 0; case short_block_forced: return 1; } } return -1; } int lame_set_short_threshold_lrm(lame_global_flags * gfp, float lrm) { if (is_lame_global_flags_valid(gfp)) { gfp->attackthre = lrm; return 0; } return -1; } float lame_get_short_threshold_lrm(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->attackthre; } return 0; } int lame_set_short_threshold_s(lame_global_flags * gfp, float s) { if (is_lame_global_flags_valid(gfp)) { gfp->attackthre_s = s; return 0; } return -1; } float lame_get_short_threshold_s(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->attackthre_s; } return 0; } int lame_set_short_threshold(lame_global_flags * gfp, float lrm, float s) { if (is_lame_global_flags_valid(gfp)) { lame_set_short_threshold_lrm(gfp, lrm); lame_set_short_threshold_s(gfp, s); return 0; } return -1; } /* * Input PCM is emphased PCM * (for instance from one of the rarely emphased CDs). * * It is STRONGLY not recommended to use this, because psycho does not * take it into account, and last but not least many decoders * ignore these bits */ int lame_set_emphasis(lame_global_flags * gfp, int emphasis) { if (is_lame_global_flags_valid(gfp)) { /* XXX: emphasis should be converted to an enum */ if (0 <= emphasis && emphasis < 4) { gfp->emphasis = emphasis; return 0; } } return -1; } int lame_get_emphasis(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { assert(0 <= gfp->emphasis && gfp->emphasis < 4); return gfp->emphasis; } return 0; } /***************************************************************/ /* internal variables, cannot be set... */ /* provided because they may be of use to calling application */ /***************************************************************/ /* MPEG version. * 0 = MPEG-2 * 1 = MPEG-1 * (2 = MPEG-2.5) */ int lame_get_version(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->cfg.version; } } return 0; } /* Encoder delay. */ int lame_get_encoder_delay(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->ov_enc.encoder_delay; } } return 0; } /* padding added to the end of the input */ int lame_get_encoder_padding(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->ov_enc.encoder_padding; } } return 0; } /* Size of MPEG frame. */ int lame_get_framesize(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; return 576 * cfg->mode_gr; } } return 0; } /* Number of frames encoded so far. */ int lame_get_frameNum(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->ov_enc.frame_number; } } return 0; } int lame_get_mf_samples_to_encode(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->sv_enc.mf_samples_to_encode; } } return 0; } int CDECL lame_get_size_mp3buffer(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { int size; compute_flushbits(gfc, &size); return size; } } return 0; } int lame_get_RadioGain(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->ov_rpg.RadioGain; } } return 0; } int lame_get_AudiophileGain(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return 0; } } return 0; } float lame_get_PeakSample(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return (float) gfc->ov_rpg.PeakSample; } } return 0; } int lame_get_noclipGainChange(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->ov_rpg.noclipGainChange; } } return 0; } float lame_get_noclipScale(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { return gfc->ov_rpg.noclipScale; } } return 0; } /* * LAME's estimate of the total number of frames to be encoded. * Only valid if calling program set num_samples. */ int lame_get_totalframes(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { lame_internal_flags const *const gfc = gfp->internal_flags; if (is_lame_internal_flags_valid(gfc)) { SessionConfig_t const *const cfg = &gfc->cfg; unsigned long const pcm_samples_per_frame = 576 * cfg->mode_gr; unsigned long pcm_samples_to_encode = gfp->num_samples; unsigned long end_padding = 0; /* estimate based on user set num_samples: */ if (pcm_samples_to_encode == (0ul-1ul)) { return 0; } if (gfp->samplerate_in != gfp->samplerate_out && gfp->samplerate_in > 0) { double const q = (double)gfp->samplerate_out / gfp->samplerate_in; pcm_samples_to_encode *= q; } pcm_samples_to_encode += 576; end_padding = pcm_samples_per_frame - (pcm_samples_to_encode % pcm_samples_per_frame); if (end_padding < 576) { end_padding += pcm_samples_per_frame; } pcm_samples_to_encode += end_padding; /* check to see if we underestimated totalframes */ /* if (totalframes < gfp->frameNum) */ /* totalframes = gfp->frameNum; */ return pcm_samples_to_encode / pcm_samples_per_frame; } } return 0; } int lame_set_preset(lame_global_flags * gfp, int preset) { if (is_lame_global_flags_valid(gfp)) { gfp->preset = preset; return apply_preset(gfp, preset, 1); } return -1; } int lame_set_asm_optimizations(lame_global_flags * gfp, int optim, int mode) { if (is_lame_global_flags_valid(gfp)) { mode = (mode == 1 ? 1 : 0); switch (optim) { case MMX:{ gfp->asm_optimizations.mmx = mode; return optim; } case AMD_3DNOW:{ gfp->asm_optimizations.amd3dnow = mode; return optim; } case SSE:{ gfp->asm_optimizations.sse = mode; return optim; } default: return optim; } } return -1; } void lame_set_write_id3tag_automatic(lame_global_flags * gfp, int v) { if (is_lame_global_flags_valid(gfp)) { gfp->write_id3tag_automatic = v; } } int lame_get_write_id3tag_automatic(lame_global_flags const *gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->write_id3tag_automatic; } return 1; } /* UNDOCUMENTED, experimental settings. These routines are not prototyped in lame.h. You should not use them, they are experimental and may change. */ /* * just another daily changing developer switch */ void CDECL lame_set_tune(lame_global_flags *, float); void lame_set_tune(lame_global_flags * gfp, float val) { if (is_lame_global_flags_valid(gfp)) { gfp->tune_value_a = val; gfp->tune = 1; } } /* Custom msfix hack */ void lame_set_msfix(lame_global_flags * gfp, double msfix) { if (is_lame_global_flags_valid(gfp)) { /* default = 0 */ gfp->msfix = msfix; } } float lame_get_msfix(const lame_global_flags * gfp) { if (is_lame_global_flags_valid(gfp)) { return gfp->msfix; } return 0; } #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED int CDECL lame_set_preset_expopts(lame_global_flags *, int); #else #endif int lame_set_preset_expopts(lame_global_flags * gfp, int preset_expopts) { (void) gfp; (void) preset_expopts; return 0; } int lame_set_preset_notune(lame_global_flags * gfp, int preset_notune) { (void) gfp; (void) preset_notune; return 0; } ================================================ FILE: app/jni/libmp3lame/set_get.h ================================================ /* * set_get.h -- Internal set/get definitions * * Copyright (C) 2003 Gabriel Bouvigne / Lame project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __SET_GET_H__ #define __SET_GET_H__ #include #if defined(__cplusplus) extern "C" { #endif /* select psychoacoustic model */ /* manage short blocks */ int CDECL lame_set_short_threshold(lame_global_flags *, float, float); int CDECL lame_set_short_threshold_lrm(lame_global_flags *, float); float CDECL lame_get_short_threshold_lrm(const lame_global_flags *); int CDECL lame_set_short_threshold_s(lame_global_flags *, float); float CDECL lame_get_short_threshold_s(const lame_global_flags *); int CDECL lame_set_maskingadjust(lame_global_flags *, float); float CDECL lame_get_maskingadjust(const lame_global_flags *); int CDECL lame_set_maskingadjust_short(lame_global_flags *, float); float CDECL lame_get_maskingadjust_short(const lame_global_flags *); /* select ATH formula 4 shape */ int CDECL lame_set_ATHcurve(lame_global_flags *, float); float CDECL lame_get_ATHcurve(const lame_global_flags *); int CDECL lame_set_preset_notune(lame_global_flags *, int); /* substep shaping method */ int CDECL lame_set_substep(lame_global_flags *, int); int CDECL lame_get_substep(const lame_global_flags *); /* scalefactors scale */ int CDECL lame_set_sfscale(lame_global_flags *, int); int CDECL lame_get_sfscale(const lame_global_flags *); /* subblock gain */ int CDECL lame_set_subblock_gain(lame_global_flags *, int); int CDECL lame_get_subblock_gain(const lame_global_flags *); /*presets*/ int apply_preset(lame_global_flags *, int preset, int enforce); void CDECL lame_set_tune(lame_t, float); /* FOR INTERNAL USE ONLY */ void CDECL lame_set_msfix(lame_t gfp, double msfix); #if defined(__cplusplus) } #endif #endif ================================================ FILE: app/jni/libmp3lame/tables.c ================================================ /* * MPEG layer 3 tables source file * * Copyright (c) 1999 Albert L Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: tables.c,v 1.29 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include "machine.h" #include "lame.h" #include "tables.h" static const uint16_t t1HB[] = { 1, 1, 1, 0 }; static const uint16_t t2HB[] = { 1, 2, 1, 3, 1, 1, 3, 2, 0 }; static const uint16_t t3HB[] = { 3, 2, 1, 1, 1, 1, 3, 2, 0 }; static const uint16_t t5HB[] = { 1, 2, 6, 5, 3, 1, 4, 4, 7, 5, 7, 1, 6, 1, 1, 0 }; static const uint16_t t6HB[] = { 7, 3, 5, 1, 6, 2, 3, 2, 5, 4, 4, 1, 3, 3, 2, 0 }; static const uint16_t t7HB[] = { 1, 2, 10, 19, 16, 10, 3, 3, 7, 10, 5, 3, 11, 4, 13, 17, 8, 4, 12, 11, 18, 15, 11, 2, 7, 6, 9, 14, 3, 1, 6, 4, 5, 3, 2, 0 }; static const uint16_t t8HB[] = { 3, 4, 6, 18, 12, 5, 5, 1, 2, 16, 9, 3, 7, 3, 5, 14, 7, 3, 19, 17, 15, 13, 10, 4, 13, 5, 8, 11, 5, 1, 12, 4, 4, 1, 1, 0 }; static const uint16_t t9HB[] = { 7, 5, 9, 14, 15, 7, 6, 4, 5, 5, 6, 7, 7, 6, 8, 8, 8, 5, 15, 6, 9, 10, 5, 1, 11, 7, 9, 6, 4, 1, 14, 4, 6, 2, 6, 0 }; static const uint16_t t10HB[] = { 1, 2, 10, 23, 35, 30, 12, 17, 3, 3, 8, 12, 18, 21, 12, 7, 11, 9, 15, 21, 32, 40, 19, 6, 14, 13, 22, 34, 46, 23, 18, 7, 20, 19, 33, 47, 27, 22, 9, 3, 31, 22, 41, 26, 21, 20, 5, 3, 14, 13, 10, 11, 16, 6, 5, 1, 9, 8, 7, 8, 4, 4, 2, 0 }; static const uint16_t t11HB[] = { 3, 4, 10, 24, 34, 33, 21, 15, 5, 3, 4, 10, 32, 17, 11, 10, 11, 7, 13, 18, 30, 31, 20, 5, 25, 11, 19, 59, 27, 18, 12, 5, 35, 33, 31, 58, 30, 16, 7, 5, 28, 26, 32, 19, 17, 15, 8, 14, 14, 12, 9, 13, 14, 9, 4, 1, 11, 4, 6, 6, 6, 3, 2, 0 }; static const uint16_t t12HB[] = { 9, 6, 16, 33, 41, 39, 38, 26, 7, 5, 6, 9, 23, 16, 26, 11, 17, 7, 11, 14, 21, 30, 10, 7, 17, 10, 15, 12, 18, 28, 14, 5, 32, 13, 22, 19, 18, 16, 9, 5, 40, 17, 31, 29, 17, 13, 4, 2, 27, 12, 11, 15, 10, 7, 4, 1, 27, 12, 8, 12, 6, 3, 1, 0 }; static const uint16_t t13HB[] = { 1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19, 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14, 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16, 22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14, 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24, 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17, 47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15, 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42, 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16, 53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11, 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22, 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7, 34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5, 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3, 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2, 16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1 }; static const uint16_t t15HB[] = { 7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63, 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36, 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33, 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29, 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27, 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38, 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30, 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25, 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20, 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15, 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9, 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7, 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3, 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1, 71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0 }; static const uint16_t t16HB[] = { 1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17, 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9, 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16, 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26, 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9, 66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16, 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10, 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8, 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7, 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11, 139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4, 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6, 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4, 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2, 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0, 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3 }; static const uint16_t t24HB[] = { 15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88, 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42, 47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18, 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16, 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14, 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12, 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10, 435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17, 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16, 335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11, 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10, 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6, 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4, 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2, 1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0, 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3 }; static const uint16_t t32HB[] = { 1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3, 7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4 }; static const uint16_t t33HB[] = { 15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3, 7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4 }; const uint8_t t1l[] = { 1, 4, 3, 5 }; static const uint8_t t2l[] = { 1, 4, 7, 4, 5, 7, 6, 7, 8 }; static const uint8_t t3l[] = { 2, 3, 7, 4, 4, 7, 6, 7, 8 }; static const uint8_t t5l[] = { 1, 4, 7, 8, 4, 5, 8, 9, 7, 8, 9, 10, 8, 8, 9, 10 }; static const uint8_t t6l[] = { 3, 4, 6, 8, 4, 4, 6, 7, 5, 6, 7, 8, 7, 7, 8, 9 }; static const uint8_t t7l[] = { 1, 4, 7, 9, 9, 10, 4, 6, 8, 9, 9, 10, 7, 7, 9, 10, 10, 11, 8, 9, 10, 11, 11, 11, 8, 9, 10, 11, 11, 12, 9, 10, 11, 12, 12, 12 }; static const uint8_t t8l[] = { 2, 4, 7, 9, 9, 10, 4, 4, 6, 10, 10, 10, 7, 6, 8, 10, 10, 11, 9, 10, 10, 11, 11, 12, 9, 9, 10, 11, 12, 12, 10, 10, 11, 11, 13, 13 }; static const uint8_t t9l[] = { 3, 4, 6, 7, 9, 10, 4, 5, 6, 7, 8, 10, 5, 6, 7, 8, 9, 10, 7, 7, 8, 9, 9, 10, 8, 8, 9, 9, 10, 11, 9, 9, 10, 10, 11, 11 }; static const uint8_t t10l[] = { 1, 4, 7, 9, 10, 10, 10, 11, 4, 6, 8, 9, 10, 11, 10, 10, 7, 8, 9, 10, 11, 12, 11, 11, 8, 9, 10, 11, 12, 12, 11, 12, 9, 10, 11, 12, 12, 12, 12, 12, 10, 11, 12, 12, 13, 13, 12, 13, 9, 10, 11, 12, 12, 12, 13, 13, 10, 10, 11, 12, 12, 13, 13, 13 }; static const uint8_t t11l[] = { 2, 4, 6, 8, 9, 10, 9, 10, 4, 5, 6, 8, 10, 10, 9, 10, 6, 7, 8, 9, 10, 11, 10, 10, 8, 8, 9, 11, 10, 12, 10, 11, 9, 10, 10, 11, 11, 12, 11, 12, 9, 10, 11, 12, 12, 13, 12, 13, 9, 9, 9, 10, 11, 12, 12, 12, 9, 9, 10, 11, 12, 12, 12, 12 }; static const uint8_t t12l[] = { 4, 4, 6, 8, 9, 10, 10, 10, 4, 5, 6, 7, 9, 9, 10, 10, 6, 6, 7, 8, 9, 10, 9, 10, 7, 7, 8, 8, 9, 10, 10, 10, 8, 8, 9, 9, 10, 10, 10, 11, 9, 9, 10, 10, 10, 11, 10, 11, 9, 9, 9, 10, 10, 11, 11, 12, 10, 10, 10, 11, 11, 11, 11, 12 }; static const uint8_t t13l[] = { 1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14, 4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14, 7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15, 8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15, 9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16, 10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16, 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, 11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17, 11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17, 11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19, 12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18, 12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18, 13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18, 14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18, 13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18 }; static const uint8_t t15l[] = { 3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14, 5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14, 10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15 }; static const uint8_t t16_5l[] = { 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11, 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11, 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12, 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12, 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13, 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13, 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14, 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13, 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14, 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14, 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14, 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12 }; static const uint8_t t16l[] = { 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10, 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10, 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11, 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11, 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12, 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12, 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13, 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12, 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13, 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13, 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10 }; static const uint8_t t24l[] = { 4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10, 5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9, 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9, 11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10, 12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, 12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10, 13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6 }; const uint8_t t32l[] = { 1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3, 4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4 }; const uint8_t t33l[] = { 4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4 }; const struct huffcodetab ht[HTN] = { /* xlen, linmax, table, hlen */ {0, 0, NULL, NULL}, {2, 0, t1HB, t1l}, {3, 0, t2HB, t2l}, {3, 0, t3HB, t3l}, {0, 0, NULL, NULL}, /* Apparently not used */ {4, 0, t5HB, t5l}, {4, 0, t6HB, t6l}, {6, 0, t7HB, t7l}, {6, 0, t8HB, t8l}, {6, 0, t9HB, t9l}, {8, 0, t10HB, t10l}, {8, 0, t11HB, t11l}, {8, 0, t12HB, t12l}, {16, 0, t13HB, t13l}, {0, 0, NULL, t16_5l}, /* Apparently not used */ {16, 0, t15HB, t15l}, {1, 1, t16HB, t16l}, {2, 3, t16HB, t16l}, {3, 7, t16HB, t16l}, {4, 15, t16HB, t16l}, {6, 63, t16HB, t16l}, {8, 255, t16HB, t16l}, {10, 1023, t16HB, t16l}, {13, 8191, t16HB, t16l}, {4, 15, t24HB, t24l}, {5, 31, t24HB, t24l}, {6, 63, t24HB, t24l}, {7, 127, t24HB, t24l}, {8, 255, t24HB, t24l}, {9, 511, t24HB, t24l}, {11, 2047, t24HB, t24l}, {13, 8191, t24HB, t24l}, {0, 0, t32HB, t32l}, {0, 0, t33HB, t33l}, }; /* for (i = 0; i < 16*16; i++) { * largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i]; * } */ const uint32_t largetbl[16 * 16] = { 0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b, 0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a, 0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b, 0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a, 0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b, 0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009, 0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009, 0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009, 0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009, 0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a, 0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a, 0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a, 0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a, 0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c, 0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a, 0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a, 0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a, 0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d, 0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a, 0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009, 0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006 }; /* for (i = 0; i < 3*3; i++) { * table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i]; * } */ const uint32_t table23[3 * 3] = { 0x010002, 0x040003, 0x070007, 0x040004, 0x050004, 0x070007, 0x060006, 0x070007, 0x080008 }; /* for (i = 0; i < 4*4; i++) { * table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i]; * } */ const uint32_t table56[4 * 4] = { 0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007, 0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009 }; /* * 0: MPEG-2 LSF * 1: MPEG-1 * 2: MPEG-2.5 LSF FhG extention (1995-07-11 shn) */ typedef enum { MPEG_2 = 0, MPEG_1 = 1, MPEG_25 = 2 } MPEG_t; const int bitrate_table[3][16] = { {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, /* MPEG 2 */ {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}, /* MPEG 1 */ {0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1}, /* MPEG 2.5 */ }; const int samplerate_table[3][4] = { {22050, 24000, 16000, -1}, /* MPEG 2 */ {44100, 48000, 32000, -1}, /* MPEG 1 */ {11025, 12000, 8000, -1}, /* MPEG 2.5 */ }; int lame_get_bitrate(int mpeg_version, int table_index) { if (0 <= mpeg_version && mpeg_version <= 2) { if (0 <= table_index && table_index <= 15) { return bitrate_table[mpeg_version][table_index]; } } return -1; } int lame_get_samplerate(int mpeg_version, int table_index) { if (0 <= mpeg_version && mpeg_version <= 2) { if (0 <= table_index && table_index <= 3) { return samplerate_table[mpeg_version][table_index]; } } return -1; } /* This is the scfsi_band table from 2.4.2.7 of the IS */ const int scfsi_band[5] = { 0, 6, 11, 16, 21 }; /* end of tables.c */ ================================================ FILE: app/jni/libmp3lame/tables.h ================================================ /* * MPEG layer 3 tables include file * * Copyright (c) 1999 Albert L Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_TABLES_H #define LAME_TABLES_H #if 0 typedef struct { unsigned char no; unsigned char width; unsigned char minval_2; float quiet_thr; float norm; float bark; } type1_t; typedef struct { unsigned char no; unsigned char width; float quiet_thr; float norm; float SNR; float bark; } type2_t; typedef struct { unsigned int no:5; unsigned int cbw:3; unsigned int bu:6; unsigned int bo:6; unsigned int w1_576:10; unsigned int w2_576:10; } type34_t; typedef struct { size_t len1; const type1_t *const tab1; size_t len2; const type2_t *const tab2; size_t len3; const type34_t *const tab3; size_t len4; const type34_t *const tab4; } type5_t; extern const type5_t table5[6]; #endif #define HTN 34 struct huffcodetab { const unsigned int xlen; /* max. x-index+ */ const unsigned int linmax; /* max number to be stored in linbits */ const uint16_t *table; /* pointer to array[xlen][ylen] */ const uint8_t *hlen; /* pointer to array[xlen][ylen] */ }; extern const struct huffcodetab ht[HTN]; /* global memory block */ /* array of all huffcodtable headers */ /* 0..31 Huffman code table 0..31 */ /* 32,33 count1-tables */ extern const uint8_t t32l[]; extern const uint8_t t33l[]; extern const uint32_t largetbl[16 * 16]; extern const uint32_t table23[3 * 3]; extern const uint32_t table56[4 * 4]; extern const int scfsi_band[5]; extern const int bitrate_table [3][16]; extern const int samplerate_table [3][ 4]; #endif /* LAME_TABLES_H */ ================================================ FILE: app/jni/libmp3lame/takehiro.c ================================================ /* * MP3 huffman table selecting and bit counting * * Copyright (c) 1999-2005 Takehiro TOMINAGA * Copyright (c) 2002-2005 Gabriel Bouvigne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: takehiro.c,v 1.79 2011/05/07 16:05:17 rbrito Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "quantize_pvt.h" #include "tables.h" static const struct { const int region0_count; const int region1_count; } subdv_table[23] = { { 0, 0}, /* 0 bands */ { 0, 0}, /* 1 bands */ { 0, 0}, /* 2 bands */ { 0, 0}, /* 3 bands */ { 0, 0}, /* 4 bands */ { 0, 1}, /* 5 bands */ { 1, 1}, /* 6 bands */ { 1, 1}, /* 7 bands */ { 1, 2}, /* 8 bands */ { 2, 2}, /* 9 bands */ { 2, 3}, /* 10 bands */ { 2, 3}, /* 11 bands */ { 3, 4}, /* 12 bands */ { 3, 4}, /* 13 bands */ { 3, 4}, /* 14 bands */ { 4, 5}, /* 15 bands */ { 4, 5}, /* 16 bands */ { 4, 6}, /* 17 bands */ { 5, 6}, /* 18 bands */ { 5, 6}, /* 19 bands */ { 5, 7}, /* 20 bands */ { 6, 7}, /* 21 bands */ { 6, 7}, /* 22 bands */ }; /********************************************************************* * nonlinear quantization of xr * More accurate formula than the ISO formula. Takes into account * the fact that we are quantizing xr -> ix, but we want ix^4/3 to be * as close as possible to x^4/3. (taking the nearest int would mean * ix is as close as possible to xr, which is different.) * * From Segher Boessenkool 11/1999 * * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro * Tominaga. If you need the ASM code, check CVS circa Aug 2000. * * 01/2004: Optimizations by Gabriel Bouvigne *********************************************************************/ static void quantize_lines_xrpow_01(unsigned int l, FLOAT istep, const FLOAT * xr, int *ix) { const FLOAT compareval0 = (1.0f - 0.4054f) / istep; unsigned int i; assert(l > 0); assert(l % 2 == 0); for (i = 0; i < l; i += 2) { FLOAT const xr_0 = xr[i+0]; FLOAT const xr_1 = xr[i+1]; int const ix_0 = (compareval0 > xr_0) ? 0 : 1; int const ix_1 = (compareval0 > xr_1) ? 0 : 1; ix[i+0] = ix_0; ix[i+1] = ix_1; } } #ifdef TAKEHIRO_IEEE754_HACK typedef union { float f; int i; } fi_union; #define MAGIC_FLOAT (65536*(128)) #define MAGIC_INT 0x4b000000 static void quantize_lines_xrpow(unsigned int l, FLOAT istep, const FLOAT * xp, int *pi) { fi_union *fi; unsigned int remaining; assert(l > 0); fi = (fi_union *) pi; l = l >> 1; remaining = l % 2; l = l >> 1; while (l--) { double x0 = istep * xp[0]; double x1 = istep * xp[1]; double x2 = istep * xp[2]; double x3 = istep * xp[3]; x0 += MAGIC_FLOAT; fi[0].f = x0; x1 += MAGIC_FLOAT; fi[1].f = x1; x2 += MAGIC_FLOAT; fi[2].f = x2; x3 += MAGIC_FLOAT; fi[3].f = x3; fi[0].f = x0 + adj43asm[fi[0].i - MAGIC_INT]; fi[1].f = x1 + adj43asm[fi[1].i - MAGIC_INT]; fi[2].f = x2 + adj43asm[fi[2].i - MAGIC_INT]; fi[3].f = x3 + adj43asm[fi[3].i - MAGIC_INT]; fi[0].i -= MAGIC_INT; fi[1].i -= MAGIC_INT; fi[2].i -= MAGIC_INT; fi[3].i -= MAGIC_INT; fi += 4; xp += 4; }; if (remaining) { double x0 = istep * xp[0]; double x1 = istep * xp[1]; x0 += MAGIC_FLOAT; fi[0].f = x0; x1 += MAGIC_FLOAT; fi[1].f = x1; fi[0].f = x0 + adj43asm[fi[0].i - MAGIC_INT]; fi[1].f = x1 + adj43asm[fi[1].i - MAGIC_INT]; fi[0].i -= MAGIC_INT; fi[1].i -= MAGIC_INT; } } #else /********************************************************************* * XRPOW_FTOI is a macro to convert floats to ints. * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x] * ROUNDFAC= -0.0946 * * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x] * ROUNDFAC=0.4054 * * Note: using floor() or (int) is extremely slow. On machines where * the TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile * to write some ASM for XRPOW_FTOI(). *********************************************************************/ #define XRPOW_FTOI(src,dest) ((dest) = (int)(src)) #define QUANTFAC(rx) adj43[rx] #define ROUNDFAC 0.4054 static void quantize_lines_xrpow(unsigned int l, FLOAT istep, const FLOAT * xr, int *ix) { unsigned int remaining; assert(l > 0); l = l >> 1; remaining = l % 2; l = l >> 1; while (l--) { FLOAT x0, x1, x2, x3; int rx0, rx1, rx2, rx3; x0 = *xr++ * istep; x1 = *xr++ * istep; XRPOW_FTOI(x0, rx0); x2 = *xr++ * istep; XRPOW_FTOI(x1, rx1); x3 = *xr++ * istep; XRPOW_FTOI(x2, rx2); x0 += QUANTFAC(rx0); XRPOW_FTOI(x3, rx3); x1 += QUANTFAC(rx1); XRPOW_FTOI(x0, *ix++); x2 += QUANTFAC(rx2); XRPOW_FTOI(x1, *ix++); x3 += QUANTFAC(rx3); XRPOW_FTOI(x2, *ix++); XRPOW_FTOI(x3, *ix++); }; if (remaining) { FLOAT x0, x1; int rx0, rx1; x0 = *xr++ * istep; x1 = *xr++ * istep; XRPOW_FTOI(x0, rx0); XRPOW_FTOI(x1, rx1); x0 += QUANTFAC(rx0); x1 += QUANTFAC(rx1); XRPOW_FTOI(x0, *ix++); XRPOW_FTOI(x1, *ix++); } } #endif /********************************************************************* * Quantization function * This function will select which lines to quantize and call the * proper quantization function *********************************************************************/ static void quantize_xrpow(const FLOAT * xp, int *pi, FLOAT istep, gr_info const *const cod_info, calc_noise_data const *prev_noise) { /* quantize on xr^(3/4) instead of xr */ int sfb; int sfbmax; int j = 0; int prev_data_use; int *iData; int accumulate = 0; int accumulate01 = 0; int *acc_iData; const FLOAT *acc_xp; iData = pi; acc_xp = xp; acc_iData = iData; /* Reusing previously computed data does not seems to work if global gain is changed. Finding why it behaves this way would allow to use a cache of previously computed values (let's 10 cached values per sfb) that would probably provide a noticeable speedup */ prev_data_use = (prev_noise && (cod_info->global_gain == prev_noise->global_gain)); if (cod_info->block_type == SHORT_TYPE) sfbmax = 38; else sfbmax = 21; for (sfb = 0; sfb <= sfbmax; sfb++) { int step = -1; if (prev_data_use || cod_info->block_type == NORM_TYPE) { step = cod_info->global_gain - ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)) - cod_info->subblock_gain[cod_info->window[sfb]] * 8; } assert(cod_info->width[sfb] >= 0); if (prev_data_use && (prev_noise->step[sfb] == step)) { /* do not recompute this part, but compute accumulated lines */ if (accumulate) { quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData); accumulate = 0; } if (accumulate01) { quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData); accumulate01 = 0; } } else { /*should compute this part */ int l; l = cod_info->width[sfb]; if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) { /*do not compute upper zero part */ int usefullsize; usefullsize = cod_info->max_nonzero_coeff - j + 1; memset(&pi[cod_info->max_nonzero_coeff], 0, sizeof(int) * (576 - cod_info->max_nonzero_coeff)); l = usefullsize; if (l < 0) { l = 0; } /* no need to compute higher sfb values */ sfb = sfbmax + 1; } /*accumulate lines to quantize */ if (!accumulate && !accumulate01) { acc_iData = iData; acc_xp = xp; } if (prev_noise && prev_noise->sfb_count1 > 0 && sfb >= prev_noise->sfb_count1 && prev_noise->step[sfb] > 0 && step >= prev_noise->step[sfb]) { if (accumulate) { quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData); accumulate = 0; acc_iData = iData; acc_xp = xp; } accumulate01 += l; } else { if (accumulate01) { quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData); accumulate01 = 0; acc_iData = iData; acc_xp = xp; } accumulate += l; } if (l <= 0) { /* rh: 20040215 * may happen due to "prev_data_use" optimization */ if (accumulate01) { quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData); accumulate01 = 0; } if (accumulate) { quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData); accumulate = 0; } break; /* ends for-loop */ } } if (sfb <= sfbmax) { iData += cod_info->width[sfb]; xp += cod_info->width[sfb]; j += cod_info->width[sfb]; } } if (accumulate) { /*last data part */ quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData); accumulate = 0; } if (accumulate01) { /*last data part */ quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData); accumulate01 = 0; } } /*************************************************************************/ /* ix_max */ /*************************************************************************/ static int ix_max(const int *ix, const int *end) { int max1 = 0, max2 = 0; do { int const x1 = *ix++; int const x2 = *ix++; if (max1 < x1) max1 = x1; if (max2 < x2) max2 = x2; } while (ix < end); if (max1 < max2) max1 = max2; return max1; } static int count_bit_ESC(const int *ix, const int *const end, int t1, const int t2, unsigned int *const s) { /* ESC-table is used */ unsigned int const linbits = ht[t1].xlen * 65536u + ht[t2].xlen; unsigned int sum = 0, sum2; do { unsigned int x = *ix++; unsigned int y = *ix++; if (x >= 15u) { x = 15u; sum += linbits; } if (y >= 15u) { y = 15u; sum += linbits; } x <<= 4u; x += y; sum += largetbl[x]; } while (ix < end); sum2 = sum & 0xffffu; sum >>= 16u; if (sum > sum2) { sum = sum2; t1 = t2; } *s += sum; return t1; } static int count_bit_noESC(const int *ix, const int *end, int mx, unsigned int *s) { /* No ESC-words */ unsigned int sum1 = 0; const uint8_t *const hlen1 = ht[1].hlen; (void) mx; do { unsigned int const x0 = *ix++; unsigned int const x1 = *ix++; sum1 += hlen1[ x0+x0 + x1 ]; } while (ix < end); *s += sum1; return 1; } static const int huf_tbl_noESC[] = { 1, 2, 5, 7, 7, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13 }; static int count_bit_noESC_from2(const int *ix, const int *end, int max, unsigned int *s) { int t1 = huf_tbl_noESC[max - 1]; /* No ESC-words */ const unsigned int xlen = ht[t1].xlen; uint32_t const* table = (t1 == 2) ? &table23[0] : &table56[0]; unsigned int sum = 0, sum2; do { unsigned int const x0 = *ix++; unsigned int const x1 = *ix++; sum += table[ x0 * xlen + x1 ]; } while (ix < end); sum2 = sum & 0xffffu; sum >>= 16u; if (sum > sum2) { sum = sum2; t1++; } *s += sum; return t1; } inline static int count_bit_noESC_from3(const int *ix, const int *end, int max, unsigned int * s) { int t1 = huf_tbl_noESC[max - 1]; /* No ESC-words */ unsigned int sum1 = 0; unsigned int sum2 = 0; unsigned int sum3 = 0; const unsigned int xlen = ht[t1].xlen; const uint8_t *const hlen1 = ht[t1].hlen; const uint8_t *const hlen2 = ht[t1 + 1].hlen; const uint8_t *const hlen3 = ht[t1 + 2].hlen; int t; do { unsigned int x0 = *ix++; unsigned int x1 = *ix++; unsigned int x = x0 * xlen + x1; sum1 += hlen1[x]; sum2 += hlen2[x]; sum3 += hlen3[x]; } while (ix < end); t = t1; if (sum1 > sum2) { sum1 = sum2; t++; } if (sum1 > sum3) { sum1 = sum3; t = t1 + 2; } *s += sum1; return t; } /*************************************************************************/ /* choose table */ /*************************************************************************/ /* Choose the Huffman table that will encode ix[begin..end] with the fewest bits. Note: This code contains knowledge about the sizes and characteristics of the Huffman tables as defined in the IS (Table B.7), and will not work with any arbitrary tables. */ static int count_bit_null(const int* ix, const int* end, int max, unsigned int* s) { (void) ix; (void) end; (void) max; (void) s; return 0; } typedef int (*count_fnc)(const int* ix, const int* end, int max, unsigned int* s); static count_fnc count_fncs[] = { &count_bit_null , &count_bit_noESC , &count_bit_noESC_from2 , &count_bit_noESC_from2 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 , &count_bit_noESC_from3 }; static int choose_table_nonMMX(const int *ix, const int *const end, int *const _s) { unsigned int* s = (unsigned int*)_s; unsigned int max; int choice, choice2; max = ix_max(ix, end); if (max <= 15) { return count_fncs[max](ix, end, max, s); } /* try tables with linbits */ if (max > IXMAX_VAL) { *s = LARGE_BITS; return -1; } max -= 15u; for (choice2 = 24; choice2 < 32; choice2++) { if (ht[choice2].linmax >= max) { break; } } for (choice = choice2 - 8; choice < 24; choice++) { if (ht[choice].linmax >= max) { break; } } return count_bit_ESC(ix, end, choice, choice2, s); } /*************************************************************************/ /* count_bit */ /*************************************************************************/ int noquant_count_bits(lame_internal_flags const *const gfc, gr_info * const gi, calc_noise_data * prev_noise) { SessionConfig_t const *const cfg = &gfc->cfg; int bits = 0; int i, a1, a2; int const *const ix = gi->l3_enc; i = Min(576, ((gi->max_nonzero_coeff + 2) >> 1) << 1); if (prev_noise) prev_noise->sfb_count1 = 0; /* Determine count1 region */ for (; i > 1; i -= 2) if (ix[i - 1] | ix[i - 2]) break; gi->count1 = i; /* Determines the number of bits to encode the quadruples. */ a1 = a2 = 0; for (; i > 3; i -= 4) { int x4 = ix[i-4]; int x3 = ix[i-3]; int x2 = ix[i-2]; int x1 = ix[i-1]; int p; /* hack to check if all values <= 1 */ if ((unsigned int) (x4 | x3 | x2 | x1) > 1) break; p = ((x4 * 2 + x3) * 2 + x2) * 2 + x1; a1 += t32l[p]; a2 += t33l[p]; } bits = a1; gi->count1table_select = 0; if (a1 > a2) { bits = a2; gi->count1table_select = 1; } gi->count1bits = bits; gi->big_values = i; if (i == 0) return bits; if (gi->block_type == SHORT_TYPE) { a1 = 3 * gfc->scalefac_band.s[3]; if (a1 > gi->big_values) a1 = gi->big_values; a2 = gi->big_values; } else if (gi->block_type == NORM_TYPE) { assert(i <= 576); /* bv_scf has 576 entries (0..575) */ a1 = gi->region0_count = gfc->sv_qnt.bv_scf[i - 2]; a2 = gi->region1_count = gfc->sv_qnt.bv_scf[i - 1]; assert(a1 + a2 + 2 < SBPSY_l); a2 = gfc->scalefac_band.l[a1 + a2 + 2]; a1 = gfc->scalefac_band.l[a1 + 1]; if (a2 < i) gi->table_select[2] = gfc->choose_table(ix + a2, ix + i, &bits); } else { gi->region0_count = 7; /*gi->region1_count = SBPSY_l - 7 - 1; */ gi->region1_count = SBMAX_l - 1 - 7 - 1; a1 = gfc->scalefac_band.l[7 + 1]; a2 = i; if (a1 > a2) { a1 = a2; } } /* have to allow for the case when bigvalues < region0 < region1 */ /* (and region0, region1 are ignored) */ a1 = Min(a1, i); a2 = Min(a2, i); assert(a1 >= 0); assert(a2 >= 0); /* Count the number of bits necessary to code the bigvalues region. */ if (0 < a1) gi->table_select[0] = gfc->choose_table(ix, ix + a1, &bits); if (a1 < a2) gi->table_select[1] = gfc->choose_table(ix + a1, ix + a2, &bits); if (cfg->use_best_huffman == 2) { gi->part2_3_length = bits; best_huffman_divide(gfc, gi); bits = gi->part2_3_length; } if (prev_noise) { if (gi->block_type == NORM_TYPE) { int sfb = 0; while (gfc->scalefac_band.l[sfb] < gi->big_values) { sfb++; } prev_noise->sfb_count1 = sfb; } } return bits; } int count_bits(lame_internal_flags const *const gfc, const FLOAT * const xr, gr_info * const gi, calc_noise_data * prev_noise) { int *const ix = gi->l3_enc; /* since quantize_xrpow uses table lookup, we need to check this first: */ FLOAT const w = (IXMAX_VAL) / IPOW20(gi->global_gain); if (gi->xrpow_max > w) return LARGE_BITS; quantize_xrpow(xr, ix, IPOW20(gi->global_gain), gi, prev_noise); if (gfc->sv_qnt.substep_shaping & 2) { int sfb, j = 0; /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */ int const gain = gi->global_gain + gi->scalefac_scale; const FLOAT roundfac = 0.634521682242439 / IPOW20(gain); for (sfb = 0; sfb < gi->sfbmax; sfb++) { int const width = gi->width[sfb]; assert(width >= 0); if (!gfc->sv_qnt.pseudohalf[sfb]) { j += width; } else { int k; for (k = j, j += width; k < j; ++k) { ix[k] = (xr[k] >= roundfac) ? ix[k] : 0; } } } } return noquant_count_bits(gfc, gi, prev_noise); } /*********************************************************************** re-calculate the best scalefac_compress using scfsi the saved bits are kept in the bit reservoir. **********************************************************************/ inline static void recalc_divide_init(const lame_internal_flags * const gfc, gr_info const *cod_info, int const *const ix, int r01_bits[], int r01_div[], int r0_tbl[], int r1_tbl[]) { int r0, r1, bigv, r0t, r1t, bits; bigv = cod_info->big_values; for (r0 = 0; r0 <= 7 + 15; r0++) { r01_bits[r0] = LARGE_BITS; } for (r0 = 0; r0 < 16; r0++) { int const a1 = gfc->scalefac_band.l[r0 + 1]; int r0bits; if (a1 >= bigv) break; r0bits = 0; r0t = gfc->choose_table(ix, ix + a1, &r0bits); for (r1 = 0; r1 < 8; r1++) { int const a2 = gfc->scalefac_band.l[r0 + r1 + 2]; if (a2 >= bigv) break; bits = r0bits; r1t = gfc->choose_table(ix + a1, ix + a2, &bits); if (r01_bits[r0 + r1] > bits) { r01_bits[r0 + r1] = bits; r01_div[r0 + r1] = r0; r0_tbl[r0 + r1] = r0t; r1_tbl[r0 + r1] = r1t; } } } } inline static void recalc_divide_sub(const lame_internal_flags * const gfc, const gr_info * cod_info2, gr_info * const gi, const int *const ix, const int r01_bits[], const int r01_div[], const int r0_tbl[], const int r1_tbl[]) { int bits, r2, a2, bigv, r2t; bigv = cod_info2->big_values; for (r2 = 2; r2 < SBMAX_l + 1; r2++) { a2 = gfc->scalefac_band.l[r2]; if (a2 >= bigv) break; bits = r01_bits[r2 - 2] + cod_info2->count1bits; if (gi->part2_3_length <= bits) break; r2t = gfc->choose_table(ix + a2, ix + bigv, &bits); if (gi->part2_3_length <= bits) continue; memcpy(gi, cod_info2, sizeof(gr_info)); gi->part2_3_length = bits; gi->region0_count = r01_div[r2 - 2]; gi->region1_count = r2 - 2 - r01_div[r2 - 2]; gi->table_select[0] = r0_tbl[r2 - 2]; gi->table_select[1] = r1_tbl[r2 - 2]; gi->table_select[2] = r2t; } } void best_huffman_divide(const lame_internal_flags * const gfc, gr_info * const gi) { SessionConfig_t const *const cfg = &gfc->cfg; int i, a1, a2; gr_info cod_info2; int const *const ix = gi->l3_enc; int r01_bits[7 + 15 + 1]; int r01_div[7 + 15 + 1]; int r0_tbl[7 + 15 + 1]; int r1_tbl[7 + 15 + 1]; /* SHORT BLOCK stuff fails for MPEG2 */ if (gi->block_type == SHORT_TYPE && cfg->mode_gr == 1) return; memcpy(&cod_info2, gi, sizeof(gr_info)); if (gi->block_type == NORM_TYPE) { recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); recalc_divide_sub(gfc, &cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); } i = cod_info2.big_values; if (i == 0 || (unsigned int) (ix[i - 2] | ix[i - 1]) > 1) return; i = gi->count1 + 2; if (i > 576) return; /* Determines the number of bits to encode the quadruples. */ memcpy(&cod_info2, gi, sizeof(gr_info)); cod_info2.count1 = i; a1 = a2 = 0; assert(i <= 576); for (; i > cod_info2.big_values; i -= 4) { int const p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1]; a1 += t32l[p]; a2 += t33l[p]; } cod_info2.big_values = i; cod_info2.count1table_select = 0; if (a1 > a2) { a1 = a2; cod_info2.count1table_select = 1; } cod_info2.count1bits = a1; if (cod_info2.block_type == NORM_TYPE) recalc_divide_sub(gfc, &cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); else { /* Count the number of bits necessary to code the bigvalues region. */ cod_info2.part2_3_length = a1; a1 = gfc->scalefac_band.l[7 + 1]; if (a1 > i) { a1 = i; } if (a1 > 0) cod_info2.table_select[0] = gfc->choose_table(ix, ix + a1, (int *) &cod_info2.part2_3_length); if (i > a1) cod_info2.table_select[1] = gfc->choose_table(ix + a1, ix + i, (int *) &cod_info2.part2_3_length); if (gi->part2_3_length > cod_info2.part2_3_length) memcpy(gi, &cod_info2, sizeof(gr_info)); } } static const int slen1_n[16] = { 1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16 }; static const int slen2_n[16] = { 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8 }; const int slen1_tab[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }; const int slen2_tab[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }; static void scfsi_calc(int ch, III_side_info_t * l3_side) { unsigned int i; int s1, s2, c1, c2; int sfb; gr_info *const gi = &l3_side->tt[1][ch]; gr_info const *const g0 = &l3_side->tt[0][ch]; for (i = 0; i < (sizeof(scfsi_band) / sizeof(int)) - 1; i++) { for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) { if (g0->scalefac[sfb] != gi->scalefac[sfb] && gi->scalefac[sfb] >= 0) break; } if (sfb == scfsi_band[i + 1]) { for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) { gi->scalefac[sfb] = -1; } l3_side->scfsi[ch][i] = 1; } } s1 = c1 = 0; for (sfb = 0; sfb < 11; sfb++) { if (gi->scalefac[sfb] == -1) continue; c1++; if (s1 < gi->scalefac[sfb]) s1 = gi->scalefac[sfb]; } s2 = c2 = 0; for (; sfb < SBPSY_l; sfb++) { if (gi->scalefac[sfb] == -1) continue; c2++; if (s2 < gi->scalefac[sfb]) s2 = gi->scalefac[sfb]; } for (i = 0; i < 16; i++) { if (s1 < slen1_n[i] && s2 < slen2_n[i]) { int const c = slen1_tab[i] * c1 + slen2_tab[i] * c2; if (gi->part2_length > c) { gi->part2_length = c; gi->scalefac_compress = (int)i; } } } } /* Find the optimal way to store the scalefactors. Only call this routine after final scalefactors have been chosen and the channel/granule will not be re-encoded. */ void best_scalefac_store(const lame_internal_flags * gfc, const int gr, const int ch, III_side_info_t * const l3_side) { SessionConfig_t const *const cfg = &gfc->cfg; /* use scalefac_scale if we can */ gr_info *const gi = &l3_side->tt[gr][ch]; int sfb, i, j, l; int recalc = 0; /* remove scalefacs from bands with ix=0. This idea comes * from the AAC ISO docs. added mt 3/00 */ /* check if l3_enc=0 */ j = 0; for (sfb = 0; sfb < gi->sfbmax; sfb++) { int const width = gi->width[sfb]; assert(width >= 0); for (l = j, j += width; l < j; ++l) { if (gi->l3_enc[l] != 0) break; } if (l == j) gi->scalefac[sfb] = recalc = -2; /* anything goes. */ /* only best_scalefac_store and calc_scfsi * know--and only they should know--about the magic number -2. */ } if (!gi->scalefac_scale && !gi->preflag) { int s = 0; for (sfb = 0; sfb < gi->sfbmax; sfb++) if (gi->scalefac[sfb] > 0) s |= gi->scalefac[sfb]; if (!(s & 1) && s != 0) { for (sfb = 0; sfb < gi->sfbmax; sfb++) if (gi->scalefac[sfb] > 0) gi->scalefac[sfb] >>= 1; gi->scalefac_scale = recalc = 1; } } if (!gi->preflag && gi->block_type != SHORT_TYPE && cfg->mode_gr == 2) { for (sfb = 11; sfb < SBPSY_l; sfb++) if (gi->scalefac[sfb] < pretab[sfb] && gi->scalefac[sfb] != -2) break; if (sfb == SBPSY_l) { for (sfb = 11; sfb < SBPSY_l; sfb++) if (gi->scalefac[sfb] > 0) gi->scalefac[sfb] -= pretab[sfb]; gi->preflag = recalc = 1; } } for (i = 0; i < 4; i++) l3_side->scfsi[ch][i] = 0; if (cfg->mode_gr == 2 && gr == 1 && l3_side->tt[0][ch].block_type != SHORT_TYPE && l3_side->tt[1][ch].block_type != SHORT_TYPE) { scfsi_calc(ch, l3_side); recalc = 0; } for (sfb = 0; sfb < gi->sfbmax; sfb++) { if (gi->scalefac[sfb] == -2) { gi->scalefac[sfb] = 0; /* if anything goes, then 0 is a good choice */ } } if (recalc) { (void) scale_bitcount(gfc, gi); } } #ifndef NDEBUG static int all_scalefactors_not_negative(int const *scalefac, int n) { int i; for (i = 0; i < n; ++i) { if (scalefac[i] < 0) return 0; } return 1; } #endif /* number of bits used to encode scalefacs */ /* 18*slen1_tab[i] + 18*slen2_tab[i] */ static const int scale_short[16] = { 0, 18, 36, 54, 54, 36, 54, 72, 54, 72, 90, 72, 90, 108, 108, 126 }; /* 17*slen1_tab[i] + 18*slen2_tab[i] */ static const int scale_mixed[16] = { 0, 18, 36, 54, 51, 35, 53, 71, 52, 70, 88, 69, 87, 105, 104, 122 }; /* 11*slen1_tab[i] + 10*slen2_tab[i] */ static const int scale_long[16] = { 0, 10, 20, 30, 33, 21, 31, 41, 32, 42, 52, 43, 53, 63, 64, 74 }; /*************************************************************************/ /* scale_bitcount */ /*************************************************************************/ /* Also calculates the number of bits necessary to code the scalefactors. */ static int mpeg1_scale_bitcount(const lame_internal_flags * gfc, gr_info * const cod_info) { int k, sfb, max_slen1 = 0, max_slen2 = 0; /* maximum values */ const int *tab; int *const scalefac = cod_info->scalefac; (void) gfc; assert(all_scalefactors_not_negative(scalefac, cod_info->sfbmax)); if (cod_info->block_type == SHORT_TYPE) { tab = scale_short; if (cod_info->mixed_block_flag) tab = scale_mixed; } else { /* block_type == 1,2,or 3 */ tab = scale_long; if (!cod_info->preflag) { for (sfb = 11; sfb < SBPSY_l; sfb++) if (scalefac[sfb] < pretab[sfb]) break; if (sfb == SBPSY_l) { cod_info->preflag = 1; for (sfb = 11; sfb < SBPSY_l; sfb++) scalefac[sfb] -= pretab[sfb]; } } } for (sfb = 0; sfb < cod_info->sfbdivide; sfb++) if (max_slen1 < scalefac[sfb]) max_slen1 = scalefac[sfb]; for (; sfb < cod_info->sfbmax; sfb++) if (max_slen2 < scalefac[sfb]) max_slen2 = scalefac[sfb]; /* from Takehiro TOMINAGA 10/99 * loop over *all* posible values of scalefac_compress to find the * one which uses the smallest number of bits. ISO would stop * at first valid index */ cod_info->part2_length = LARGE_BITS; for (k = 0; k < 16; k++) { if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k] && cod_info->part2_length > tab[k]) { cod_info->part2_length = tab[k]; cod_info->scalefac_compress = k; } } return cod_info->part2_length == LARGE_BITS; } /* table of largest scalefactor values for MPEG2 */ static const int max_range_sfac_tab[6][4] = { {15, 15, 7, 7}, {15, 15, 7, 0}, {7, 3, 0, 0}, {15, 31, 31, 0}, {7, 7, 7, 0}, {3, 3, 0, 0} }; /*************************************************************************/ /* scale_bitcount_lsf */ /*************************************************************************/ /* Also counts the number of bits to encode the scalefacs but for MPEG 2 */ /* Lower sampling frequencies (24, 22.05 and 16 kHz.) */ /* This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS, */ /* "Audio Decoding Layer III" */ static int mpeg2_scale_bitcount(const lame_internal_flags * gfc, gr_info * const cod_info) { int table_number, row_in_table, partition, nr_sfb, window, over; int i, sfb, max_sfac[4]; const int *partition_table; int const *const scalefac = cod_info->scalefac; /* Set partition table. Note that should try to use table one, but do not yet... */ if (cod_info->preflag) table_number = 2; else table_number = 0; for (i = 0; i < 4; i++) max_sfac[i] = 0; if (cod_info->block_type == SHORT_TYPE) { row_in_table = 1; partition_table = &nr_of_sfb_block[table_number][row_in_table][0]; for (sfb = 0, partition = 0; partition < 4; partition++) { nr_sfb = partition_table[partition] / 3; for (i = 0; i < nr_sfb; i++, sfb++) for (window = 0; window < 3; window++) if (scalefac[sfb * 3 + window] > max_sfac[partition]) max_sfac[partition] = scalefac[sfb * 3 + window]; } } else { row_in_table = 0; partition_table = &nr_of_sfb_block[table_number][row_in_table][0]; for (sfb = 0, partition = 0; partition < 4; partition++) { nr_sfb = partition_table[partition]; for (i = 0; i < nr_sfb; i++, sfb++) if (scalefac[sfb] > max_sfac[partition]) max_sfac[partition] = scalefac[sfb]; } } for (over = 0, partition = 0; partition < 4; partition++) { if (max_sfac[partition] > max_range_sfac_tab[table_number][partition]) over++; } if (!over) { /* Since no bands have been over-amplified, we can set scalefac_compress and slen[] for the formatter */ static const int log2tab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; int slen1, slen2, slen3, slen4; cod_info->sfb_partition_table = nr_of_sfb_block[table_number][row_in_table]; for (partition = 0; partition < 4; partition++) cod_info->slen[partition] = log2tab[max_sfac[partition]]; /* set scalefac_compress */ slen1 = cod_info->slen[0]; slen2 = cod_info->slen[1]; slen3 = cod_info->slen[2]; slen4 = cod_info->slen[3]; switch (table_number) { case 0: cod_info->scalefac_compress = (((slen1 * 5) + slen2) << 4) + (slen3 << 2) + slen4; break; case 1: cod_info->scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2) + slen3; break; case 2: cod_info->scalefac_compress = 500 + (slen1 * 3) + slen2; break; default: ERRORF(gfc, "intensity stereo not implemented yet\n"); break; } } #ifdef DEBUG if (over) ERRORF(gfc, "---WARNING !! Amplification of some bands over limits\n"); #endif if (!over) { assert(cod_info->sfb_partition_table); cod_info->part2_length = 0; for (partition = 0; partition < 4; partition++) cod_info->part2_length += cod_info->slen[partition] * cod_info->sfb_partition_table[partition]; } return over; } int scale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info) { if (gfc->cfg.mode_gr == 2) { return mpeg1_scale_bitcount(gfc, cod_info); } else { return mpeg2_scale_bitcount(gfc, cod_info); } } #ifdef MMX_choose_table extern int choose_table_MMX(const int *ix, const int *const end, int *const s); #endif void huffman_init(lame_internal_flags * const gfc) { int i; gfc->choose_table = choose_table_nonMMX; #ifdef MMX_choose_table if (gfc->CPU_features.MMX) { gfc->choose_table = choose_table_MMX; } #endif for (i = 2; i <= 576; i += 2) { int scfb_anz = 0, bv_index; while (gfc->scalefac_band.l[++scfb_anz] < i); bv_index = subdv_table[scfb_anz].region0_count; while (gfc->scalefac_band.l[bv_index + 1] > i) bv_index--; if (bv_index < 0) { /* this is an indication that everything is going to be encoded as region0: bigvalues < region0 < region1 so lets set region0, region1 to some value larger than bigvalues */ bv_index = subdv_table[scfb_anz].region0_count; } gfc->sv_qnt.bv_scf[i - 2] = bv_index; bv_index = subdv_table[scfb_anz].region1_count; while (gfc->scalefac_band.l[bv_index + gfc->sv_qnt.bv_scf[i - 2] + 2] > i) bv_index--; if (bv_index < 0) { bv_index = subdv_table[scfb_anz].region1_count; } gfc->sv_qnt.bv_scf[i - 1] = bv_index; } } ================================================ FILE: app/jni/libmp3lame/util.c ================================================ /* * lame utility library source file * * Copyright (c) 1999 Albert L Faber * Copyright (c) 2000-2005 Alexander Leidinger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: util.c,v 1.154.2.1 2012/01/08 23:49:58 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "tables.h" #define PRECOMPUTE #if defined(__FreeBSD__) && !defined(__alpha__) # include #endif /*********************************************************************** * * Global Function Definitions * ***********************************************************************/ /*empty and close mallocs in gfc */ void free_id3tag(lame_internal_flags * const gfc) { if (gfc->tag_spec.title != 0) { free(gfc->tag_spec.title); gfc->tag_spec.title = 0; } if (gfc->tag_spec.artist != 0) { free(gfc->tag_spec.artist); gfc->tag_spec.artist = 0; } if (gfc->tag_spec.album != 0) { free(gfc->tag_spec.album); gfc->tag_spec.album = 0; } if (gfc->tag_spec.comment != 0) { free(gfc->tag_spec.comment); gfc->tag_spec.comment = 0; } if (gfc->tag_spec.albumart != 0) { free(gfc->tag_spec.albumart); gfc->tag_spec.albumart = 0; gfc->tag_spec.albumart_size = 0; gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE; } if (gfc->tag_spec.v2_head != 0) { FrameDataNode *node = gfc->tag_spec.v2_head; do { void *p = node->dsc.ptr.b; void *q = node->txt.ptr.b; void *r = node; node = node->nxt; free(p); free(q); free(r); } while (node != 0); gfc->tag_spec.v2_head = 0; gfc->tag_spec.v2_tail = 0; } } static void free_global_data(lame_internal_flags * gfc) { if (gfc && gfc->cd_psy) { if (gfc->cd_psy->l.s3) { /* XXX allocated in psymodel_init() */ free(gfc->cd_psy->l.s3); } if (gfc->cd_psy->s.s3) { /* XXX allocated in psymodel_init() */ free(gfc->cd_psy->s.s3); } free(gfc->cd_psy); gfc->cd_psy = 0; } } void freegfc(lame_internal_flags * const gfc) { /* bit stream structure */ int i; for (i = 0; i <= 2 * BPC; i++) if (gfc->sv_enc.blackfilt[i] != NULL) { free(gfc->sv_enc.blackfilt[i]); gfc->sv_enc.blackfilt[i] = NULL; } if (gfc->sv_enc.inbuf_old[0]) { free(gfc->sv_enc.inbuf_old[0]); gfc->sv_enc.inbuf_old[0] = NULL; } if (gfc->sv_enc.inbuf_old[1]) { free(gfc->sv_enc.inbuf_old[1]); gfc->sv_enc.inbuf_old[1] = NULL; } if (gfc->bs.buf != NULL) { free(gfc->bs.buf); gfc->bs.buf = NULL; } if (gfc->VBR_seek_table.bag) { free(gfc->VBR_seek_table.bag); gfc->VBR_seek_table.bag = NULL; gfc->VBR_seek_table.size = 0; } if (gfc->ATH) { free(gfc->ATH); } if (gfc->sv_rpg.rgdata) { free(gfc->sv_rpg.rgdata); } if (gfc->sv_enc.in_buffer_0) { free(gfc->sv_enc.in_buffer_0); } if (gfc->sv_enc.in_buffer_1) { free(gfc->sv_enc.in_buffer_1); } free_id3tag(gfc); #ifdef DECODE_ON_THE_FLY if (gfc->hip) { hip_decode_exit(gfc->hip); gfc->hip = 0; } #endif free_global_data(gfc); free(gfc); } void malloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes) { if (ptr) { if (!ptr->pointer) { ptr->pointer = malloc(size + bytes); if (bytes > 0) { ptr->aligned = (void *) ((((size_t) ptr->pointer + bytes - 1) / bytes) * bytes); } else { ptr->aligned = ptr->pointer; } } } } void free_aligned(aligned_pointer_t * ptr) { if (ptr) { if (ptr->pointer) { free(ptr->pointer); ptr->pointer = 0; ptr->aligned = 0; } } } /*those ATH formulas are returning their minimum value for input = -1*/ static FLOAT ATHformula_GB(FLOAT f, FLOAT value, FLOAT f_min, FLOAT f_max) { /* from Painter & Spanias modified by Gabriel Bouvigne to better fit the reality ath = 3.640 * pow(f,-0.8) - 6.800 * exp(-0.6*pow(f-3.4,2.0)) + 6.000 * exp(-0.15*pow(f-8.7,2.0)) + 0.6* 0.001 * pow(f,4.0); In the past LAME was using the Painter &Spanias formula. But we had some recurrent problems with HF content. We measured real ATH values, and found the older formula to be inacurate in the higher part. So we made this new formula and this solved most of HF problematic testcases. The tradeoff is that in VBR mode it increases a lot the bitrate. */ /*this curve can be udjusted according to the VBR scale: it adjusts from something close to Painter & Spanias on V9 up to Bouvigne's formula for V0. This way the VBR bitrate is more balanced according to the -V value.*/ FLOAT ath; /* the following Hack allows to ask for the lowest value */ if (f < -.3) f = 3410; f /= 1000; /* convert to khz */ f = Max(f_min, f); f = Min(f_max, f); ath = 3.640 * pow(f, -0.8) - 6.800 * exp(-0.6 * pow(f - 3.4, 2.0)) + 6.000 * exp(-0.15 * pow(f - 8.7, 2.0)) + (0.6 + 0.04 * value) * 0.001 * pow(f, 4.0); return ath; } FLOAT ATHformula(SessionConfig_t const *cfg, FLOAT f) { FLOAT ath; switch (cfg->ATHtype) { case 0: ath = ATHformula_GB(f, 9, 0.1f, 24.0f); break; case 1: ath = ATHformula_GB(f, -1, 0.1f, 24.0f); /*over sensitive, should probably be removed */ break; case 2: ath = ATHformula_GB(f, 0, 0.1f, 24.0f); break; case 3: ath = ATHformula_GB(f, 1, 0.1f, 24.0f) + 6; /*modification of GB formula by Roel */ break; case 4: ath = ATHformula_GB(f, cfg->ATHcurve, 0.1f, 24.0f); break; case 5: ath = ATHformula_GB(f, cfg->ATHcurve, 3.41f, 16.1f); break; default: ath = ATHformula_GB(f, 0, 0.1f, 24.0f); break; } return ath; } /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */ FLOAT freq2bark(FLOAT freq) { /* input: freq in hz output: barks */ if (freq < 0) freq = 0; freq = freq * 0.001; return 13.0 * atan(.76 * freq) + 3.5 * atan(freq * freq / (7.5 * 7.5)); } #if 0 extern FLOAT freq2cbw(FLOAT freq); /* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */ FLOAT freq2cbw(FLOAT freq) { /* input: freq in hz output: critical band width */ freq = freq * 0.001; return 25 + 75 * pow(1 + 1.4 * (freq * freq), 0.69); } #endif #define ABS(A) (((A)>0) ? (A) : -(A)) int FindNearestBitrate(int bRate, /* legal rates from 8 to 320 */ int version, int samplerate) { /* MPEG-1 or MPEG-2 LSF */ int bitrate; int i; if (samplerate < 16000) version = 2; bitrate = bitrate_table[version][1]; for (i = 2; i <= 14; i++) { if (bitrate_table[version][i] > 0) { if (ABS(bitrate_table[version][i] - bRate) < ABS(bitrate - bRate)) bitrate = bitrate_table[version][i]; } } return bitrate; } #ifndef Min #define Min(A, B) ((A) < (B) ? (A) : (B)) #endif #ifndef Max #define Max(A, B) ((A) > (B) ? (A) : (B)) #endif /* Used to find table index when * we need bitrate-based values * determined using tables * * bitrate in kbps * * Gabriel Bouvigne 2002-11-03 */ int nearestBitrateFullIndex(uint16_t bitrate) { /* borrowed from DM abr presets */ const int full_bitrate_table[] = { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }; int lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0; int b; /* We assume specified bitrate will be 320kbps */ upper_range_kbps = full_bitrate_table[16]; upper_range = 16; lower_range_kbps = full_bitrate_table[16]; lower_range = 16; /* Determine which significant bitrates the value specified falls between, * if loop ends without breaking then we were correct above that the value was 320 */ for (b = 0; b < 16; b++) { if ((Max(bitrate, full_bitrate_table[b + 1])) != bitrate) { upper_range_kbps = full_bitrate_table[b + 1]; upper_range = b + 1; lower_range_kbps = full_bitrate_table[b]; lower_range = (b); break; /* We found upper range */ } } /* Determine which range the value specified is closer to */ if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) { return lower_range; } return upper_range; } /* map frequency to a valid MP3 sample frequency * * Robert Hegemann 2000-07-01 */ int map2MP3Frequency(int freq) { if (freq <= 8000) return 8000; if (freq <= 11025) return 11025; if (freq <= 12000) return 12000; if (freq <= 16000) return 16000; if (freq <= 22050) return 22050; if (freq <= 24000) return 24000; if (freq <= 32000) return 32000; if (freq <= 44100) return 44100; return 48000; } int BitrateIndex(int bRate, /* legal rates from 32 to 448 kbps */ int version, /* MPEG-1 or MPEG-2/2.5 LSF */ int samplerate) { /* convert bitrate in kbps to index */ int i; if (samplerate < 16000) version = 2; for (i = 0; i <= 14; i++) { if (bitrate_table[version][i] > 0) { if (bitrate_table[version][i] == bRate) { return i; } } } return -1; } /* convert samp freq in Hz to index */ int SmpFrqIndex(int sample_freq, int *const version) { switch (sample_freq) { case 44100: *version = 1; return 0; case 48000: *version = 1; return 1; case 32000: *version = 1; return 2; case 22050: *version = 0; return 0; case 24000: *version = 0; return 1; case 16000: *version = 0; return 2; case 11025: *version = 0; return 0; case 12000: *version = 0; return 1; case 8000: *version = 0; return 2; default: *version = 0; return -1; } } /***************************************************************************** * * End of bit_stream.c package * *****************************************************************************/ /* resampling via FIR filter, blackman window */ inline static FLOAT blackman(FLOAT x, FLOAT fcn, int l) { /* This algorithm from: SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C S.D. Stearns and R.A. David, Prentice-Hall, 1992 */ FLOAT bkwn, x2; FLOAT const wcn = (PI * fcn); x /= l; if (x < 0) x = 0; if (x > 1) x = 1; x2 = x - .5; bkwn = 0.42 - 0.5 * cos(2 * x * PI) + 0.08 * cos(4 * x * PI); if (fabs(x2) < 1e-9) return wcn / PI; else return (bkwn * sin(l * wcn * x2) / (PI * l * x2)); } /* gcd - greatest common divisor */ /* Joint work of Euclid and M. Hendry */ static int gcd(int i, int j) { /* assert ( i > 0 && j > 0 ); */ return j ? gcd(j, i % j) : i; } static int fill_buffer_resample(lame_internal_flags * gfc, sample_t * outbuf, int desired_len, sample_t const *inbuf, int len, int *num_used, int ch) { SessionConfig_t const *const cfg = &gfc->cfg; EncStateVar_t *esv = &gfc->sv_enc; double resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out; int BLACKSIZE; FLOAT offset, xvalue; int i, j = 0, k; int filter_l; FLOAT fcn, intratio; FLOAT *inbuf_old; int bpc; /* number of convolution functions to pre-compute */ bpc = cfg->samplerate_out / gcd(cfg->samplerate_out, cfg->samplerate_in); if (bpc > BPC) bpc = BPC; intratio = (fabs(resample_ratio - floor(.5 + resample_ratio)) < .0001); fcn = 1.00 / resample_ratio; if (fcn > 1.00) fcn = 1.00; filter_l = 31; /* must be odd */ filter_l += intratio; /* unless resample_ratio=int, it must be even */ BLACKSIZE = filter_l + 1; /* size of data needed for FIR */ if (gfc->fill_buffer_resample_init == 0) { esv->inbuf_old[0] = calloc(BLACKSIZE, sizeof(esv->inbuf_old[0][0])); esv->inbuf_old[1] = calloc(BLACKSIZE, sizeof(esv->inbuf_old[0][0])); for (i = 0; i <= 2 * bpc; ++i) esv->blackfilt[i] = calloc(BLACKSIZE, sizeof(esv->blackfilt[0][0])); esv->itime[0] = 0; esv->itime[1] = 0; /* precompute blackman filter coefficients */ for (j = 0; j <= 2 * bpc; j++) { FLOAT sum = 0.; offset = (j - bpc) / (2. * bpc); for (i = 0; i <= filter_l; i++) sum += esv->blackfilt[j][i] = blackman(i - offset, fcn, filter_l); for (i = 0; i <= filter_l; i++) esv->blackfilt[j][i] /= sum; } gfc->fill_buffer_resample_init = 1; } inbuf_old = esv->inbuf_old[ch]; /* time of j'th element in inbuf = itime + j/ifreq; */ /* time of k'th element in outbuf = j/ofreq */ for (k = 0; k < desired_len; k++) { double time0 = k * resample_ratio; /* time of k'th output sample */ int joff; j = floor(time0 - esv->itime[ch]); /* check if we need more input data */ if ((filter_l + j - filter_l / 2) >= len) break; /* blackman filter. by default, window centered at j+.5(filter_l%2) */ /* but we want a window centered at time0. */ offset = (time0 - esv->itime[ch] - (j + .5 * (filter_l % 2))); assert(fabs(offset) <= .501); /* find the closest precomputed window for this offset: */ joff = floor((offset * 2 * bpc) + bpc + .5); xvalue = 0.; for (i = 0; i <= filter_l; ++i) { int const j2 = i + j - filter_l / 2; sample_t y; assert(j2 < len); assert(j2 + BLACKSIZE >= 0); y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[j2]; #ifdef PRECOMPUTE xvalue += y * esv->blackfilt[joff][i]; #else xvalue += y * blackman(i - offset, fcn, filter_l); /* very slow! */ #endif } outbuf[k] = xvalue; } /* k = number of samples added to outbuf */ /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2] */ /* how many samples of input data were used: */ *num_used = Min(len, filter_l + j - filter_l / 2); /* adjust our input time counter. Incriment by the number of samples used, * then normalize so that next output sample is at time 0, next * input buffer is at time itime[ch] */ esv->itime[ch] += *num_used - k * resample_ratio; /* save the last BLACKSIZE samples into the inbuf_old buffer */ if (*num_used >= BLACKSIZE) { for (i = 0; i < BLACKSIZE; i++) inbuf_old[i] = inbuf[*num_used + i - BLACKSIZE]; } else { /* shift in *num_used samples into inbuf_old */ int const n_shift = BLACKSIZE - *num_used; /* number of samples to shift */ /* shift n_shift samples by *num_used, to make room for the * num_used new samples */ for (i = 0; i < n_shift; ++i) inbuf_old[i] = inbuf_old[i + *num_used]; /* shift in the *num_used samples */ for (j = 0; i < BLACKSIZE; ++i, ++j) inbuf_old[i] = inbuf[j]; assert(j == *num_used); } return k; /* return the number samples created at the new samplerate */ } int isResamplingNecessary(SessionConfig_t const* cfg) { int const l = cfg->samplerate_out * 0.9995f; int const h = cfg->samplerate_out * 1.0005f; return (cfg->samplerate_in < l) || (h < cfg->samplerate_in) ? 1 : 0; } /* copy in new samples from in_buffer into mfbuf, with resampling if necessary. n_in = number of samples from the input buffer that were used. n_out = number of samples copied into mfbuf */ void fill_buffer(lame_internal_flags * gfc, sample_t * const mfbuf[2], sample_t const * const in_buffer[2], int nsamples, int *n_in, int *n_out) { SessionConfig_t const *const cfg = &gfc->cfg; int mf_size = gfc->sv_enc.mf_size; int framesize = 576 * cfg->mode_gr; int nout, ch = 0; int nch = cfg->channels_out; /* copy in new samples into mfbuf, with resampling if necessary */ if (isResamplingNecessary(cfg)) { do { nout = fill_buffer_resample(gfc, &mfbuf[ch][mf_size], framesize, in_buffer[ch], nsamples, n_in, ch); } while (++ch < nch); *n_out = nout; } else { nout = Min(framesize, nsamples); do { memcpy(&mfbuf[ch][mf_size], &in_buffer[ch][0], nout * sizeof(mfbuf[0][0])); } while (++ch < nch); *n_out = nout; *n_in = nout; } } /*********************************************************************** * * Message Output * ***********************************************************************/ void lame_report_def(const char *format, va_list args) { (void) vfprintf(stderr, format, args); fflush(stderr); /* an debug function should flush immediately */ } void lame_report_fnc(lame_report_function print_f, const char *format, ...) { if (print_f) { va_list args; va_start(args, format); print_f(format, args); va_end(args); } } void lame_debugf(const lame_internal_flags* gfc, const char *format, ...) { if (gfc && gfc->report_dbg) { va_list args; va_start(args, format); gfc->report_dbg(format, args); va_end(args); } } void lame_msgf(const lame_internal_flags* gfc, const char *format, ...) { if (gfc && gfc->report_msg) { va_list args; va_start(args, format); gfc->report_msg(format, args); va_end(args); } } void lame_errorf(const lame_internal_flags* gfc, const char *format, ...) { if (gfc && gfc->report_err) { va_list args; va_start(args, format); gfc->report_err(format, args); va_end(args); } } /*********************************************************************** * * routines to detect CPU specific features like 3DNow, MMX, SSE * * donated by Frank Klemm * added Robert Hegemann 2000-10-10 * ***********************************************************************/ #ifdef HAVE_NASM extern int has_MMX_nasm(void); extern int has_3DNow_nasm(void); extern int has_SSE_nasm(void); extern int has_SSE2_nasm(void); #endif int has_MMX(void) { #ifdef HAVE_NASM return has_MMX_nasm(); #else return 0; /* don't know, assume not */ #endif } int has_3DNow(void) { #ifdef HAVE_NASM return has_3DNow_nasm(); #else return 0; /* don't know, assume not */ #endif } int has_SSE(void) { #ifdef HAVE_NASM return has_SSE_nasm(); #else #if defined( _M_X64 ) || defined( MIN_ARCH_SSE ) return 1; #else return 0; /* don't know, assume not */ #endif #endif } int has_SSE2(void) { #ifdef HAVE_NASM return has_SSE2_nasm(); #else #if defined( _M_X64 ) || defined( MIN_ARCH_SSE ) return 1; #else return 0; /* don't know, assume not */ #endif #endif } void disable_FPE(void) { /* extremly system dependent stuff, move to a lib to make the code readable */ /*==========================================================================*/ /* * Disable floating point exceptions */ #if defined(__FreeBSD__) && !defined(__alpha__) { /* seet floating point mask to the Linux default */ fp_except_t mask; mask = fpgetmask(); /* if bit is set, we get SIGFPE on that error! */ fpsetmask(mask & ~(FP_X_INV | FP_X_DZ)); /* DEBUGF("FreeBSD mask is 0x%x\n",mask); */ } #endif #if defined(__riscos__) && !defined(ABORTFP) /* Disable FPE's under RISC OS */ /* if bit is set, we disable trapping that error! */ /* _FPE_IVO : invalid operation */ /* _FPE_DVZ : divide by zero */ /* _FPE_OFL : overflow */ /* _FPE_UFL : underflow */ /* _FPE_INX : inexact */ DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL); #endif /* * Debugging stuff * The default is to ignore FPE's, unless compiled with -DABORTFP * so add code below to ENABLE FPE's. */ #if defined(ABORTFP) #if defined(_MSC_VER) { #if 0 /* rh 061207 the following fix seems to be a workaround for a problem in the parent process calling LAME. It would be better to fix the broken application => code disabled. */ /* set affinity to a single CPU. Fix for EAC/lame on SMP systems from "Todd Richmond" */ SYSTEM_INFO si; GetSystemInfo(&si); SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask); #endif #include unsigned int mask; mask = _controlfp(0, 0); mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID); mask = _controlfp(mask, _MCW_EM); } #elif defined(__CYGWIN__) # define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw)) # define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw)) # define _EM_INEXACT 0x00000020 /* inexact (precision) */ # define _EM_UNDERFLOW 0x00000010 /* underflow */ # define _EM_OVERFLOW 0x00000008 /* overflow */ # define _EM_ZERODIVIDE 0x00000004 /* zero divide */ # define _EM_INVALID 0x00000001 /* invalid */ { unsigned int mask; _FPU_GETCW(mask); /* Set the FPU control word to abort on most FPEs */ mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID); _FPU_SETCW(mask); } # elif defined(__linux__) { # include # ifndef _FPU_GETCW # define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw)) # endif # ifndef _FPU_SETCW # define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw)) # endif /* * Set the Linux mask to abort on most FPE's * if bit is set, we _mask_ SIGFPE on that error! * mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM ); */ unsigned int mask; _FPU_GETCW(mask); mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM); _FPU_SETCW(mask); } #endif #endif /* ABORTFP */ } #ifdef USE_FAST_LOG /*********************************************************************** * * Fast Log Approximation for log2, used to approximate every other log * (log10 and log) * maximum absolute error for log10 is around 10-6 * maximum *relative* error can be high when x is almost 1 because error/log10(x) tends toward x/e * * use it if typical RESULT values are > 1e-5 (for example if x>1.00001 or x<0.99999) * or if the relative precision in the domain around 1 is not important (result in 1 is exact and 0) * ***********************************************************************/ #define LOG2_SIZE (512) #define LOG2_SIZE_L2 (9) static ieee754_float32_t log_table[LOG2_SIZE + 1]; void init_log_table(void) { int j; static int init = 0; /* Range for log2(x) over [1,2[ is [0,1[ */ assert((1 << LOG2_SIZE_L2) == LOG2_SIZE); if (!init) { for (j = 0; j < LOG2_SIZE + 1; j++) log_table[j] = log(1.0f + j / (ieee754_float32_t) LOG2_SIZE) / log(2.0f); } init = 1; } ieee754_float32_t fast_log2(ieee754_float32_t x) { ieee754_float32_t log2val, partial; union { ieee754_float32_t f; int i; } fi; int mantisse; fi.f = x; mantisse = fi.i & 0x7fffff; log2val = ((fi.i >> 23) & 0xFF) - 0x7f; partial = (mantisse & ((1 << (23 - LOG2_SIZE_L2)) - 1)); partial *= 1.0f / ((1 << (23 - LOG2_SIZE_L2))); mantisse >>= (23 - LOG2_SIZE_L2); /* log2val += log_table[mantisse]; without interpolation the results are not good */ log2val += log_table[mantisse] * (1.0f - partial) + log_table[mantisse + 1] * partial; return log2val; } #else /* Don't use FAST_LOG */ void init_log_table(void) { } #endif /* end of util.c */ ================================================ FILE: app/jni/libmp3lame/util.h ================================================ /* * lame utility library include file * * Copyright (c) 1999 Albert L Faber * Copyright (c) 2008 Robert Hegemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_UTIL_H #define LAME_UTIL_H #include "l3side.h" #include "id3tag.h" #include "lame_global_flags.h" #ifdef __cplusplus extern "C" { #endif /*********************************************************************** * * Global Definitions * ***********************************************************************/ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE (!FALSE) #endif #ifdef UINT_MAX # define MAX_U_32_NUM UINT_MAX #else # define MAX_U_32_NUM 0xFFFFFFFF #endif #ifndef PI # ifdef M_PI # define PI M_PI # else # define PI 3.14159265358979323846 # endif #endif #ifdef M_LN2 # define LOG2 M_LN2 #else # define LOG2 0.69314718055994530942 #endif #ifdef M_LN10 # define LOG10 M_LN10 #else # define LOG10 2.30258509299404568402 #endif #ifdef M_SQRT2 # define SQRT2 M_SQRT2 #else # define SQRT2 1.41421356237309504880 #endif #define CRC16_POLYNOMIAL 0x8005 #define MAX_BITS_PER_CHANNEL 4095 #define MAX_BITS_PER_GRANULE 7680 /* "bit_stream.h" Definitions */ #define BUFFER_SIZE LAME_MAXMP3BUFFER #define Min(A, B) ((A) < (B) ? (A) : (B)) #define Max(A, B) ((A) > (B) ? (A) : (B)) /* log/log10 approximations */ #ifdef USE_FAST_LOG #define FAST_LOG10(x) (fast_log2(x)*(LOG2/LOG10)) #define FAST_LOG(x) (fast_log2(x)*LOG2) #define FAST_LOG10_X(x,y) (fast_log2(x)*(LOG2/LOG10*(y))) #define FAST_LOG_X(x,y) (fast_log2(x)*(LOG2*(y))) #else #define FAST_LOG10(x) log10(x) #define FAST_LOG(x) log(x) #define FAST_LOG10_X(x,y) (log10(x)*(y)) #define FAST_LOG_X(x,y) (log(x)*(y)) #endif struct replaygain_data; #ifndef replaygain_data_defined #define replaygain_data_defined typedef struct replaygain_data replaygain_t; #endif struct plotting_data; #ifndef plotting_data_defined #define plotting_data_defined typedef struct plotting_data plotting_data; #endif /*********************************************************************** * * Global Type Definitions * ***********************************************************************/ typedef struct { void *aligned; /* pointer to ie. 128 bit aligned memory */ void *pointer; /* to use with malloc/free */ } aligned_pointer_t; void malloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes); void free_aligned(aligned_pointer_t * ptr); typedef void (*iteration_loop_t) (lame_internal_flags * gfc, const FLOAT pe[2][2], const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); /* "bit_stream.h" Type Definitions */ typedef struct bit_stream_struc { unsigned char *buf; /* bit stream buffer */ int buf_size; /* size of buffer (in number of bytes) */ int totbit; /* bit counter of bit stream */ int buf_byte_idx; /* pointer to top byte in buffer */ int buf_bit_idx; /* pointer to top bit of top byte in buffer */ /* format of file in rd mode (BINARY/ASCII) */ } Bit_stream_struc; typedef struct { int sum; /* what we have seen so far */ int seen; /* how many frames we have seen in this chunk */ int want; /* how many frames we want to collect into one chunk */ int pos; /* actual position in our bag */ int size; /* size of our bag */ int *bag; /* pointer to our bag */ unsigned int nVbrNumFrames; unsigned long nBytesWritten; /* VBR tag data */ unsigned int TotalFrameSize; } VBR_seek_info_t; /** * ATH related stuff, if something new ATH related has to be added, * please plugg it here into the ATH_t struct */ typedef struct { int use_adjust; /* method for the auto adjustment */ FLOAT aa_sensitivity_p; /* factor for tuning the (sample power) point below which adaptive threshold of hearing adjustment occurs */ FLOAT adjust_factor; /* lowering based on peak volume, 1 = no lowering */ FLOAT adjust_limit; /* limit for dynamic ATH adjust */ FLOAT decay; /* determined to lower x dB each second */ FLOAT floor; /* lowest ATH value */ FLOAT l[SBMAX_l]; /* ATH for sfbs in long blocks */ FLOAT s[SBMAX_s]; /* ATH for sfbs in short blocks */ FLOAT psfb21[PSFB21]; /* ATH for partitionned sfb21 in long blocks */ FLOAT psfb12[PSFB12]; /* ATH for partitionned sfb12 in short blocks */ FLOAT cb_l[CBANDS]; /* ATH for long block convolution bands */ FLOAT cb_s[CBANDS]; /* ATH for short block convolution bands */ FLOAT eql_w[BLKSIZE / 2]; /* equal loudness weights (based on ATH) */ } ATH_t; /** * PSY Model related stuff */ typedef struct { FLOAT masking_lower[CBANDS]; FLOAT minval[CBANDS]; FLOAT rnumlines[CBANDS]; FLOAT mld_cb[CBANDS]; FLOAT mld[Max(SBMAX_l,SBMAX_s)]; FLOAT bo_weight[Max(SBMAX_l,SBMAX_s)]; /* band weight long scalefactor bands, at transition */ FLOAT attack_threshold; /* short block tuning */ int s3ind[CBANDS][2]; int numlines[CBANDS]; int bm[Max(SBMAX_l,SBMAX_s)]; int bo[Max(SBMAX_l,SBMAX_s)]; int npart; int n_sb; /* SBMAX_l or SBMAX_s */ FLOAT *s3; } PsyConst_CB2SB_t; /** * global data constants */ typedef struct { PsyConst_CB2SB_t l; PsyConst_CB2SB_t s; PsyConst_CB2SB_t l_to_s; FLOAT attack_threshold[4]; FLOAT decay; int force_short_block_calc; } PsyConst_t; typedef struct { FLOAT nb_l1[4][CBANDS], nb_l2[4][CBANDS]; FLOAT nb_s1[4][CBANDS], nb_s2[4][CBANDS]; III_psy_xmin thm[4]; III_psy_xmin en[4]; /* loudness calculation (for adaptive threshold of hearing) */ FLOAT loudness_sq_save[2]; /* account for granule delay of L3psycho_anal */ FLOAT tot_ener[4]; FLOAT last_en_subshort[4][9]; int last_attacks[4]; int blocktype_old[2]; } PsyStateVar_t; typedef struct { /* loudness calculation (for adaptive threshold of hearing) */ FLOAT loudness_sq[2][2]; /* loudness^2 approx. per granule and channel */ } PsyResult_t; /* variables used by encoder.c */ typedef struct { /* variables for newmdct.c */ FLOAT sb_sample[2][2][18][SBLIMIT]; FLOAT amp_filter[32]; /* variables used by util.c */ /* BPC = maximum number of filter convolution windows to precompute */ #define BPC 320 double itime[2]; /* float precision seems to be not enough */ sample_t *inbuf_old[2]; sample_t *blackfilt[2 * BPC + 1]; FLOAT pefirbuf[19]; /* used for padding */ int frac_SpF; int slot_lag; /* variables for bitstream.c */ /* mpeg1: buffer=511 bytes smallest frame: 96-38(sideinfo)=58 * max number of frames in reservoir: 8 * mpeg2: buffer=255 bytes. smallest frame: 24-23bytes=1 * with VBR, if you are encoding all silence, it is possible to * have 8kbs/24khz frames with 1byte of data each, which means we need * to buffer up to 255 headers! */ /* also, max_header_buf has to be a power of two */ #define MAX_HEADER_BUF 256 #define MAX_HEADER_LEN 40 /* max size of header is 38 */ struct { int write_timing; int ptr; char buf[MAX_HEADER_LEN]; } header[MAX_HEADER_BUF]; int h_ptr; int w_ptr; int ancillary_flag; /* variables for reservoir.c */ int ResvSize; /* in bits */ int ResvMax; /* in bits */ int in_buffer_nsamples; sample_t *in_buffer_0; sample_t *in_buffer_1; #ifndef MFSIZE # define MFSIZE ( 3*1152 + ENCDELAY - MDCTDELAY ) #endif sample_t mfbuf[2][MFSIZE]; int mf_samples_to_encode; int mf_size; } EncStateVar_t; typedef struct { /* simple statistics */ int bitrate_channelmode_hist[16][4 + 1]; int bitrate_blocktype_hist[16][4 + 1 + 1]; /*norm/start/short/stop/mixed(short)/sum */ int bitrate_index; int frame_number; /* number of frames encoded */ int padding; /* padding for the current frame? */ int mode_ext; int encoder_delay; int encoder_padding; /* number of samples of padding appended to input */ } EncResult_t; /* variables used by quantize.c */ typedef struct { /* variables for nspsytune */ FLOAT longfact[SBMAX_l]; FLOAT shortfact[SBMAX_s]; FLOAT masking_lower; FLOAT mask_adjust; /* the dbQ stuff */ FLOAT mask_adjust_short; /* the dbQ stuff */ int OldValue[2]; int CurrentStep[2]; int pseudohalf[SFBMAX]; int sfb21_extra; /* will be set in lame_init_params */ int substep_shaping; /* 0 = no substep 1 = use substep shaping at last step(VBR only) (not implemented yet) 2 = use substep inside loop 3 = use substep inside loop and last step */ char bv_scf[576]; } QntStateVar_t; typedef struct { replaygain_t *rgdata; /* ReplayGain */ } RpgStateVar_t; typedef struct { FLOAT noclipScale; /* user-specified scale factor required for preventing clipping */ sample_t PeakSample; int RadioGain; int noclipGainChange; /* gain change required for preventing clipping */ } RpgResult_t; typedef struct { int version; /* 0=MPEG-2/2.5 1=MPEG-1 */ int samplerate_index; int sideinfo_len; int noise_shaping; /* 0 = none 1 = ISO AAC model 2 = allow scalefac_select=1 */ int subblock_gain; /* 0 = no, 1 = yes */ int use_best_huffman; /* 0 = no. 1=outside loop 2=inside loop(slow) */ int noise_shaping_amp; /* 0 = ISO model: amplify all distorted bands 1 = amplify within 50% of max (on db scale) 2 = amplify only most distorted band 3 = method 1 and refine with method 2 */ int noise_shaping_stop; /* 0 = stop at over=0, all scalefacs amplified or a scalefac has reached max value 1 = stop when all scalefacs amplified or a scalefac has reached max value 2 = stop when all scalefacs amplified */ int full_outer_loop; /* 0 = stop early after 0 distortion found. 1 = full search */ int lowpassfreq; int highpassfreq; int samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz */ int samplerate_out; /* output_samp_rate. */ int channels_in; /* number of channels in the input data stream (PCM or decoded PCM) */ int channels_out; /* number of channels in the output data stream (not used for decoding) */ int mode_gr; /* granules per frame */ int force_ms; /* force M/S mode. requires mode=1 */ int quant_comp; int quant_comp_short; int use_temporal_masking_effect; int use_safe_joint_stereo; int preset; vbr_mode vbr; int vbr_avg_bitrate_kbps; int vbr_min_bitrate_index; /* min bitrate index */ int vbr_max_bitrate_index; /* max bitrate index */ int avg_bitrate; int enforce_min_bitrate; /* strictly enforce VBR_min_bitrate normaly, it will be violated for analog silence */ int findReplayGain; /* find the RG value? default=0 */ int findPeakSample; int decode_on_the_fly; /* decode on the fly? default=0 */ int analysis; int disable_reservoir; int buffer_constraint; /* enforce ISO spec as much as possible */ int free_format; int write_lame_tag; /* add Xing VBR tag? */ int error_protection; /* use 2 bytes per frame for a CRC checksum. default=0 */ int copyright; /* mark as copyright. default=0 */ int original; /* mark as original. default=1 */ int extension; /* the MP3 'private extension' bit. Meaningless */ int emphasis; /* Input PCM is emphased PCM (for instance from one of the rarely emphased CDs), it is STRONGLY not recommended to use this, because psycho does not take it into account, and last but not least many decoders don't care about these bits */ MPEG_mode mode; short_block_t short_blocks; float interChRatio; float msfix; /* Naoki's adjustment of Mid/Side maskings */ float ATH_offset_db;/* add to ATH this many db */ float ATH_offset_factor;/* change ATH by this factor, derived from ATH_offset_db */ float ATHcurve; /* change ATH formula 4 shape */ int ATHtype; int ATHonly; /* only use ATH */ int ATHshort; /* only use ATH for short blocks */ int noATH; /* disable ATH */ float ATHfixpoint; float adjust_alto_db; float adjust_bass_db; float adjust_treble_db; float adjust_sfb21_db; float compression_ratio; /* sizeof(wav file)/sizeof(mp3 file) */ /* lowpass and highpass filter control */ FLOAT lowpass1, lowpass2; /* normalized frequency bounds of passband */ FLOAT highpass1, highpass2; /* normalized frequency bounds of passband */ /* scale input by this amount before encoding at least not used for MP3 decoding */ FLOAT pcm_transform[2][2]; FLOAT minval; } SessionConfig_t; struct lame_internal_flags { /******************************************************************** * internal variables NOT set by calling program, and should not be * * modified by the calling program * ********************************************************************/ /* * Some remarks to the Class_ID field: * The Class ID is an Identifier for a pointer to this struct. * It is very unlikely that a pointer to lame_global_flags has the same 32 bits * in it's structure (large and other special properties, for instance prime). * * To test that the structure is right and initialized, use: * if ( gfc -> Class_ID == LAME_ID ) ... * Other remark: * If you set a flag to 0 for uninit data and 1 for init data, the right test * should be "if (flag == 1)" and NOT "if (flag)". Unintended modification * of this element will be otherwise misinterpreted as an init. */ # define LAME_ID 0xFFF88E3B unsigned long class_id; int lame_encode_frame_init; int iteration_init_init; int fill_buffer_resample_init; SessionConfig_t cfg; /* variables used by lame.c */ Bit_stream_struc bs; III_side_info_t l3_side; scalefac_struct scalefac_band; PsyStateVar_t sv_psy; /* DATA FROM PSYMODEL.C */ PsyResult_t ov_psy; EncStateVar_t sv_enc; /* DATA FROM ENCODER.C */ EncResult_t ov_enc; QntStateVar_t sv_qnt; /* DATA FROM QUANTIZE.C */ RpgStateVar_t sv_rpg; RpgResult_t ov_rpg; /* optional ID3 tags, used in id3tag.c */ struct id3tag_spec tag_spec; uint16_t nMusicCRC; uint16_t _unused; /* CPU features */ struct { unsigned int MMX:1; /* Pentium MMX, Pentium II...IV, K6, K6-2, K6-III, Athlon */ unsigned int AMD_3DNow:1; /* K6-2, K6-III, Athlon */ unsigned int SSE:1; /* Pentium III, Pentium 4 */ unsigned int SSE2:1; /* Pentium 4, K8 */ unsigned int _unused:28; } CPU_features; VBR_seek_info_t VBR_seek_table; /* used for Xing VBR header */ ATH_t *ATH; /* all ATH related stuff */ PsyConst_t *cd_psy; /* used by the frame analyzer */ plotting_data *pinfo; hip_t hip; iteration_loop_t iteration_loop; /* functions to replace with CPU feature optimized versions in takehiro.c */ int (*choose_table) (const int *ix, const int *const end, int *const s); void (*fft_fht) (FLOAT *, int); void (*init_xrpow_core) (gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum); lame_report_function report_msg; lame_report_function report_dbg; lame_report_function report_err; }; #ifndef lame_internal_flags_defined #define lame_internal_flags_defined typedef struct lame_internal_flags lame_internal_flags; #endif /*********************************************************************** * * Global Function Prototype Declarations * ***********************************************************************/ void freegfc(lame_internal_flags * const gfc); void free_id3tag(lame_internal_flags * const gfc); extern int BitrateIndex(int, int, int); extern int FindNearestBitrate(int, int, int); extern int map2MP3Frequency(int freq); extern int SmpFrqIndex(int, int *const); extern int nearestBitrateFullIndex(uint16_t brate); extern FLOAT ATHformula(SessionConfig_t const *cfg, FLOAT freq); extern FLOAT freq2bark(FLOAT freq); void disable_FPE(void); /* log/log10 approximations */ extern void init_log_table(void); extern float fast_log2(float x); int isResamplingNecessary(SessionConfig_t const* cfg); void fill_buffer(lame_internal_flags * gfc, sample_t *const mfbuf[2], sample_t const *const in_buffer[2], int nsamples, int *n_in, int *n_out); /* same as lame_decode1 (look in lame.h), but returns unclipped raw floating-point samples. It is declared here, not in lame.h, because it returns LAME's internal type sample_t. No more than 1152 samples per channel are allowed. */ int hip_decode1_unclipped(hip_t hip, unsigned char *mp3buf, size_t len, sample_t pcm_l[], sample_t pcm_r[]); extern int has_MMX(void); extern int has_3DNow(void); extern int has_SSE(void); extern int has_SSE2(void); /*********************************************************************** * * Macros about Message Printing and Exit * ***********************************************************************/ extern void lame_report_def(const char* format, va_list args); extern void lame_report_fnc(lame_report_function print_f, const char *, ...); extern void lame_errorf(const lame_internal_flags * gfc, const char *, ...); extern void lame_debugf(const lame_internal_flags * gfc, const char *, ...); extern void lame_msgf(const lame_internal_flags * gfc, const char *, ...); #define DEBUGF lame_debugf #define ERRORF lame_errorf #define MSGF lame_msgf int is_lame_internal_flags_valid(const lame_internal_flags * gfp); extern void hip_set_pinfo(hip_t hip, plotting_data* pinfo); #ifdef __cplusplus } #endif #endif /* LAME_UTIL_H */ ================================================ FILE: app/jni/libmp3lame/vbrquantize.c ================================================ /* * MP3 quantization * * Copyright (c) 1999-2000 Mark Taylor * Copyright (c) 2000-2012 Robert Hegemann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: vbrquantize.c,v 1.141.2.1 2012/02/07 13:40:37 robert Exp $ */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "vbrquantize.h" #include "quantize_pvt.h" struct algo_s; typedef struct algo_s algo_t; typedef void (*alloc_sf_f) (const algo_t *, const int *, const int *, int); typedef uint8_t (*find_sf_f) (const FLOAT *, const FLOAT *, FLOAT, unsigned int, uint8_t); struct algo_s { alloc_sf_f alloc; find_sf_f find; const FLOAT *xr34orig; lame_internal_flags *gfc; gr_info *cod_info; int mingain_l; int mingain_s[3]; }; /* Remarks on optimizing compilers: * * the MSVC compiler may get into aliasing problems when accessing * memory through the fi_union. declaring it volatile does the trick here * * the calc_sfb_noise_* functions are not inlined because the intel compiler * optimized executeables won't work as expected anymore */ #ifdef _MSC_VER # if _MSC_VER < 1400 # define VOLATILE volatile # else # define VOLATILE # endif #else # define VOLATILE #endif typedef VOLATILE union { float f; int i; } fi_union; #ifdef TAKEHIRO_IEEE754_HACK #define DOUBLEX double #else #define DOUBLEX FLOAT #endif #define MAGIC_FLOAT_def (65536*(128)) #define MAGIC_INT_def 0x4b000000 #ifdef TAKEHIRO_IEEE754_HACK #else /********************************************************************* * XRPOW_FTOI is a macro to convert floats to ints. * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x] * ROUNDFAC= -0.0946 * * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x] * ROUNDFAC=0.4054 *********************************************************************/ # define QUANTFAC(rx) adj43[rx] # define ROUNDFAC_def 0.4054f # define XRPOW_FTOI(src,dest) ((dest) = (int)(src)) #endif static int const MAGIC_INT = MAGIC_INT_def; #ifndef TAKEHIRO_IEEE754_HACK static DOUBLEX const ROUNDFAC = ROUNDFAC_def; #endif static DOUBLEX const MAGIC_FLOAT = MAGIC_FLOAT_def; inline static float vec_max_c(const float * xr34, unsigned int bw) { float xfsf = 0; unsigned int i = bw >> 2u; unsigned int const remaining = (bw & 0x03u); while (i-- > 0) { if (xfsf < xr34[0]) { xfsf = xr34[0]; } if (xfsf < xr34[1]) { xfsf = xr34[1]; } if (xfsf < xr34[2]) { xfsf = xr34[2]; } if (xfsf < xr34[3]) { xfsf = xr34[3]; } xr34 += 4; } switch( remaining ) { case 3: if (xfsf < xr34[2]) xfsf = xr34[2]; case 2: if (xfsf < xr34[1]) xfsf = xr34[1]; case 1: if (xfsf < xr34[0]) xfsf = xr34[0]; default: break; } return xfsf; } inline static uint8_t find_lowest_scalefac(const FLOAT xr34) { uint8_t sf_ok = 255; uint8_t sf = 128, delsf = 64; uint8_t i; FLOAT const ixmax_val = IXMAX_VAL; for (i = 0; i < 8; ++i) { FLOAT const xfsf = ipow20[sf] * xr34; if (xfsf <= ixmax_val) { sf_ok = sf; sf -= delsf; } else { sf += delsf; } delsf >>= 1; } return sf_ok; } inline static void k_34_4(DOUBLEX x[4], int l3[4]) { #ifdef TAKEHIRO_IEEE754_HACK fi_union fi[4]; assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL); x[0] += MAGIC_FLOAT; fi[0].f = x[0]; x[1] += MAGIC_FLOAT; fi[1].f = x[1]; x[2] += MAGIC_FLOAT; fi[2].f = x[2]; x[3] += MAGIC_FLOAT; fi[3].f = x[3]; fi[0].f = x[0] + adj43asm[fi[0].i - MAGIC_INT]; fi[1].f = x[1] + adj43asm[fi[1].i - MAGIC_INT]; fi[2].f = x[2] + adj43asm[fi[2].i - MAGIC_INT]; fi[3].f = x[3] + adj43asm[fi[3].i - MAGIC_INT]; l3[0] = fi[0].i - MAGIC_INT; l3[1] = fi[1].i - MAGIC_INT; l3[2] = fi[2].i - MAGIC_INT; l3[3] = fi[3].i - MAGIC_INT; #else assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL); XRPOW_FTOI(x[0], l3[0]); XRPOW_FTOI(x[1], l3[1]); XRPOW_FTOI(x[2], l3[2]); XRPOW_FTOI(x[3], l3[3]); x[0] += QUANTFAC(l3[0]); x[1] += QUANTFAC(l3[1]); x[2] += QUANTFAC(l3[2]); x[3] += QUANTFAC(l3[3]); XRPOW_FTOI(x[0], l3[0]); XRPOW_FTOI(x[1], l3[1]); XRPOW_FTOI(x[2], l3[2]); XRPOW_FTOI(x[3], l3[3]); #endif } /* do call the calc_sfb_noise_* functions only with sf values * for which holds: sfpow34*xr34 <= IXMAX_VAL */ static FLOAT calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, unsigned int bw, uint8_t sf) { DOUBLEX x[4]; int l3[4]; const FLOAT sfpow = pow20[sf + Q_MAX2]; /*pow(2.0,sf/4.0); */ const FLOAT sfpow34 = ipow20[sf]; /*pow(sfpow,-3.0/4.0); */ FLOAT xfsf = 0; unsigned int i = bw >> 2u; unsigned int const remaining = (bw & 0x03u); while (i-- > 0) { x[0] = sfpow34 * xr34[0]; x[1] = sfpow34 * xr34[1]; x[2] = sfpow34 * xr34[2]; x[3] = sfpow34 * xr34[3]; k_34_4(x, l3); x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]]; x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]]; x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]]; x[3] = fabsf(xr[3]) - sfpow * pow43[l3[3]]; xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]); xr += 4; xr34 += 4; } if (remaining) { x[0] = x[1] = x[2] = x[3] = 0; switch( remaining ) { case 3: x[2] = sfpow34 * xr34[2]; case 2: x[1] = sfpow34 * xr34[1]; case 1: x[0] = sfpow34 * xr34[0]; } k_34_4(x, l3); x[0] = x[1] = x[2] = x[3] = 0; switch( remaining ) { case 3: x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]]; case 2: x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]]; case 1: x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]]; } xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]); } return xfsf; } struct calc_noise_cache { int valid; FLOAT value; }; typedef struct calc_noise_cache calc_noise_cache_t; static uint8_t tri_calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf, calc_noise_cache_t * did_it) { if (did_it[sf].valid == 0) { did_it[sf].valid = 1; did_it[sf].value = calc_sfb_noise_x34(xr, xr34, bw, sf); } if (l3_xmin < did_it[sf].value) { return 1; } if (sf < 255) { uint8_t const sf_x = sf + 1; if (did_it[sf_x].valid == 0) { did_it[sf_x].valid = 1; did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x); } if (l3_xmin < did_it[sf_x].value) { return 1; } } if (sf > 0) { uint8_t const sf_x = sf - 1; if (did_it[sf_x].valid == 0) { did_it[sf_x].valid = 1; did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x); } if (l3_xmin < did_it[sf_x].value) { return 1; } } return 0; } /** * Robert Hegemann 2001-05-01 * calculates quantization step size determined by allowed masking */ static int calc_scalefac(FLOAT l3_xmin, int bw) { FLOAT const c = 5.799142446; /* 10 * 10^(2/3) * log10(4/3) */ return 210 + (int) (c * log10f(l3_xmin / bw) - .5f); } static uint8_t guess_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf_min) { int const guess = calc_scalefac(l3_xmin, bw); if (guess < sf_min) return sf_min; if (guess >= 255) return 255; (void) xr; (void) xr34; return guess; } /* the find_scalefac* routines calculate * a quantization step size which would * introduce as much noise as is allowed. * The larger the step size the more * quantization noise we'll get. The * scalefactors are there to lower the * global step size, allowing limited * differences in quantization step sizes * per band (shaping the noise). */ static uint8_t find_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf_min) { calc_noise_cache_t did_it[256]; uint8_t sf = 128, sf_ok = 255, delsf = 128, seen_good_one = 0, i; memset(did_it, 0, sizeof(did_it)); for (i = 0; i < 8; ++i) { delsf >>= 1; if (sf <= sf_min) { sf += delsf; } else { uint8_t const bad = tri_calc_sfb_noise_x34(xr, xr34, l3_xmin, bw, sf, did_it); if (bad) { /* distortion. try a smaller scalefactor */ sf -= delsf; } else { sf_ok = sf; sf += delsf; seen_good_one = 1; } } } /* returning a scalefac without distortion, if possible */ if (seen_good_one > 0) { sf = sf_ok; } if (sf <= sf_min) { sf = sf_min; } return sf; } /*********************************************************************** * * calc_short_block_vbr_sf() * calc_long_block_vbr_sf() * * Mark Taylor 2000-??-?? * Robert Hegemann 2000-10-25 made functions of it * ***********************************************************************/ /* a variation for vbr-mtrh */ static int block_sf(algo_t * that, const FLOAT l3_xmin[SFBMAX], int vbrsf[SFBMAX], int vbrsfmin[SFBMAX]) { FLOAT max_xr34; const FLOAT *const xr = &that->cod_info->xr[0]; const FLOAT *const xr34_orig = &that->xr34orig[0]; const int *const width = &that->cod_info->width[0]; const char *const energy_above_cutoff = &that->cod_info->energy_above_cutoff[0]; unsigned int const max_nonzero_coeff = (unsigned int) that->cod_info->max_nonzero_coeff; uint8_t maxsf = 0; int sfb = 0, m_o = -1; unsigned int j = 0, i = 0; int const psymax = that->cod_info->psymax; assert(that->cod_info->max_nonzero_coeff >= 0); that->mingain_l = 0; that->mingain_s[0] = 0; that->mingain_s[1] = 0; that->mingain_s[2] = 0; while (j <= max_nonzero_coeff) { unsigned int const w = (unsigned int) width[sfb]; unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1); unsigned int l = w; uint8_t m1, m2; if (l > m) { l = m; } max_xr34 = vec_max_c(&xr34_orig[j], l); m1 = find_lowest_scalefac(max_xr34); vbrsfmin[sfb] = m1; if (that->mingain_l < m1) { that->mingain_l = m1; } if (that->mingain_s[i] < m1) { that->mingain_s[i] = m1; } if (++i > 2) { i = 0; } if (sfb < psymax && w > 2) { /* mpeg2.5 at 8 kHz doesn't use all scalefactors, unused have width 2 */ if (energy_above_cutoff[sfb]) { m2 = that->find(&xr[j], &xr34_orig[j], l3_xmin[sfb], l, m1); #if 0 if (0) { /** Robert Hegemann 2007-09-29: * It seems here is some more potential for speed improvements. * Current find method does 11-18 quantization calculations. * Using a "good guess" may help to reduce this amount. */ uint8_t guess = calc_scalefac(l3_xmin[sfb], l); DEBUGF(that->gfc, "sfb=%3d guess=%3d found=%3d diff=%3d\n", sfb, guess, m2, m2 - guess); } #endif if (maxsf < m2) { maxsf = m2; } if (m_o < m2 && m2 < 255) { m_o = m2; } } else { m2 = 255; maxsf = 255; } } else { if (maxsf < m1) { maxsf = m1; } m2 = maxsf; } vbrsf[sfb] = m2; ++sfb; j += w; } for (; sfb < SFBMAX; ++sfb) { vbrsf[sfb] = maxsf; vbrsfmin[sfb] = 0; } if (m_o > -1) { maxsf = m_o; for (sfb = 0; sfb < SFBMAX; ++sfb) { if (vbrsf[sfb] == 255) { vbrsf[sfb] = m_o; } } } return maxsf; } /*********************************************************************** * * quantize xr34 based on scalefactors * * block_xr34 * * Mark Taylor 2000-??-?? * Robert Hegemann 2000-10-20 made functions of them * ***********************************************************************/ static void quantize_x34(const algo_t * that) { DOUBLEX x[4]; const FLOAT *xr34_orig = that->xr34orig; gr_info *const cod_info = that->cod_info; int const ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4; int *l3 = cod_info->l3_enc; unsigned int j = 0, sfb = 0; unsigned int const max_nonzero_coeff = (unsigned int) cod_info->max_nonzero_coeff; assert(cod_info->max_nonzero_coeff >= 0); assert(cod_info->max_nonzero_coeff < 576); while (j <= max_nonzero_coeff) { int const s = (cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep + cod_info->subblock_gain[cod_info->window[sfb]] * 8; uint8_t const sfac = (uint8_t) (cod_info->global_gain - s); FLOAT const sfpow34 = ipow20[sfac]; unsigned int const w = (unsigned int) cod_info->width[sfb]; unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1); unsigned int i, remaining; assert((cod_info->global_gain - s) >= 0); assert(cod_info->width[sfb] >= 0); j += w; ++sfb; i = (w <= m) ? w : m; remaining = (i & 0x03u); i >>= 2u; while (i-- > 0) { x[0] = sfpow34 * xr34_orig[0]; x[1] = sfpow34 * xr34_orig[1]; x[2] = sfpow34 * xr34_orig[2]; x[3] = sfpow34 * xr34_orig[3]; k_34_4(x, l3); l3 += 4; xr34_orig += 4; } if (remaining) { int tmp_l3[4]; x[0] = x[1] = x[2] = x[3] = 0; switch( remaining ) { case 3: x[2] = sfpow34 * xr34_orig[2]; case 2: x[1] = sfpow34 * xr34_orig[1]; case 1: x[0] = sfpow34 * xr34_orig[0]; } k_34_4(x, tmp_l3); switch( remaining ) { case 3: l3[2] = tmp_l3[2]; case 2: l3[1] = tmp_l3[1]; case 1: l3[0] = tmp_l3[0]; } l3 += remaining; xr34_orig += remaining; } } } static const uint8_t max_range_short[SBMAX_s * 3] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0 }; static const uint8_t max_range_long[SBMAX_l] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0 }; static const uint8_t max_range_long_lsf_pretab[SBMAX_l] = { 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* sfb=0..5 scalefac < 16 sfb>5 scalefac < 8 ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; ol_sf = (cod_info->global_gain-210.0); ol_sf -= 8*cod_info->subblock_gain[i]; ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i]; */ static void set_subblock_gain(gr_info * cod_info, const int mingain_s[3], int sf[]) { const int maxrange1 = 15, maxrange2 = 7; const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2; int *const sbg = cod_info->subblock_gain; unsigned int const psymax = (unsigned int) cod_info->psymax; unsigned int psydiv = 18; int sbg0, sbg1, sbg2; unsigned int sfb, i; int min_sbg = 7; if (psydiv > psymax) { psydiv = psymax; } for (i = 0; i < 3; ++i) { int maxsf1 = 0, maxsf2 = 0, minsf = 1000; /* see if we should use subblock gain */ for (sfb = i; sfb < psydiv; sfb += 3) { /* part 1 */ int const v = -sf[sfb]; if (maxsf1 < v) { maxsf1 = v; } if (minsf > v) { minsf = v; } } for (; sfb < SFBMAX; sfb += 3) { /* part 2 */ int const v = -sf[sfb]; if (maxsf2 < v) { maxsf2 = v; } if (minsf > v) { minsf = v; } } /* boost subblock gain as little as possible so we can * reach maxsf1 with scalefactors * 8*sbg >= maxsf1 */ { int const m1 = maxsf1 - (maxrange1 << ifqstepShift); int const m2 = maxsf2 - (maxrange2 << ifqstepShift); maxsf1 = Max(m1, m2); } if (minsf > 0) { sbg[i] = minsf >> 3; } else { sbg[i] = 0; } if (maxsf1 > 0) { int const m1 = sbg[i]; int const m2 = (maxsf1 + 7) >> 3; sbg[i] = Max(m1, m2); } if (sbg[i] > 0 && mingain_s[i] > (cod_info->global_gain - sbg[i] * 8)) { sbg[i] = (cod_info->global_gain - mingain_s[i]) >> 3; } if (sbg[i] > 7) { sbg[i] = 7; } if (min_sbg > sbg[i]) { min_sbg = sbg[i]; } } sbg0 = sbg[0] * 8; sbg1 = sbg[1] * 8; sbg2 = sbg[2] * 8; for (sfb = 0; sfb < SFBMAX; sfb += 3) { sf[sfb + 0] += sbg0; sf[sfb + 1] += sbg1; sf[sfb + 2] += sbg2; } if (min_sbg > 0) { for (i = 0; i < 3; ++i) { sbg[i] -= min_sbg; } cod_info->global_gain -= min_sbg * 8; } } /* ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; ol_sf = (cod_info->global_gain-210.0); ol_sf -= ifqstep*scalefac[gr][ch].l[sfb]; if (cod_info->preflag && sfb>=11) ol_sf -= ifqstep*pretab[sfb]; */ static void set_scalefacs(gr_info * cod_info, const int *vbrsfmin, int sf[], const uint8_t * max_range) { const int ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4; const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2; int *const scalefac = cod_info->scalefac; int const sfbmax = cod_info->sfbmax; int sfb; int const *const sbg = cod_info->subblock_gain; int const *const window = cod_info->window; int const preflag = cod_info->preflag; if (preflag) { for (sfb = 11; sfb < sfbmax; ++sfb) { sf[sfb] += pretab[sfb] * ifqstep; } } for (sfb = 0; sfb < sfbmax; ++sfb) { int const gain = cod_info->global_gain - (sbg[window[sfb]] * 8) - ((preflag ? pretab[sfb] : 0) * ifqstep); if (sf[sfb] < 0) { int const m = gain - vbrsfmin[sfb]; /* ifqstep*scalefac >= -sf[sfb], so round UP */ scalefac[sfb] = (ifqstep - 1 - sf[sfb]) >> ifqstepShift; if (scalefac[sfb] > max_range[sfb]) { scalefac[sfb] = max_range[sfb]; } if (scalefac[sfb] > 0 && (scalefac[sfb] << ifqstepShift) > m) { scalefac[sfb] = m >> ifqstepShift; } } else { scalefac[sfb] = 0; } } for (; sfb < SFBMAX; ++sfb) { scalefac[sfb] = 0; /* sfb21 */ } } #ifndef NDEBUG static int checkScalefactor(const gr_info * cod_info, const int vbrsfmin[SFBMAX]) { int const ifqstep = cod_info->scalefac_scale == 0 ? 2 : 4; int sfb; for (sfb = 0; sfb < cod_info->psymax; ++sfb) { const int s = ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep) + cod_info->subblock_gain[cod_info->window[sfb]] * 8; if ((cod_info->global_gain - s) < vbrsfmin[sfb]) { /* fprintf( stdout, "sf %d\n", sfb ); fprintf( stdout, "min %d\n", vbrsfmin[sfb] ); fprintf( stdout, "ggain %d\n", cod_info->global_gain ); fprintf( stdout, "scalefac %d\n", cod_info->scalefac[sfb] ); fprintf( stdout, "pretab %d\n", (cod_info->preflag ? pretab[sfb] : 0) ); fprintf( stdout, "scale %d\n", (cod_info->scalefac_scale + 1) ); fprintf( stdout, "subgain %d\n", cod_info->subblock_gain[cod_info->window[sfb]] * 8 ); fflush( stdout ); exit(-1); */ return 0; } } return 1; } #endif /****************************************************************** * * short block scalefacs * ******************************************************************/ static void short_block_constrain(const algo_t * that, const int vbrsf[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax) { gr_info *const cod_info = that->cod_info; lame_internal_flags const *const gfc = that->gfc; SessionConfig_t const *const cfg = &gfc->cfg; int const maxminsfb = that->mingain_l; int mover, maxover0 = 0, maxover1 = 0, delta = 0; int v, v0, v1; int sfb; int const psymax = cod_info->psymax; for (sfb = 0; sfb < psymax; ++sfb) { assert(vbrsf[sfb] >= vbrsfmin[sfb]); v = vbrmax - vbrsf[sfb]; if (delta < v) { delta = v; } v0 = v - (4 * 14 + 2 * max_range_short[sfb]); v1 = v - (4 * 14 + 4 * max_range_short[sfb]); if (maxover0 < v0) { maxover0 = v0; } if (maxover1 < v1) { maxover1 = v1; } } if (cfg->noise_shaping == 2) { /* allow scalefac_scale=1 */ mover = Min(maxover0, maxover1); } else { mover = maxover0; } if (delta > mover) { delta = mover; } vbrmax -= delta; maxover0 -= mover; maxover1 -= mover; if (maxover0 == 0) { cod_info->scalefac_scale = 0; } else if (maxover1 == 0) { cod_info->scalefac_scale = 1; } if (vbrmax < maxminsfb) { vbrmax = maxminsfb; } cod_info->global_gain = vbrmax; if (cod_info->global_gain < 0) { cod_info->global_gain = 0; } else if (cod_info->global_gain > 255) { cod_info->global_gain = 255; } { int sf_temp[SFBMAX]; for (sfb = 0; sfb < SFBMAX; ++sfb) { sf_temp[sfb] = vbrsf[sfb] - vbrmax; } set_subblock_gain(cod_info, &that->mingain_s[0], sf_temp); set_scalefacs(cod_info, vbrsfmin, sf_temp, max_range_short); } assert(checkScalefactor(cod_info, vbrsfmin)); } /****************************************************************** * * long block scalefacs * ******************************************************************/ static void long_block_constrain(const algo_t * that, const int vbrsf[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax) { gr_info *const cod_info = that->cod_info; lame_internal_flags const *const gfc = that->gfc; SessionConfig_t const *const cfg = &gfc->cfg; uint8_t const *max_rangep; int const maxminsfb = that->mingain_l; int sfb; int maxover0, maxover1, maxover0p, maxover1p, mover, delta = 0; int v, v0, v1, v0p, v1p, vm0p = 1, vm1p = 1; int const psymax = cod_info->psymax; max_rangep = cfg->mode_gr == 2 ? max_range_long : max_range_long_lsf_pretab; maxover0 = 0; maxover1 = 0; maxover0p = 0; /* pretab */ maxover1p = 0; /* pretab */ for (sfb = 0; sfb < psymax; ++sfb) { assert(vbrsf[sfb] >= vbrsfmin[sfb]); v = vbrmax - vbrsf[sfb]; if (delta < v) { delta = v; } v0 = v - 2 * max_range_long[sfb]; v1 = v - 4 * max_range_long[sfb]; v0p = v - 2 * (max_rangep[sfb] + pretab[sfb]); v1p = v - 4 * (max_rangep[sfb] + pretab[sfb]); if (maxover0 < v0) { maxover0 = v0; } if (maxover1 < v1) { maxover1 = v1; } if (maxover0p < v0p) { maxover0p = v0p; } if (maxover1p < v1p) { maxover1p = v1p; } } if (vm0p == 1) { int gain = vbrmax - maxover0p; if (gain < maxminsfb) { gain = maxminsfb; } for (sfb = 0; sfb < psymax; ++sfb) { int const a = (gain - vbrsfmin[sfb]) - 2 * pretab[sfb]; if (a <= 0) { vm0p = 0; vm1p = 0; break; } } } if (vm1p == 1) { int gain = vbrmax - maxover1p; if (gain < maxminsfb) { gain = maxminsfb; } for (sfb = 0; sfb < psymax; ++sfb) { int const b = (gain - vbrsfmin[sfb]) - 4 * pretab[sfb]; if (b <= 0) { vm1p = 0; break; } } } if (vm0p == 0) { maxover0p = maxover0; } if (vm1p == 0) { maxover1p = maxover1; } if (cfg->noise_shaping != 2) { maxover1 = maxover0; maxover1p = maxover0p; } mover = Min(maxover0, maxover0p); mover = Min(mover, maxover1); mover = Min(mover, maxover1p); if (delta > mover) { delta = mover; } vbrmax -= delta; if (vbrmax < maxminsfb) { vbrmax = maxminsfb; } maxover0 -= mover; maxover0p -= mover; maxover1 -= mover; maxover1p -= mover; if (maxover0 == 0) { cod_info->scalefac_scale = 0; cod_info->preflag = 0; max_rangep = max_range_long; } else if (maxover0p == 0) { cod_info->scalefac_scale = 0; cod_info->preflag = 1; } else if (maxover1 == 0) { cod_info->scalefac_scale = 1; cod_info->preflag = 0; max_rangep = max_range_long; } else if (maxover1p == 0) { cod_info->scalefac_scale = 1; cod_info->preflag = 1; } else { assert(0); /* this should not happen */ } cod_info->global_gain = vbrmax; if (cod_info->global_gain < 0) { cod_info->global_gain = 0; } else if (cod_info->global_gain > 255) { cod_info->global_gain = 255; } { int sf_temp[SFBMAX]; for (sfb = 0; sfb < SFBMAX; ++sfb) { sf_temp[sfb] = vbrsf[sfb] - vbrmax; } set_scalefacs(cod_info, vbrsfmin, sf_temp, max_rangep); } assert(checkScalefactor(cod_info, vbrsfmin)); } static void bitcount(const algo_t * that) { int rc = scale_bitcount(that->gfc, that->cod_info); if (rc == 0) { return; } /* this should not happen due to the way the scalefactors are selected */ ERRORF(that->gfc, "INTERNAL ERROR IN VBR NEW CODE (986), please send bug report\n"); exit(-1); } static int quantizeAndCountBits(const algo_t * that) { quantize_x34(that); that->cod_info->part2_3_length = noquant_count_bits(that->gfc, that->cod_info, 0); return that->cod_info->part2_3_length; } static int tryGlobalStepsize(const algo_t * that, const int sfwork[SFBMAX], const int vbrsfmin[SFBMAX], int delta) { FLOAT const xrpow_max = that->cod_info->xrpow_max; int sftemp[SFBMAX], i, nbits; int gain, vbrmax = 0; for (i = 0; i < SFBMAX; ++i) { gain = sfwork[i] + delta; if (gain < vbrsfmin[i]) { gain = vbrsfmin[i]; } if (gain > 255) { gain = 255; } if (vbrmax < gain) { vbrmax = gain; } sftemp[i] = gain; } that->alloc(that, sftemp, vbrsfmin, vbrmax); bitcount(that); nbits = quantizeAndCountBits(that); that->cod_info->xrpow_max = xrpow_max; return nbits; } static void searchGlobalStepsizeMax(const algo_t * that, const int sfwork[SFBMAX], const int vbrsfmin[SFBMAX], int target) { gr_info const *const cod_info = that->cod_info; const int gain = cod_info->global_gain; int curr = gain; int gain_ok = 1024; int nbits = LARGE_BITS; int l = gain, r = 512; assert(gain >= 0); while (l <= r) { curr = (l + r) >> 1; nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain); if (nbits == 0 || (nbits + cod_info->part2_length) < target) { r = curr - 1; gain_ok = curr; } else { l = curr + 1; if (gain_ok == 1024) { gain_ok = curr; } } } if (gain_ok != curr) { curr = gain_ok; nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain); } } static int sfDepth(const int sfwork[SFBMAX]) { int m = 0; unsigned int i, j; for (j = SFBMAX, i = 0; j > 0; --j, ++i) { int const di = 255 - sfwork[i]; if (m < di) { m = di; } assert(sfwork[i] >= 0); assert(sfwork[i] <= 255); } assert(m >= 0); assert(m <= 255); return m; } static void cutDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int cut) { unsigned int i, j; for (j = SFBMAX, i = 0; j > 0; --j, ++i) { int const x = sfwork[i]; sf_out[i] = x < cut ? x : cut; } } static int flattenDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int dm, int k, int p) { unsigned int i, j; int x, sfmax = 0; if (dm > 0) { for (j = SFBMAX, i = 0; j > 0; --j, ++i) { int const di = p - sfwork[i]; x = sfwork[i] + (k * di) / dm; if (x < 0) { x = 0; } else { if (x > 255) { x = 255; } } sf_out[i] = x; if (sfmax < x) { sfmax = x; } } } else { for (j = SFBMAX, i = 0; j > 0u; --j, ++i) { x = sfwork[i]; sf_out[i] = x; if (sfmax < x) { sfmax = x; } } } return sfmax; } static int tryThatOne(algo_t const* that, const int sftemp[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax) { FLOAT const xrpow_max = that->cod_info->xrpow_max; int nbits = LARGE_BITS; that->alloc(that, sftemp, vbrsfmin, vbrmax); bitcount(that); nbits = quantizeAndCountBits(that); nbits += that->cod_info->part2_length; that->cod_info->xrpow_max = xrpow_max; return nbits; } static void outOfBitsStrategy(algo_t const* that, const int sfwork[SFBMAX], const int vbrsfmin[SFBMAX], int target) { int wrk[SFBMAX]; int const dm = sfDepth(sfwork); int const p = that->cod_info->global_gain; int nbits; /* PART 1 */ { int bi = dm / 2; int bi_ok = -1; int bu = 0; int bo = dm; for (;;) { int const sfmax = flattenDistribution(sfwork, wrk, dm, bi, p); nbits = tryThatOne(that, wrk, vbrsfmin, sfmax); if (nbits <= target) { bi_ok = bi; bo = bi - 1; } else { bu = bi + 1; } if (bu <= bo) { bi = (bu + bo) / 2; } else { break; } } if (bi_ok >= 0) { if (bi != bi_ok) { int const sfmax = flattenDistribution(sfwork, wrk, dm, bi_ok, p); nbits = tryThatOne(that, wrk, vbrsfmin, sfmax); } return; } } /* PART 2: */ { int bi = (255 + p) / 2; int bi_ok = -1; int bu = p; int bo = 255; for (;;) { int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi); nbits = tryThatOne(that, wrk, vbrsfmin, sfmax); if (nbits <= target) { bi_ok = bi; bo = bi - 1; } else { bu = bi + 1; } if (bu <= bo) { bi = (bu + bo) / 2; } else { break; } } if (bi_ok >= 0) { if (bi != bi_ok) { int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi_ok); nbits = tryThatOne(that, wrk, vbrsfmin, sfmax); } return; } } /* fall back to old code, likely to be never called */ searchGlobalStepsizeMax(that, wrk, vbrsfmin, target); } static int reduce_bit_usage(lame_internal_flags * gfc, int gr, int ch #if 0 , const FLOAT xr34orig[576], const FLOAT l3_xmin[SFBMAX], int maxbits #endif ) { SessionConfig_t const *const cfg = &gfc->cfg; gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; /* try some better scalefac storage */ best_scalefac_store(gfc, gr, ch, &gfc->l3_side); /* best huffman_divide may save some bits too */ if (cfg->use_best_huffman == 1) best_huffman_divide(gfc, cod_info); return cod_info->part2_3_length + cod_info->part2_length; } int VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576], const FLOAT l3_xmin[2][2][SFBMAX], const int max_bits[2][2]) { SessionConfig_t const *const cfg = &gfc->cfg; int sfwork_[2][2][SFBMAX]; int vbrsfmin_[2][2][SFBMAX]; algo_t that_[2][2]; int const ngr = cfg->mode_gr; int const nch = cfg->channels_out; int max_nbits_ch[2][2] = {{0, 0}, {0 ,0}}; int max_nbits_gr[2] = {0, 0}; int max_nbits_fr = 0; int use_nbits_ch[2][2] = {{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1} ,{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}}; int use_nbits_gr[2] = { MAX_BITS_PER_GRANULE+1, MAX_BITS_PER_GRANULE+1 }; int use_nbits_fr = MAX_BITS_PER_GRANULE+MAX_BITS_PER_GRANULE; int gr, ch; int ok, sum_fr; /* set up some encoding parameters */ for (gr = 0; gr < ngr; ++gr) { max_nbits_gr[gr] = 0; for (ch = 0; ch < nch; ++ch) { max_nbits_ch[gr][ch] = max_bits[gr][ch]; use_nbits_ch[gr][ch] = 0; max_nbits_gr[gr] += max_bits[gr][ch]; max_nbits_fr += max_bits[gr][ch]; that_[gr][ch].find = (cfg->full_outer_loop < 0) ? guess_scalefac_x34 : find_scalefac_x34; that_[gr][ch].gfc = gfc; that_[gr][ch].cod_info = &gfc->l3_side.tt[gr][ch]; that_[gr][ch].xr34orig = xr34orig[gr][ch]; if (that_[gr][ch].cod_info->block_type == SHORT_TYPE) { that_[gr][ch].alloc = short_block_constrain; } else { that_[gr][ch].alloc = long_block_constrain; } } /* for ch */ } /* searches scalefactors */ for (gr = 0; gr < ngr; ++gr) { for (ch = 0; ch < nch; ++ch) { if (max_bits[gr][ch] > 0) { algo_t *that = &that_[gr][ch]; int *sfwork = sfwork_[gr][ch]; int *vbrsfmin = vbrsfmin_[gr][ch]; int vbrmax; vbrmax = block_sf(that, l3_xmin[gr][ch], sfwork, vbrsfmin); that->alloc(that, sfwork, vbrsfmin, vbrmax); bitcount(that); } else { /* xr contains no energy * l3_enc, our encoding data, will be quantized to zero * continue with next channel */ } } /* for ch */ } /* encode 'as is' */ use_nbits_fr = 0; for (gr = 0; gr < ngr; ++gr) { use_nbits_gr[gr] = 0; for (ch = 0; ch < nch; ++ch) { algo_t const *that = &that_[gr][ch]; if (max_bits[gr][ch] > 0) { memset(&that->cod_info->l3_enc[0], 0, sizeof(that->cod_info->l3_enc)); (void) quantizeAndCountBits(that); } else { /* xr contains no energy * l3_enc, our encoding data, will be quantized to zero * continue with next channel */ } use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch); use_nbits_gr[gr] += use_nbits_ch[gr][ch]; } /* for ch */ use_nbits_fr += use_nbits_gr[gr]; } /* check bit constrains */ if (use_nbits_fr <= max_nbits_fr) { ok = 1; for (gr = 0; gr < ngr; ++gr) { if (use_nbits_gr[gr] > MAX_BITS_PER_GRANULE) { /* violates the rule that every granule has to use no more * bits than MAX_BITS_PER_GRANULE */ ok = 0; } for (ch = 0; ch < nch; ++ch) { if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) { /* violates the rule that every gr_ch has to use no more * bits than MAX_BITS_PER_CHANNEL * * This isn't explicitly stated in the ISO docs, but the * part2_3_length field has only 12 bits, that makes it * up to a maximum size of 4095 bits!!! */ ok = 0; } } } if (ok) { return use_nbits_fr; } } /* OK, we are in trouble and have to define how many bits are * to be used for each granule */ { ok = 1; sum_fr = 0; for (gr = 0; gr < ngr; ++gr) { max_nbits_gr[gr] = 0; for (ch = 0; ch < nch; ++ch) { if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) { max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL; } else { max_nbits_ch[gr][ch] = use_nbits_ch[gr][ch]; } max_nbits_gr[gr] += max_nbits_ch[gr][ch]; } if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) { float f[2] = {0.0f, 0.0f}, s = 0.0f; for (ch = 0; ch < nch; ++ch) { if (max_nbits_ch[gr][ch] > 0) { f[ch] = sqrt(sqrt(max_nbits_ch[gr][ch])); s += f[ch]; } else { f[ch] = 0; } } for (ch = 0; ch < nch; ++ch) { if (s > 0) { max_nbits_ch[gr][ch] = MAX_BITS_PER_GRANULE * f[ch] / s; } else { max_nbits_ch[gr][ch] = 0; } } if (nch > 1) { if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) { max_nbits_ch[gr][1] += max_nbits_ch[gr][0]; max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32; max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32; } if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) { max_nbits_ch[gr][0] += max_nbits_ch[gr][1]; max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32; max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32; } if (max_nbits_ch[gr][0] > MAX_BITS_PER_CHANNEL) { max_nbits_ch[gr][0] = MAX_BITS_PER_CHANNEL; } if (max_nbits_ch[gr][1] > MAX_BITS_PER_CHANNEL) { max_nbits_ch[gr][1] = MAX_BITS_PER_CHANNEL; } } max_nbits_gr[gr] = 0; for (ch = 0; ch < nch; ++ch) { max_nbits_gr[gr] += max_nbits_ch[gr][ch]; } } sum_fr += max_nbits_gr[gr]; } if (sum_fr > max_nbits_fr) { { float f[2] = {0.0f, 0.0f}, s = 0.0f; for (gr = 0; gr < ngr; ++gr) { if (max_nbits_gr[gr] > 0) { f[gr] = sqrt(max_nbits_gr[gr]); s += f[gr]; } else { f[gr] = 0; } } for (gr = 0; gr < ngr; ++gr) { if (s > 0) { max_nbits_gr[gr] = max_nbits_fr * f[gr] / s; } else { max_nbits_gr[gr] = 0; } } } if (ngr > 1) { if (max_nbits_gr[0] > use_nbits_gr[0] + 125) { max_nbits_gr[1] += max_nbits_gr[0]; max_nbits_gr[1] -= use_nbits_gr[0] + 125; max_nbits_gr[0] = use_nbits_gr[0] + 125; } if (max_nbits_gr[1] > use_nbits_gr[1] + 125) { max_nbits_gr[0] += max_nbits_gr[1]; max_nbits_gr[0] -= use_nbits_gr[1] + 125; max_nbits_gr[1] = use_nbits_gr[1] + 125; } for (gr = 0; gr < ngr; ++gr) { if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) { max_nbits_gr[gr] = MAX_BITS_PER_GRANULE; } } } for (gr = 0; gr < ngr; ++gr) { float f[2] = {0.0f, 0.0f}, s = 0.0f; for (ch = 0; ch < nch; ++ch) { if (max_nbits_ch[gr][ch] > 0) { f[ch] = sqrt(max_nbits_ch[gr][ch]); s += f[ch]; } else { f[ch] = 0; } } for (ch = 0; ch < nch; ++ch) { if (s > 0) { max_nbits_ch[gr][ch] = max_nbits_gr[gr] * f[ch] / s; } else { max_nbits_ch[gr][ch] = 0; } } if (nch > 1) { if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) { max_nbits_ch[gr][1] += max_nbits_ch[gr][0]; max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32; max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32; } if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) { max_nbits_ch[gr][0] += max_nbits_ch[gr][1]; max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32; max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32; } for (ch = 0; ch < nch; ++ch) { if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) { max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL; } } } } } /* sanity check */ sum_fr = 0; for (gr = 0; gr < ngr; ++gr) { int sum_gr = 0; for (ch = 0; ch < nch; ++ch) { sum_gr += max_nbits_ch[gr][ch]; if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) { ok = 0; } } sum_fr += sum_gr; if (sum_gr > MAX_BITS_PER_GRANULE) { ok = 0; } } if (sum_fr > max_nbits_fr) { ok = 0; } if (!ok) { /* we must have done something wrong, fallback to 'on_pe' based constrain */ for (gr = 0; gr < ngr; ++gr) { for (ch = 0; ch < nch; ++ch) { max_nbits_ch[gr][ch] = max_bits[gr][ch]; } } } } /* we already called the 'best_scalefac_store' function, so we need to reset some * variables before we can do it again. */ for (ch = 0; ch < nch; ++ch) { gfc->l3_side.scfsi[ch][0] = 0; gfc->l3_side.scfsi[ch][1] = 0; gfc->l3_side.scfsi[ch][2] = 0; gfc->l3_side.scfsi[ch][3] = 0; } for (gr = 0; gr < ngr; ++gr) { for (ch = 0; ch < nch; ++ch) { gfc->l3_side.tt[gr][ch].scalefac_compress = 0; } } /* alter our encoded data, until it fits into the target bitrate */ use_nbits_fr = 0; for (gr = 0; gr < ngr; ++gr) { use_nbits_gr[gr] = 0; for (ch = 0; ch < nch; ++ch) { algo_t const *that = &that_[gr][ch]; use_nbits_ch[gr][ch] = 0; if (max_bits[gr][ch] > 0) { int *sfwork = sfwork_[gr][ch]; int const *vbrsfmin = vbrsfmin_[gr][ch]; cutDistribution(sfwork, sfwork, that->cod_info->global_gain); outOfBitsStrategy(that, sfwork, vbrsfmin, max_nbits_ch[gr][ch]); } use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch); assert(use_nbits_ch[gr][ch] <= max_nbits_ch[gr][ch]); use_nbits_gr[gr] += use_nbits_ch[gr][ch]; } /* for ch */ use_nbits_fr += use_nbits_gr[gr]; } /* check bit constrains, but it should always be ok, iff there are no bugs ;-) */ if (use_nbits_fr <= max_nbits_fr) { return use_nbits_fr; } ERRORF(gfc, "INTERNAL ERROR IN VBR NEW CODE (1313), please send bug report\n" "maxbits=%d usedbits=%d\n", max_nbits_fr, use_nbits_fr); exit(-1); } ================================================ FILE: app/jni/libmp3lame/vbrquantize.h ================================================ /* * MP3 VBR quantization * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_VBRQUANTIZE_H #define LAME_VBRQUANTIZE_H int VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576], const FLOAT l3_xmin[2][2][SFBMAX], const int maxbits[2][2]); #endif /* LAME_VBRQUANTIZE_H */ ================================================ FILE: app/jni/libmp3lame/vector/Makefile.am ================================================ ## $Id: Makefile.am,v 1.1 2007/01/09 10:15:53 aleidinger Exp $ include $(top_srcdir)/Makefile.am.global if WITH_XMM noinst_LTLIBRARIES = liblamevectorroutines.la endif ##liblamecpuroutines_la_LIBADD = ##liblamecpuroutines_la_LDFLAGS = INCLUDES = @INCLUDES@ \ -I$(top_srcdir)/libmp3lame \ -I$(top_srcdir)/mpglib \ -I$(top_builddir) DEFS = @DEFS@ @CONFIG_DEFS@ xmm_sources = xmm_quantize_sub.c if WITH_XMM liblamevectorroutines_la_SOURCES = $(xmm_sources) endif noinst_HEADERS = lame_intrin.h EXTRA_liblamevectorroutines_la_SOURCES = $(xmm_sources) CLEANFILES = lclint.txt LCLINTFLAGS= \ +posixlib \ +showsummary \ +showalluses \ +whichlib \ +forcehints \ -fixedformalarray \ +matchanyintegral \ -Dlint lclint.txt: ${liblamecpuroutines_la_SOURCES} ${noinst_HEADERS} @lclint ${LCLINTFLAGS} ${INCLUDES} ${DEFS} ${liblamecpuroutines_la_SOURCES} 2>&1 >lclint.txt || true lclint: lclint.txt more lclint.txt #$(OBJECTS): libtool #libtool: $(LIBTOOL_DEPS) # $(SHELL) $(top_builddir)/config.status --recheck ================================================ FILE: app/jni/libmp3lame/vector/Makefile.in ================================================ # Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # global section for every Makefile.am VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ ANSI2KNR = $(top_srcdir)/ansi2knr DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/Makefile.am.global subdir = libmp3lame/vector ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) liblamevectorroutines_la_LIBADD = am__liblamevectorroutines_la_SOURCES_DIST = xmm_quantize_sub.c am__objects_1 = xmm_quantize_sub$U.lo @WITH_XMM_TRUE@am_liblamevectorroutines_la_OBJECTS = $(am__objects_1) liblamevectorroutines_la_OBJECTS = \ $(am_liblamevectorroutines_la_OBJECTS) @WITH_XMM_TRUE@am_liblamevectorroutines_la_rpath = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(liblamevectorroutines_la_SOURCES) \ $(EXTRA_liblamevectorroutines_la_SOURCES) DIST_SOURCES = $(am__liblamevectorroutines_la_SOURCES_DIST) \ $(EXTRA_liblamevectorroutines_la_SOURCES) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONFIG_DEFS = @CONFIG_DEFS@ CONFIG_MATH_LIB = @CONFIG_MATH_LIB@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CPUCCODE = @CPUCCODE@ CPUTYPE = @CPUTYPE@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ @CONFIG_DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FRONTEND_CFLAGS = @FRONTEND_CFLAGS@ FRONTEND_LDADD = @FRONTEND_LDADD@ FRONTEND_LDFLAGS = @FRONTEND_LDFLAGS@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ INCLUDES = @INCLUDES@ \ -I$(top_srcdir)/libmp3lame \ -I$(top_srcdir)/mpglib \ -I$(top_builddir) INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDADD = @LDADD@ LDFLAGS = @LDFLAGS@ LIBICONV = @LIBICONV@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_MAJOR_VERSION = @LIB_MAJOR_VERSION@ LIB_MINOR_VERSION = @LIB_MINOR_VERSION@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEDEP = @MAKEDEP@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NASM = @NASM@ NASM_FORMAT = @NASM_FORMAT@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RM_F = @RM_F@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ SNDFILE_LIBS = @SNDFILE_LIBS@ STRIP = @STRIP@ U = @U@ VERSION = @VERSION@ WITH_FRONTEND = @WITH_FRONTEND@ WITH_MP3RTP = @WITH_MP3RTP@ WITH_MP3X = @WITH_MP3X@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = 1.11 foreign $(top_srcdir)/ansi2knr @WITH_XMM_TRUE@noinst_LTLIBRARIES = liblamevectorroutines.la xmm_sources = xmm_quantize_sub.c @WITH_XMM_TRUE@liblamevectorroutines_la_SOURCES = $(xmm_sources) noinst_HEADERS = lame_intrin.h EXTRA_liblamevectorroutines_la_SOURCES = $(xmm_sources) CLEANFILES = lclint.txt LCLINTFLAGS = \ +posixlib \ +showsummary \ +showalluses \ +whichlib \ +forcehints \ -fixedformalarray \ +matchanyintegral \ -Dlint all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.global $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libmp3lame/vector/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign libmp3lame/vector/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done liblamevectorroutines.la: $(liblamevectorroutines_la_OBJECTS) $(liblamevectorroutines_la_DEPENDENCIES) $(LINK) $(am_liblamevectorroutines_la_rpath) $(liblamevectorroutines_la_OBJECTS) $(liblamevectorroutines_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c $(top_srcdir)/ansi2knr: $(am__cd) $(top_srcdir) && $(MAKE) $(AM_MAKEFLAGS) ./ansi2knr mostlyclean-kr: -test "$U" = "" || rm -f *_.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmm_quantize_sub$U.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< xmm_quantize_sub_.c: xmm_quantize_sub.c $(ANSI2KNR) $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/xmm_quantize_sub.c; then echo $(srcdir)/xmm_quantize_sub.c; else echo xmm_quantize_sub.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@ xmm_quantize_sub_.$(OBJEXT) xmm_quantize_sub_.lo : $(ANSI2KNR) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic mostlyclean-kr \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: $(top_srcdir)/ansi2knr install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-kr \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ uninstall-am # end global section lclint.txt: ${liblamecpuroutines_la_SOURCES} ${noinst_HEADERS} @lclint ${LCLINTFLAGS} ${INCLUDES} ${DEFS} ${liblamecpuroutines_la_SOURCES} 2>&1 >lclint.txt || true lclint: lclint.txt more lclint.txt #$(OBJECTS): libtool #libtool: $(LIBTOOL_DEPS) # $(SHELL) $(top_builddir)/config.status --recheck # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ================================================ FILE: app/jni/libmp3lame/vector/lame_intrin.h ================================================ /* * lame_intrin.h include file * * Copyright (c) 2006 Gabriel Bouvigne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_INTRIN_H #define LAME_INTRIN_H void init_xrpow_core_sse(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum); void fht_SSE2(FLOAT* , int); #endif ================================================ FILE: app/jni/libmp3lame/vector/xmm_quantize_sub.c ================================================ /* * MP3 quantization, intrinsics functions * * Copyright (c) 2005-2006 Gabriel Bouvigne * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "encoder.h" #include "util.h" #include "lame_intrin.h" #ifdef HAVE_XMMINTRIN_H #include typedef union { int32_t _i_32[4]; /* unions are initialized by its first member */ float _float[4]; __m128 _m128; } vecfloat_union; #define TRI_SIZE (5-1) /* 1024 = 4**5 */ static const FLOAT costab[TRI_SIZE * 2] = { 9.238795325112867e-01, 3.826834323650898e-01, 9.951847266721969e-01, 9.801714032956060e-02, 9.996988186962042e-01, 2.454122852291229e-02, 9.999811752826011e-01, 6.135884649154475e-03 }; void init_xrpow_core_sse(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum) { int i; float tmp_max = 0; float tmp_sum = 0; int upper4 = (upper / 4) * 4; int rest = upper-upper4; const vecfloat_union fabs_mask = {{ 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }}; const __m128 vec_fabs_mask = _mm_loadu_ps(&fabs_mask._float[0]); vecfloat_union vec_xrpow_max; vecfloat_union vec_sum; vecfloat_union vec_tmp; _mm_prefetch((char *) cod_info->xr, _MM_HINT_T0); _mm_prefetch((char *) xrpow, _MM_HINT_T0); vec_xrpow_max._m128 = _mm_set_ps1(0); vec_sum._m128 = _mm_set_ps1(0); for (i = 0; i < upper4; i += 4) { vec_tmp._m128 = _mm_loadu_ps(&(cod_info->xr[i])); /* load */ vec_tmp._m128 = _mm_and_ps(vec_tmp._m128, vec_fabs_mask); /* fabs */ vec_sum._m128 = _mm_add_ps(vec_sum._m128, vec_tmp._m128); vec_tmp._m128 = _mm_sqrt_ps(_mm_mul_ps(vec_tmp._m128, _mm_sqrt_ps(vec_tmp._m128))); vec_xrpow_max._m128 = _mm_max_ps(vec_xrpow_max._m128, vec_tmp._m128); /* retrieve max */ _mm_storeu_ps(&(xrpow[i]), vec_tmp._m128); /* store into xrpow[] */ } vec_tmp._m128 = _mm_set_ps1(0); switch (rest) { case 3: vec_tmp._float[2] = cod_info->xr[upper4+2]; case 2: vec_tmp._float[1] = cod_info->xr[upper4+1]; case 1: vec_tmp._float[0] = cod_info->xr[upper4+0]; vec_tmp._m128 = _mm_and_ps(vec_tmp._m128, vec_fabs_mask); /* fabs */ vec_sum._m128 = _mm_add_ps(vec_sum._m128, vec_tmp._m128); vec_tmp._m128 = _mm_sqrt_ps(_mm_mul_ps(vec_tmp._m128, _mm_sqrt_ps(vec_tmp._m128))); vec_xrpow_max._m128 = _mm_max_ps(vec_xrpow_max._m128, vec_tmp._m128); /* retrieve max */ switch (rest) { case 3: xrpow[upper4+2] = vec_tmp._float[2]; case 2: xrpow[upper4+1] = vec_tmp._float[1]; case 1: xrpow[upper4+0] = vec_tmp._float[0]; default: break; } default: break; } tmp_sum = vec_sum._float[0] + vec_sum._float[1] + vec_sum._float[2] + vec_sum._float[3]; { float ma = vec_xrpow_max._float[0] > vec_xrpow_max._float[1] ? vec_xrpow_max._float[0] : vec_xrpow_max._float[1]; float mb = vec_xrpow_max._float[2] > vec_xrpow_max._float[3] ? vec_xrpow_max._float[2] : vec_xrpow_max._float[3]; tmp_max = ma > mb ? ma : mb; } cod_info->xrpow_max = tmp_max; *sum = tmp_sum; } static void store4(__m128 v, float* f0, float* f1, float* f2, float* f3) { vecfloat_union r; r._m128 = v; *f0 = r._float[0]; *f1 = r._float[1]; *f2 = r._float[2]; *f3 = r._float[3]; } void fht_SSE2(FLOAT * fz, int n) { const FLOAT *tri = costab; int k4; FLOAT *fi, *gi; FLOAT const *fn; n <<= 1; /* to get BLKSIZE, because of 3DNow! ASM routine */ fn = fz + n; k4 = 4; do { FLOAT s1, c1; int i, k1, k2, k3, kx; kx = k4 >> 1; k1 = k4; k2 = k4 << 1; k3 = k2 + k1; k4 = k2 << 1; fi = fz; gi = fi + kx; do { FLOAT f0, f1, f2, f3; f1 = fi[0] - fi[k1]; f0 = fi[0] + fi[k1]; f3 = fi[k2] - fi[k3]; f2 = fi[k2] + fi[k3]; fi[k2] = f0 - f2; fi[0] = f0 + f2; fi[k3] = f1 - f3; fi[k1] = f1 + f3; f1 = gi[0] - gi[k1]; f0 = gi[0] + gi[k1]; f3 = SQRT2 * gi[k3]; f2 = SQRT2 * gi[k2]; gi[k2] = f0 - f2; gi[0] = f0 + f2; gi[k3] = f1 - f3; gi[k1] = f1 + f3; gi += k4; fi += k4; } while (fi < fn); c1 = tri[0]; s1 = tri[1]; for (i = 1; i < kx; i++) { __m128 v_s2; __m128 v_c2; __m128 v_c1; __m128 v_s1; FLOAT c2, s2, s1_2 = s1+s1; c2 = 1 - s1_2 * s1; s2 = s1_2 * c1; fi = fz + i; gi = fz + k1 - i; v_c1 = _mm_set_ps1(c1); v_s1 = _mm_set_ps1(s1); v_c2 = _mm_set_ps1(c2); v_s2 = _mm_set_ps1(s2); { static const vecfloat_union sign_mask = {{0x80000000,0,0,0}}; v_c1 = _mm_xor_ps(sign_mask._m128, v_c1); /* v_c1 := {-c1, +c1, +c1, +c1} */ } { static const vecfloat_union sign_mask = {{0,0x80000000,0,0}}; v_s1 = _mm_xor_ps(sign_mask._m128, v_s1); /* v_s1 := {+s1, -s1, +s1, +s1} */ } { static const vecfloat_union sign_mask = {{0,0,0x80000000,0x80000000}}; v_c2 = _mm_xor_ps(sign_mask._m128, v_c2); /* v_c2 := {+c2, +c2, -c2, -c2} */ } do { __m128 p, q, r; q = _mm_setr_ps(fi[k1], fi[k3], gi[k1], gi[k3]); /* Q := {fi_k1,fi_k3,gi_k1,gi_k3}*/ p = _mm_mul_ps(_mm_set_ps1(s2), q); /* P := s2 * Q */ q = _mm_mul_ps(v_c2, q); /* Q := c2 * Q */ q = _mm_shuffle_ps(q, q, _MM_SHUFFLE(1,0,3,2)); /* Q := {-c2*gi_k1,-c2*gi_k3,c2*fi_k1,c2*fi_k3} */ p = _mm_add_ps(p, q); r = _mm_setr_ps(gi[0], gi[k2], fi[0], fi[k2]); /* R := {gi_0,gi_k2,fi_0,fi_k2} */ q = _mm_sub_ps(r, p); /* Q := {gi_0-p0,gi_k2-p1,fi_0-p2,fi_k2-p3} */ r = _mm_add_ps(r, p); /* R := {gi_0+p0,gi_k2+p1,fi_0+p2,fi_k2+p3} */ p = _mm_shuffle_ps(q, r, _MM_SHUFFLE(2,0,2,0)); /* P := {q0,q2,r0,r2} */ p = _mm_shuffle_ps(p, p, _MM_SHUFFLE(3,1,2,0)); /* P := {q0,r0,q2,r2} */ q = _mm_shuffle_ps(q, r, _MM_SHUFFLE(3,1,3,1)); /* Q := {q1,q3,r1,r3} */ r = _mm_mul_ps(v_c1, q); q = _mm_mul_ps(v_s1, q); q = _mm_shuffle_ps(q, q, _MM_SHUFFLE(0,1,2,3)); /* Q := {q3,q2,q1,q0} */ q = _mm_add_ps(q, r); store4(_mm_sub_ps(p, q), &gi[k3], &gi[k2], &fi[k3], &fi[k2]); store4(_mm_add_ps(p, q), &gi[k1], &gi[ 0], &fi[k1], &fi[ 0]); gi += k4; fi += k4; } while (fi < fn); c2 = c1; c1 = c2 * tri[0] - s1 * tri[1]; s1 = c2 * tri[1] + s1 * tri[0]; } tri += 2; } while (k4 < n); } #endif /* HAVE_XMMINTRIN_H */ ================================================ FILE: app/jni/libmp3lame/version.c ================================================ /* * Version numbering for LAME. * * Copyright (c) 1999 A.L. Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /*! \file version.c \brief Version numbering for LAME. Contains functions which describe the version of LAME. \author A.L. Faber \version \$Id: version.c,v 1.32.2.2 2011/11/18 09:18:28 robert Exp $ \ingroup libmp3lame */ #ifdef HAVE_CONFIG_H # include #endif #include "lame.h" #include "machine.h" #include "version.h" /* macros of version numbers */ /*! Get the LAME version string. */ /*! \param void \return a pointer to a string which describes the version of LAME. */ const char * get_lame_version(void) { /* primary to write screen reports */ /* Here we can also add informations about compile time configurations */ #if LAME_ALPHA_VERSION static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " " "(alpha " STR(LAME_PATCH_VERSION) ", " __DATE__ " " __TIME__ ")"; #elif LAME_BETA_VERSION static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " " "(beta " STR(LAME_PATCH_VERSION) ", " __DATE__ ")"; #elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0) static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION); #else static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION); #endif return str; } /*! Get the short LAME version string. */ /*! It's mainly for inclusion into the MP3 stream. \param void \return a pointer to the short version of the LAME version string. */ const char * get_lame_short_version(void) { /* adding date and time to version string makes it harder for output validation */ #if LAME_ALPHA_VERSION static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " (alpha " STR(LAME_PATCH_VERSION) ")"; #elif LAME_BETA_VERSION static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " (beta " STR(LAME_PATCH_VERSION) ")"; #elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0) static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION); #else static /*@observer@ */ const char *const str = STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION); #endif return str; } /*! Get the _very_ short LAME version string. */ /*! It's used in the LAME VBR tag only. \param void \return a pointer to the short version of the LAME version string. */ const char * get_lame_very_short_version(void) { /* adding date and time to version string makes it harder for output validation */ #if LAME_ALPHA_VERSION #define P "a" #elif LAME_BETA_VERSION #define P "b" #elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0) #define P "r" #else #define P "" #endif static /*@observer@ */ const char *const str = #if (LAME_PATCH_VERSION > 0) "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P STR(LAME_PATCH_VERSION) #else "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P #endif ; return str; } /*! Get the _very_ short LAME version string. */ /*! It's used in the LAME VBR tag only, limited to 9 characters max. Due to some 3rd party HW/SW decoders, it has to start with LAME. \param void \return a pointer to the short version of the LAME version string. */ const char* get_lame_tag_encoder_short_version(void) { static /*@observer@ */ const char *const str = /* FIXME: new scheme / new version counting / drop versioning here ? */ "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P ; return str; } /*! Get the version string for GPSYCHO. */ /*! \param void \return a pointer to a string which describes the version of GPSYCHO. */ const char * get_psy_version(void) { #if PSY_ALPHA_VERSION > 0 static /*@observer@ */ const char *const str = STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION) " (alpha " STR(PSY_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")"; #elif PSY_BETA_VERSION > 0 static /*@observer@ */ const char *const str = STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION) " (beta " STR(PSY_BETA_VERSION) ", " __DATE__ ")"; #else static /*@observer@ */ const char *const str = STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION); #endif return str; } /*! Get the URL for the LAME website. */ /*! \param void \return a pointer to a string which is a URL for the LAME website. */ const char * get_lame_url(void) { static /*@observer@ */ const char *const str = LAME_URL; return str; } /*! Get the numerical representation of the version. */ /*! Writes the numerical representation of the version of LAME and GPSYCHO into lvp. \param lvp */ void get_lame_version_numerical(lame_version_t * lvp) { static /*@observer@ */ const char *const features = ""; /* obsolete */ /* generic version */ lvp->major = LAME_MAJOR_VERSION; lvp->minor = LAME_MINOR_VERSION; #if LAME_ALPHA_VERSION lvp->alpha = LAME_PATCH_VERSION; lvp->beta = 0; #elif LAME_BETA_VERSION lvp->alpha = 0; lvp->beta = LAME_PATCH_VERSION; #else lvp->alpha = 0; lvp->beta = 0; #endif /* psy version */ lvp->psy_major = PSY_MAJOR_VERSION; lvp->psy_minor = PSY_MINOR_VERSION; lvp->psy_alpha = PSY_ALPHA_VERSION; lvp->psy_beta = PSY_BETA_VERSION; /* compile time features */ /*@-mustfree@ */ lvp->features = features; /*@=mustfree@ */ } const char * get_lame_os_bitness(void) { static /*@observer@ */ const char *const strXX = ""; static /*@observer@ */ const char *const str32 = "32bits"; static /*@observer@ */ const char *const str64 = "64bits"; switch (sizeof(void *)) { case 4: return str32; case 8: return str64; default: return strXX; } } /* end of version.c */ ================================================ FILE: app/jni/libmp3lame/version.h ================================================ /* * Version numbering for LAME. * * Copyright (c) 1999 A.L. Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef LAME_VERSION_H #define LAME_VERSION_H /* * To make a string from a token, use the # operator: */ #ifndef STR # define __STR(x) #x # define STR(x) __STR(x) #endif # define LAME_URL "http://lame.sf.net" # define LAME_MAJOR_VERSION 3 /* Major version number */ # define LAME_MINOR_VERSION 99 /* Minor version number */ # define LAME_TYPE_VERSION 2 /* 0:alpha 1:beta 2:release */ # define LAME_PATCH_VERSION 5 /* Patch level */ # define LAME_ALPHA_VERSION (LAME_TYPE_VERSION==0) # define LAME_BETA_VERSION (LAME_TYPE_VERSION==1) # define LAME_RELEASE_VERSION (LAME_TYPE_VERSION==2) # define PSY_MAJOR_VERSION 1 /* Major version number */ # define PSY_MINOR_VERSION 0 /* Minor version number */ # define PSY_ALPHA_VERSION 0 /* Set number if this is an alpha version, otherwise zero */ # define PSY_BETA_VERSION 0 /* Set number if this is a beta version, otherwise zero */ #if LAME_ALPHA_VERSION #define LAME_PATCH_LEVEL_STRING " alpha " STR(LAME_PATCH_VERSION) #endif #if LAME_BETA_VERSION #define LAME_PATCH_LEVEL_STRING " beta " STR(LAME_PATCH_VERSION) #endif #if LAME_RELEASE_VERSION #if LAME_PATCH_VERSION #define LAME_PATCH_LEVEL_STRING " release " STR(LAME_PATCH_VERSION) #else #define LAME_PATCH_LEVEL_STRING "" #endif #endif # define LAME_VERSION_STRING STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) LAME_PATCH_LEVEL_STRING #endif /* LAME_VERSION_H */ /* End of version.h */ ================================================ FILE: app/jni/silk.c ================================================ // // Created by ketian on 16-9-23. // #include "silk.h" #ifdef _WIN32 #define _CRT_SECURE_NO_DEPRECATE 1 #endif #include #include #include #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_SigProc_FIX.h" /* Define codec specific settings should be moved to h file */ #define MAX_BYTES_PER_FRAME 1024 #define MAX_INPUT_FRAMES 5 #define MAX_FRAME_LENGTH 480 #define FRAME_LENGTH_MS 20 #define MAX_API_FS_KHZ 48 #define MAX_LBRR_DELAY 2 #ifdef _SYSTEM_IS_BIG_ENDIAN /* Function to convert a little endian int16 to a */ /* big endian int16 or vica verca */ void swap_endian( SKP_int16 vec[], SKP_int len ) { SKP_int i; SKP_int16 tmp; SKP_uint8 *p1, *p2; for( i = 0; i < len; i++ ){ tmp = vec[ i ]; p1 = (SKP_uint8 *)&vec[ i ]; p2 = (SKP_uint8 *)&tmp; p1[ 0 ] = p2[ 1 ]; p1[ 1 ] = p2[ 0 ]; } } #endif #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else // Linux or Mac #include #endif #ifdef _WIN32 unsigned long GetHighResolutionTime() /* O: time in usec*/ { /* Returns a time counter in microsec */ /* the resolution is platform dependent */ /* but is typically 1.62 us resolution */ LARGE_INTEGER lpPerformanceCount; LARGE_INTEGER lpFrequency; QueryPerformanceCounter(&lpPerformanceCount); QueryPerformanceFrequency(&lpFrequency); return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart); } #else // Linux or Mac unsigned long GetHighResolutionTime() /* O: time in usec*/ { struct timeval tv; gettimeofday(&tv, 0); return((tv.tv_sec*1000000)+(tv.tv_usec)); } #endif // _WIN32 /* Seed for the random number generator, which is used for simulating packet loss */ static SKP_int32 rand_seed = 1; int convertSilk2PCM(const char* src, const FILE* destFile) { unsigned long tottime, starttime; double filetime; size_t counter; SKP_int32 args, totPackets, i, k; SKP_int16 ret, len, tot_len; SKP_int16 nBytes; SKP_uint8 payload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ]; SKP_uint8 *payloadEnd = NULL, *payloadToDec = NULL; SKP_uint8 FECpayload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ], *payloadPtr; SKP_int16 nBytesFEC; SKP_int16 nBytesPerPacket[ MAX_LBRR_DELAY + 1 ], totBytes; SKP_int16 out[ ( ( FRAME_LENGTH_MS * MAX_API_FS_KHZ ) << 1 ) * MAX_INPUT_FRAMES ], *outPtr; char bitInFileName[ 150 ]; FILE *bitInFile, *speechOutFile; SKP_int32 packetSize_ms=0, API_Fs_Hz = 0; SKP_int32 decSizeBytes; void *psDec; SKP_float loss_prob; SKP_int32 frames, lost, quiet; SKP_SILK_SDK_DecControlStruct DecControl; strcpy( bitInFileName, src ); if( !quiet ) { printf("********** Silk Decoder (Fixed Point) v %s ********************\n", SKP_Silk_SDK_get_version()); printf("********** Compiled for %d bit cpu *******************************\n", (int)sizeof(void*) * 8 ); printf( "Input: %s\n", bitInFileName ); } /* Open files */ bitInFile = fopen( bitInFileName, "rb" ); if( bitInFile == NULL ) { printf( "Error: could not open input file %s\n", bitInFileName ); exit( 0 ); } /* Check Silk header */ { char header_buf[50]; fseek(bitInFile, 1, SEEK_SET); counter = fread(header_buf, sizeof(char), strlen("#!SILK_V3"), bitInFile); header_buf[strlen("#!SILK_V3")] = '\0'; /* Terminate with a null character */ if (strcmp(header_buf, "#!SILK_V3") == 0) { } else { fseek(bitInFile, 0, SEEK_SET); counter = fread(header_buf, sizeof(char), strlen("#!SILK_V3"), bitInFile); header_buf[strlen("#!SILK_V3")] = '\0'; /* Terminate with a null character */ if (strcmp(header_buf, "#!SILK_V3") != 0) { /* Non-equal strings */ exit(0); } } } speechOutFile = (FILE *) destFile; if( speechOutFile == NULL ) { exit( 0 ); } /* Set the samplingrate that is requested for the output */ DecControl.API_sampleRate = 24000; /* Initialize to one frame per packet, for proper concealment before first packet arrives */ DecControl.framesPerPacket = 1; /* Create decoder */ ret = (short) SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes ); if( ret ) { printf( "\nSKP_Silk_SDK_Get_Decoder_Size returned %d", ret ); } psDec = malloc((size_t) decSizeBytes); /* Reset decoder */ ret = (short) SKP_Silk_SDK_InitDecoder(psDec ); if( ret ) { printf( "\nSKP_Silk_InitDecoder returned %d", ret ); } totPackets = 0; tottime = 0; payloadEnd = payload; /* Simulate the jitter buffer holding MAX_FEC_DELAY packets */ for( i = 0; i < MAX_LBRR_DELAY; i++ ) { /* Read payload size */ counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile ); #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( &nBytes, 1 ); #endif /* Read payload */ counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile ); if( ( SKP_int16 )counter < nBytes ) { break; } nBytesPerPacket[ i ] = nBytes; payloadEnd += nBytes; totPackets++; } while( 1 ) { /* Read payload size */ counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile ); #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( &nBytes, 1 ); #endif if( nBytes < 0 || counter < 1 ) { break; } /* Read payload */ counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile ); if( ( SKP_int16 )counter < nBytes ) { break; } /* Simulate losses */ rand_seed = SKP_RAND( rand_seed ); if( ( ( ( float )( ( rand_seed >> 16 ) + ( 1 << 15 ) ) ) / 65535.0f >= ( loss_prob / 100.0f ) ) && ( counter > 0 ) ) { nBytesPerPacket[ MAX_LBRR_DELAY ] = nBytes; payloadEnd += nBytes; } else { nBytesPerPacket[ MAX_LBRR_DELAY ] = 0; } if( nBytesPerPacket[ 0 ] == 0 ) { /* Indicate lost packet */ lost = 1; /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */ payloadPtr = payload; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { if( nBytesPerPacket[ i + 1 ] > 0 ) { starttime = GetHighResolutionTime(); SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC ); tottime += GetHighResolutionTime() - starttime; if( nBytesFEC > 0 ) { payloadToDec = FECpayload; nBytes = nBytesFEC; lost = 0; break; } } payloadPtr += nBytesPerPacket[ i + 1 ]; } } else { lost = 0; nBytes = nBytesPerPacket[ 0 ]; payloadToDec = payload; } /* Silk decoder */ outPtr = out; tot_len = 0; starttime = GetHighResolutionTime(); if( lost == 0 ) { /* No Loss: Decode all frames in the packet */ frames = 0; do { /* Decode 20 ms */ ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_SDK_Decode returned %d", ret ); } frames++; outPtr += len; tot_len += len; if( frames > MAX_INPUT_FRAMES ) { /* Hack for corrupt stream that could generate too many frames */ outPtr = out; tot_len = 0; frames = 0; } /* Until last 20 ms frame of packet has been decoded */ } while( DecControl.moreInternalDecoderFrames ); } else { /* Loss: Decode enough frames to cover one packet duration */ for( i = 0; i < DecControl.framesPerPacket; i++ ) { /* Generate 20 ms */ ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_Decode returned %d", ret ); } outPtr += len; tot_len += len; } } packetSize_ms = tot_len / ( DecControl.API_sampleRate / 1000 ); tottime += GetHighResolutionTime() - starttime; totPackets++; /* Write output to file */ #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( out, tot_len ); #endif fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile ); /* Update buffer */ totBytes = 0; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { totBytes += nBytesPerPacket[ i + 1 ]; } SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) ); payloadEnd -= nBytesPerPacket[ 0 ]; SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) ); } /* Empty the recieve buffer */ for( k = 0; k < MAX_LBRR_DELAY; k++ ) { if( nBytesPerPacket[ 0 ] == 0 ) { /* Indicate lost packet */ lost = 1; /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */ payloadPtr = payload; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { if( nBytesPerPacket[ i + 1 ] > 0 ) { starttime = GetHighResolutionTime(); SKP_Silk_SDK_search_for_LBRR( payloadPtr, nBytesPerPacket[ i + 1 ], ( i + 1 ), FECpayload, &nBytesFEC ); tottime += GetHighResolutionTime() - starttime; if( nBytesFEC > 0 ) { payloadToDec = FECpayload; nBytes = nBytesFEC; lost = 0; break; } } payloadPtr += nBytesPerPacket[ i + 1 ]; } } else { lost = 0; nBytes = nBytesPerPacket[ 0 ]; payloadToDec = payload; } /* Silk decoder */ outPtr = out; tot_len = 0; starttime = GetHighResolutionTime(); if( lost == 0 ) { /* No loss: Decode all frames in the packet */ frames = 0; do { /* Decode 20 ms */ ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_SDK_Decode returned %d", ret ); } frames++; outPtr += len; tot_len += len; if( frames > MAX_INPUT_FRAMES ) { /* Hack for corrupt stream that could generate too many frames */ outPtr = out; tot_len = 0; frames = 0; } /* Until last 20 ms frame of packet has been decoded */ } while( DecControl.moreInternalDecoderFrames ); } else { /* Loss: Decode enough frames to cover one packet duration */ /* Generate 20 ms */ for( i = 0; i < DecControl.framesPerPacket; i++ ) { ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_Decode returned %d", ret ); } outPtr += len; tot_len += len; } } packetSize_ms = tot_len / ( DecControl.API_sampleRate / 1000 ); tottime += GetHighResolutionTime() - starttime; totPackets++; /* Write output to file */ #ifdef _SYSTEM_IS_BIG_ENDIAN swap_endian( out, tot_len ); #endif fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile ); /* Update Buffer */ totBytes = 0; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { totBytes += nBytesPerPacket[ i + 1 ]; } SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) ); payloadEnd -= nBytesPerPacket[ 0 ]; SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) ); } /* Free decoder */ free( psDec ); /* Close files */ fclose( bitInFile ); filetime = totPackets * 1e-3 * packetSize_ms; if( !quiet ) { printf("\nFile length: %.3f s", filetime); printf("\nTime for decoding: %.3f s (%.3f%% of realtime)", 1e-6 * tottime, 1e-4 * tottime / filetime); printf("\n\n"); } else { /* print time and % of realtime */ printf( "%.3f %.3f %d\n", 1e-6 * tottime, 1e-4 * tottime / filetime, totPackets ); } return 0; } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /home/ketian/tools/adt-bundle-linux-x86_64-20140702/sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/java/com/ketian/android/silkv3/App.kt ================================================ package com.ketian.android.silkv3 import android.app.Application /** * Created by ketian. */ class App : Application() { override fun onCreate() { super.onCreate() } } ================================================ FILE: app/src/main/java/com/ketian/android/silkv3/ExportFragment.kt ================================================ package com.ketian.android.silkv3 import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup /** * Created by ketian. */ class ExportFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_export, container, false) } } ================================================ FILE: app/src/main/java/com/ketian/android/silkv3/MainActivity.kt ================================================ package com.ketian.android.silkv3 import android.Manifest import android.content.pm.PackageManager import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentPagerAdapter import kotlinx.android.synthetic.main.activity_main.* import java.util.* class MainActivity : AppCompatActivity() { private var mPagerAdapter: PagerAdapter? = null private var mFragments: MutableList? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) hint.text="" if (getPermission()) { initFragments() mPagerAdapter = PagerAdapter(supportFragmentManager) pager.adapter = mPagerAdapter } } fun getPermission(): Boolean { val permissionCheck1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); val permissionCheck2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE), 124) return false } return true } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 124) { if ((grantResults.isNotEmpty()) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { initFragments() mPagerAdapter = PagerAdapter(supportFragmentManager) pager.adapter = mPagerAdapter } } } private fun initFragments() { mFragments = ArrayList(2) mFragments?.add(VoiceFragment()) mFragments?.add(ExportFragment()) } fun wechatVoiceDecodeResult(rlt: Int, dest: String) { when(rlt){ 0->{ hint.text="参数有误" Toast.makeText(this, "参数有误", Toast.LENGTH_SHORT).show() } 1->{ hint.text="转换成功,恭喜你成功扒了微信的底裤" Toast.makeText(this, "Convert to $dest OK", Toast.LENGTH_SHORT).show() } else->{} } } private inner class PagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) { override fun getItem(position: Int): Fragment? { return mFragments?.get(position) } override fun getCount(): Int { return mFragments?.size ?: 0 } } } ================================================ FILE: app/src/main/java/com/ketian/android/silkv3/PathUtils.kt ================================================ package com.ketian.android.silkv3 import android.content.Context import android.os.Environment import android.util.Log import java.io.File import java.util.* /** * Created by ketian. */ class PathUtils private constructor(context: Context) { var exportDir: String? = null private set var voice_wechat_paths: MutableList var voice_qq_paths: List init { context.toString() voice_wechat_paths = ArrayList() voice_qq_paths = ArrayList() if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) { Log.e("doInBackground","哪个快?") val dir = Environment.getExternalStorageDirectory() val f = File("${dir.path}/tencent/MicroMsg/") var interrupt = false if (f.exists() && f.isDirectory) { val files = f.listFiles() if (files != null && files.isNotEmpty()) { for (f0 in files) { if (f0.isDirectory && f0.name.length > 24) { voice_wechat_paths.add(f0.absolutePath + "/voice2") } } } else { interrupt = true } } if (!interrupt) { val exportDir = File(dir, "silkv3_mp3") if (!exportDir.exists()) { exportDir.mkdirs() } this.exportDir = exportDir.absolutePath } } } companion object { private var instance: PathUtils? = null private fun createUtil(context: Context): PathUtils { if (instance == null) { instance = PathUtils(context) } return instance!! } fun getVoiceFiles_WeChat(context: Context): List { return createUtil(context).voice_wechat_paths } fun getVoiceFiles_QQ(context: Context): List { return createUtil(context).voice_qq_paths } fun getExportDir(context: Context): String? { return createUtil(context).exportDir } } } ================================================ FILE: app/src/main/java/com/ketian/android/silkv3/VoiceFragment.kt ================================================ package com.ketian.android.silkv3 import android.content.Context import android.os.AsyncTask import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.TextView import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.ketian.android.silkv3.jni.JNI import kotlinx.android.synthetic.main.fragment_voice.* import java.io.File import java.util.* /** * Created by ketian. */ class VoiceFragment : Fragment() { private var mTask: LoadTask? = null private var mAdapter: ItemAdapter? = null private val mItems = ArrayList() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_voice, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) recycler_view.apply { layoutManager = LinearLayoutManager(this.context) adapter = ItemAdapter(requireContext(), mItems).apply { mAdapter = this } initData() } } private fun initData() { mTask?.cancel(true) mTask = LoadTask(requireContext()) mTask?.execute() } private inner class LoadTask(private val mContext: Context) : AsyncTask>() { override fun onPreExecute() { } override fun doInBackground(vararg voids: Void): List { val paths = PathUtils.getVoiceFiles_WeChat(mContext) Log.e("doInBackground", "${paths}") val voicePaths = ArrayList() if (paths.size > 0) { var file: File? for (path in paths) { file = File(path) if (file.exists() && file.isDirectory) { val stack = Stack() stack.push(path) while (!stack.empty()) { var fs: Array? = null val parent = stack.pop() if (parent != null) { file = File(parent) if (file.isDirectory) { // ignore file, FIXME fs = file.listFiles() } else { continue } } if (fs == null || fs.isEmpty()) continue for (i in fs.indices) { val name = fs[i].name if (fs[i].isDirectory && name != "." && name != "..") { stack.push(fs[i].path) } else if (fs[i].isFile) { if (name.endsWith(".amr")) { voicePaths.add(fs[i].absolutePath) } } } } } } } return voicePaths } override fun onPostExecute(strings: List) { mItems.clear() mItems.addAll(strings) mAdapter?.notifyDataSetChanged() } } override fun onDestroy() { super.onDestroy() if (mTask != null) { mTask!!.cancel(true) } } private class ItemAdapter(private val mContext: Context, private val paths: List?) : RecyclerView.Adapter() { private val listener = View.OnClickListener { view -> val index = view.tag as Int val path = paths?.get(index) ?: return@OnClickListener val file = File(path) if (file.exists() && file.canRead()) { val dest = PathUtils.getExportDir(mContext) + "/" + file.name + ".mp3" val temp = PathUtils.getExportDir(mContext) + "/temp_" + file.name + ".mp3" val rlt = JNI.convert(path, dest, temp) (mContext as? MainActivity)?.wechatVoiceDecodeResult(rlt,dest) } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemAdapter.VH { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false) return VH(view) } override fun onBindViewHolder(holder: ItemAdapter.VH, position: Int) { holder.textView.text = paths!![position] holder.button.tag = position holder.button.setOnClickListener(listener) } override fun getItemCount(): Int { return paths?.size ?: 0 } class VH(itemView: View) : RecyclerView.ViewHolder(itemView) { var textView: TextView var button: Button init { textView = itemView.findViewById(R.id.title) as TextView button = itemView.findViewById(R.id.click) as Button } } } } ================================================ FILE: app/src/main/java/com/ketian/android/silkv3/jni/JNI.kt ================================================ package com.ketian.android.silkv3.jni /** * Created by ketian on 16-10-10. */ object JNI { init { System.loadLibrary("silkx") } external fun convert(src: String, dest: String, tmpfile: String): Int } ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: app/src/main/res/layout/export_item_layout.xml ================================================ ================================================ FILE: app/src/main/res/layout/fragment_export.xml ================================================ ================================================ FILE: app/src/main/res/layout/fragment_voice.xml ================================================ ================================================ FILE: app/src/main/res/layout/item_layout.xml ================================================