summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--Android.mk1
-rwxr-xr-xamadec/Android.mk282
-rw-r--r--amadec/acodec_lib_50/libstagefright_soft_dcvdec.so80
-rw-r--r--amadec/acodec_lib_50/libstagefright_soft_dtshd.so85
-rw-r--r--amadec/acodec_lib_50/libstagefright_soft_truehddec.so41
-rw-r--r--amadec/acodec_lib_android_n/libstagefright_soft_dcvdec.so109
-rw-r--r--amadec/acodec_lib_android_n/libstagefright_soft_dtshd.so272
-rw-r--r--amadec/acodec_lib_android_n/libstagefright_soft_truehddec.so87
-rwxr-xr-xamadec/acodec_lib_mx/libstagefright_soft_ddpdec.so113
-rwxr-xr-xamadec/acodec_lib_mx/libstagefright_soft_dtshd.so121
-rw-r--r--amadec/adec-armdec-mgt.h57
-rw-r--r--amadec/adec-external-ctrl.c899
-rw-r--r--amadec/adec-ffmpeg-mgt.c1550
-rw-r--r--amadec/adec-internal-mgt.c772
-rw-r--r--amadec/adec-message.c156
-rw-r--r--amadec/adec-message.h61
-rwxr-xr-xamadec/adec-pts-mgt.c1107
-rw-r--r--amadec/adec-pts-mgt.h82
-rw-r--r--amadec/adec-wfd-out.cpp361
-rw-r--r--amadec/adec-wfd.c811
-rw-r--r--amadec/adec_omx_brige.c284
-rw-r--r--amadec/adec_omx_brige.h56
-rw-r--r--amadec/adec_read.c200
-rw-r--r--amadec/adec_reg.h76
-rw-r--r--amadec/adec_write.c189
-rw-r--r--amadec/adec_write.h42
-rw-r--r--amadec/audio-dec.h314
-rw-r--r--amadec/audio_out/alsa-out.c1082
-rw-r--r--amadec/audio_out/aml_resample.c708
-rw-r--r--amadec/audio_out/aml_resample.h86
-rwxr-xr-xamadec/audio_out/android-out.cpp1640
-rw-r--r--amadec/audiodsp_update_format.c188
-rw-r--r--amadec/dsp/audiodsp-ctl.c471
-rw-r--r--amadec/dts_enc.c209
-rw-r--r--amadec/dts_enc.h11
-rw-r--r--amadec/dts_transenc_api.c143
-rw-r--r--amadec/dts_transenc_api.h19
-rw-r--r--amadec/feeder.c231
-rw-r--r--amadec/feeder.h26
-rw-r--r--amadec/include/adec-external-ctrl.h63
-rwxr-xr-xamadec/include/adec-macros.h41
-rw-r--r--amadec/include/adec-types.h53
-rwxr-xr-xamadec/include/alsa-out.h26
-rw-r--r--amadec/include/audio-out.h41
-rw-r--r--amadec/include/audiodsp.h142
-rw-r--r--amadec/include/audiodsp_update_format.h25
-rw-r--r--amadec/include/log-print.h26
-rwxr-xr-xamadec/omx_audio/ALAC_mediasource.cpp205
-rw-r--r--amadec/omx_audio/ALAC_mediasource.h62
-rwxr-xr-xamadec/omx_audio/ASF_mediasource.cpp184
-rw-r--r--amadec/omx_audio/ASF_mediasource.h127
-rwxr-xr-xamadec/omx_audio/Android.mk34
-rwxr-xr-xamadec/omx_audio/DDP_mediasource.cpp528
-rw-r--r--amadec/omx_audio/DDP_mediasource.h141
-rw-r--r--amadec/omx_audio/DTSHD_mediasource.cpp316
-rw-r--r--amadec/omx_audio/DTSHD_mediasource.h74
-rwxr-xr-xamadec/omx_audio/MP3_mediasource.cpp579
-rw-r--r--amadec/omx_audio/MP3_mediasource.h80
-rw-r--r--amadec/omx_audio/THD_mediasource.cpp229
-rw-r--r--amadec/omx_audio/THD_mediasource.h74
-rwxr-xr-xamadec/omx_audio/Vorbis_mediasource.cpp245
-rw-r--r--amadec/omx_audio/Vorbis_mediasource.h58
-rw-r--r--amadec/omx_audio/adec_omx.cpp421
-rw-r--r--amadec/omx_audio/adec_omx.h71
-rwxr-xr-xamadec/omx_audio/audio_mediasource.cpp37
-rw-r--r--amadec/omx_audio/audio_mediasource.h46
-rw-r--r--amadec/omx_audio/audio_medissource.h137
-rw-r--r--amadec/pcmenc_api.c147
-rw-r--r--amadec/pcmenc_api.h25
-rw-r--r--amadec/spdif_api.c306
-rw-r--r--amadec/spdif_api.h26
-rwxr-xr-xaudio_codec/Android.mk1
-rw-r--r--audio_codec/config.mk10
-rwxr-xr-xaudio_codec/libadpcm/Android.mk12
-rw-r--r--audio_codec/libadpcm/adpcm.h346
-rw-r--r--audio_codec/libadpcm/adpcm_decode.c841
-rwxr-xr-xaudio_codec/libamr/Android.mk25
-rwxr-xr-xaudio_codec/libamr/Makefile5
-rw-r--r--audio_codec/libamr/amr_decode.c186
-rw-r--r--audio_codec/libamr/amr_decode.h8
-rwxr-xr-xaudio_codec/libamr/dec.h18
-rw-r--r--audio_codec/libamr/dec_acelp.c620
-rwxr-xr-xaudio_codec/libamr/dec_acelp.h17
-rw-r--r--audio_codec/libamr/dec_dtx.c683
-rw-r--r--audio_codec/libamr/dec_dtx.h49
-rw-r--r--audio_codec/libamr/dec_gain.c853
-rw-r--r--audio_codec/libamr/dec_gain.h28
-rw-r--r--audio_codec/libamr/dec_if.c834
-rwxr-xr-xaudio_codec/libamr/dec_if.h23
-rw-r--r--audio_codec/libamr/dec_lpc.c789
-rw-r--r--audio_codec/libamr/dec_lpc.h25
-rw-r--r--audio_codec/libamr/dec_main.c842
-rw-r--r--audio_codec/libamr/dec_main.h57
-rw-r--r--audio_codec/libamr/dec_rom.c2114
-rw-r--r--audio_codec/libamr/dec_util.c1304
-rw-r--r--audio_codec/libamr/dec_util.h33
-rw-r--r--audio_codec/libamr/if_rom.c1030
-rwxr-xr-xaudio_codec/libamr/if_rom.h70
-rw-r--r--audio_codec/libamr/interf_dec.c906
-rw-r--r--audio_codec/libamr/interf_dec.h56
-rw-r--r--audio_codec/libamr/interf_rom.h1788
-rw-r--r--audio_codec/libamr/rom_dec.h13274
-rw-r--r--audio_codec/libamr/sp_dec.c6078
-rw-r--r--audio_codec/libamr/sp_dec.h83
-rwxr-xr-xaudio_codec/libamr/typedef.h17
-rwxr-xr-xaudio_codec/libape/Android.mk28
-rw-r--r--audio_codec/libape/Ape_decoder.h216
-rw-r--r--audio_codec/libape/amlogic_r30813_audio_ape_lib.c1
-rw-r--r--audio_codec/libape/apedec.c1120
-rw-r--r--audio_codec/libcook/Android.mk28
-rw-r--r--audio_codec/libcook/aac_bitstream.h133
-rw-r--r--audio_codec/libcook/aac_decode.h148
-rw-r--r--audio_codec/libcook/aac_reorder.h53
-rw-r--r--audio_codec/libcook/assembly.h119
-rw-r--r--audio_codec/libcook/challenge.h132
-rw-r--r--audio_codec/libcook/codec_defines.h93
-rw-r--r--audio_codec/libcook/coder.h287
-rw-r--r--audio_codec/libcook/cook_codec.h30
-rw-r--r--audio_codec/libcook/cook_decode.c624
-rw-r--r--audio_codec/libcook/cook_decode.h35
-rw-r--r--audio_codec/libcook/ga_config.h86
-rw-r--r--audio_codec/libcook/gecko2codec.c833
-rw-r--r--audio_codec/libcook/gecko2codec.h60
-rw-r--r--audio_codec/libcook/helix_config.h92
-rw-r--r--audio_codec/libcook/helix_mime_types.h56
-rw-r--r--audio_codec/libcook/helix_result.h107
-rw-r--r--audio_codec/libcook/helix_types.h305
-rw-r--r--audio_codec/libcook/helix_utils.h106
-rw-r--r--audio_codec/libcook/md5.h113
-rw-r--r--audio_codec/libcook/memory_utils.c100
-rw-r--r--audio_codec/libcook/memory_utils.h58
-rw-r--r--audio_codec/libcook/pack_utils.c306
-rw-r--r--audio_codec/libcook/pack_utils.h93
-rw-r--r--audio_codec/libcook/packet_defines.h48
-rw-r--r--audio_codec/libcook/ra8lbr_decode.c378
-rw-r--r--audio_codec/libcook/ra8lbr_decode.h161
-rw-r--r--audio_codec/libcook/ra_backend.h94
-rw-r--r--audio_codec/libcook/ra_bitpack.c197
-rw-r--r--audio_codec/libcook/ra_buffers.c127
-rw-r--r--audio_codec/libcook/ra_category.c298
-rw-r--r--audio_codec/libcook/ra_couple.c224
-rw-r--r--audio_codec/libcook/ra_decode.c321
-rw-r--r--audio_codec/libcook/ra_decode.h183
-rw-r--r--audio_codec/libcook/ra_depack.c230
-rw-r--r--audio_codec/libcook/ra_depack.h177
-rw-r--r--audio_codec/libcook/ra_depack_internal.c1710
-rw-r--r--audio_codec/libcook/ra_depack_internal.h232
-rw-r--r--audio_codec/libcook/ra_envelope.c123
-rw-r--r--audio_codec/libcook/ra_fft.c368
-rw-r--r--audio_codec/libcook/ra_format_info.h60
-rw-r--r--audio_codec/libcook/ra_gainctrl.c584
-rw-r--r--audio_codec/libcook/ra_huffman.c86
-rw-r--r--audio_codec/libcook/ra_hufftabs.c244
-rw-r--r--audio_codec/libcook/ra_mlt.c357
-rw-r--r--audio_codec/libcook/ra_sqvh.c431
-rw-r--r--audio_codec/libcook/ra_trigtabs.c932
-rw-r--r--audio_codec/libcook/rasl.c376
-rw-r--r--audio_codec/libcook/rasl.h71
-rw-r--r--audio_codec/libcook/rdtpck.h153
-rw-r--r--audio_codec/libcook/rm_error.h54
-rw-r--r--audio_codec/libcook/rm_error_default.c58
-rw-r--r--audio_codec/libcook/rm_error_default.h53
-rw-r--r--audio_codec/libcook/rm_io_default.c101
-rw-r--r--audio_codec/libcook/rm_io_default.h49
-rw-r--r--audio_codec/libcook/rm_memory.h54
-rw-r--r--audio_codec/libcook/rm_memory_default.c54
-rw-r--r--audio_codec/libcook/rm_memory_default.h46
-rw-r--r--audio_codec/libcook/rm_packet.c117
-rw-r--r--audio_codec/libcook/rm_packet.h80
-rw-r--r--audio_codec/libcook/rm_parse.h302
-rw-r--r--audio_codec/libcook/rm_parser.c649
-rw-r--r--audio_codec/libcook/rm_parser_internal.c3342
-rw-r--r--audio_codec/libcook/rm_parser_internal.h420
-rw-r--r--audio_codec/libcook/rm_property.c105
-rw-r--r--audio_codec/libcook/rm_property.h107
-rw-r--r--audio_codec/libcook/rm_stream.c356
-rw-r--r--audio_codec/libcook/rm_stream.h115
-rw-r--r--audio_codec/libcook/rm_stream_internal.h77
-rw-r--r--audio_codec/libcook/rv20backend.h69
-rw-r--r--audio_codec/libcook/rv30backend.h68
-rw-r--r--audio_codec/libcook/rv_backend.h84
-rw-r--r--audio_codec/libcook/rv_backend_types.h198
-rw-r--r--audio_codec/libcook/rv_decode.h208
-rw-r--r--audio_codec/libcook/rv_decode_message.h492
-rw-r--r--audio_codec/libcook/rv_depack.c271
-rw-r--r--audio_codec/libcook/rv_depack.h162
-rw-r--r--audio_codec/libcook/rv_depack_internal.c1071
-rw-r--r--audio_codec/libcook/rv_depack_internal.h171
-rw-r--r--audio_codec/libcook/rv_format_info.h91
-rw-r--r--audio_codec/libcook/statname.h118
-rw-r--r--audio_codec/libcook/stream_hdr_structs.h66
-rw-r--r--audio_codec/libcook/stream_hdr_utils.c136
-rw-r--r--audio_codec/libcook/stream_hdr_utils.h77
-rw-r--r--audio_codec/libcook/string_utils.c87
-rw-r--r--audio_codec/libcook/string_utils.h62
-rw-r--r--audio_codec/libcook/tngpkt.h400
-rwxr-xr-xaudio_codec/libfaad/Android.mk101
-rwxr-xr-xaudio_codec/libfaad/Makefile130
-rw-r--r--audio_codec/libfaad/analysis.h52
-rwxr-xr-xaudio_codec/libfaad/audio.d3
-rw-r--r--audio_codec/libfaad/bits.c261
-rwxr-xr-xaudio_codec/libfaad/bits.d18
-rw-r--r--audio_codec/libfaad/bits.h446
-rw-r--r--audio_codec/libfaad/cfft.c988
-rw-r--r--audio_codec/libfaad/cfft.h55
-rw-r--r--audio_codec/libfaad/cfft_tab.h1816
-rw-r--r--audio_codec/libfaad/codebook/hcb.h140
-rw-r--r--audio_codec/libfaad/codebook/hcb_1.h186
-rw-r--r--audio_codec/libfaad/codebook/hcb_10.h312
-rw-r--r--audio_codec/libfaad/codebook/hcb_11.h415
-rw-r--r--audio_codec/libfaad/codebook/hcb_2.h185
-rw-r--r--audio_codec/libfaad/codebook/hcb_3.h196
-rw-r--r--audio_codec/libfaad/codebook/hcb_4.h199
-rw-r--r--audio_codec/libfaad/codebook/hcb_5.h196
-rw-r--r--audio_codec/libfaad/codebook/hcb_6.h182
-rw-r--r--audio_codec/libfaad/codebook/hcb_7.h162
-rw-r--r--audio_codec/libfaad/codebook/hcb_8.h173
-rw-r--r--audio_codec/libfaad/codebook/hcb_9.h372
-rw-r--r--audio_codec/libfaad/codebook/hcb_sf.h276
-rw-r--r--audio_codec/libfaad/common.c558
-rw-r--r--audio_codec/libfaad/common.h453
-rw-r--r--audio_codec/libfaad/decoder.c2266
-rw-r--r--audio_codec/libfaad/drc.c173
-rw-r--r--audio_codec/libfaad/drc.h49
-rw-r--r--audio_codec/libfaad/drm_dec.c912
-rw-r--r--audio_codec/libfaad/drm_dec.h99
-rw-r--r--audio_codec/libfaad/error.c72
-rw-r--r--audio_codec/libfaad/error.h44
-rw-r--r--audio_codec/libfaad/filtbank.c408
-rw-r--r--audio_codec/libfaad/filtbank.h61
-rw-r--r--audio_codec/libfaad/fixed.h287
-rw-r--r--audio_codec/libfaad/hcr.c422
-rw-r--r--audio_codec/libfaad/helixaac/aaccommon.h210
-rw-r--r--audio_codec/libfaad/helixaac/aacdec.c508
-rw-r--r--audio_codec/libfaad/helixaac/aacdec.h206
-rw-r--r--audio_codec/libfaad/helixaac/aactabs.c157
-rw-r--r--audio_codec/libfaad/helixaac/assembly.h631
-rw-r--r--audio_codec/libfaad/helixaac/assembly_mw.h743
-rw-r--r--audio_codec/libfaad/helixaac/bitstream.c261
-rw-r--r--audio_codec/libfaad/helixaac/bitstream.h74
-rw-r--r--audio_codec/libfaad/helixaac/buffers.c140
-rw-r--r--audio_codec/libfaad/helixaac/coder.h369
-rw-r--r--audio_codec/libfaad/helixaac/dct4.c337
-rw-r--r--audio_codec/libfaad/helixaac/decelmnt.c445
-rw-r--r--audio_codec/libfaad/helixaac/dequant.c379
-rw-r--r--audio_codec/libfaad/helixaac/fft.c391
-rw-r--r--audio_codec/libfaad/helixaac/filefmt.c539
-rw-r--r--audio_codec/libfaad/helixaac/huffman_helix.c450
-rw-r--r--audio_codec/libfaad/helixaac/hufftabs.c177
-rw-r--r--audio_codec/libfaad/helixaac/imdct.c596
-rw-r--r--audio_codec/libfaad/helixaac/noiseless.c513
-rw-r--r--audio_codec/libfaad/helixaac/pns_helix.c371
-rw-r--r--audio_codec/libfaad/helixaac/sbr.c433
-rw-r--r--audio_codec/libfaad/helixaac/sbr.h380
-rw-r--r--audio_codec/libfaad/helixaac/sbrfft.c368
-rw-r--r--audio_codec/libfaad/helixaac/sbrfreq.c673
-rw-r--r--audio_codec/libfaad/helixaac/sbrhfadj.c882
-rw-r--r--audio_codec/libfaad/helixaac/sbrhfgen.c655
-rw-r--r--audio_codec/libfaad/helixaac/sbrhuff.c494
-rw-r--r--audio_codec/libfaad/helixaac/sbrimdct.c447
-rw-r--r--audio_codec/libfaad/helixaac/sbrmath.c198
-rw-r--r--audio_codec/libfaad/helixaac/sbrqmf.c648
-rw-r--r--audio_codec/libfaad/helixaac/sbrside.c634
-rw-r--r--audio_codec/libfaad/helixaac/sbrtabs.c400
-rw-r--r--audio_codec/libfaad/helixaac/statname.h115
-rw-r--r--audio_codec/libfaad/helixaac/stproc.c251
-rw-r--r--audio_codec/libfaad/helixaac/tns_helix.c307
-rw-r--r--audio_codec/libfaad/helixaac/trigtabs.c1000
-rw-r--r--audio_codec/libfaad/helixaac/trigtabs_fltgen.c357
-rw-r--r--audio_codec/libfaad/huffman.c582
-rw-r--r--audio_codec/libfaad/huffman.h47
-rw-r--r--audio_codec/libfaad/ic_predict.c258
-rw-r--r--audio_codec/libfaad/ic_predict.h252
-rw-r--r--audio_codec/libfaad/iq_table.h16456
-rw-r--r--audio_codec/libfaad/is.c106
-rw-r--r--audio_codec/libfaad/is.h67
-rw-r--r--audio_codec/libfaad/kbd_win.h2294
-rw-r--r--audio_codec/libfaad/libaacdec.c544
-rw-r--r--audio_codec/libfaad/libaacdec.h64
-rwxr-xr-xaudio_codec/libfaad/libfaad2.def14
-rw-r--r--audio_codec/libfaad/lt_predict.c205
-rw-r--r--audio_codec/libfaad/lt_predict.h66
-rw-r--r--audio_codec/libfaad/mdct.c307
-rw-r--r--audio_codec/libfaad/mdct.h48
-rw-r--r--audio_codec/libfaad/mdct_tab.h3639
-rw-r--r--audio_codec/libfaad/mp4.c307
-rw-r--r--audio_codec/libfaad/mp4.h52
-rw-r--r--audio_codec/libfaad/ms.c71
-rw-r--r--audio_codec/libfaad/ms.h44
-rw-r--r--audio_codec/libfaad/neaacdec.h257
-rw-r--r--audio_codec/libfaad/output.c583
-rw-r--r--audio_codec/libfaad/output.h48
-rw-r--r--audio_codec/libfaad/pns.c273
-rw-r--r--audio_codec/libfaad/pns.h58
-rw-r--r--audio_codec/libfaad/ps_dec.c1905
-rw-r--r--audio_codec/libfaad/ps_dec.h151
-rw-r--r--audio_codec/libfaad/ps_syntax.c532
-rw-r--r--audio_codec/libfaad/ps_tables.h547
-rw-r--r--audio_codec/libfaad/pulse.c59
-rw-r--r--audio_codec/libfaad/pulse.h43
-rw-r--r--audio_codec/libfaad/rvlc.c524
-rw-r--r--audio_codec/libfaad/rvlc.h55
-rw-r--r--audio_codec/libfaad/sbr_dct.c2267
-rw-r--r--audio_codec/libfaad/sbr_dct.h52
-rw-r--r--audio_codec/libfaad/sbr_dec.c679
-rw-r--r--audio_codec/libfaad/sbr_dec.h253
-rw-r--r--audio_codec/libfaad/sbr_e_nf.c475
-rw-r--r--audio_codec/libfaad/sbr_e_nf.h50
-rw-r--r--audio_codec/libfaad/sbr_fbt.c737
-rw-r--r--audio_codec/libfaad/sbr_fbt.h55
-rw-r--r--audio_codec/libfaad/sbr_hfadj.c1644
-rw-r--r--audio_codec/libfaad/sbr_hfadj.h56
-rw-r--r--audio_codec/libfaad/sbr_hfgen.c647
-rw-r--r--audio_codec/libfaad/sbr_hfgen.h49
-rw-r--r--audio_codec/libfaad/sbr_huff.c344
-rw-r--r--audio_codec/libfaad/sbr_huff.h46
-rw-r--r--audio_codec/libfaad/sbr_noise.h564
-rw-r--r--audio_codec/libfaad/sbr_qmf.c614
-rw-r--r--audio_codec/libfaad/sbr_qmf.h55
-rw-r--r--audio_codec/libfaad/sbr_qmf_c.h368
-rw-r--r--audio_codec/libfaad/sbr_syntax.c893
-rw-r--r--audio_codec/libfaad/sbr_syntax.h68
-rw-r--r--audio_codec/libfaad/sbr_tf_grid.c247
-rw-r--r--audio_codec/libfaad/sbr_tf_grid.h47
-rw-r--r--audio_codec/libfaad/sine_win.h4296
-rw-r--r--audio_codec/libfaad/specrec.c1249
-rw-r--r--audio_codec/libfaad/specrec.h49
-rw-r--r--audio_codec/libfaad/ssr.c170
-rw-r--r--audio_codec/libfaad/ssr.h59
-rw-r--r--audio_codec/libfaad/ssr_fb.c191
-rw-r--r--audio_codec/libfaad/ssr_fb.h53
-rw-r--r--audio_codec/libfaad/ssr_ipqf.c171
-rw-r--r--audio_codec/libfaad/ssr_ipqf.h46
-rw-r--r--audio_codec/libfaad/ssr_win.h635
-rw-r--r--audio_codec/libfaad/structs.h513
-rw-r--r--audio_codec/libfaad/syntax.c2539
-rw-r--r--audio_codec/libfaad/syntax.h129
-rw-r--r--audio_codec/libfaad/tns.c304
-rw-r--r--audio_codec/libfaad/tns.h51
-rwxr-xr-xaudio_codec/libflac/Android.mk22
-rw-r--r--audio_codec/libflac/avcodec.h337
-rw-r--r--audio_codec/libflac/bswap.h94
-rw-r--r--audio_codec/libflac/codec.h36
-rw-r--r--audio_codec/libflac/codec_message.h109
-rw-r--r--audio_codec/libflac/common.h356
-rw-r--r--audio_codec/libflac/crc.c146
-rw-r--r--audio_codec/libflac/crc.h46
-rw-r--r--audio_codec/libflac/flac.c43
-rw-r--r--audio_codec/libflac/flac.h124
-rw-r--r--audio_codec/libflac/flac_decode.c943
-rw-r--r--audio_codec/libflac/flacdata.c38
-rw-r--r--audio_codec/libflac/flacdata.h29
-rw-r--r--audio_codec/libflac/get_bits.h564
-rw-r--r--audio_codec/libflac/golomb.h585
-rw-r--r--audio_codec/libflac/internal.h195
-rw-r--r--audio_codec/libflac/intreadwrite.h390
-rw-r--r--audio_codec/libflac/mathops.h78
-rw-r--r--audio_codec/libflac/types.h49
-rwxr-xr-xaudio_codec/liblpcm/Android.mk13
-rw-r--r--audio_codec/liblpcm/lpcm_decode.c437
-rwxr-xr-xaudio_codec/libmad/Android.mk13
-rwxr-xr-xaudio_codec/libmad/D.dat607
-rw-r--r--audio_codec/libmad/bit.c244
-rw-r--r--audio_codec/libmad/bit.h47
-rw-r--r--audio_codec/libmad/config.h133
-rw-r--r--audio_codec/libmad/decoder.c1102
-rw-r--r--audio_codec/libmad/decoder.h91
-rw-r--r--audio_codec/libmad/fixed.c85
-rw-r--r--audio_codec/libmad/fixed.h499
-rw-r--r--audio_codec/libmad/frame.c525
-rw-r--r--audio_codec/libmad/frame.h118
-rw-r--r--audio_codec/libmad/global.h58
-rw-r--r--audio_codec/libmad/huffman.c3109
-rw-r--r--audio_codec/libmad/huffman.h66
-rwxr-xr-xaudio_codec/libmad/imdct_l_arm.S1000
-rwxr-xr-xaudio_codec/libmad/imdct_s.dat62
-rw-r--r--audio_codec/libmad/layer12.c552
-rwxr-xr-xaudio_codec/libmad/layer12.h31
-rw-r--r--audio_codec/libmad/layer3.c2742
-rwxr-xr-xaudio_codec/libmad/layer3.h30
-rw-r--r--audio_codec/libmad/mad.h966
-rwxr-xr-xaudio_codec/libmad/qc_table.dat77
-rwxr-xr-xaudio_codec/libmad/rq_table.dat8747
-rwxr-xr-xaudio_codec/libmad/sf_table.dat106
-rw-r--r--audio_codec/libmad/stream.c185
-rw-r--r--audio_codec/libmad/stream.h111
-rw-r--r--audio_codec/libmad/synth.c921
-rw-r--r--audio_codec/libmad/synth.h69
-rw-r--r--audio_codec/libmad/timer.c493
-rw-r--r--audio_codec/libmad/timer.h100
-rw-r--r--audio_codec/libmad/version.c91
-rw-r--r--audio_codec/libmad/version.h47
-rwxr-xr-xaudio_codec/libpcm/Android.mk11
-rw-r--r--audio_codec/libpcm/intreadwrite.h390
-rw-r--r--audio_codec/libpcm/pcm_decode.c780
-rw-r--r--audio_codec/libraac/Android.mk51
-rw-r--r--audio_codec/libraac/aac_bitstream.c200
-rw-r--r--audio_codec/libraac/aac_bitstream.h133
-rw-r--r--audio_codec/libraac/aac_decode.h148
-rw-r--r--audio_codec/libraac/aac_decode_main.c396
-rw-r--r--audio_codec/libraac/aac_reorder.c85
-rw-r--r--audio_codec/libraac/aac_reorder.h53
-rw-r--r--audio_codec/libraac/aaccommon.h200
-rw-r--r--audio_codec/libraac/aacdec.c607
-rw-r--r--audio_codec/libraac/aacdec.h200
-rw-r--r--audio_codec/libraac/aactabs.c157
-rw-r--r--audio_codec/libraac/assembly.h147
-rw-r--r--audio_codec/libraac/bitstream.c451
-rw-r--r--audio_codec/libraac/bitstream.h76
-rw-r--r--audio_codec/libraac/buffers.c132
-rw-r--r--audio_codec/libraac/coder.h370
-rw-r--r--audio_codec/libraac/dct4.c339
-rw-r--r--audio_codec/libraac/decelmnt.c451
-rw-r--r--audio_codec/libraac/dequant.c382
-rw-r--r--audio_codec/libraac/fft.c393
-rw-r--r--audio_codec/libraac/filefmt.c531
-rw-r--r--audio_codec/libraac/ga_config.c209
-rw-r--r--audio_codec/libraac/ga_config.h86
-rw-r--r--audio_codec/libraac/huffman.c449
-rw-r--r--audio_codec/libraac/hufftabs.c177
-rw-r--r--audio_codec/libraac/imdct.c598
-rw-r--r--audio_codec/libraac/include/challenge.h132
-rw-r--r--audio_codec/libraac/include/codec_defines.h93
-rw-r--r--audio_codec/libraac/include/gecko2codec.h60
-rw-r--r--audio_codec/libraac/include/helix_config.h92
-rw-r--r--audio_codec/libraac/include/helix_mime_types.h56
-rw-r--r--audio_codec/libraac/include/helix_result.h107
-rw-r--r--audio_codec/libraac/include/helix_types.h305
-rw-r--r--audio_codec/libraac/include/helix_utils.h106
-rw-r--r--audio_codec/libraac/include/md5.h113
-rw-r--r--audio_codec/libraac/include/memory_utils.h58
-rw-r--r--audio_codec/libraac/include/pack_utils.h93
-rw-r--r--audio_codec/libraac/include/packet_defines.h48
-rw-r--r--audio_codec/libraac/include/ra8lbr_decode.h161
-rw-r--r--audio_codec/libraac/include/ra_backend.h94
-rw-r--r--audio_codec/libraac/include/ra_decode.h183
-rw-r--r--audio_codec/libraac/include/ra_depack.h177
-rw-r--r--audio_codec/libraac/include/ra_format_info.h60
-rw-r--r--audio_codec/libraac/include/rasl.h71
-rw-r--r--audio_codec/libraac/include/rdtpck.h153
-rw-r--r--audio_codec/libraac/include/rm_error.h54
-rw-r--r--audio_codec/libraac/include/rm_error_default.h53
-rw-r--r--audio_codec/libraac/include/rm_io_default.h49
-rw-r--r--audio_codec/libraac/include/rm_memory.h54
-rw-r--r--audio_codec/libraac/include/rm_memory_default.h46
-rw-r--r--audio_codec/libraac/include/rm_packet.h80
-rw-r--r--audio_codec/libraac/include/rm_parse.h302
-rw-r--r--audio_codec/libraac/include/rm_property.h107
-rw-r--r--audio_codec/libraac/include/rm_stream.h115
-rw-r--r--audio_codec/libraac/include/rm_stream_internal.h77
-rw-r--r--audio_codec/libraac/include/rv20backend.h69
-rw-r--r--audio_codec/libraac/include/rv30backend.h68
-rw-r--r--audio_codec/libraac/include/rv_backend.h84
-rw-r--r--audio_codec/libraac/include/rv_backend_types.h198
-rw-r--r--audio_codec/libraac/include/rv_decode.h208
-rw-r--r--audio_codec/libraac/include/rv_decode_message.h492
-rw-r--r--audio_codec/libraac/include/rv_depack.h162
-rw-r--r--audio_codec/libraac/include/rv_format_info.h91
-rw-r--r--audio_codec/libraac/include/statname.h118
-rw-r--r--audio_codec/libraac/include/stream_hdr_structs.h66
-rw-r--r--audio_codec/libraac/include/stream_hdr_utils.h77
-rw-r--r--audio_codec/libraac/include/string_utils.h62
-rw-r--r--audio_codec/libraac/include/tngpkt.h400
-rw-r--r--audio_codec/libraac/memory_utils.c100
-rw-r--r--audio_codec/libraac/noiseless.c503
-rw-r--r--audio_codec/libraac/pack_utils.c306
-rw-r--r--audio_codec/libraac/pns.c369
-rw-r--r--audio_codec/libraac/ra_depack.c230
-rw-r--r--audio_codec/libraac/ra_depack_internal.c1713
-rw-r--r--audio_codec/libraac/ra_depack_internal.h232
-rw-r--r--audio_codec/libraac/raac_decode.c854
-rw-r--r--audio_codec/libraac/raac_decode.h37
-rw-r--r--audio_codec/libraac/rm_error_default.c60
-rw-r--r--audio_codec/libraac/rm_io_default.c101
-rw-r--r--audio_codec/libraac/rm_memory_default.c54
-rw-r--r--audio_codec/libraac/rm_packet.c117
-rw-r--r--audio_codec/libraac/rm_parser.c649
-rw-r--r--audio_codec/libraac/rm_parser_internal.c3342
-rw-r--r--audio_codec/libraac/rm_parser_internal.h420
-rw-r--r--audio_codec/libraac/rm_property.c105
-rw-r--r--audio_codec/libraac/rm_stream.c356
-rw-r--r--audio_codec/libraac/rv_depack.c271
-rw-r--r--audio_codec/libraac/rv_depack_internal.c1071
-rw-r--r--audio_codec/libraac/rv_depack_internal.h171
-rw-r--r--audio_codec/libraac/sbr.c431
-rw-r--r--audio_codec/libraac/sbr.h381
-rwxr-xr-xaudio_codec/libraac/sbrcov.s164
-rw-r--r--audio_codec/libraac/sbrfft.c368
-rw-r--r--audio_codec/libraac/sbrfreq.c667
-rw-r--r--audio_codec/libraac/sbrhfadj.c877
-rw-r--r--audio_codec/libraac/sbrhfgen.c646
-rw-r--r--audio_codec/libraac/sbrhuff.c492
-rw-r--r--audio_codec/libraac/sbrimdct.c447
-rw-r--r--audio_codec/libraac/sbrmath.c198
-rw-r--r--audio_codec/libraac/sbrqmf.c643
-rwxr-xr-xaudio_codec/libraac/sbrqmfak.s182
-rwxr-xr-xaudio_codec/libraac/sbrqmfsk.s130
-rw-r--r--audio_codec/libraac/sbrside.c615
-rw-r--r--audio_codec/libraac/sbrtabs.c400
-rw-r--r--audio_codec/libraac/statname.h115
-rw-r--r--audio_codec/libraac/stproc.c252
-rw-r--r--audio_codec/libraac/stream_hdr_utils.c136
-rw-r--r--audio_codec/libraac/string_utils.c87
-rw-r--r--audio_codec/libraac/tns.c307
-rw-r--r--audio_codec/libraac/trigtabs.c1000
-rw-r--r--audio_codec/libraac/trigtabs_fltgen.c357
-rwxr-xr-xaudio_codec/wfd_aac_decoder/Android.mk23
-rw-r--r--audio_codec/wfd_aac_decoder/aaccommon.h210
-rw-r--r--audio_codec/wfd_aac_decoder/aacdec.c508
-rw-r--r--audio_codec/wfd_aac_decoder/aacdec.h206
-rw-r--r--audio_codec/wfd_aac_decoder/aactabs.c157
-rw-r--r--audio_codec/wfd_aac_decoder/assembly.h640
-rw-r--r--audio_codec/wfd_aac_decoder/assembly_mw.h743
-rw-r--r--audio_codec/wfd_aac_decoder/bitstream.c261
-rw-r--r--audio_codec/wfd_aac_decoder/bitstream.h74
-rw-r--r--audio_codec/wfd_aac_decoder/buffers.c140
-rw-r--r--audio_codec/wfd_aac_decoder/coder.h369
-rw-r--r--audio_codec/wfd_aac_decoder/dct4.c337
-rw-r--r--audio_codec/wfd_aac_decoder/decelmnt.c445
-rw-r--r--audio_codec/wfd_aac_decoder/dequant.c379
-rw-r--r--audio_codec/wfd_aac_decoder/fft.c391
-rw-r--r--audio_codec/wfd_aac_decoder/filefmt.c539
-rw-r--r--audio_codec/wfd_aac_decoder/helix_aac_decode.c548
-rw-r--r--audio_codec/wfd_aac_decoder/huffman.c450
-rw-r--r--audio_codec/wfd_aac_decoder/hufftabs.c177
-rw-r--r--audio_codec/wfd_aac_decoder/imdct.c596
-rw-r--r--audio_codec/wfd_aac_decoder/noiseless.c513
-rw-r--r--audio_codec/wfd_aac_decoder/pns.c371
-rw-r--r--audio_codec/wfd_aac_decoder/sbr.c434
-rw-r--r--audio_codec/wfd_aac_decoder/sbr.h380
-rw-r--r--audio_codec/wfd_aac_decoder/sbrfft.c368
-rw-r--r--audio_codec/wfd_aac_decoder/sbrfreq.c673
-rw-r--r--audio_codec/wfd_aac_decoder/sbrhfadj.c882
-rw-r--r--audio_codec/wfd_aac_decoder/sbrhfgen.c655
-rw-r--r--audio_codec/wfd_aac_decoder/sbrhuff.c494
-rw-r--r--audio_codec/wfd_aac_decoder/sbrimdct.c447
-rw-r--r--audio_codec/wfd_aac_decoder/sbrmath.c198
-rw-r--r--audio_codec/wfd_aac_decoder/sbrqmf.c648
-rw-r--r--audio_codec/wfd_aac_decoder/sbrside.c634
-rw-r--r--audio_codec/wfd_aac_decoder/sbrtabs.c400
-rw-r--r--audio_codec/wfd_aac_decoder/statname.h115
-rw-r--r--audio_codec/wfd_aac_decoder/stproc.c251
-rw-r--r--audio_codec/wfd_aac_decoder/tns.c307
-rw-r--r--audio_codec/wfd_aac_decoder/trigtabs.c1000
-rw-r--r--audio_codec/wfd_aac_decoder/trigtabs_fltgen.c357
545 files changed, 230976 insertions, 0 deletions
diff --git a/audio_codec/libamr/sp_dec.c b/audio_codec/libamr/sp_dec.c
new file mode 100644
index 0000000..8ccca93
--- a/dev/null
+++ b/audio_codec/libamr/sp_dec.c
@@ -0,0 +1,6078 @@
+/*
+ * ===================================================================
+ * TS 26.104
+ * R99 V3.5.0 2003-03
+ * REL-4 V4.4.0 2003-03
+ * REL-5 V5.1.0 2003-03
+ * 3GPP AMR Floating-point Speech Codec
+ * ===================================================================
+ *
+ */
+
+/*
+ * sp_dec.c
+ *
+ *
+ * Project:
+ * AMR Floating-Point Codec
+ *
+ * Contains:
+ * This module contains all the functions needed decoding AMR
+ * encoder parameters to 16-bit speech samples
+ *
+ */
+/*
+ * include files
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <math.h>
+#include "sp_dec.h"
+#include "rom_dec.h"
+
+
+/*
+ * Declare structure types
+ */
+enum DTXStateType {
+ SPEECH = 0, DTX, DTX_MUTE
+};
+
+/*
+ * Decoder memory structure
+ */
+typedef struct {
+ /* history vector of past synthesis speech energy */
+ Word32 frameEnergyHist[L_ENERGYHIST];
+
+
+ /* state flags */
+ Word16 bgHangover; /* counter; number of frames after last speech frame */
+
+
+} Bgn_scdState;
+typedef struct {
+ Word32 hangCount; /* counter; */
+ /* history vector of past synthesis speech energy */
+ Word32 cbGainHistory[L_CBGAINHIST];
+ Word16 hangVar; /* counter; */
+
+} Cb_gain_averageState;
+typedef struct {
+ Word32 lsp_meanSave[M]; /* Averaged LSPs saved for efficiency */
+
+
+} lsp_avgState;
+typedef struct {
+ Word32 past_r_q[M]; /* Past quantized prediction error, Q15 */
+ Word32 past_lsf_q[M]; /* Past dequantized lsfs, Q15 */
+
+
+} D_plsfState;
+typedef struct {
+ Word32 pbuf[5];
+ Word32 past_gain_pit;
+ Word32 prev_gp;
+
+
+} ec_gain_pitchState;
+typedef struct {
+ Word32 gbuf[5];
+ Word32 past_gain_code;
+ Word32 prev_gc;
+
+
+} ec_gain_codeState;
+typedef struct {
+ /*
+ * normal MA predictor memory, Q10
+ * (contains 20*log10(quaErr))
+ */
+ Word32 past_qua_en[4];
+
+
+ /*
+ * MA predictor memory for MR122 mode, Q10
+ * (contains log2(quaErr))
+ */
+ Word32 past_qua_en_MR122[4];
+
+
+} gc_predState;
+typedef struct {
+ Word32 gainMem[PHDGAINMEMSIZE];
+ Word32 prevCbGain;
+ Word32 prevState;
+ Word16 lockFull;
+ Word16 onset;
+
+
+} ph_dispState;
+typedef struct {
+ enum DTXStateType dtxGlobalState; /* contains previous state */
+
+ Word32 log_en;
+ Word32 old_log_en;
+ Word32 pn_seed_rx;
+ Word32 lsp[M];
+ Word32 lsp_old[M];
+ Word32 lsf_hist[M * DTX_HIST_SIZE];
+ Word32 lsf_hist_mean[M * DTX_HIST_SIZE];
+ Word32 log_en_hist[DTX_HIST_SIZE];
+ Word32 true_sid_period_inv;
+ Word16 since_last_sid;
+ Word16 lsf_hist_ptr;
+ Word16 log_pg_mean;
+ Word16 log_en_hist_ptr;
+ Word16 log_en_adjust;
+ Word16 dtxHangoverCount;
+ Word16 decAnaElapsedCount;
+ Word16 sid_frame;
+ Word16 valid_data;
+ Word16 dtxHangoverAdded;
+
+
+ /* updated in main decoder */
+ Word16 data_updated; /* marker to know if CNI data is ever renewed */
+
+
+} dtx_decState;
+typedef struct {
+ Word32 past_gain;
+
+
+} agcState;
+typedef struct {
+ /* Excitation vector */
+ Word32 old_exc[L_SUBFR + PIT_MAX + L_INTERPOL];
+ Word32 *exc;
+ Word32 lsp_old[M];
+
+
+ /* Filter's memory */
+ Word32 mem_syn[M];
+
+
+ /* pitch sharpening */
+ Word32 sharp;
+ Word32 old_T0;
+
+
+ /* Variable holding received ltpLag, used in background noise and BFI */
+ Word32 T0_lagBuff;
+
+
+ /* Variables for the source characteristic detector (SCD) */
+ Word32 inBackgroundNoise;
+ Word32 voicedHangover;
+ Word32 ltpGainHistory[9];
+
+
+ /* Memories for bad frame handling */
+ Word32 excEnergyHist[9];
+ Word16 prev_bf;
+ Word16 prev_pdf;
+ Word16 state;
+ Word16 nodataSeed;
+
+
+ Bgn_scdState * background_state;
+ Cb_gain_averageState * Cb_gain_averState;
+ lsp_avgState * lsp_avg_st;
+ D_plsfState * lsfState;
+ ec_gain_pitchState * ec_gain_p_st;
+ ec_gain_codeState * ec_gain_c_st;
+ gc_predState * pred_state;
+ ph_dispState * ph_disp_st;
+ dtx_decState * dtxDecoderState;
+} Decoder_amrState;
+typedef struct {
+ Word32 res2[L_SUBFR];
+ Word32 mem_syn_pst[M];
+ Word32 synth_buf[M + L_FRAME];
+ Word32 preemph_state_mem_pre;
+ agcState * agc_state;
+} Post_FilterState;
+typedef struct {
+ Word32 y2_hi;
+ Word32 y2_lo;
+ Word32 y1_hi;
+ Word32 y1_lo;
+ Word32 x0;
+ Word32 x1;
+
+
+} Post_ProcessState;
+typedef struct {
+ Decoder_amrState * decoder_amrState;
+ Post_FilterState * post_state;
+ Post_ProcessState * postHP_state;
+} Speech_Decode_FrameState;
+
+
+/*
+ * CodAmrReset
+ *
+ *
+ * Parameters:
+ * state B: state structure
+ * mode I: AMR mode
+ *
+ * Function:
+ * Resets state memory
+ *
+ * Returns:
+ * void
+ */
+static void Decoder_amr_reset(Decoder_amrState *state, enum Mode mode)
+{
+ Word32 i;
+
+ /* Cb_gain_average_reset */
+ memset(state->Cb_gain_averState->cbGainHistory, 0, L_CBGAINHIST << 2);
+ state->Cb_gain_averState->hangVar = 0;
+ state->Cb_gain_averState->hangCount = 0;
+
+ /* Initialize static pointer */
+ state->exc = state->old_exc + PIT_MAX + L_INTERPOL;
+
+ /* Static vectors to zero */
+ memset(state->old_exc, 0, (PIT_MAX + L_INTERPOL) << 2);
+
+ if (mode != MRDTX) {
+ memset(state->mem_syn, 0, M << 2);
+ }
+
+ /* initialize pitch sharpening */
+ state->sharp = SHARPMIN;
+ state->old_T0 = 40;
+
+ /* Initialize state->lsp_old [] */
+ if (mode != MRDTX) {
+ state->lsp_old[0] = 30000;
+ state->lsp_old[1] = 26000;
+ state->lsp_old[2] = 21000;
+ state->lsp_old[3] = 15000;
+ state->lsp_old[4] = 8000;
+ state->lsp_old[5] = 0;
+ state->lsp_old[6] = -8000;
+ state->lsp_old[7] = -15000;
+ state->lsp_old[8] = -21000;
+ state->lsp_old[9] = -26000;
+ }
+
+ /* Initialize memories of bad frame handling */
+ state->prev_bf = 0;
+ state->prev_pdf = 0;
+ state->state = 0;
+ state->T0_lagBuff = 40;
+ state->inBackgroundNoise = 0;
+ state->voicedHangover = 0;
+
+ if (mode != MRDTX) {
+ memset(state->excEnergyHist, 0, 9 << 2);
+ }
+ memset(state->ltpGainHistory, 0, 9 << 2);
+
+ if (mode != MRDTX) {
+ state->lsp_avg_st->lsp_meanSave[0] = 1384;
+ state->lsp_avg_st->lsp_meanSave[1] = 2077;
+ state->lsp_avg_st->lsp_meanSave[2] = 3420;
+ state->lsp_avg_st->lsp_meanSave[3] = 5108;
+ state->lsp_avg_st->lsp_meanSave[4] = 6742;
+ state->lsp_avg_st->lsp_meanSave[5] = 8122;
+ state->lsp_avg_st->lsp_meanSave[6] = 9863;
+ state->lsp_avg_st->lsp_meanSave[7] = 11092;
+ state->lsp_avg_st->lsp_meanSave[8] = 12714;
+ state->lsp_avg_st->lsp_meanSave[9] = 13701;
+ }
+ memset(state->lsfState->past_r_q, 0, M << 2);
+
+ /* Past dequantized lsfs */
+ state->lsfState->past_lsf_q[0] = 1384;
+ state->lsfState->past_lsf_q[1] = 2077;
+ state->lsfState->past_lsf_q[2] = 3420;
+ state->lsfState->past_lsf_q[3] = 5108;
+ state->lsfState->past_lsf_q[4] = 6742;
+ state->lsfState->past_lsf_q[5] = 8122;
+ state->lsfState->past_lsf_q[6] = 9863;
+ state->lsfState->past_lsf_q[7] = 11092;
+ state->lsfState->past_lsf_q[8] = 12714;
+ state->lsfState->past_lsf_q[9] = 13701;
+
+ for (i = 0; i < 5; i++) {
+ state->ec_gain_p_st->pbuf[i] = 1640;
+ }
+ state->ec_gain_p_st->past_gain_pit = 0;
+ state->ec_gain_p_st->prev_gp = 16384;
+
+ for (i = 0; i < 5; i++) {
+ state->ec_gain_c_st->gbuf[i] = 1;
+ }
+ state->ec_gain_c_st->past_gain_code = 0;
+ state->ec_gain_c_st->prev_gc = 1;
+
+ if (mode != MRDTX) {
+ for (i = 0; i < NPRED; i++) {
+ state->pred_state->past_qua_en[i] = MIN_ENERGY;
+ state->pred_state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
+ }
+ }
+ state->nodataSeed = 21845;
+
+ /* Static vectors to zero */
+ memset(state->background_state->frameEnergyHist, 0, L_ENERGYHIST << 2);
+
+ /* Initialize hangover handling */
+ state->background_state->bgHangover = 0;
+
+ /* phDispReset */
+ memset(state->ph_disp_st->gainMem, 0, PHDGAINMEMSIZE << 2);
+ state->ph_disp_st->prevState = 0;
+ state->ph_disp_st->prevCbGain = 0;
+ state->ph_disp_st->lockFull = 0;
+ state->ph_disp_st->onset = 0; /* assume no onset in start */
+
+ if (mode != MRDTX) {
+ state->dtxDecoderState->since_last_sid = 0;
+ state->dtxDecoderState->true_sid_period_inv = 8192;
+ state->dtxDecoderState->log_en = 3500;
+ state->dtxDecoderState->old_log_en = 3500;
+
+ /* low level noise for better performance in DTX handover cases*/
+ state->dtxDecoderState->pn_seed_rx = PN_INITIAL_SEED;
+
+ /* Initialize state->lsp [] */
+ state->dtxDecoderState->lsp[0] = 30000;
+ state->dtxDecoderState->lsp[1] = 26000;
+ state->dtxDecoderState->lsp[2] = 21000;
+ state->dtxDecoderState->lsp[3] = 15000;
+ state->dtxDecoderState->lsp[4] = 8000;
+ state->dtxDecoderState->lsp[5] = 0;
+ state->dtxDecoderState->lsp[6] = -8000;
+ state->dtxDecoderState->lsp[7] = -15000;
+ state->dtxDecoderState->lsp[8] = -21000;
+ state->dtxDecoderState->lsp[9] = -26000;
+
+ /* Initialize state->lsp_old [] */
+ state->dtxDecoderState->lsp_old[0] = 30000;
+ state->dtxDecoderState->lsp_old[1] = 26000;
+ state->dtxDecoderState->lsp_old[2] = 21000;
+ state->dtxDecoderState->lsp_old[3] = 15000;
+ state->dtxDecoderState->lsp_old[4] = 8000;
+ state->dtxDecoderState->lsp_old[5] = 0;
+ state->dtxDecoderState->lsp_old[6] = -8000;
+ state->dtxDecoderState->lsp_old[7] = -15000;
+ state->dtxDecoderState->lsp_old[8] = -21000;
+ state->dtxDecoderState->lsp_old[9] = -26000;
+ state->dtxDecoderState->lsf_hist_ptr = 0;
+ state->dtxDecoderState->log_pg_mean = 0;
+ state->dtxDecoderState->log_en_hist_ptr = 0;
+
+ /* initialize decoder lsf history */
+ state->dtxDecoderState->lsf_hist[0] = 1384;
+ state->dtxDecoderState->lsf_hist[1] = 2077;
+ state->dtxDecoderState->lsf_hist[2] = 3420;
+ state->dtxDecoderState->lsf_hist[3] = 5108;
+ state->dtxDecoderState->lsf_hist[4] = 6742;
+ state->dtxDecoderState->lsf_hist[5] = 8122;
+ state->dtxDecoderState->lsf_hist[6] = 9863;
+ state->dtxDecoderState->lsf_hist[7] = 11092;
+ state->dtxDecoderState->lsf_hist[8] = 12714;
+ state->dtxDecoderState->lsf_hist[9] = 13701;
+
+ for (i = 1; i < DTX_HIST_SIZE; i++) {
+ memcpy(&state->dtxDecoderState->lsf_hist[M * i], &state->
+ dtxDecoderState->lsf_hist[0], M << 2);
+ }
+ memset(state->dtxDecoderState->lsf_hist_mean, 0, M * DTX_HIST_SIZE << 2);
+
+ /* initialize decoder log frame energy */
+ for (i = 0; i < DTX_HIST_SIZE; i++) {
+ state->dtxDecoderState->log_en_hist[i] = state->dtxDecoderState->log_en
+ ;
+ }
+ state->dtxDecoderState->log_en_adjust = 0;
+ state->dtxDecoderState->dtxHangoverCount = DTX_HANG_CONST;
+ state->dtxDecoderState->decAnaElapsedCount = 31;
+ state->dtxDecoderState->sid_frame = 0;
+ state->dtxDecoderState->valid_data = 0;
+ state->dtxDecoderState->dtxHangoverAdded = 0;
+ state->dtxDecoderState->dtxGlobalState = DTX;
+ state->dtxDecoderState->data_updated = 0;
+ }
+ return;
+}
+
+
+/*
+ * rx_dtx_handler
+ *
+ *
+ * Parameters:
+ * st->dtxGlobalState I: DTX state
+ * st->since_last_sid B: Frames after last SID frame
+ * st->data_updated I: SID update flag
+ * st->decAnaElapsedCount B: state machine that synch with the GSMEFR txDtx machine
+ * st->dtxHangoverAdded B: DTX hangover
+ * st->sid_frame O: SID frame indicator
+ * st->valid_data O: Vaild data indicator
+ * frame_type O: Frame type
+ *
+ * Function:
+ * Find the new DTX state
+ *
+ * Returns:
+ * DTXStateType DTX, DTX_MUTE or SPEECH
+ */
+static enum DTXStateType rx_dtx_handler(dtx_decState *st, enum RXFrameType frame_type)
+{
+ enum DTXStateType newState;
+ enum DTXStateType encState;
+
+ /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
+ if (table_SID[frame_type] | ((st->dtxGlobalState != SPEECH) &
+ table_speech_bad[frame_type])) {
+ newState = DTX;
+
+ /* stay in mute for these input types */
+ if ((st->dtxGlobalState == DTX_MUTE) & table_mute[frame_type]) {
+ newState = DTX_MUTE;
+ }
+
+ /*
+ * evaluate if noise parameters are too old
+ * since_last_sid is reset when CN parameters have been updated
+ */
+ st->since_last_sid += 1;
+
+ /* no update of sid parameters in DTX for a long while */
+ if ((frame_type != RX_SID_UPDATE) & (st->since_last_sid > DTX_MAX_EMPTY_THRESH)) {
+ newState = DTX_MUTE;
+ }
+ } else {
+ newState = SPEECH;
+ st->since_last_sid = 0;
+ }
+
+ /*
+ * reset the decAnaElapsed Counter when receiving CNI data the first
+ * time, to robustify counter missmatch after handover
+ * this might delay the bwd CNI analysis in the new decoder slightly.
+ */
+ if ((st->data_updated == 0) & (frame_type == RX_SID_UPDATE)) {
+ st->decAnaElapsedCount = 0;
+ }
+
+ /*
+ * update the SPE-SPD DTX hangover synchronization
+ * to know when SPE has added dtx hangover
+ */
+ st->decAnaElapsedCount += 1;
+ st->dtxHangoverAdded = 0;
+ encState = SPEECH;
+
+ if (table_DTX[frame_type]) {
+ encState = DTX;
+ if ((frame_type == RX_NO_DATA) & (newState == SPEECH)) {
+ encState = SPEECH;
+ }
+ }
+
+ if (encState == SPEECH) {
+ st->dtxHangoverCount = DTX_HANG_CONST;
+ } else {
+ if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH) {
+ st->dtxHangoverAdded = 1;
+ st->decAnaElapsedCount = 0;
+ st->dtxHangoverCount = 0;
+ } else if (st->dtxHangoverCount == 0) {
+ st->decAnaElapsedCount = 0;
+ } else {
+ st->dtxHangoverCount -= 1;
+ }
+ }
+
+ if (newState != SPEECH) {
+ /*
+ * DTX or DTX_MUTE
+ * CN data is not in a first SID, first SIDs are marked as SID_BAD
+ * but will do backwards analysis if a hangover period has been added
+ * according to the state machine above
+ */
+ st->sid_frame = 0;
+ st->valid_data = 0;
+
+ if (frame_type == RX_SID_FIRST) {
+ st->sid_frame = 1;
+ } else if (frame_type == RX_SID_UPDATE) {
+ st->sid_frame = 1;
+ st->valid_data = 1;
+ } else if (frame_type == RX_SID_BAD) {
+ st->sid_frame = 1;
+
+ /* use old data */
+ st->dtxHangoverAdded = 0;
+ }
+ }
+
+ /* newState is used by both SPEECH AND DTX synthesis routines */
+ return newState;
+}
+
+
+/*
+ * Lsf_lsp
+ *
+ *
+ * Parameters:
+ * lsf I: vector of LSFs
+ * lsp O: vector of LSPs
+ *
+ * Function:
+ * Transformation lsf to lsp, order M
+ *
+ * Returns:
+ * void
+ */
+static void Lsf_lsp(Word32 lsf[], Word32 lsp[])
+{
+ Word32 i, ind, offset, tmp;
+
+
+ for (i = 0; i < M; i++) {
+ /* ind = b8-b15 of lsf[i] */
+ ind = lsf[i] >> 8;
+
+ /* offset = b0-b7 of lsf[i] */
+ offset = lsf[i] & 0x00ff;
+
+ /* lsp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 256 */
+ tmp = ((cos_table[ind + 1] - cos_table[ind]) * offset) << 1;
+ lsp[i] = cos_table[ind] + (tmp >> 9);
+ }
+ return;
+}
+
+
+/*
+ * D_plsf_3
+ *
+ *
+ * Parameters:
+ * st->past_lsf_q I: Past dequantized LFSs
+ * st->past_r_q B: past quantized residual
+ * mode I: AMR mode
+ * bfi B: bad frame indicator
+ * indice I: quantization indices of 3 submatrices, Q0
+ * lsp1_q O: quantized 1st LSP vector
+ *
+ * Function:
+ * Decodes the LSP parameters using the received quantization indices.
+ * 1st order MA prediction and split by 3 vector quantization (split-VQ)
+ *
+ * Returns:
+ * void
+ */
+static void D_plsf_3(D_plsfState *st, enum Mode mode, Word16 bfi, Word16 *
+ indice, Word32 *lsp1_q)
+{
+ Word32 lsf1_r[M], lsf1_q[M];
+ Word32 i, index, temp;
+ const Word32 *p_cb1, *p_cb2, *p_cb3, *p_dico;
+
+
+ /* if bad frame */
+ if (bfi != 0) {
+ /* use the past LSFs slightly shifted towards their mean */
+ for (i = 0; i < M; i++) {
+ /* lsfi_q[i] = ALPHA*past_lsf_q[i] + ONE_ALPHA*meanLsf[i]; */
+ lsf1_q[i] = ((st->past_lsf_q[i] * ALPHA) >> 15) + ((mean_lsf_3[i]
+ * ONE_ALPHA) >> 15);
+ }
+
+ /* estimate past quantized residual to be used in next frame */
+ if (mode != MRDTX) {
+ for (i = 0; i < M; i++) {
+ /* temp = meanLsf[i] + pastR2_q[i] * pred_fac; */
+ temp = mean_lsf_3[i] + ((st->past_r_q[i] * pred_fac[i]) >> 15);
+ st->past_r_q[i] = lsf1_q[i] - temp;
+ }
+ } else {
+ for (i = 0; i < M; i++) {
+ /* temp = meanLsf[i] + pastR2_q[i]; */
+ temp = mean_lsf_3[i] + st->past_r_q[i];
+ st->past_r_q[i] = lsf1_q[i] - temp;
+ }
+ }
+ }
+
+ /* if good LSFs received */
+ else {
+ if ((mode == MR475) | (mode == MR515)) {
+ /* MR475, MR515 */
+ p_cb1 = dico1_lsf_3;
+ p_cb2 = dico2_lsf_3;
+ p_cb3 = mr515_3_lsf;
+ } else if (mode == MR795) {
+ /* MR795 */
+ p_cb1 = mr795_1_lsf;
+ p_cb2 = dico2_lsf_3;
+ p_cb3 = dico3_lsf_3;
+ } else {
+ /* MR59, MR67, MR74, MR102, MRDTX */
+ p_cb1 = dico1_lsf_3;
+ p_cb2 = dico2_lsf_3;
+ p_cb3 = dico3_lsf_3;
+ }
+
+ /* decode prediction residuals from 3 received indices */
+ index = *indice++;
+ p_dico = &p_cb1[index + index + index];
+ index = *indice++;
+ lsf1_r[0] = *p_dico++;
+ lsf1_r[1] = *p_dico++;
+ lsf1_r[2] = *p_dico++;
+
+ if ((mode == MR475) | (mode == MR515)) {
+ /* MR475, MR515 only using every second entry */
+ index = index << 1;
+ }
+ p_dico = &p_cb2[index + index + index];
+ index = *indice++;
+ lsf1_r[3] = *p_dico++;
+ lsf1_r[4] = *p_dico++;
+ lsf1_r[5] = *p_dico++;
+ p_dico = &p_cb3[index << 2];
+ lsf1_r[6] = *p_dico++;
+ lsf1_r[7] = *p_dico++;
+ lsf1_r[8] = *p_dico++;
+ lsf1_r[9] = *p_dico++;
+
+ /* Compute quantized LSFs and update the past quantized residual */
+ if (mode != MRDTX) {
+ for (i = 0; i < M; i++) {
+ lsf1_q[i] = lsf1_r[i] + (mean_lsf_3[i] + ((st->past_r_q[i] *
+ pred_fac[i]) >> 15));
+ }
+ memcpy(st->past_r_q, lsf1_r, M << 2);
+ } else {
+ for (i = 0; i < M; i++) {
+ lsf1_q[i] = lsf1_r[i] + (mean_lsf_3[i] + st->past_r_q[i]);
+ }
+ memcpy(st->past_r_q, lsf1_r, M << 2);
+ }
+ }
+
+ /* verification that LSFs has minimum distance of LSF_GAP Hz */
+ temp = LSF_GAP;
+
+ for (i = 0; i < M; i++) {
+ if (lsf1_q[i] < temp) {
+ lsf1_q[i] = temp;
+ }
+ temp = lsf1_q[i] + LSF_GAP;
+ }
+ memcpy(st->past_lsf_q, lsf1_q, M << 2);
+
+ /* convert LSFs to the cosine domain */
+ Lsf_lsp(lsf1_q, lsp1_q);
+ return;
+}
+
+
+/*
+ * pseudonoise
+ *
+ *
+ * Parameters:
+ * shift_reg B: Old CN generator shift register state
+ * no_bits I: Number of bits
+ *
+ * Function:
+ * pseudonoise
+ *
+ * Returns:
+ * noise_bits
+ */
+static Word32 pseudonoise(Word32 *shift_reg, Word32 no_bits)
+{
+ Word32 noise_bits, Sn, i;
+ Word32 s_reg;
+
+
+ s_reg = *shift_reg;
+ noise_bits = 0;
+
+ for (i = 0; i < no_bits; i++) {
+ /* State n == 31 */
+ Sn = s_reg & 0x00000001L;
+
+ /* State n == 3 */
+ if (s_reg & 0x10000000L) {
+ Sn = Sn ^ 0x1L;
+ } else {
+ Sn = Sn ^ 0x0L;
+ }
+ noise_bits = (noise_bits << 1) | (s_reg & 1);
+ s_reg = s_reg >> 1;
+
+ if (Sn & 1) {
+ s_reg = s_reg | 0x40000000L;
+ }
+ }
+ *shift_reg = s_reg;
+ return noise_bits;
+}
+
+
+/*
+ * Lsp_lsf
+ *
+ *
+ * Parameters:
+ * lsp I: LSP vector (range: -1<=val<1)
+ * lsf O: LSF vector Old CN generator shift register state
+ *
+ * Function:
+ * Transformation lsp to lsf, LPC order M
+ * lsf[i] = arccos(lsp[i])/(2*pi)
+ *
+ * Returns:
+ * void
+ */
+static void Lsp_lsf(Word32 lsp[], Word32 lsf[])
+{
+ Word32 i, ind = 63; /* begin at end of table -1 */
+
+
+ for (i = M - 1; i >= 0; i--) {
+ /* find value in table that is just greater than lsp[i] */
+ while (cos_table[ind] < lsp[i]) {
+ ind--;
+ }
+ lsf[i] = ((((lsp[i] - cos_table[ind]) * acos_slope[ind]) + 0x800)
+ >> 12) + (ind << 8);
+ }
+ return;
+}
+
+
+/*
+ * Reorder_lsf
+ *
+ *
+ * Parameters:
+ * lsf B: vector of LSFs (range: 0<=val<=0.5)
+ * min_dist I: minimum required distance
+ *
+ * Function:
+ * Make sure that the LSFs are properly ordered and to keep a certain minimum
+ * distance between adjacent LSFs. LPC order = M.
+ *
+ * Returns:
+ * void
+ */
+static void Reorder_lsf(Word32 *lsf, Word32 min_dist)
+{
+ Word32 lsf_min, i;
+
+
+ lsf_min = min_dist;
+
+ for (i = 0; i < M; i++) {
+ if (lsf[i] < lsf_min) {
+ lsf[i] = lsf_min;
+ }
+ lsf_min = lsf[i] + min_dist;
+ }
+}
+
+/* VC5.0 Global optimization does not work with this function */
+#if _MSC_VER == 1100
+#pragma optimize( "g", off )
+#endif
+/*
+ * Get_lsp_pol
+ *
+ *
+ * Parameters:
+ * lsp I: line spectral frequencies
+ * f O: polynomial F1(z) or F2(z)
+ *
+ * Function:
+ * Find the polynomial F1(z) or F2(z) from the LSPs.
+ *
+ * F1(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
+ * i=0,2,4,6,8
+ * F2(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
+ * i=1,3,5,7,9
+ *
+ * where lsp[] is the LSP vector in the cosine domain.
+ *
+ * The expansion is performed using the following recursion:
+ *
+ * f[0] = 1
+ * b = -2.0 * lsp[0]
+ * f[1] = b
+ * for i=2 to 5 do
+ * b = -2.0 * lsp[2*i-2];
+ * f[i] = b*f[i-1] + 2.0*f[i-2];
+ * for j=i-1 down to 2 do
+ * f[j] = f[j] + b*f[j-1] + f[j-2];
+ * f[1] = f[1] + b;
+ *
+ * Returns:
+ * void
+ */
+static void Get_lsp_pol(Word32 *lsp, Word32 *f)
+{
+ Word32 f0, f1, f2, f3, f4, f5;
+ Word32 l1, l2, l3, l4;
+
+ /* f[0] = 1.0; */
+ f0 = 16777216L;
+
+ /* f1 = *lsp * -1024; */
+ f1 = -lsp[0] << 10;
+ l1 = lsp[2];
+ l2 = lsp[4];
+ l3 = lsp[6];
+ l4 = lsp[8];
+ f2 = f0 << 1;
+ f2 -= (((f1 >> 16) * l1) + (((f1 & 0xFFFE) * l1) >> 16)) << 2;
+ f1 -= l1 << 10;
+ f3 = f1 << 1;
+ f3 -= (((f2 >> 16) * l2) + (((f2 & 0xFFFE) * l2) >> 16)) << 2;
+ f2 += f0;
+ f2 -= (((f1 >> 16) * l2) + (((f1 & 0xFFFE) * l2) >> 16)) << 2;
+ f1 -= l2 << 10;
+ f4 = f2 << 1;
+ f4 -= (((f3 >> 16) * l3) + (((f3 & 0xFFFE) * l3) >> 16)) << 2;
+ f3 += f1;
+ f3 -= (((f2 >> 16) * l3) + (((f2 & 0xFFFE) * l3) >> 16)) << 2;
+ f2 += f0;
+ f2 -= (((f1 >> 16) * l3) + (((f1 & 0xFFFE) * l3) >> 16)) << 2;
+ f1 -= l3 << 10;
+ f5 = f3 << 1;
+ f5 -= (((f4 >> 16) * l4) + (((f4 & 0xFFFE) * l4) >> 16)) << 2;
+ f4 += f2;
+ f4 -= (((f3 >> 16) * l4) + (((f3 & 0xFFFE) * l4) >> 16)) << 2;
+ f3 += f1;
+ f3 -= (((f2 >> 16) * l4) + (((f2 & 0xFFFE) * l4) >> 16)) << 2;
+ f2 += f0;
+ f2 -= (((f1 >> 16) * l4) + (((f1 & 0xFFFE) * l4) >> 16)) << 2;
+ f1 -= l4 << 10;
+ f[0] = f0;
+ f[1] = f1;
+ f[2] = f2;
+ f[3] = f3;
+ f[4] = f4;
+ f[5] = f5;
+
+ return;
+}
+#if _MSC_VER == 1100
+#pragma optimize( "", on )
+#endif
+
+
+/*
+ * Lsp_Az
+ *
+ *
+ * Parameters:
+ * lsp I: Line spectral frequencies
+ * a O: Predictor coefficients
+ *
+ * Function:
+ * Converts from the line spectral pairs (LSP) to LP coefficients,
+ * for a 10th order filter.
+ *
+ * Find the coefficients of F1(z) and F2(z)
+ * Multiply F1(z) by 1+z^{-1} and F2(z) by 1-z^{-1}
+ * A(z) = ( F1(z) + F2(z) ) / 2
+ *
+ * Returns:
+ * void
+ */
+static void Lsp_Az(Word32 lsp[], Word32 a[])
+{
+ Word32 f1[6], f2[6];
+ Word32 T0, i, j;
+
+
+ Get_lsp_pol(&lsp[0], f1);
+ Get_lsp_pol(&lsp[1], f2);
+
+ for (i = 5; i > 0; i--) {
+ f1[i] += f1[i - 1];
+ f2[i] -= f2[i - 1];
+ }
+ a[0] = 4096;
+
+ for (i = 1, j = 10; i <= 5; i++, j--) {
+ T0 = f1[i] + f2[i];
+ a[i] = (Word16)(T0 >> 13); /* emulate fixed point bug */
+ if ((T0 & 4096) != 0) {
+ a[i]++;
+ }
+ T0 = f1[i] - f2[i];
+ a[j] = (Word16)(T0 >> 13); /* emulate fixed point bug */
+
+ if ((T0 & 4096) != 0) {
+ a[j]++;
+ }
+ }
+ return;
+}
+
+
+/*
+ * A_Refl
+ *
+ *
+ * Parameters:
+ * a I: Directform coefficients
+ * refl O: Reflection coefficients
+ *
+ * Function:
+ * Converts from the directform coefficients to reflection coefficients
+ *
+ * Returns:
+ * void
+ */
+static void A_Refl(Word32 a[], Word32 refl[])
+{
+ /* local variables */
+ int normShift;
+ Word32 aState[M], bState[M];
+ Word32 normProd, acc, temp, mult, scale, i, j;
+
+
+ /* initialize states */
+ memcpy(aState, a, M << 2);
+
+ /* backward Levinson recursion */
+ for (i = M - 1; i >= 0; i--) {
+ if (labs(aState[i]) >= 4096) {
+ goto ExitRefl;
+ }
+ refl[i] = aState[i] << 3;
+ temp = (refl[i] * refl[i]) << 1;
+ acc = (MAX_32 - temp);
+ normShift = 0;
+ if (acc != 0) {
+ temp = acc;
+ while (!(temp & 0x40000000)) {
+ normShift++;
+ temp = temp << 1;
+ }
+ } else {
+ normShift = 0;
+ }
+ scale = 15 - normShift;
+ acc = (acc << normShift);
+ temp = (acc + (Word32)0x00008000L);
+
+ if (temp > 0) {
+ normProd = temp >> 16;
+ mult = 0x20000000L / normProd;
+ } else {
+ mult = 16384;
+ }
+
+ for (j = 0; j < i; j++) {
+ acc = aState[j] << 16;
+ acc -= (refl[i] * aState[i - j - 1]) << 1;
+ temp = (acc + (Word32)0x00008000L) >> 16;
+ temp = (mult * temp) << 1;
+
+ if (scale > 0) {
+ if ((temp & ((Word32)1 << (scale - 1))) != 0) {
+ temp = (temp >> scale) + 1;
+ } else {
+ temp = (temp >> scale);
+ }
+ } else {
+ temp = (temp >> scale);
+ }
+
+ if (labs(temp) > 32767) {
+ goto ExitRefl;
+ }
+ bState[j] = temp;
+ }
+ memcpy(aState, bState, i << 2);
+ }
+ return;
+ExitRefl:
+ memset(refl, 0, M << 2);
+}
+
+
+/*
+ * Log2_norm
+ *
+ *
+ * Parameters:
+ * x I: input value
+ * exp I: exponent
+ * exponent O: Integer part of Log2. (range: 0<=val<=30)
+ * fraction O: Fractional part of Log2. (range: 0<=val<1)
+ *
+ * Function:
+ * Computes log2
+ *
+ * Computes log2(L_x, exp), where L_x is positive and
+ * normalized, and exp is the normalisation exponent
+ * If L_x is negative or zero, the result is 0.
+ *
+ * The function Log2(L_x) is approximated by a table and linear
+ * interpolation. The following steps are used to compute Log2(L_x)
+ *
+ * exponent = 30-normExponent
+ * i = bit25-b31 of L_x; 32<=i<=63 (because of normalization).
+ * a = bit10-b24
+ * i -=32
+ * fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
+ *
+ * Returns:
+ * void
+ */
+static void Log2_norm(Word32 x, Word32 exp, Word32 *exponent, Word32 *
+ fraction)
+{
+ Word32 y, i, a;
+
+
+ if (x <= 0) {
+ *exponent = 0;
+ *fraction = 0;
+ return;
+ }
+
+ /* Extract b25-b31 */
+ i = x >> 25;
+ i = i - 32;
+
+ /* Extract b10-b24 of fraction */
+ a = x >> 9;
+ a = a & 0xFFFE; /* 2a */
+
+ /* fraction */
+ y = (log2_table[i] << 16) - a * (log2_table[i] - log2_table[i + 1]);
+ *fraction = y >> 16;
+ *exponent = 30 - exp;
+ return;
+}
+
+
+/*
+ * Log2
+ *
+ *
+ * Parameters:
+ * x I: input value
+ * exponent O: Integer part of Log2. (range: 0<=val<=30)
+ * fraction O: Fractional part of Log2. (range: 0<=val<1)
+ *
+ * Function:
+ * Computes log2(L_x)
+ * If x is negative or zero, the result is 0.
+ *
+ * Returns:
+ * void
+ */
+static void Log2(Word32 x, Word32 *exponent, Word32 *fraction)
+{
+ int tmp, exp = 0;
+
+ if (x != 0) {
+ tmp = x;
+ while (!((tmp & 0x80000000) ^((tmp & 0x40000000) << 1))) {
+ exp++;
+ tmp = tmp << 1;
+ }
+ }
+ Log2_norm(x << exp, exp, exponent, fraction);
+}
+
+
+/*
+ * Pow2
+ *
+ *
+ * Parameters:
+ * exponent I: Integer part. (range: 0<=val<=30)
+ * fraction O: Fractional part. (range: 0.0<=val<1.0)
+ *
+ * Function:
+ * pow(2.0, exponent.fraction)
+ *
+ * The function Pow2(L_x) is approximated by a table and linear interpolation.
+ *
+ * i = bit10-b15 of fraction, 0 <= i <= 31
+ * a = biT0-b9 of fraction
+ * x = table[i]<<16 - (table[i] - table[i+1]) * a * 2
+ * x = L_x >> (30-exponent) (with rounding)
+ *
+ * Returns:
+ * result (range: 0<=val<=0x7fffffff)
+ */
+static Word32 Pow2(Word32 exponent, Word32 fraction)
+{
+ Word32 i, a, tmp, x, exp;
+
+
+ /* Extract b10-b16 of fraction */
+ i = fraction >> 10;
+
+ /* Extract b0-b9 of fraction */
+ a = (fraction << 5) & 0x7fff;
+
+ /* table[i] << 16 */
+ x = pow2_table[i] << 16;
+
+ /* table[i] - table[i+1] */
+ tmp = pow2_table[i] - pow2_table[i + 1];
+
+ /* L_x -= tmp*a*2 */
+ x -= (tmp * a) << 1;
+
+ if (exponent >= -1) {
+ exp = (30 - exponent);
+
+ /* Rounding */
+ if ((x & ((Word32)1 << (exp - 1))) != 0) {
+ x = (x >> exp) + 1;
+ } else {
+ x = x >> exp;
+ }
+ } else {
+ x = 0;
+ }
+ return(x);
+}
+
+
+/*
+ * Build_CN_code
+ *
+ *
+ * Parameters:
+ * seed B: Old CN generator shift register state
+ * cod O: Generated CN fixed codebook vector
+ *
+ * Function:
+ * Generate CN fixed codebook vector
+ *
+ * Returns:
+ * void
+ */
+static void Build_CN_code(Word32 *seed, Word32 cod[])
+{
+ Word32 i, j, k;
+
+
+ memset(cod, 0, L_SUBFR << 2);
+
+ for (k = 0; k < 10; k++) {
+ i = pseudonoise(seed, 2); /* generate pulse position */
+ i = (i * 20) >> 1;
+ i = (i + k);
+ j = pseudonoise(seed, 1); /* generate sign */
+
+ if (j > 0) {
+ cod[i] = 4096;
+ } else {
+ cod[i] = -4096;
+ }
+ }
+ return;
+}
+
+
+/*
+ * Build_CN_param
+ *
+ *
+ * Parameters:
+ * seed B: Old CN generator shift register state
+ * nParam I: number of params
+ * paramSizeTable I: size of params
+ * parm O: CN Generated params
+ *
+ * Function:
+ * Generate parameters for comfort noise generation
+ *
+ * Returns:
+ * void
+ */
+static void Build_CN_param(Word16 *seed, enum Mode mode, Word16 parm[])
+{
+ Word32 i;
+ const Word32 *p;
+
+
+ *seed = (Word16)((*seed * 31821) + 13849L);
+ p = &window_200_40[ * seed & 0x7F];
+
+ switch (mode) {
+ case MR122:
+ for (i = 0; i < PRMNO_MR122; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR122[i]));
+ }
+ break;
+
+ case MR102:
+ for (i = 0; i < PRMNO_MR102; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR102[i]));
+ }
+ break;
+
+ case MR795:
+ for (i = 0; i < PRMNO_MR795; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR795[i]));
+ }
+ break;
+
+ case MR74:
+ for (i = 0; i < PRMNO_MR74; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR74[i]));
+ }
+ break;
+
+ case MR67:
+ for (i = 0; i < PRMNO_MR67; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR67[i]));
+ }
+ break;
+
+ case MR59:
+ for (i = 0; i < PRMNO_MR59; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR59[i]));
+ }
+ break;
+
+ case MR515:
+ for (i = 0; i < PRMNO_MR515; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR515[i]));
+ }
+ break;
+
+ case MR475:
+ for (i = 0; i < PRMNO_MR475; i++) {
+ parm[i] = (Word16)(*p++ & ~(0xFFFF << bitno_MR475[i]));
+ }
+ break;
+ }
+}
+
+
+/*
+ * Syn_filt
+ *
+ *
+ * Parameters:
+ * a I: prediction coefficients [M+1]
+ * x I: input signal
+ * y O: output signal
+ * lg I: size of filtering
+ * mem B: memory associated with this filtering
+ * update I: 0=no update, 1=update of memory.
+ *
+ * Function:
+ * Perform synthesis filtering through 1/A(z).
+ *
+ * Returns:
+ * void
+ */
+volatile int kk_entery = 0;
+static Word32 Syn_filt(Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
+ , Word32 update)
+{
+ Word32 tmp[50]; /* malloc is slow */
+ Word32 s, a0, overflow = 0;
+ Word32 *yy, *yy_limit;
+
+
+ /* Copy mem[] to yy[] */
+ memcpy(tmp, mem, 40);
+ yy = tmp + M;
+ yy_limit = yy + lg;
+ a0 = a[0];
+ kk_entery++;
+ /* Do the filtering. */
+ while (yy < yy_limit) {
+
+ s = *x++ * a0;
+ s -= yy[-1] * a[1];
+ s -= yy[-2] * a[2];
+ s -= yy[-3] * a[3];
+ s -= yy[-4] * a[4];
+ s -= yy[-5] * a[5];
+ s -= yy[-6] * a[6];
+ s -= yy[-7] * a[7];
+ s -= yy[-8] * a[8];
+ s -= yy[-9] * a[9];
+ s -= yy[-10] * a[10];
+ if (labs(s) < 0x7ffffff) {
+ *yy = (s + 0x800L) >> 12;
+ } else if (s > 0) {
+ *yy = 32767;
+ overflow = 1;
+ } else {
+ *yy = -32768;
+ overflow = 1;
+ }
+ yy++;
+ }
+ memcpy(y, &tmp[M], lg << 2);
+
+ /* Update of memory if update==1 */
+ if (update) {
+ memcpy(mem, &y[lg - M], 40);
+ }
+ return overflow;
+}
+
+/*
+ * Syn_filt_overflow
+ *
+ *
+ * Parameters:
+ * a I: prediction coefficients [M+1]
+ * x I: input signal
+ * y O: output signal
+ * lg I: size of filtering
+ * mem B: memory associated with this filtering
+ * update I: 0=no update, 1=update of memory.
+ *
+ * Function:
+ * Perform synthesis filtering through 1/A(z).
+ * Saturate after every multiplication.
+ * Returns:
+ * void
+ */
+static void Syn_filt_overflow(Word32 a[], Word32 x[], Word32 y[], Word32 lg, Word32 mem[]
+ , Word32 update)
+{
+ Word32 tmp[50]; /* malloc is slow */
+ Word32 i, j, s, a0;
+ Word32 *yy;
+
+
+ /* Copy mem[] to yy[] */
+ memcpy(tmp, mem, 40);
+ yy = tmp + M;
+ a0 = a[0];
+
+ /* Do the filtering. */
+ for (i = 0; i < lg; i++) {
+ s = x[i] * a0;
+
+ for (j = 1; j <= M; j++) {
+ s -= a[j] * yy[ - j];
+ if (s > 1073741823) {
+ s = 1073741823;
+ } else if (s < -1073741824) {
+ s = -1073741824;
+ }
+ }
+
+ if (labs(s) < 0x7FFE800) {
+ *yy = (s + 0x800L) >> 12;
+ } else if (s > 0) {
+ *yy = 32767;
+ } else {
+ *yy = -32768;
+ }
+ yy++;
+ }
+ memcpy(y, &tmp[M], lg << 2);
+
+ /* Update of memory if update==1 */
+ if (update) {
+ memcpy(mem, &y[lg - M], 40);
+ }
+ return;
+}
+
+/*
+ * dtx_dec
+ *
+ *
+ * Parameters:
+ * st B: DTX state struct
+ * mem_syn I: AMR decoder state
+ * lsfState B: LSF state struct
+ * pred_state->past_qua_en O: table of past quantized energies
+ * pred_state->past_qua_en_MR122 O: table of past quantized energies MR122
+ * averState->hangVar O:
+ * averState->hangCount O: hangover variable
+ * new_state I: new DTX state
+ * mode I: AMR mode
+ * parm I: vector of synthesis parameters
+ * synth O: synthesised speech
+ * A_t O: decoded LP filter in 4 subframes
+ *
+ * Function:
+ * DTX
+ *
+ * Returns:
+ * void
+ */
+static void dtx_dec(dtx_decState *st, Word32 *mem_syn, D_plsfState *lsfState,
+ gc_predState *pred_state, Cb_gain_averageState *averState, enum
+ DTXStateType new_state, enum Mode mode, Word16 parm[], Word32 synth[],
+ Word32 A_t[])
+{
+ Word32 ex[L_SUBFR], acoeff[11], acoeff_variab[M + 1], lsp_int[M];
+ Word32 refl[M], lsf[M], lsf_int[M], lsf_int_variab[M], lsp_int_variab[M];
+ Word32 i, j, int_fac, log_en_int, pred_err, log_pg_e, log_pg_m, log_pg;
+ Word32 negative, lsf_mean, lsf_variab_index, lsf_variab_factor, ptr;
+ Word16 log_en_index, log_en_int_e, log_en_int_m, level, ma_pred_init,
+ tmp_int_length;
+
+
+ if ((st->dtxHangoverAdded != 0) & (st->sid_frame != 0)) {
+ /*
+ * sidFirst after dtx hangover period
+ * or sidUpd after dtxhangover
+ */
+ /* set log_en_adjust to correct value */
+ st->log_en_adjust = dtx_log_en_adjust[mode];
+ ptr = st->lsf_hist_ptr + M;
+
+ if (ptr == 80) {
+ ptr = 0;
+ }
+ memcpy(&st->lsf_hist[ptr], &st->lsf_hist[st->lsf_hist_ptr], M << 2);
+ ptr = st->log_en_hist_ptr + 1;
+
+ if (ptr == DTX_HIST_SIZE) {
+ ptr = 0;
+ }
+ st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */
+
+ /*
+ * compute mean log energy and lsp
+ * from decoded signal (SID_FIRST)
+ */
+ st->log_en = 0;
+ memset(lsf, 0, M << 2);
+
+ /* average energy and lsp */
+ for (i = 0; i < DTX_HIST_SIZE; i++) {
+ st->log_en = st->log_en + (st->log_en_hist[i] >> 3);
+
+ for (j = 0; j < M; j++) {
+ lsf[j] += st->lsf_hist[i * M + j];
+ }
+ }
+
+ for (j = 0; j < M; j++) {
+ lsf[j] = lsf[j] >> 3; /* divide by 8 */
+ }
+ Lsf_lsp(lsf, st->lsp);
+
+ /*
+ * make log_en speech coder mode independent
+ * added again later before synthesis
+ */
+ st->log_en = st->log_en - st->log_en_adjust;
+
+ /* compute lsf variability vector */
+ memcpy(st->lsf_hist_mean, st->lsf_hist, 80 << 2);
+
+ for (i = 0; i < M; i++) {
+ lsf_mean = 0;
+
+ /* compute mean lsf */
+ for (j = 0; j < 8; j++) {
+ lsf_mean += st->lsf_hist_mean[i + j * M];
+ }
+ lsf_mean = lsf_mean >> 3;
+
+ /*
+ * subtract mean and limit to within reasonable limits
+ * moreover the upper lsf's are attenuated
+ */
+ for (j = 0; j < 8; j++) {
+ /* subtract mean */
+ st->lsf_hist_mean[i + j * M] = st->lsf_hist_mean[i + j * M] -
+ lsf_mean;
+
+ /* attenuate deviation from mean, especially for upper lsf's */
+ st->lsf_hist_mean[i + j * M] = (st->lsf_hist_mean[i + j * M] *
+ lsf_hist_mean_scale[i]) >> 15;
+
+ /* limit the deviation */
+ if (st->lsf_hist_mean[i + j * M] < 0) {
+ negative = 1;
+ } else {
+ negative = 0;
+ }
+ st->lsf_hist_mean[i + j * M] = labs(st->lsf_hist_mean[i + j * M]);
+
+ /* apply soft limit */
+ if (st->lsf_hist_mean[i + j * M] > 655) {
+ st->lsf_hist_mean[i + j * M] = 655 + ((st->lsf_hist_mean[i + j
+ * M] - 655) >> 2);
+ }
+
+ /* apply hard limit */
+ if (st->lsf_hist_mean[i + j * M] > 1310) {
+ st->lsf_hist_mean[i + j * M] = 1310;
+ }
+
+ if (negative != 0) {
+ st->lsf_hist_mean[i + j * M] = -st->lsf_hist_mean[i + j * M];
+ }
+ }
+ }
+ }
+
+ if (st->sid_frame != 0) {
+ /*
+ * Set old SID parameters, always shift
+ * even if there is no new valid_data
+ */
+ memcpy(st->lsp_old, st->lsp, M << 2);
+ st->old_log_en = st->log_en;
+
+ if (st->valid_data != 0) { /* new data available (no CRC) */
+ /* Compute interpolation factor, since the division only works
+ * for values of since_last_sid < 32 we have to limit the
+ * interpolation to 32 frames
+ */
+ tmp_int_length = st->since_last_sid;
+ st->since_last_sid = 0;
+
+ if (tmp_int_length > 32) {
+ tmp_int_length = 32;
+ }
+
+ if (tmp_int_length >= 2) {
+ st->true_sid_period_inv = 0x2000000 / (tmp_int_length
+ << 10);
+ } else {
+ st->true_sid_period_inv = 16384; /* 0.5 it Q15 */
+ }
+ memcpy(lsfState->past_r_q, &past_rq_init[parm[0] * M], M << 2);
+ D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp);
+
+ /* reset for next speech frame */
+ memset(lsfState->past_r_q, 0, M << 2);
+ log_en_index = parm[4];
+
+ /* Q11 and divide by 4 */
+ st->log_en = (Word16)(log_en_index << 9);
+
+ /* Subtract 2.5 in Q11 */
+ st->log_en = (Word16)(st->log_en - 5120);
+
+ /* Index 0 is reserved for silence */
+ if (log_en_index == 0) {
+ st->log_en = MIN_16;
+ }
+
+ /*
+ * no interpolation at startup after coder reset
+ * or when SID_UPD has been received right after SPEECH
+ */
+ if ((st->data_updated == 0) || (st->dtxGlobalState == SPEECH)) {
+ memcpy(st->lsp_old, st->lsp, M << 2);
+ st->old_log_en = st->log_en;
+ }
+ } /* endif valid_data */
+
+ /* initialize gain predictor memory of other modes */
+ ma_pred_init = (Word16)((st->log_en >> 1) - 9000);
+
+ if (ma_pred_init > 0) {
+ ma_pred_init = 0;
+ }
+
+ if (ma_pred_init < - 14436) {
+ ma_pred_init = -14436;
+ }
+ pred_state->past_qua_en[0] = ma_pred_init;
+ pred_state->past_qua_en[1] = ma_pred_init;
+ pred_state->past_qua_en[2] = ma_pred_init;
+ pred_state->past_qua_en[3] = ma_pred_init;
+
+ /* past_qua_en for other modes than MR122 */
+ ma_pred_init = (Word16)((5443 * ma_pred_init) >> 15);
+
+ /* scale down by factor 20*log10(2) in Q15 */
+ pred_state->past_qua_en_MR122[0] = ma_pred_init;
+ pred_state->past_qua_en_MR122[1] = ma_pred_init;
+ pred_state->past_qua_en_MR122[2] = ma_pred_init;
+ pred_state->past_qua_en_MR122[3] = ma_pred_init;
+ } /* endif sid_frame */
+
+ /*
+ * CN generation
+ * recompute level adjustment factor Q11
+ * st->log_en_adjust = 0.9*st->log_en_adjust +
+ * 0.1*dtx_log_en_adjust[mode]);
+ */
+ st->log_en_adjust = (Word16)(((st->log_en_adjust * 29491) >> 15) + ((
+ (dtx_log_en_adjust[mode] << 5) * 3277) >> 20));
+
+ /* Interpolate SID info */
+ /* Q10 */
+ if (st->since_last_sid > 30) {
+ int_fac = 32767;
+ } else {
+ int_fac = (Word16)((st->since_last_sid + 1) << 10);
+ }
+
+ /* Q10 * Q15 -> Q10 */
+ int_fac = (int_fac * st->true_sid_period_inv) >> 15;
+
+ /* Maximize to 1.0 in Q10 */
+ if (int_fac > 1024) {
+ int_fac = 1024;
+ }
+
+ /* Q10 -> Q14 */
+ int_fac = (Word16)(int_fac << 4);
+
+ /* Q14 * Q11->Q26 */
+ log_en_int = (int_fac * st->log_en) << 1;
+
+ for (i = 0; i < M; i++) {
+ /* Q14 * Q15 -> Q14 */
+ lsp_int[i] = (int_fac * st->lsp[i]) >> 15;
+ }
+
+ /* 1-k in Q14 */
+ int_fac = 16384 - int_fac;
+
+ /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */
+ log_en_int += (int_fac * st->old_log_en) << 1;
+
+ for (i = 0; i < M; i++) {
+ /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
+ lsp_int[i] = lsp_int[i] + ((int_fac * st->lsp_old[i]) >> 15);
+
+ /* Q14 -> Q15 */
+ lsp_int[i] = lsp_int[i] << 1;
+ }
+
+ /* compute the amount of lsf variability */
+ /* -0.6 in Q12 */
+ lsf_variab_factor = st->log_pg_mean - 2457;
+
+ /* *0.3 Q12*Q15 -> Q12 */
+ lsf_variab_factor = 4096 - ((lsf_variab_factor * 9830) >> 15);
+
+ /* limit to values between 0..1 in Q12 */
+ if (lsf_variab_factor >= 4096) {
+ lsf_variab_factor = 32767;
+ } else if (lsf_variab_factor < 0) {
+ lsf_variab_factor = 0;
+ } else {
+ lsf_variab_factor = lsf_variab_factor << 3; /* -> Q15 */
+ }
+
+ /* get index of vector to do variability with */
+ lsf_variab_index = pseudonoise(&st->pn_seed_rx, 3);
+
+ /* convert to lsf */
+ Lsp_lsf(lsp_int, lsf_int);
+
+ /* apply lsf variability */
+ memcpy(lsf_int_variab, lsf_int, M << 2);
+
+ for (i = 0; i < M; i++) {
+ lsf_int_variab[i] = lsf_int_variab[i] + ((lsf_variab_factor * st->
+ lsf_hist_mean[i + lsf_variab_index * M]) >> 15);
+ }
+
+ /* make sure that LSP's are ordered */
+ Reorder_lsf(lsf_int, LSF_GAP);
+ Reorder_lsf(lsf_int_variab, LSF_GAP);
+
+ /* copy lsf to speech decoders lsf state */
+ memcpy(lsfState->past_lsf_q, lsf_int, M << 2);
+
+ /* convert to lsp */
+ Lsf_lsp(lsf_int, lsp_int);
+ Lsf_lsp(lsf_int_variab, lsp_int_variab);
+
+ /* Compute acoeffs Q12 acoeff is used for level
+ * normalization and Post_Filter, acoeff_variab is
+ * used for synthesis filter
+ * by doing this we make sure that the level
+ * in high frequenncies does not jump up and down
+ */
+ Lsp_Az(lsp_int, acoeff);
+ Lsp_Az(lsp_int_variab, acoeff_variab);
+
+ /* For use in Post_Filter */
+ memcpy(&A_t[0], acoeff, MP1 << 2);
+ memcpy(&A_t[MP1], acoeff, MP1 << 2);
+ memcpy(&A_t[MP1 << 1], acoeff, MP1 << 2);
+ memcpy(&A_t[MP1 + MP1 + MP1], acoeff, MP1 << 2);
+
+ /* Compute reflection coefficients Q15 */
+ A_Refl(&acoeff[1], refl);
+
+ /* Compute prediction error in Q15 */
+ /* 0.99997 in Q15 */
+ pred_err = MAX_16;
+
+ for (i = 0; i < M; i++) {
+ pred_err = (pred_err * (MAX_16 - ((refl[i] * refl[i]) >> 15))) >>
+ 15;
+ }
+
+ /* compute logarithm of prediction gain */
+ Log2(pred_err, &log_pg_e, &log_pg_m);
+
+ /* convert exponent and mantissa to Word16 Q12 */
+ /* Q12 */
+ log_pg = (log_pg_e - 15) << 12;
+ /* saturate */
+ if (log_pg < -32768) {
+ log_pg = -32768;
+ }
+ log_pg = (-(log_pg + (log_pg_m >> 3))) >> 1;
+ st->log_pg_mean = (Word16)(((29491 * st->log_pg_mean) >> 15) + ((3277
+ * log_pg) >> 15));
+
+ /* Compute interpolated log energy */
+ /* Q26 -> Q16 */
+ log_en_int = log_en_int >> 10;
+
+ /* Add 4 in Q16 */
+ log_en_int += 262144L;
+
+ /* subtract prediction gain */
+ log_en_int = log_en_int - (log_pg << 4);
+
+ /* adjust level to speech coder mode */
+ log_en_int += st->log_en_adjust << 5;
+ log_en_int_e = (Word16)(log_en_int >> 16);
+ log_en_int_m = (Word16)((log_en_int - (log_en_int_e << 16)) >> 1);
+
+ /* Q4 */
+ level = (Word16)(Pow2(log_en_int_e, log_en_int_m));
+
+ for (i = 0; i < 4; i++) {
+ /* Compute innovation vector */
+ Build_CN_code(&st->pn_seed_rx, ex);
+
+ for (j = 0; j < L_SUBFR; j++) {
+ ex[j] = (level * ex[j]) >> 15;
+ }
+
+ /* Synthesize */
+ Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, mem_syn, 1);
+ } /* next i */
+
+ /* reset codebook averaging variables */
+ averState->hangVar = 20;
+ averState->hangCount = 0;
+
+ if (new_state == DTX_MUTE) {
+ /*
+ * mute comfort noise as it has been quite a long time since
+ * last SID update was performed
+ */
+ Word32 num, denom;
+
+
+ tmp_int_length = st->since_last_sid;
+
+ if (tmp_int_length > 32) {
+ tmp_int_length = 32;
+ }
+
+ if (tmp_int_length == 1) {
+ st->true_sid_period_inv = MAX_16;
+ } else {
+ num = 1024;
+ denom = (tmp_int_length << 10);
+ st->true_sid_period_inv = 0;
+
+ for (i = 0; i < 15; i++) {
+ st->true_sid_period_inv <<= 1;
+ num <<= 1;
+
+ if (num >= denom) {
+ num = num - denom;
+ st->true_sid_period_inv += 1;
+ }
+ }
+ }
+ st->since_last_sid = 0;
+ memcpy(st->lsp_old, st->lsp, M << 2);
+ st->old_log_en = st->log_en;
+
+ /* subtract 1/8 in Q11 i.e -6/8 dB */
+ st->log_en = st->log_en - 256;
+ if (st->log_en < -32768) {
+ st->log_en = -32768;
+ }
+ }
+
+ /*
+ * reset interpolation length timer
+ * if data has been updated.
+ */
+ if ((st->sid_frame != 0) & ((st->valid_data != 0) || ((st->valid_data
+ == 0) & (st->dtxHangoverAdded != 0)))) {
+ st->since_last_sid = 0;
+ st->data_updated = 1;
+ }
+ return;
+}
+
+
+/*
+ * lsp_avg
+ *
+ *
+ * Parameters:
+ * st->lsp_meanSave B: LSP averages
+ * lsp I: LSPs
+ *
+ * Function:
+ * Calculate the LSP averages
+ *
+ * Returns:
+ * void
+ */
+static void lsp_avg(lsp_avgState *st, Word32 *lsp)
+{
+ Word32 i, tmp;
+
+
+ for (i = 0; i < M; i++) {
+ /* mean = 0.84*mean */
+ tmp = (st->lsp_meanSave[i] << 16);
+ tmp -= (EXPCONST * st->lsp_meanSave[i]) << 1;
+
+ /* Add 0.16 of newest LSPs to mean */
+ tmp += (EXPCONST * lsp[i]) << 1;
+
+ /* Save means */
+ tmp += 0x00008000L;
+ st->lsp_meanSave[i] = tmp >> 16;
+ }
+ return;
+}
+
+
+/*
+ * Int_lpc_1and3
+ *
+ *
+ * Parameters:
+ * lsp_old I: LSP vector at the 4th subfr. of past frame [M]
+ * lsp_mid I: LSP vector at the 2nd subframe of present frame [M]
+ * lsp_new I: LSP vector at the 4th subframe of present frame [M]
+ * Az O: interpolated LP parameters in subframes 1 and 3
+ * [AZ_SIZE]
+ *
+ * Function:
+ * Interpolates the LSPs and converts to LPC parameters
+ * to get a different LP filter in each subframe.
+ *
+ * The 20 ms speech frame is divided into 4 subframes.
+ * The LSPs are quantized and transmitted at the 2nd and
+ * 4th subframes (twice per frame) and interpolated at the
+ * 1st and 3rd subframe.
+ *
+ * Returns:
+ * void
+ */
+static void Int_lpc_1and3(Word32 lsp_old[], Word32 lsp_mid[], Word32 lsp_new[],
+ Word32 Az[])
+{
+ Word32 lsp[M];
+ Word32 i;
+
+ Word32 *Az1;
+ Az1 = Az;
+ /* lsp[i] = lsp_mid[i] * 0.5 + lsp_old[i] * 0.5 */
+ for (i = 0; i < 10; i++) {
+ lsp[i] = (lsp_mid[i] >> 1) + (lsp_old[i] >> 1);
+ }
+
+ /* Subframe 1 */
+ Lsp_Az(lsp, Az);
+ Az += MP1;
+
+ /* Subframe 2 */
+ Lsp_Az(lsp_mid, Az);
+ Az += MP1;
+
+ for (i = 0; i < 10; i++) {
+ lsp[i] = (lsp_mid[i] >> 1) + (lsp_new[i] >> 1);
+ }
+
+ /* Subframe 3 */
+ Lsp_Az(lsp, Az);
+ Az += MP1;
+
+ /* Subframe 4 */
+ Lsp_Az(lsp_new, Az);
+ return;
+}
+
+
+/*
+ * Int_lpc_1to3
+ *
+ *
+ * Parameters:
+ * lsp_old I: LSP vector at the 4th subframe of past frame [M]
+ * lsp_new I: LSP vector at the 4th subframe of present frame [M]
+ * Az O: interpolated LP parameters in all subframes
+ * [AZ_SIZE]
+ *
+ * Function:
+ * Interpolates the LSPs and converts to LPC parameters to get a different
+ * LP filter in each subframe.
+ *
+ * The 20 ms speech frame is divided into 4 subframes.
+ * The LSPs are quantized and transmitted at the 4th
+ * subframes (once per frame) and interpolated at the
+ * 1st, 2nd and 3rd subframe.
+ *
+ * Returns:
+ * void
+ */
+static void Int_lpc_1to3(Word32 lsp_old[], Word32 lsp_new[], Word32 Az[])
+{
+ Word32 lsp[M];
+ Word32 i;
+
+
+ for (i = 0; i < 10; i++) {
+ lsp[i] = (lsp_new[i] >> 2) + (lsp_old[i] - (lsp_old[i] >> 2));
+ }
+
+ /* Subframe 1 */
+ Lsp_Az(lsp, Az);
+ Az += MP1;
+
+ for (i = 0; i < 10; i++) {
+ lsp[i] = (lsp_old[i] >> 1) + (lsp_new[i] >> 1);
+ }
+
+ /* Subframe 2 */
+ Lsp_Az(lsp, Az);
+ Az += MP1;
+
+ for (i = 0; i < 10; i++) {
+ lsp[i] = (lsp_old[i] >> 2) + (lsp_new[i] - (lsp_new[i] >> 2));
+ }
+
+ /* Subframe 3 */
+ Lsp_Az(lsp, Az);
+ Az += MP1;
+
+ /* Subframe 4 */
+ Lsp_Az(lsp_new, Az);
+ return;
+}
+
+
+/*
+ * D_plsf_5
+ *
+ *
+ * Parameters:
+ * st->past_lsf_q I: Past dequantized LFSs
+ * st->past_r_q B: past quantized residual
+ * bfi B: bad frame indicator
+ * indice I: quantization indices of 3 submatrices, Q0
+ * lsp1_q O: quantized 1st LSP vector
+ * lsp2_q O: quantized 2nd LSP vector
+ *
+ * Function:
+ * Decodes the 2 sets of LSP parameters in a frame
+ * using the received quantization indices.
+ *
+ * Returns:
+ * void
+ */
+static void D_plsf_5(D_plsfState *st, Word16 bfi, Word16 *indice, Word32 *lsp1_q
+ , Word32 *lsp2_q)
+{
+ Word32 lsf1_r[M], lsf2_r[M], lsf1_q[M], lsf2_q[M];
+ Word32 i, temp1, temp2, sign;
+ const Word32 *p_dico;
+
+
+ /* if bad frame */
+ if (bfi != 0) {
+ /* use the past LSFs slightly shifted towards their mean */
+ for (i = 0; i < M; i += 2) {
+ /* lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*meanLsf[i]; */
+ lsf1_q[i] = ((st->past_lsf_q[i] * ALPHA_122) >> 15) + ((mean_lsf_5[i]
+ * ONE_ALPHA_122) >> 15);
+ lsf1_q[i + 1] = ((st->past_lsf_q[i + 1] * ALPHA_122) >> 15) + ((
+ mean_lsf_5[i + 1] * ONE_ALPHA_122) >> 15);
+ }
+ memcpy(lsf2_q, lsf1_q, M << 2);
+
+ /* estimate past quantized residual to be used in next frame */
+ for (i = 0; i < M; i += 2) {
+ /* temp = meanLsf[i] + st->past_r_q[i] * LSPPpred_facMR122; */
+ temp1 = mean_lsf_5[i] + ((st->past_r_q[i] * LSP_PRED_FAC_MR122) >>
+ 15);
+ temp2 = mean_lsf_5[i + 1] + ((st->past_r_q[i + 1] * LSP_PRED_FAC_MR122
+ ) >> 15);
+ st->past_r_q[i] = lsf2_q[i] - temp1;
+ st->past_r_q[i + 1] = lsf2_q[i + 1] - temp2;
+ }
+ }
+
+ /* if good LSFs received */
+ else {
+ /* decode prediction residuals from 5 received indices */
+ p_dico = &dico1_lsf_5[indice[0] << 2];
+ lsf1_r[0] = *p_dico++;
+ lsf1_r[1] = *p_dico++;
+ lsf2_r[0] = *p_dico++;
+ lsf2_r[1] = *p_dico++;
+ p_dico = &dico2_lsf_5[indice[1] << 2];
+ lsf1_r[2] = *p_dico++;
+ lsf1_r[3] = *p_dico++;
+ lsf2_r[2] = *p_dico++;
+ lsf2_r[3] = *p_dico++;
+ sign = (Word16)(indice[2] & 1);
+ i = indice[2] >> 1;
+ p_dico = &dico3_lsf_5[i << 2];
+
+ if (sign == 0) {
+ lsf1_r[4] = *p_dico++;
+ lsf1_r[5] = *p_dico++;
+ lsf2_r[4] = *p_dico++;
+ lsf2_r[5] = *p_dico++;
+ } else {
+ lsf1_r[4] = (Word16)(-(*p_dico++));
+ lsf1_r[5] = (Word16)(-(*p_dico++));
+ lsf2_r[4] = (Word16)(-(*p_dico++));
+ lsf2_r[5] = (Word16)(-(*p_dico++));
+ }
+ p_dico = &dico4_lsf_5[(indice[3] << 2)];
+ lsf1_r[6] = *p_dico++;
+ lsf1_r[7] = *p_dico++;
+ lsf2_r[6] = *p_dico++;
+ lsf2_r[7] = *p_dico++;
+ p_dico = &dico5_lsf_5[(indice[4] << 2)];
+ lsf1_r[8] = *p_dico++;
+ lsf1_r[9] = *p_dico++;
+ lsf2_r[8] = *p_dico++;
+ lsf2_r[9] = *p_dico++;
+
+ /* Compute quantized LSFs and update the past quantized residual */
+ for (i = 0; i < M; i++) {
+ temp1 = mean_lsf_5[i] + ((st->past_r_q[i] * LSP_PRED_FAC_MR122) >>
+ 15);
+ lsf1_q[i] = lsf1_r[i] + temp1;
+ lsf2_q[i] = lsf2_r[i] + temp1;
+ st->past_r_q[i] = lsf2_r[i];
+ }
+ }
+
+ /* verification that LSFs have minimum distance of LSF_GAP Hz */
+ Reorder_lsf(lsf1_q, LSF_GAP);
+ Reorder_lsf(lsf2_q, LSF_GAP);
+ memcpy(st->past_lsf_q, lsf2_q, M << 2);
+
+ /* convert LSFs to the cosine domain */
+ Lsf_lsp(lsf1_q, lsp1_q);
+ Lsf_lsp(lsf2_q, lsp2_q);
+ return;
+}
+
+
+/*
+ * Dec_lag3
+ *
+ *
+ * Parameters:
+ * index I: received pitch index
+ * t0_min I: minimum of search range
+ * t0_max I: maximum of search range
+ * i_subfr I: subframe flag
+ * T0_prev I: integer pitch delay of last subframe used
+ * in 2nd and 4th subframes
+ * T0 O: integer part of pitch lag
+ * T0_frac O : fractional part of pitch lag
+ * flag4 I : flag for encoding with 4 bits
+ * Function:
+ * Decoding of fractional pitch lag with 1/3 resolution.
+ * Extract the integer and fraction parts of the pitch lag from
+ * the received adaptive codebook index.
+ *
+ * The fractional lag in 1st and 3rd subframes is encoded with 8 bits
+ * while that in 2nd and 4th subframes is relatively encoded with 4, 5
+ * and 6 bits depending on the mode.
+ *
+ * Returns:
+ * void
+ */
+static void Dec_lag3(Word32 index, Word32 t0_min, Word32 t0_max, Word32 i_subfr
+ , Word32 T0_prev, Word32 *T0, Word32 *T0_frac, Word32 flag4)
+{
+ Word32 i, tmp_lag;
+
+
+ /* if 1st or 3rd subframe */
+ if (i_subfr == 0) {
+ if (index < 197) {
+ *T0 = (((index + 2) * 10923) >> 15) + 19;
+ i = *T0 + *T0 + *T0;
+ *T0_frac = (index - i) + 58;
+ } else {
+ *T0 = index - 112;
+ *T0_frac = 0;
+ }
+ }
+
+ /* 2nd or 4th subframe */
+ else {
+ if (flag4 == 0) {
+ /* 'normal' decoding: either with 5 or 6 bit resolution */
+ i = (((index + 2) * 10923) >> 15) - 1;
+ *T0 = i + t0_min;
+ i = i + i + i;
+ *T0_frac = (index - 2) - i;
+ } else {
+ /* decoding with 4 bit resolution */
+ tmp_lag = T0_prev;
+
+ if ((tmp_lag - t0_min) > 5) {
+ tmp_lag = t0_min + 5;
+ }
+
+ if ((t0_max - tmp_lag) > 4) {
+ tmp_lag = t0_max - 4;
+ }
+
+ if (index < 4) {
+ i = (tmp_lag - 5);
+ *T0 = i + index;
+ *T0_frac = 0;
+ } else {
+ if (index < 12) {
+ i = (((index - 5) * 10923) >> 15) - 1;
+ *T0 = i + tmp_lag;
+ i = i + i + i;
+ *T0_frac = (index - 9) - i;
+ } else {
+ i = (index - 12) + tmp_lag;
+ *T0 = i + 1;
+ *T0_frac = 0;
+ }
+ }
+ } /* end if (decoding with 4 bit resolution) */
+ }
+ return;
+}
+
+
+/*
+ * Pred_lt_3or6_40
+ *
+ *
+ * Parameters:
+ * exc B: excitation buffer
+ * T0 I: integer pitch lag
+ * frac I: fraction of lag
+ * flag3 I: if set, upsampling rate = 3 (6 otherwise)
+ *
+ * Function:
+ * Compute the result of long term prediction with fractional
+ * interpolation of resolution 1/3 or 1/6. (Interpolated past excitation).
+ *
+ * Once the fractional pitch lag is determined,
+ * the adaptive codebook vector v(n) is computed by interpolating
+ * the past excitation signal u(n) at the given integer delay k
+ * and phase (fraction) :
+ *
+ * 9 9
+ * v(n) = SUM[ u(n-k-i) * b60(t+i*6) ] + SUM[ u(n-k+1+i) * b60(6-t+i*6) ],
+ * i=0 i=0
+ * n = 0, ...,39, t = 0, ...,5.
+ *
+ * The interpolation filter b60 is based on a Hamming windowed sin(x)/x
+ * function truncated at ± 59 and padded with zeros at ± 60 (b60(60)=0)).
+ * The filter has a cut-off frequency (-3 dB) at 3 600 Hz in
+ * the over-sampled domain.
+ *
+ * Returns:
+ * void
+ */
+static void Pred_lt_3or6_40(Word32 exc[], Word32 T0, Word32 frac, Word32 flag3)
+{
+ Word32 s, i;
+ Word32 *x0, *x1, *x2;
+ const Word32 *c1, *c2;
+
+
+ x0 = &exc[ - T0];
+ frac = -frac;
+
+ if (flag3 != 0) {
+ frac <<= 1; /* inter_3l[k] = inter6[2*k] -> k' = 2*k */
+ }
+
+ if (frac < 0) {
+ frac += 6;
+ x0--;
+ }
+ c1 = &inter6[frac];
+ c2 = &inter6[6 - frac];
+
+ for (i = 0; i < 40; i++) {
+ x1 = x0++;
+ x2 = x0;
+ s = x1[0] * c1[0];
+ s += x1[ - 1] * c1[6];
+ s += x1[ - 2] * c1[12];
+ s += x1[ - 3] * c1[18];
+ s += x1[ - 4] * c1[24];
+ s += x1[ - 5] * c1[30];
+ s += x1[ - 6] * c1[36];
+ s += x1[ - 7] * c1[42];
+ s += x1[ - 8] * c1[48];
+ s += x1[ - 9] * c1[54];
+ s += x2[0] * c2[0];
+ s += x2[1] * c2[6];
+ s += x2[2] * c2[12];
+ s += x2[3] * c2[18];
+ s += x2[4] * c2[24];
+ s += x2[5] * c2[30];
+ s += x2[6] * c2[36];
+ s += x2[7] * c2[42];
+ s += x2[8] * c2[48];
+ s += x2[9] * c2[54];
+ exc[i] = (s + 0x4000) >> 15;
+
+ }
+}
+
+
+/*
+ * Dec_lag6
+ *
+ *
+ * Parameters:
+ * index I: received pitch index
+ * pit_min I: minimum pitch lag
+ * pit_max I: maximum pitch lag
+ * i_subfr I: subframe flag
+ * T0 B: integer part of pitch lag
+ * T0_frac O : fractional part of pitch lag
+ *
+ * Function:
+ * Decoding of fractional pitch lag with 1/6 resolution.
+ * Extract the integer and fraction parts of the pitch lag from
+ * the received adaptive codebook index.
+ *
+ * The fractional lag in 1st and 3rd subframes is encoded with 9 bits
+ * while that in 2nd and 4th subframes is relatively encoded with 6 bits.
+ * Note that in relative encoding only 61 values are used. If the
+ * decoder receives 61, 62, or 63 as the relative pitch index, it means
+ * that a transmission error occurred. In this case, the pitch lag from
+ * previous subframe (actually from previous frame) is used.
+ *
+ * Returns:
+ * void
+ */
+static void Dec_lag6(Word32 index, Word32 pit_min, Word32 pit_max, Word32
+ i_subfr, Word32 *T0, Word32 *T0_frac)
+{
+ Word32 t0_min, t0_max, i;
+
+
+ /* if 1st or 3rd subframe */
+ if (i_subfr == 0) {
+ if (index < 463) {
+ /* T0 = (index+5)/6 + 17 */
+ *T0 = (index + 5) / 6 + 17;
+ i = *T0 + *T0 + *T0;
+
+ /* *T0_frac = index - T0*6 + 105 */
+ *T0_frac = (index - (i + i)) + 105;
+ } else {
+ *T0 = index - 368;
+ *T0_frac = 0;
+ }
+ }
+
+ /* second or fourth subframe */
+ else {
+ /* find t0_min and t0_max for 2nd (or 4th) subframe */
+ t0_min = *T0 - 5;
+
+ if (t0_min < pit_min) {
+ t0_min = pit_min;
+ }
+ t0_max = t0_min + 9;
+
+ if (t0_max > pit_max) {
+ t0_max = pit_max;
+ t0_min = t0_max - 9;
+ }
+
+ /* i = (index+5)/6 - 1 */
+ i = (index + 5) / 6 - 1;
+ *T0 = i + t0_min;
+ i = i + i + i;
+ *T0_frac = (index - 3) - (i + i);
+ }
+}
+
+
+/*
+ * decompress10
+ *
+ *
+ * Parameters:
+ * MSBs I: MSB part of the index
+ * LSBs I: LSB part of the index
+ * index1 I: index for first pos in posIndex
+ * index2 I: index for second pos in posIndex
+ * index3 I: index for third pos in posIndex
+ * pos_indx O: position of 3 pulses (decompressed)
+ * Function:
+ * Decompression of the linear codeword
+ *
+ * Returns:
+ * void
+ */
+static void decompress10(Word32 MSBs, Word32 LSBs, Word32 index1, Word32 index2
+ , Word32 index3, Word32 pos_indx[])
+{
+ Word32 divMSB;
+
+ if (MSBs > 124) {
+ MSBs = 124;
+ }
+ /*
+ * pos_indx[index1] = ((MSBs-25*(MSBs/25))%5)*2 + (LSBs-4*(LSBs/4))%2;
+ * pos_indx[index2] = ((MSBs-25*(MSBs/25))/5)*2 + (LSBs-4*(LSBs/4))/2;
+ * pos_indx[index3] = (MSBs/25)*2 + LSBs/4;
+ */
+ divMSB = MSBs / 25;
+ pos_indx[index1] = (((MSBs - 25 * (divMSB)) % 5) << 1) + (LSBs & 0x1
+ );
+ pos_indx[index2] = (((MSBs - 25 * (divMSB)) / 5) << 1) + ((LSBs &
+ 0x2) >> 1);
+ pos_indx[index3] = (divMSB << 1) + (LSBs >> 2);
+ return;
+}
+
+
+/*
+ * decompress_codewords
+ *
+ *
+ * Parameters:
+ * indx I: position of 8 pulses (compressed)
+ * pos_indx O: position index of 8 pulses (position only)
+ *
+ * Function:
+ * Decompression of the linear codewords to 4+three indeces
+ * one bit from each pulse is made robust to errors by
+ * minimizing the phase shift of a bit error.
+ *
+ * i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust
+ * i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust
+ * i3,i7 => one index (5+2) bits, 2-3 LSbs more robust
+ *
+ * Returns:
+ * void
+ */
+static void decompress_codewords(Word16 indx[], Word32 pos_indx[])
+{
+ Word32 ia, ib, MSBs, LSBs, MSBs0_24, tmp;
+
+
+ /*
+ * First index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits
+ * MSBs = indx[NB_TRACK]/8;
+ * LSBs = indx[NB_TRACK]%8;
+ */
+ MSBs = *indx >> 3;
+ LSBs = *indx & 0x7;
+ decompress10(MSBs, LSBs, 0, 4, 1, pos_indx);
+
+ /*
+ * Second index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits
+ * MSBs = indx[NB_TRACK+1]/8;
+ * LSBs = indx[NB_TRACK+1]%8;
+ */
+ MSBs = indx[1] >> 3;
+ LSBs = indx[1] & 0x7;
+ decompress10(MSBs, LSBs, 2, 6, 5, pos_indx);
+
+ /*
+ * Third index: 10x10 -> 2x5x2x5-> 25x2x2 -> 5+1x2 bits
+ * MSBs = indx[NB_TRACK+2]/4;
+ * LSBs = indx[NB_TRACK+2]%4;
+ * MSBs0_24 = (MSBs*25+12)/32;
+ * if ((MSBs0_24/5)%2==1)
+ * pos_indx[3] = (4-(MSBs0_24%5))*2 + LSBs%2;
+ * else
+ * pos_indx[3] = (MSBs0_24%5)*2 + LSBs%2;
+ * pos_indx[7] = (MSBs0_24/5)*2 + LSBs/2;
+ */
+ MSBs = indx[2] >> 2;
+ LSBs = indx[2] & 0x3;
+ MSBs0_24 = (((MSBs * 25) + 12) >> 5);
+ tmp = (MSBs0_24 * 6554) >> 15;
+ ia = tmp & 0x1;
+ ib = (MSBs0_24 - (tmp * 5));
+
+ if (ia == 1) {
+ ib = 4 - ib;
+ }
+ pos_indx[3] = (ib << 1) + (LSBs & 0x1);
+ pos_indx[7] = (tmp << 1) + (LSBs >> 1);
+}
+
+
+/*
+ * decode_2i40_9bits
+ *
+ *
+ * Parameters:
+ * subNr I: subframe number
+ * sign I: signs of 2 pulses
+ * index I: Positions of the 2 pulses
+ * cod O: algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * Algebraic codebook decoder
+ *
+ * Returns:
+ * void
+ */
+static void decode_2i40_9bits(Word32 subNr, Word32 sign, Word32 index, Word32
+ cod[])
+{
+ Word32 pos[2];
+ Word32 i, j, k;
+
+
+ /* Decode the positions */
+ /* table bit is the MSB */
+ j = (index & 64) >> 6;
+ i = index & 7;
+
+ /* pos0 =i*5+startPos[j*8+subNr*2] */
+ i = (i + (i << 2));
+ k = startPos[(j << 3) + (subNr << 1)];
+ pos[0] = i + k;
+ index = index >> 3;
+ i = index & 7;
+
+ /* pos1 =i*5+startPos[j*8+subNr*2+1] */
+ i = (i + (i << 2));
+ k = startPos[((j << 3) + (subNr << 1)) + 1];
+ pos[1] = (Word16)(i + k);
+
+ /* decode the signs and build the codeword */
+ memset(cod, 0, L_SUBFR << 2);
+
+ for (j = 0; j < 2; j++) {
+ i = sign & 1;
+ sign = sign >> 1;
+
+ if (i != 0) {
+ cod[pos[j]] = 8191; /* +1.0 */
+ } else {
+ cod[pos[j]] = -8192; /* -1.0 */
+ }
+ }
+ return;
+}
+
+
+/*
+ * decode_2i40_11bits
+ *
+ *
+ * Parameters:
+ * sign I: signs of 2 pulses
+ * index I: Positions of the 2 pulses
+ * cod O: algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * Algebraic codebook decoder
+ *
+ * Returns:
+ * void
+ */
+static void decode_2i40_11bits(Word32 sign, Word32 index, Word32 cod[])
+{
+ Word32 pos[2];
+ Word32 i, j;
+
+
+ /* Decode the positions */
+ j = index & 1;
+ index = index >> 1;
+ i = index & 7;
+
+ /* pos0 =i*5+1+j*2 */
+ i = (i + (i << 2));
+ i = (i + 1);
+ j = (j << 1);
+ pos[0] = i + j;
+ index = index >> 3;
+ j = index & 3;
+ index = index >> 2;
+ i = index & 7;
+
+ if (j == 3) {
+ /* pos1 =i*5+4 */
+ i = (i + (i << 2));
+ pos[1] = i + 4;
+ } else {
+ /* pos1 =i*5+j */
+ i = (i + (i << 2));
+ pos[1] = i + j;
+ }
+
+ /* decode the signs and build the codeword */
+ memset(cod, 0, L_SUBFR << 2);
+
+ for (j = 0; j < 2; j++) {
+ i = sign & 1;
+ sign = sign >> 1;
+
+ if (i != 0) {
+ cod[pos[j]] = 8191; /* +1.0 */
+ } else {
+ cod[pos[j]] = -8192; /* -1.0 */
+ }
+ }
+ return;
+}
+
+
+/*
+ * decode_3i40_14bits
+ *
+ *
+ * Parameters:
+ * sign I: signs of 3 pulses
+ * index I: Positions of the 3 pulses
+ * cod O: algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * Algebraic codebook decoder
+ *
+ * Returns:
+ * void
+ */
+static void decode_3i40_14bits(Word32 sign, Word32 index, Word32 cod[])
+{
+ Word32 pos[3];
+ Word32 i, j;
+
+
+ /* Decode the positions */
+ i = index & 7;
+
+ /* pos0 =i*5 */
+ pos[0] = i + (i << 2);
+ index = index >> 3;
+ j = index & 1;
+ index = index >> 1;
+ i = index & 7;
+
+ /* pos1 =i*5+1+j*2 */
+ i = (i + (i << 2));
+ i = (i + 1);
+ j = (j << 1);
+ pos[1] = i + j;
+ index = index >> 3;
+ j = index & 1;
+ index = index >> 1;
+ i = index & 7;
+
+ /* pos2 =i*5+2+j*2 */
+ i = (i + (i << 2));
+ i = (i + 2);
+ j = (j << 1);
+ pos[2] = i + j;
+
+ /* decode the signs and build the codeword */
+ memset(cod, 0, L_SUBFR << 2);
+
+ for (j = 0; j < 3; j++) {
+ i = sign & 1;
+ sign = sign >> 1;
+
+ if (i > 0) {
+ cod[pos[j]] = 8191; /* +1.0 */
+ } else {
+ cod[pos[j]] = -8192; /* -1.0 */
+ }
+ }
+ return;
+}
+
+
+/*
+ * decode_3i40_14bits
+ *
+ *
+ * Parameters:
+ * sign I: signs of 4 pulses
+ * index I: Positions of the 4 pulses
+ * cod O: algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * Algebraic codebook decoder
+ *
+ * Returns:
+ * void
+ */
+static void decode_4i40_17bits(Word32 sign, Word32 index, Word32 cod[])
+{
+ Word32 pos[4];
+ Word32 i, j;
+
+
+ /* Decode the positions */
+ i = index & 7;
+ i = dgray[i];
+
+ /* pos0 =i*5 */
+ pos[0] = i + (i << 2);
+ index = index >> 3;
+ i = index & 7;
+ i = dgray[i];
+
+ /* pos1 =i*5+1 */
+ i = (i + (i << 2));
+ pos[1] = i + 1;
+ index = index >> 3;
+ i = index & 7;
+ i = dgray[i];
+
+ /* pos2 =i*5+1 */
+ i = (i + (i << 2));
+ pos[2] = i + 2;
+ index = index >> 3;
+ j = index & 1;
+ index = index >> 1;
+ i = index & 7;
+ i = dgray[i];
+
+ /* pos3 =i*5+3+j */
+ i = (i + (i << 2));
+ i = (i + 3);
+ pos[3] = i + j;
+
+ /* decode the signs and build the codeword */
+ memset(cod, 0, L_SUBFR << 2);
+
+ for (j = 0; j < 4; j++) {
+ i = sign & 1;
+ sign = sign >> 1;
+
+ if (i != 0) {
+ cod[pos[j]] = 8191;
+ } else {
+ cod[pos[j]] = -8192;
+ }
+ }
+ return;
+}
+
+
+/*
+ * decode_8i40_31bits
+ *
+ *
+ * Parameters:
+ * index I: index of 8 pulses (sign+position)
+ * cod O: algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * Algebraic codebook decoder
+ *
+ * Returns:
+ * void
+ */
+static void decode_8i40_31bits(Word16 index[], Word32 cod[])
+{
+ Word32 linear_codewords[8];
+ Word32 i, j, pos1, pos2, sign;
+
+
+ memset(cod, 0, L_CODE << 2);
+ decompress_codewords(&index[NB_TRACK_MR102], linear_codewords);
+
+ /* decode the positions and signs of pulses and build the codeword */
+ for (j = 0; j < NB_TRACK_MR102; j++) {
+ /* compute index i */
+ i = linear_codewords[j];
+ i <<= 2;
+
+ /* position of pulse "j" */
+ pos1 = i + j;
+
+ if (index[j] == 0) {
+ sign = POS_CODE; /* +1.0 */
+ } else {
+ sign = -NEG_CODE; /* -1.0 */
+ }
+
+ /* compute index i */
+ i = linear_codewords[j + 4];
+ i = i << 2;
+
+ /* position of pulse "j+4" */
+ pos2 = i + j;
+ cod[pos1] = sign;
+
+ if (pos2 < pos1) {
+ sign = -(sign);
+ }
+ cod[pos2] = cod[pos2] + sign;
+ }
+ return;
+}
+
+
+/*
+ * decode_10i40_35bits
+ *
+ *
+ * Parameters:
+ * index I: index of 10 pulses (sign+position)
+ * cod O: algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * Algebraic codebook decoder
+ *
+ * Returns:
+ * void
+ */
+static void decode_10i40_35bits(Word16 index[], Word32 cod[])
+{
+ Word32 i, j, pos1, pos2, sign, tmp;
+
+
+ memset(cod, 0, L_CODE << 2);
+
+ /* decode the positions and signs of pulses and build the codeword */
+ for (j = 0; j < 5; j++) {
+ /* compute index i */
+ tmp = index[j];
+ i = tmp & 7;
+ i = dgray[i];
+ i = (i * 5);
+
+ /* position of pulse "j" */
+ pos1 = (i + j);
+ i = (tmp >> 3) & 1;
+
+ if (i == 0) {
+ sign = 4096; /* +1.0 */
+ } else {
+ sign = -4096; /* -1.0 */
+ }
+
+ /* compute index i */
+ i = index[j + 5] & 7;
+ i = dgray[i];
+ i = i * 5;
+
+ /* position of pulse "j+5" */
+ pos2 = (i + j);
+ cod[pos1] = sign;
+
+ if (pos2 < pos1) {
+ sign = -(sign);
+ }
+ cod[pos2] = cod[pos2] + sign;
+ }
+ return;
+}
+
+
+/*
+ * gmed_n
+ *
+ *
+ * Parameters:
+ * ind I: values
+ * n I: The number of gains (odd)
+ *
+ * Function:
+ * Calculates N-point median.
+ *
+ * Returns:
+ * index of the median value
+ */
+static Word32 gmed_n(Word32 ind[], Word32 n)
+{
+ Word32 tmp[NMAX], tmp2[NMAX];
+ Word32 max, medianIndex, i, j, ix = 0;
+
+
+ for (i = 0; i < n; i++) {
+ tmp2[i] = ind[i];
+ }
+
+ for (i = 0; i < n; i++) {
+ max = -32767;
+
+ for (j = 0; j < n; j++) {
+ if (tmp2[j] >= max) {
+ max = tmp2[j];
+ ix = j;
+ }
+ }
+ tmp2[ix] = -32768;
+ tmp[i] = ix;
+ }
+ medianIndex = tmp[(n >> 1)];
+ return(ind[medianIndex]);
+}
+
+
+/*
+ * ec_gain_pitch
+ *
+ *
+ * Parameters:
+ * st->pbuf I: last five gains
+ * st->past_gain_pit I: past gain
+ * state I: state of the state machine
+ * gain_pitch O: pitch gain
+ *
+ * Function:
+ * Calculates pitch from previous values.
+ *
+ * Returns:
+ * void
+ */
+static void ec_gain_pitch(ec_gain_pitchState *st, Word16 state, Word32 *
+ gain_pitch)
+{
+ Word32 tmp;
+
+
+ /* calculate median of last five gains */
+ tmp = gmed_n(st->pbuf, 5);
+
+ /* new gain = minimum(median, past_gain) * pdown[state] */
+ if (tmp > st->past_gain_pit) {
+ tmp = st->past_gain_pit;
+ }
+ *gain_pitch = (tmp * pdown[state]) >> 15;
+}
+
+
+/*
+ * d_gain_pitch
+ *
+ *
+ * Parameters:
+ * mode I: AMR mode
+ * index I: index of quantization
+ *
+ * Function:
+ * Decodes the pitch gain using the received index
+ *
+ * Returns:
+ * gain
+ */
+static Word32 d_gain_pitch(enum Mode mode, Word32 index)
+{
+ Word32 gain;
+
+
+ if (mode == MR122) {
+ /* clear 2 LSBits */
+ gain = (qua_gain_pitch[index] >> 2) << 2;
+ } else {
+ gain = qua_gain_pitch[index];
+ }
+ return gain;
+}
+
+
+/*
+ * ec_gain_pitch_update
+ *
+ *
+ * Parameters:
+ * st->prev_gp B: previous pitch gain
+ * st->past_gain_pit O: past gain
+ * st->pbuf B: past gain buffer
+ * bfi I: bad frame indicator
+ * prev_bf I: previous frame was bad
+ * gain_pitch B: pitch gain
+ *
+ * Function:
+ * Update the pitch gain concealment state
+ * Limit gain_pitch if the previous frame was bad
+ *
+ * Returns:
+ * gain
+ */
+static void ec_gain_pitch_update(ec_gain_pitchState *st, Word32 bfi,
+ Word32 prev_bf, Word32 *gain_pitch)
+{
+ if (bfi == 0) {
+ if (prev_bf != 0) {
+ if (*gain_pitch > st->prev_gp) {
+ *gain_pitch = st->prev_gp;
+ }
+ }
+ st->prev_gp = *gain_pitch;
+ }
+ st->past_gain_pit = *gain_pitch;
+
+ /* if (st->past_gain_pit > 1.0) */
+ if (st->past_gain_pit > 16384) {
+ st->past_gain_pit = 16384;
+ }
+ st->pbuf[0] = st->pbuf[1];
+ st->pbuf[1] = st->pbuf[2];
+ st->pbuf[2] = st->pbuf[3];
+ st->pbuf[3] = st->pbuf[4];
+ st->pbuf[4] = st->past_gain_pit;
+}
+
+
+/*
+ * gc_pred (366)
+ *
+ *
+ * Parameters:
+ * st->past_qua_en I: MA predictor
+ * st->past_qua_en_MR122 I: MA predictor MR122
+ * mode I: AMR mode
+ * code I: innovative codebook vector
+ * exp_gcode0 O: predicted gain factor (exponent)
+ * frac_gcode0 O: predicted gain factor (fraction)
+ * exp_en I: innovation energy (MR795) (exponent)
+ * frac_en I: innovation energy (MR795) (fraction)
+ *
+ * Function:
+ * MA prediction of the innovation energy
+ *
+ * Mean removed innovation energy (dB) in subframe n
+ * N-1
+ * E(n) = 10*log(gc*gc * SUM[(code(i) * code(i)]/N) - EMean
+ * i=0
+ * N=40
+ *
+ * Mean innovation energy (dB)
+ * N-1
+ * Ei(n) = 10*log(SUM[(code(i) * code(i)]/N)
+ * i=0
+ *
+ * Predicted energy
+ * 4
+ * Ep(n) = SUM[b(i) * R(n-i)]
+ * i=1
+ * b = [0.68 0.58 0.34 0.19]
+ * R(k) is quantified prediction error at subframe k
+ *
+ * E_Mean = 36 dB (MR122)
+ *
+ * Predicted gain gc is found by
+ *
+ * gc = POW[10, 0.05 * (Ep(n) + EMean - Ei)]
+ *
+ * Returns:
+ * void
+ */
+static void gc_pred(gc_predState *st, enum Mode mode, Word32 *code, Word32 *
+ exp_gcode0, Word32 *frac_gcode0, Word32 *exp_en, Word32 *frac_en)
+{
+ Word32 exp, frac, ener_code = 0, i = 0;
+
+
+ /* energy of code:
+ * ener_code = sum(code[i]^2)
+ */
+ while (i < L_SUBFR) {
+ ener_code += code[i] * code[i];
+ i++;
+ }
+
+ if ((0x3fffffff <= ener_code) | (ener_code < 0)) {
+ ener_code = MAX_32;
+ } else {
+ ener_code <<= 1;
+ }
+
+ if (mode == MR122) {
+ Word32 ener;
+
+
+ /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
+ ener_code = ((ener_code + 0x00008000L) >> 16) * 52428;
+
+ /* Q9 * Q20 -> Q30 */
+ /* energy of code:
+ * ener_code(Q17) = 10 * Log10(energy) / constant
+ * = 1/2 * Log2(energy)
+ * constant = 20*Log10(2)
+ */
+ /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
+ Log2(ener_code, &exp, &frac);
+ ener_code = ((exp - 30) << 16) + (frac << 1);
+
+ /* Q16 for log(), ->Q17 for 1/2 log() */
+ /*
+ * predicted energy:
+ * ener(Q24) = (Emean + sum{pred[i]*pastEn[i]})/constant
+ * = MEAN_ENER + sum(pred[i]*past_qua_en[i])
+ * constant = 20*Log10(2)
+ */
+ ener = 0;
+ i = 0;
+
+ while (i < 4) {
+ ener += st->past_qua_en_MR122[i] * pred_MR122[i];
+ i++;
+ }
+ ener <<= 1;
+ ener += MEAN_ENER_MR122;
+
+ /*
+ * predicted codebook gain
+
+ * gc0 = Pow10( (ener*constant - ener_code*constant) / 20 )
+ * = Pow2(ener-ener_code)
+ * = Pow2(int(d)+frac(d))
+ */
+ ener = (ener - ener_code) >> 1; /* Q16 */
+ *exp_gcode0 = ener >> 16;
+ *frac_gcode0 = (ener >> 1) - (*exp_gcode0 << 15);
+ }
+
+ /* all modes except 12.2 */
+ else {
+ Word32 tmp, gcode0;
+ int exp_code;
+
+
+ /*
+ * Compute: meansEner - 10log10(ener_code/ LSufr)
+ */
+ exp_code = 0;
+ if (ener_code != 0) {
+ while (!(ener_code & 0x40000000)) {
+ exp_code++;
+ ener_code = ener_code << 1;
+ }
+ }
+
+ /* Log2 = log2 + 27 */
+ Log2_norm(ener_code, exp_code, &exp, &frac);
+
+ /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
+ /* Q0.Q15 * Q13 -> Q14 */
+ tmp = (exp * (-49320)) + (((frac * (-24660)) >> 15) << 1);
+
+ /*
+ * tmp = meansEner - 10log10(ener_code/L_SUBFR)
+ * = meansEner - 10log10(ener_code) + 10log10(L_SUBFR)
+ * = K - fact * Log2(ener_code)
+ * = K - fact * log2(ener_code) - fact*27
+ *
+ * ==> K = meansEner + fact*27 + 10log10(L_SUBFR)
+ *
+ * meansEner = 33 = 540672 Q14 (MR475, MR515, MR59)
+ * meansEner = 28.75 = 471040 Q14 (MR67)
+ * meansEner = 30 = 491520 Q14 (MR74)
+ * meansEner = 36 = 589824 Q14 (MR795)
+ * meansEner = 33 = 540672 Q14 (MR102)
+ * 10log10(L_SUBFR) = 16.02 = 262481.51 Q14
+ * fact * 27 = 1331640 Q14
+ * -----------------------------------------
+ * (MR475, MR515, MR59) K = 2134793.51 Q14 ~= 16678 * 64 * 2
+ * (MR67) K = 2065161.51 Q14 ~= 32268 * 32 * 2
+ * (MR74) K = 2085641.51 Q14 ~= 32588 * 32 * 2
+ * (MR795) K = 2183945.51 Q14 ~= 17062 * 64 * 2
+ * (MR102) K = 2134793.51 Q14 ~= 16678 * 64 * 2
+ */
+ if (mode == MR102) {
+ /* mean = 33 dB */
+ tmp += 2134784; /* Q14 */
+ } else if (mode == MR795) {
+ /* mean = 36 dB */
+ tmp += 2183936; /* Q14 */
+
+ /*
+ * ener_code = <xn xn> * 2^27*2^exp_code
+ * frac_en = ener_code / 2^16
+ * = <xn xn> * 2^11*2^exp_code
+ * <xn xn> = <xn xn>*2^11*2^exp * 2^exp_en
+ * := frac_en * 2^exp_en
+ *
+ * ==> exp_en = -11-exp_code;
+ */
+ *frac_en = ener_code >> 16;
+ *exp_en = -11 - exp_code;
+ } else if (mode == MR74) {
+ /* mean = 30 dB */
+ tmp += 2085632; /* Q14 */
+ } else if (mode == MR67) {
+ /* mean = 28.75 dB */
+ tmp += 2065152; /* Q14 */
+ } else { /* MR59, MR515, MR475 */
+ /* mean = 33 dB */
+ tmp += 2134784; /* Q14 */
+ }
+
+ /*
+ * Compute gcode0
+ * = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + meanEner
+ */
+ tmp = tmp << 9; /* Q23 */
+
+ /* Q13 * Q10 -> Q23 */
+ i = 0;
+
+ while (i < 4) {
+ tmp += pred[i] * st->past_qua_en[i];
+ i++;
+ }
+ gcode0 = tmp >> 15; /* Q8 */
+
+ /*
+ * gcode0 = pow(10.0, gcode0/20)
+ * = pow(2, 3.3219*gcode0/20)
+ * = pow(2, 0.166*gcode0)
+ */
+ /* 5439 Q15 = 0.165985 */
+ /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15) */
+ /* For IS641 bitexactness */
+ if (mode == MR74) {
+ /* Q8 * Q15 -> Q24 */
+ tmp = gcode0 * 10878;
+ } else {
+ /* Q8 * Q15 -> Q24 */
+ tmp = gcode0 * 10886;
+ }
+ tmp = tmp >> 9; /* -> Q15 */
+
+ /* -> Q0.Q15 */
+ *exp_gcode0 = tmp >> 15;
+ *frac_gcode0 = tmp - (*exp_gcode0 * 32768);
+ }
+}
+
+
+/*
+ * gc_pred_update
+ *
+ *
+ * Parameters:
+ * st->past_qua_en B: MA predictor
+ * st->past_qua_en_MR122 B: MA predictor MR122
+ * qua_ener_MR122 I: quantized energy for update (log2(quaErr))
+ * qua_ener I: quantized energy for update (20*log10(quaErr))
+ *
+ * Function:
+ * Update MA predictor with last quantized energy
+ *
+ * Returns:
+ * void
+ */
+static void gc_pred_update(gc_predState *st, Word32 qua_ener_MR122,
+ Word32 qua_ener)
+{
+ Word32 i;
+
+
+ for (i = 3; i > 0; i--) {
+ st->past_qua_en[i] = st->past_qua_en[i - 1];
+ st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1];
+ }
+ st->past_qua_en_MR122[0] = qua_ener_MR122; /* log2 (quaErr), Q10 */
+ st->past_qua_en[0] = qua_ener; /* 20*log10(quaErr), Q10 */
+}
+
+
+/*
+ * Dec_gain
+ *
+ *
+ * Parameters:
+ * pred_state->past_qua_en B: MA predictor
+ * pred_state->past_qua_en_MR122 B: MA predictor MR122
+ * mode I: AMR mode
+ * index I: index of quantization
+ * code I: Innovative vector
+ * evenSubfr I: Flag for even subframes
+ * gain_pit O: Pitch gain
+ * gain_cod O: Code gain
+ *
+ * Function:
+ * Decode the pitch and codebook gains
+ *
+ * Returns:
+ * void
+ */
+static void Dec_gain(gc_predState *pred_state, enum Mode mode, Word32 index,
+ Word32 code[], Word32 evenSubfr, Word32 *gain_pit, Word32 *gain_cod)
+{
+ Word32 frac, gcode0, exp, qua_ener, qua_ener_MR122, g_code, tmp;
+ const Word32 *p;
+
+
+ /* Read the quantized gains (table depends on mode) */
+ index = index << 2;
+
+ if ((mode == MR102) || (mode == MR74) || (mode == MR67)) {
+ p = &table_gain_highrates[index];
+ *gain_pit = *p++;
+ g_code = *p++;
+ qua_ener_MR122 = *p++;
+ qua_ener = *p;
+ } else {
+ if (mode == MR475) {
+ index = index + ((1 - evenSubfr) << 1);
+ p = &table_gain_MR475[index];
+ *gain_pit = *p++;
+ g_code = *p++;
+
+ /*
+ * calculate predictor update values (not stored in 4.75
+ * quantizer table to save space):
+ * qua_ener = log2(g)
+ * qua_ener_MR122 = 20*log10(g)
+ */
+ /* Log2(x Q12) = log2(x) + 12 */
+ Log2(g_code, &exp, &frac);
+ exp = exp - 12;
+ tmp = frac >> 5;
+
+ if ((frac & ((Word16)1 << 4)) != 0) {
+ tmp++;
+ }
+ qua_ener_MR122 = tmp + (exp << 10);
+
+ /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
+ tmp = exp * 49320;
+ tmp += (((frac * 24660) >> 15) << 1);
+
+ /* Q12 * Q0 = Q13 -> Q10 */
+ qua_ener = ((tmp << 13) + 0x00008000L) >> 16;
+ } else {
+ p = &table_gain_lowrates[index];
+ *gain_pit = *p++;
+ g_code = *p++;
+ qua_ener_MR122 = *p++;
+ qua_ener = *p;
+ }
+ }
+
+ /*
+ * predict codebook gain
+ * gc0 = Pow2(int(d)+frac(d))
+ * = 2^exp + 2^frac
+ * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)
+ */
+ gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL);
+ gcode0 = Pow2(14, frac);
+
+ /*
+ * read quantized gains, update table of past quantized energies
+ * st->past_qua_en(Q10) = 20 * Log10(gFac) / constant
+ * = Log2(gFac)
+ * = qua_ener
+ * constant = 20*Log10(2)
+ */
+ if (exp < 11) {
+ *gain_cod = (g_code * gcode0) >> (25 - exp);
+ } else {
+ tmp = ((g_code * gcode0) << (exp - 9));
+
+ if ((tmp >> (exp - 9)) != (g_code * gcode0)) {
+ *gain_cod = 0x7FFF;
+ } else {
+ *gain_cod = tmp >> 16;
+ }
+ }
+
+ /* update table of past quantized energies */
+ gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
+ return;
+}
+
+
+/*
+ * gc_pred_average_limited
+ *
+ *
+ * Parameters:
+ * st->past_qua_en I: MA predictor
+ * st->past_qua_en_MR122 I: MA predictor MR122
+ * ener_avg_MR122 O: everaged quantized energy (log2(quaErr))
+ * ener_avg O: averaged quantized energy (20*log10(quaErr))
+ *
+ * Function:
+ * Compute average limited quantized energy
+ * Returns:
+ * void
+ */
+static void gc_pred_average_limited(gc_predState *st, Word32 *ener_avg_MR122,
+ Word32 *ener_avg)
+{
+ Word32 av_pred_en, i;
+
+
+ /* do average in MR122 mode (log2() domain) */
+ av_pred_en = 0;
+
+ for (i = 0; i < NPRED; i++) {
+ av_pred_en = (av_pred_en + st->past_qua_en_MR122[i]);
+ }
+
+ /* av_pred_en = 0.25*av_pred_en */
+ av_pred_en = (av_pred_en * 8192) >> 15;
+
+ /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
+ if (av_pred_en < MIN_ENERGY_MR122) {
+ av_pred_en = MIN_ENERGY_MR122;
+ }
+ *ener_avg_MR122 = (Word16)av_pred_en;
+
+ /* do average for other modes (20*log10() domain) */
+ av_pred_en = 0;
+
+ for (i = 0; i < NPRED; i++) {
+ av_pred_en = (av_pred_en + st->past_qua_en[i]);
+ if (av_pred_en < -32768) {
+ av_pred_en = -32768;
+ } else if (av_pred_en > 32767) {
+ av_pred_en = 32767;
+ }
+ }
+
+ /* av_pred_en = 0.25*av_pred_en */
+ av_pred_en = (av_pred_en * 8192) >> 15;
+
+ *ener_avg = av_pred_en;
+}
+
+
+/*
+ * ec_gain_code
+ *
+ *
+ * Parameters:
+ * st->gbuf I: last five gains
+ * st->past_gain_code I: past gain
+ * pred_state B: MA predictor state
+ * state I: state of the state machine
+ * gain_code O: decoded innovation gain
+ *
+ * Function:
+ * Conceal the codebook gain
+ *
+ * Returns:
+ * void
+ */
+static void ec_gain_code(ec_gain_codeState *st, gc_predState *pred_state,
+ Word16 state, Word32 *gain_code)
+{
+ Word32 tmp, qua_ener_MR122, qua_ener;
+
+
+ /* calculate median of last five gain values */
+ tmp = gmed_n(st->gbuf, 5);
+
+ /* new gain = minimum(median, past_gain) * cdown[state] */
+ if (tmp > st->past_gain_code) {
+ tmp = st->past_gain_code;
+ }
+ tmp = (tmp * cdown[state]) >> 15;
+ *gain_code = tmp;
+
+ /*
+ * update table of past quantized energies with average of
+ * current values
+ */
+ gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
+ gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
+}
+
+
+/*
+ * ec_gain_code_update
+ *
+ *
+ * Parameters:
+ * st->gbuf B: last five gains
+ * st->past_gain_code O: past gain
+ * st->prev_gc B previous gain
+ * bfi I: bad indicator
+ * prev_bf I: previous frame bad indicator
+ * gain_code O: decoded innovation gain
+ *
+ * Function:
+ * Update the codebook gain concealment state
+ *
+ * Returns:
+ * void
+ */
+static void ec_gain_code_update(ec_gain_codeState *st, Word16 bfi,
+ Word16 prev_bf, Word32 *gain_code)
+{
+ /* limit gain_code by previous good gain if previous frame was bad */
+ if (bfi == 0) {
+ if (prev_bf != 0) {
+ if (*gain_code > st->prev_gc) {
+ *gain_code = st->prev_gc;
+ }
+ }
+ st->prev_gc = *gain_code;
+ }
+
+ /* update EC states: previous gain, gain buffer */
+ st->past_gain_code = *gain_code;
+ st->gbuf[0] = st->gbuf[1];
+ st->gbuf[1] = st->gbuf[2];
+ st->gbuf[2] = st->gbuf[3];
+ st->gbuf[3] = st->gbuf[4];
+ st->gbuf[4] = *gain_code;
+ return;
+}
+
+
+/*
+ * d_gain_code
+ *
+ *
+ * Parameters:
+ * pred_state B: MA predictor state
+ * mode I: AMR mode (MR795 or MR122)
+ * index I: received quantization index
+ * code I: innovation codevector
+ * gain_code O: decoded innovation gain
+ *
+ * Function:
+ * Decode the fixed codebook gain using the received index
+ *
+ * Returns:
+ * void
+ */
+static void d_gain_code(gc_predState *pred_state, enum Mode mode, Word32 index,
+ Word32 code[], Word32 *gain_code)
+{
+ Word32 g_code0, exp, frac, qua_ener_MR122, qua_ener;
+ Word32 exp_inn_en, frac_inn_en, tmp, tmp2, i;
+ const Word32 *p;
+
+
+ /*
+ * Decode codebook gain
+ */
+ gc_pred(pred_state, mode, code, &exp, &frac, &exp_inn_en, &frac_inn_en);
+ p = &qua_gain_code[((index + index) + index)];
+
+ /* Different scalings between MR122 and the other modes */
+ if (mode == MR122) {
+ /* predicted gain */
+ g_code0 = Pow2(exp, frac);
+
+ if (g_code0 <= 2047) {
+ g_code0 = g_code0 << 4;
+ } else {
+ g_code0 = 32767;
+ }
+ *gain_code = ((g_code0 * *p++) >> 15) << 1;
+ if (*gain_code & 0xFFFF8000) {
+ *gain_code = 32767;
+ }
+
+ } else {
+ g_code0 = Pow2(14, frac);
+ tmp = (*p++ * g_code0) << 1;
+ exp = 9 - exp;
+
+ if (exp > 0) {
+ tmp = tmp >> exp;
+ } else {
+ for (i = exp; i < 0; i++) {
+ tmp2 = tmp << 1;
+ if ((tmp ^ tmp2) & 0x80000000) {
+ tmp = (tmp & 0x80000000) ? 0x80000000 : 0x7FFFFFFF;
+ break;
+ } else {
+ tmp = tmp2;
+ }
+ }
+ }
+ *gain_code = tmp >> 16;
+ if (*gain_code & 0xFFFF8000) {
+ *gain_code = 32767;
+ }
+ }
+
+ /*
+ * update table of past quantized energies
+ */
+ qua_ener_MR122 = *p++;
+ qua_ener = *p++;
+ gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
+ return;
+}
+
+
+/*
+ * Int_lsf
+ *
+ *
+ * Parameters:
+ * lsf_old I: LSF vector at the 4th subframe of past frame
+ * lsf_new I: LSF vector at the 4th subframe of present frame
+ * i_subfr I: current subframe
+ * lsf_out O: interpolated LSF parameters for current subframe
+ *
+ * Function:
+ * Interpolates the LSFs for selected subframe
+ *
+ * The LSFs are interpolated at the 1st, 2nd and 3rd
+ * ubframe and only forwarded at the 4th subframe.
+ *
+ * sf1: 3/4 F0 + 1/4 F1
+ * sf2: 1/2 F0 + 1/2 F1
+ * sf3: 1/4 F0 + 3/4 F1
+ * sf4: F1
+ *
+ * Returns:
+ * void
+ */
+static void Int_lsf(Word32 lsf_old[], Word32 lsf_new[], int i_subfr, Word32
+ lsf_out[])
+{
+ Word32 i;
+
+
+ switch (i_subfr) {
+ case 0:
+ for (i = 0; i < 10; i++) {
+ lsf_out[i] = lsf_old[i] - (lsf_old[i] >> 2) + (lsf_new[i] >> 2);
+ }
+ break;
+
+ case 40:
+ for (i = 0; i < 10; i++) {
+ lsf_out[i] = (lsf_old[i] >> 1) + (lsf_new[i] >> 1);
+ }
+ break;
+
+ case 80:
+ for (i = 0; i < 10; i++) {
+ lsf_out[i] = (lsf_old[i] >> 2) - (lsf_new[i] >> 2) +
+ lsf_new[i];
+ }
+ break;
+
+ case 120:
+ memcpy(lsf_out, lsf_new, M << 2);
+ break;
+ }
+}
+
+
+/*
+ * Cb_gain_average
+ *
+ *
+ * Parameters:
+ * st->cbGainHistory B: codebook gain history
+ * st->hangCount B: hangover counter
+ * mode I: AMR mode
+ * gain_code I: codebook gain
+ * lsp I: The LSP for the current frame
+ * lspAver I: The average of LSP for 8 frames
+ * bfi I: bad frame indication
+ * prev_bf I: previous bad frame indication
+ * pdfi I: potential degraded bad frame indication
+ * prev_pdf I: previous potential degraded bad frame indication
+ * inBackgroundNoise I: background noise decision
+ * voicedHangover I: number of frames after last voiced frame
+ *
+ * Function:
+ * The mixed codebook gain, used to make codebook gain more smooth in background
+ *
+ *
+ * Returns:
+ * void
+ */
+static Word32 Cb_gain_average(Cb_gain_averageState *st, enum Mode mode, Word32
+ gain_code, Word32 lsp[], Word32 lspAver[], Word16 bfi, Word16 prev_bf,
+ Word16 pdfi, Word16 prev_pdf, Word32 inBackgroundNoise, Word32
+ voicedHangover)
+{
+ Word32 tmp[M];
+ Word32 i, cbGainMix, tmp_diff, bgMix, cbGainMean, sum, diff, tmp1, tmp2;
+ int shift1, shift2, shift;
+
+
+ /* set correct cbGainMix for MR74, MR795, MR122 */
+ cbGainMix = gain_code;
+
+ /*
+ * Store list of CB gain needed in the CB gain averaging *
+ */
+ st->cbGainHistory[0] = st->cbGainHistory[1];
+ st->cbGainHistory[1] = st->cbGainHistory[2];
+ st->cbGainHistory[2] = st->cbGainHistory[3];
+ st->cbGainHistory[3] = st->cbGainHistory[4];
+ st->cbGainHistory[4] = st->cbGainHistory[5];
+ st->cbGainHistory[5] = st->cbGainHistory[6];
+ st->cbGainHistory[6] = gain_code;
+
+ /* compute lsp difference */
+ for (i = 0; i < M; i++) {
+ tmp1 = labs(lspAver[i] - lsp[i]);
+ shift1 = 0;
+ if (tmp1 != 0) {
+ while (!(tmp1 & 0x2000)) {
+ shift1++;
+ tmp1 = tmp1 << 1;
+ }
+ }
+ tmp2 = lspAver[i];
+ shift2 = 0;
+ if (tmp2 != 0) {
+ while (!(tmp2 & 0x4000)) {
+ shift2++;
+ tmp2 = tmp2 << 1;
+ }
+ }
+ tmp[i] = (tmp1 << 15) / tmp2;
+ shift = 2 + shift1 - shift2;
+
+ if (shift >= 0) {
+ tmp[i] = tmp[i] >> shift;
+ } else {
+ tmp[i] = tmp[i] << -(shift);
+ }
+ }
+ diff = *tmp + tmp[1] + tmp[2] + tmp[3] + tmp[4] + tmp[5] + tmp[6] + tmp[7] +
+ tmp[8] + tmp[9];
+
+ /* saturate */
+ if (diff > 32767) {
+ diff = 32767;
+ }
+
+ /* Compute hangover */
+ st->hangVar += 1;
+
+ if (diff <= 5325) {
+ st->hangVar = 0;
+ }
+
+ if (st->hangVar > 10) {
+ /* Speech period, reset hangover variable */
+ st->hangCount = 0;
+ }
+
+ /* Compute mix constant (bgMix) */
+ bgMix = 8192;
+
+ /* MR475, MR515, MR59, MR67, MR102 */
+ if ((mode <= MR67) | (mode == MR102)) {
+ /* disable mix if too short time since */
+ if ((st->hangCount >= 40) & (diff <= 5325)) { /* 0.65 in Q13 */
+ /* if errors and presumed noise make smoothing probability stronger */
+ if (((((pdfi != 0) & (prev_pdf != 0)) | (bfi != 0) | (
+ prev_bf != 0)) & ((voicedHangover > 1)) & (
+ inBackgroundNoise != 0) & (mode < MR67))) {
+ /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */
+ tmp_diff = diff - 4506; /* 0.55 in Q13 */
+
+ /* max(0.0, diff-0.55) */
+ tmp1 = 0;
+
+ if (tmp_diff > 0) {
+ tmp1 = tmp_diff;
+ }
+
+ /* min(0.25, tmp1) */
+ if (2048 >= tmp1) {
+ bgMix = tmp1 << 2;
+ }
+ } else {
+ /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */
+ tmp_diff = diff - 3277; /* 0.4 in Q13 */
+
+ /* max(0.0, diff-0.40) */
+ tmp1 = 0;
+
+ if (tmp_diff > 0) {
+ tmp1 = tmp_diff;
+ }
+
+ /* min(0.25, tmp1) */
+ if (2048 >= tmp1) {
+ bgMix = tmp1 << 2;
+ }
+ }
+ }
+
+ /*
+ * Smoothen the cb gain trajectory
+ * smoothing depends on mix constant bgMix
+ */
+ sum = st->cbGainHistory[2] + st->cbGainHistory[3] + st->cbGainHistory[4] +
+ st->cbGainHistory[5] + st->cbGainHistory[6];
+
+ if (sum > 163822) {
+ cbGainMean = 32767;
+ } else {
+ cbGainMean = (3277 * sum + 0x00002000L) >> 14; /* Q1 */
+ }
+
+ /* more smoothing in error and bg noise (NB no DFI used here) */
+ if (((bfi != 0) | (prev_bf != 0)) & (inBackgroundNoise != 0) & (
+ mode < MR67)) {
+ sum = 9362 * (st->cbGainHistory[0] + st->cbGainHistory[1] + st->
+ cbGainHistory[2] + st->cbGainHistory[3] + st->cbGainHistory[4] +
+ st->cbGainHistory[5] + st->cbGainHistory[6]);
+ cbGainMean = (sum + 0x00008000L) >> 16; /* Q1 */
+ }
+
+ /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */
+ sum = bgMix * cbGainMix; /* sum in Q14 */
+ sum += cbGainMean << 13;
+ sum -= bgMix * cbGainMean;
+ cbGainMix = (sum + 0x00001000L) >> 13;
+
+ /* Q1 */
+ }
+ st->hangCount += 1;
+ if (st->hangCount & 0x80000000) {
+ st->hangCount = 40;
+ }
+ return cbGainMix;
+}
+
+
+/*
+ * ph_disp
+ *
+ *
+ * Parameters:
+ * state->gainMem B: LTP gain memory
+ * state->prevCbGain B: Codebook gain memory
+ * mode I: AMR mode
+ * x B: LTP excitation signal -> total excitation signal
+ * cbGain I: Codebook gain
+ * ltpGain I: LTP gain
+ * inno B: Innovation vector
+ * pitch_fac I: pitch factor used to scale the LTP excitation
+ * tmp_shift I: shift factor applied to sum of scaled LTP ex & innov.
+ * before rounding
+ *
+ * Function:
+ * Adaptive phase dispersion; forming of total excitation
+ *
+ *
+ * Returns:
+ * void
+ */
+static void ph_disp(ph_dispState *state, enum Mode mode, Word32 x[],
+ Word32 cbGain, Word32 ltpGain, Word32 inno[],
+ Word32 pitch_fac, Word32 tmp_shift)
+{
+ Word32 inno_sav[L_SUBFR], ps_poss[L_SUBFR];
+ Word32 i, i1, impNr, temp1, temp2, j, nze, nPulse, ppos;
+ const Word32 *ph_imp; /* Pointer to phase dispersion filter */
+
+
+ /* Update LTP gain memory */
+ state->gainMem[4] = state->gainMem[3];
+ state->gainMem[3] = state->gainMem[2];
+ state->gainMem[2] = state->gainMem[1];
+ state->gainMem[1] = state->gainMem[0];
+ state->gainMem[0] = ltpGain;
+
+ /* basic adaption of phase dispersion */
+ /* no dispersion */
+ impNr = 2;
+
+ /* if (ltpGain < 0.9) */
+ if (ltpGain < PHDTHR2LTP) {
+ /* maximum dispersion */
+ impNr = 0;
+
+ /* if (ltpGain > 0.6 */
+ if (ltpGain > PHDTHR1LTP) {
+ /* medium dispersion */
+ impNr = 1;
+ }
+ }
+
+ /* onset indicator */
+ /* onset = (cbGain > onFact * cbGainMem[0]) */
+ temp1 = ((state->prevCbGain * ONFACTPLUS1) + 0x1000) >> 13;
+
+ if (cbGain > temp1) {
+ state->onset = ONLENGTH;
+ } else {
+ if (state->onset > 0) {
+ state->onset--;
+ }
+ }
+
+ /*
+ * if not onset, check ltpGain buffer and use max phase dispersion if
+ * half or more of the ltpGain-parameters say so
+ */
+ if (state->onset == 0) {
+ /* Check LTP gain memory and set filter accordingly */
+ i1 = 0;
+
+ for (i = 0; i < PHDGAINMEMSIZE; i++) {
+ if (state->gainMem[i] < PHDTHR1LTP) {
+ i1++;
+ }
+ }
+
+ if (i1 > 2) {
+ impNr = 0;
+ }
+ }
+
+ /* Restrict decrease in phase dispersion to one step if not onset */
+ if ((impNr > (state->prevState + 1)) & (state->onset == 0)) {
+ impNr--;
+ }
+
+ /* if onset, use one step less phase dispersion */
+ if ((impNr < 2) & (state->onset > 0)) {
+ impNr++;
+ }
+
+ /* disable for very low levels */
+ if (cbGain < 10) {
+ impNr = 2;
+ }
+
+ if (state->lockFull == 1) {
+ impNr = 0;
+ }
+
+ /* update static memory */
+ state->prevState = impNr;
+ state->prevCbGain = cbGain;
+
+ /*
+ * do phase dispersion for all modes but 12.2 and 7.4;
+ * don't modify the innovation if impNr >=2 (= no phase disp)
+ */
+ if ((mode != MR122) & (mode != MR102) & (mode != MR74) & (impNr < 2)
+ ) {
+ /*
+ * track pulse positions, save innovation,
+ * and initialize new innovation
+ */
+ nze = 0;
+
+ for (i = 0; i < L_SUBFR; i++) {
+ if (inno[i] != 0) {
+ ps_poss[nze] = i;
+ nze++;
+ }
+ }
+ memcpy(inno_sav, inno, L_SUBFR << 2);
+ memset(inno, 0, L_SUBFR << 2);
+
+ /* Choose filter corresponding to codec mode and dispersion criterium */
+ ph_imp = ph_imp_mid;
+
+ if (impNr == 0) {
+ ph_imp = ph_imp_low;
+ }
+
+ if (mode == MR795) {
+ ph_imp = ph_imp_mid_MR795;
+
+ if (impNr == 0) {
+ ph_imp = ph_imp_low_MR795;
+ }
+ }
+
+ /* Do phase dispersion of innovation */
+ for (nPulse = 0; nPulse < nze; nPulse++) {
+ ppos = ps_poss[nPulse];
+
+ /* circular convolution with impulse response */
+ j = 0;
+
+ for (i = ppos; i < L_SUBFR; i++) {
+ /* inno[i1] += inno_sav[ppos] * ph_imp[i1-ppos] */
+ temp1 = (inno_sav[ppos] * ph_imp[j++]) >> 15;
+ inno[i] = inno[i] + temp1;
+ }
+
+ for (i = 0; i < ppos; i++) {
+ /* inno[i] += inno_sav[ppos] * ph_imp[L_SUBFR-ppos+i] */
+ temp1 = (inno_sav[ppos] * ph_imp[j++]) >> 15;
+ inno[i] = inno[i] + temp1;
+ }
+ }
+ }
+
+ /*
+ * compute total excitation for synthesis part of decoder
+ * (using modified innovation if phase dispersion is active)
+ */
+ for (i = 0; i < L_SUBFR; i++) {
+ /* x[i] = gain_pit*x[i] + cbGain*code[i]; */
+ temp1 = x[i] * pitch_fac + inno[i] * cbGain;
+ temp2 = temp1 << tmp_shift;
+ x[i] = (temp2 + 0x4000) >> 15;
+ if (labs(x[i]) > 32767) {
+ if ((temp1 ^ temp2) & 0x80000000) {
+ x[i] = (temp1 & 0x80000000) ? -32768 : 32767;
+ } else {
+ x[i] = (temp2 & 0x80000000) ? -32768 : 32767;
+ }
+ }
+ }
+ return;
+}
+
+
+/*
+ * sqrt_l_exp
+ *
+ *
+ * Parameters:
+ * x I: input value
+ * exp O: right shift to be applied to result
+ *
+ * Function:
+ * Sqrt with exponent value.
+ *
+ * y = sqrt(x)
+ * x = f * 2^-e, 0.5 <= f < 1 (normalization)
+ * y = sqrt(f) * 2^(-e/2)
+ *
+ * a) e = 2k --> y = sqrt(f) * 2^-k
+ * (k = e div 2, 0.707 <= sqrt(f) < 1)
+ * b) e = 2k+1 --> y = sqrt(f/2) * 2^-k
+ * (k = e div 2, 0.5 <= sqrt(f/2) < 0.707)
+ *
+ *
+ * Returns:
+ * y output value
+ */
+static Word32 sqrt_l_exp(Word32 x, Word32 *exp)
+{
+ Word32 y, a, i, tmp;
+ int e;
+
+
+ if (x <= (Word32)0) {
+ *exp = 0;
+ return(Word32)0;
+ }
+ e = 0;
+ if (x != 0) {
+ tmp = x;
+ while (!(tmp & 0x40000000)) {
+ e++;
+ tmp = tmp << 1;
+ }
+ }
+ e = e & 0xFFFE;
+ x = (x << e);
+ *exp = (Word16)e;
+ x = (x >> 9);
+ i = (Word16)(x >> 16);
+ x = (x >> 1);
+ a = x & (Word16)0x7fff;
+ i = (i - 16);
+ y = (sqrt_table[i] << 16);
+ tmp = (sqrt_table[i] - sqrt_table[i + 1]);
+ y -= (tmp * a) << 1;
+ return(y);
+}
+
+
+/*
+ * Ex_ctrl
+ *
+ *
+ * Parameters:
+ * excitation B: Current subframe excitation
+ * excEnergy I: Exc. Energy, sqrt(totEx*totEx)
+ * exEnergyHist I: History of subframe energies
+ * voicedHangover I: number of frames after last voiced frame
+ * prevBFI I: Set i previous bad frame indicators
+ * carefulFlag I: Restrict dymamic in scaling
+ *
+ * Function:
+ * Charaterice synthesis speech and detect background noise
+ *
+ * Returns:
+ * background noise decision; 0 = no bgn, 1 = bgn
+ */
+static Word16 Ex_ctrl(Word32 excitation[], Word32 excEnergy, Word32
+ exEnergyHist[], Word32 voicedHangover, Word16 prevBFI, Word16 carefulFlag
+ )
+{
+ Word32 i, testEnergy, scaleFactor, avgEnergy, prevEnergy, T0;
+ int exp;
+
+
+ /* get target level */
+ avgEnergy = gmed_n(exEnergyHist, 9);
+ prevEnergy = (exEnergyHist[7] + exEnergyHist[8]) >> 1;
+
+ if (exEnergyHist[8] < prevEnergy) {
+ prevEnergy = exEnergyHist[8];
+ }
+
+ /* upscaling to avoid too rapid energy rises for some cases */
+ if ((excEnergy<avgEnergy) & (excEnergy>5)) {
+ /* testEnergy = 4*prevEnergy; */
+ testEnergy = prevEnergy << 2;
+
+ if ((voicedHangover < 7) || prevBFI != 0) {
+ /* testEnergy = 3*prevEnergy */
+ testEnergy = testEnergy - prevEnergy;
+ }
+
+ if (avgEnergy > testEnergy) {
+ avgEnergy = testEnergy;
+ }
+
+ /* scaleFactor=avgEnergy/excEnergy in Q0 */
+ exp = 0;
+ if (excEnergy != 0) {
+ while (!(excEnergy & 0x4000)) {
+ exp++;
+ excEnergy = excEnergy << 1;
+ }
+ }
+ excEnergy = 536838144 / excEnergy;
+ T0 = (avgEnergy * excEnergy) << 1;
+ T0 = (T0 >> (20 - exp));
+
+ if (T0 > 32767) {
+ /* saturate */
+ T0 = 32767;
+ }
+ scaleFactor = T0;
+
+ /* test if scaleFactor > 3.0 */
+ if ((carefulFlag != 0) & (scaleFactor > 3072)) {
+ scaleFactor = 3072;
+ }
+
+ /* scale the excitation by scaleFactor */
+ for (i = 0; i < L_SUBFR; i++) {
+ T0 = (scaleFactor * excitation[i]) << 1;
+ T0 = (T0 >> 11);
+ excitation[i] = T0;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * Inv_sqrt
+ *
+ *
+ * Parameters:
+ * x I: input value
+ *
+ * Function:
+ * 1/sqrt(x)
+ *
+ * Returns:
+ * y 1/sqrt(x)
+ */
+static Word32 Inv_sqrt(Word32 x)
+{
+ int i, a, tmp, exp;
+ Word32 y;
+
+
+ if (x <= (Word32)0) {
+ return((Word32)0x3fffffffL);
+ }
+ exp = 0;
+ while (!(x & 0x40000000)) {
+ exp++;
+ x = x << 1;
+ }
+
+ /* x is normalized */
+ exp = (30 - exp);
+
+ /* If exponent even -> shift right */
+ if ((exp & 1) == 0) {
+ x = (x >> 1);
+ }
+ exp = (exp >> 1);
+ exp = (exp + 1);
+ x = (x >> 9);
+
+ /* Extract b25-b31 */
+ i = (Word16)(x >> 16);
+
+ /* Extract b10-b24 */
+ x = (x >> 1);
+ a = x & (Word16)0x7fff;
+ i = (i - 16);
+
+ /* table[i] << 16 */
+ y = inv_sqrt_table[i] << 16;
+
+ /* table[i] - table[i+1]) */
+ tmp = (inv_sqrt_table[i] - inv_sqrt_table[i + 1]);
+
+ /* y -= tmp*a*2 */
+ y -= (tmp * a) << 1;
+
+ /* denormalization */
+ y = (y >> exp);
+ return(y);
+}
+
+
+/*
+ * energy_old
+ *
+ *
+ * Parameters:
+ * in I: input value
+ *
+ * Function:
+ * Energy of signal
+ *
+ * Returns:
+ * Energy
+ */
+static Word32 energy_old(Word32 in[])
+{
+ Word32 temp, i, sum = 0;
+
+
+ for (i = 0; i < L_SUBFR; i += 8) {
+ temp = in[i] >> 2;
+ sum += temp * temp;
+ temp = in[i + 1] >> 2;
+ sum += temp * temp;
+ temp = in[i + 2] >> 2;
+ sum += temp * temp;
+ temp = in[i + 3] >> 2;
+ sum += temp * temp;
+ temp = in[i + 4] >> 2;
+ sum += temp * temp;
+ temp = in[i + 5] >> 2;
+ sum += temp * temp;
+ temp = in[i + 6] >> 2;
+ sum += temp * temp;
+ temp = in[i + 7] >> 2;
+ sum += temp * temp;
+ }
+
+ if (sum & 0xC0000000) {
+ return 0x7FFFFFFF;
+ }
+ return(sum << 1);
+}
+
+
+/*
+ * energy_new
+ *
+ *
+ * Parameters:
+ * in I: input value
+ *
+ * Function:
+ * Energy of signal
+ *
+ * Returns:
+ * Energy
+ */
+static Word32 energy_new(Word32 in[])
+{
+ Word32 i, s = 0, overflow = 0;
+
+ s += in[0] * in[0];
+ for (i = 1; i < L_SUBFR; i += 3) {
+ s += in[i] * in[i];
+ s += in[i + 1] * in[i + 1];
+ s += in[i + 2] * in[i + 2];
+
+
+ if (s & 0xC0000000) {
+ overflow = 1;
+ break;
+ }
+ }
+
+ /* check for overflow */
+ if (overflow) {
+ s = energy_old(in);
+ } else {
+ s = (s >> 3);
+ }
+ return s;
+}
+
+
+/*
+ * agc2
+ *
+ *
+ * Parameters:
+ * sig_in I: Post_Filter input signal
+ * sig_out B: Post_Filter output signal
+ *
+ * Function:
+ * Scales the excitation on a subframe basis
+ *
+ * Returns:
+ * Energy
+ */
+static void agc2(Word32 *sig_in, Word32 *sig_out)
+{
+ Word32 s;
+ int i, exp;
+ Word16 gain_in, gain_out, g0;
+
+
+ /* calculate gain_out with exponent */
+ s = energy_new(sig_out);
+
+ if (s == 0) {
+ return;
+ }
+ exp = 0;
+ while (!(s & 0x20000000)) {
+ exp++;
+ s = s << 1;
+ }
+
+ gain_out = (Word16)((s + 0x00008000L) >> 16);
+
+ /* calculate gain_in with exponent */
+ s = energy_new(sig_in);
+
+ if (s == 0) {
+ g0 = 0;
+ } else {
+ i = 0;
+ while (!(s & 0x40000000)) {
+ i++;
+ s = s << 1;
+ }
+
+ if (s < 0x7fff7fff) {
+ gain_in = (Word16)((s + 0x00008000L) >> 16);
+ } else {
+ gain_in = 32767;
+ }
+ exp = (exp - i);
+
+ /*
+ * g0 = sqrt(gain_in/gain_out);
+ */
+ /* s = gain_out / gain_in */
+ s = (gain_out << 15) / gain_in;
+ s = (s << 7);
+
+ if (exp > 0) {
+ s = (s >> exp);
+ } else {
+ s = (s << (-exp));
+ }
+ s = Inv_sqrt(s);
+ g0 = (Word16)(((s << 9) + 0x00008000L) >> 16);
+ }
+
+ /* sig_out(n) = gain(n) * sig_out(n) */
+ for (i = 0; i < L_SUBFR; i++) {
+ sig_out[i] = (sig_out[i] * g0) >> 12;
+ }
+ return;
+}
+
+
+/*
+ * Bgn_scd
+ *
+ *
+ * Parameters:
+ * st->frameEnergyHist B: Frame Energy memory
+ * st->bgHangover B: Background hangover counter
+ * ltpGainHist I: LTP gain history
+ * speech I: synthesis speech frame
+ * voicedHangover O: number of frames after last voiced frame
+ *
+ * Function:
+ * Charaterice synthesis speech and detect background noise
+ *
+ * Returns:
+ * inbgNoise background noise decision; 0 = no bgn, 1 = bgn
+ */
+static Word16 Bgn_scd(Bgn_scdState *st, Word32 ltpGainHist[], Word32 speech[],
+ Word32 *voicedHangover)
+{
+ Word32 temp, ltpLimit, frame_energyMin, currEnergy, noiseFloor, maxEnergy,
+ maxEnergyLastPart, s, i;
+ Word16 prevVoiced, inbgNoise;
+
+
+ /*
+ * Update the inBackgroundNoise flag (valid for use in next frame if BFI)
+ * it now works as a energy detector floating on top
+ * not as good as a VAD.
+ */
+ s = 0;
+
+ for (i = 0; i < L_FRAME; i++) {
+ s += speech[i] * speech[i];
+ }
+
+ if ((s < 0xFFFFFFF) & (s >= 0)) {
+ currEnergy = s >> 13;
+ } else {
+ currEnergy = 32767;
+ }
+ frame_energyMin = 32767;
+
+ for (i = 0; i < L_ENERGYHIST; i++) {
+ if (st->frameEnergyHist[i] < frame_energyMin) {
+ frame_energyMin = st->frameEnergyHist[i];
+ }
+ }
+
+ /* Frame Energy Margin of 16 */
+ noiseFloor = frame_energyMin << 4;
+ maxEnergy = st->frameEnergyHist[0];
+
+ for (i = 1; i < L_ENERGYHIST - 4; i++) {
+ if (maxEnergy < st->frameEnergyHist[i]) {
+ maxEnergy = st->frameEnergyHist[i];
+ }
+ }
+ maxEnergyLastPart = st->frameEnergyHist[2 * L_ENERGYHIST / 3];
+
+ for (i = 2 * L_ENERGYHIST / 3 + 1; i < L_ENERGYHIST; i++) {
+ if (maxEnergyLastPart < st->frameEnergyHist[i]) {
+ maxEnergyLastPart = st->frameEnergyHist[i];
+ }
+ }
+
+ /* false */
+ inbgNoise = 0;
+
+ /*
+ * Do not consider silence as noise
+ * Do not consider continuous high volume as noise
+ * Or if the current noise level is very low
+ * Mark as noise if under current noise limit
+ * OR if the maximum energy is below the upper limit
+ */
+ if ((maxEnergy > LOWERNOISELIMIT) & (currEnergy < FRAMEENERGYLIMIT) & (
+ currEnergy > LOWERNOISELIMIT) & ((currEnergy < noiseFloor) || (
+ maxEnergyLastPart < UPPERNOISELIMIT))) {
+ if ((st->bgHangover + 1) > 30) {
+ st->bgHangover = 30;
+ } else {
+ st->bgHangover += 1;
+ }
+ } else {
+ st->bgHangover = 0;
+ }
+
+ /* make final decision about frame state, act somewhat cautiosly */
+ if (st->bgHangover > 1) {
+ inbgNoise = 1; /* true */
+ }
+
+ for (i = 0; i < L_ENERGYHIST - 1; i++) {
+ st->frameEnergyHist[i] = st->frameEnergyHist[i + 1];
+ }
+ st->frameEnergyHist[L_ENERGYHIST - 1] = currEnergy;
+
+ /*
+ * prepare for voicing decision;
+ * tighten the threshold after some time in noise
+ */
+ ltpLimit = 13926; /* 0.85 Q14 */
+
+ if (st->bgHangover > 8) {
+ ltpLimit = 15565; /* 0.95 Q14 */
+ }
+
+ if (st->bgHangover > 15) {
+ ltpLimit = 16383; /* 1.00 Q14 */
+ }
+
+ /* weak sort of voicing indication. */
+ prevVoiced = 0; /* false */
+
+ if (gmed_n(&ltpGainHist[4], 5) > ltpLimit) {
+ prevVoiced = 1; /* true */
+ }
+
+ if (st->bgHangover > 20) {
+ if (gmed_n(ltpGainHist, 9) > ltpLimit) {
+ prevVoiced = 1; /* true */
+ } else {
+ prevVoiced = 0; /* false */
+ }
+ }
+
+ if (prevVoiced) {
+ *voicedHangover = 0;
+ } else {
+ temp = *voicedHangover + 1;
+
+ if (temp > 10) {
+ *voicedHangover = 10;
+ } else {
+ *voicedHangover = temp;
+ }
+ }
+ return inbgNoise;
+}
+
+
+/*
+ * dtx_dec_activity_update
+ *
+ *
+ * Parameters:
+ * st->lsf_hist_ptr B: LSF history pointer
+ * st->lsf_hist B: LSF history
+ * lsf I: lsf
+ * frame I: noise frame
+ *
+ * Function:
+ * Update lsp history and compute log energy.
+ *
+ * Returns:
+ * void
+ */
+static void dtx_dec_activity_update(dtx_decState *st, Word32 lsf[], Word32
+ frame[])
+{
+ Word32 frame_en;
+ Word32 log_en_e, log_en_m, log_en, i;
+
+
+ /* update lsp history */
+ st->lsf_hist_ptr += M;
+
+ if (st->lsf_hist_ptr == 80) {
+ st->lsf_hist_ptr = 0;
+ }
+ memcpy(&st->lsf_hist[st->lsf_hist_ptr], lsf, M << 2);
+
+ /* compute log energy based on frame energy */
+ frame_en = 0; /* Q0 */
+
+ for (i = 0; (i < L_FRAME); i ++) {
+ frame_en += frame[i] * frame[i];
+ if (frame_en & 0x80000000) {
+ break;
+ }
+ }
+
+ log_en = (frame_en & 0xC0000000) ? 0x7FFFFFFE : (Word32)frame_en << 1;
+
+ Log2(log_en , &log_en_e, &log_en_m);
+
+ /* convert exponent and mantissa to Word16 Q10 */
+ log_en = log_en_e << 10; /* Q10 */
+ log_en = log_en + (log_en_m >> 5);
+
+ /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
+ log_en = log_en - 8521;
+
+ /*
+ * insert into log energy buffer, no division by two as
+ * log_en in decoder is Q11
+ */
+ st->log_en_hist_ptr += 1;
+
+ if (st->log_en_hist_ptr == DTX_HIST_SIZE) {
+ st->log_en_hist_ptr = 0;
+ }
+ st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */
+}
+
+
+/*
+ * Decoder_amr
+ *
+ *
+ * Parameters:
+ * st B: State variables
+ * mode I: AMR mode
+ * parm I: vector of synthesis parameters
+ * frame_type I: received frame type
+ * synth O: synthesis speech
+ * A_t O: decoded LP filter in 4 subframes
+ *
+ * Function:
+ * Speech decoder routine
+ *
+ * Returns:
+ * void
+ */
+static void Decoder_amr(Decoder_amrState *st, enum Mode mode, Word16 parm[],
+ enum RXFrameType frame_type, Word32 synth[], Word32 A_t[])
+{
+ /* LSPs */
+ Word32 lsp_new[M];
+ Word32 lsp_mid[M];
+
+
+ /* LSFs */
+ Word32 prev_lsf[M];
+ Word32 lsf_i[M];
+
+
+ /* Algebraic codevector */
+ Word32 code[L_SUBFR];
+
+
+ /* excitation */
+ Word32 excp[L_SUBFR];
+ Word32 exc_enhanced[L_SUBFR];
+
+
+ /* Scalars */
+ Word32 i, i_subfr, overflow, T0_frac, index, temp, temp2, subfrNr, excEnergy;
+ Word32 gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac, t0_min, t0_max;
+ Word32 gain_pit = 0, evenSubfr = 0, T0 = 0, index_mr475 = 0;
+ Word32 *Az; /* Pointer on A_t */
+ Word16 flag4, carefulFlag;
+ Word16 delta_frc_low, delta_frc_range, tmp_shift;
+ Word16 bfi = 0, pdfi = 0;
+ /* bad frame indication flag, potential degraded bad frame flag */
+
+
+ enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */
+
+ /* find the new DTX state SPEECH OR DTX */
+ newDTXState = rx_dtx_handler(st->dtxDecoderState, frame_type);
+
+ /* DTX actions */
+ if (newDTXState != SPEECH) {
+ Decoder_amr_reset(st, MRDTX);
+ dtx_dec(st->dtxDecoderState, st->mem_syn, st->lsfState, st->pred_state,
+ st->Cb_gain_averState, newDTXState, mode, parm, synth, A_t);
+
+ /* update average lsp */
+ Lsf_lsp(st->lsfState->past_lsf_q, st->lsp_old);
+ lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q);
+ goto theEnd;
+ }
+
+ /* SPEECH action state machine */
+ if (table_speech_bad[frame_type]) {
+ bfi = 1;
+
+ if (frame_type != RX_SPEECH_BAD) {
+ Build_CN_param(&st->nodataSeed, mode, parm);
+ }
+ } else if (frame_type == RX_SPEECH_DEGRADED) {
+ pdfi = 1;
+ }
+
+ if (bfi != 0) {
+ st->state += 1;
+ } else if (st->state == 6) {
+ st->state = 5;
+ } else {
+ st->state = 0;
+ }
+
+ if (st->state > 6) {
+ st->state = 6;
+ }
+
+ /*
+ * If this frame is the first speech frame after CNI period,
+ * set the BFH state machine to an appropriate state depending
+ * on whether there was DTX muting before start of speech or not
+ * If there was DTX muting, the first speech frame is muted.
+ * If there was no DTX muting, the first speech frame is not
+ * muted. The BFH state machine starts from state 5, however, to
+ * keep the audible noise resulting from a SID frame which is
+ * erroneously interpreted as a good speech frame as small as
+ * possible (the decoder output in this case is quickly muted)
+ */
+ if (st->dtxDecoderState->dtxGlobalState == DTX) {
+ st->state = 5;
+ st->prev_bf = 0;
+ } else if (st->dtxDecoderState->dtxGlobalState == DTX_MUTE) {
+ st->state = 5;
+ st->prev_bf = 1;
+ }
+
+ /* save old LSFs for CB gain smoothing */
+ memcpy(prev_lsf, st->lsfState->past_lsf_q, M << 2);
+
+ /*
+ * decode LSF parameters and generate interpolated lpc coefficients
+ * for the 4 subframes
+ */
+ if (mode != MR122) {
+ D_plsf_3(st->lsfState, mode, bfi, parm, lsp_new);
+
+ /* Advance synthesis parameters pointer */
+ parm += 3;
+ Int_lpc_1to3(st->lsp_old, lsp_new, A_t);
+ } else {
+ D_plsf_5(st->lsfState, bfi, parm, lsp_mid, lsp_new);
+
+ /* Advance synthesis parameters pointer */
+ parm += 5;
+ Int_lpc_1and3(st->lsp_old, lsp_mid, lsp_new, A_t);
+ }
+
+ /* update the LSPs for the next frame */
+ memcpy(st->lsp_old, lsp_new, M << 2);
+
+ /*
+ * Loop for every subframe in the analysis frame
+ *
+ * The subframe size is L_SUBFR and the loop is repeated
+ * L_FRAME/L_SUBFR times *
+ * - decode the pitch delay
+ * - decode algebraic code
+ * - decode pitch and codebook gains
+ * - find the excitation and compute synthesis speech
+ */
+ /* pointer to interpolated LPC parameters */
+ Az = A_t;
+ evenSubfr = 0;
+ subfrNr = -1;
+
+ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
+ subfrNr += 1;
+ evenSubfr = 1 - evenSubfr;
+
+ /* flag for first and 3th subframe */
+ pit_flag = i_subfr;
+
+ if (i_subfr == L_FRAME_BY2) {
+ if ((mode != MR475) & (mode != MR515)) {
+ pit_flag = 0;
+ }
+ }
+
+ /* pitch index */
+ index = *parm++;
+
+ /*
+ * decode pitch lag and find adaptive codebook vector.
+ */
+ if (mode != MR122) {
+ /*
+ * flag4 indicates encoding with 4 bit resolution;
+ * this is needed for mode MR475, MR515, MR59 and MR67
+ */
+ flag4 = 0;
+
+ if ((mode == MR475) || (mode == MR515) || (mode == MR59) || (
+ mode == MR67)) {
+ flag4 = 1;
+ }
+
+ /*
+ * get ranges for the t0_min and t0_max
+ * only needed in delta decoding
+ */
+ delta_frc_low = 5;
+ delta_frc_range = 9;
+
+ if (mode == MR795) {
+ delta_frc_low = 10;
+ delta_frc_range = 19;
+ }
+ t0_min = st->old_T0 - delta_frc_low;
+
+ if (t0_min < PIT_MIN) {
+ t0_min = PIT_MIN;
+ }
+ t0_max = t0_min + delta_frc_range;
+
+ if (t0_max > PIT_MAX) {
+ t0_max = PIT_MAX;
+ t0_min = t0_max - delta_frc_range;
+ }
+ Dec_lag3(index, t0_min, t0_max, pit_flag, st->old_T0, &T0, &T0_frac,
+ flag4);
+ st->T0_lagBuff = T0;
+
+ if (bfi != 0) {
+ if (st->old_T0 < PIT_MAX) {
+ /* Graceful pitch degradation */
+ st->old_T0 += 1;
+ }
+ T0 = st->old_T0;
+ T0_frac = 0;
+
+ if ((st->inBackgroundNoise != 0) & (st->voicedHangover > 4) & (
+ (mode == MR475) || (mode == MR515) || (mode == MR59))) {
+ T0 = st->T0_lagBuff;
+ }
+ }
+ Pred_lt_3or6_40(st->exc, T0, T0_frac, 1);
+ } else {
+ Dec_lag6(index, PIT_MIN_MR122, PIT_MAX, pit_flag, &T0, &T0_frac);
+
+ if ((bfi != 0) || ((pit_flag != 0) & (index > 60))) {
+ st->T0_lagBuff = T0;
+ T0 = st->old_T0;
+ T0_frac = 0;
+ }
+ Pred_lt_3or6_40(st->exc, T0, T0_frac, 0);
+ }
+
+ /*
+ * (MR122 only: Decode pitch gain.)
+ * Decode innovative codebook.
+ * set pitch sharpening factor
+ */
+ /* MR475, MR515 */
+ if ((mode == MR475) || (mode == MR515)) {
+ /* index of position */
+ index = *parm++;
+
+ /* signs */
+ i = *parm++;
+ decode_2i40_9bits(subfrNr, i, index, code);
+ pit_sharp = st->sharp << 1;
+ }
+
+ /* MR59 */
+ else if (mode == MR59) {
+ /* index of position */
+ index = *parm++;
+
+ /* signs */
+ i = *parm++;
+ decode_2i40_11bits(i, index, code);
+ pit_sharp = st->sharp << 1;
+ }
+
+ /* MR67 */
+ else if (mode == MR67) {
+ /* index of position */
+ index = *parm++;
+
+ /* signs */
+ i = *parm++;
+ decode_3i40_14bits(i, index, code);
+ pit_sharp = st->sharp << 1;
+ }
+
+ /* MR74, MR795 */
+ else if (mode <= MR795) {
+ /* index of position */
+ index = *parm++;
+
+ /* signs */
+ i = *parm++;
+ decode_4i40_17bits(i, index, code);
+ pit_sharp = st->sharp << 1;
+ }
+
+ /* MR102 */
+ else if (mode == MR102) {
+ decode_8i40_31bits(parm, code);
+ parm += 7;
+ pit_sharp = st->sharp << 1;
+ }
+
+ /* MR122 */
+ else {
+ index = *parm++;
+
+ if (bfi != 0) {
+ ec_gain_pitch(st->ec_gain_p_st, st->state, &gain_pit);
+ } else {
+ gain_pit = d_gain_pitch(mode, index);
+ }
+ ec_gain_pitch_update(st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit);
+ decode_10i40_35bits(parm, code);
+ parm += 10;
+
+ /*
+ * pit_sharp = gain_pit;
+ * if (pit_sharp > 1.0) pit_sharp = 1.0;
+ */
+ pit_sharp = gain_pit;
+
+ if (pit_sharp > 16383) {
+ pit_sharp = 32767;
+ } else {
+ pit_sharp *= 2;
+ }
+ }
+
+ /*
+ * Add the pitch contribution to code[].
+ */
+ for (i = T0; i < L_SUBFR; i++) {
+ temp = (code[i - T0] * pit_sharp) >> 15;
+ code[i] = code[i] + temp;
+ }
+
+ /*
+ * Decode codebook gain (MR122) or both pitch
+ * gain and codebook gain (all others)
+ * Update pitch sharpening "sharp" with quantized gain_pit
+ */
+ if (mode == MR475) {
+ /* read and decode pitch and code gain */
+ if (evenSubfr != 0) {
+ /* index of gain(s) */
+ index_mr475 = *parm++;
+ }
+
+ if (bfi == 0) {
+ Dec_gain(st->pred_state, mode, index_mr475, code, evenSubfr, &
+ gain_pit, &gain_code);
+ } else {
+ ec_gain_pitch(st->ec_gain_p_st, st->state, &gain_pit);
+ ec_gain_code(st->ec_gain_c_st, st->pred_state, st->state, &
+ gain_code);
+ }
+ ec_gain_pitch_update(st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit);
+ ec_gain_code_update(st->ec_gain_c_st, bfi, st->prev_bf, &gain_code);
+ pit_sharp = gain_pit;
+
+ if (pit_sharp > SHARPMAX) {
+ pit_sharp = SHARPMAX;
+ }
+ } else if ((mode <= MR74) || (mode == MR102)) {
+ /* read and decode pitch and code gain */
+ /* index of gain(s) */
+ index = *parm++;
+
+ if (bfi == 0) {
+ Dec_gain(st->pred_state, mode, index, code, evenSubfr, &gain_pit, &
+ gain_code);
+ } else {
+ ec_gain_pitch(st->ec_gain_p_st, st->state, &gain_pit);
+ ec_gain_code(st->ec_gain_c_st, st->pred_state, st->state, &
+ gain_code);
+ }
+ ec_gain_pitch_update(st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit);
+ ec_gain_code_update(st->ec_gain_c_st, bfi, st->prev_bf, &gain_code);
+ pit_sharp = gain_pit;
+
+ if (pit_sharp > SHARPMAX) {
+ pit_sharp = SHARPMAX;
+ }
+
+ if (mode == MR102) {
+ if (st->old_T0 > (L_SUBFR + 5)) {
+ pit_sharp = pit_sharp >> 2;
+ }
+ }
+ } else {
+ /* read and decode pitch gain */
+ /* index of gain(s) */
+ index = *parm++;
+
+ if (mode == MR795) {
+ /* decode pitch gain */
+ if (bfi != 0) {
+ ec_gain_pitch(st->ec_gain_p_st, st->state, &gain_pit);
+ } else {
+ gain_pit = d_gain_pitch(mode, index);
+ }
+ ec_gain_pitch_update(st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit
+ );
+
+ /* read and decode code gain */
+ index = *parm++;
+
+ if (bfi == 0) {
+ d_gain_code(st->pred_state, mode, index, code, &gain_code);
+ } else {
+ ec_gain_code(st->ec_gain_c_st, st->pred_state, st->state, &
+ gain_code);
+ }
+ ec_gain_code_update(st->ec_gain_c_st, bfi, st->prev_bf, &gain_code
+ );
+ pit_sharp = gain_pit;
+
+ if (pit_sharp > SHARPMAX) {
+ pit_sharp = SHARPMAX;
+ }
+ } else { /* MR122 */
+
+ if (bfi == 0) {
+ d_gain_code(st->pred_state, mode, index, code, &gain_code);
+ } else {
+ ec_gain_code(st->ec_gain_c_st, st->pred_state, st->state, &
+ gain_code);
+ }
+ ec_gain_code_update(st->ec_gain_c_st, bfi, st->prev_bf, &gain_code
+ );
+ pit_sharp = gain_pit;
+ }
+ }
+
+ /*
+ * store pitch sharpening for next subframe
+ * (for modes which use the previous pitch gain for
+ * pitch sharpening in the search phase)
+ * do not update sharpening in even subframes for MR475
+ */
+ if ((mode != MR475) || evenSubfr == 0) {
+ st->sharp = gain_pit;
+
+ if (st->sharp > SHARPMAX) {
+ st->sharp = SHARPMAX;
+ }
+ }
+
+ if (pit_sharp > 16383) {
+ pit_sharp = 32767;
+ } else {
+ pit_sharp *= 2;
+ }
+
+ if (pit_sharp > 16384) {
+ for (i = 0; i < L_SUBFR; i++) {
+ temp = (st->exc[i] * pit_sharp) >> 15;
+ temp2 = (temp * gain_pit) << 1;
+
+ if (mode == MR122) {
+ temp2 = (temp2 >> 1);
+ }
+ excp[i] = (temp2 + 0x00008000L) >> 16;
+ }
+ }
+
+ /*
+ * Store list of LTP gains needed in the source
+ * characteristic detector (SCD)
+ */
+ if (bfi == 0) {
+ for (i = 0; i < 8; i++) {
+ st->ltpGainHistory[i] = st->ltpGainHistory[i + 1];
+ }
+ st->ltpGainHistory[8] = gain_pit;
+ }
+
+
+ /*
+ * Limit gain_pit if in background noise and BFI
+ * for MR475, MR515, MR59
+ */
+ if ((st->prev_bf != 0 || bfi != 0) & (st->inBackgroundNoise != 0) & (
+ (mode == MR475) || (mode == MR515) || (mode == MR59))) {
+ /* if (gain_pit > 0.75) in Q14*/
+ if (gain_pit > 12288)
+ /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */
+ {
+ gain_pit = ((gain_pit - 12288) >> 1) + 12288;
+ }
+
+ /* if (gain_pit > 0.90) in Q14*/
+ if (gain_pit > 14745) {
+ gain_pit = 14745;
+ }
+ }
+
+ /*
+ * Calculate CB mixed gain
+ */
+ Int_lsf(prev_lsf, st->lsfState->past_lsf_q, i_subfr, lsf_i);
+ gain_code_mix = Cb_gain_average(st->Cb_gain_averState, mode, gain_code,
+ lsf_i, st->lsp_avg_st->lsp_meanSave, bfi, st->prev_bf, pdfi, st->
+ prev_pdf, st->inBackgroundNoise, st->voicedHangover);
+
+ /* make sure that MR74, MR795, MR122 have original codeGain*/
+ /* MR74, MR795, MR122 */
+ if ((mode > MR67) & (mode != MR102)) {
+ gain_code_mix = gain_code;
+ }
+
+ /*
+ * Find the total excitation.
+ * Find synthesis speech corresponding to st->exc[].
+ */
+ /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/
+ if (mode <= MR102) {
+ pitch_fac = gain_pit;
+ tmp_shift = 1;
+ }
+
+ /* MR122 */
+ else {
+ pitch_fac = gain_pit >> 1;
+ tmp_shift = 2;
+ }
+
+ /*
+ * copy unscaled LTP excitation to exc_enhanced (used in phase
+ * dispersion below) and compute total excitation for LTP feedback
+ */
+ memcpy(exc_enhanced, st->exc, L_SUBFR << 2);
+
+ for (i = 0; i < L_SUBFR; i++) {
+ /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */
+ temp = (st->exc[i] * pitch_fac) + (code[i] * gain_code);
+ temp2 = (temp << tmp_shift);
+ if (((temp2 >> 1) ^ temp2) & 0x40000000) {
+ if ((temp ^ temp2) & 0x80000000) {
+ temp2 = (temp & 0x80000000) ? (-1073741824L) : 1073725439;
+ } else {
+ temp2 = (temp2 & 0x80000000) ? (-1073741824L) : 1073725439;
+ }
+ }
+ st->exc[i] = (temp2 + 0x00004000L) >> 15;
+ }
+ /*
+ * Adaptive phase dispersion
+ */
+
+ /* free phase dispersion adaption */
+ st->ph_disp_st->lockFull = 0;
+
+ if (((mode == MR475) || (mode == MR515) || (mode == MR59)) & (st
+ ->voicedHangover > 3) & (st->inBackgroundNoise != 0) & (bfi != 0
+ )) {
+ /*
+ * Always Use full Phase Disp.
+ * if error in bg noise
+ */
+ st->ph_disp_st->lockFull = 1;
+ }
+
+ /*
+ * apply phase dispersion to innovation (if enabled) and
+ * compute total excitation for synthesis part
+ */
+ ph_disp(st->ph_disp_st, mode, exc_enhanced, gain_code_mix, gain_pit, code
+ , pitch_fac, tmp_shift);
+
+ /*
+ * The Excitation control module are active during BFI.
+ * Conceal drops in signal energy if in bg noise.
+ */
+ temp2 = 0;
+
+ for (i = 0; i < L_SUBFR; i++) {
+ temp2 += (exc_enhanced[i] * exc_enhanced[i]);
+ }
+
+ if (temp2 > 0x3FFFFFFF) {
+ excEnergy = 11584;
+ } else {
+ temp2 = sqrt_l_exp(temp2, &temp);
+ temp2 = (temp2 >> ((temp >> 1) + 15));
+ excEnergy = temp2 >> 2;
+ }
+
+ if (((mode == MR475) || (mode == MR515) || (mode == MR59)) & (st
+ ->voicedHangover > 5) & (st->inBackgroundNoise != 0) & (st->
+ state < 4) & (((pdfi != 0) & (st->prev_pdf != 0)) || bfi !=
+ 0 || st->prev_bf != 0)) {
+ carefulFlag = 0;
+
+ if ((pdfi != 0) & (bfi == 0)) {
+ carefulFlag = 1;
+ }
+ Ex_ctrl(exc_enhanced, excEnergy, st->excEnergyHist, st->voicedHangover
+ , st->prev_bf, carefulFlag);
+ }
+
+ if ((st->inBackgroundNoise != 0) & (bfi != 0 || st->prev_bf != 0) & (
+ st->state < 4)) {
+ ; /* do nothing! */
+ } else {
+ /* Update energy history for all modes */
+ for (i = 0; i < 8; i++) {
+ st->excEnergyHist[i] = st->excEnergyHist[i + 1];
+ }
+ st->excEnergyHist[8] = excEnergy;
+ }
+
+ /*
+ * Excitation control module end.
+ */
+ if (pit_sharp > 16384) {
+ for (i = 0; i < L_SUBFR; i++) {
+ excp[i] = excp[i] + exc_enhanced[i];
+ if (labs(excp[i]) > 32767) {
+ excp[i] = (excp[i] & 0x80000000) ? -32768 : 32767;
+ }
+ }
+ agc2(exc_enhanced, excp);
+ overflow = Syn_filt(Az, excp, &synth[i_subfr], L_SUBFR, st->mem_syn, 0
+ );
+ } else {
+ overflow = Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->
+ mem_syn, 0);
+ }
+
+ if (overflow) {
+ for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) {
+ st->old_exc[i] = st->old_exc[i] >> 2;
+ }
+
+ for (i = 0; i < L_SUBFR; i++) {
+ exc_enhanced[i] = exc_enhanced[i] >> 2;
+ }
+ Syn_filt_overflow(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1);
+ } else {
+ memcpy(st->mem_syn, &synth[i_subfr + 30], 40);
+ }
+
+ /*
+ * Update signal for next frame.
+ * -> shift to the left by L_SUBFR st->exc[]
+ */
+ memcpy(&st->old_exc[0], &st->old_exc[L_SUBFR], (PIT_MAX + L_INTERPOL) <<
+ 2);
+
+ /* interpolated LPC parameters for next subframe */
+ Az += MP1;
+
+ /* store T0 for next subframe */
+ st->old_T0 = T0;
+ }
+
+ /*
+ * Call the Source Characteristic Detector which updates
+ * st->inBackgroundNoise and st->voicedHangover.
+ */
+ st->inBackgroundNoise = Bgn_scd(st->background_state, &(st->ltpGainHistory[
+ 0]), &(synth[0]), &(st->voicedHangover));
+ dtx_dec_activity_update(st->dtxDecoderState, st->lsfState->past_lsf_q, synth
+ );
+
+ /* store bfi for next subframe */
+ st->prev_bf = bfi;
+ st->prev_pdf = pdfi;
+
+ /*
+ * Calculate the LSF averages on the eight
+ * previous frames
+ */
+ lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q);
+theEnd:
+ st->dtxDecoderState->dtxGlobalState = newDTXState;
+ return;
+}
+
+
+/*
+ * Residu40
+ *
+ *
+ * Parameters:
+ * a I: prediction coefficients
+ * x I: speech signal
+ * y O: residual signal
+ *
+ * Function:
+ * The LP residual is computed by filtering the input
+ * speech through the LP inverse filter a(z)
+ *
+ * Returns:
+ * void
+ */
+static void Residu40(Word32 a[], Word32 x[], Word32 y[])
+{
+ Word32 s, i, j;
+
+
+ for (i = 0; i < 40; i++) {
+ s = a[0] * x[i] + a[1] * x[i - 1] + a[2] * x[i - 2] + a[3] * x[i - 3];
+ s += a[4] * x[i - 4] + a[5] * x[i - 5] + a[6] * x[i - 6] + a[7] * x[i - 7]
+ ;
+ s += a[8] * x[i - 8] + a[9] * x[i - 9] + a[10] * x[i - 10];
+ y[i] = (s + 0x800) >> 12;
+ if (abs(y[i]) > 32767) {
+ /* go to safe mode */
+ for (i = 0; i < 40; i++) {
+ s = a[0] * x[i];
+ for (j = 1; j <= 10; j++) {
+ s += a[j] * x[i - j];
+ if (s > 1073741823) {
+ s = 1073741823;
+ } else if (s < -1073741824) {
+ s = -1073741824;
+ }
+ }
+ y[i] = (s + 0x800) >> 12;
+ if (abs(y[i]) > 32767) {
+ y[i] = (y[i] & 0x80000000) ? -32768 : 32767;
+ }
+ }
+ return;
+ }
+
+ }
+ return;
+}
+
+
+/*
+ * agc
+ *
+ *
+ * Parameters:
+ * st->past_gain B: gain memory
+ * sig_in I: Post_Filter input signal
+ * sig_out B: Post_Filter output signal
+ * agc_fac I: AGC factor
+ *
+ * Function:
+ * Scales the Post_Filter output on a subframe basis
+ *
+ * Returns:
+ * void
+ */
+static void agc(agcState *st, Word32 *sig_in, Word32 *sig_out, Word16 agc_fac)
+{
+ Word32 s, gain_in, gain_out, g0, gain;
+ int exp, i;
+
+
+ /* calculate gain_out with exponent */
+ s = energy_new(sig_out);
+
+ if (s == 0) {
+ st->past_gain = 0;
+ return;
+ }
+ exp = 0;
+ i = s;
+ while (!(i & 0x40000000)) {
+ exp++;
+ i = i << 1;
+ }
+ exp -= 1;
+ if (exp & 0x80000000) {
+ s >>= 1;
+ } else {
+ s <<= exp;
+ }
+ gain_out = (s + 0x00008000L) >> 16;
+
+ /* calculate gain_in with exponent */
+ s = energy_new(sig_in);
+
+ if (s == 0) {
+ g0 = 0;
+ } else {
+ i = 0;
+ while (!(s & 0x40000000)) {
+ i++;
+ s = s << 1;
+ }
+ s = s + 0x00008000L;
+
+ if (s >= 0) {
+ gain_in = s >> 16;
+ } else {
+ gain_in = 32767;
+ }
+ exp = (exp - i);
+
+ /*
+ * g0 = (1-agc_fac) * sqrt(gain_in/gain_out);
+ */
+ /* s = gain_out / gain_in */
+ s = (gain_out << 15) / gain_in;
+ exp = 7 - exp;
+
+ if (exp > 0) {
+ if (exp > 31) {
+ if (s) {
+ s = 2147483647;
+ }
+ } else {
+ s = s << exp ;
+ }
+ } else {
+ s = (s >> (-exp));
+ }
+ if (s < 0) {
+ s = 2147483647;
+ }
+ s = Inv_sqrt(s);
+ i = ((s << 9) + 0x00008000L) >> 16;
+ if (i & 0xFFFF8000) {
+ i = 32767;
+ }
+
+ /* g0 = i * (1-agc_fac) */
+ g0 = (i * (32767 - agc_fac)) >> 15;
+ }
+
+ /*
+ * compute gain[n] = agc_fac * gain[n-1] + (1-agc_fac) * sqrt(gain_in/gain_out)
+ * sig_out[n] = gain[n] * sig_out[n]
+ */
+ gain = st->past_gain;
+
+ for (i = 0; i < L_SUBFR; i++) {
+ gain = (gain * agc_fac) >> 15;
+ gain = gain + g0;
+ sig_out[i] = (sig_out[i] * gain) >> 12;
+ if (labs(sig_out[i]) > 32767) {
+ sig_out[i] = (sig_out[i] & 0x8000000) ? -32768 : 32767;
+ }
+ }
+ st->past_gain = gain;
+ return;
+}
+
+
+/*
+ * Post_Filter
+ *
+ *
+ * Parameters:
+ * st B: post filter states
+ * mode I: AMR mode
+ * syn B: synthesis speech
+ * Az_4 I: interpolated LPC parameters in all subfr.
+ *
+ * Function:
+ * Post_Filtering of synthesis speech.
+ *
+ * inverse filtering of syn[] through A(z/0.7) to get res2[]
+ * tilt compensation filtering; 1 - MU*k*z^-1
+ * synthesis filtering through 1/A(z/0.75)
+ * adaptive gain control
+ *
+ * Returns:
+ * void
+ */
+static void Post_Filter(Post_FilterState *st, enum Mode mode, Word32 *syn,
+ Word32 *Az_4)
+{
+ Word32 h[22], Ap3[MP1], Ap4[MP1]; /* bandwidth expanded LP parameters */
+ Word32 tmp, i_subfr, i, temp1, temp2, overflow = 0;
+ Word32 *Az, *p1, *p2, *syn_work = &st->synth_buf[M];
+ const Word32 *pgamma3 = &gamma3[0];
+ const Word32 *pgamma4 = &gamma4_gamma3_MR122[0];
+
+
+ /*
+ * Post filtering
+ */
+ memcpy(syn_work, syn, L_FRAME << 2);
+ Az = Az_4;
+
+ if ((mode == MR122) || (mode == MR102)) {
+ pgamma3 = &gamma4_gamma3_MR122[0];
+ pgamma4 = &gamma4_MR122[0];
+ }
+
+ for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
+ /* Find weighted filter coefficients Ap3[] and Ap[4] */
+ Ap3[0] = Az[0];
+ Ap4[0] = Az[0];
+
+ for (i = 1; i <= 10; i++) {
+ Ap3[i] = (Az[i] * pgamma3[i - 1] + 0x4000) >> 15;
+ Ap4[i] = (Az[i] * pgamma4[i - 1] + 0x4000) >> 15;
+ }
+
+ /* filtering of synthesis speech by A(z/0.7) to find res2[] */
+ Residu40(Ap3, &syn_work[i_subfr], st->res2);
+
+ /* tilt compensation filter */
+ /* impulse response of A(z/0.7)/A(z/0.75) */
+ memcpy(h, Ap3, MP1 << 2);
+ memset(&h[M + 1], 0, (22 - M - 1) << 2);
+ Syn_filt(Ap4, h, h, 22, &h[M + 1], 0);
+
+ /* 1st correlation of h[] */
+ tmp = 16777216 + h[1] * h[1];
+
+ for (i = 2; i < 22; i++) {
+ tmp += h[i] * h[i];
+ if (tmp > 0x3FFF8000) {
+ break;
+ }
+ }
+ temp1 = tmp >> 15;
+ if (temp1 & 0xFFFF8000) {
+ temp1 = 32767;
+ }
+
+ tmp = h[0] * h[1];
+
+ for (i = 1; i < 21; i++) {
+ tmp += h[i] * h[i + 1];
+ if (abs(tmp) > 1073741823) {
+ tmp = 1073741823;
+ }
+ }
+ temp2 = tmp >> 15;
+
+ if (temp2 <= 0) {
+ temp2 = 0;
+ } else {
+ tmp = temp2 * 26214;
+ temp2 = (tmp & 0xffff8000) / temp1;
+ }
+
+ /* preemphasis */
+ p1 = st->res2 + 39;
+ p2 = p1 - 1;
+ tmp = *p1;
+
+ do {
+ *p1 = *p1 - ((temp2 * *p2--) >> 15);
+ if (abs(*p1) > 32767) {
+ *p1 = (*p1 & 0x80000000) ? -32768 : 32767;
+ }
+ p1--;
+ *p1 = *p1 - ((temp2 * *p2--) >> 15);
+ if (abs(*p1) > 32767) {
+ *p1 = (*p1 & 0x80000000) ? -32768 : 32767;
+ }
+ p1--;
+ *p1 = *p1 - ((temp2 * *p2--) >> 15);
+ if (abs(*p1) > 32767) {
+ *p1 = (*p1 & 0x80000000) ? -32768 : 32767;
+ }
+ p1--;
+ } while (p1 > st->res2);
+ *p1 = *p1 - ((temp2 * st->preemph_state_mem_pre) >> 15);
+ if (abs(*p1) > 32767) {
+ *p1 = (*p1 & 0x80000000) ? -32768 : 32767;
+ }
+ st->preemph_state_mem_pre = tmp;
+
+ /* filtering through 1/A(z/0.75) */
+ overflow = Syn_filt(Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 0);
+ if (overflow) {
+ Syn_filt_overflow(Ap4, st->res2, &syn[i_subfr], L_SUBFR, st->mem_syn_pst, 1);
+ overflow = 0;
+ } else {
+ memcpy(st->mem_syn_pst, &syn[i_subfr + 30], 40);
+ }
+
+ /* scale output to input */
+ agc(st->agc_state, &syn_work[i_subfr], &syn[i_subfr], AGC_FAC);
+ Az += MP1;
+ }
+
+ /* update syn_work[] buffer */
+ memcpy(&syn_work[- M], &syn_work[L_FRAME - M], M << 2);
+ return;
+}
+
+
+/*
+ * Post_Process
+ *
+ *
+ * Parameters:
+ * st B: post filter states
+ * signal B: signal
+ *
+ * Function:
+ * Postprocessing of input speech.
+ *
+ * 2nd order high pass filtering with cut off frequency at 60 Hz.
+ * Multiplication of output by two.
+ *
+ *
+ * Returns:
+ * void
+ */
+static void Post_Process(Post_ProcessState *st, Word32 signal[])
+{
+ Word32 x2, tmp, i = 0;
+ Word32 mask = 0x40000000;
+
+ do {
+ x2 = st->x1;
+ st->x1 = st->x0;
+ st->x0 = signal[i];
+
+ /*
+ * y[i] = b[0]*x[i]*2 + b[1]*x[i-1]*2 + b140[2]*x[i-2]/2
+ * + a[1]*y[i-1] + a[2] * y[i-2];
+ */
+ tmp = (st->y1_hi * 15836) + (((st->y1_lo * 15836) & (Word32)0xffff8000) >> 15);
+ tmp += (st->y2_hi * -7667) + (((st->y2_lo * (-7667)) & (Word32)0xffff8000) >> 15);
+ tmp += st->x0 * 7699;
+ tmp += st->x1 * -15398;
+ if (((tmp >> 1) ^ tmp) & mask) {
+ tmp = (tmp & 0x80000000) ? -1073741824 : 1073741823;
+ }
+
+ tmp += x2 * 7699;
+ if (((tmp >> 1) ^ tmp) & mask) {
+ tmp = (tmp & 0x80000000) ? -1073741824 : 1073741823;
+ }
+
+ tmp = tmp << 1;
+ if (((tmp >> 1) ^ tmp) & mask) {
+ tmp = (tmp & 0x80000000) ? -1073741824 : 1073741823;
+ }
+
+ tmp = tmp << 1;
+ if (((tmp >> 1) ^ tmp) & mask) {
+ tmp = (tmp & 0x80000000) ? -1073741824 : 1073741823;
+ }
+
+ if (labs(tmp) < 536862720) {
+ signal[i++] = (tmp + 0x00002000L) >> 14;
+ } else if (tmp > 0) {
+ signal[i++] = 32767;
+ } else {
+ signal[i++] = -32768;
+ }
+ st->y2_hi = st->y1_hi;
+ st->y2_lo = st->y1_lo;
+ st->y1_hi = tmp >> 15;
+ st->y1_lo = ((tmp << 1) - (st->y1_hi << 16)) >> 1;
+ } while (i < 160);
+ return;
+}
+
+
+/*
+ * Speech_Decode_Frame
+ *
+ *
+ * Parameters:
+ * st B: decoder memory
+ * mode I: AMR mode
+ * parm I: speech parameters
+ * frame_type I: Frame type
+ * synth O: synthesis speech
+
+ * Function:
+ * Decode one frame
+ *
+ * Returns:
+ * void
+ */
+void Speech_Decode_Frame(void *st, enum Mode mode, Word16 *parm, enum
+ RXFrameType frame_type, Word16 *synth)
+{
+ Word32 Az_dec[AZ_SIZE]; /* Decoded Az for post-filter in 4 subframes*/
+ Word32 synth_speech[L_FRAME];
+ Word32 i;
+
+ /* Synthesis */
+ Decoder_amr(((Speech_Decode_FrameState *) st)->decoder_amrState, mode,
+ parm, frame_type, synth_speech, Az_dec);
+ Post_Filter(((Speech_Decode_FrameState *) st)->post_state, mode,
+ synth_speech, Az_dec);
+
+ /* post HP filter, and 15->16 bits */
+ Post_Process(((Speech_Decode_FrameState *) st)->postHP_state,
+ synth_speech);
+
+ for (i = 0; i < L_FRAME; i++) {
+#ifndef NO13BIT
+ /* Truncate to 13 bits */
+ synth[i] = (Word16)(synth_speech[i] & 0xfff8);
+#else
+ synth[i] = (Word16)(synth_speech[i]);
+#endif
+ }
+
+
+ return;
+}
+
+
+/*
+ * Decoder_amr_exit
+ *
+ *
+ * Parameters:
+ * state I: state structure
+ *
+ * Function:
+ * The memory used for state memory is freed
+ *
+ * Returns:
+ * Void
+ */
+static void Decoder_amr_exit(Decoder_amrState **state)
+{
+ if (state == NULL || *state == NULL) {
+ return;
+ }
+ /* tlsf_free( ( *state )->lsfState );
+ tlsf_free( ( *state )->ec_gain_p_st );
+ tlsf_free( ( *state )->ec_gain_c_st );
+ tlsf_free( ( *state )->pred_state );
+ tlsf_free( ( *state )->background_state );
+ tlsf_free( ( *state )->ph_disp_st );
+ tlsf_free( ( *state )->Cb_gain_averState );
+ tlsf_free( ( *state )->lsp_avg_st );
+ tlsf_free( ( *state )->dtxDecoderState );
+ */
+ /* deallocate memory
+ tlsf_free( *state );*/
+ *state = NULL;
+ return;
+}
+
+
+/*
+ * Post_Filter_exit
+ *
+ *
+ * Parameters:
+ * state I: state structure
+ *
+ * Function:
+ * The memory used for state memory is freed
+ *
+ * Returns:
+ * Void
+ */
+static void Post_Filter_exit(Post_FilterState **state)
+{
+ if (state == NULL || *state == NULL) {
+ return;
+ }
+ //tlsf_free( ( *state )->agc_state );
+
+ /* deallocate memory */
+ //tlsf_free( *state );
+ *state = NULL;
+ return;
+}
+
+
+/*
+ * Post_Process_reset
+ *
+ *
+ * Parameters:
+ * state B: state structure
+ *
+ * Function:
+ * Resets state memory
+ *
+ * Returns:
+ * -1 failure
+ */
+static int Post_Process_reset(Post_ProcessState *state)
+{
+ if ((Post_ProcessState *)state == NULL) {
+ //fprintf( stderr, "Post_Process_reset: invalid parameter\n" );
+ return -1;
+ }
+ state->y2_hi = 0;
+ state->y2_lo = 0;
+ state->y1_hi = 0;
+ state->y1_lo = 0;
+ state->x0 = 0;
+ state->x1 = 0;
+ return 0;
+}
+
+
+/*
+ * Post_Process_exit
+ *
+ *
+ * Parameters:
+ * state I: state structure
+ *
+ * Function:
+ * The memory used for state memory is freed
+ *
+ * Returns:
+ * Void
+ */
+static void Post_Process_exit(Post_ProcessState **state)
+{
+ if (state == NULL || *state == NULL) {
+ return;
+ }
+
+ /* deallocate memory */
+ //tlsf_free( *state );
+ *state = NULL;
+ return;
+}
+
+
+/*
+ * Decoder_amr_init
+ *
+ *
+ * Parameters:
+ * state O: state structure
+ *
+ * Function:
+ * Allocates state memory and initializes state memory
+ *
+ * Returns:
+ * success = 0
+ */
+static Decoder_amrState g_Decoder_amrState;
+static D_plsfState g_D_plsfState;
+static ec_gain_pitchState g_ec_gain_pitchState;
+static ec_gain_codeState g_ec_gain_codeState;
+static dtx_decState g_dtx_decState;
+static ph_dispState g_ph_dispState;
+static Cb_gain_averageState g_Cb_gain_averageState;
+static lsp_avgState g_lsp_avgState;
+static Bgn_scdState g_Bgn_scdState;
+static gc_predState g_gc_predState;
+static int Decoder_amr_init(Decoder_amrState **state)
+{
+ Decoder_amrState * s;
+
+ if ((Decoder_amrState *)state == NULL) {
+ //fprintf( stderr, "Decoder_amr_init: invalid parameter\n" );
+ return -1;
+ }
+ *state = NULL;
+
+ /* allocate memory
+ if ( ( s = ( Decoder_amrState * ) tlsf_malloc( sizeof( Decoder_amrState ) ) ) ==
+ NULL ) {
+ fprintf( stderr, "Decoder_amr_init: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s = &g_Decoder_amrState;
+
+ /* DPlsf_init */
+ /* allocate memory
+ if ( ( s->lsfState = ( D_plsfState * ) tlsf_malloc( sizeof( D_plsfState ) ) ) ==
+ NULL ) {
+ fprintf( stderr, "DPlsf_init: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->lsfState = &g_D_plsfState;
+
+ /* ecGainPitchInit */
+ /* allocate memory
+ if ( ( s->ec_gain_p_st = ( ec_gain_pitchState * ) tlsf_malloc( sizeof(
+ ec_gain_pitchState ) ) ) == NULL ) {
+ fprintf( stderr, "ecGainPitchInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->ec_gain_p_st = &g_ec_gain_pitchState;
+
+ /* ecGainCodeInit */
+ /* allocate memory
+ if ( ( s->ec_gain_c_st = ( ec_gain_codeState * ) tlsf_malloc( sizeof(
+ ec_gain_codeState ) ) ) == NULL ) {
+ fprintf( stderr, "ecGainCodeInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->ec_gain_c_st = &g_ec_gain_codeState;
+ /* gcPredInit */
+ /* allocate memory
+ if ( ( s->pred_state = ( gc_predState * ) tlsf_malloc( sizeof( gc_predState ) ) )
+ == NULL ) {
+ fprintf( stderr, "gcPredInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->pred_state = &g_gc_predState;
+ /* Cb_gain_averageInit */
+ /* allocate memory
+ if ( ( s->Cb_gain_averState = ( Cb_gain_averageState * ) tlsf_malloc( sizeof(
+ Cb_gain_averageState ) ) ) == NULL ) {
+ fprintf( stderr, "Cb_gain_averageInit: can not malloc state structure\n" )
+ ;
+ return-1;
+ }*/
+ s->Cb_gain_averState = &g_Cb_gain_averageState;
+ memset(s->Cb_gain_averState->cbGainHistory, 0, L_CBGAINHIST << 2);
+
+ /* Initialize hangover handling */
+ s->Cb_gain_averState->hangVar = 0;
+ s->Cb_gain_averState->hangCount = 0;
+
+ /* lsp_avgInit */
+ /* allocate memory
+ if ( ( s->lsp_avg_st = ( lsp_avgState * ) tlsf_malloc( sizeof( lsp_avgState ) ) )
+ == NULL ) {
+ fprintf( stderr, "lsp_avgInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->lsp_avg_st = &g_lsp_avgState;
+ /* Bgn_scdInit */
+ /* allocate memory
+ if ( ( s->background_state = ( Bgn_scdState * ) tlsf_malloc( sizeof( Bgn_scdState
+ ) ) ) == NULL ) {
+ fprintf( stderr, "Bgn_scdInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->background_state = &g_Bgn_scdState;
+ /* phDispInit */
+ /* allocate memory
+ if ( ( s->ph_disp_st = ( ph_dispState * ) tlsf_malloc( sizeof( ph_dispState ) ) )
+ == NULL ) {
+ fprintf( stderr, "phDispInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->ph_disp_st = &g_ph_dispState;
+ /* dtxDecInit */
+ /* allocate memory
+ if ( ( s->dtxDecoderState = ( dtx_decState * ) tlsf_malloc( sizeof( dtx_decState )
+ ) ) == NULL ) {
+ fprintf( stderr, "dtxDecInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->dtxDecoderState = &g_dtx_decState;
+ Decoder_amr_reset(s, 0);
+ *state = s;
+ return 0;
+}
+
+
+/*
+ * Post_Filter_reset
+ *
+ *
+ * Parameters:
+ * state B: state structure
+ *
+ * Function:
+ * Resets state memory
+ *
+ * Returns:
+ * -1 failure
+ */
+static int Post_Filter_reset(Post_FilterState *state)
+{
+ if ((Post_FilterState *)state == NULL) {
+ //fprintf( stderr, "Post_Filter_reset: invalid parameter\n" );
+ return -1;
+ }
+ state->preemph_state_mem_pre = 0;
+ state->agc_state->past_gain = 4096;
+ memset(state->mem_syn_pst, 0, M << 2);
+ memset(state->res2, 0, L_SUBFR << 2);
+ memset(state->synth_buf, 0, (L_FRAME + M) << 2);
+ return 0;
+}
+
+
+/*
+ * Post_Filter_init
+ *
+ *
+ * Parameters:
+ * state O: state structure
+ *
+ * Function:
+ * Allocates state memory and initializes state memory
+ *
+ * Returns:
+ * success = 0
+ */
+static Post_FilterState g_Post_FilterState;
+static agcState g_agcState;
+static int Post_Filter_init(Post_FilterState **state)
+{
+ Post_FilterState * s;
+
+ if ((Post_FilterState *)state == NULL) {
+ //fprintf( stderr, "F057:invalid parameter\n" );
+ return -1;
+ }
+ *state = NULL;
+
+ /* allocate memory
+ if ( ( s = ( Post_FilterState * ) tlsf_malloc( sizeof( Post_FilterState ) ) ) ==
+ NULL ) {
+ fprintf( stderr, "F057:can not malloc filter structure\n" );
+ return-1;
+ }*/
+ s = &g_Post_FilterState;
+ s->agc_state = NULL;
+
+ /* allocate memory
+ if ( ( s->agc_state = ( agcState * ) tlsf_malloc( sizeof( agcState ) ) ) == NULL )
+ {
+ fprintf( stderr, "agcInit: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s->agc_state = &g_agcState;
+ Post_Filter_reset(s);
+ *state = s;
+ return 0;
+}
+
+
+/*
+ * Post_Process_init
+ *
+ *
+ * Parameters:
+ * state O: state structure
+ *
+ * Function:
+ * Allocates state memory and initializes state memory
+ *
+ * Returns:
+ * success = 0
+ */
+static Post_ProcessState g_Post_ProcessState;
+static int Post_Process_init(Post_ProcessState **state)
+{
+ Post_ProcessState * s;
+
+ if ((Post_ProcessState *)state == NULL) {
+ //fprintf( stderr, "Post_Process_init: invalid parameter\n" );
+ return -1;
+ }
+ *state = NULL;
+
+ /* allocate memory
+ if ( ( s = ( Post_ProcessState * ) tlsf_malloc( sizeof( Post_ProcessState ) ) ) ==
+ NULL ) {
+ fprintf( stderr, "Post_Process_init: can not malloc state structure\n" );
+ return-1;
+ }*/
+ s = &g_Post_ProcessState;
+ Post_Process_reset(s);
+ *state = s;
+ return 0;
+}
+
+
+/*
+ * Speech_Decode_Frame_exit
+ *
+ *
+ * Parameters:
+ * state I: state structure
+ *
+ * Function:
+ * The memory used for state memory is freed
+ *
+ * Returns:
+ * Void
+ */
+void Speech_Decode_Frame_exit(void **st)
+{
+ if (((Speech_Decode_FrameState *)(st)) == NULL) {
+ return;
+ }
+ Decoder_amr_exit(&(((Speech_Decode_FrameState *) st)->decoder_amrState
+ ));
+ Post_Filter_exit(&(((Speech_Decode_FrameState *) st)->post_state));
+ Post_Process_exit(&(((Speech_Decode_FrameState *) st)->postHP_state))
+ ;
+
+ /* deallocate memory */
+ //tlsf_free( (( Speech_Decode_FrameState * )st) );
+ return;
+}
+
+
+/*
+ * Speech_Decode_Frame_reset
+ *
+ *
+ * Parameters:
+ * state B: state structure
+ *
+ * Function:
+ * Resets state memory
+ *
+ * Returns:
+ * -1 = failure
+ */
+int Speech_Decode_Frame_reset(void **st)
+{
+ Speech_Decode_FrameState * state;
+
+ if (st == NULL || *st == NULL) {
+ return (-1);
+ }
+ state = (Speech_Decode_FrameState *)st;
+ Decoder_amr_reset(state->decoder_amrState, (enum Mode) 0);
+ Post_Filter_reset(state->post_state);
+ Post_Process_reset(state->postHP_state);
+ return 0;
+}
+
+
+/*
+ * Speech_Decode_Frame_init
+ *
+ *
+ * Parameters:
+ * state O: state structure
+ *
+ * Function:
+ * Allocates state memory and initializes state memory
+ *
+ * Returns:
+ * success = 0
+ */
+static Speech_Decode_FrameState g_Speech_Decode_FrameState;
+
+void * Speech_Decode_Frame_init()
+{
+ Speech_Decode_FrameState * s;
+
+ /* allocate memory
+ if ( ( s = ( Speech_Decode_FrameState * ) tlsf_malloc( sizeof(
+ Speech_Decode_FrameState ) ) ) == NULL ) {
+ fprintf( stderr, "Speech_Decode_Frame_init: can not malloc state "
+ "structure\n" );
+ return NULL;
+ }*/
+ s = &g_Speech_Decode_FrameState;
+ s->decoder_amrState = NULL;
+ s->post_state = NULL;
+ s->postHP_state = NULL;
+
+ if (Decoder_amr_init(&s->decoder_amrState) || Post_Filter_init(&s->
+ post_state) || Post_Process_init(&s->postHP_state)) {
+ Speech_Decode_Frame_exit((void **)(&s));
+ return NULL;
+ }
+ return s;
+}