Network Working Group S. Andersen Request for Comments: 3951 Aalborg University Category: Experimental A. Duric Telio H. Astrom R. Hagen W. Kleijn J. Linden Global IP Sound December 2004
Network Working Group S. Andersen Request for Comments: 3951 Aalborg University Category: Experimental A. Duric Telio H. Astrom R. Hagen W. Kleijn J. Linden Global IP Sound December 2004
Internet Low Bit Rate Codec (iLBC)
因特网低比特率编解码器(iLBC)
Status of this Memo
本备忘录的状况
This memo defines an Experimental Protocol for the Internet community. It does not specify an Internet standard of any kind. Discussion and suggestions for improvement are requested. Distribution of this memo is unlimited.
这份备忘录为互联网社区定义了一个实验性协议。它没有规定任何类型的互联网标准。要求进行讨论并提出改进建议。本备忘录的分发不受限制。
Copyright Notice
版权公告
Copyright (C) The Internet Society (2004).
版权所有(C)互联网协会(2004年)。
Abstract
摘要
This document specifies a speech codec suitable for robust voice communication over IP. The codec is developed by Global IP Sound (GIPS). It is designed for narrow band speech and results in a payload bit rate of 13.33 kbit/s for 30 ms frames and 15.20 kbit/s for 20 ms frames. The codec enables graceful speech quality degradation in the case of lost frames, which occurs in connection with lost or delayed IP packets.
本文档指定了一种适用于通过IP进行稳健语音通信的语音编解码器。编解码器由全球IP声音(GIPS)开发。它专为窄带语音设计,30毫秒帧的有效负载比特率为13.33 kbit/s,20毫秒帧的有效负载比特率为15.20 kbit/s。编解码器能够在丢失帧的情况下实现优美的语音质量下降,这与丢失或延迟的IP数据包有关。
Table of Contents
目录
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 2. Outline of the Codec . . . . . . . . . . . . . . . . . . . . . 5 2.1. Encoder. . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2. Decoder. . . . . . . . . . . . . . . . . . . . . . . . . 7 3. Encoder Principles . . . . . . . . . . . . . . . . . . . . . . 7 3.1. Pre-processing . . . . . . . . . . . . . . . . . . . . . 9 3.2. LPC Analysis and Quantization. . . . . . . . . . . . . . 9 3.2.1. Computation of Autocorrelation Coefficients. . . 10 3.2.2. Computation of LPC Coefficients. . . . . . . . . 11 3.2.3. Computation of LSF Coefficients from LPC Coefficients . . . . . . . . . . . . . . . . . . 11 3.2.4. Quantization of LSF Coefficients . . . . . . . . 12 3.2.5. Stability Check of LSF Coefficients. . . . . . . 13 3.2.6. Interpolation of LSF Coefficients. . . . . . . . 13 3.2.7. LPC Analysis and Quantization for 20 ms Frames . 14 3.3. Calculation of the Residual. . . . . . . . . . . . . . . 15 3.4. Perceptual Weighting Filter. . . . . . . . . . . . . . . 15 3.5. Start State Encoder. . . . . . . . . . . . . . . . . . . 15 3.5.1. Start State Estimation . . . . . . . . . . . . . 16 3.5.2. All-Pass Filtering and Scale Quantization. . . . 17 3.5.3. Scalar Quantization. . . . . . . . . . . . . . . 18 3.6. Encoding the Remaining Samples . . . . . . . . . . . . . 19 3.6.1. Codebook Memory. . . . . . . . . . . . . . . . . 20 3.6.2. Perceptual Weighting of Codebook Memory and Target . . . . . . . . . . . . . . . . . . . 22 3.6.3. Codebook Creation. . . . . . . . . . . . . . . . 23 3.6.3.1. Creation of a Base Codebook . . . . . . 23 3.6.3.2. Codebook Expansion. . . . . . . . . . . 24 3.6.3.3. Codebook Augmentation . . . . . . . . . 24 3.6.4. Codebook Search. . . . . . . . . . . . . . . . . 26 3.6.4.1. Codebook Search at Each Stage . . . . . 26 3.6.4.2. Gain Quantization at Each Stage . . . . 27 3.6.4.3. Preparation of Target for Next Stage. . 28 3.7. Gain Correction Encoding . . . . . . . . . . . . . . . . 28 3.8. Bitstream Definition . . . . . . . . . . . . . . . . . . 29 4. Decoder Principles . . . . . . . . . . . . . . . . . . . . . . 32 4.1. LPC Filter Reconstruction. . . . . . . . . . . . . . . . 33 4.2. Start State Reconstruction . . . . . . . . . . . . . . . 33 4.3. Excitation Decoding Loop . . . . . . . . . . . . . . . . 34 4.4. Multistage Adaptive Codebook Decoding. . . . . . . . . . 35 4.4.1. Construction of the Decoded Excitation Signal. . 35 4.5. Packet Loss Concealment. . . . . . . . . . . . . . . . . 35 4.5.1. Block Received Correctly and Previous Block Also Received. . . . . . . . . . . . . . . . . . 35 4.5.2. Block Not Received . . . . . . . . . . . . . . . 36
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 2. Outline of the Codec . . . . . . . . . . . . . . . . . . . . . 5 2.1. Encoder. . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2. Decoder. . . . . . . . . . . . . . . . . . . . . . . . . 7 3. Encoder Principles . . . . . . . . . . . . . . . . . . . . . . 7 3.1. Pre-processing . . . . . . . . . . . . . . . . . . . . . 9 3.2. LPC Analysis and Quantization. . . . . . . . . . . . . . 9 3.2.1. Computation of Autocorrelation Coefficients. . . 10 3.2.2. Computation of LPC Coefficients. . . . . . . . . 11 3.2.3. Computation of LSF Coefficients from LPC Coefficients . . . . . . . . . . . . . . . . . . 11 3.2.4. Quantization of LSF Coefficients . . . . . . . . 12 3.2.5. Stability Check of LSF Coefficients. . . . . . . 13 3.2.6. Interpolation of LSF Coefficients. . . . . . . . 13 3.2.7. LPC Analysis and Quantization for 20 ms Frames . 14 3.3. Calculation of the Residual. . . . . . . . . . . . . . . 15 3.4. Perceptual Weighting Filter. . . . . . . . . . . . . . . 15 3.5. Start State Encoder. . . . . . . . . . . . . . . . . . . 15 3.5.1. Start State Estimation . . . . . . . . . . . . . 16 3.5.2. All-Pass Filtering and Scale Quantization. . . . 17 3.5.3. Scalar Quantization. . . . . . . . . . . . . . . 18 3.6. Encoding the Remaining Samples . . . . . . . . . . . . . 19 3.6.1. Codebook Memory. . . . . . . . . . . . . . . . . 20 3.6.2. Perceptual Weighting of Codebook Memory and Target . . . . . . . . . . . . . . . . . . . 22 3.6.3. Codebook Creation. . . . . . . . . . . . . . . . 23 3.6.3.1. Creation of a Base Codebook . . . . . . 23 3.6.3.2. Codebook Expansion. . . . . . . . . . . 24 3.6.3.3. Codebook Augmentation . . . . . . . . . 24 3.6.4. Codebook Search. . . . . . . . . . . . . . . . . 26 3.6.4.1. Codebook Search at Each Stage . . . . . 26 3.6.4.2. Gain Quantization at Each Stage . . . . 27 3.6.4.3. Preparation of Target for Next Stage. . 28 3.7. Gain Correction Encoding . . . . . . . . . . . . . . . . 28 3.8. Bitstream Definition . . . . . . . . . . . . . . . . . . 29 4. Decoder Principles . . . . . . . . . . . . . . . . . . . . . . 32 4.1. LPC Filter Reconstruction. . . . . . . . . . . . . . . . 33 4.2. Start State Reconstruction . . . . . . . . . . . . . . . 33 4.3. Excitation Decoding Loop . . . . . . . . . . . . . . . . 34 4.4. Multistage Adaptive Codebook Decoding. . . . . . . . . . 35 4.4.1. Construction of the Decoded Excitation Signal. . 35 4.5. Packet Loss Concealment. . . . . . . . . . . . . . . . . 35 4.5.1. Block Received Correctly and Previous Block Also Received. . . . . . . . . . . . . . . . . . 35 4.5.2. Block Not Received . . . . . . . . . . . . . . . 36
4.5.3. Block Received Correctly When Previous Block Not Received . . . . . . . . . . . . . . . . . . 36 4.6. Enhancement. . . . . . . . . . . . . . . . . . . . . . . 37 4.6.1. Estimating the Pitch . . . . . . . . . . . . . . 39 4.6.2. Determination of the Pitch-Synchronous Sequences. . . . . . . . . . . . . . . . . . . . 39 4.6.3. Calculation of the Smoothed Excitation . . . . . 41 4.6.4. Enhancer Criterion . . . . . . . . . . . . . . . 41 4.6.5. Enhancing the Excitation . . . . . . . . . . . . 42 4.7. Synthesis Filtering. . . . . . . . . . . . . . . . . . . 43 4.8. Post Filtering . . . . . . . . . . . . . . . . . . . . . 43 5. Security Considerations. . . . . . . . . . . . . . . . . . . . 43 6. Evaluation of the iLBC Implementations . . . . . . . . . . . . 43 7. References . . . . . . . . . . . . . . . . . . . . . . . . . . 43 7.1. Normative References . . . . . . . . . . . . . . . . . . 43 7.2. Informative References . . . . . . . . . . . . . . . . . 44 8. ACKNOWLEDGEMENTS . . . . . . . . . . . . . . . . . . . . . . . 44 APPENDIX A: Reference Implementation . . . . . . . . . . . . . . . 45 A.1. iLBC_test.c. . . . . . . . . . . . . . . . . . . . . . . 46 A.2 iLBC_encode.h. . . . . . . . . . . . . . . . . . . . . . 52 A.3. iLBC_encode.c. . . . . . . . . . . . . . . . . . . . . . 53 A.4. iLBC_decode.h. . . . . . . . . . . . . . . . . . . . . . 63 A.5. iLBC_decode.c. . . . . . . . . . . . . . . . . . . . . . 64 A.6. iLBC_define.h. . . . . . . . . . . . . . . . . . . . . . 76 A.7. constants.h. . . . . . . . . . . . . . . . . . . . . . . 80 A.8. constants.c. . . . . . . . . . . . . . . . . . . . . . . 82 A.9. anaFilter.h. . . . . . . . . . . . . . . . . . . . . . . 96 A.10. anaFilter.c. . . . . . . . . . . . . . . . . . . . . . . 97 A.11. createCB.h . . . . . . . . . . . . . . . . . . . . . . . 98 A.12. createCB.c . . . . . . . . . . . . . . . . . . . . . . . 99 A.13. doCPLC.h . . . . . . . . . . . . . . . . . . . . . . . .104 A.14. doCPLC.c . . . . . . . . . . . . . . . . . . . . . . . .104 A.15. enhancer.h . . . . . . . . . . . . . . . . . . . . . . .109 A.16. enhancer.c . . . . . . . . . . . . . . . . . . . . . . .110 A.17. filter.h . . . . . . . . . . . . . . . . . . . . . . . .123 A.18. filter.c . . . . . . . . . . . . . . . . . . . . . . . .125 A.19. FrameClassify.h. . . . . . . . . . . . . . . . . . . . .128 A.20. FrameClassify.c. . . . . . . . . . . . . . . . . . . . .129 A.21. gainquant.h. . . . . . . . . . . . . . . . . . . . . . .131 A.22. gainquant.c. . . . . . . . . . . . . . . . . . . . . . .131 A.23. getCBvec.h . . . . . . . . . . . . . . . . . . . . . . .134 A.24. getCBvec.c . . . . . . . . . . . . . . . . . . . . . . .134 A.25. helpfun.h. . . . . . . . . . . . . . . . . . . . . . . .138 A.26. helpfun.c. . . . . . . . . . . . . . . . . . . . . . . .140 A.27. hpInput.h. . . . . . . . . . . . . . . . . . . . . . . .146 A.28. hpInput.c. . . . . . . . . . . . . . . . . . . . . . . .146 A.29. hpOutput.h . . . . . . . . . . . . . . . . . . . . . . .148 A.30. hpOutput.c . . . . . . . . . . . . . . . . . . . . . . .148
4.5.3. Block Received Correctly When Previous Block Not Received . . . . . . . . . . . . . . . . . . 36 4.6. Enhancement. . . . . . . . . . . . . . . . . . . . . . . 37 4.6.1. Estimating the Pitch . . . . . . . . . . . . . . 39 4.6.2. Determination of the Pitch-Synchronous Sequences. . . . . . . . . . . . . . . . . . . . 39 4.6.3. Calculation of the Smoothed Excitation . . . . . 41 4.6.4. Enhancer Criterion . . . . . . . . . . . . . . . 41 4.6.5. Enhancing the Excitation . . . . . . . . . . . . 42 4.7. Synthesis Filtering. . . . . . . . . . . . . . . . . . . 43 4.8. Post Filtering . . . . . . . . . . . . . . . . . . . . . 43 5. Security Considerations. . . . . . . . . . . . . . . . . . . . 43 6. Evaluation of the iLBC Implementations . . . . . . . . . . . . 43 7. References . . . . . . . . . . . . . . . . . . . . . . . . . . 43 7.1. Normative References . . . . . . . . . . . . . . . . . . 43 7.2. Informative References . . . . . . . . . . . . . . . . . 44 8. ACKNOWLEDGEMENTS . . . . . . . . . . . . . . . . . . . . . . . 44 APPENDIX A: Reference Implementation . . . . . . . . . . . . . . . 45 A.1. iLBC_test.c. . . . . . . . . . . . . . . . . . . . . . . 46 A.2 iLBC_encode.h. . . . . . . . . . . . . . . . . . . . . . 52 A.3. iLBC_encode.c. . . . . . . . . . . . . . . . . . . . . . 53 A.4. iLBC_decode.h. . . . . . . . . . . . . . . . . . . . . . 63 A.5. iLBC_decode.c. . . . . . . . . . . . . . . . . . . . . . 64 A.6. iLBC_define.h. . . . . . . . . . . . . . . . . . . . . . 76 A.7. constants.h. . . . . . . . . . . . . . . . . . . . . . . 80 A.8. constants.c. . . . . . . . . . . . . . . . . . . . . . . 82 A.9. anaFilter.h. . . . . . . . . . . . . . . . . . . . . . . 96 A.10. anaFilter.c. . . . . . . . . . . . . . . . . . . . . . . 97 A.11. createCB.h . . . . . . . . . . . . . . . . . . . . . . . 98 A.12. createCB.c . . . . . . . . . . . . . . . . . . . . . . . 99 A.13. doCPLC.h . . . . . . . . . . . . . . . . . . . . . . . .104 A.14. doCPLC.c . . . . . . . . . . . . . . . . . . . . . . . .104 A.15. enhancer.h . . . . . . . . . . . . . . . . . . . . . . .109 A.16. enhancer.c . . . . . . . . . . . . . . . . . . . . . . .110 A.17. filter.h . . . . . . . . . . . . . . . . . . . . . . . .123 A.18. filter.c . . . . . . . . . . . . . . . . . . . . . . . .125 A.19. FrameClassify.h. . . . . . . . . . . . . . . . . . . . .128 A.20. FrameClassify.c. . . . . . . . . . . . . . . . . . . . .129 A.21. gainquant.h. . . . . . . . . . . . . . . . . . . . . . .131 A.22. gainquant.c. . . . . . . . . . . . . . . . . . . . . . .131 A.23. getCBvec.h . . . . . . . . . . . . . . . . . . . . . . .134 A.24. getCBvec.c . . . . . . . . . . . . . . . . . . . . . . .134 A.25. helpfun.h. . . . . . . . . . . . . . . . . . . . . . . .138 A.26. helpfun.c. . . . . . . . . . . . . . . . . . . . . . . .140 A.27. hpInput.h. . . . . . . . . . . . . . . . . . . . . . . .146 A.28. hpInput.c. . . . . . . . . . . . . . . . . . . . . . . .146 A.29. hpOutput.h . . . . . . . . . . . . . . . . . . . . . . .148 A.30. hpOutput.c . . . . . . . . . . . . . . . . . . . . . . .148
A.31. iCBConstruct.h . . . . . . . . . . . . . . . . . . . . .149 A.32. iCBConstruct.c . . . . . . . . . . . . . . . . . . . . .150 A.33. iCBSearch.h. . . . . . . . . . . . . . . . . . . . . . .152 A.34. iCBSearch.c. . . . . . . . . . . . . . . . . . . . . . .153 A.35. LPCdecode.h. . . . . . . . . . . . . . . . . . . . . . .163 A.36. LPCdecode.c. . . . . . . . . . . . . . . . . . . . . . .164 A.37. LPCencode.h. . . . . . . . . . . . . . . . . . . . . . .167 A.38. LPCencode.c. . . . . . . . . . . . . . . . . . . . . . .167 A.39. lsf.h. . . . . . . . . . . . . . . . . . . . . . . . . .172 A.40. lsf.c. . . . . . . . . . . . . . . . . . . . . . . . . .172 A.41. packing.h. . . . . . . . . . . . . . . . . . . . . . . .178 A.42. packing.c. . . . . . . . . . . . . . . . . . . . . . . .179 A.43. StateConstructW.h. . . . . . . . . . . . . . . . . . . .182 A.44. StateConstructW.c. . . . . . . . . . . . . . . . . . . .183 A.45. StateSearchW.h . . . . . . . . . . . . . . . . . . . . .185 A.46. StateSearchW.c . . . . . . . . . . . . . . . . . . . . .186 A.47. syntFilter.h . . . . . . . . . . . . . . . . . . . . . .190 A.48. syntFilter.c . . . . . . . . . . . . . . . . . . . . . .190 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . .192 Full Copyright Statement . . . . . . . . . . . . . . . . . . . . .194
A.31. iCBConstruct.h . . . . . . . . . . . . . . . . . . . . .149 A.32. iCBConstruct.c . . . . . . . . . . . . . . . . . . . . .150 A.33. iCBSearch.h. . . . . . . . . . . . . . . . . . . . . . .152 A.34. iCBSearch.c. . . . . . . . . . . . . . . . . . . . . . .153 A.35. LPCdecode.h. . . . . . . . . . . . . . . . . . . . . . .163 A.36. LPCdecode.c. . . . . . . . . . . . . . . . . . . . . . .164 A.37. LPCencode.h. . . . . . . . . . . . . . . . . . . . . . .167 A.38. LPCencode.c. . . . . . . . . . . . . . . . . . . . . . .167 A.39. lsf.h. . . . . . . . . . . . . . . . . . . . . . . . . .172 A.40. lsf.c. . . . . . . . . . . . . . . . . . . . . . . . . .172 A.41. packing.h. . . . . . . . . . . . . . . . . . . . . . . .178 A.42. packing.c. . . . . . . . . . . . . . . . . . . . . . . .179 A.43. StateConstructW.h. . . . . . . . . . . . . . . . . . . .182 A.44. StateConstructW.c. . . . . . . . . . . . . . . . . . . .183 A.45. StateSearchW.h . . . . . . . . . . . . . . . . . . . . .185 A.46. StateSearchW.c . . . . . . . . . . . . . . . . . . . . .186 A.47. syntFilter.h . . . . . . . . . . . . . . . . . . . . . .190 A.48. syntFilter.c . . . . . . . . . . . . . . . . . . . . . .190 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . .192 Full Copyright Statement . . . . . . . . . . . . . . . . . . . . .194
This document contains the description of an algorithm for the coding of speech signals sampled at 8 kHz. The algorithm, called iLBC, uses a block-independent linear-predictive coding (LPC) algorithm and has support for two basic frame lengths: 20 ms at 15.2 kbit/s and 30 ms at 13.33 kbit/s. When the codec operates at block lengths of 20 ms, it produces 304 bits per block, which SHOULD be packetized as in [1]. Similarly, for block lengths of 30 ms it produces 400 bits per block, which SHOULD be packetized as in [1]. The two modes for the different frame sizes operate in a very similar way. When they differ it is explicitly stated in the text, usually with the notation x/y, where x refers to the 20 ms mode and y refers to the 30 ms mode.
本文件描述了8 kHz采样语音信号的编码算法。该算法称为iLBC,使用块独立线性预测编码(LPC)算法,支持两种基本帧长度:15.2 kbit/s时为20 ms,13.33 kbit/s时为30 ms。当编解码器以20ms的块长度运行时,它每块产生304位,应按[1]中所述进行打包。类似地,对于30ms的块长度,它会为每个块生成400位,应按照[1]中所述进行打包。不同帧大小的两种模式以非常相似的方式运行。当它们不同时,文本中会明确说明,通常使用符号x/y,其中x表示20毫秒模式,y表示30毫秒模式。
The described algorithm results in a speech coding system with a controlled response to packet losses similar to what is known from pulse code modulation (PCM) with packet loss concealment (PLC), such as the ITU-T G.711 standard [4], which operates at a fixed bit rate of 64 kbit/s. At the same time, the described algorithm enables fixed bit rate coding with a quality-versus-bit rate tradeoff close to state-of-the-art. A suitable RTP payload format for the iLBC codec is specified in [1].
所述算法产生的语音编码系统具有对分组丢失的受控响应,类似于已知的具有分组丢失隐藏(PLC)的脉冲编码调制(PCM),例如ITU-T G.711标准[4],其以64 kbit/s的固定比特率运行。同时,所述算法实现了固定比特率编码,其质量与比特率的折衷接近最新技术。[1]中规定了适用于iLBC编解码器的RTP有效负载格式。
Some of the applications for which this coder is suitable are real time communications such as telephony and videoconferencing, streaming audio, archival, and messaging.
该编码器适用于实时通信的一些应用,如电话和视频会议、流式音频、存档和消息传递。
Cable Television Laboratories (CableLabs(R)) has adopted iLBC as a mandatory PacketCable(TM) audio codec standard for VoIP over Cable applications [3].
有线电视实验室(CableLabs(R))已采用iLBC作为有线VoIP应用的强制性PacketCable(TM)音频编解码器标准[3]。
This document is organized as follows. Section 2 gives a brief outline of the codec. The specific encoder and decoder algorithms are explained in sections 3 and 4, respectively. Appendix A provides a c-code reference implementation.
本文件的组织结构如下。第2节简要介绍了编解码器。具体的编码器和解码器算法分别在第3节和第4节中解释。附录A提供了一个c代码参考实现。
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [2].
本文件中的关键词“必须”、“不得”、“要求”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照BCP 14、RFC 2119[2]中的描述进行解释。
The codec consists of an encoder and a decoder as described in sections 2.1 and 2.2, respectively.
编解码器由编码器和解码器组成,分别如第2.1节和第2.2节所述。
The essence of the codec is LPC and block-based coding of the LPC residual signal. For each 160/240 (20 ms/30 ms) sample block, the following major steps are performed: A set of LPC filters are computed, and the speech signal is filtered through them to produce the residual signal. The codec uses scalar quantization of the dominant part, in terms of energy, of the residual signal for the block. The dominant state is of length 57/58 (20 ms/30 ms) samples and forms a start state for dynamic codebooks constructed from the already coded parts of the residual signal. These dynamic codebooks are used to code the remaining parts of the residual signal. By this method, coding independence between blocks is achieved, resulting in elimination of propagation of perceptual degradations due to packet loss. The method facilitates high-quality packet loss concealment (PLC).
编解码器的本质是LPC和基于块的LPC剩余信号编码。对于每个160/240(20 ms/30 ms)样本块,执行以下主要步骤:计算一组LPC滤波器,并通过它们过滤语音信号以产生残余信号。编解码器使用块的剩余信号的主要部分(能量)的标量量化。主导状态的样本长度为57/58(20ms/30ms),并形成由剩余信号的已编码部分构造的动态码本的开始状态。这些动态码本用于对剩余信号的其余部分进行编码。通过该方法,实现了块之间的编码独立性,从而消除了由于分组丢失而引起的感知退化的传播。该方法有助于高质量分组丢失隐藏(PLC)。
The input to the encoder SHOULD be 16 bit uniform PCM sampled at 8 kHz. It SHOULD be partitioned into blocks of BLOCKL=160/240 samples for the 20/30 ms frame size. Each block is divided into NSUB=4/6 consecutive sub-blocks of SUBL=40 samples each. For 30 ms frame size, the encoder performs two LPC_FILTERORDER=10 linear-predictive coding (LPC) analyses. The first analysis applies a smooth window centered over the second sub-block and extending to the middle of the fifth sub-block. The second LPC analysis applies a smooth asymmetric window centered over the fifth sub-block and extending to the end of the sixth sub-block. For 20 ms frame size, one LPC_FILTERORDER=10 linear-predictive coding (LPC) analysis is performed with a smooth window centered over the third sub-frame.
编码器的输入应为以8 kHz采样的16位统一PCM。对于20/30毫秒帧大小,应将其划分为BLOCKL=160/240个样本块。每个块被划分为NSUB=4/6个连续子块,每个子块的SUBL=40个样本。对于30毫秒的帧大小,编码器执行两次LPC_过滤器顺序=10线性预测编码(LPC)分析。第一个分析应用一个平滑窗口,该窗口位于第二个子块的中心,并延伸到第五个子块的中间。第二个LPC分析应用以第五个子块为中心并延伸至第六个子块末端的平滑不对称窗口。对于20ms的帧大小,使用以第三个子帧为中心的平滑窗口执行一个LPC_滤波器order=10线性预测编码(LPC)分析。
For each of the LPC analyses, a set of line-spectral frequencies (LSFs) are obtained, quantized, and interpolated to obtain LSF coefficients for each sub-block. Subsequently, the LPC residual is computed by using the quantized and interpolated LPC analysis filters.
对于每个LPC分析,获得一组线谱频率(LSF),量化并插值以获得每个子块的LSF系数。随后,通过使用量化和插值LPC分析滤波器来计算LPC残差。
The two consecutive sub-blocks of the residual exhibiting the maximal weighted energy are identified. Within these two sub-blocks, the start state (segment) is selected from two choices: the first 57/58 samples or the last 57/58 samples of the two consecutive sub-blocks. The selected segment is the one of higher energy. The start state is encoded with scalar quantization.
识别显示最大加权能量的残差的两个连续子块。在这两个子块内,从两个选项中选择开始状态(段):两个连续子块的前57/58个样本或最后57/58个样本。选定的段是能量较高的段。开始状态用标量量化编码。
A dynamic codebook encoding procedure is used to encode 1) the 23/22 (20 ms/30 ms) remaining samples in the two sub-blocks containing the start state; 2) the sub-blocks after the start state in time; and 3) the sub-blocks before the start state in time. Thus, the encoding target can be either the 23/22 samples remaining of the two sub-blocks containing the start state or a 40-sample sub-block. This target can consist of samples indexed forward in time or backward in time, depending on the location of the start state.
使用动态码本编码过程来编码1)包含开始状态的两个子块中的23/22(20ms/30ms)剩余样本;2) 在时间上处于启动状态之后的子块;以及3)在时间上处于开始状态之前的子块。因此,编码目标可以是包含开始状态的两个子块中剩余的23/22个样本,也可以是40个样本子块。此目标可以由时间上向前或向后索引的样本组成,具体取决于开始状态的位置。
The codebook coding is based on an adaptive codebook built from a codebook memory that contains decoded LPC excitation samples from the already encoded part of the block. These samples are indexed in the same time direction as the target vector, ending at the sample instant prior to the first sample instant represented in the target vector. The codebook is used in CB_NSTAGES=3 stages in a successive refinement approach, and the resulting three code vector gains are encoded with 5-, 4-, and 3-bit scalar quantization, respectively.
码本编码基于从码本存储器构建的自适应码本,该码本存储器包含来自块的已编码部分的解码LPC激励样本。这些样本在与目标向量相同的时间方向上进行索引,在目标向量中表示的第一个样本瞬间之前的样本瞬间结束。在连续细化方法中,在CB_NSTAGES=3个阶段中使用码本,并且所得的三个码向量增益分别用5、4和3位标量量化进行编码。
The codebook search method employs noise shaping derived from the LPC filters, and the main decision criterion is to minimize the squared error between the target vector and the code vectors. Each code vector in this codebook comes from one of CB_EXPAND=2 codebook sections. The first section is filled with delayed, already encoded residual vectors. The code vectors of the second codebook section are constructed by predefined linear combinations of vectors in the first section of the codebook.
码本搜索方法采用LPC滤波器产生的噪声整形,主要判定准则是最小化目标向量和码向量之间的平方误差。此码本中的每个代码向量来自CB_EXPAND=2码本部分中的一个。第一部分用延迟的、已经编码的剩余向量填充。第二码本部分的码向量由码本第一部分中的向量的预定义线性组合构造。
As codebook encoding with squared-error matching is known to produce a coded signal of less power than does the scalar quantized start state signal, a gain re-scaling method is implemented by a refined search for a better set of codebook gains in terms of power matching after encoding. This is done by searching for a higher value of the gain factor for the first stage codebook, as the subsequent stage codebook gains are scaled by the first stage gain.
由于已知具有平方误差匹配的码本编码产生的编码信号的功率小于标量量化的起始状态信号,因此通过在编码后的功率匹配方面精确搜索更好的码本增益集来实现增益重缩放方法。这是通过搜索第一级码本的增益因子的更高值来实现的,因为后续级码本增益由第一级增益缩放。
Typically for packet communications, a jitter buffer placed at the receiving end decides whether the packet containing an encoded signal block has been received or lost. This logic is not part of the codec described here. For each encoded signal block received the decoder performs a decoding. For each lost signal block, the decoder performs a PLC operation.
通常对于分组通信,放置在接收端的抖动缓冲器决定包含编码信号块的分组是否已被接收或丢失。此逻辑不是此处描述的编解码器的一部分。对于接收到的每个编码信号块,解码器执行解码。对于每个丢失的信号块,解码器执行PLC操作。
The decoding for each block starts by decoding and interpolating the LPC coefficients. Subsequently the start state is decoded.
每个块的解码从解码和插值LPC系数开始。随后,开始状态被解码。
For codebook-encoded segments, each segment is decoded by constructing the three code vectors given by the received codebook indices in the same way that the code vectors were constructed in the encoder. The three gain factors are also decoded and the resulting decoded signal is given by the sum of the three codebook vectors scaled with respective gain.
对于码本编码的段,每个段通过构造由接收的码本索引给出的三个码向量来解码,其方式与编码器中构造码向量的方式相同。这三个增益因子也被解码,得到的解码信号由三个码本矢量的和与各自增益成比例给出。
An enhancement algorithm is applied to the reconstructed excitation signal. This enhancement augments the periodicity of voiced speech regions. The enhancement is optimized under the constraint that the modification signal (defined as the difference between the enhanced excitation and the excitation signal prior to enhancement) has a short-time energy that does not exceed a preset fraction of the short-time energy of the excitation signal prior to enhancement.
对重构的激励信号采用增强算法。这种增强增强了浊音区域的周期性。在修改信号(定义为增强激励和增强前的激励信号之间的差异)具有不超过增强前激励信号的短时能量的预设分数的短时能量的约束下优化增强。
A packet loss concealment (PLC) operation is easily embedded in the decoder. The PLC operation can, e.g., be based on repeating LPC filters and obtaining the LPC residual signal by using a long-term prediction estimate from previous residual blocks.
解码器中容易嵌入丢包隐藏(PLC)操作。例如,PLC操作可以基于重复的LPC滤波器,并通过使用来自先前残余块的长期预测估计来获得LPC残余信号。
The following block diagram is an overview of all the components of the iLBC encoding procedure. The description of the blocks contains references to the section where that particular procedure is further described.
以下框图概述了iLBC编码过程的所有组件。块的描述包含对进一步描述特定程序的章节的引用。
+-----------+ +---------+ +---------+ speech -> | 1. Pre P | -> | 2. LPC | -> | 3. Ana | -> +-----------+ +---------+ +---------+
+-----------+ +---------+ +---------+ speech -> | 1. Pre P | -> | 2. LPC | -> | 3. Ana | -> +-----------+ +---------+ +---------+
+---------------+ +--------------+ -> | 4. Start Sel | ->| 5. Scalar Qu | -> +---------------+ +--------------+
+---------------+ +--------------+ -> | 4. Start Sel | ->| 5. Scalar Qu | -> +---------------+ +--------------+
+--------------+ +---------------+ -> |6. CB Search | -> | 7. Packetize | -> payload | +--------------+ | +---------------+ ----<---------<------ sub-frame 0..2/4 (20 ms/30 ms)
+--------------+ +---------------+ -> |6. CB Search | -> | 7. Packetize | -> payload | +--------------+ | +---------------+ ----<---------<------ sub-frame 0..2/4 (20 ms/30 ms)
Figure 3.1. Flow chart of the iLBC encoder
图3.1。iLBC编码器的流程图
1. Pre-process speech with a HP filter, if needed (section 3.1).
1. 如果需要,使用HP过滤器预处理语音(第3.1节)。
2. Compute LPC parameters, quantize, and interpolate (section 3.2).
2. 计算LPC参数、量化和插值(第3.2节)。
3. Use analysis filters on speech to compute residual (section 3.3).
3. 对语音使用分析滤波器来计算残差(第3.3节)。
4. Select position of 57/58-sample start state (section 3.5).
4. 选择57/58样品开始状态的位置(第3.5节)。
5. Quantize the 57/58-sample start state with scalar quantization (section 3.5).
5. 使用标量量化对57/58样本开始状态进行量化(第3.5节)。
6. Search the codebook for each sub-frame. Start with 23/22 sample block, then encode sub-blocks forward in time, and then encode sub-blocks backward in time. For each block, the steps in Figure 3.4 are performed (section 3.6).
6. 在码本中搜索每个子帧。从23/22采样块开始,然后在时间上向前编码子块,然后在时间上向后编码子块。对于每个块,执行图3.4中的步骤(第3.6节)。
7. Packetize the bits into the payload specified in Table 3.2.
7. 将位打包到表3.2中规定的有效载荷中。
The input to the encoder SHOULD be 16-bit uniform PCM sampled at 8 kHz. Also it SHOULD be partitioned into blocks of BLOCKL=160/240 samples. Each block input to the encoder is divided into NSUB=4/6 consecutive sub-blocks of SUBL=40 samples each.
编码器的输入应为以8 kHz采样的16位统一PCM。此外,还应将其划分为BLOCKL=160/240样本块。输入到编码器的每个块被划分为NSUB=4/6个SUBL=40个样本的连续子块。
0 39 79 119 159 +---------------------------------------+ | 1 | 2 | 3 | 4 | +---------------------------------------+ 20 ms frame
0 39 79 119 159 +---------------------------------------+ | 1 | 2 | 3 | 4 | +---------------------------------------+ 20 ms frame
0 39 79 119 159 199 239 +-----------------------------------------------------------+ | 1 | 2 | 3 | 4 | 5 | 6 | +-----------------------------------------------------------+ 30 ms frame Figure 3.2. One input block to the encoder for 20 ms (with four sub- frames) and 30 ms (with six sub-frames).
0 39 79 119 159 199 239 +-----------------------------------------------------------+ | 1 | 2 | 3 | 4 | 5 | 6 | +-----------------------------------------------------------+ 30 ms frame Figure 3.2. One input block to the encoder for 20 ms (with four sub- frames) and 30 ms (with six sub-frames).
In some applications, the recorded speech signal contains DC level and/or 50/60 Hz noise. If these components have not been removed prior to the encoder call, they should be removed by a high-pass filter. A reference implementation of this, using a filter with a cutoff frequency of 90 Hz, can be found in Appendix A.28.
在某些应用中,记录的语音信号包含直流电平和/或50/60 Hz噪声。如果在编码器调用之前未移除这些组件,则应通过高通滤波器移除它们。附录A.28中提供了使用截止频率为90 Hz的滤波器的参考实施方案。
The input to the LPC analysis module is a possibly high-pass filtered speech buffer, speech_hp, that contains 240/300 (LPC_LOOKBACK + BLOCKL = 80/60 + 160/240 = 240/300) speech samples, where samples 0 through 79/59 are from the previous block and samples 80/60 through 239/299 are from the current block. No look-ahead into the next block is used. For the very first block processed, the look-back samples are assumed to be zeros.
LPC分析模块的输入可能是高通滤波语音缓冲器speech_hp,其中包含240/300(LPC_LOOKBACK+BLOCKL=80/60+160/240=240/300)语音样本,其中样本0到79/59来自前一个块,样本80/60到239/299来自当前块。不使用对下一个区块的展望。对于处理的第一个块,回望样本假定为零。
For each input block, the LPC analysis calculates one/two set(s) of LPC_FILTERORDER=10 LPC filter coefficients using the autocorrelation method and the Levinson-Durbin recursion. These coefficients are converted to the Line Spectrum Frequency representation. In the 20 ms case, the single lsf set represents the spectral characteristics as measured at the center of the third sub-block. For 30 ms frames, the first set, lsf1, represents the spectral properties of the input signal at the center of the second sub-block, and the other set, lsf2, represents the spectral characteristics as measured at the center of the fifth sub-block. The details of the computation for 30 ms frames are described in sections 3.2.1 through 3.2.6. Section 3.2.7 explains how the LPC Analysis and Quantization differs for 20 ms frames.
对于每个输入块,LPC分析使用自相关方法和Levinson-Durbin递归计算一组或两组LPC_滤波器顺序=10个LPC滤波器系数。这些系数转换为线谱频率表示。在20ms的情况下,单个lsf集表示在第三个子块的中心处测量的光谱特性。对于30ms帧,第一组lsf1表示第二子块中心处输入信号的光谱特性,而另一组lsf2表示在第五子块中心处测量的光谱特性。第3.2.1节至第3.2.6节描述了30ms帧的计算细节。第3.2.7节解释了20 ms帧的LPC分析和量化如何不同。
The first step in the LPC analysis procedure is to calculate autocorrelation coefficients by using windowed speech samples. This windowing is the only difference in the LPC analysis procedure for the two sets of coefficients. For the first set, a 240-sample-long standard symmetric Hanning window is applied to samples 0 through 239 of the input data. The first window, lpc_winTbl, is defined as
LPC分析过程的第一步是使用加窗语音样本计算自相关系数。该窗口是两组系数的LPC分析过程中唯一的区别。对于第一组,对输入数据的样本0到239应用240样本长的标准对称汉宁窗口。第一个窗口lpc_winTbl定义为
lpc_winTbl[i]= 0.5 * (1.0 - cos((2*PI*(i+1))/(BLOCKL+1))); i=0,...,119 lpc_winTbl[i] = winTbl[BLOCKL - i - 1]; i=120,...,239
lpc_winTbl[i]= 0.5 * (1.0 - cos((2*PI*(i+1))/(BLOCKL+1))); i=0,...,119 lpc_winTbl[i] = winTbl[BLOCKL - i - 1]; i=120,...,239
The windowed speech speech_hp_win1 is then obtained by multiplying the first 240 samples of the input speech buffer with the window coefficients:
然后,通过将输入语音缓冲区的前240个样本与窗口系数相乘,获得加窗语音语音\u hp\u win1:
speech_hp_win1[i] = speech_hp[i] * lpc_winTbl[i]; i=0,...,BLOCKL-1
speech_hp_win1[i] = speech_hp[i] * lpc_winTbl[i]; i=0,...,BLOCKL-1
From these 240 windowed speech samples, 11 (LPC_FILTERORDER + 1) autocorrelation coefficients, acf1, are calculated:
从这240个加窗语音样本中,计算出11个(LPC_FILTERORDER+1)自相关系数acf1:
acf1[lag] += speech_hp_win1[n] * speech_hp_win1[n + lag]; lag=0,...,LPC_FILTERORDER; n=0,...,BLOCKL-lag-1
acf1[lag] += speech_hp_win1[n] * speech_hp_win1[n + lag]; lag=0,...,LPC_FILTERORDER; n=0,...,BLOCKL-lag-1
In order to make the analysis more robust against numerical precision problems, a spectral smoothing procedure is applied by windowing the autocorrelation coefficients before the LPC coefficients are computed. Also, a white noise floor is added to the autocorrelation function by multiplying coefficient zero by 1.0001 (40dB below the energy of the windowed speech signal). These two steps are implemented by multiplying the autocorrelation coefficients with the following window:
为了使分析对数值精度问题更具鲁棒性,在计算LPC系数之前,通过加窗自相关系数来应用谱平滑程序。此外,通过将系数0乘以1.0001(比加窗语音信号的能量低40dB),将白噪声下限添加到自相关函数中。这两个步骤通过将自相关系数乘以以下窗口来实现:
lpc_lagwinTbl[0] = 1.0001; lpc_lagwinTbl[i] = exp(-0.5 * ((2 * PI * 60.0 * i) /FS)^2); i=1,...,LPC_FILTERORDER where FS=8000 is the sampling frequency
lpc_lagwinTbl[0] = 1.0001; lpc_lagwinTbl[i] = exp(-0.5 * ((2 * PI * 60.0 * i) /FS)^2); i=1,...,LPC_FILTERORDER where FS=8000 is the sampling frequency
Then, the windowed acf function acf1_win is obtained by
然后,通过以下方式获得加窗acf函数acf1_win:
acf1_win[i] = acf1[i] * lpc_lagwinTbl[i]; i=0,...,LPC_FILTERORDER
acf1_win[i] = acf1[i] * lpc_lagwinTbl[i]; i=0,...,LPC_FILTERORDER
The second set of autocorrelation coefficients, acf2_win, are obtained in a similar manner. The window, lpc_asymwinTbl, is applied to samples 60 through 299, i.e., the entire current block. The
第二组自相关系数acf2_win以类似的方式获得。窗口lpc_asymwinTbl应用于样本60到299,即整个当前块。这个
window consists of two segments, the first (samples 0 to 219) being half a Hanning window with length 440 and the second a quarter of a cycle of a cosine wave. By using this asymmetric window, an LPC analysis centered in the fifth sub-block is obtained without the need for any look-ahead, which would add delay. The asymmetric window is defined as
窗口由两段组成,第一段(样本0至219)为长度为440的半个汉宁窗口,第二段为余弦波周期的四分之一。通过使用此非对称窗口,可以获得以第五个子块为中心的LPC分析,而无需任何前瞻,这将增加延迟。非对称窗口定义为
lpc_asymwinTbl[i] = (sin(PI * (i + 1) / 441))^2; i=0,...,219
lpc_asymwinTbl[i] = (sin(PI * (i + 1) / 441))^2; i=0,...,219
lpc_asymwinTbl[i] = cos((i - 220) * PI / 40); i=220,...,239
lpc_asymwinTbl[i] = cos((i - 220) * PI / 40); i=220,...,239
and the windowed speech is computed by
加窗语音由
speech_hp_win2[i] = speech_hp[i + LPC_LOOKBACK] * lpc_asymwinTbl[i]; i=0,....BLOCKL-1
speech_hp_win2[i] = speech_hp[i + LPC_LOOKBACK] * lpc_asymwinTbl[i]; i=0,....BLOCKL-1
The windowed autocorrelation coefficients are then obtained in exactly the same way as for the first analysis instance.
然后以与第一个分析实例完全相同的方式获得加窗自相关系数。
The generation of the windows lpc_winTbl, lpc_asymwinTbl, and lpc_lagwinTbl are typically done in advance, and the arrays are stored in ROM rather than repeating the calculation for every block.
windows lpc_winTbl、lpc_asymwinTbl和lpc_lagwinTbl的生成通常提前完成,数组存储在ROM中,而不是对每个块重复计算。
From the 2 x 11 smoothed autocorrelation coefficients, acf1_win and acf2_win, the 2 x 11 LPC coefficients, lp1 and lp2, are calculated in the same way for both analysis locations by using the well known Levinson-Durbin recursion. The first LPC coefficient is always 1.0, resulting in ten unique coefficients.
从2 x 11平滑的自相关系数acf1_-win和acf2_-win,通过使用著名的Levinson-Durbin递归,以相同的方式计算两个分析位置的2 x 11 LPC系数lp1和lp2。第一个LPC系数始终为1.0,由此产生十个唯一系数。
After determining the LPC coefficients, a bandwidth expansion procedure is applied to smooth the spectral peaks in the short-term spectrum. The bandwidth addition is obtained by the following modification of the LPC coefficients:
在确定LPC系数后,应用带宽扩展程序平滑短期频谱中的频谱峰值。通过以下修改LPC系数获得带宽增加:
lp1_bw[i] = lp1[i] * chirp^i; i=0,...,LPC_FILTERORDER lp2_bw[i] = lp2[i] * chirp^i; i=0,...,LPC_FILTERORDER
lp1_bw[i] = lp1[i] * chirp^i; i=0,...,LPC_FILTERORDER lp2_bw[i] = lp2[i] * chirp^i; i=0,...,LPC_FILTERORDER
where "chirp" is a real number between 0 and 1. It is RECOMMENDED to use a value of 0.9.
其中“chirp”是介于0和1之间的实数。建议使用0.9的值。
Thus far, two sets of LPC coefficients that represent the short-term spectral characteristics of the speech signal for two different time locations within the current block have been determined. These coefficients SHOULD be quantized and interpolated. Before this is
迄今为止,已经确定了表示当前块内两个不同时间位置的语音信号的短期频谱特征的两组LPC系数。这些系数应进行量化和插值。在这之前
done, it is advantageous to convert the LPC parameters into another type of representation called Line Spectral Frequencies (LSF). The LSF parameters are used because they are better suited for quantization and interpolation than the regular LPC coefficients. Many computationally efficient methods for calculating the LSFs from the LPC coefficients have been proposed in the literature. The detailed implementation of one applicable method can be found in Appendix A.26. The two arrays of LSF coefficients obtained, lsf1 and lsf2, are of dimension 10 (LPC_FILTERORDER).
完成后,将LPC参数转换为另一种称为线谱频率(LSF)的表示形式是有利的。使用LSF参数是因为它们比常规LPC系数更适合量化和插值。文献中提出了许多从LPC系数计算LSF的计算效率高的方法。一种适用方法的详细实施情况见附录A.26。获得的LSF系数的两个数组lsf1和lsf2的维数为10(LPC_FILTERORDER)。
Because the LPC filters defined by the two sets of LSFs are also needed in the decoder, the LSF parameters need to be quantized and transmitted as side information. The total number of bits required to represent the quantization of the two LSF representations for one block of speech is 40, with 20 bits used for each of lsf1 and lsf2.
由于解码器中还需要由两组LSF定义的LPC滤波器,因此LSF参数需要量化并作为旁侧信息传输。表示一个语音块的两个LSF表示的量化所需的总比特数为40,其中20比特用于lsf1和lsf2中的每一个。
For computational and storage reasons, the LSF vectors are quantized using three-split vector quantization (VQ). That is, the LSF vectors are split into three sub-vectors that are each quantized with a regular VQ. The quantized versions of lsf1 and lsf2, qlsf1 and qlsf2, are obtained by using the same memoryless split VQ. The length of each of these two LSF vectors is 10, and they are split into three sub-vectors containing 3, 3, and 4 values, respectively.
出于计算和存储原因,使用三分裂矢量量化(VQ)对LSF矢量进行量化。也就是说,LSF向量被分割成三个子向量,每个子向量用规则VQ量化。lsf1和lsf2、qlsf1和qlsf2的量化版本是通过使用相同的无记忆分割VQ获得的。这两个LSF向量的长度都是10,它们被分成三个子向量,分别包含3、3和4个值。
For each of the sub-vectors, a separate codebook of quantized values has been designed with a standard VQ training method for a large database containing speech from a large number of speakers recorded under various conditions. The size of each of the three codebooks associated with the split definitions above is
对于每个子向量,使用标准VQ训练方法设计了量化值的单独码本,用于包含在各种条件下记录的大量说话人的语音的大型数据库。与上述拆分定义关联的三个码本的大小分别为
int size_lsfCbTbl[LSF_NSPLIT] = {64,128,128};
int size_lsfCbTbl[LSF_NSPLIT] = {64,128,128};
The actual values of the vector quantization codebook that must be used can be found in the reference code of Appendix A. Both sets of LSF coefficients, lsf1 and lsf2, are quantized with a standard memoryless split vector quantization (VQ) structure using the squared error criterion in the LSF domain. The split VQ quantization consists of the following steps:
必须使用的矢量量化码本的实际值可在附录A的参考代码中找到。两组LSF系数lsf1和lsf2均使用LSF域中的平方误差准则,使用标准无记忆分割矢量量化(VQ)结构进行量化。分割VQ量化包括以下步骤:
1) Quantize the first three LSF coefficients (1 - 3) with a VQ codebook of size 64. 2) Quantize the next three LSF coefficients 4 - 6 with VQ a codebook of size 128. 3) Quantize the last four LSF coefficients (7 - 10) with a VQ codebook of size 128.
1) 使用大小为64的VQ码本量化前三个LSF系数(1-3)。2) 使用大小为128的码本对接下来的三个LSF系数4-6进行量化。3) 使用大小为128的VQ码本量化最后四个LSF系数(7-10)。
This procedure, repeated for lsf1 and lsf2, gives six quantization indices and the quantized sets of LSF coefficients qlsf1 and qlsf2. Each set of three indices is encoded with 6 + 7 + 7 = 20 bits. The total number of bits used for LSF quantization in a block is thus 40 bits.
此过程对lsf1和lsf2重复,给出了六个量化索引和LSF系数qlsf1和qlsf2的量化集。每组三个索引用6+7+7=20位编码。因此,块中用于LSF量化的总比特数为40比特。
The LSF representation of the LPC filter has the convenient property that the coefficients are ordered by increasing value, i.e., lsf(n-1) < lsf(n), 0 < n < 10, if the corresponding synthesis filter is stable. As we are employing a split VQ scheme, it is possible that at the split boundaries the LSF coefficients are not ordered correctly and hence that the corresponding LP filter is unstable. To ensure that the filter used is stable, a stability check is performed for the quantized LSF vectors. If it turns out that the coefficients are not ordered appropriately (with a safety margin of 50 Hz to ensure that formant peaks are not too narrow), they will be moved apart. The detailed method for this can be found in Appendix A.40. The same procedure is performed in the decoder. This ensures that exactly the same LSF representations are used in both encoder and decoder.
LPC滤波器的LSF表示具有方便的特性,即如果相应的合成滤波器是稳定的,则系数按增加的值排序,即LSF(n-1)<LSF(n),0<n<10。由于我们采用分割VQ方案,可能在分割边界处LSF系数顺序不正确,因此相应的LP滤波器不稳定。为了确保所使用的滤波器是稳定的,对量化的LSF向量执行稳定性检查。如果结果表明系数顺序不正确(安全裕度为50 Hz,以确保共振峰不太窄),它们将被分开。详细方法见附录A.40。在解码器中执行相同的过程。这确保在编码器和解码器中使用完全相同的LSF表示。
From the two sets of LSF coefficients that are computed for each block of speech, different LSFs are obtained for each sub-block by means of interpolation. This procedure is performed for the original LSFs (lsf1 and lsf2), as well as the quantized versions qlsf1 and qlsf2, as both versions are used in the encoder. Here follows a brief summary of the interpolation scheme; the details are found in the c-code of Appendix A. In the first sub-block, the average of the second LSF vector from the previous block and the first LSF vector in the current block is used. For sub-blocks two through five, the LSFs used are obtained by linear interpolation from lsf1 (and qlsf1) to lsf2 (and qlsf2), with lsf1 used in sub-block two and lsf2 in sub-block five. In the last sub-block, lsf2 is used. For the very first block it is assumed that the last LSF vector of the previous block is equal to a predefined vector, lsfmeanTbl, obtained by calculating the mean LSF vector of the LSF design database.
从为每个语音块计算的两组LSF系数中,通过插值为每个子块获得不同的LSF。此过程针对原始LSF(lsf1和lsf2)以及量化版本qlsf1和qlsf2执行,因为编码器中使用了这两个版本。下面是插值方案的简要概述;详细信息见附录A的c代码。在第一个子块中,使用前一个块中的第二个LSF向量和当前块中的第一个LSF向量的平均值。对于子块2到5,使用的LSF通过从lsf1(和qlsf1)到lsf2(和qlsf2)的线性插值获得,lsf1用于子块2,lsf2用于子块5。在最后一个子块中,使用lsf2。对于第一个块,假设前一块的最后一个LSF向量等于通过计算LSF设计数据库的平均LSF向量而获得的预定义向量lsfmeanTbl。
lsfmeanTbl[LPC_FILTERORDER] = {0.281738, 0.445801, 0.663330, 0.962524, 1.251831, 1.533081, 1.850586, 2.137817, 2.481445, 2.777344}
lsfmeanTbl[LPC_FILTERORDER] = {0.281738, 0.445801, 0.663330, 0.962524, 1.251831, 1.533081, 1.850586, 2.137817, 2.481445, 2.777344}
The interpolation method is standard linear interpolation in the LSF domain. The interpolated LSF values are converted to LPC coefficients for each sub-block. The unquantized and quantized LPC coefficients form two sets of filters respectively. The unquantized analysis filter for sub-block k is defined as follows
插值方法是LSF域中的标准线性插值。插值的LSF值被转换为每个子块的LPC系数。未量化和量化的LPC系数分别形成两组滤波器。子块k的非量化分析滤波器定义如下
___ \ Ak(z)= 1 + > ak(i)*z^(-i) /__ i=1...LPC_FILTERORDER
___ \ Ak(z)= 1 + > ak(i)*z^(-i) /__ i=1...LPC_FILTERORDER
The quantized analysis filter for sub-block k is defined as follows ___ \ A~k(z)= 1 + > a~k(i)*z^(-i) /__ i=1...LPC_FILTERORDER
The quantized analysis filter for sub-block k is defined as follows ___ \ A~k(z)= 1 + > a~k(i)*z^(-i) /__ i=1...LPC_FILTERORDER
A reference implementation of the lsf encoding is given in Appendix A.38. A reference implementation of the corresponding decoding can be found in Appendix A.36.
附录A.38中给出了lsf编码的参考实现。相应解码的参考实现可在附录A.36中找到。
As previously stated, the codec only calculates one set of LPC parameters for the 20 ms frame size as opposed to two sets for 30 ms frames. A single set of autocorrelation coefficients is calculated on the LPC_LOOKBACK + BLOCKL = 80 + 160 = 240 samples. These samples are windowed with the asymmetric window lpc_asymwinTbl, centered over the third sub-frame, to form speech_hp_win. Autocorrelation coefficients, acf, are calculated on the 240 samples in speech_hp_win and then windowed exactly as in section 3.2.1 (resulting in acf_win).
如前所述,编解码器仅为20ms帧大小计算一组LPC参数,而不是为30ms帧计算两组LPC参数。在LPC_回望+块L=80+160=240个样本上计算一组自相关系数。这些样本用不对称窗口lpc_asymwinTbl加窗,以第三个子帧为中心,形成语音。在speech_hp_win中,对240个样本计算自相关系数acf,然后按照第3.2.1节的要求对其加窗(结果为acf_win)。
This single set of windowed autocorrelation coefficients is used to calculate LPC coefficients, LSF coefficients, and quantized LSF coefficients in exactly the same manner as in sections 3.2.3 through 3.2.4. As for the 30 ms frame size, the ten LSF coefficients are divided into three sub-vectors of size 3, 3, and 4 and quantized by using the same scheme and codebook as in section 3.2.4 to finally get 3 quantization indices. The quantized LSF coefficients are stabilized with the algorithm described in section 3.2.5.
该单组加窗自相关系数用于计算LPC系数、LSF系数和量化LSF系数,计算方式与第3.2.3节至第3.2.4节完全相同。对于30ms帧大小,将十个LSF系数划分为大小为3、3和4的三个子向量,并使用与第3.2.4节中相同的方案和码本进行量化,以最终获得3个量化索引。使用第3.2.5节中描述的算法稳定量化LSF系数。
From the set of LSF coefficients computed for this block and those from the previous block, different LSFs are obtained for each sub-block by means of interpolation. The interpolation is done linearly in the LSF domain over the four sub-blocks, so that the n-th sub-
从为该块和前一块计算的LSF系数集合中,通过插值为每个子块获得不同的LSF。插值在四个子块上的LSF域中线性完成,因此第n个子块-
frame uses the weight (4-n)/4 for the LSF from old frame and the weight n/4 of the LSF from the current frame. For the very first block the mean LSF, lsfmeanTbl, is used as the LSF from the previous block. Similarly as seen in section 3.2.6, both unquantized, A(z), and quantized, A~(z), analysis filters are calculated for each of the four sub-blocks.
帧使用来自旧帧的LSF的权重(4-n)/4和来自当前帧的LSF的权重n/4。对于第一个块,平均LSF lsfmeanTbl用作前一个块的LSF。类似地,如第3.2.6节所示,为四个子块中的每一个子块计算未量化A(z)和量化A~(z)分析滤波器。
The block of speech samples is filtered by the quantized and interpolated LPC analysis filters to yield the residual signal. In particular, the corresponding LPC analysis filter for each 40 sample sub-block is used to filter the speech samples for the same sub-block. The filter memory at the end of each sub-block is carried over to the LPC filter of the next sub-block. The signal at the output of each LP analysis filter constitutes the residual signal for the corresponding sub-block.
语音样本块通过量化和插值LPC分析滤波器进行滤波,以产生残余信号。具体地,每个40个样本子块的对应LPC分析滤波器用于过滤相同子块的语音样本。每个子块末尾的滤波器存储器被传送到下一个子块的LPC滤波器。每个LP分析滤波器输出处的信号构成相应子块的剩余信号。
A reference implementation of the LPC analysis filters is given in Appendix A.10.
附录A.10中给出了LPC分析过滤器的参考实现。
In principle any good design of a perceptual weighting filter can be applied in the encoder without compromising this codec definition. However, it is RECOMMENDED to use the perceptual weighting filter Wk for sub-block k specified below:
原则上,感知加权滤波器的任何良好设计都可以应用于编码器中,而不会影响编解码器的定义。但是,建议对下面指定的子块k使用感知加权滤波器Wk:
Wk(z)=1/Ak(z/LPC_CHIRP_WEIGHTDENUM), where LPC_CHIRP_WEIGHTDENUM = 0.4222
Wk(z)=1/Ak(z/LPC_CHIRP_WEIGHTDENUM), where LPC_CHIRP_WEIGHTDENUM = 0.4222
This is a simple design with low complexity that is applied in the LPC residual domain. Here Ak(z) is the filter obtained for sub-block k from unquantized but interpolated LSF coefficients.
这是一种应用于LPC剩余域的简单设计,具有较低的复杂性。这里,Ak(z)是从未量化但插值的LSF系数中为子块k获得的滤波器。
The start state is quantized by using a common 6-bit scalar quantizer for the block and a 3-bit scalar quantizer operating on scaled samples in the weighted speech domain. In the following we describe the state encoding in greater detail.
通过使用块的公共6位标量量化器和对加权语音域中的缩放样本进行操作的3位标量量化器对开始状态进行量化。下面我们将更详细地描述状态编码。
The two sub-blocks containing the start state are determined by finding the two consecutive sub-blocks in the block having the highest power. Advantageously, down-weighting is used in the beginning and end of the sub-frames, i.e., the following measure is computed (NSUB=4/6 for 20/30 ms frame size):
通过查找具有最高功率的块中的两个连续子块来确定包含启动状态的两个子块。有利地,在子帧的开始和结束处使用下加权,即,计算以下度量(对于20/30ms帧大小,NSUB=4/6):
nsub=1,...,NSUB-1 ssqn[nsub] = 0.0; for (i=(nsub-1)*SUBL; i<(nsub-1)*SUBL+5; i++) ssqn[nsub] += sampEn_win[i-(nsub-1)*SUBL]* residual[i]*residual[i]; for (i=(nsub-1)*SUBL+5; i<(nsub+1)*SUBL-5; i++) ssqn[nsub] += residual[i]*residual[i]; for (i=(nsub+1)*SUBL-5; i<(nsub+1)*SUBL; i++) ssqn[nsub] += sampEn_win[(nsub+1)*SUBL-i-1]* residual[i]*residual[i];
nsub=1,...,NSUB-1 ssqn[nsub] = 0.0; for (i=(nsub-1)*SUBL; i<(nsub-1)*SUBL+5; i++) ssqn[nsub] += sampEn_win[i-(nsub-1)*SUBL]* residual[i]*residual[i]; for (i=(nsub-1)*SUBL+5; i<(nsub+1)*SUBL-5; i++) ssqn[nsub] += residual[i]*residual[i]; for (i=(nsub+1)*SUBL-5; i<(nsub+1)*SUBL; i++) ssqn[nsub] += sampEn_win[(nsub+1)*SUBL-i-1]* residual[i]*residual[i];
where sampEn_win[5]={1/6, 2/6, 3/6, 4/6, 5/6}; MAY be used. The sub-frame number corresponding to the maximum value of ssqEn_win[nsub-1]*ssqn[nsub] is selected as the start state indicator. A weighting of ssqEn_win[]={0.8,0.9,1.0,0.9,0.8} for 30 ms frames and ssqEn_win[]={0.9,1.0,0.9} for 20 ms frames; MAY advantageously be used to bias the start state towards the middle of the frame.
其中sampEn_win[5]={1/6,2/6,3/6,4/6,5/6};可以使用。选择与ssqEn_win[nsub-1]*ssqn[nsub]的最大值相对应的子帧编号作为启动状态指示器。对于30ms帧,ssqEn_-win[]={0.8,0.9,1.0,0.9,0.8}的权重,对于20ms帧,ssqEn_-win[]={0.9,1.0,0.9}的权重;可有利地用于使开始状态偏向帧的中间。
For 20 ms frames there are three possible positions for the two-sub-block length maximum power segment; the start state position is encoded with 2 bits. The start state position, start, MUST be encoded as
对于20ms帧,两个子块长度最大功率段有三个可能的位置;起始状态位置用2位编码。开始状态位置start必须编码为
start=1: start state in sub-frame 0 and 1 start=2: start state in sub-frame 1 and 2 start=3: start state in sub-frame 2 and 3
start=1: start state in sub-frame 0 and 1 start=2: start state in sub-frame 1 and 2 start=3: start state in sub-frame 2 and 3
For 30 ms frames there are five possible positions of the two-sub-block length maximum power segment, the start state position is encoded with 3 bits. The start state position, start, MUST be encoded as
对于30ms帧,两个子块长度最大功率段有五个可能的位置,起始状态位置用3位编码。开始状态位置start必须编码为
start=1: start state in sub-frame 0 and 1 start=2: start state in sub-frame 1 and 2 start=3: start state in sub-frame 2 and 3 start=4: start state in sub-frame 3 and 4 start=5: start state in sub-frame 4 and 5
start=1: start state in sub-frame 0 and 1 start=2: start state in sub-frame 1 and 2 start=3: start state in sub-frame 2 and 3 start=4: start state in sub-frame 3 and 4 start=5: start state in sub-frame 4 and 5
Hence, in both cases, index 0 is not used. In order to shorten the start state for bit rate efficiency, the start state is brought down to STATE_SHORT_LEN=57 samples for 20 ms frames and STATE_SHORT_LEN=58 samples for 30 ms frames. The power of the first 23/22 and last 23/22 samples of the two sub-frame blocks identified above is computed as the sum of the squared signal sample values, and the 23/22-sample segment with the lowest power is excluded from the start state. One bit is transmitted to indicate which of the two possible 57/58 sample segments is used. The start state position within the two sub-frames determined above, state_first, MUST be encoded as
因此,在这两种情况下,都不使用索引0。为了缩短比特率效率的启动状态,启动状态降低为20毫秒帧的状态_SHORT_LEN=57个样本,30毫秒帧的状态_SHORT_LEN=58个样本。将上面识别的两个子帧块的前23/22和最后23/22样本的功率计算为平方信号样本值的和,并且从开始状态排除具有最低功率的23/22样本段。传输一位以指示使用了两个可能的57/58采样段中的哪一个。上面确定的两个子帧内的开始状态位置,即状态_first,必须编码为
state_first=1: start state is first STATE_SHORT_LEN samples state_first=0: start state is last STATE_SHORT_LEN samples
state_first=1: start state is first STATE_SHORT_LEN samples state_first=0: start state is last STATE_SHORT_LEN samples
The block of residual samples in the start state is first filtered by an all-pass filter with the quantized LPC coefficients as denominator and reversed quantized LPC coefficients as numerator. The purpose of this phase-dispersion filter is to get a more even distribution of the sample values in the residual signal. The filtering is performed by circular convolution, where the initial filter memory is set to zero.
开始状态下的剩余样本块首先由全通滤波器进行滤波,其中量化LPC系数作为分母,反向量化LPC系数作为分子。该相位色散滤波器的目的是在剩余信号中获得更均匀的采样值分布。通过循环卷积执行滤波,其中初始滤波器存储器设置为零。
res(0..(STATE_SHORT_LEN-1)) = uncoded start state residual res((STATE_SHORT_LEN)..(2*STATE_SHORT_LEN-1)) = 0
res(0..(STATE_SHORT_LEN-1)) = uncoded start state residual res((STATE_SHORT_LEN)..(2*STATE_SHORT_LEN-1)) = 0
Pk(z) = A~rk(z)/A~k(z), where ___ \ A~rk(z)= z^(-LPC_FILTERORDER)+>a~k(i+1)*z^(i-(LPC_FILTERORDER-1)) /__ i=0...(LPC_FILTERORDER-1)
Pk(z) = A~rk(z)/A~k(z), where ___ \ A~rk(z)= z^(-LPC_FILTERORDER)+>a~k(i+1)*z^(i-(LPC_FILTERORDER-1)) /__ i=0...(LPC_FILTERORDER-1)
and A~k(z) is taken from the block where the start state begins
A~k(z)取自起始状态开始的块
res -> Pk(z) -> filtered
res -> Pk(z) -> filtered
ccres(k) = filtered(k) + filtered(k+STATE_SHORT_LEN), k=0..(STATE_SHORT_LEN-1)
ccres(k) = filtered(k) + filtered(k+STATE_SHORT_LEN), k=0..(STATE_SHORT_LEN-1)
The all-pass filtered block is searched for its largest magnitude sample. The 10-logarithm of this magnitude is quantized with a 6-bit quantizer, state_frgqTbl, by finding the nearest representation.
搜索全通滤波块以查找其最大幅值样本。通过查找最近的表示,使用6位量化器state_frgqTbl对该幅度的10个对数进行量化。
This results in an index, idxForMax, corresponding to a quantized value, qmax. The all-pass filtered residual samples in the block are then multiplied with a scaling factor scal=4.5/(10^qmax) to yield normalized samples.
这会产生一个索引idxForMax,对应于量化值qmax。然后,将块中的全通滤波剩余样本与缩放因子scal=4.5/(10^qmax)相乘,以产生归一化样本。
state_frgqTbl[64] = {1.000085, 1.071695, 1.140395, 1.206868, 1.277188, 1.351503, 1.429380, 1.500727, 1.569049, 1.639599, 1.707071, 1.781531, 1.840799, 1.901550, 1.956695, 2.006750, 2.055474, 2.102787, 2.142819, 2.183592, 2.217962, 2.257177, 2.295739, 2.332967, 2.369248, 2.402792, 2.435080, 2.468598, 2.503394, 2.539284, 2.572944, 2.605036, 2.636331, 2.668939, 2.698780, 2.729101, 2.759786, 2.789834, 2.818679, 2.848074, 2.877470, 2.906899, 2.936655, 2.967804, 3.000115, 3.033367, 3.066355, 3.104231, 3.141499, 3.183012, 3.222952, 3.265433, 3.308441, 3.350823, 3.395275, 3.442793, 3.490801, 3.542514, 3.604064, 3.666050, 3.740994, 3.830749, 3.938770, 4.101764}
state_frgqTbl[64] = {1.000085, 1.071695, 1.140395, 1.206868, 1.277188, 1.351503, 1.429380, 1.500727, 1.569049, 1.639599, 1.707071, 1.781531, 1.840799, 1.901550, 1.956695, 2.006750, 2.055474, 2.102787, 2.142819, 2.183592, 2.217962, 2.257177, 2.295739, 2.332967, 2.369248, 2.402792, 2.435080, 2.468598, 2.503394, 2.539284, 2.572944, 2.605036, 2.636331, 2.668939, 2.698780, 2.729101, 2.759786, 2.789834, 2.818679, 2.848074, 2.877470, 2.906899, 2.936655, 2.967804, 3.000115, 3.033367, 3.066355, 3.104231, 3.141499, 3.183012, 3.222952, 3.265433, 3.308441, 3.350823, 3.395275, 3.442793, 3.490801, 3.542514, 3.604064, 3.666050, 3.740994, 3.830749, 3.938770, 4.101764}
The normalized samples are quantized in the perceptually weighted speech domain by a sample-by-sample scalar DPCM quantization as depicted in Figure 3.3. Each sample in the block is filtered by a weighting filter Wk(z), specified in section 3.4, to form a weighted speech sample x[n]. The target sample d[n] is formed by subtracting a predicted sample y[n], where the prediction filter is given by
归一化样本在感知加权语音域中通过逐样本标量DPCM量化进行量化,如图3.3所示。块中的每个样本由第3.4节中规定的加权滤波器Wk(z)进行滤波,以形成加权语音样本x[n]。通过减去预测样本y[n]形成目标样本d[n],其中预测滤波器由下式给出
Pk(z) = 1 - 1 / Wk(z).
Pk(z)=1-1/周(z)。
+-------+ x[n] + d[n] +-----------+ u[n] residual -->| Wk(z) |-------->(+)---->| Quantizer |------> quantized +-------+ - /|\ +-----------+ | residual | \|/ y[n] +--------------------->(+) | | | +------+ | +--------| Pk(z)|<------+ +------+
+-------+ x[n] + d[n] +-----------+ u[n] residual -->| Wk(z) |-------->(+)---->| Quantizer |------> quantized +-------+ - /|\ +-----------+ | residual | \|/ y[n] +--------------------->(+) | | | +------+ | +--------| Pk(z)|<------+ +------+
Figure 3.3. Quantization of start state samples by DPCM in weighted speech domain.
图3.3。在加权语音域中通过DPCM对起始状态样本进行量化。
The coded state sample u[n] is obtained by quantizing d[n] with a 3- bit quantizer with quantization table state_sq3Tbl.
编码状态样本u[n]是通过使用具有量化表state_sq3Tbl的3位量化器对d[n]进行量化而获得的。
state_sq3Tbl[8] = {-3.719849, -2.177490, -1.130005, -0.309692, 0.444214, 1.329712, 2.436279, 3.983887}
state_sq3Tbl[8] = {-3.719849, -2.177490, -1.130005, -0.309692, 0.444214, 1.329712, 2.436279, 3.983887}
The quantized samples are transformed back to the residual domain by 1) scaling with 1/scal; 2) time-reversing the scaled samples; 3) filtering the time-reversed samples by the same all-pass filter, as in section 3.5.2, by using circular convolution; and 4) time-reversing the filtered samples. (More detail is in section 4.2.)
通过1)1/scal缩放将量化样本转换回剩余域;2) 对缩放样本进行时间反转;3) 如第3.5.2节所述,通过使用循环卷积,使用相同的全通滤波器对时间反转样本进行滤波;4)对过滤后的样品进行时间反转。(更多详情见第4.2节。)
A reference implementation of the start-state encoding can be found in Appendix A.46.
可在附录A.46中找到启动状态编码的参考实现。
A dynamic codebook is used to encode 1) the 23/22 remaining samples in the two sub-blocks containing the start state; 2) the sub-blocks after the start state in time; and 3) the sub-blocks before the start state in time. Thus, the encoding target can be either the 23/22 samples remaining of the 2 sub-blocks containing the start state, or a 40-sample sub-block. This target can consist of samples that are indexed forward in time or backward in time, depending on the location of the start state. The length of the target is denoted by lTarget.
动态码本用于编码1)包含开始状态的两个子块中的23/22剩余样本;2) 在时间上处于启动状态之后的子块;以及3)在时间上处于开始状态之前的子块。因此,编码目标可以是包含开始状态的2个子块中剩余的23/22个样本,或者是40个样本子块。此目标可以由时间上向前或向后索引的样本组成,具体取决于开始状态的位置。目标的长度由lTarget表示。
The coding is based on an adaptive codebook that is built from a codebook memory that contains decoded LPC excitation samples from the already encoded part of the block. These samples are indexed in the same time direction as is the target vector and end at the sample instant prior to the first sample instant represented in the target vector. The codebook memory has length lMem, which is equal to CB_MEML=147 for the two/four 40-sample sub-blocks and 85 for the 23/22-sample sub-block.
该编码基于自适应码本,该自适应码本由码本存储器构建,该码本存储器包含来自块的已编码部分的解码LPC激励样本。这些样本在与目标向量相同的时间方向上进行索引,并在目标向量中表示的第一个样本瞬间之前的样本瞬间结束。码本存储器具有长度lMem,对于两个/4个40采样子块,其等于CB_MEML=147,对于23/22采样子块,其等于85。
The following figure shows an overview of the encoding procedure.
下图显示了编码过程的概述。
+------------+ +---------------+ +-------------+ -> | 1. Decode | -> | 2. Mem setup | -> | 3. Perc. W. | -> +------------+ +---------------+ +-------------+
+------------+ +---------------+ +-------------+ -> | 1. Decode | -> | 2. Mem setup | -> | 3. Perc. W. | -> +------------+ +---------------+ +-------------+
+------------+ +-----------------+ -> | 4. Search | -> | 5. Upd. Target | ------------------> | +------------+ +------------------ | ----<-------------<-----------<---------- stage=0..2
+------------+ +-----------------+ -> | 4. Search | -> | 5. Upd. Target | ------------------> | +------------+ +------------------ | ----<-------------<-----------<---------- stage=0..2
+----------------+ -> | 6. Recalc G[0] | ---------------> gains and CB indices +----------------+
+----------------+ -> | 6. Recalc G[0] | ---------------> gains and CB indices +----------------+
Figure 3.4. Flow chart of the codebook search in the iLBC encoder.
图3.4。iLBC编码器中码本搜索的流程图。
1. Decode the part of the residual that has been encoded so far, using the codebook without perceptual weighting.
1. 使用无感知加权的码本解码到目前为止已编码的剩余部分。
2. Set up the memory by taking data from the decoded residual. This memory is used to construct codebooks. For blocks preceding the start state, both the decoded residual and the target are time reversed (section 3.6.1). 3. Filter the memory + target with the perceptual weighting filter (section 3.6.2).
2. 通过从解码的残差中获取数据来设置存储器。该内存用于构造代码本。对于开始状态之前的块,解码残差和目标都是时间反转的(第3.6.1节)。3.使用感知加权过滤器过滤记忆+目标(第3.6.2节)。
4. Search for the best match between the target and the codebook vector. Compute the optimal gain for this match and quantize that gain (section 3.6.4).
4. 搜索目标和码本向量之间的最佳匹配。计算此匹配的最佳增益并量化该增益(第3.6.4节)。
5. Update the perceptually weighted target by subtracting the contribution from the selected codebook vector from the perceptually weighted memory (quantized gain times selected vector). Repeat 4 and 5 for the two additional stages.
5. 通过从感知加权存储器中减去所选码本向量的贡献(量化增益乘以所选向量),更新感知加权目标。对另外两个阶段重复4和5。
6. Calculate the energy loss due to encoding of the residual. If needed, compensate for this loss by an upscaling and requantization of the gain for the first stage (section 3.7).
6. 计算残差编码引起的能量损失。如果需要,通过放大和重新量化第一阶段的增益来补偿该损失(第3.7节)。
The following sections provide an in-depth description of the different blocks of Figure 3.4.
以下各节对图3.4中的不同块进行了深入描述。
The codebook memory is based on the already encoded sub-blocks, so the available data for encoding increases for each new sub-block that has been encoded. Until enough sub-blocks have been encoded to fill the codebook memory with data, it is padded with zeros. The following figure shows an example of the order in which the sub-blocks are encoded for the 30 ms frame size if the start state is located in the last 58 samples of sub-block 2 and 3.
码本存储器基于已经编码的子块,因此对于已经编码的每个新子块,用于编码的可用数据增加。在编码足够的子块以用数据填充码本内存之前,将使用零填充。下图显示了如果开始状态位于子块2和3的最后58个样本中,则针对30ms帧大小对子块进行编码的顺序的示例。
+-----------------------------------------------------+ | 5 | 1 |///|////////| 2 | 3 | 4 | +-----------------------------------------------------+
+-----------------------------------------------------+ | 5 | 1 |///|////////| 2 | 3 | 4 | +-----------------------------------------------------+
Figure 3.5. The order from 1 to 5 in which the sub-blocks are encoded. The slashed area is the start state.
图3.5。子块编码的顺序从1到5。斜线区域是开始状态。
The first target sub-block to be encoded is number 1, and the corresponding codebook memory is shown in the following figure. As the target vector comes before the start state in time, the codebook memory and target vector are time reversed; thus, after the block has been time reversed the search algorithm can be reused. As only the start state has been encoded so far, the last samples of the codebook memory are padded with zeros.
第一个编码的目标子块为1号,对应的码本存储器如下图所示,当目标向量在时间上先于开始状态时,码本存储器与目标向量时间反转;因此,在对块进行时间反转之后,可以重用搜索算法。由于到目前为止只对开始状态进行了编码,所以码本内存的最后一个样本用零填充。
+------------------------- |zeros|\\\\\\\\|\\\\| 1 | +-------------------------
+------------------------- |zeros|\\\\\\\\|\\\\| 1 | +-------------------------
Figure 3.6. The codebook memory, length lMem=85 samples, and the target vector 1, length 22 samples.
图3.6。码本存储器的长度lMem=85个样本,目标向量1的长度为22个样本。
The next step is to encode sub-block 2 by using the memory that now has increased since sub-block 1 has been encoded. The following figure shows the codebook memory for encoding of sub-block 2.
下一步是使用自子块1编码以来现在增加的内存对子块2进行编码。下图显示用于子块2编码的码本存储器。
+----------------------------------- | zeros | 1 |///|////////| 2 | +-----------------------------------
+----------------------------------- | zeros | 1 |///|////////| 2 | +-----------------------------------
Figure 3.7. The codebook memory, length lMem=147 samples, and the target vector 2, length 40 samples.
图3.7。码本存储器的长度lMem=147个样本,目标向量2的长度为40个样本。
The next step is to encode sub-block 3 by using the memory which has been increased yet again since sub-blocks 1 and 2 have been encoded, but the sub-block still has to be padded with a few zeros. The following figure shows the codebook memory for encoding of sub-block 3.
下一步是使用自子块1和2编码以来再次增加的存储器对子块3进行编码,但是子块仍然必须用几个零填充。下图显示用于子块3编码的码本存储器。
+------------------------------------------ |zeros| 1 |///|////////| 2 | 3 | +------------------------------------------
+------------------------------------------ |zeros| 1 |///|////////| 2 | 3 | +------------------------------------------
Figure 3.8. The codebook memory, length lMem=147 samples, and the target vector 3, length 40 samples.
图3.8。码本存储器的长度lMem=147个样本,目标向量3的长度为40个样本。
The next step is to encode sub-block 4 by using the memory which now has increased yet again since sub-blocks 1, 2, and 3 have been encoded. This time, the memory does not have to be padded with zeros. The following figure shows the codebook memory for encoding of sub-block 4.
下一步是使用自子块1、2和3被编码以来现在再次增加的存储器来编码子块4。这一次,内存不必用零填充。下图显示用于子块4编码的码本存储器。
+------------------------------------------ |1|///|////////| 2 | 3 | 4 | +------------------------------------------
+------------------------------------------ |1|///|////////| 2 | 3 | 4 | +------------------------------------------
Figure 3.9. The codebook memory, length lMem=147 samples, and the target vector 4, length 40 samples.
图3.9。码本存储器,长度lMem=147个样本,目标向量4,长度40个样本。
The final target sub-block to be encoded is number 5, and the following figure shows the corresponding codebook memory. As the target vector comes before the start state in time, the codebook memory and target vector are time reversed.
要编码的最终目标子块是数字5,下图显示了相应的码本内存。当目标向量在时间上先于开始状态时,码本存储器和目标向量被时间反转。
+------------------------------------------- | 3 | 2 |\\\\\\\\|\\\\| 1 | 5 | +-------------------------------------------
+------------------------------------------- | 3 | 2 |\\\\\\\\|\\\\| 1 | 5 | +-------------------------------------------
Figure 3.10. The codebook memory, length lMem=147 samples, and the target vector 5, length 40 samples.
图3.10。码本存储器,长度lMem=147个样本,目标向量5,长度40个样本。
For the case of 20 ms frames, the encoding procedure looks almost exactly the same. The only difference is that the size of the start state is 57 samples and that there are only three sub-blocks to be encoded. The encoding order is the same as above, starting with the 23-sample target and then encoding the two remaining 40-sample sub-blocks, first going forward in time and then going backward in time relative to the start state.
对于20ms帧的情况,编码过程看起来几乎完全相同。唯一的区别是开始状态的大小是57个样本,并且只有三个子块要编码。编码顺序与上面相同,从23个样本目标开始,然后编码剩余的两个40个样本子块,首先在时间上向前,然后在时间上相对于开始状态向后。
To provide a perceptual weighting of the coding error, a concatenation of the codebook memory and the target to be coded is all-pole filtered with the perceptual weighting filter specified in section 3.4. The filter state of the weighting filter is set to zero.
为了提供编码错误的感知加权,使用第3.4节中规定的感知加权滤波器对码本存储器和待编码目标的串联进行全极点滤波。加权过滤器的过滤器状态设置为零。
in(0..(lMem-1)) = unweighted codebook memory in(lMem..(lMem+lTarget-1)) = unweighted target signal
in(0..(lMem-1)) = unweighted codebook memory in(lMem..(lMem+lTarget-1)) = unweighted target signal
in -> Wk(z) -> filtered, where Wk(z) is taken from the sub-block of the target
in -> Wk(z) -> filtered, where Wk(z) is taken from the sub-block of the target
weighted codebook memory = filtered(0..(lMem-1)) weighted target signal = filtered(lMem..(lMem+lTarget-1))
weighted codebook memory = filtered(0..(lMem-1)) weighted target signal = filtered(lMem..(lMem+lTarget-1))
The codebook search is done with the weighted codebook memory and the weighted target, whereas the decoding and the codebook memory update uses the unweighted codebook memory.
码本搜索使用加权码本内存和加权目标完成,而解码和码本内存更新使用未加权码本内存。
The codebook for the search is created from the perceptually weighted codebook memory. It consists of two sections, where the first is referred to as the base codebook and the second as the expanded codebook, as it is created by linear combinations of the first. Each of these two sections also has a subsection referred to as the augmented codebook. The augmented codebook is only created and used for the coding of the 40-sample sub-blocks and not for the 23/22- sample sub-block case. The codebook size used for the different sub-blocks and different stages are summarized in the table below.
用于搜索的码本是从感知加权码本存储器创建的。它由两部分组成,第一部分称为基本码本,第二部分称为扩展码本,因为它是由第一部分的线性组合创建的。这两个部分中的每一部分都有一个子部分称为增强码本。增广码本仅用于40个样本子块的编码,而不用于23/22样本子块的情况。下表总结了用于不同子块和不同阶段的码本大小。
Stage 1 2 & 3 -------------------------------------------- 22 128 (64+0)*2 128 (64+0)*2 Sub- 1:st 40 256 (108+20)*2 128 (44+20)*2 Blocks 2:nd 40 256 (108+20)*2 256 (108+20)*2 3:rd 40 256 (108+20)*2 256 (108+20)*2 4:th 40 256 (108+20)*2 256 (108+20)*2
Stage 1 2 & 3 -------------------------------------------- 22 128 (64+0)*2 128 (64+0)*2 Sub- 1:st 40 256 (108+20)*2 128 (44+20)*2 Blocks 2:nd 40 256 (108+20)*2 256 (108+20)*2 3:rd 40 256 (108+20)*2 256 (108+20)*2 4:th 40 256 (108+20)*2 256 (108+20)*2
Table 3.1. Codebook sizes for the 30 ms mode.
表3.1。30毫秒模式下的码本大小。
Table 3.1 shows the codebook size for the different sub-blocks and stages for 30 ms frames. Inside the parentheses it shows how the number of codebook vectors is distributed, within the two sections, between the base/expanded codebook and the augmented base/expanded codebook. It should be interpreted in the following way: (base/expanded cb + augmented base/expanded cb). The total number of codebook vectors for a specific sub-block and stage is given by the following formula:
表3.1显示了30ms帧的不同子块和阶段的码本大小。在括号内,它显示了在基本/扩展码本和扩展基本/扩展码本之间的两个部分中,码本向量的数量是如何分布的。应按以下方式解释:(基本/扩展cb+扩展基本/扩展cb)。特定子块和级的码本向量总数由以下公式给出:
Tot. cb vectors = base cb + aug. base cb + exp. cb + aug. exp. cb
Tot. cb vectors = base cb + aug. base cb + exp. cb + aug. exp. cb
The corresponding values to Figure 3.1 for 20 ms frames are only slightly modified. The short sub-block is 23 instead of 22 samples, and the 3:rd and 4:th sub-frame are not present.
图3.1中20 ms帧的对应值仅作了轻微修改。短子块是23而不是22个样本,并且第3:rd和第4:th子帧不存在。
The base codebook is given by the perceptually weighted codebook memory that is mentioned in section 3.5.3. The different codebook vectors are given by sliding a window of length 23/22 or 40, given by variable lTarget, over the lMem-long perceptually weighted codebook memory. The indices are ordered so that the codebook vector containing sample (lMem-lTarget-n) to (lMem-n-1) of the codebook
基本码本由第3.5.3节中提到的感知加权码本存储器给出。通过在lMem长的感知加权码书存储器上滑动由变量lTarget给出的长度为23/22或40的窗口来给出不同的码书向量。对索引进行排序,以便包含码本样本(lMem-lTarget-n)到(lMem-n-1)的码本向量
memory vector has index n, where n=0..lMem-lTarget. Thus the total number of base codebook vectors is lMem-lTarget+1, and the indices are ordered from sample delay lTarget (23/22 or 40) to lMem+1 (86 or 148).
内存向量具有索引n,其中n=0..lMem lTarget。因此,基本码本向量的总数是lMem lTarget+1,并且索引从采样延迟lTarget(23/22或40)到lMem+1(86或148)排序。
The base codebook is expanded by a factor of 2, creating an additional section in the codebook. This new section is obtained by filtering the base codebook, base_cb, with a FIR filter with filter length CB_FILTERLEN=8. The construction of the expanded codebook compensates for the delay of four samples introduced by the FIR filter.
基本码本扩展了2倍,在码本中创建了一个额外的部分。这个新的部分是通过使用滤波器长度cb_FILTERLEN=8的FIR滤波器对基本码本base_cb进行滤波而获得的。扩展码本的构造补偿了FIR滤波器引入的四个样本的延迟。
cbfiltersTbl[CB_FILTERLEN]={-0.033691, 0.083740, -0.144043, 0.713379, 0.806152, -0.184326, 0.108887, -0.034180};
cbfiltersTbl[CB_FILTERLEN]={-0.033691, 0.083740, -0.144043, 0.713379, 0.806152, -0.184326, 0.108887, -0.034180};
___ \ exp_cb(k)= + > cbfiltersTbl(i)*x(k-i+4) /__ i=0...(LPC_FILTERORDER-1)
___ \ exp_cb(k)= + > cbfiltersTbl(i)*x(k-i+4) /__ i=0...(LPC_FILTERORDER-1)
where x(j) = base_cb(j) for j=0..lMem-1 and 0 otherwise
where x(j) = base_cb(j) for j=0..lMem-1 and 0 otherwise
The individual codebook vectors of the new filtered codebook, exp_cb, and their indices are obtained in the same fashion as described above for the base codebook.
新过滤码本的各个码本向量exp_cb及其索引以与上述基本码本相同的方式获得。
For cases where encoding entire sub-blocks, i.e., cbveclen=40, the base and expanded codebooks are augmented to increase codebook richness. The codebooks are augmented by vectors produced by interpolation of segments. The base and expanded codebook, constructed above, consists of vectors corresponding to sample delays in the range from cbveclen to lMem. The codebook augmentation attempts to augment these codebooks with vectors corresponding to sample delays from 20 to 39. However, not all of these samples are present in the base codebook and expanded codebook, respectively. Therefore, the augmentation vectors are constructed as linear combinations between samples corresponding to sample delays in the range 20 to 39. The general idea of this procedure is presented in the following figures and text. The procedure is performed for both the base codebook and the expanded codebook.
对于编码整个子块的情况,即cbveclen=40,基本码本和扩展码本被扩充以增加码本的丰富性。码本由段内插产生的向量扩充。上面构造的基本和扩展码本由对应于从cbveclen到lMem范围内的采样延迟的向量组成。码本扩充尝试使用对应于从20到39的采样延迟的向量来扩充这些码本。然而,并非所有这些示例都分别出现在基本码本和扩展码本中。因此,增强向量被构造为与范围20到39中的样本延迟相对应的样本之间的线性组合。下面的图和文本介绍了该程序的总体思路。对基本码本和扩展码本执行该过程。
- - ------------------------| codebook memory | - - ------------------------| |-5-|---15---|-5-| pi pp po
- - ------------------------| codebook memory | - - ------------------------| |-5-|---15---|-5-| pi pp po
| | Codebook vector |---15---|-5-|-----20-----| <- corresponding to i ii iii sample delay 20
| | Codebook vector |---15---|-5-|-----20-----| <- corresponding to i ii iii sample delay 20
Figure 3.11. Generation of the first augmented codebook.
图3.11。生成第一个增强码本。
Figure 3.11 shows the codebook memory with pointers pi, pp, and po, where pi points to sample 25, pp to sample 20, and po to sample 5. Below the codebook memory, the augmented codebook vector corresponding to sample delay 20 is drawn. Segment i consists of fifteen samples from pointer pp and forward in time. Segment ii consists of five interpolated samples from pi and forward and from po and forward. The samples are linearly interpolated with weights [0.0, 0.2, 0.4, 0.6, 0.8] for pi and weights [1.0, 0.8, 0.6, 0.4, 0.2] for po. Segment iii consists of twenty samples from pp and forward. The augmented codebook vector corresponding to sample delay 21 is produced by moving pointers pp and pi one sample backward in time. This gives us the following figure.
图3.11显示了带有指针pi、pp和po的码本内存,其中pi指向样本25,pp指向样本20,po指向样本5。在码本存储器下方,绘制与采样延迟20相对应的增强码本向量。第i段由15个来自指针pp和时间向前的样本组成。第二段包括来自pi和forward以及来自po和forward的五个插值样本。对于pi,使用权重[0.0,0.2,0.4,0.6,0.8]对样本进行线性插值,对于po,使用权重[1.0,0.8,0.6,0.4,0.2]对样本进行线性插值。第三部分包括来自pp和forward的20个样品。通过将指针pp和pi在时间上向后移动一个样本来产生与样本延迟21相对应的增强码本向量。这为我们提供了下图。
- - ------------------------| codebook memory | - - ------------------------| |-5-|---16---|-5-| pi pp po
- - ------------------------| codebook memory | - - ------------------------| |-5-|---16---|-5-| pi pp po
| | Codebook vector |---16---|-5-|-----19-----| <- corresponding to i ii iii sample delay 21
| | Codebook vector |---16---|-5-|-----19-----| <- corresponding to i ii iii sample delay 21
Figure 3.12. Generation of the second augmented codebook.
图3.12。生成第二个增强码本。
Figure 3.12 shows the codebook memory with pointers pi, pp and po where pi points to sample 26, pp to sample 21, and po to sample 5. Below the codebook memory, the augmented codebook vector corresponding to sample delay 21 is drawn. Segment i now consists of sixteen samples from pp and forward. Segment ii consists of five interpolated samples from pi and forward and from po and forward, and the interpolation weights are the same throughout the procedure. Segment iii consists of nineteen samples from pp and forward. The same procedure of moving the two pointers is continued until the last augmented vector corresponding to sample delay 39 has been created. This gives a total of twenty new codebook vectors to each of the two
图3.12显示了带有指针pi、pp和po的码本内存,其中pi指向样本26,pp指向样本21,po指向样本5。在码本存储器下方,绘制与采样延迟21相对应的增强码本向量。第一部分现在由来自pp和forward的16个样本组成。第二段由来自pi和forward以及po和forward的五个插值样本组成,在整个过程中,插值权重相同。第三部分包括来自pp和forward的19个样品。继续移动两个指针的相同过程,直到创建了与采样延迟39相对应的最后一个增强向量。这将为这两个向量中的每一个提供总共二十个新的码本向量
sections. Thus the total number of codebook vectors for each of the two sections, when including the augmented codebook, becomes lMem-SUBL+1+SUBL/2. This is provided that augmentation is evoked, i.e., that lTarget=SUBL.
部分。因此,当包括增强码本时,两个部分中的每一部分的码本向量的总数变为lMem SUBL+1+SUBL/2。前提是诱发增强,即lTarget=SUBL。
The codebook search uses the codebooks described in the sections above to find the best match of the perceptually weighted target, see section 3.6.2. The search method is a multi-stage gain-shape matching performed as follows. At each stage the best shape vector is identified, then the gain is calculated and quantized, and finally the target is updated in preparation for the next codebook search stage. The number of stages is CB_NSTAGES=3.
码本搜索使用上述章节中描述的码本来查找感知加权目标的最佳匹配,见第3.6.2节。搜索方法是如下执行的多级增益形状匹配。在每个阶段,识别最佳形状向量,然后计算增益并量化,最后更新目标,为下一个码本搜索阶段做准备。阶段数为CB_NSTAGES=3。
If the target is the 23/22-sample vector the codebooks are indexed so that the base codebook is followed by the expanded codebook. If the target is 40 samples the order is as follows: base codebook, augmented base codebook, expanded codebook, and augmented expanded codebook. The size of each codebook section and its corresponding augmented section is given by Table 3.1 in section 3.6.3.
如果目标是23/22样本向量,则对码本进行索引,以便基本码本后面跟着扩展码本。如果目标是40个样本,则顺序如下:基本码本、扩充基本码本、扩充码本和扩充扩充码本。第3.6.3节中的表3.1给出了每个码本部分及其相应的增强部分的大小。
For example, when the second 40-sample sub-block is coded, indices 0 - 107 correspond to the base codebook, 108 - 127 correspond to the augmented base codebook, 128 - 235 correspond to the expanded codebook, and indices 236 - 255 correspond to the augmented expanded codebook. The indices are divided in the same fashion for all stages in the example. Only in the case of coding the first 40-sample sub-block is there a difference between stages (see Table 3.1).
例如,当对第二个40样本子块进行编码时,索引0-107对应于基本码本,108-127对应于增强基本码本,128-235对应于扩展码本,索引236-255对应于增强扩展码本。对于示例中的所有阶段,索引以相同的方式划分。只有在编码前40个样本子块的情况下,各阶段之间才存在差异(见表3.1)。
The codebooks are searched to find the best match to the target at each stage. When the best match is found, the target is updated and the next-stage search is started. The three chosen codebook vectors and their corresponding gains constitute the encoded sub-block. The best match is decided by the following three criteria:
在每个阶段搜索码本以找到与目标的最佳匹配。当找到最佳匹配时,将更新目标并开始下一阶段搜索。三个选择的码本向量及其相应的增益构成编码子块。最佳匹配由以下三个标准决定:
1. Compute the measure
1. 计算度量值
(target*cbvec)^2 / ||cbvec||^2
(target*cbvec)^2 / ||cbvec||^2
for all codebook vectors, cbvec, and choose the codebook vector maximizing the measure. The expression (target*cbvec) is the dot product between the target vector to be coded and the codebook vector for which we compute the measure. The norm, ||x||, is defined as the square root of (x*x).
对于所有码本向量,选择cbvec,然后选择最大化度量的码本向量。表达式(target*cbvec)是要编码的目标向量和我们计算度量的码本向量之间的点积。范数| | x | |被定义为(x*x)的平方根。
2. The absolute value of the gain, corresponding to the chosen codebook vector, cbvec, must be smaller than a fixed limit, CB_MAXGAIN=1.3:
2. 与所选码本矢量cbvec相对应的增益绝对值必须小于固定极限CB_MAXGAIN=1.3:
|gain| < CB_MAXGAIN
|增益|<CB_最大增益
where the gain is computed in the following way:
其中,增益按以下方式计算:
gain = (target*cbvec) / ||cbvec||^2
gain = (target*cbvec) / ||cbvec||^2
3. For the first stage, the dot product of the chosen codebook vector and target must be positive:
3. 对于第一阶段,所选码本向量和目标的点积必须为正:
target*cbvec > 0
目标*cbvec>0
In practice the above criteria are used in a sequential search through all codebook vectors. The best match is found by registering a new max measure and index whenever the previously registered max measure is surpassed and all other criteria are fulfilled. If none of the codebook vectors fulfill (2) and (3), the first codebook vector is selected.
在实践中,在通过所有码本向量的顺序搜索中使用上述标准。当超过先前注册的最大度量值且满足所有其他条件时,通过注册新的最大度量值和索引来找到最佳匹配。如果没有一个码本向量满足(2)和(3),则选择第一个码本向量。
The gain follows as a result of the computation
计算结果如下所示
gain = (target*cbvec) / ||cbvec||^2
gain = (target*cbvec) / ||cbvec||^2
for the optimal codebook vector found by the procedure in section 3.6.4.1.
对于通过第3.6.4.1节中的程序找到的最佳码本向量。
The three stages quantize the gain, using 5, 4, and 3 bits, respectively. In the first stage, the gain is limited to positive values. This gain is quantized by finding the nearest value in the quantization table gain_sq5Tbl.
三级分别使用5、4和3位对增益进行量化。在第一阶段,增益被限制为正值。通过在量化表增益_sq5Tbl中找到最近的值来量化该增益。
gain_sq5Tbl[32]={0.037476, 0.075012, 0.112488, 0.150024, 0.187500, 0.224976, 0.262512, 0.299988, 0.337524, 0.375000, 0.412476, 0.450012, 0.487488, 0.525024, 0.562500, 0.599976, 0.637512, 0.674988, 0.712524, 0.750000, 0.787476, 0.825012, 0.862488, 0.900024, 0.937500, 0.974976, 1.012512, 1.049988, 1.087524, 1.125000, 1.162476, 1.200012}
[32]{0.037476、0.07747、0.112488、0.150024、0.150024、0.187500、0.187500、0.224976、0.262512、0.262512、0.29988、0.29988、0.33757、0.037476、0.03747.037476、0.03747.037476、0.0.037476、0.0.037476、0.0.0.575万0.877万0.187500、0.187500、0.187500、0.187500、0.187500、0.187500、0.187500、0.187500、0.2240.2240.2240.2246、0.2240.2246、0.2246、0.2240.2246 0.2240.2246、0.2246、0.2246.2246、0.2246、0.2246、0.2242000.12}
The gains of the subsequent two stages can be either positive or negative. The gains are quantized by using a quantization table times a scale factor. The second stage uses the table gain_sq4Tbl, and the third stage uses gain_sq3Tbl. The scale factor equates 0.1
随后两个阶段的收益可以是正的,也可以是负的。通过使用量化表乘以比例因子对增益进行量化。第二阶段使用表格增益sq4Tbl,第三阶段使用增益sq3Tbl。比例因子等于0.1
or the absolute value of the quantized gain representation value obtained in the previous stage, whichever is larger. Again, the resulting gain index is the index to the nearest value of the quantization table times the scale factor.
或在前一阶段中获得的量化增益表示值的绝对值,以较大者为准。同样,所得增益指数是量化表的最近值乘以比例因子的指数。
gainQ = scaleFact * gain_sqXTbl[index]
gainQ=比例效应*增益×指数
gain_sq4Tbl[16]={-1.049988, -0.900024, -0.750000, -0.599976, -0.450012, -0.299988, -0.150024, 0.000000, 0.150024, 0.299988, 0.450012, 0.599976, 0.750000, 0.900024, 1.049988, 1.200012}
gain_sq4Tbl[16]={-1.049988, -0.900024, -0.750000, -0.599976, -0.450012, -0.299988, -0.150024, 0.000000, 0.150024, 0.299988, 0.450012, 0.599976, 0.750000, 0.900024, 1.049988, 1.200012}
gain_sq3Tbl[8]={-1.000000, -0.659973, -0.330017,0.000000, 0.250000, 0.500000, 0.750000, 1.00000}
gain_sq3Tbl[8]={-1.000000, -0.659973, -0.330017,0.000000, 0.250000, 0.500000, 0.750000, 1.00000}
Before performing the search for the next stage, the perceptually weighted target vector is updated by subtracting from it the selected codebook vector (from the perceptually weighted codebook) times the corresponding quantized gain.
在执行下一阶段的搜索之前,通过从中减去所选码本向量(来自感知加权码本)乘以相应的量化增益来更新感知加权目标向量。
target[i] = target[i] - gainQ * selected_vec[i];
target[i] = target[i] - gainQ * selected_vec[i];
A reference implementation of the codebook encoding is found in Appendix A.34.
附录A.34中提供了码本编码的参考实现。
The start state is quantized in a relatively model independent manner using 3 bits per sample. In contrast, the remaining parts of the block are encoded by using an adaptive codebook. This codebook will produce high matching accuracy whenever there is a high correlation between the target and the best codebook vector. For unvoiced speech segments and background noises, this is not necessarily so, which, due to the nature of the squared error criterion, results in a coded signal with less power than the target signal. As the coded start state has good power matching to the target, the result is a power fluctuation within the encoded frame. Perceptually, the main problem with this is that the time envelope of the signal energy becomes unsteady. To overcome this problem, the gains for the codebooks are re-scaled after the codebook encoding by searching for a new gain factor for the first stage codebook that provides better power matching.
开始状态以相对独立于模型的方式量化,每个样本使用3位。相反,块的其余部分通过使用自适应码本进行编码。每当目标和最佳码本向量之间存在高度相关性时,该码本将产生高匹配精度。对于清音语音段和背景噪声,这不一定如此,因为平方误差准则的性质,导致编码信号的功率小于目标信号。由于编码的起始状态与目标具有良好的功率匹配,因此结果是编码帧内的功率波动。从感知上看,这方面的主要问题是信号能量的时间包络变得不稳定。为了克服这个问题,在码本编码之后,通过为第一级码本搜索新的增益因子来重新缩放码本的增益,以提供更好的功率匹配。
First, the energy for the target signal, tene, is computed along with the energy for the coded signal, cene, given by the addition of the three gain scaled codebook vectors. Because the gains of the second
首先,目标信号tene的能量与编码信号cene的能量一起计算,cene由三个增益缩放码本向量相加而得到。因为第二次的收获
and third stage scale with the gain of the first stage, when the first stage gain is changed from gain[0] to gain_sq5Tbl[i] the energy of the coded signal changes from cene to
以及第三级与第一级的增益成比例,当第一级增益从增益[0]改变为增益_sq5Tbl[i]时,编码信号的能量从cene改变为
cene*(gain_sq5Tbl[i]*gain_sq5Tbl[i])/(gain[0]*gain[0])
cene*(gain_sq5Tbl[i]*gain_sq5Tbl[i])/(gain[0]*gain[0])
where gain[0] is the gain for the first stage found in the original codebook search. A refined search is performed by testing the gain indices i=0 to 31, and as long as the new codebook energy as given above is less than tene, the gain index for stage 1 is increased. A restriction is applied so that the new gain value for stage 1 cannot be more than two times higher than the original value found in the codebook search. Note that by using this method we do not change the shape of the encoded vector, only the gain or amplitude.
其中,增益[0]是在原始码本搜索中找到的第一阶段的增益。通过测试增益指数i=0到31来执行精细搜索,并且只要如上所述的新码本能量小于tene,则阶段1的增益指数增加。应用限制,以便阶段1的新增益值不能高于码本搜索中找到的原始值的两倍以上。请注意,通过使用此方法,我们不会改变编码向量的形状,只会改变增益或振幅。
The total number of bits used to describe one frame of 20 ms speech is 304, which fits in 38 bytes and results in a bit rate of 15.20 kbit/s. For the case of a frame length of 30 ms speech, the total number of bits used is 400, which fits in 50 bytes and results in a bit rate of 13.33 kbit/s. In the bitstream definition, the bits are distributed into three classes according to their bit error or loss sensitivity. The most sensitive bits (class 1) are placed first in the bitstream for each frame. The less sensitive bits (class 2) are placed after the class 1 bits. The least sensitive bits (class 3) are placed at the end of the bitstream for each frame.
用于描述20毫秒语音的一帧的总位数为304,适合38字节,比特率为15.20 kbit/s。对于30 ms语音的帧长,使用的总比特数为400,适合于50字节,比特率为13.33 kbit/s。在比特流定义中,根据比特的误码或丢失敏感性将比特分为三类。对于每个帧,最敏感的位(类1)被放在比特流的第一位。敏感度较低的位(类别2)放在类别1位之后。对于每个帧,最不敏感的位(类别3)被放置在比特流的末尾。
In the 20/30 ms frame length cases for each class, the following hold true: The class 1 bits occupy a total of 6/8 bytes (48/64 bits), the class 2 bits occupy 8/12 bytes (64/96 bits), and the class 3 bits occupy 24/30 bytes (191/239 bits). This distribution of the bits enables the use of uneven level protection (ULP) as is exploited in the payload format definition for iLBC [1]. The detailed bit allocation is shown in the table below. When a quantization index is distributed between more classes, the more significant bits belong to the lowest class.
在每个类的20/30毫秒帧长度情况下,以下情况成立:类1位总共占用6/8字节(48/64位),类2位占用8/12字节(64/96位),类3位占用24/30字节(191/239位)。比特的这种分布使得能够使用iLBC的有效负载格式定义中利用的不均匀级别保护(ULP)[1]。详细的位分配如下表所示。当量化索引分布在更多类别之间时,更重要的比特属于最低类别。
Bitstream structure:
比特流结构:
------------------------------------------------------------------+ Parameter | Bits Class <1,2,3> | | 20 ms frame | 30 ms frame | ----------------------------------+---------------+---------------+ Split 1 | 6 <6,0,0> | 6 <6,0,0> | LSF 1 Split 2 | 7 <7,0,0> | 7 <7,0,0> | LSF Split 3 | 7 <7,0,0> | 7 <7,0,0> | ------------------+---------------+---------------+ Split 1 | NA (Not Appl.)| 6 <6,0,0> | LSF 2 Split 2 | NA | 7 <7,0,0> | Split 3 | NA | 7 <7,0,0> | ------------------+---------------+---------------+ Sum | 20 <20,0,0> | 40 <40,0,0> | ----------------------------------+---------------+---------------+ Block Class | 2 <2,0,0> | 3 <3,0,0> | ----------------------------------+---------------+---------------+ Position 22 sample segment | 1 <1,0,0> | 1 <1,0,0> | ----------------------------------+---------------+---------------+ Scale Factor State Coder | 6 <6,0,0> | 6 <6,0,0> | ----------------------------------+---------------+---------------+ Sample 0 | 3 <0,1,2> | 3 <0,1,2> | Quantized Sample 1 | 3 <0,1,2> | 3 <0,1,2> | Residual : | : : | : : | State : | : : | : : | Samples : | : : | : : | Sample 56 | 3 <0,1,2> | 3 <0,1,2> | Sample 57 | NA | 3 <0,1,2> | ------------------+---------------+---------------+ Sum | 171 <0,57,114>| 174 <0,58,116>| ----------------------------------+---------------+---------------+ Stage 1 | 7 <6,0,1> | 7 <4,2,1> | CB for 22/23 Stage 2 | 7 <0,0,7> | 7 <0,0,7> | sample block Stage 3 | 7 <0,0,7> | 7 <0,0,7> | ------------------+---------------+---------------+ Sum | 21 <6,0,15> | 21 <4,2,15> | ----------------------------------+---------------+---------------+ Stage 1 | 5 <2,0,3> | 5 <1,1,3> | Gain for 22/23 Stage 2 | 4 <1,1,2> | 4 <1,1,2> | sample block Stage 3 | 3 <0,0,3> | 3 <0,0,3> | ------------------+---------------+---------------+ Sum | 12 <3,1,8> | 12 <2,2,8> | ----------------------------------+---------------+---------------+ Stage 1 | 8 <7,0,1> | 8 <6,1,1> | sub-block 1 Stage 2 | 7 <0,0,7> | 7 <0,0,7> | Stage 3 | 7 <0,0,7> | 7 <0,0,7> | ------------------+---------------+---------------+
------------------------------------------------------------------+ Parameter | Bits Class <1,2,3> | | 20 ms frame | 30 ms frame | ----------------------------------+---------------+---------------+ Split 1 | 6 <6,0,0> | 6 <6,0,0> | LSF 1 Split 2 | 7 <7,0,0> | 7 <7,0,0> | LSF Split 3 | 7 <7,0,0> | 7 <7,0,0> | ------------------+---------------+---------------+ Split 1 | NA (Not Appl.)| 6 <6,0,0> | LSF 2 Split 2 | NA | 7 <7,0,0> | Split 3 | NA | 7 <7,0,0> | ------------------+---------------+---------------+ Sum | 20 <20,0,0> | 40 <40,0,0> | ----------------------------------+---------------+---------------+ Block Class | 2 <2,0,0> | 3 <3,0,0> | ----------------------------------+---------------+---------------+ Position 22 sample segment | 1 <1,0,0> | 1 <1,0,0> | ----------------------------------+---------------+---------------+ Scale Factor State Coder | 6 <6,0,0> | 6 <6,0,0> | ----------------------------------+---------------+---------------+ Sample 0 | 3 <0,1,2> | 3 <0,1,2> | Quantized Sample 1 | 3 <0,1,2> | 3 <0,1,2> | Residual : | : : | : : | State : | : : | : : | Samples : | : : | : : | Sample 56 | 3 <0,1,2> | 3 <0,1,2> | Sample 57 | NA | 3 <0,1,2> | ------------------+---------------+---------------+ Sum | 171 <0,57,114>| 174 <0,58,116>| ----------------------------------+---------------+---------------+ Stage 1 | 7 <6,0,1> | 7 <4,2,1> | CB for 22/23 Stage 2 | 7 <0,0,7> | 7 <0,0,7> | sample block Stage 3 | 7 <0,0,7> | 7 <0,0,7> | ------------------+---------------+---------------+ Sum | 21 <6,0,15> | 21 <4,2,15> | ----------------------------------+---------------+---------------+ Stage 1 | 5 <2,0,3> | 5 <1,1,3> | Gain for 22/23 Stage 2 | 4 <1,1,2> | 4 <1,1,2> | sample block Stage 3 | 3 <0,0,3> | 3 <0,0,3> | ------------------+---------------+---------------+ Sum | 12 <3,1,8> | 12 <2,2,8> | ----------------------------------+---------------+---------------+ Stage 1 | 8 <7,0,1> | 8 <6,1,1> | sub-block 1 Stage 2 | 7 <0,0,7> | 7 <0,0,7> | Stage 3 | 7 <0,0,7> | 7 <0,0,7> | ------------------+---------------+---------------+
Stage 1 | 8 <0,0,8> | 8 <0,7,1> | sub-block 2 Stage 2 | 8 <0,0,8> | 8 <0,0,8> | Indices Stage 3 | 8 <0,0,8> | 8 <0,0,8> | for CB ------------------+---------------+---------------+ sub-blocks Stage 1 | NA | 8 <0,7,1> | sub-block 3 Stage 2 | NA | 8 <0,0,8> | Stage 3 | NA | 8 <0,0,8> | ------------------+---------------+---------------+ Stage 1 | NA | 8 <0,7,1> | sub-block 4 Stage 2 | NA | 8 <0,0,8> | Stage 3 | NA | 8 <0,0,8> | ------------------+---------------+---------------+ Sum | 46 <7,0,39> | 94 <6,22,66> | ----------------------------------+---------------+---------------+ Stage 1 | 5 <1,2,2> | 5 <1,2,2> | sub-block 1 Stage 2 | 4 <1,1,2> | 4 <1,2,1> | Stage 3 | 3 <0,0,3> | 3 <0,0,3> | ------------------+---------------+---------------+ Stage 1 | 5 <1,1,3> | 5 <0,2,3> | sub-block 2 Stage 2 | 4 <0,2,2> | 4 <0,2,2> | Stage 3 | 3 <0,0,3> | 3 <0,0,3> | Gains for ------------------+---------------+---------------+ sub-blocks Stage 1 | NA | 5 <0,1,4> | sub-block 3 Stage 2 | NA | 4 <0,1,3> | Stage 3 | NA | 3 <0,0,3> | ------------------+---------------+---------------+ Stage 1 | NA | 5 <0,1,4> | sub-block 4 Stage 2 | NA | 4 <0,1,3> | Stage 3 | NA | 3 <0,0,3> | ------------------+---------------+---------------+ Sum | 24 <3,6,15> | 48 <2,12,34> | ----------------------------------+---------------+---------------+ Empty frame indicator | 1 <0,0,1> | 1 <0,0,1> | ------------------------------------------------------------------- SUM 304 <48,64,192> 400 <64,96,240>
Stage 1 | 8 <0,0,8> | 8 <0,7,1> | sub-block 2 Stage 2 | 8 <0,0,8> | 8 <0,0,8> | Indices Stage 3 | 8 <0,0,8> | 8 <0,0,8> | for CB ------------------+---------------+---------------+ sub-blocks Stage 1 | NA | 8 <0,7,1> | sub-block 3 Stage 2 | NA | 8 <0,0,8> | Stage 3 | NA | 8 <0,0,8> | ------------------+---------------+---------------+ Stage 1 | NA | 8 <0,7,1> | sub-block 4 Stage 2 | NA | 8 <0,0,8> | Stage 3 | NA | 8 <0,0,8> | ------------------+---------------+---------------+ Sum | 46 <7,0,39> | 94 <6,22,66> | ----------------------------------+---------------+---------------+ Stage 1 | 5 <1,2,2> | 5 <1,2,2> | sub-block 1 Stage 2 | 4 <1,1,2> | 4 <1,2,1> | Stage 3 | 3 <0,0,3> | 3 <0,0,3> | ------------------+---------------+---------------+ Stage 1 | 5 <1,1,3> | 5 <0,2,3> | sub-block 2 Stage 2 | 4 <0,2,2> | 4 <0,2,2> | Stage 3 | 3 <0,0,3> | 3 <0,0,3> | Gains for ------------------+---------------+---------------+ sub-blocks Stage 1 | NA | 5 <0,1,4> | sub-block 3 Stage 2 | NA | 4 <0,1,3> | Stage 3 | NA | 3 <0,0,3> | ------------------+---------------+---------------+ Stage 1 | NA | 5 <0,1,4> | sub-block 4 Stage 2 | NA | 4 <0,1,3> | Stage 3 | NA | 3 <0,0,3> | ------------------+---------------+---------------+ Sum | 24 <3,6,15> | 48 <2,12,34> | ----------------------------------+---------------+---------------+ Empty frame indicator | 1 <0,0,1> | 1 <0,0,1> | ------------------------------------------------------------------- SUM 304 <48,64,192> 400 <64,96,240>
Table 3.2. The bitstream definition for iLBC for both the 20 ms frame size mode and the 30 ms frame size mode.
表3.2。iLBC在20毫秒帧大小模式和30毫秒帧大小模式下的比特流定义。
When packetized into the payload, the bits MUST be sorted as follows: All the class 1 bits in the order (from top to bottom) as specified in the table, all the class 2 bits (from top to bottom), and all the class 3 bits in the same sequential order. The last bit, the empty frame indicator, SHOULD be set to zero by the encoder. If this bit is set to 1 the decoder SHOULD treat the data as a lost frame. For example, this bit can be set to 1 to indicate lost frame for file storage format, as in [1].
当打包到有效负载中时,位必须按如下顺序排序:所有1类位按照表中指定的顺序(从上到下)、所有2类位(从上到下)以及所有3类位按照相同的顺序。编码器应将最后一位(空帧指示器)设置为零。如果此位设置为1,解码器应将数据视为丢失帧。例如,该位可以设置为1,以指示文件存储格式的丢失帧,如[1]所示。
This section describes the principles of each component of the decoder algorithm.
本节介绍解码器算法每个组件的原理。
+-------------+ +--------+ +---------------+ payload -> | 1. Get para | -> | 2. LPC | -> | 3. Sc Dequant | -> +-------------+ +--------+ +---------------+
+-------------+ +--------+ +---------------+ payload -> | 1. Get para | -> | 2. LPC | -> | 3. Sc Dequant | -> +-------------+ +--------+ +---------------+
+-------------+ +------------------+ -> | 4. Mem setup| -> | 5. Construct res |-------> | +-------------+ +------------------- | ---------<-----------<-----------<------------ Sub-frame 0...2/4 (20 ms/30 ms)
+-------------+ +------------------+ -> | 4. Mem setup| -> | 5. Construct res |-------> | +-------------+ +------------------- | ---------<-----------<-----------<------------ Sub-frame 0...2/4 (20 ms/30 ms)
+----------------+ +----------+ -> | 6. Enhance res | -> | 7. Synth | ------------> +----------------+ +----------+
+----------------+ +----------+ -> | 6. Enhance res | -> | 7. Synth | ------------> +----------------+ +----------+
+-----------------+ -> | 8. Post Process | ----------------> decoded speech +-----------------+
+-----------------+ -> | 8. Post Process | ----------------> decoded speech +-----------------+
Figure 4.1. Flow chart of the iLBC decoder. If a frame was lost, steps 1 to 5 SHOULD be replaced by a PLC algorithm.
图4.1。iLBC解码器的流程图。如果帧丢失,步骤1至5应替换为PLC算法。
1. Extract the parameters from the bitstream.
1. 从比特流中提取参数。
2. Decode the LPC and interpolate (section 4.1).
2. 解码LPC并插值(第4.1节)。
3. Construct the 57/58-sample start state (section 4.2).
3. 构建57/58样本开始状态(第4.2节)。
4. Set up the memory by using data from the decoded residual. This memory is used for codebook construction. For blocks preceding the start state, both the decoded residual and the target are time reversed. Sub-frames are decoded in the same order as they were encoded.
4. 使用解码残差中的数据设置内存。该内存用于码本构造。对于开始状态之前的块,解码的残差和目标都是时间反转的。子帧的解码顺序与编码顺序相同。
5. Construct the residuals of this sub-frame (gain[0]*cbvec[0] + gain[1]*cbvec[1] + gain[2]*cbvec[2]). Repeat 4 and 5 until the residual of all sub-blocks has been constructed.
5. 构造该子帧的残差(增益[0]*cbvec[0]+增益[1]*cbvec[1]+增益[2]*cbvec[2])。重复4和5,直到所有子块的剩余部分都已构建完毕。
6. Enhance the residual with the post filter (section 4.6).
6. 使用后滤器(第4.6节)增强残余物。
7. Synthesis of the residual (section 4.7).
7. 残留物的合成(第4.7节)。
8. Post process with HP filter, if desired (section 4.8).
8. 如果需要,使用HP过滤器进行后处理(第4.8节)。
The decoding of the LP filter parameters is very straightforward. For a set of three/six indices, the corresponding LSF vector(s) are found by simple table lookup. For each of the LSF vectors, the three split vectors are concatenated to obtain qlsf1 and qlsf2, respectively (in the 20 ms mode only one LSF vector, qlsf, is constructed). The next step is the stability check described in section 3.2.5 followed by the interpolation scheme described in section 3.2.6 (3.2.7 for 20 ms frames). The only difference is that only the quantized LSFs are known at the decoder, and hence the unquantized LSFs are not processed.
LP滤波器参数的解码非常简单。对于一组三/六个索引,通过简单的表格查找找到相应的LSF向量。对于每个LSF向量,将三个分割向量串联以分别获得qlsf1和qlsf2(在20 ms模式中,仅构造一个LSF向量qlsf)。下一步是第3.2.5节中描述的稳定性检查,然后是第3.2.6节中描述的插值方案(3.2.7用于20ms帧)。唯一的区别是在解码器处只有量化的lsf是已知的,因此不处理未量化的lsf。
A reference implementation of the LPC filter reconstruction is given in Appendix A.36.
附录A.36中给出了LPC滤波器重构的参考实现。
The scalar encoded STATE_SHORT_LEN=58 (STATE_SHORT_LEN=57 in the 20 ms mode) state samples are reconstructed by 1) forming a set of samples (by table lookup) from the index stream idxVec[n], 2) multiplying the set with 1/scal=(10^qmax)/4.5, 3) time reversing the 57/58 samples, 4) filtering the time reversed block with the dispersion (all-pass) filter used in the encoder (as described in section 3.5.2); this compensates for the phase distortion of the earlier filter operation, and 5 reversing the 57/58 samples from the previous step.
标量编码状态_SHORT_LEN=58(在20ms模式下状态_SHORT_LEN=57)状态样本通过1)从索引流idxVec[n]形成一组样本(通过查表),2)将该组乘以1/scal=(10^qmax)/4.5,3)对57/58样本进行时间反转,4)用色散(全通)过滤时间反转块来重构编码器中使用的滤波器(如第3.5.2节所述);这补偿了先前滤波操作的相位失真,5从上一步反转57/58个样本。
in(0..(STATE_SHORT_LEN-1)) = time reversed samples from table look-up, idxVecDec((STATE_SHORT_LEN-1)..0)
in(0..(STATE_SHORT_LEN-1))=来自表查找的时间反转样本,idxVecDec((STATE_SHORT_LEN-1)…0)
in(STATE_SHORT_LEN..(2*STATE_SHORT_LEN-1)) = 0
in(STATE_SHORT_LEN..(2*STATE_SHORT_LEN-1)) = 0
Pk(z) = A~rk(z)/A~k(z), where ___ \ A~rk(z)= z^(-LPC_FILTERORDER) + > a~ki*z^(i-(LPC_FILTERORDER-1)) /__ i=0...(LPC_FILTERORDER-1)
Pk(z) = A~rk(z)/A~k(z), where ___ \ A~rk(z)= z^(-LPC_FILTERORDER) + > a~ki*z^(i-(LPC_FILTERORDER-1)) /__ i=0...(LPC_FILTERORDER-1)
and A~k(z) is taken from the block where the start state begins
A~k(z)取自起始状态开始的块
in -> Pk(z) -> filtered
in -> Pk(z) -> filtered
out(k) = filtered(STATE_SHORT_LEN-1-k) + filtered(2*STATE_SHORT_LEN-1-k), k=0..(STATE_SHORT_LEN-1)
out(k) = filtered(STATE_SHORT_LEN-1-k) + filtered(2*STATE_SHORT_LEN-1-k), k=0..(STATE_SHORT_LEN-1)
The remaining 23/22 samples in the state are reconstructed by the same adaptive codebook technique described in section 4.3. The location bit determines whether these are the first or the last 23/22 samples of the 80-sample state vector. If the remaining 23/22 samples are the first samples, then the scalar encoded STATE_SHORT_LEN state samples are time-reversed before initialization of the adaptive codebook memory vector.
该状态下剩余的23/22个样本通过第4.3节中描述的相同自适应码本技术重建。位置位确定这些是80个样本状态向量的第一个还是最后的23/22个样本。如果剩余的23/22个样本是第一个样本,则在初始化自适应码本存储器向量之前,标量编码状态\u短\u LEN状态样本被时间反转。
A reference implementation of the start state reconstruction is given in Appendix A.44.
附录A.44中给出了启动状态重构的参考实施。
The decoding of the LPC excitation vector proceeds in the same order in which the residual was encoded at the encoder. That is, after the decoding of the entire 80-sample state vector, the forward sub-blocks (corresponding to samples occurring after the state vector samples) are decoded, and then the backward sub-blocks (corresponding to samples occurring before the state vector) are decoded, resulting in a fully decoded block of excitation signal samples.
LPC激励向量的解码按照编码器处残差编码的相同顺序进行。也就是说,在对整个80个样本状态向量进行解码之后,对前向子块(对应于在状态向量样本之后发生的样本)进行解码,然后对后向子块(对应于在状态向量之前发生的样本)进行解码,从而得到激励信号样本的完全解码块。
In particular, each sub-block is decoded by using the multistage adaptive codebook decoding module described in section 4.4. This module relies upon an adaptive codebook memory constructed before each run of the adaptive codebook decoding. The construction of the adaptive codebook memory in the decoder is identical to the method outlined in section 3.6.3, except that it is done on the codebook memory without perceptual weighting.
具体而言,使用第4.4节中描述的多级自适应码本解码模块对每个子块进行解码。该模块依赖于在每次自适应码本解码运行之前构造的自适应码本存储器。解码器中自适应码本存储器的构造与第3.6.3节中概述的方法相同,不同之处在于它是在码本存储器上进行的,没有感知加权。
For the initial forward sub-block, the last STATE_LEN=80 samples of the length CB_LMEM=147 adaptive codebook memory are filled with the samples of the state vector. For subsequent forward sub-blocks, the first SUBL=40 samples of the adaptive codebook memory are discarded, the remaining samples are shifted by SUBL samples toward the beginning of the vector, and the newly decoded SUBL=40 samples are placed at the end of the adaptive codebook memory. For backward sub-blocks, the construction is similar, except that every vector of samples involved is first time reversed.
对于初始前向子块,使用状态向量的样本填充长度CB_LMEM=147自适应码本存储器的最后状态_LEN=80个样本。对于随后的前向子块,丢弃自适应码本存储器的第一个SUBL=40样本,剩余样本被SUBL样本移向向量的开头,并且新解码的SUBL=40样本被放置在自适应码本存储器的末端。对于向后的子块,构造是类似的,只是涉及的每个样本向量都是第一次反转的。
A reference implementation of the excitation decoding loop is found in Appendix A.5.
附录A.5中给出了励磁解码回路的参考实现。
The Multistage Adaptive Codebook Decoding module is used at both the sender (encoder) and the receiver (decoder) ends to produce a synthetic signal in the residual domain that is eventually used to produce synthetic speech. The module takes the index values used to construct vectors that are scaled and summed together to produce a synthetic signal that is the output of the module.
多级自适应码本解码模块在发送方(编码器)和接收方(解码器)端使用,以在剩余域中产生最终用于产生合成语音的合成信号。该模块获取用于构建向量的索引值,这些向量被缩放并相加,以生成作为模块输出的合成信号。
The unpacked index values provided at the input to the module are references to extended codebooks, which are constructed as described in section 3.6.3, except that they are based on the codebook memory without the perceptual weighting. The unpacked three indices are used to look up three codebook vectors. The unpacked three gain indices are used to decode the corresponding 3 gains. In this decoding, the successive rescaling, as described in section 3.6.4.2, is applied.
在模块输入端提供的未打包索引值是对扩展码本的引用,扩展码本按照第3.6.3节所述进行构造,但它们基于码本存储器,无感知加权。未打包的三个索引用于查找三个码本向量。未打包的三个增益索引用于解码相应的三个增益。在该解码中,应用了第3.6.4.2节所述的连续重缩放。
A reference implementation of the adaptive codebook decoding is listed in Appendix A.32.
附录A.32中列出了自适应码本解码的参考实现。
If packet loss occurs, the decoder receives a signal saying that information regarding a block is lost. For such blocks it is RECOMMENDED to use a Packet Loss Concealment (PLC) unit to create a decoded signal that masks the effect of that packet loss. In the following we will describe an example of a PLC unit that can be used with the iLBC codec. As the PLC unit is used only at the decoder, the PLC unit does not affect interoperability between implementations. Other PLC implementations MAY therefore be used.
如果发生分组丢失,则解码器接收到表示关于块的信息丢失的信号。对于这样的块,建议使用分组丢失隐藏(PLC)单元来创建屏蔽该分组丢失影响的解码信号。在下文中,我们将描述一个可与iLBC编解码器一起使用的PLC单元示例。由于PLC单元仅在解码器处使用,因此PLC单元不会影响实现之间的互操作性。因此,可以使用其他PLC实现。
The PLC described operates on the LP filters and the excitation signals and is based on the following principles:
所述PLC在LP滤波器和励磁信号上运行,并基于以下原则:
If the block is received correctly, the PLC only records state information of the current block that can be used in case the next block is lost. The LP filter coefficients for each sub-block and the entire decoded excitation signal are all saved in the decoder state structure. All of this information will be needed if the following block is lost.
如果正确接收块,PLC仅记录当前块的状态信息,以便在下一个块丢失时使用。每个子块的LP滤波器系数和整个解码激励信号都保存在解码器状态结构中。如果以下块丢失,则需要所有这些信息。
If the block is not received, the block substitution is based on a pitch-synchronous repetition of the excitation signal, which is filtered by the last LP filter of the previous block. The previous block's information is stored in the decoder state structure.
如果未接收到块,则块替换基于激励信号的基音同步重复,该激励信号由前一块的最后一个LP滤波器滤波。前一块的信息存储在解码器状态结构中。
A correlation analysis is performed on the previous block's excitation signal in order to detect the amount of pitch periodicity and a pitch value. The correlation measure is also used to decide on the voicing level (the degree to which the previous block's excitation was a voiced or roughly periodic signal). The excitation in the previous block is used to create an excitation for the block to be substituted, such that the pitch of the previous block is maintained. Therefore, the new excitation is constructed in a pitch-synchronous manner. In order to avoid a buzzy-sounding substituted block, a random excitation is mixed with the new pitch periodic excitation, and the relative use of the two components is computed from the correlation measure (voicing level).
在前一块的激励信号上执行相关分析,以检测基音周期量和基音值。相关性度量还用于确定发声水平(前一块的激励是浊音或大致周期信号的程度)。前一块中的激励用于为要替换的块创建激励,从而保持前一块的节距。因此,新励磁以基音同步方式构造。为了避免嗡嗡声替代块,将随机激励与新的基音周期激励混合,并根据相关度量(发声水平)计算两个分量的相对使用。
For the block to be substituted, the newly constructed excitation signal is then passed through the LP filter to produce the speech that will be substituted for the lost block.
对于要被替换的块,新构造的激励信号随后通过LP滤波器来产生将被替换为丢失块的语音。
For several consecutive lost blocks, the packet loss concealment continues in a similar manner. The correlation measure of the last block received is still used along with the same pitch value. The LP filters of the last block received are also used again. The energy of the substituted excitation for consecutive lost blocks is decreased, leading to a dampened excitation, and therefore to dampened speech.
对于几个连续的丢失块,分组丢失隐藏以类似的方式继续。接收到的最后一个块的相关性度量仍然与相同的基音值一起使用。最后接收到的块的LP滤波器也将再次使用。连续丢失块的替代激励能量降低,导致阻尼激励,从而导致阻尼语音。
For the case in which a block is received correctly when the previous block was not, the correctly received block's directly decoded speech (based solely on the received block) is not used as the actual output. The reason for this is that the directly decoded speech does not necessarily smoothly merge into the synthetic speech generated for the previous lost block. If the two signals are not smoothly merged, an audible discontinuity is accidentally produced. Therefore, a correlation analysis between the two blocks of excitation signal (the excitation of the previous concealed block and that of the current received block) is performed to find the best phase match. Then a simple overlap-add procedure is performed to merge the previous excitation smoothly into the current block's excitation.
对于在前一块未被正确接收的情况下正确接收到块的情况,正确接收到的块的直接解码语音(仅基于接收到的块)不被用作实际输出。这是因为直接解码的语音不一定会平滑地合并到为先前丢失的块生成的合成语音中。如果两个信号不能顺利合并,则会意外产生音频中断。因此,执行两个激励信号块(先前隐藏块的激励和当前接收块的激励)之间的相关性分析,以找到最佳相位匹配。然后执行一个简单的重叠添加程序,将先前的激励平滑地合并到当前块的激励中。
The exact implementation of the packet loss concealment does not influence interoperability of the codec.
包丢失隐藏的精确实现不会影响编解码器的互操作性。
A reference implementation of the packet loss concealment is suggested in Appendix A.14. Exact compliance with this suggested algorithm is not needed for a reference implementation to be fully compatible with the overall codec specification.
附录A.14中建议了分组丢失隐藏的参考实现。要使参考实现与整个编解码器规范完全兼容,不需要严格遵守此建议的算法。
The decoder contains an enhancement unit that operates on the reconstructed excitation signal. The enhancement unit increases the perceptual quality of the reconstructed signal by reducing the speech-correlated noise in the voiced speech segments. Compared to traditional postfilters, the enhancer has an advantage in that it can only modify the excitation signal slightly. This means that there is no risk of over enhancement. The enhancer works very similarly for both the 20 ms frame size mode and the 30 ms frame size mode.
解码器包含对重构的激励信号进行操作的增强单元。增强单元通过降低浊音语音段中的语音相关噪声来提高重构信号的感知质量。与传统的后滤波器相比,增强器的优点在于它只能轻微地修改激励信号。这意味着没有过度增强的风险。增强器在20毫秒帧大小模式和30毫秒帧大小模式下的工作原理非常相似。
For the mode with 20 ms frame size, the enhancer uses a memory of six 80-sample excitation blocks prior in time plus the two new 80-sample excitation blocks. For each block of 160 new unenhanced excitation samples, 160 enhanced excitation samples are produced. The enhanced excitation is 40-sample delayed compared to the unenhanced excitation, as the enhancer algorithm uses lookahead.
对于帧大小为20 ms的模式,增强器使用六个80样本激励块的内存,再加上两个新的80样本激励块。对于每一块160个新的非增强激励样本,产生160个增强激励样本。增强激励比未增强激励延迟40个样本,因为增强器算法使用前瞻。
For the mode with 30 ms frame size, the enhancer uses a memory of five 80-sample excitation blocks prior in time plus the three new 80-sample excitation blocks. For each block of 240 new unenhanced excitation samples, 240 enhanced excitation samples are produced. The enhanced excitation is 80-sample delayed compared to the unenhanced excitation, as the enhancer algorithm uses lookahead.
对于帧大小为30ms的模式,增强器在时间上使用五个80样本激励块加上三个新的80样本激励块的存储器。对于每一块240个新的非增强激励样本,产生240个增强激励样本。增强型激励比未增强型激励延迟80个样本,因为增强器算法使用前瞻。
Outline of Enhancer
增强子概述
The speech enhancement unit operates on sub-blocks of 80 samples, which means that there are two/three 80 sample sub-blocks per frame. Each of these two/three sub-blocks is enhanced separately, but in an analogous manner.
语音增强单元对80个样本的子块进行操作,这意味着每帧有两/三个80个样本子块。这两个/三个子块中的每一个子块单独地被增强,但是以类似的方式。
unenhanced residual | | +---------------+ +--------------+ +-> | 1. Pitch Est | -> | 2. Find PSSQ | --------> +---------------+ | +--------------+ +-----<-------<------<--+ +------------+ enh block 0..1/2 | -> | 3. Smooth | | +------------+ | \ | /\ | / \ Already | / 4. \----------->----------->-----------+ | \Crit/ Fulfilled | | \? / v | \/ | | \ +-----------------+ +---------+ | | Not +->| 5. Use Constr. | -> | 6. Mix | -----> Fulfilled +-----------------+ +---------+
unenhanced residual | | +---------------+ +--------------+ +-> | 1. Pitch Est | -> | 2. Find PSSQ | --------> +---------------+ | +--------------+ +-----<-------<------<--+ +------------+ enh block 0..1/2 | -> | 3. Smooth | | +------------+ | \ | /\ | / \ Already | / 4. \----------->----------->-----------+ | \Crit/ Fulfilled | | \? / v | \/ | | \ +-----------------+ +---------+ | | Not +->| 5. Use Constr. | -> | 6. Mix | -----> Fulfilled +-----------------+ +---------+
---------------> enhanced residual
---------------> enhanced residual
Figure 4.2. Flow chart of the enhancer.
图4.2。增强器的流程图。
1. Pitch estimation of each of the two/three new 80-sample blocks.
1. 两个/三个新的80个样本块中每个块的基音估计。
2. Find the pitch-period-synchronous sequence n (for block k) by a search around the estimated pitch value. Do this for n=1,2,3, -1,-2,-3.
2. 通过搜索估计的基音周期值,找到基音周期同步序列n(对于块k)。对n=1,2,3,-1,-2,-3执行此操作。
3. Calculate the smoothed residual generated by the six pitch-period-synchronous sequences from prior step.
3. 计算前一步中六个基音周期同步序列产生的平滑残差。
4. Check if the smoothed residual satisfies the criterion (section 4.6.4).
4. 检查平滑后的残差是否符合标准(第4.6.4节)。
5. Use constraint to calculate mixing factor (section 4.6.5).
5. 使用约束计算混合系数(第4.6.5节)。
6. Mix smoothed signal with unenhanced residual (pssq(n) n=0).
6. 将平滑信号与未增强残差混合(pssq(n)n=0)。
The main idea of the enhancer is to find three 80 sample blocks before and three 80-sample blocks after the analyzed unenhanced sub-block and to use these to improve the quality of the excitation in that sub-block. The six blocks are chosen so that they have the highest possible correlation with the unenhanced sub-block that is being enhanced. In other words, the six blocks are pitch-period-synchronous sequences to the unenhanced sub-block.
增强器的主要思想是在分析的非增强子块之前找到三个80样本块,在分析的非增强子块之后找到三个80样本块,并使用它们来改善该子块中的激发质量。选择这六个块,以便它们与正在增强的未增强子块具有尽可能高的相关性。换句话说,六个块是与未增强子块的基音周期同步序列。
A linear combination of the six pitch-period-synchronous sequences is calculated that approximates the sub-block. If the squared error between the approximation and the unenhanced sub-block is small enough, the enhanced residual is set equal to this approximation. For the cases when the squared error criterion is not fulfilled, a linear combination of the approximation and the unenhanced residual forms the enhanced residual.
计算六个基音周期同步序列的线性组合,以近似子块。如果近似值和未增强子块之间的平方误差足够小,则增强残差设置为等于此近似值。对于不满足平方误差标准的情况,近似和未增强残差的线性组合形成增强残差。
Pitch estimates are needed to determine the locations of the pitch-period-synchronous sequences in a complexity-efficient way. For each of the new two/three sub-blocks, a pitch estimate is calculated by finding the maximum correlation in the range from lag 20 to lag 120. These pitch estimates are used to narrow down the search for the best possible pitch-period-synchronous sequences.
基音周期估计需要以一种复杂高效的方式确定基音周期同步序列的位置。对于新的两/三个子块中的每一个子块,通过查找从滞后20到滞后120范围内的最大相关性来计算基音估计。这些基音周期估计用于缩小对最佳基音周期同步序列的搜索范围。
Upon receiving the pitch estimates from the prior step, the enhancer analyzes and enhances one 80-sample sub-block at a time. The pitch-period-synchronous-sequences pssq(n) can be viewed as vectors of length 80 samples each shifted n*lag samples from the current sub-block. The six pitch-period-synchronous-sequences, pssq(-3) to pssq(-1) and pssq(1) to pssq(3), are found one at a time by the steps below:
在接收到来自前一步骤的基音估计后,增强器一次分析并增强一个80样本子块。基音周期同步序列pssq(n)可被视为长度为80个样本的向量,每个样本从当前子块移位n×滞后样本。六个变桨周期同步序列pssq(-3)至pssq(-1)和pssq(1)至pssq(3)通过以下步骤一次找到一个:
1) Calculate the estimate of the position of the pssq(n). For pssq(n) in front of pssq(0) (n > 0), the location of the pssq(n) is estimated by moving one pitch estimate forward in time from the exact location of pssq(n-1). Similarly, pssq(n) behind pssq(0) (n < 0) is estimated by moving one pitch estimate backward in time from the exact location of pssq(n+1). If the estimated pssq(n) vector location is totally within the enhancer memory (Figure 4.3), steps 2, 3, and 4 are performed, otherwise the pssq(n) is set to zeros.
1) 计算pssq(n)位置的估计值。对于pssq(n)在pssq(0)(n>0)之前的pssq(n),pssq(n)的位置通过从pssq(n-1)的精确位置在时间上向前移动一个俯仰估计来估计。类似地,pssq(0)(n<0)后面的pssq(n)通过从pssq(n+1)的精确位置向后移动一个基音估计值来估计。如果估计的pssq(n)矢量位置完全在增强器内存中(图4.3),则执行步骤2、3和4,否则pssq(n)设置为零。
2) Compute the correlation between the unenhanced excitation and vectors around the estimated location interval of pssq(n). The correlation is calculated in the interval estimated location +/- 2 samples. This results in five correlation values.
2) 计算非增强激励与pssq(n)估计位置间隔周围矢量之间的相关性。在区间估计位置+/-2个样本中计算相关性。这将产生五个相关值。
3) The five correlation values are upsampled by a factor of 4, by using four simple upsampling filters (MA filters with coefficients upsFilter1.. upsFilter4). Within these the maximum value is found, which specifies the best pitch-period with a resolution of a quarter of a sample.
3) 通过使用四个简单的上采样滤波器(系数为upsFilter1..upsFilter4的MA滤波器),将五个相关值以因子4进行上采样。在这些最大值中,指定了分辨率为四分之一样本的最佳基音周期。
upsFilter1[7]={0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000} upsFilter2[7]={0.015625 -0.076904 0.288330 0.862061 -0.106445 0.018799 -0.015625} upsFilter3[7]={0.023682 -0.124268 0.601563 0.601563 -0.124268 0.023682 -0.023682} upsFilter4[7]={0.018799 -0.106445 0.862061 0.288330 -0.076904 0.015625 -0.018799}
upsFilter1[7]={0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000} upsFilter2[7]={0.015625 -0.076904 0.288330 0.862061 -0.106445 0.018799 -0.015625} upsFilter3[7]={0.023682 -0.124268 0.601563 0.601563 -0.124268 0.023682 -0.023682} upsFilter4[7]={0.018799 -0.106445 0.862061 0.288330 -0.076904 0.015625 -0.018799}
4) Generate the pssq(n) vector by upsampling of the excitation memory and extracting the sequence that corresponds to the lag delay that was calculated in prior step.
4) 通过对励磁存储器进行上采样并提取与前一步骤中计算的滞后延迟相对应的序列,生成pssq(n)矢量。
With the steps above, all the pssq(n) can be found in an iterative manner, first moving backward in time from pssq(0) and then forward in time from pssq(0).
通过上述步骤,所有pssq(n)都可以以迭代方式找到,首先从pssq(0)在时间上向后移动,然后从pssq(0)在时间上向前移动。
0 159 319 479 639 +---------------------------------------------------------------+ | -5 | -4 | -3 | -2 | -1 | 0 | 1 | 2 | +---------------------------------------------------------------+ |pssq 0 | |pssq -1| |pssq 1 | |pssq -2| |pssq 2 | |pssq -3| |pssq 3 |
0 159 319 479 639 +---------------------------------------------------------------+ | -5 | -4 | -3 | -2 | -1 | 0 | 1 | 2 | +---------------------------------------------------------------+ |pssq 0 | |pssq -1| |pssq 1 | |pssq -2| |pssq 2 | |pssq -3| |pssq 3 |
Figure 4.3. Enhancement for 20 ms frame size.
图4.3。20毫秒帧大小的增强。
Figure 4.3 depicts pitch-period-synchronous sequences in the enhancement of the first 80 sample block in the 20 ms frame size mode. The unenhanced signal input is stored in the last two sub-blocks (1 - 2), and the six other sub-blocks contain unenhanced residual prior-in-time. We perform the enhancement algorithm on two blocks of 80 samples, where the first of the two blocks consists of the last 40 samples of sub-block 0 and the first 40 samples of sub-block 1. The second 80-sample block consists of the last 40 samples of sub-block 1 and the first 40 samples of sub-block 2.
图4.3描述了在20 ms帧大小模式下增强前80个样本块时的基音周期同步序列。未增强信号输入存储在最后两个子块(1-2)中,其他六个子块包含时间上的未增强剩余。我们在两个80个样本的块上执行增强算法,其中两个块中的第一个由子块0的最后40个样本和子块1的前40个样本组成。第二个80个样本块由子块1的最后40个样本和子块2的前40个样本组成。
0 159 319 479 639 +---------------------------------------------------------------+ | -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | +---------------------------------------------------------------+ |pssq 0 | |pssq -1| |pssq 1 | |pssq -2| |pssq 2 | |pssq -3| |pssq 3 |
0 159 319 479 639 +---------------------------------------------------------------+ | -4 | -3 | -2 | -1 | 0 | 1 | 2 | 3 | +---------------------------------------------------------------+ |pssq 0 | |pssq -1| |pssq 1 | |pssq -2| |pssq 2 | |pssq -3| |pssq 3 |
Figure 4.4. Enhancement for 30 ms frame size.
图4.4。增强30毫秒帧大小。
Figure 4.4 depicts pitch-period-synchronous sequences in the enhancement of the first 80-sample block in the 30 ms frame size mode. The unenhanced signal input is stored in the last three sub-blocks (1 - 3). The five other sub-blocks contain unenhanced residual prior-in-time. The enhancement algorithm is performed on the three 80 sample sub-blocks 0, 1, and 2.
图4.4描述了在30ms帧大小模式下增强前80个样本块时的基音周期同步序列。非增强信号输入存储在最后三个子块(1-3)中。其他五个子块包含未增强的剩余时间。在三个80样本子块0、1和2上执行增强算法。
A linear combination of the six pssq(n) (n!=0) form a smoothed approximation, z, of pssq(0). Most of the weight is put on the sequences that are close to pssq(0), as these are likely to be most similar to pssq(0). The smoothed vector is also rescaled so that the energy of z is the same as the energy of pssq(0).
六个pssq(n)(n!=0)的线性组合形成pssq(0)的平滑近似z。大部分权重放在接近pssq(0)的序列上,因为这些序列可能与pssq(0)最为相似。平滑后的矢量也会重新缩放,以便z的能量与pssq(0)的能量相同。
___ \ y = > pssq(i) * pssq_weight(i) /__ i=-3,-2,-1,1,2,3
___ \ y = > pssq(i) * pssq_weight(i) /__ i=-3,-2,-1,1,2,3
pssq_weight(i) = 0.5*(1-cos(2*pi*(i+4)/(2*3+2)))
pssq_weight(i) = 0.5*(1-cos(2*pi*(i+4)/(2*3+2)))
z = C * y, where C = ||pssq(0)||/||y||
z = C * y, where C = ||pssq(0)||/||y||
The criterion of the enhancer is that the enhanced excitation is not allowed to differ much from the unenhanced excitation. This criterion is checked for each 80-sample sub-block.
增强器的标准是,增强激发与非增强激发之间不允许有太大差异。针对每个80个样本子块检查该标准。
e < (b * ||pssq(0)||^2), where b=0.05 and (Constraint 1)
e < (b * ||pssq(0)||^2), where b=0.05 and (Constraint 1)
e = (pssq(0)-z)*(pssq(0)-z), and "*" means the dot product
e = (pssq(0)-z)*(pssq(0)-z), and "*" means the dot product
From the criterion in the previous section, it is clear that the excitation is not allowed to change much. The purpose of this constraint is to prevent the creation of an enhanced signal significantly different from the original signal. This also means that the constraint limits the numerical size of the errors that the enhancement procedure can make. That is especially important in unvoiced segments and background noise segments for which increased periodicity could lead to lower perceived quality.
根据上一节中的标准,很明显,不允许励磁发生太大变化。该约束的目的是防止产生明显不同于原始信号的增强信号。这也意味着约束限制了增强过程可能产生的误差的数值大小。这在清音段和背景噪声段尤其重要,因为增加的周期性可能导致较低的感知质量。
When the constraint in the prior section is not met, the enhanced residual is instead calculated through a constrained optimization by using the Lagrange multiplier technique. The new constraint is that
当不满足前一节中的约束时,使用拉格朗日乘子技术通过约束优化计算增强残差。新的限制是
e = (b * ||pssq(0)||^2) (Constraint 2)
e = (b * ||pssq(0)||^2) (Constraint 2)
We distinguish two solution regions for the optimization: 1) the region where the first constraint is fulfilled and 2) the region where the first constraint is not fulfilled and the second constraint must be used.
我们为优化区分了两个解区域:1)满足第一个约束的区域和2)不满足第一个约束的区域,必须使用第二个约束。
In the first case, where the second constraint is not needed, the optimized re-estimated vector is simply z, the energy-scaled version of y.
在第一种情况下,在不需要第二个约束的情况下,优化的重新估计向量只是z,即y的能量缩放版本。
In the second case, where the second constraint is activated and becomes an equality constraint, we have
在第二种情况下,当第二个约束被激活并成为相等约束时,我们有
z= A*y + B*pssq(0)
z= A*y + B*pssq(0)
where
哪里
A = sqrt((b-b^2/4)*(w00*w00)/ (w11*w00 + w10*w10)) and
A = sqrt((b-b^2/4)*(w00*w00)/ (w11*w00 + w10*w10)) and
w11 = pssq(0)*pssq(0) w00 = y*y w10 = y*pssq(0) (* symbolizes the dot product)
w11 = pssq(0)*pssq(0) w00 = y*y w10 = y*pssq(0) (* symbolizes the dot product)
and
和
B = 1 - b/2 - A * w10/w00
B = 1 - b/2 - A * w10/w00
Appendix A.16 contains a listing of a reference implementation for the enhancement method.
附录A.16包含增强方法的参考实施清单。
Upon decoding or PLC of the LP excitation block, the decoded speech block is obtained by running the decoded LP synthesis filter, 1/A~k(z), over the block. The synthesis filters have to be shifted to compensate for the delay in the enhancer. For 20 ms frame size mode, they SHOULD be shifted one 40-sample sub-block, and for 30 ms frame size mode, they SHOULD be shifted two 40-sample sub-blocks. The LP coefficients SHOULD be changed at the first sample of every sub-block while keeping the filter state. For PLC blocks, one solution is to apply the last LP coefficients of the last decoded speech block for all sub-blocks.
对LP激励块进行解码或PLC后,通过在该块上运行解码LP合成滤波器1/A~k(z)来获得解码语音块。必须移动合成滤波器以补偿增强器中的延迟。对于20ms帧大小模式,应将其移动一个40采样子块,对于30ms帧大小模式,应将其移动两个40采样子块。LP系数应在每个子块的第一个样本处改变,同时保持滤波器状态。对于PLC块,一种解决方案是将最后解码语音块的最后LP系数应用于所有子块。
The reference implementation for the synthesis filtering can be found in Appendix A.48.
综合过滤的参考实施可在附录A.48中找到。
If desired, the decoded block can be filtered by a high-pass filter. This removes the low frequencies of the decoded signal. A reference implementation of this, with cutoff at 65 Hz, is shown in Appendix A.30.
如果需要,可通过高通滤波器对解码块进行滤波。这将去除解码信号的低频率。附录A.30中给出了截止频率为65 Hz的参考实施方案。
This algorithm for the coding of speech signals is not subject to any known security consideration; however, its RTP payload format [1] is subject to several considerations, which are addressed there. Confidentiality of the media streams is achieved by encryption; therefore external mechanisms, such as SRTP [5], MAY be used for that purpose.
该语音信号编码算法不受任何已知安全考虑的约束;然而,其RTP有效负载格式[1]受到若干考虑因素的影响,这些考虑因素将在此处讨论。通过加密实现媒体流的机密性;因此,外部机制(如SRTP[5])可用于该目的。
It is possible and suggested to evaluate certain iLBC implementation by utilizing methodology and tools available at http://www.ilbcfreeware.org/evaluation.html
有可能并建议通过利用网站上提供的方法和工具来评估某些iLBC实施http://www.ilbcfreeware.org/evaluation.html
[1] Duric, A. and S. Andersen, "Real-time Transport Protocol (RTP) Payload Format for internet Low Bit Rate Codec (iLBC) Speech", RFC 3952, December 2004.
[1] Duric,A.和S.Andersen,“互联网低比特率编解码器(iLBC)语音的实时传输协议(RTP)有效载荷格式”,RFC 3952,2004年12月。
[2] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
[2] Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。
[3] PacketCable(TM) Audio/Video Codecs Specification, Cable Television Laboratories, Inc.
[3] PacketCable(TM)音频/视频编解码器规范,有线电视实验室有限公司。
[4] ITU-T Recommendation G.711, available online from the ITU bookstore at http://www.itu.int.
[4] ITU-T建议G.711,可从ITU书店在线获取,网址为http://www.itu.int.
[5] Baugher, M., McGrew, D., Naslund, M., Carrara, E., and K. Norman, "The Secure Real Time Transport Protocol (SRTP)", RFC 3711, March 2004.
[5] Baugher,M.,McGrew,D.,Naslund,M.,Carrara,E.,和K.Norman,“安全实时传输协议(SRTP)”,RFC 37112004年3月。
This extensive work, besides listed authors, has the following authors, who could not have been listed among "official" authors (due to IESG restrictions in the number of authors who can be listed):
除了列出的作者外,这项广泛的工作还有以下作者,他们不可能被列为“官方”作者(由于IESG对可以被列为“官方”作者的作者数量的限制):
Manohar N. Murthi (Department of Electrical and Computer Engineering, University of Miami), Fredrik Galschiodt, Julian Spittka, and Jan Skoglund (Global IP Sound).
Manohar N. Murthi(迈阿密大学电气与计算机工程系),Fredrik Galschiodt,Julian Spittka,Jan Skoglund(全球IP声音)。
The authors are deeply indebted to the following people and thank them sincerely:
作者深深感谢以下人士,并衷心感谢他们:
Henry Sinnreich, Patrik Faltstrom, Alan Johnston, and Jean-Francois Mule for great support of the iLBC initiative and for valuable feedback and comments.
Henry Sinnreich、Patrik Faltstrom、Alan Johnston和Jean-Francois Mule对iLBC倡议的大力支持以及宝贵的反馈和评论。
Peter Vary, Frank Mertz, and Christoph Erdmann (RWTH Aachen); Vladimir Cuperman (Niftybox LLC); Thomas Eriksson (Chalmers Univ of Tech), and Gernot Kubin (TU Graz), for thorough review of the iLBC document and their valuable feedback and remarks.
彼得·法利、弗兰克·默茨和克里斯托夫·埃尔德曼(亚琛RWTH);Vladimir Cuperman(Niftybox有限责任公司);Thomas Eriksson(查尔默斯理工大学)和Gernot Kubin(TU Graz)对iLBC文件及其宝贵反馈和评论进行了全面审查。
APPENDIX A. Reference Implementation
附录A.参考实施
This appendix contains the complete c-code for a reference implementation of encoder and decoder for the specified codec.
本附录包含用于指定编解码器的编码器和解码器参考实现的完整c代码。
The c-code consists of the following files with highest-level functions:
c代码由以下具有最高级别功能的文件组成:
iLBC_test.c: main function for evaluation purpose iLBC_encode.h: encoder header iLBC_encode.c: encoder function iLBC_decode.h: decoder header iLBC_decode.c: decoder function
iLBC_test.c:用于评估目的的主要函数iLBC_encode.h:编码器头iLBC_encode.c:编码器函数iLBC_decode.h:解码器头iLBC_decode.c:解码器函数
The following files contain global defines and constants:
以下文件包含全局定义和常量:
iLBC_define.h: global defines constants.h: global constants header constants.c: global constants memory allocations
iLBC_define.h:全局定义常量。h:全局常量标题常量。c:全局常量内存分配
The following files contain subroutines:
以下文件包含子例程:
anaFilter.h: lpc analysis filter header anaFilter.c: lpc analysis filter function createCB.h: codebook construction header createCB.c: codebook construction function doCPLC.h: packet loss concealment header doCPLC.c: packet loss concealment function enhancer.h: signal enhancement header enhancer.c: signal enhancement function filter.h: general filter header filter.c: general filter functions FrameClassify.h: start state classification header FrameClassify.c: start state classification function gainquant.h: gain quantization header gainquant.c: gain quantization function getCBvec.h: codebook vector construction header getCBvec.c: codebook vector construction function helpfun.h: general purpose header helpfun.c: general purpose functions hpInput.h: input high pass filter header hpInput.c: input high pass filter function hpOutput.h: output high pass filter header hpOutput.c: output high pass filter function iCBConstruct.h: excitation decoding header iCBConstruct.c: excitation decoding function iCBSearch.h: excitation encoding header iCBSearch.c: excitation encoding function
anaFilter.h:lpc分析筛选器标头anaFilter.c:lpc分析筛选器函数createCB.h:codebook构造标头createCB.c:codebook构造函数doCPLC.h:packet loss隐蔽标头doCPLC.c:packet loss隐蔽函数增强器.h:signal enhancement标头增强器.c:signal enhancement函数筛选器.h:general过滤器标题过滤器.c:常规过滤器函数FrameClassification.h:开始状态分类标题FrameClassification.c:开始状态分类函数GainQuent.h:增益量化标题GainQuent.c:增益量化函数getCBvec.h:码本向量构造标题getCBvec.c:码本向量构造函数helpfun.h:常规目的头帮助函数.c:通用函数hpInput.h:输入高通滤波器头hpInput.c:输入高通滤波器函数hpOutput.h:输出高通滤波器头hpOutput.c:输出高通滤波器函数iCBConstruct.h:激励解码头iCBConstruct.c:激励解码函数iCBSearch.h:激励编码标题iCBSearch.c:激励编码功能
LPCdecode.h: lpc decoding header LPCdecode.c: lpc decoding function LPCencode.h: lpc encoding header LPCencode.c: lpc encoding function lsf.h: line spectral frequencies header lsf.c: line spectral frequencies functions packing.h: bitstream packetization header packing.c: bitstream packetization functions StateConstructW.h: state decoding header StateConstructW.c: state decoding functions StateSearchW.h: state encoding header StateSearchW.c: state encoding function syntFilter.h: lpc synthesis filter header syntFilter.c: lpc synthesis filter function
LPCdecode.h:lpc解码头LPCdecode.c:lpc解码函数LPCencode.h:lpc编码头LPCencode.c:lpc编码函数lsf.h:line Spectrum frequencies header lsf.c:line Spectrum frequencies functions packing.h:bitstream Packetize header packing.c:bitstream Packetize Packetize functions StateConstructW.h:state解码头StateConstructW.c:状态解码函数StateSearchW.h:状态编码标头StateSearchW.c:状态编码函数syntFilter.h:lpc合成筛选器标头syntFilter.c:lpc合成筛选器函数
The implementation is portable and should work on many different platforms. However, it is not difficult to optimize the implementation on particular platforms, an exercise left to the reader.
该实现是可移植的,应该可以在许多不同的平台上工作。然而,在特定平台上优化实现并不困难,这是留给读者的练习。
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iLBC_test.c
iLBC_测试.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include "iLBC_define.h" #include "iLBC_encode.h" #include "iLBC_decode.h"
#include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include "iLBC_define.h" #include "iLBC_encode.h" #include "iLBC_decode.h"
/* Runtime statistics */ #include <time.h>
/* Runtime statistics */ #include <time.h>
#define ILBCNOOFWORDS_MAX (NO_OF_BYTES_30MS/2)
#定义ILBCNOOFWORDS_MAX(无字节数_30MS/2)
/*----------------------------------------------------------------* * Encoder interface function
/*----------------------------------------------------------------* * Encoder interface function
*---------------------------------------------------------------*/
*---------------------------------------------------------------*/
short encode( /* (o) Number of bytes encoded */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ short *encoded_data, /* (o) The encoded bytes */ short *data /* (i) The signal block to encode*/ ){ float block[BLOCKL_MAX]; int k;
short encode( /* (o) Number of bytes encoded */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ short *encoded_data, /* (o) The encoded bytes */ short *data /* (i) The signal block to encode*/ ){ float block[BLOCKL_MAX]; int k;
/* convert signal to float */
/* convert signal to float */
for (k=0; k<iLBCenc_inst->blockl; k++) block[k] = (float)data[k];
for (k=0; k<iLBCenc_inst->blockl; k++) block[k] = (float)data[k];
/* do the actual encoding */
/* do the actual encoding */
iLBC_encode((unsigned char *)encoded_data, block, iLBCenc_inst);
iLBC_encode((unsigned char *)encoded_data, block, iLBCenc_inst);
return (iLBCenc_inst->no_of_bytes); }
return (iLBCenc_inst->no_of_bytes); }
/*----------------------------------------------------------------* * Decoder interface function *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Decoder interface function *---------------------------------------------------------------*/
short decode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ short *decoded_data, /* (o) Decoded signal block*/ short *encoded_data, /* (i) Encoded bytes */ short mode /* (i) 0=PL, 1=Normal */ ){ int k; float decblock[BLOCKL_MAX], dtmp;
short decode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ short *decoded_data, /* (o) Decoded signal block*/ short *encoded_data, /* (i) Encoded bytes */ short mode /* (i) 0=PL, 1=Normal */ ){ int k; float decblock[BLOCKL_MAX], dtmp;
/* check if mode is valid */
/* check if mode is valid */
if (mode<0 || mode>1) { printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);}
if (mode<0 || mode>1) { printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);}
/* do actual decoding of block */
/* do actual decoding of block */
iLBC_decode(decblock, (unsigned char *)encoded_data, iLBCdec_inst, mode);
iLBC_解码(decblock(无符号字符*)编码_数据,iLBCdec_指令,模式);
/* convert to short */
/* convert to short */
for (k=0; k<iLBCdec_inst->blockl; k++){ dtmp=decblock[k];
for (k=0; k<iLBCdec_inst->blockl; k++){ dtmp=decblock[k];
if (dtmp<MIN_SAMPLE) dtmp=MIN_SAMPLE; else if (dtmp>MAX_SAMPLE) dtmp=MAX_SAMPLE; decoded_data[k] = (short) dtmp; }
if (dtmp<MIN_SAMPLE) dtmp=MIN_SAMPLE; else if (dtmp>MAX_SAMPLE) dtmp=MAX_SAMPLE; decoded_data[k] = (short) dtmp; }
return (iLBCdec_inst->blockl); }
return (iLBCdec_inst->blockl); }
/*---------------------------------------------------------------* * Main program to test iLBC encoding and decoding * * Usage: * exefile_name.exe <infile> <bytefile> <outfile> <channel> * * <infile> : Input file, speech for encoder (16-bit pcm file) * <bytefile> : Bit stream output from the encoder * <outfile> : Output file, decoded speech (16-bit pcm file) * <channel> : Bit error file, optional (16-bit) * 1 - Packet received correctly * 0 - Packet Lost * *--------------------------------------------------------------*/
/*---------------------------------------------------------------* * Main program to test iLBC encoding and decoding * * Usage: * exefile_name.exe <infile> <bytefile> <outfile> <channel> * * <infile> : Input file, speech for encoder (16-bit pcm file) * <bytefile> : Bit stream output from the encoder * <outfile> : Output file, decoded speech (16-bit pcm file) * <channel> : Bit error file, optional (16-bit) * 1 - Packet received correctly * 0 - Packet Lost * *--------------------------------------------------------------*/
int main(int argc, char* argv[]) {
int main(int argc,char*argv[]){
/* Runtime statistics */
/* Runtime statistics */
float starttime; float runtime; float outtime;
float starttime; float runtime; float outtime;
FILE *ifileid,*efileid,*ofileid, *cfileid; short data[BLOCKL_MAX]; short encoded_data[ILBCNOOFWORDS_MAX], decoded_data[BLOCKL_MAX]; int len; short pli, mode; int blockcount = 0; int packetlosscount = 0;
FILE *ifileid,*efileid,*ofileid, *cfileid; short data[BLOCKL_MAX]; short encoded_data[ILBCNOOFWORDS_MAX], decoded_data[BLOCKL_MAX]; int len; short pli, mode; int blockcount = 0; int packetlosscount = 0;
/* Create structs */ iLBC_Enc_Inst_t Enc_Inst; iLBC_Dec_Inst_t Dec_Inst;
/* Create structs */ iLBC_Enc_Inst_t Enc_Inst; iLBC_Dec_Inst_t Dec_Inst;
/* get arguments and open files */
/* get arguments and open files */
if ((argc!=5) && (argc!=6)) { fprintf(stderr, "\n*-----------------------------------------------*\n"); fprintf(stderr, " %s <20,30> input encoded decoded (channel)\n\n", argv[0]); fprintf(stderr, " mode : Frame size for the encoding/decoding\n"); fprintf(stderr, " 20 - 20 ms\n"); fprintf(stderr, " 30 - 30 ms\n"); fprintf(stderr, " input : Speech for encoder (16-bit pcm file)\n"); fprintf(stderr, " encoded : Encoded bit stream\n"); fprintf(stderr, " decoded : Decoded speech (16-bit pcm file)\n"); fprintf(stderr, " channel : Packet loss pattern, optional (16-bit)\n"); fprintf(stderr, " 1 - Packet received correctly\n"); fprintf(stderr, " 0 - Packet Lost\n"); fprintf(stderr, "*-----------------------------------------------*\n\n"); exit(1); } mode=atoi(argv[1]); if (mode != 20 && mode != 30) { fprintf(stderr,"Wrong mode %s, must be 20, or 30\n", argv[1]); exit(2); } if ( (ifileid=fopen(argv[2],"rb")) == NULL) { fprintf(stderr,"Cannot open input file %s\n", argv[2]); exit(2);} if ( (efileid=fopen(argv[3],"wb")) == NULL) { fprintf(stderr, "Cannot open encoded file %s\n", argv[3]); exit(1);} if ( (ofileid=fopen(argv[4],"wb")) == NULL) { fprintf(stderr, "Cannot open decoded file %s\n", argv[4]); exit(1);} if (argc==6) { if( (cfileid=fopen(argv[5],"rb")) == NULL) { fprintf(stderr, "Cannot open channel file %s\n",
if ((argc!=5) && (argc!=6)) { fprintf(stderr, "\n*-----------------------------------------------*\n"); fprintf(stderr, " %s <20,30> input encoded decoded (channel)\n\n", argv[0]); fprintf(stderr, " mode : Frame size for the encoding/decoding\n"); fprintf(stderr, " 20 - 20 ms\n"); fprintf(stderr, " 30 - 30 ms\n"); fprintf(stderr, " input : Speech for encoder (16-bit pcm file)\n"); fprintf(stderr, " encoded : Encoded bit stream\n"); fprintf(stderr, " decoded : Decoded speech (16-bit pcm file)\n"); fprintf(stderr, " channel : Packet loss pattern, optional (16-bit)\n"); fprintf(stderr, " 1 - Packet received correctly\n"); fprintf(stderr, " 0 - Packet Lost\n"); fprintf(stderr, "*-----------------------------------------------*\n\n"); exit(1); } mode=atoi(argv[1]); if (mode != 20 && mode != 30) { fprintf(stderr,"Wrong mode %s, must be 20, or 30\n", argv[1]); exit(2); } if ( (ifileid=fopen(argv[2],"rb")) == NULL) { fprintf(stderr,"Cannot open input file %s\n", argv[2]); exit(2);} if ( (efileid=fopen(argv[3],"wb")) == NULL) { fprintf(stderr, "Cannot open encoded file %s\n", argv[3]); exit(1);} if ( (ofileid=fopen(argv[4],"wb")) == NULL) { fprintf(stderr, "Cannot open decoded file %s\n", argv[4]); exit(1);} if (argc==6) { if( (cfileid=fopen(argv[5],"rb")) == NULL) { fprintf(stderr, "Cannot open channel file %s\n",
argv[5]); exit(1); } } else { cfileid=NULL; }
argv[5]); exit(1); } } else { cfileid=NULL; }
/* print info */
/* print info */
fprintf(stderr, "\n"); fprintf(stderr, "*---------------------------------------------------*\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "* iLBC test program *\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "*---------------------------------------------------*\n"); fprintf(stderr,"\nMode : %2d ms\n", mode); fprintf(stderr,"Input file : %s\n", argv[2]); fprintf(stderr,"Encoded file : %s\n", argv[3]); fprintf(stderr,"Output file : %s\n", argv[4]); if (argc==6) { fprintf(stderr,"Channel file : %s\n", argv[5]); } fprintf(stderr,"\n");
fprintf(stderr, "\n"); fprintf(stderr, "*---------------------------------------------------*\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "* iLBC test program *\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "*---------------------------------------------------*\n"); fprintf(stderr,"\nMode : %2d ms\n", mode); fprintf(stderr,"Input file : %s\n", argv[2]); fprintf(stderr,"Encoded file : %s\n", argv[3]); fprintf(stderr,"Output file : %s\n", argv[4]); if (argc==6) { fprintf(stderr,"Channel file : %s\n", argv[5]); } fprintf(stderr,"\n");
/* Initialization */
/* Initialization */
initEncode(&Enc_Inst, mode); initDecode(&Dec_Inst, mode, 1);
initEncode(&Enc_Inst, mode); initDecode(&Dec_Inst, mode, 1);
/* Runtime statistics */
/* Runtime statistics */
starttime=clock()/(float)CLOCKS_PER_SEC;
starttime=clock()/(float)CLOCKS_PER_SEC;
/* loop over input blocks */
/* loop over input blocks */
while (fread(data,sizeof(short),Enc_Inst.blockl,ifileid)== Enc_Inst.blockl) {
while (fread(data,sizeof(short),Enc_Inst.blockl,ifileid)== Enc_Inst.blockl) {
blockcount++;
blockcount++;
/* encoding */
/* encoding */
fprintf(stderr, "--- Encoding block %i --- ",blockcount); len=encode(&Enc_Inst, encoded_data, data); fprintf(stderr, "\r");
fprintf(stderr, "--- Encoding block %i --- ",blockcount); len=encode(&Enc_Inst, encoded_data, data); fprintf(stderr, "\r");
/* write byte file */
/* write byte file */
fwrite(encoded_data, sizeof(unsigned char), len, efileid);
fwrite(encoded_data, sizeof(unsigned char), len, efileid);
/* get channel data if provided */ if (argc==6) { if (fread(&pli, sizeof(short), 1, cfileid)) { if ((pli!=0)&&(pli!=1)) { fprintf(stderr, "Error in channel file\n"); exit(0); } if (pli==0) { /* Packet loss -> remove info from frame */ memset(encoded_data, 0, sizeof(short)*ILBCNOOFWORDS_MAX); packetlosscount++; } } else { fprintf(stderr, "Error. Channel file too short\n"); exit(0); } } else { pli=1; }
/* get channel data if provided */ if (argc==6) { if (fread(&pli, sizeof(short), 1, cfileid)) { if ((pli!=0)&&(pli!=1)) { fprintf(stderr, "Error in channel file\n"); exit(0); } if (pli==0) { /* Packet loss -> remove info from frame */ memset(encoded_data, 0, sizeof(short)*ILBCNOOFWORDS_MAX); packetlosscount++; } } else { fprintf(stderr, "Error. Channel file too short\n"); exit(0); } } else { pli=1; }
/* decoding */
/* decoding */
fprintf(stderr, "--- Decoding block %i --- ",blockcount);
fprintf(stderr, "--- Decoding block %i --- ",blockcount);
len=decode(&Dec_Inst, decoded_data, encoded_data, pli); fprintf(stderr, "\r");
len=decode(&Dec_Inst, decoded_data, encoded_data, pli); fprintf(stderr, "\r");
/* write output file */
/* write output file */
fwrite(decoded_data,sizeof(short),len,ofileid); }
fwrite(decoded_data,sizeof(short),len,ofileid); }
/* Runtime statistics */
/* Runtime statistics */
runtime = (float)(clock()/(float)CLOCKS_PER_SEC-starttime); outtime = (float)((float)blockcount*(float)mode/1000.0); printf("\n\nLength of speech file: %.1f s\n", outtime); printf("Packet loss : %.1f%%\n", 100.0*(float)packetlosscount/(float)blockcount);
runtime = (float)(clock()/(float)CLOCKS_PER_SEC-starttime); outtime = (float)((float)blockcount*(float)mode/1000.0); printf("\n\nLength of speech file: %.1f s\n", outtime); printf("Packet loss : %.1f%%\n", 100.0*(float)packetlosscount/(float)blockcount);
printf("Time to run iLBC :"); printf(" %.1f s (%.1f %% of realtime)\n\n", runtime, (100*runtime/outtime));
printf("Time to run iLBC :"); printf(" %.1f s (%.1f %% of realtime)\n\n", runtime, (100*runtime/outtime));
/* close files */
/* close files */
fclose(ifileid); fclose(efileid); fclose(ofileid); if (argc==6) { fclose(cfileid); } return(0); }
fclose(ifileid); fclose(efileid); fclose(ofileid); if (argc==6) { fclose(cfileid); } return(0); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iLBC_encode.h
iLBC_编码.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_ILBCENCODE_H #define __iLBC_ILBCENCODE_H
#ifndef __iLBC_ILBCENCODE_H #define __iLBC_ILBCENCODE_H
#include "iLBC_define.h"
#包括“iLBC_define.h”
short initEncode( /* (o) Number of bytes encoded */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ int mode /* (i) frame size mode */ );
short initEncode( /* (o) Number of bytes encoded */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ int mode /* (i) frame size mode */ );
void iLBC_encode(
无效iLBC_编码(
unsigned char *bytes, /* (o) encoded data bits iLBC */ float *block, /* (o) speech vector to encode */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder state */ );
unsigned char *bytes, /* (o) encoded data bits iLBC */ float *block, /* (o) speech vector to encode */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder state */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iLBC_encode.c
iLBC_encode.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <stdlib.h> #include <string.h>
#include <math.h> #include <stdlib.h> #include <string.h>
#include "iLBC_define.h" #include "LPCencode.h" #include "FrameClassify.h" #include "StateSearchW.h" #include "StateConstructW.h" #include "helpfun.h" #include "constants.h" #include "packing.h" #include "iCBSearch.h" #include "iCBConstruct.h" #include "hpInput.h" #include "anaFilter.h" #include "syntFilter.h"
#包括“iLBC_define.h”#包括“LPCencode.h”#包括“FrameClassify.h”#包括“StateSearchW.h”#包括“StateConstructW.h”#包括“helpfun.h”#包括“constants.h”#包括“packing.h”#包括“iCBSearch.h”#包括“iCBConstruct.h”#包括“hpInput.h”#包括“anaFilter.h”#
/*----------------------------------------------------------------* * Initiation of encoder instance. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Initiation of encoder instance. *---------------------------------------------------------------*/
short initEncode( /* (o) Number of bytes encoded */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ int mode /* (i) frame size mode */ ){ iLBCenc_inst->mode = mode; if (mode==30) { iLBCenc_inst->blockl = BLOCKL_30MS; iLBCenc_inst->nsub = NSUB_30MS; iLBCenc_inst->nasub = NASUB_30MS; iLBCenc_inst->lpc_n = LPC_N_30MS; iLBCenc_inst->no_of_bytes = NO_OF_BYTES_30MS; iLBCenc_inst->no_of_words = NO_OF_WORDS_30MS;
short initEncode( /* (o) Number of bytes encoded */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) Encoder instance */ int mode /* (i) frame size mode */ ){ iLBCenc_inst->mode = mode; if (mode==30) { iLBCenc_inst->blockl = BLOCKL_30MS; iLBCenc_inst->nsub = NSUB_30MS; iLBCenc_inst->nasub = NASUB_30MS; iLBCenc_inst->lpc_n = LPC_N_30MS; iLBCenc_inst->no_of_bytes = NO_OF_BYTES_30MS; iLBCenc_inst->no_of_words = NO_OF_WORDS_30MS;
iLBCenc_inst->state_short_len=STATE_SHORT_LEN_30MS; /* ULP init */ iLBCenc_inst->ULP_inst=&ULP_30msTbl; } else if (mode==20) { iLBCenc_inst->blockl = BLOCKL_20MS; iLBCenc_inst->nsub = NSUB_20MS; iLBCenc_inst->nasub = NASUB_20MS; iLBCenc_inst->lpc_n = LPC_N_20MS; iLBCenc_inst->no_of_bytes = NO_OF_BYTES_20MS; iLBCenc_inst->no_of_words = NO_OF_WORDS_20MS; iLBCenc_inst->state_short_len=STATE_SHORT_LEN_20MS; /* ULP init */ iLBCenc_inst->ULP_inst=&ULP_20msTbl; } else { exit(2); }
iLBCenc_inst->state_short_len=STATE_SHORT_LEN_30MS; /* ULP init */ iLBCenc_inst->ULP_inst=&ULP_30msTbl; } else if (mode==20) { iLBCenc_inst->blockl = BLOCKL_20MS; iLBCenc_inst->nsub = NSUB_20MS; iLBCenc_inst->nasub = NASUB_20MS; iLBCenc_inst->lpc_n = LPC_N_20MS; iLBCenc_inst->no_of_bytes = NO_OF_BYTES_20MS; iLBCenc_inst->no_of_words = NO_OF_WORDS_20MS; iLBCenc_inst->state_short_len=STATE_SHORT_LEN_20MS; /* ULP init */ iLBCenc_inst->ULP_inst=&ULP_20msTbl; } else { exit(2); }
memset((*iLBCenc_inst).anaMem, 0, LPC_FILTERORDER*sizeof(float)); memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl, LPC_FILTERORDER*sizeof(float)); memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl, LPC_FILTERORDER*sizeof(float)); memset((*iLBCenc_inst).lpc_buffer, 0, (LPC_LOOKBACK+BLOCKL_MAX)*sizeof(float)); memset((*iLBCenc_inst).hpimem, 0, 4*sizeof(float));
memset((*iLBCenc_inst).anaMem, 0, LPC_FILTERORDER*sizeof(float)); memcpy((*iLBCenc_inst).lsfold, lsfmeanTbl, LPC_FILTERORDER*sizeof(float)); memcpy((*iLBCenc_inst).lsfdeqold, lsfmeanTbl, LPC_FILTERORDER*sizeof(float)); memset((*iLBCenc_inst).lpc_buffer, 0, (LPC_LOOKBACK+BLOCKL_MAX)*sizeof(float)); memset((*iLBCenc_inst).hpimem, 0, 4*sizeof(float));
return (iLBCenc_inst->no_of_bytes); }
return (iLBCenc_inst->no_of_bytes); }
/*----------------------------------------------------------------* * main encoder function *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * main encoder function *---------------------------------------------------------------*/
void iLBC_encode( unsigned char *bytes, /* (o) encoded data bits iLBC */ float *block, /* (o) speech vector to encode */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder state */ ){
void iLBC_encode( unsigned char *bytes, /* (o) encoded data bits iLBC */ float *block, /* (o) speech vector to encode */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the general encoder state */ ){
float data[BLOCKL_MAX]; float residual[BLOCKL_MAX], reverseResidual[BLOCKL_MAX];
float data[BLOCKL_MAX]; float residual[BLOCKL_MAX], reverseResidual[BLOCKL_MAX];
int start, idxForMax, idxVec[STATE_LEN];
int start、idxForMax、idxVec[STATE_LEN];
float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML]; int n, k, meml_gotten, Nfor, Nback, i, pos; int gain_index[CB_NSTAGES*NASUB_MAX], extra_gain_index[CB_NSTAGES]; int cb_index[CB_NSTAGES*NASUB_MAX],extra_cb_index[CB_NSTAGES]; int lsf_i[LSF_NSPLIT*LPC_N_MAX]; unsigned char *pbytes; int diff, start_pos, state_first; float en1, en2; int index, ulp, firstpart; int subcount, subframe; float weightState[LPC_FILTERORDER]; float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; float weightdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; float decresidual[BLOCKL_MAX];
float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML]; int n, k, meml_gotten, Nfor, Nback, i, pos; int gain_index[CB_NSTAGES*NASUB_MAX], extra_gain_index[CB_NSTAGES]; int cb_index[CB_NSTAGES*NASUB_MAX],extra_cb_index[CB_NSTAGES]; int lsf_i[LSF_NSPLIT*LPC_N_MAX]; unsigned char *pbytes; int diff, start_pos, state_first; float en1, en2; int index, ulp, firstpart; int subcount, subframe; float weightState[LPC_FILTERORDER]; float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; float weightdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; float decresidual[BLOCKL_MAX];
/* high pass filtering of input signal if such is not done prior to calling this function */
/* high pass filtering of input signal if such is not done prior to calling this function */
hpInput(block, iLBCenc_inst->blockl, data, (*iLBCenc_inst).hpimem);
hpInput(block, iLBCenc_inst->blockl, data, (*iLBCenc_inst).hpimem);
/* otherwise simply copy */
/* otherwise simply copy */
/*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/
/*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/
/* LPC of hp filtered input data */
/* LPC of hp filtered input data */
LPCencode(syntdenum, weightdenum, lsf_i, data, iLBCenc_inst);
LPCencode(syntdenum、weightdenum、lsf_i、数据、iLBCenc_inst);
/* inverse filter to get residual */
/* inverse filter to get residual */
for (n=0; n<iLBCenc_inst->nsub; n++) { anaFilter(&data[n*SUBL], &syntdenum[n*(LPC_FILTERORDER+1)], SUBL, &residual[n*SUBL], iLBCenc_inst->anaMem); }
for (n=0; n<iLBCenc_inst->nsub; n++) { anaFilter(&data[n*SUBL], &syntdenum[n*(LPC_FILTERORDER+1)], SUBL, &residual[n*SUBL], iLBCenc_inst->anaMem); }
/* find state location */
/* find state location */
start = FrameClassify(iLBCenc_inst, residual);
start = FrameClassify(iLBCenc_inst, residual);
/* check if state should be in first or last part of the two subframes */
/* check if state should be in first or last part of the two subframes */
diff = STATE_LEN - iLBCenc_inst->state_short_len; en1 = 0; index = (start-1)*SUBL;
diff = STATE_LEN - iLBCenc_inst->state_short_len; en1 = 0; index = (start-1)*SUBL;
for (i = 0; i < iLBCenc_inst->state_short_len; i++) { en1 += residual[index+i]*residual[index+i]; } en2 = 0; index = (start-1)*SUBL+diff; for (i = 0; i < iLBCenc_inst->state_short_len; i++) { en2 += residual[index+i]*residual[index+i]; }
for (i = 0; i < iLBCenc_inst->state_short_len; i++) { en1 += residual[index+i]*residual[index+i]; } en2 = 0; index = (start-1)*SUBL+diff; for (i = 0; i < iLBCenc_inst->state_short_len; i++) { en2 += residual[index+i]*residual[index+i]; }
if (en1 > en2) { state_first = 1; start_pos = (start-1)*SUBL; } else { state_first = 0; start_pos = (start-1)*SUBL + diff; }
if (en1 > en2) { state_first = 1; start_pos = (start-1)*SUBL; } else { state_first = 0; start_pos = (start-1)*SUBL + diff; }
/* scalar quantization of state */
/* scalar quantization of state */
StateSearchW(iLBCenc_inst, &residual[start_pos], &syntdenum[(start-1)*(LPC_FILTERORDER+1)], &weightdenum[(start-1)*(LPC_FILTERORDER+1)], &idxForMax, idxVec, iLBCenc_inst->state_short_len, state_first);
StateSearchW(iLBCenc_inst, &residual[start_pos], &syntdenum[(start-1)*(LPC_FILTERORDER+1)], &weightdenum[(start-1)*(LPC_FILTERORDER+1)], &idxForMax, idxVec, iLBCenc_inst->state_short_len, state_first);
StateConstructW(idxForMax, idxVec, &syntdenum[(start-1)*(LPC_FILTERORDER+1)], &decresidual[start_pos], iLBCenc_inst->state_short_len);
StateConstructW(idxForMax, idxVec, &syntdenum[(start-1)*(LPC_FILTERORDER+1)], &decresidual[start_pos], iLBCenc_inst->state_short_len);
/* predictive quantization in state */
/* predictive quantization in state */
if (state_first) { /* put adaptive part in the end */
if (state_first) { /* put adaptive part in the end */
/* setup memory */
/* setup memory */
memset(mem, 0, (CB_MEML-iLBCenc_inst->state_short_len)*sizeof(float)); memcpy(mem+CB_MEML-iLBCenc_inst->state_short_len, decresidual+start_pos, iLBCenc_inst->state_short_len*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
memset(mem, 0, (CB_MEML-iLBCenc_inst->state_short_len)*sizeof(float)); memcpy(mem+CB_MEML-iLBCenc_inst->state_short_len, decresidual+start_pos, iLBCenc_inst->state_short_len*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* encode sub-frames */
/* encode sub-frames */
iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index, &residual[start_pos+iLBCenc_inst->state_short_len], mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES,
ICB研究(iLBCenc指令、额外cb指令、额外增益指令和剩余[start\u pos+iLBCenc指令->state\u short\u len]、mem+cb\u MEML-stMemLTbl、stMemLTbl、diff、cb指令、,
&weightdenum[start*(LPC_FILTERORDER+1)], weightState, 0);
&weightdenum[start*(LPC_FILTERORDER+1)],weightState,0);
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct( &decresidual[start_pos+iLBCenc_inst->state_short_len], extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);
iCBConstruct(和Decresidial[启动位置+iLBCenc安装->状态短列]、额外cb索引、额外增益索引、mem+cb\U MEML-stMemLTbl、stMemLTbl、差异、cb\U安装);
} else { /* put adaptive part in the beginning */
} else { /* put adaptive part in the beginning */
/* create reversed vectors for prediction */
/* create reversed vectors for prediction */
for (k=0; k<diff; k++) { reverseResidual[k] = residual[(start+1)*SUBL-1 -(k+iLBCenc_inst->state_short_len)]; }
for (k=0; k<diff; k++) { reverseResidual[k] = residual[(start+1)*SUBL-1 -(k+iLBCenc_inst->state_short_len)]; }
/* setup memory */
/* setup memory */
meml_gotten = iLBCenc_inst->state_short_len; for (k=0; k<meml_gotten; k++) { mem[CB_MEML-1-k] = decresidual[start_pos + k]; } memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
meml_gotten = iLBCenc_inst->state_short_len; for (k=0; k<meml_gotten; k++) { mem[CB_MEML-1-k] = decresidual[start_pos + k]; } memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* encode sub-frames */
/* encode sub-frames */
iCBSearch(iLBCenc_inst, extra_cb_index, extra_gain_index, reverseResidual, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES, &weightdenum[(start-1)*(LPC_FILTERORDER+1)], weightState, 0);
ICB研究(iLBCenc_仪器、额外cb_指数、额外增益_指数、反向剩余、mem+cb_MEML-stMemLTbl、stMemLTbl、diff、cb_仪器和权重密度[(start-1)*(LPC_过滤器顺序+1)],权重状态,0);
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct(reverseDecresidual, extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);
iCBConstruct(反向个体、额外cb指数、额外增益指数、mem+cb MEML-stMemLTbl、stMemLTbl、差异、cb装置);
/* get decoded residual from reversed vector */
/* get decoded residual from reversed vector */
for (k=0; k<diff; k++) { decresidual[start_pos-1-k] = reverseDecresidual[k];
for (k=0; k<diff; k++) { decresidual[start_pos-1-k] = reverseDecresidual[k];
} }
} }
/* counter for predicted sub-frames */
/* counter for predicted sub-frames */
subcount=0;
次计数=0;
/* forward prediction of sub-frames */
/* forward prediction of sub-frames */
Nfor = iLBCenc_inst->nsub-start-1;
Nfor = iLBCenc_inst->nsub-start-1;
if ( Nfor > 0 ) {
如果(n>0){
/* setup memory */
/* setup memory */
memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, STATE_LEN*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, STATE_LEN*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* loop over sub-frames to encode */
/* loop over sub-frames to encode */
for (subframe=0; subframe<Nfor; subframe++) {
for (subframe=0; subframe<Nfor; subframe++) {
/* encode sub-frame */
/* encode sub-frame */
iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, &residual[(start+1+subframe)*SUBL], mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES, &weightdenum[(start+1+subframe)* (LPC_FILTERORDER+1)], weightState, subcount+1);
iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, &residual[(start+1+subframe)*SUBL], mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES, &weightdenum[(start+1+subframe)* (LPC_FILTERORDER+1)], weightState, subcount+1);
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct(&decresidual[(start+1+subframe)*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
iCBConstruct(&decresidual[(start+1+subframe)*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
/* update memory */
/* update memory */
memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); memcpy(mem+CB_MEML-SUBL,
memcpy(mem,mem+SUBL,(CB_MEML-SUBL)*sizeof(float));memcpy(mem+CB_MEML-SUBL,
&decresidual[(start+1+subframe)*SUBL], SUBL*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
&decresidual[(start+1+subframe)*SUBL], SUBL*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
subcount++; } }
subcount++; } }
/* backward prediction of sub-frames */
/* backward prediction of sub-frames */
Nback = start-1;
Nback=start-1;
if ( Nback > 0 ) {
如果(Nback>0){
/* create reverse order vectors */
/* create reverse order vectors */
for (n=0; n<Nback; n++) { for (k=0; k<SUBL; k++) { reverseResidual[n*SUBL+k] = residual[(start-1)*SUBL-1-n*SUBL-k]; reverseDecresidual[n*SUBL+k] = decresidual[(start-1)*SUBL-1-n*SUBL-k]; } }
for (n=0; n<Nback; n++) { for (k=0; k<SUBL; k++) { reverseResidual[n*SUBL+k] = residual[(start-1)*SUBL-1-n*SUBL-k]; reverseDecresidual[n*SUBL+k] = decresidual[(start-1)*SUBL-1-n*SUBL-k]; } }
/* setup memory */
/* setup memory */
meml_gotten = SUBL*(iLBCenc_inst->nsub+1-start);
meml_gotten = SUBL*(iLBCenc_inst->nsub+1-start);
if ( meml_gotten > CB_MEML ) { meml_gotten=CB_MEML; } for (k=0; k<meml_gotten; k++) { mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; } memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
if ( meml_gotten > CB_MEML ) { meml_gotten=CB_MEML; } for (k=0; k<meml_gotten; k++) { mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; } memset(mem, 0, (CB_MEML-k)*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
/* loop over sub-frames to encode */
/* loop over sub-frames to encode */
for (subframe=0; subframe<Nback; subframe++) {
for (subframe=0; subframe<Nback; subframe++) {
/* encode sub-frame */
/* encode sub-frame */
iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,
ICB研究(iLBCenc_inst、cb_index+子账户*cb_NSTAGES、,
gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL], mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES, &weightdenum[(start-2-subframe)* (LPC_FILTERORDER+1)], weightState, subcount+1);
gain_index+subcount*CB_NSTAGES, &reverseResidual[subframe*SUBL], mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES, &weightdenum[(start-2-subframe)* (LPC_FILTERORDER+1)], weightState, subcount+1);
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct(&reverseDecresidual[subframe*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
iCBConstruct(&reverseDecresidual[subframe*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
/* update memory */
/* update memory */
memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); memcpy(mem+CB_MEML-SUBL, &reverseDecresidual[subframe*SUBL], SUBL*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); memcpy(mem+CB_MEML-SUBL, &reverseDecresidual[subframe*SUBL], SUBL*sizeof(float)); memset(weightState, 0, LPC_FILTERORDER*sizeof(float));
subcount++;
subcount++;
}
}
/* get decoded residual from reversed vector */
/* get decoded residual from reversed vector */
for (i=0; i<SUBL*Nback; i++) { decresidual[SUBL*Nback - i - 1] = reverseDecresidual[i]; } } /* end encoding part */
for (i=0; i<SUBL*Nback; i++) { decresidual[SUBL*Nback - i - 1] = reverseDecresidual[i]; } } /* end encoding part */
/* adjust index */ index_conv_enc(cb_index);
/* adjust index */ index_conv_enc(cb_index);
/* pack bytes */
/* pack bytes */
pbytes=bytes; pos=0;
pbytes=bytes; pos=0;
/* loop over the 3 ULP classes */
/* loop over the 3 ULP classes */
for (ulp=0; ulp<3; ulp++) {
for (ulp=0; ulp<3; ulp++) {
/* LSF */ for (k=0; k<LSF_NSPLIT*iLBCenc_inst->lpc_n; k++) { packsplit(&lsf_i[k], &firstpart, &lsf_i[k], iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], iLBCenc_inst->ULP_inst->lsf_bits[k][ulp]+ iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+1]+ iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], &pos); }
/* LSF */ for (k=0; k<LSF_NSPLIT*iLBCenc_inst->lpc_n; k++) { packsplit(&lsf_i[k], &firstpart, &lsf_i[k], iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], iLBCenc_inst->ULP_inst->lsf_bits[k][ulp]+ iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+1]+ iLBCenc_inst->ULP_inst->lsf_bits[k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->lsf_bits[k][ulp], &pos); }
/* Start block info */
/* Start block info */
packsplit(&start, &firstpart, &start, iLBCenc_inst->ULP_inst->start_bits[ulp], iLBCenc_inst->ULP_inst->start_bits[ulp]+ iLBCenc_inst->ULP_inst->start_bits[ulp+1]+ iLBCenc_inst->ULP_inst->start_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->start_bits[ulp], &pos);
packsplit(&start, &firstpart, &start, iLBCenc_inst->ULP_inst->start_bits[ulp], iLBCenc_inst->ULP_inst->start_bits[ulp]+ iLBCenc_inst->ULP_inst->start_bits[ulp+1]+ iLBCenc_inst->ULP_inst->start_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->start_bits[ulp], &pos);
packsplit(&state_first, &firstpart, &state_first, iLBCenc_inst->ULP_inst->startfirst_bits[ulp], iLBCenc_inst->ULP_inst->startfirst_bits[ulp]+ iLBCenc_inst->ULP_inst->startfirst_bits[ulp+1]+ iLBCenc_inst->ULP_inst->startfirst_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->startfirst_bits[ulp], &pos);
packsplit(&state_first, &firstpart, &state_first, iLBCenc_inst->ULP_inst->startfirst_bits[ulp], iLBCenc_inst->ULP_inst->startfirst_bits[ulp]+ iLBCenc_inst->ULP_inst->startfirst_bits[ulp+1]+ iLBCenc_inst->ULP_inst->startfirst_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->startfirst_bits[ulp], &pos);
packsplit(&idxForMax, &firstpart, &idxForMax, iLBCenc_inst->ULP_inst->scale_bits[ulp], iLBCenc_inst->ULP_inst->scale_bits[ulp]+ iLBCenc_inst->ULP_inst->scale_bits[ulp+1]+ iLBCenc_inst->ULP_inst->scale_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->scale_bits[ulp], &pos);
packsplit(&idxForMax, &firstpart, &idxForMax, iLBCenc_inst->ULP_inst->scale_bits[ulp], iLBCenc_inst->ULP_inst->scale_bits[ulp]+ iLBCenc_inst->ULP_inst->scale_bits[ulp+1]+ iLBCenc_inst->ULP_inst->scale_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->scale_bits[ulp], &pos);
for (k=0; k<iLBCenc_inst->state_short_len; k++) { packsplit(idxVec+k, &firstpart, idxVec+k, iLBCenc_inst->ULP_inst->state_bits[ulp], iLBCenc_inst->ULP_inst->state_bits[ulp]+ iLBCenc_inst->ULP_inst->state_bits[ulp+1]+ iLBCenc_inst->ULP_inst->state_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->state_bits[ulp], &pos); }
for (k=0; k<iLBCenc_inst->state_short_len; k++) { packsplit(idxVec+k, &firstpart, idxVec+k, iLBCenc_inst->ULP_inst->state_bits[ulp], iLBCenc_inst->ULP_inst->state_bits[ulp]+ iLBCenc_inst->ULP_inst->state_bits[ulp+1]+ iLBCenc_inst->ULP_inst->state_bits[ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->state_bits[ulp], &pos); }
/* 23/22 (20ms/30ms) sample block */
/* 23/22 (20ms/30ms) sample block */
for (k=0;k<CB_NSTAGES;k++) { packsplit(extra_cb_index+k, &firstpart, extra_cb_index+k, iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp], iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp]+ iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+1]+ iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp], &pos); }
for (k=0;k<CB_NSTAGES;k++) { packsplit(extra_cb_index+k, &firstpart, extra_cb_index+k, iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp], iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp]+ iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+1]+ iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->extra_cb_index[k][ulp], &pos); }
for (k=0;k<CB_NSTAGES;k++) { packsplit(extra_gain_index+k, &firstpart, extra_gain_index+k, iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp], iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp]+ iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+1]+ iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp], &pos); }
for (k=0;k<CB_NSTAGES;k++) { packsplit(extra_gain_index+k, &firstpart, extra_gain_index+k, iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp], iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp]+ iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+1]+ iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->extra_cb_gain[k][ulp], &pos); }
/* The two/four (20ms/30ms) 40 sample sub-blocks */
/* The two/four (20ms/30ms) 40 sample sub-blocks */
for (i=0; i<iLBCenc_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { packsplit(cb_index+i*CB_NSTAGES+k, &firstpart, cb_index+i*CB_NSTAGES+k, iLBCenc_inst->ULP_inst->cb_index[i][k][ulp], iLBCenc_inst->ULP_inst->cb_index[i][k][ulp]+ iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+1]+ iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->cb_index[i][k][ulp], &pos); } }
for (i=0; i<iLBCenc_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { packsplit(cb_index+i*CB_NSTAGES+k, &firstpart, cb_index+i*CB_NSTAGES+k, iLBCenc_inst->ULP_inst->cb_index[i][k][ulp], iLBCenc_inst->ULP_inst->cb_index[i][k][ulp]+ iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+1]+ iLBCenc_inst->ULP_inst->cb_index[i][k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->cb_index[i][k][ulp], &pos); } }
for (i=0; i<iLBCenc_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { packsplit(gain_index+i*CB_NSTAGES+k, &firstpart, gain_index+i*CB_NSTAGES+k, iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp], iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp]+
for (i=0; i<iLBCenc_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { packsplit(gain_index+i*CB_NSTAGES+k, &firstpart, gain_index+i*CB_NSTAGES+k, iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp], iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp]+
iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+1]+ iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp], &pos); } } }
iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+1]+ iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp+2]); dopack( &pbytes, firstpart, iLBCenc_inst->ULP_inst->cb_gain[i][k][ulp], &pos); } } }
/* set the last bit to zero (otherwise the decoder will treat it as a lost frame) */ dopack( &pbytes, 0, 1, &pos); }
/* set the last bit to zero (otherwise the decoder will treat it as a lost frame) */ dopack( &pbytes, 0, 1, &pos); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iLBC_decode.h
iLBC_解码.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_ILBCDECODE_H #define __iLBC_ILBCDECODE_H
#ifndef __iLBC_ILBCDECODE_H #define __iLBC_ILBCDECODE_H
#include "iLBC_define.h"
#包括“iLBC_define.h”
short initDecode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ int mode, /* (i) frame size mode */ int use_enhancer /* (i) 1 to use enhancer 0 to run without enhancer */ );
short initDecode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ int mode, /* (i) frame size mode */ int use_enhancer /* (i) 1 to use enhancer 0 to run without enhancer */ );
void iLBC_decode( float *decblock, /* (o) decoded signal block */ unsigned char *bytes, /* (i) encoded signal bits */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state structure */ int mode /* (i) 0: bad packet, PLC, 1: normal */
void iLBC_decode( float *decblock, /* (o) decoded signal block */ unsigned char *bytes, /* (i) encoded signal bits */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state structure */ int mode /* (i) 0: bad packet, PLC, 1: normal */
);
);
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iLBC_decode.c
iLBC_解码.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <stdlib.h>
#include <math.h> #include <stdlib.h>
#include "iLBC_define.h" #include "StateConstructW.h" #include "LPCdecode.h" #include "iCBConstruct.h" #include "doCPLC.h" #include "helpfun.h" #include "constants.h" #include "packing.h" #include "string.h" #include "enhancer.h" #include "hpOutput.h" #include "syntFilter.h"
#包括“iLBC_define.h”#包括“StateConstructW.h”#包括“LPCdecode.h”#包括“iCBConstruct.h”#包括“doCPLC.h”#包括“helpfun.h”#包括“constants.h”#包括“packing.h”#包括“string.h”#包括“enhancer.h”#包括“hpOutput.h”#包括“syntFilter.h”
/*----------------------------------------------------------------* * Initiation of decoder instance. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Initiation of decoder instance. *---------------------------------------------------------------*/
short initDecode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ int mode, /* (i) frame size mode */ int use_enhancer /* (i) 1 to use enhancer 0 to run without enhancer */ ){ int i;
short initDecode( /* (o) Number of decoded samples */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) Decoder instance */ int mode, /* (i) frame size mode */ int use_enhancer /* (i) 1 to use enhancer 0 to run without enhancer */ ){ int i;
iLBCdec_inst->mode = mode;
iLBCdec_inst->mode = mode;
if (mode==30) { iLBCdec_inst->blockl = BLOCKL_30MS; iLBCdec_inst->nsub = NSUB_30MS; iLBCdec_inst->nasub = NASUB_30MS; iLBCdec_inst->lpc_n = LPC_N_30MS; iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS; iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS; iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS; /* ULP init */ iLBCdec_inst->ULP_inst=&ULP_30msTbl; } else if (mode==20) { iLBCdec_inst->blockl = BLOCKL_20MS; iLBCdec_inst->nsub = NSUB_20MS; iLBCdec_inst->nasub = NASUB_20MS; iLBCdec_inst->lpc_n = LPC_N_20MS; iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS; iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS; iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS; /* ULP init */ iLBCdec_inst->ULP_inst=&ULP_20msTbl; } else { exit(2); }
if (mode==30) { iLBCdec_inst->blockl = BLOCKL_30MS; iLBCdec_inst->nsub = NSUB_30MS; iLBCdec_inst->nasub = NASUB_30MS; iLBCdec_inst->lpc_n = LPC_N_30MS; iLBCdec_inst->no_of_bytes = NO_OF_BYTES_30MS; iLBCdec_inst->no_of_words = NO_OF_WORDS_30MS; iLBCdec_inst->state_short_len=STATE_SHORT_LEN_30MS; /* ULP init */ iLBCdec_inst->ULP_inst=&ULP_30msTbl; } else if (mode==20) { iLBCdec_inst->blockl = BLOCKL_20MS; iLBCdec_inst->nsub = NSUB_20MS; iLBCdec_inst->nasub = NASUB_20MS; iLBCdec_inst->lpc_n = LPC_N_20MS; iLBCdec_inst->no_of_bytes = NO_OF_BYTES_20MS; iLBCdec_inst->no_of_words = NO_OF_WORDS_20MS; iLBCdec_inst->state_short_len=STATE_SHORT_LEN_20MS; /* ULP init */ iLBCdec_inst->ULP_inst=&ULP_20msTbl; } else { exit(2); }
memset(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER*sizeof(float)); memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl, LPC_FILTERORDER*sizeof(float));
memset(iLBCdec_inst->syntMem, 0, LPC_FILTERORDER*sizeof(float)); memcpy((*iLBCdec_inst).lsfdeqold, lsfmeanTbl, LPC_FILTERORDER*sizeof(float));
memset(iLBCdec_inst->old_syntdenum, 0, ((LPC_FILTERORDER + 1)*NSUB_MAX)*sizeof(float)); for (i=0; i<NSUB_MAX; i++) iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0;
memset(iLBCdec_inst->old_syntdenum, 0, ((LPC_FILTERORDER + 1)*NSUB_MAX)*sizeof(float)); for (i=0; i<NSUB_MAX; i++) iLBCdec_inst->old_syntdenum[i*(LPC_FILTERORDER+1)]=1.0;
iLBCdec_inst->last_lag = 20;
iLBCdec_inst->last_lag = 20;
iLBCdec_inst->prevLag = 120; iLBCdec_inst->per = 0.0; iLBCdec_inst->consPLICount = 0; iLBCdec_inst->prevPLI = 0; iLBCdec_inst->prevLpc[0] = 1.0; memset(iLBCdec_inst->prevLpc+1,0, LPC_FILTERORDER*sizeof(float)); memset(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX*sizeof(float)); iLBCdec_inst->seed=777;
iLBCdec_inst->prevLag = 120; iLBCdec_inst->per = 0.0; iLBCdec_inst->consPLICount = 0; iLBCdec_inst->prevPLI = 0; iLBCdec_inst->prevLpc[0] = 1.0; memset(iLBCdec_inst->prevLpc+1,0, LPC_FILTERORDER*sizeof(float)); memset(iLBCdec_inst->prevResidual, 0, BLOCKL_MAX*sizeof(float)); iLBCdec_inst->seed=777;
memset(iLBCdec_inst->hpomem, 0, 4*sizeof(float));
memset(iLBCdec_inst->hpomem, 0, 4*sizeof(float));
iLBCdec_inst->use_enhancer = use_enhancer; memset(iLBCdec_inst->enh_buf, 0, ENH_BUFL*sizeof(float)); for (i=0;i<ENH_NBLOCKS_TOT;i++) iLBCdec_inst->enh_period[i]=(float)40.0;
iLBCdec_inst->use_enhancer = use_enhancer; memset(iLBCdec_inst->enh_buf, 0, ENH_BUFL*sizeof(float)); for (i=0;i<ENH_NBLOCKS_TOT;i++) iLBCdec_inst->enh_period[i]=(float)40.0;
iLBCdec_inst->prev_enh_pl = 0;
iLBCdec_inst->prev_enh_pl = 0;
return (iLBCdec_inst->blockl); }
return (iLBCdec_inst->blockl); }
/*----------------------------------------------------------------* * frame residual decoder function (subrutine to iLBC_decode) *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * frame residual decoder function (subrutine to iLBC_decode) *---------------------------------------------------------------*/
void Decode( iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state structure */ float *decresidual, /* (o) decoded residual frame */ int start, /* (i) location of start state */ int idxForMax, /* (i) codebook index for the maximum value */ int *idxVec, /* (i) codebook indexes for the samples in the start state */ float *syntdenum, /* (i) the decoded synthesis filter coefficients */ int *cb_index, /* (i) the indexes for the adaptive codebook */ int *gain_index, /* (i) the indexes for the corresponding gains */ int *extra_cb_index, /* (i) the indexes for the adaptive codebook part of start state */ int *extra_gain_index, /* (i) the indexes for the corresponding gains */ int state_first /* (i) 1 if non adaptive part of start state comes first 0 if that part comes last */ ){ float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML]; int k, meml_gotten, Nfor, Nback, i; int diff, start_pos; int subcount, subframe;
void Decode( iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state structure */ float *decresidual, /* (o) decoded residual frame */ int start, /* (i) location of start state */ int idxForMax, /* (i) codebook index for the maximum value */ int *idxVec, /* (i) codebook indexes for the samples in the start state */ float *syntdenum, /* (i) the decoded synthesis filter coefficients */ int *cb_index, /* (i) the indexes for the adaptive codebook */ int *gain_index, /* (i) the indexes for the corresponding gains */ int *extra_cb_index, /* (i) the indexes for the adaptive codebook part of start state */ int *extra_gain_index, /* (i) the indexes for the corresponding gains */ int state_first /* (i) 1 if non adaptive part of start state comes first 0 if that part comes last */ ){ float reverseDecresidual[BLOCKL_MAX], mem[CB_MEML]; int k, meml_gotten, Nfor, Nback, i; int diff, start_pos; int subcount, subframe;
diff = STATE_LEN - iLBCdec_inst->state_short_len;
diff = STATE_LEN - iLBCdec_inst->state_short_len;
if (state_first == 1) { start_pos = (start-1)*SUBL; } else { start_pos = (start-1)*SUBL + diff; }
if (state_first == 1) { start_pos = (start-1)*SUBL; } else { start_pos = (start-1)*SUBL + diff; }
/* decode scalar part of start state */
/* decode scalar part of start state */
StateConstructW(idxForMax, idxVec, &syntdenum[(start-1)*(LPC_FILTERORDER+1)], &decresidual[start_pos], iLBCdec_inst->state_short_len);
StateConstructW(idxForMax, idxVec, &syntdenum[(start-1)*(LPC_FILTERORDER+1)], &decresidual[start_pos], iLBCdec_inst->state_short_len);
if (state_first) { /* put adaptive part in the end */
if (state_first) { /* put adaptive part in the end */
/* setup memory */
/* setup memory */
memset(mem, 0, (CB_MEML-iLBCdec_inst->state_short_len)*sizeof(float)); memcpy(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos, iLBCdec_inst->state_short_len*sizeof(float));
memset(mem, 0, (CB_MEML-iLBCdec_inst->state_short_len)*sizeof(float)); memcpy(mem+CB_MEML-iLBCdec_inst->state_short_len, decresidual+start_pos, iLBCdec_inst->state_short_len*sizeof(float));
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct( &decresidual[start_pos+iLBCdec_inst->state_short_len], extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);
iCBConstruct(&decresidual[start\u pos+iLBCdec\u inst->state\u short\u len]、额外cb\u指数、额外增益指数、mem+cb\u MEML-STMMLTBL、STMMLTBL、diff、cb\u装置);
} else {/* put adaptive part in the beginning */
} else {/* put adaptive part in the beginning */
/* create reversed vectors for prediction */
/* create reversed vectors for prediction */
for (k=0; k<diff; k++) { reverseDecresidual[k] = decresidual[(start+1)*SUBL-1- (k+iLBCdec_inst->state_short_len)]; }
for (k=0; k<diff; k++) { reverseDecresidual[k] = decresidual[(start+1)*SUBL-1- (k+iLBCdec_inst->state_short_len)]; }
/* setup memory */
/* setup memory */
meml_gotten = iLBCdec_inst->state_short_len; for (k=0; k<meml_gotten; k++){ mem[CB_MEML-1-k] = decresidual[start_pos + k];
meml_gotten = iLBCdec_inst->state_short_len; for (k=0; k<meml_gotten; k++){ mem[CB_MEML-1-k] = decresidual[start_pos + k];
} memset(mem, 0, (CB_MEML-k)*sizeof(float));
} memset(mem, 0, (CB_MEML-k)*sizeof(float));
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct(reverseDecresidual, extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);
iCBConstruct(反向个体、额外cb指数、额外增益指数、mem+cb MEML-stMemLTbl、stMemLTbl、差异、cb装置);
/* get decoded residual from reversed vector */
/* get decoded residual from reversed vector */
for (k=0; k<diff; k++) { decresidual[start_pos-1-k] = reverseDecresidual[k]; } }
for (k=0; k<diff; k++) { decresidual[start_pos-1-k] = reverseDecresidual[k]; } }
/* counter for predicted sub-frames */
/* counter for predicted sub-frames */
subcount=0;
次计数=0;
/* forward prediction of sub-frames */
/* forward prediction of sub-frames */
Nfor = iLBCdec_inst->nsub-start-1;
Nfor = iLBCdec_inst->nsub-start-1;
if ( Nfor > 0 ){
如果(n>0){
/* setup memory */
/* setup memory */
memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, STATE_LEN*sizeof(float));
memset(mem, 0, (CB_MEML-STATE_LEN)*sizeof(float)); memcpy(mem+CB_MEML-STATE_LEN, decresidual+(start-1)*SUBL, STATE_LEN*sizeof(float));
/* loop over sub-frames to encode */
/* loop over sub-frames to encode */
for (subframe=0; subframe<Nfor; subframe++) {
for (subframe=0; subframe<Nfor; subframe++) {
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct(&decresidual[(start+1+subframe)*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
iCBConstruct(&decresidual[(start+1+subframe)*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
/* update memory */
/* update memory */
memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); memcpy(mem+CB_MEML-SUBL,
memcpy(mem,mem+SUBL,(CB_MEML-SUBL)*sizeof(float));memcpy(mem+CB_MEML-SUBL,
&decresidual[(start+1+subframe)*SUBL], SUBL*sizeof(float));
&decresidual[(start+1+subframe)*SUBL], SUBL*sizeof(float));
subcount++;
subcount++;
}
}
}
}
/* backward prediction of sub-frames */
/* backward prediction of sub-frames */
Nback = start-1;
Nback=start-1;
if ( Nback > 0 ) {
如果(Nback>0){
/* setup memory */
/* setup memory */
meml_gotten = SUBL*(iLBCdec_inst->nsub+1-start);
meml_gotten = SUBL*(iLBCdec_inst->nsub+1-start);
if ( meml_gotten > CB_MEML ) { meml_gotten=CB_MEML; } for (k=0; k<meml_gotten; k++) { mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; } memset(mem, 0, (CB_MEML-k)*sizeof(float));
if ( meml_gotten > CB_MEML ) { meml_gotten=CB_MEML; } for (k=0; k<meml_gotten; k++) { mem[CB_MEML-1-k] = decresidual[(start-1)*SUBL + k]; } memset(mem, 0, (CB_MEML-k)*sizeof(float));
/* loop over subframes to decode */
/* loop over subframes to decode */
for (subframe=0; subframe<Nback; subframe++) {
for (subframe=0; subframe<Nback; subframe++) {
/* construct decoded vector */
/* construct decoded vector */
iCBConstruct(&reverseDecresidual[subframe*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
iCBConstruct(&reverseDecresidual[subframe*SUBL], cb_index+subcount*CB_NSTAGES, gain_index+subcount*CB_NSTAGES, mem+CB_MEML-memLfTbl[subcount], memLfTbl[subcount], SUBL, CB_NSTAGES);
/* update memory */
/* update memory */
memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); memcpy(mem+CB_MEML-SUBL, &reverseDecresidual[subframe*SUBL], SUBL*sizeof(float));
memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float)); memcpy(mem+CB_MEML-SUBL, &reverseDecresidual[subframe*SUBL], SUBL*sizeof(float));
subcount++; }
subcount++; }
/* get decoded residual from reversed vector */
/* get decoded residual from reversed vector */
for (i=0; i<SUBL*Nback; i++) decresidual[SUBL*Nback - i - 1] = reverseDecresidual[i]; } }
for (i=0; i<SUBL*Nback; i++) decresidual[SUBL*Nback - i - 1] = reverseDecresidual[i]; } }
/*----------------------------------------------------------------* * main decoder function *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * main decoder function *---------------------------------------------------------------*/
void iLBC_decode( float *decblock, /* (o) decoded signal block */ unsigned char *bytes, /* (i) encoded signal bits */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state structure */ int mode /* (i) 0: bad packet, PLC, 1: normal */ ){ float data[BLOCKL_MAX]; float lsfdeq[LPC_FILTERORDER*LPC_N_MAX]; float PLCresidual[BLOCKL_MAX], PLClpc[LPC_FILTERORDER + 1]; float zeros[BLOCKL_MAX], one[LPC_FILTERORDER + 1]; int k, i, start, idxForMax, pos, lastpart, ulp; int lag, ilag; float cc, maxcc; int idxVec[STATE_LEN]; int check; int gain_index[NASUB_MAX*CB_NSTAGES], extra_gain_index[CB_NSTAGES]; int cb_index[CB_NSTAGES*NASUB_MAX], extra_cb_index[CB_NSTAGES]; int lsf_i[LSF_NSPLIT*LPC_N_MAX]; int state_first; int last_bit; unsigned char *pbytes; float weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX]; int order_plus_one; float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; float decresidual[BLOCKL_MAX];
void iLBC_decode( float *decblock, /* (o) decoded signal block */ unsigned char *bytes, /* (i) encoded signal bits */ iLBC_Dec_Inst_t *iLBCdec_inst, /* (i/o) the decoder state structure */ int mode /* (i) 0: bad packet, PLC, 1: normal */ ){ float data[BLOCKL_MAX]; float lsfdeq[LPC_FILTERORDER*LPC_N_MAX]; float PLCresidual[BLOCKL_MAX], PLClpc[LPC_FILTERORDER + 1]; float zeros[BLOCKL_MAX], one[LPC_FILTERORDER + 1]; int k, i, start, idxForMax, pos, lastpart, ulp; int lag, ilag; float cc, maxcc; int idxVec[STATE_LEN]; int check; int gain_index[NASUB_MAX*CB_NSTAGES], extra_gain_index[CB_NSTAGES]; int cb_index[CB_NSTAGES*NASUB_MAX], extra_cb_index[CB_NSTAGES]; int lsf_i[LSF_NSPLIT*LPC_N_MAX]; int state_first; int last_bit; unsigned char *pbytes; float weightdenum[(LPC_FILTERORDER + 1)*NSUB_MAX]; int order_plus_one; float syntdenum[NSUB_MAX*(LPC_FILTERORDER+1)]; float decresidual[BLOCKL_MAX];
if (mode>0) { /* the data are good */
if (mode>0) { /* the data are good */
/* decode data */
/* decode data */
pbytes=bytes; pos=0;
pbytes=bytes; pos=0;
/* Set everything to zero before decoding */
/* Set everything to zero before decoding */
for (k=0; k<LSF_NSPLIT*LPC_N_MAX; k++) { lsf_i[k]=0; } start=0; state_first=0; idxForMax=0; for (k=0; k<iLBCdec_inst->state_short_len; k++) { idxVec[k]=0; } for (k=0; k<CB_NSTAGES; k++) { extra_cb_index[k]=0; } for (k=0; k<CB_NSTAGES; k++) { extra_gain_index[k]=0; } for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { cb_index[i*CB_NSTAGES+k]=0; } } for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { gain_index[i*CB_NSTAGES+k]=0; } }
for (k=0; k<LSF_NSPLIT*LPC_N_MAX; k++) { lsf_i[k]=0; } start=0; state_first=0; idxForMax=0; for (k=0; k<iLBCdec_inst->state_short_len; k++) { idxVec[k]=0; } for (k=0; k<CB_NSTAGES; k++) { extra_cb_index[k]=0; } for (k=0; k<CB_NSTAGES; k++) { extra_gain_index[k]=0; } for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { cb_index[i*CB_NSTAGES+k]=0; } } for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { gain_index[i*CB_NSTAGES+k]=0; } }
/* loop over ULP classes */
/* loop over ULP classes */
for (ulp=0; ulp<3; ulp++) {
for (ulp=0; ulp<3; ulp++) {
/* LSF */ for (k=0; k<LSF_NSPLIT*iLBCdec_inst->lpc_n; k++){ unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->lsf_bits[k][ulp], &pos); packcombine(&lsf_i[k], lastpart, iLBCdec_inst->ULP_inst->lsf_bits[k][ulp]); }
/* LSF */ for (k=0; k<LSF_NSPLIT*iLBCdec_inst->lpc_n; k++){ unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->lsf_bits[k][ulp], &pos); packcombine(&lsf_i[k], lastpart, iLBCdec_inst->ULP_inst->lsf_bits[k][ulp]); }
/* Start block info */
/* Start block info */
unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->start_bits[ulp], &pos); packcombine(&start, lastpart, iLBCdec_inst->ULP_inst->start_bits[ulp]);
unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->start_bits[ulp], &pos); packcombine(&start, lastpart, iLBCdec_inst->ULP_inst->start_bits[ulp]);
unpack( &pbytes, &lastpart,
拆包(&pbytes,&lastpart),
iLBCdec_inst->ULP_inst->startfirst_bits[ulp], &pos); packcombine(&state_first, lastpart, iLBCdec_inst->ULP_inst->startfirst_bits[ulp]);
iLBCdec_inst->ULP_inst->startfirst_bits[ulp], &pos); packcombine(&state_first, lastpart, iLBCdec_inst->ULP_inst->startfirst_bits[ulp]);
unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->scale_bits[ulp], &pos); packcombine(&idxForMax, lastpart, iLBCdec_inst->ULP_inst->scale_bits[ulp]);
unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->scale_bits[ulp], &pos); packcombine(&idxForMax, lastpart, iLBCdec_inst->ULP_inst->scale_bits[ulp]);
for (k=0; k<iLBCdec_inst->state_short_len; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->state_bits[ulp], &pos); packcombine(idxVec+k, lastpart, iLBCdec_inst->ULP_inst->state_bits[ulp]); }
for (k=0; k<iLBCdec_inst->state_short_len; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->state_bits[ulp], &pos); packcombine(idxVec+k, lastpart, iLBCdec_inst->ULP_inst->state_bits[ulp]); }
/* 23/22 (20ms/30ms) sample block */
/* 23/22 (20ms/30ms) sample block */
for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp], &pos); packcombine(extra_cb_index+k, lastpart, iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp]); } for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp], &pos); packcombine(extra_gain_index+k, lastpart, iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp]); }
for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp], &pos); packcombine(extra_cb_index+k, lastpart, iLBCdec_inst->ULP_inst->extra_cb_index[k][ulp]); } for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp], &pos); packcombine(extra_gain_index+k, lastpart, iLBCdec_inst->ULP_inst->extra_cb_gain[k][ulp]); }
/* The two/four (20ms/30ms) 40 sample sub-blocks */
/* The two/four (20ms/30ms) 40 sample sub-blocks */
for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->cb_index[i][k][ulp], &pos); packcombine(cb_index+i*CB_NSTAGES+k, lastpart, iLBCdec_inst->ULP_inst->cb_index[i][k][ulp]); } }
for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart, iLBCdec_inst->ULP_inst->cb_index[i][k][ulp], &pos); packcombine(cb_index+i*CB_NSTAGES+k, lastpart, iLBCdec_inst->ULP_inst->cb_index[i][k][ulp]); } }
for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart,
for (i=0; i<iLBCdec_inst->nasub; i++) { for (k=0; k<CB_NSTAGES; k++) { unpack( &pbytes, &lastpart,
iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp], &pos); packcombine(gain_index+i*CB_NSTAGES+k, lastpart, iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp]); } } } /* Extract last bit. If it is 1 this indicates an empty/lost frame */ unpack( &pbytes, &last_bit, 1, &pos);
iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp], &pos); packcombine(gain_index+i*CB_NSTAGES+k, lastpart, iLBCdec_inst->ULP_inst->cb_gain[i][k][ulp]); } } } /* Extract last bit. If it is 1 this indicates an empty/lost frame */ unpack( &pbytes, &last_bit, 1, &pos);
/* Check for bit errors or empty/lost frames */ if (start<1) mode = 0; if (iLBCdec_inst->mode==20 && start>3) mode = 0; if (iLBCdec_inst->mode==30 && start>5) mode = 0; if (last_bit==1) mode = 0;
/* Check for bit errors or empty/lost frames */ if (start<1) mode = 0; if (iLBCdec_inst->mode==20 && start>3) mode = 0; if (iLBCdec_inst->mode==30 && start>5) mode = 0; if (last_bit==1) mode = 0;
if (mode==1) { /* No bit errors was detected, continue decoding */
if (mode==1) { /* No bit errors was detected, continue decoding */
/* adjust index */ index_conv_dec(cb_index);
/* adjust index */ index_conv_dec(cb_index);
/* decode the lsf */
/* decode the lsf */
SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n); check=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n); DecoderInterpolateLSF(syntdenum, weightdenum, lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n); check=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCdec_inst->lpc_n); DecoderInterpolateLSF(syntdenum, weightdenum, lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
Decode(iLBCdec_inst, decresidual, start, idxForMax, idxVec, syntdenum, cb_index, gain_index, extra_cb_index, extra_gain_index, state_first);
解码(iLBCdec_inst、decresidual、start、idxForMax、idxVec、syntdenum、cb_索引、gain_索引、extra_cb_索引、extra_gain_索引、state_first);
/* preparing the plc for a future loss! */
/* preparing the plc for a future loss! */
doThePLC(PLCresidual, PLClpc, 0, decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1), (*iLBCdec_inst).last_lag, iLBCdec_inst);
doThePLC(PLCresidual, PLClpc, 0, decresidual, syntdenum + (LPC_FILTERORDER + 1)*(iLBCdec_inst->nsub - 1), (*iLBCdec_inst).last_lag, iLBCdec_inst);
memcpy(decresidual, PLCresidual, iLBCdec_inst->blockl*sizeof(float)); }
memcpy(decresidual, PLCresidual, iLBCdec_inst->blockl*sizeof(float)); }
}
}
if (mode == 0) { /* the data is bad (either a PLC call * was made or a severe bit error was detected) */
if (mode == 0) { /* the data is bad (either a PLC call * was made or a severe bit error was detected) */
/* packet loss conceal */
/* packet loss conceal */
memset(zeros, 0, BLOCKL_MAX*sizeof(float));
memset(zeros, 0, BLOCKL_MAX*sizeof(float));
one[0] = 1; memset(one+1, 0, LPC_FILTERORDER*sizeof(float));
one[0] = 1; memset(one+1, 0, LPC_FILTERORDER*sizeof(float));
start=0;
开始=0;
doThePLC(PLCresidual, PLClpc, 1, zeros, one, (*iLBCdec_inst).last_lag, iLBCdec_inst); memcpy(decresidual, PLCresidual, iLBCdec_inst->blockl*sizeof(float));
doThePLC(PLCresidual, PLClpc, 1, zeros, one, (*iLBCdec_inst).last_lag, iLBCdec_inst); memcpy(decresidual, PLCresidual, iLBCdec_inst->blockl*sizeof(float));
order_plus_one = LPC_FILTERORDER + 1; for (i = 0; i < iLBCdec_inst->nsub; i++) { memcpy(syntdenum+(i*order_plus_one), PLClpc, order_plus_one*sizeof(float)); } }
order_plus_one = LPC_FILTERORDER + 1; for (i = 0; i < iLBCdec_inst->nsub; i++) { memcpy(syntdenum+(i*order_plus_one), PLClpc, order_plus_one*sizeof(float)); } }
if (iLBCdec_inst->use_enhancer == 1) {
if (iLBCdec_inst->use_enhancer == 1) {
/* post filtering */
/* post filtering */
iLBCdec_inst->last_lag = enhancerInterface(data, decresidual, iLBCdec_inst);
iLBCdec_inst->last_lag = enhancerInterface(data, decresidual, iLBCdec_inst);
/* synthesis filtering */
/* synthesis filtering */
if (iLBCdec_inst->mode==20) { /* Enhancer has 40 samples delay */ i=0; syntFilter(data + i*SUBL, iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem);
if (iLBCdec_inst->mode==20) { /* Enhancer has 40 samples delay */ i=0; syntFilter(data + i*SUBL, iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-1)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem);
for (i=1; i < iLBCdec_inst->nsub; i++) { syntFilter(data + i*SUBL, syntdenum + (i-1)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); } } else if (iLBCdec_inst->mode==30) { /* Enhancer has 80 samples delay */ for (i=0; i < 2; i++) { syntFilter(data + i*SUBL, iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-2)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); } for (i=2; i < iLBCdec_inst->nsub; i++) { syntFilter(data + i*SUBL, syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); } }
for (i=1; i < iLBCdec_inst->nsub; i++) { syntFilter(data + i*SUBL, syntdenum + (i-1)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); } } else if (iLBCdec_inst->mode==30) { /* Enhancer has 80 samples delay */ for (i=0; i < 2; i++) { syntFilter(data + i*SUBL, iLBCdec_inst->old_syntdenum + (i+iLBCdec_inst->nsub-2)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); } for (i=2; i < iLBCdec_inst->nsub; i++) { syntFilter(data + i*SUBL, syntdenum + (i-2)*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); } }
} else {
}否则{
/* Find last lag */ lag = 20; maxcc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL], &decresidual[BLOCKL_MAX-ENH_BLOCKL-lag], ENH_BLOCKL);
/* Find last lag */ lag = 20; maxcc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL], &decresidual[BLOCKL_MAX-ENH_BLOCKL-lag], ENH_BLOCKL);
for (ilag=21; ilag<120; ilag++) { cc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL], &decresidual[BLOCKL_MAX-ENH_BLOCKL-ilag], ENH_BLOCKL);
for (ilag=21; ilag<120; ilag++) { cc = xCorrCoef(&decresidual[BLOCKL_MAX-ENH_BLOCKL], &decresidual[BLOCKL_MAX-ENH_BLOCKL-ilag], ENH_BLOCKL);
if (cc > maxcc) { maxcc = cc; lag = ilag; } } iLBCdec_inst->last_lag = lag;
if (cc > maxcc) { maxcc = cc; lag = ilag; } } iLBCdec_inst->last_lag = lag;
/* copy data and run synthesis filter */
/* copy data and run synthesis filter */
memcpy(data, decresidual, iLBCdec_inst->blockl*sizeof(float)); for (i=0; i < iLBCdec_inst->nsub; i++) { syntFilter(data + i*SUBL, syntdenum + i*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); }
memcpy(data, decresidual, iLBCdec_inst->blockl*sizeof(float)); for (i=0; i < iLBCdec_inst->nsub; i++) { syntFilter(data + i*SUBL, syntdenum + i*(LPC_FILTERORDER+1), SUBL, iLBCdec_inst->syntMem); }
}
}
/* high pass filtering on output if desired, otherwise copy to out */
/* high pass filtering on output if desired, otherwise copy to out */
hpOutput(data, iLBCdec_inst->blockl, decblock,iLBCdec_inst->hpomem);
hpOutput(data, iLBCdec_inst->blockl, decblock,iLBCdec_inst->hpomem);
/* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/
/* memcpy(decblock,data,iLBCdec_inst->blockl*sizeof(float));*/
memcpy(iLBCdec_inst->old_syntdenum, syntdenum,
memcpy(iLBCdec_inst->old_syntdenum,syntdenum,
iLBCdec_inst->nsub*(LPC_FILTERORDER+1)*sizeof(float));
iLBCdec_inst->nsub*(LPC_FILTERORDER+1)*sizeof(float));
iLBCdec_inst->prev_enh_pl=0;
iLBCdec_inst->prev_enh_pl=0;
if (mode==0) { /* PLC was used */ iLBCdec_inst->prev_enh_pl=1; } }
if (mode==0) { /* PLC was used */ iLBCdec_inst->prev_enh_pl=1; } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iLBC_define.h
iLBC_define.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/ #include <string.h>
******************************************************************/ #include <string.h>
#ifndef __iLBC_ILBCDEFINE_H #define __iLBC_ILBCDEFINE_H
#ifndef __iLBC_ILBCDEFINE_H #define __iLBC_ILBCDEFINE_H
/* general codec settings */
/* general codec settings */
#define FS (float)8000.0 #define BLOCKL_20MS 160 #define BLOCKL_30MS 240 #define BLOCKL_MAX 240 #define NSUB_20MS 4 #define NSUB_30MS 6 #define NSUB_MAX 6 #define NASUB_20MS 2
#定义FS(浮动)8000.0#定义区块20毫秒160#定义区块30毫秒240#定义区块最大240#定义NSUB#U 20毫秒4#定义NSUB#U 30毫秒6#定义NSUB#U最大6#定义NASUB#U 20毫秒2
#define NASUB_30MS 4 #define NASUB_MAX 4 #define SUBL 40 #define STATE_LEN 80 #define STATE_SHORT_LEN_30MS 58 #define STATE_SHORT_LEN_20MS 57
#定义NASUB_30MS 4#定义NASUB_MAX 4#定义SUBL 40#定义STATE_LEN 80#定义STATE_LEN_30MS 58#定义STATE_LEN_20MS 57
/* LPC settings */
/* LPC settings */
#define LPC_FILTERORDER 10 #define LPC_CHIRP_SYNTDENUM (float)0.9025 #define LPC_CHIRP_WEIGHTDENUM (float)0.4222 #define LPC_LOOKBACK 60 #define LPC_N_20MS 1 #define LPC_N_30MS 2 #define LPC_N_MAX 2 #define LPC_ASYMDIFF 20 #define LPC_BW (float)60.0 #define LPC_WN (float)1.0001 #define LSF_NSPLIT 3 #define LSF_NUMBER_OF_STEPS 4 #define LPC_HALFORDER (LPC_FILTERORDER/2)
#定义LPC_过滤器顺序10#定义LPC_CHIRP_SYNTDENUM(float)0.9025#定义LPC_CHIRP_weightednum(float)0.4222#定义LPC_LOOKBACK 60#定义LPC_N_20MS 1#定义LPC_N_30MS 2#定义LPC_N_MAX 2#定义LPC#u asyff 20#定义LPC#N#定义LPU float1.0001#定义LSF#NSPLIT 3#定义LSF#步骤数#4#定义LPC#U半顺序(LPC#U过滤器顺序/2)
/* cb settings */
/* cb settings */
#define CB_NSTAGES 3 #define CB_EXPAND 2 #define CB_MEML 147 #define CB_FILTERLEN 2*4 #define CB_HALFFILTERLEN 4 #define CB_RESRANGE 34 #define CB_MAXGAIN (float)1.3
#定义CB#U安装阶段3#定义CB#U扩展2#定义CB#U内存147#定义CB#U过滤器长度2*4#定义CB#U半过滤器长度4#定义CB#U重新范围34#定义CB#U最大增益(浮点)1.3
/* enhancer */
/* enhancer */
#define ENH_BLOCKL 80 /* block length */ #define ENH_BLOCKL_HALF (ENH_BLOCKL/2) #define ENH_HL 3 /* 2*ENH_HL+1 is number blocks in said second sequence */ #define ENH_SLOP 2 /* max difference estimated and correct pitch period */ #define ENH_PLOCSL 20 /* pitch-estimates and pitch- locations buffer length */ #define ENH_OVERHANG 2 #define ENH_UPS0 4 /* upsampling rate */ #define ENH_FL0 3 /* 2*FLO+1 is the length of each filter */ #define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0)
#define ENH_BLOCKL 80 /* block length */ #define ENH_BLOCKL_HALF (ENH_BLOCKL/2) #define ENH_HL 3 /* 2*ENH_HL+1 is number blocks in said second sequence */ #define ENH_SLOP 2 /* max difference estimated and correct pitch period */ #define ENH_PLOCSL 20 /* pitch-estimates and pitch- locations buffer length */ #define ENH_OVERHANG 2 #define ENH_UPS0 4 /* upsampling rate */ #define ENH_FL0 3 /* 2*FLO+1 is the length of each filter */ #define ENH_VECTL (ENH_BLOCKL+2*ENH_FL0)
#define ENH_CORRDIM (2*ENH_SLOP+1) #define ENH_NBLOCKS (BLOCKL_MAX/ENH_BLOCKL) #define ENH_NBLOCKS_EXTRA 5 #define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS + ENH_NBLOCKS_EXTRA */ #define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL #define ENH_ALPHA0 (float)0.05
#define ENH_CORRDIM (2*ENH_SLOP+1) #define ENH_NBLOCKS (BLOCKL_MAX/ENH_BLOCKL) #define ENH_NBLOCKS_EXTRA 5 #define ENH_NBLOCKS_TOT 8 /* ENH_NBLOCKS + ENH_NBLOCKS_EXTRA */ #define ENH_BUFL (ENH_NBLOCKS_TOT)*ENH_BLOCKL #define ENH_ALPHA0 (float)0.05
/* Down sampling */
/* Down sampling */
#define FILTERORDER_DS 7 #define DELAY_DS 3 #define FACTOR_DS 2
#定义过滤器顺序7#定义延迟3#定义因子2
/* bit stream defs */
/* bit stream defs */
#define NO_OF_BYTES_20MS 38 #define NO_OF_BYTES_30MS 50 #define NO_OF_WORDS_20MS 19 #define NO_OF_WORDS_30MS 25 #define STATE_BITS 3 #define BYTE_LEN 8 #define ULP_CLASSES 3
#定义无字节数38#定义无字节数50#定义无字数19#定义无字数25#定义状态位3#定义字节数8#定义ULP类3
/* help parameters */
/* help parameters */
#define FLOAT_MAX (float)1.0e37 #define EPS (float)2.220446049250313e-016 #define PI (float)3.14159265358979323846 #define MIN_SAMPLE -32768 #define MAX_SAMPLE 32767 #define TWO_PI (float)6.283185307 #define PI2 (float)0.159154943
#定义浮点最大(浮点)1.0e37定义EPS(浮点)2.220446049250313e-016定义PI(浮点)3.14159265358979323846定义最小样本-32768定义最大样本32767定义两个PI(浮点)6.283185307定义PI2(浮点)0.159154943
/* type definition encoder instance */ typedef struct iLBC_ULP_Inst_t_ { int lsf_bits[6][ULP_CLASSES+2]; int start_bits[ULP_CLASSES+2]; int startfirst_bits[ULP_CLASSES+2]; int scale_bits[ULP_CLASSES+2]; int state_bits[ULP_CLASSES+2]; int extra_cb_index[CB_NSTAGES][ULP_CLASSES+2]; int extra_cb_gain[CB_NSTAGES][ULP_CLASSES+2]; int cb_index[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2]; int cb_gain[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2]; } iLBC_ULP_Inst_t;
/* type definition encoder instance */ typedef struct iLBC_ULP_Inst_t_ { int lsf_bits[6][ULP_CLASSES+2]; int start_bits[ULP_CLASSES+2]; int startfirst_bits[ULP_CLASSES+2]; int scale_bits[ULP_CLASSES+2]; int state_bits[ULP_CLASSES+2]; int extra_cb_index[CB_NSTAGES][ULP_CLASSES+2]; int extra_cb_gain[CB_NSTAGES][ULP_CLASSES+2]; int cb_index[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2]; int cb_gain[NSUB_MAX][CB_NSTAGES][ULP_CLASSES+2]; } iLBC_ULP_Inst_t;
/* type definition encoder instance */
/* type definition encoder instance */
typedef struct iLBC_Enc_Inst_t_ {
类型定义结构iLBC_Enc_Inst_{
/* flag for frame size mode */ int mode;
/* flag for frame size mode */ int mode;
/* basic parameters for different frame sizes */ int blockl; int nsub; int nasub; int no_of_bytes, no_of_words; int lpc_n; int state_short_len; const iLBC_ULP_Inst_t *ULP_inst;
/* basic parameters for different frame sizes */ int blockl; int nsub; int nasub; int no_of_bytes, no_of_words; int lpc_n; int state_short_len; const iLBC_ULP_Inst_t *ULP_inst;
/* analysis filter state */ float anaMem[LPC_FILTERORDER];
/* analysis filter state */ float anaMem[LPC_FILTERORDER];
/* old lsf parameters for interpolation */ float lsfold[LPC_FILTERORDER]; float lsfdeqold[LPC_FILTERORDER];
/* old lsf parameters for interpolation */ float lsfold[LPC_FILTERORDER]; float lsfdeqold[LPC_FILTERORDER];
/* signal buffer for LP analysis */ float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];
/* signal buffer for LP analysis */ float lpc_buffer[LPC_LOOKBACK + BLOCKL_MAX];
/* state of input HP filter */ float hpimem[4];
/* state of input HP filter */ float hpimem[4];
} iLBC_Enc_Inst_t;
}iLBC_Enc_Inst;
/* type definition decoder instance */ typedef struct iLBC_Dec_Inst_t_ {
/* type definition decoder instance */ typedef struct iLBC_Dec_Inst_t_ {
/* flag for frame size mode */ int mode;
/* flag for frame size mode */ int mode;
/* basic parameters for different frame sizes */ int blockl; int nsub; int nasub; int no_of_bytes, no_of_words; int lpc_n; int state_short_len; const iLBC_ULP_Inst_t *ULP_inst;
/* basic parameters for different frame sizes */ int blockl; int nsub; int nasub; int no_of_bytes, no_of_words; int lpc_n; int state_short_len; const iLBC_ULP_Inst_t *ULP_inst;
/* synthesis filter state */ float syntMem[LPC_FILTERORDER];
/* synthesis filter state */ float syntMem[LPC_FILTERORDER];
/* old LSF for interpolation */
/* old LSF for interpolation */
float lsfdeqold[LPC_FILTERORDER];
浮点lsfdeqold[LPC_过滤器顺序];
/* pitch lag estimated in enhancer and used in PLC */ int last_lag;
/* pitch lag estimated in enhancer and used in PLC */ int last_lag;
/* PLC state information */ int prevLag, consPLICount, prevPLI, prev_enh_pl; float prevLpc[LPC_FILTERORDER+1]; float prevResidual[NSUB_MAX*SUBL]; float per; unsigned long seed;
/* PLC state information */ int prevLag, consPLICount, prevPLI, prev_enh_pl; float prevLpc[LPC_FILTERORDER+1]; float prevResidual[NSUB_MAX*SUBL]; float per; unsigned long seed;
/* previous synthesis filter parameters */ float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
/* previous synthesis filter parameters */ float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
/* state of output HP filter */ float hpomem[4];
/* state of output HP filter */ float hpomem[4];
/* enhancer state information */ int use_enhancer; float enh_buf[ENH_BUFL]; float enh_period[ENH_NBLOCKS_TOT];
/* enhancer state information */ int use_enhancer; float enh_buf[ENH_BUFL]; float enh_period[ENH_NBLOCKS_TOT];
} iLBC_Dec_Inst_t;
}iLBC_Dec_Inst;
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
constants.h
常数.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_CONSTANTS_H #define __iLBC_CONSTANTS_H
#ifndef __iLBC_CONSTANTS_H #define __iLBC_CONSTANTS_H
#include "iLBC_define.h"
#包括“iLBC_define.h”
/* ULP bit allocation */
/* ULP bit allocation */
extern const iLBC_ULP_Inst_t ULP_20msTbl; extern const iLBC_ULP_Inst_t ULP_30msTbl;
extern const iLBC_ULP_Inst_t ULP_20msTbl; extern const iLBC_ULP_Inst_t ULP_30msTbl;
/* high pass filters */
/* high pass filters */
extern float hpi_zero_coefsTbl[]; extern float hpi_pole_coefsTbl[]; extern float hpo_zero_coefsTbl[]; extern float hpo_pole_coefsTbl[];
extern float hpi_zero_coefsTbl[]; extern float hpi_pole_coefsTbl[]; extern float hpo_zero_coefsTbl[]; extern float hpo_pole_coefsTbl[];
/* low pass filters */ extern float lpFilt_coefsTbl[];
/* low pass filters */ extern float lpFilt_coefsTbl[];
/* LPC analysis and quantization */
/* LPC analysis and quantization */
extern float lpc_winTbl[]; extern float lpc_asymwinTbl[]; extern float lpc_lagwinTbl[]; extern float lsfCbTbl[]; extern float lsfmeanTbl[]; extern int dim_lsfCbTbl[]; extern int size_lsfCbTbl[]; extern float lsf_weightTbl_30ms[]; extern float lsf_weightTbl_20ms[];
extern float lpc_winTbl[]; extern float lpc_asymwinTbl[]; extern float lpc_lagwinTbl[]; extern float lsfCbTbl[]; extern float lsfmeanTbl[]; extern int dim_lsfCbTbl[]; extern int size_lsfCbTbl[]; extern float lsf_weightTbl_30ms[]; extern float lsf_weightTbl_20ms[];
/* state quantization tables */
/* state quantization tables */
extern float state_sq3Tbl[]; extern float state_frgqTbl[];
extern float state_sq3Tbl[]; extern float state_frgqTbl[];
/* gain quantization tables */
/* gain quantization tables */
extern float gain_sq3Tbl[]; extern float gain_sq4Tbl[]; extern float gain_sq5Tbl[];
extern float gain_sq3Tbl[]; extern float gain_sq4Tbl[]; extern float gain_sq5Tbl[];
/* adaptive codebook definitions */
/* adaptive codebook definitions */
extern int search_rangeTbl[5][CB_NSTAGES]; extern int memLfTbl[]; extern int stMemLTbl; extern float cbfiltersTbl[CB_FILTERLEN];
extern int search_rangeTbl[5][CB_NSTAGES]; extern int memLfTbl[]; extern int stMemLTbl; extern float cbfiltersTbl[CB_FILTERLEN];
/* enhancer definitions */
/* enhancer definitions */
extern float polyphaserTbl[]; extern float enh_plocsTbl[];
extern float polyphaserTbl[]; extern float enh_plocsTbl[];
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
constants.c
常数c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#包括“iLBC_define.h”
/* ULP bit allocation */
/* ULP bit allocation */
/* 20 ms frame */
/* 20 ms frame */
const iLBC_ULP_Inst_t ULP_20msTbl = { /* LSF */ { {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}, /* Start state location, gain and samples */ {2,0,0,0,0}, {1,0,0,0,0}, {6,0,0,0,0}, {0,1,2,0,0}, /* extra CB index and extra CB gain */ {{6,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{2,0,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}}, /* CB index and CB gain */ { {{7,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{0,0,8,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}}, { {{1,2,2,0,0}, {1,1,2,0,0}, {0,0,3,0,0}}, {{1,1,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}} };
const iLBC_ULP_Inst_t ULP_20msTbl = { /* LSF */ { {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}, /* Start state location, gain and samples */ {2,0,0,0,0}, {1,0,0,0,0}, {6,0,0,0,0}, {0,1,2,0,0}, /* extra CB index and extra CB gain */ {{6,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{2,0,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}}, /* CB index and CB gain */ { {{7,0,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{0,0,8,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}}, { {{1,2,2,0,0}, {1,1,2,0,0}, {0,0,3,0,0}}, {{1,1,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}, {{0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}}} };
/* 30 ms frame */
/* 30 ms frame */
const iLBC_ULP_Inst_t ULP_30msTbl = { /* LSF */
const iLBC_ULP_Inst_t ULP_30msTbl = { /* LSF */
{ {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}, {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}}, /* Start state location, gain and samples */ {3,0,0,0,0}, {1,0,0,0,0}, {6,0,0,0,0}, {0,1,2,0,0}, /* extra CB index and extra CB gain */ {{4,2,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{1,1,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}}, /* CB index and CB gain */ { {{6,1,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}, {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}, {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}}, { {{1,2,2,0,0}, {1,2,1,0,0}, {0,0,3,0,0}}, {{0,2,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}}, {{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}}, {{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}}} };
{ {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}, {6,0,0,0,0}, {7,0,0,0,0}, {7,0,0,0,0}}, /* Start state location, gain and samples */ {3,0,0,0,0}, {1,0,0,0,0}, {6,0,0,0,0}, {0,1,2,0,0}, /* extra CB index and extra CB gain */ {{4,2,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{1,1,3,0,0}, {1,1,2,0,0}, {0,0,3,0,0}}, /* CB index and CB gain */ { {{6,1,1,0,0}, {0,0,7,0,0}, {0,0,7,0,0}}, {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}, {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}, {{0,7,1,0,0}, {0,0,8,0,0}, {0,0,8,0,0}}}, { {{1,2,2,0,0}, {1,2,1,0,0}, {0,0,3,0,0}}, {{0,2,3,0,0}, {0,2,2,0,0}, {0,0,3,0,0}}, {{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}}, {{0,1,4,0,0}, {0,1,3,0,0}, {0,0,3,0,0}}} };
/* HP Filters */
/* HP Filters */
float hpi_zero_coefsTbl[3] = { (float)0.92727436, (float)-1.8544941, (float)0.92727436 }; float hpi_pole_coefsTbl[3] = { (float)1.0, (float)-1.9059465, (float)0.9114024 }; float hpo_zero_coefsTbl[3] = { (float)0.93980581, (float)-1.8795834, (float)0.93980581 }; float hpo_pole_coefsTbl[3] = { (float)1.0, (float)-1.9330735, (float)0.93589199 };
float hpi_zero_coefsTbl[3] = { (float)0.92727436, (float)-1.8544941, (float)0.92727436 }; float hpi_pole_coefsTbl[3] = { (float)1.0, (float)-1.9059465, (float)0.9114024 }; float hpo_zero_coefsTbl[3] = { (float)0.93980581, (float)-1.8795834, (float)0.93980581 }; float hpo_pole_coefsTbl[3] = { (float)1.0, (float)-1.9330735, (float)0.93589199 };
/* LP Filter */
/* LP Filter */
float lpFilt_coefsTbl[FILTERORDER_DS]={ (float)-0.066650, (float)0.125000, (float)0.316650, (float)0.414063, (float)0.316650, (float)0.125000, (float)-0.066650 };
float lpFilt_coefsTbl[FILTERORDER_DS]={ (float)-0.066650, (float)0.125000, (float)0.316650, (float)0.414063, (float)0.316650, (float)0.125000, (float)-0.066650 };
/* State quantization tables */
/* State quantization tables */
float state_sq3Tbl[8] = { (float)-3.719849, (float)-2.177490, (float)-1.130005,
float state_sq3Tbl[8] = { (float)-3.719849, (float)-2.177490, (float)-1.130005,
(float)-0.309692, (float)0.444214, (float)1.329712, (float)2.436279, (float)3.983887 };
(浮动)-0.309692,(浮动)0.444214,(浮动)1.329712,(浮动)2.436279,(浮动)3.983887};
float state_frgqTbl[64] = { (float)1.000085, (float)1.071695, (float)1.140395, (float)1.206868, (float)1.277188, (float)1.351503, (float)1.429380, (float)1.500727, (float)1.569049, (float)1.639599, (float)1.707071, (float)1.781531, (float)1.840799, (float)1.901550, (float)1.956695, (float)2.006750, (float)2.055474, (float)2.102787, (float)2.142819, (float)2.183592, (float)2.217962, (float)2.257177, (float)2.295739, (float)2.332967, (float)2.369248, (float)2.402792, (float)2.435080, (float)2.468598, (float)2.503394, (float)2.539284, (float)2.572944, (float)2.605036, (float)2.636331, (float)2.668939, (float)2.698780, (float)2.729101, (float)2.759786, (float)2.789834, (float)2.818679, (float)2.848074, (float)2.877470, (float)2.906899, (float)2.936655, (float)2.967804, (float)3.000115, (float)3.033367, (float)3.066355, (float)3.104231, (float)3.141499, (float)3.183012, (float)3.222952, (float)3.265433, (float)3.308441, (float)3.350823, (float)3.395275, (float)3.442793, (float)3.490801, (float)3.542514, (float)3.604064, (float)3.666050, (float)3.740994, (float)3.830749, (float)3.938770, (float)4.101764 };
float state_frgqTbl[64] = { (float)1.000085, (float)1.071695, (float)1.140395, (float)1.206868, (float)1.277188, (float)1.351503, (float)1.429380, (float)1.500727, (float)1.569049, (float)1.639599, (float)1.707071, (float)1.781531, (float)1.840799, (float)1.901550, (float)1.956695, (float)2.006750, (float)2.055474, (float)2.102787, (float)2.142819, (float)2.183592, (float)2.217962, (float)2.257177, (float)2.295739, (float)2.332967, (float)2.369248, (float)2.402792, (float)2.435080, (float)2.468598, (float)2.503394, (float)2.539284, (float)2.572944, (float)2.605036, (float)2.636331, (float)2.668939, (float)2.698780, (float)2.729101, (float)2.759786, (float)2.789834, (float)2.818679, (float)2.848074, (float)2.877470, (float)2.906899, (float)2.936655, (float)2.967804, (float)3.000115, (float)3.033367, (float)3.066355, (float)3.104231, (float)3.141499, (float)3.183012, (float)3.222952, (float)3.265433, (float)3.308441, (float)3.350823, (float)3.395275, (float)3.442793, (float)3.490801, (float)3.542514, (float)3.604064, (float)3.666050, (float)3.740994, (float)3.830749, (float)3.938770, (float)4.101764 };
/* CB tables */
/* CB tables */
int search_rangeTbl[5][CB_NSTAGES]={{58,58,58}, {108,44,44}, {108,108,108}, {108,108,108}, {108,108,108}}; int stMemLTbl=85; int memLfTbl[NASUB_MAX]={147,147,147,147};
int search_rangeTbl[5][CB_NSTAGES]={{58,58,58}, {108,44,44}, {108,108,108}, {108,108,108}, {108,108,108}}; int stMemLTbl=85; int memLfTbl[NASUB_MAX]={147,147,147,147};
/* expansion filter(s) */
/* expansion filter(s) */
float cbfiltersTbl[CB_FILTERLEN]={ (float)-0.034180, (float)0.108887, (float)-0.184326, (float)0.806152, (float)0.713379, (float)-0.144043, (float)0.083740, (float)-0.033691 };
float cbfiltersTbl[CB_FILTERLEN]={ (float)-0.034180, (float)0.108887, (float)-0.184326, (float)0.806152, (float)0.713379, (float)-0.144043, (float)0.083740, (float)-0.033691 };
/* Gain Quantization */
/* Gain Quantization */
float gain_sq3Tbl[8]={ (float)-1.000000, (float)-0.659973, (float)-0.330017,
浮动增益_sq3Tbl[8]={(浮动)-1.000000,(浮动)-0.659973,(浮动)-0.330017,
(float)0.000000, (float)0.250000, (float)0.500000, (float)0.750000, (float)1.00000};
(浮动)0.000000,(浮动)0.250000,(浮动)0.500000,(浮动)0.750000,(浮动)1.00000};
float gain_sq4Tbl[16]={ (float)-1.049988, (float)-0.900024, (float)-0.750000, (float)-0.599976, (float)-0.450012, (float)-0.299988, (float)-0.150024, (float)0.000000, (float)0.150024, (float)0.299988, (float)0.450012, (float)0.599976, (float)0.750000, (float)0.900024, (float)1.049988, (float)1.200012};
float gain_sq4Tbl[16]={ (float)-1.049988, (float)-0.900024, (float)-0.750000, (float)-0.599976, (float)-0.450012, (float)-0.299988, (float)-0.150024, (float)0.000000, (float)0.150024, (float)0.299988, (float)0.450012, (float)0.599976, (float)0.750000, (float)0.900024, (float)1.049988, (float)1.200012};
float gain_sq5Tbl[32]={ (float)0.037476, (float)0.075012, (float)0.112488, (float)0.150024, (float)0.187500, (float)0.224976, (float)0.262512, (float)0.299988, (float)0.337524, (float)0.375000, (float)0.412476, (float)0.450012, (float)0.487488, (float)0.525024, (float)0.562500, (float)0.599976, (float)0.637512, (float)0.674988, (float)0.712524, (float)0.750000, (float)0.787476, (float)0.825012, (float)0.862488, (float)0.900024, (float)0.937500, (float)0.974976, (float)1.012512, (float)1.049988, (float)1.087524, (float)1.125000, (float)1.162476, (float)1.200012};
float gain_sq5Tbl[32]={ (float)0.037476, (float)0.075012, (float)0.112488, (float)0.150024, (float)0.187500, (float)0.224976, (float)0.262512, (float)0.299988, (float)0.337524, (float)0.375000, (float)0.412476, (float)0.450012, (float)0.487488, (float)0.525024, (float)0.562500, (float)0.599976, (float)0.637512, (float)0.674988, (float)0.712524, (float)0.750000, (float)0.787476, (float)0.825012, (float)0.862488, (float)0.900024, (float)0.937500, (float)0.974976, (float)1.012512, (float)1.049988, (float)1.087524, (float)1.125000, (float)1.162476, (float)1.200012};
/* Enhancer - Upsamling a factor 4 (ENH_UPS0 = 4) */ float polyphaserTbl[ENH_UPS0*(2*ENH_FL0+1)]={ (float)0.000000, (float)0.000000, (float)0.000000, (float)1.000000, (float)0.000000, (float)0.000000, (float)0.000000, (float)0.015625, (float)-0.076904, (float)0.288330, (float)0.862061, (float)-0.106445, (float)0.018799, (float)-0.015625, (float)0.023682, (float)-0.124268, (float)0.601563, (float)0.601563, (float)-0.124268, (float)0.023682, (float)-0.023682, (float)0.018799, (float)-0.106445, (float)0.862061, (float)0.288330, (float)-0.076904, (float)0.015625, (float)-0.018799};
/* Enhancer - Upsamling a factor 4 (ENH_UPS0 = 4) */ float polyphaserTbl[ENH_UPS0*(2*ENH_FL0+1)]={ (float)0.000000, (float)0.000000, (float)0.000000, (float)1.000000, (float)0.000000, (float)0.000000, (float)0.000000, (float)0.015625, (float)-0.076904, (float)0.288330, (float)0.862061, (float)-0.106445, (float)0.018799, (float)-0.015625, (float)0.023682, (float)-0.124268, (float)0.601563, (float)0.601563, (float)-0.124268, (float)0.023682, (float)-0.023682, (float)0.018799, (float)-0.106445, (float)0.862061, (float)0.288330, (float)-0.076904, (float)0.015625, (float)-0.018799};
float enh_plocsTbl[ENH_NBLOCKS_TOT] = {(float)40.0, (float)120.0, (float)200.0, (float)280.0, (float)360.0, (float)440.0, (float)520.0, (float)600.0};
float enh_plocsTbl[ENH_NBLOCKS_TOT] = {(float)40.0, (float)120.0, (float)200.0, (float)280.0, (float)360.0, (float)440.0, (float)520.0, (float)600.0};
/* LPC analysis and quantization */
/* LPC analysis and quantization */
int dim_lsfCbTbl[LSF_NSPLIT] = {3, 3, 4}; int size_lsfCbTbl[LSF_NSPLIT] = {64,128,128};
int dim_lsfCbTbl[LSF_NSPLIT] = {3, 3, 4}; int size_lsfCbTbl[LSF_NSPLIT] = {64,128,128};
float lsfmeanTbl[LPC_FILTERORDER] = { (float)0.281738, (float)0.445801, (float)0.663330, (float)0.962524, (float)1.251831, (float)1.533081, (float)1.850586, (float)2.137817, (float)2.481445, (float)2.777344};
float lsfmeanTbl[LPC_FILTERORDER] = { (float)0.281738, (float)0.445801, (float)0.663330, (float)0.962524, (float)1.251831, (float)1.533081, (float)1.850586, (float)2.137817, (float)2.481445, (float)2.777344};
float lsf_weightTbl_30ms[6] = {(float)(1.0/2.0), (float)1.0, (float)(2.0/3.0), (float)(1.0/3.0), (float)0.0, (float)0.0};
float lsf_weightTbl_30ms[6] = {(float)(1.0/2.0), (float)1.0, (float)(2.0/3.0), (float)(1.0/3.0), (float)0.0, (float)0.0};
float lsf_weightTbl_20ms[4] = {(float)(3.0/4.0), (float)(2.0/4.0), (float)(1.0/4.0), (float)(0.0)};
float lsf_weightTbl_20ms[4] = {(float)(3.0/4.0), (float)(2.0/4.0), (float)(1.0/4.0), (float)(0.0)};
/* Hanning LPC window */ float lpc_winTbl[BLOCKL_MAX]={ (float)0.000183, (float)0.000671, (float)0.001526, (float)0.002716, (float)0.004242, (float)0.006104, (float)0.008301, (float)0.010834, (float)0.013702, (float)0.016907, (float)0.020416, (float)0.024261, (float)0.028442, (float)0.032928, (float)0.037750, (float)0.042877, (float)0.048309, (float)0.054047, (float)0.060089, (float)0.066437, (float)0.073090, (float)0.080017, (float)0.087219, (float)0.094727, (float)0.102509, (float)0.110535, (float)0.118835, (float)0.127411, (float)0.136230, (float)0.145294, (float)0.154602, (float)0.164154, (float)0.173920, (float)0.183899, (float)0.194122, (float)0.204529, (float)0.215149, (float)0.225952, (float)0.236938, (float)0.248108, (float)0.259460, (float)0.270966, (float)0.282654, (float)0.294464, (float)0.306396, (float)0.318481, (float)0.330688, (float)0.343018, (float)0.355438, (float)0.367981, (float)0.380585, (float)0.393280, (float)0.406067, (float)0.418884, (float)0.431763, (float)0.444702, (float)0.457672, (float)0.470673, (float)0.483704, (float)0.496735, (float)0.509766, (float)0.522797, (float)0.535828, (float)0.548798, (float)0.561768, (float)0.574677, (float)0.587524, (float)0.600342, (float)0.613068, (float)0.625732, (float)0.638306, (float)0.650787, (float)0.663147, (float)0.675415, (float)0.687561, (float)0.699585, (float)0.711487, (float)0.723206, (float)0.734802, (float)0.746216, (float)0.757477, (float)0.768585, (float)0.779480, (float)0.790192, (float)0.800720, (float)0.811005, (float)0.821106, (float)0.830994, (float)0.840668, (float)0.850067, (float)0.859253, (float)0.868225, (float)0.876892, (float)0.885345, (float)0.893524, (float)0.901428, (float)0.909058, (float)0.916412, (float)0.923492,
/* Hanning LPC window */ float lpc_winTbl[BLOCKL_MAX]={ (float)0.000183, (float)0.000671, (float)0.001526, (float)0.002716, (float)0.004242, (float)0.006104, (float)0.008301, (float)0.010834, (float)0.013702, (float)0.016907, (float)0.020416, (float)0.024261, (float)0.028442, (float)0.032928, (float)0.037750, (float)0.042877, (float)0.048309, (float)0.054047, (float)0.060089, (float)0.066437, (float)0.073090, (float)0.080017, (float)0.087219, (float)0.094727, (float)0.102509, (float)0.110535, (float)0.118835, (float)0.127411, (float)0.136230, (float)0.145294, (float)0.154602, (float)0.164154, (float)0.173920, (float)0.183899, (float)0.194122, (float)0.204529, (float)0.215149, (float)0.225952, (float)0.236938, (float)0.248108, (float)0.259460, (float)0.270966, (float)0.282654, (float)0.294464, (float)0.306396, (float)0.318481, (float)0.330688, (float)0.343018, (float)0.355438, (float)0.367981, (float)0.380585, (float)0.393280, (float)0.406067, (float)0.418884, (float)0.431763, (float)0.444702, (float)0.457672, (float)0.470673, (float)0.483704, (float)0.496735, (float)0.509766, (float)0.522797, (float)0.535828, (float)0.548798, (float)0.561768, (float)0.574677, (float)0.587524, (float)0.600342, (float)0.613068, (float)0.625732, (float)0.638306, (float)0.650787, (float)0.663147, (float)0.675415, (float)0.687561, (float)0.699585, (float)0.711487, (float)0.723206, (float)0.734802, (float)0.746216, (float)0.757477, (float)0.768585, (float)0.779480, (float)0.790192, (float)0.800720, (float)0.811005, (float)0.821106, (float)0.830994, (float)0.840668, (float)0.850067, (float)0.859253, (float)0.868225, (float)0.876892, (float)0.885345, (float)0.893524, (float)0.901428, (float)0.909058, (float)0.916412, (float)0.923492,
(float)0.930267, (float)0.936768, (float)0.942963, (float)0.948853, (float)0.954437, (float)0.959717, (float)0.964691, (float)0.969360, (float)0.973694, (float)0.977692, (float)0.981384, (float)0.984741, (float)0.987762, (float)0.990479, (float)0.992828, (float)0.994873, (float)0.996552, (float)0.997925, (float)0.998932, (float)0.999603, (float)0.999969, (float)0.999969, (float)0.999603, (float)0.998932, (float)0.997925, (float)0.996552, (float)0.994873, (float)0.992828, (float)0.990479, (float)0.987762, (float)0.984741, (float)0.981384, (float)0.977692, (float)0.973694, (float)0.969360, (float)0.964691, (float)0.959717, (float)0.954437, (float)0.948853, (float)0.942963, (float)0.936768, (float)0.930267, (float)0.923492, (float)0.916412, (float)0.909058, (float)0.901428, (float)0.893524, (float)0.885345, (float)0.876892, (float)0.868225, (float)0.859253, (float)0.850067, (float)0.840668, (float)0.830994, (float)0.821106, (float)0.811005, (float)0.800720, (float)0.790192, (float)0.779480, (float)0.768585, (float)0.757477, (float)0.746216, (float)0.734802, (float)0.723206, (float)0.711487, (float)0.699585, (float)0.687561, (float)0.675415, (float)0.663147, (float)0.650787, (float)0.638306, (float)0.625732, (float)0.613068, (float)0.600342, (float)0.587524, (float)0.574677, (float)0.561768, (float)0.548798, (float)0.535828, (float)0.522797, (float)0.509766, (float)0.496735, (float)0.483704, (float)0.470673, (float)0.457672, (float)0.444702, (float)0.431763, (float)0.418884, (float)0.406067, (float)0.393280, (float)0.380585, (float)0.367981, (float)0.355438, (float)0.343018, (float)0.330688, (float)0.318481, (float)0.306396, (float)0.294464, (float)0.282654, (float)0.270966, (float)0.259460, (float)0.248108, (float)0.236938, (float)0.225952, (float)0.215149, (float)0.204529, (float)0.194122, (float)0.183899, (float)0.173920, (float)0.164154, (float)0.154602, (float)0.145294, (float)0.136230, (float)0.127411, (float)0.118835, (float)0.110535, (float)0.102509, (float)0.094727, (float)0.087219, (float)0.080017, (float)0.073090, (float)0.066437, (float)0.060089, (float)0.054047, (float)0.048309, (float)0.042877, (float)0.037750, (float)0.032928, (float)0.028442, (float)0.024261, (float)0.020416, (float)0.016907, (float)0.013702, (float)0.010834, (float)0.008301, (float)0.006104, (float)0.004242, (float)0.002716, (float)0.001526, (float)0.000671, (float)0.000183 };
(浮点数)0.930267,(浮点数)0.936768,(浮点数)0.942963,(浮点数)0.948853,(浮点数)0.954437,(浮点数)0.959717,(浮点数)0.964691,(浮点数)0.969360,(浮点数)0.973694,(浮点数)0.977692,(浮点数)0.981384,(浮点数)0.987762,(浮点数)0.99479,(浮点数)0.992828,(浮点数)0.994873,(浮点数)0.996552,(浮点数)0.7925,(浮点数)0.99893,(浮点数)0.999969,(浮动)0.999969,(浮动)0.999603,(浮动)0.998932,(浮动)0.999925,(浮动)0.996552,(浮动)0.994873,(浮动)0.992828,(浮动)0.990479,(浮动)0.987762,(浮动)0.984741,(浮动)0.981384,(浮动)0.977692,(浮动)0.973694,(浮动)0.969360,(浮动)0.964691,(浮动)0.959717,(浮动)0.954437,(浮动)0.948868,(浮动),浮动,(浮动)0.930267,(浮动)0.923492,(浮动)0.916412,(浮动)0.909058,(浮动)0.901428,(浮动)0.893524,(浮动)0.885345,(浮动)0.876892,(浮动)0.868225,(浮动)0.859253,(浮动)0.850067,(浮动)0.840668,(浮动)0.830994,(浮动)0.821106,(浮动)0.811005,(浮动)0.800720,(浮动)0.790192,(浮动)0.779480,(浮动)0.7577,(浮动)0.746216,(浮动)0.734802,(浮动)0.723206,(浮动)0.711487,(浮动)0.699585,(浮动)0.687561,(浮动)0.675415,(浮动)0.663147,(浮动)0.650787,(浮动)0.638306,(浮动)0.625732,(浮动)0.613068,(浮动)0.600342,(浮动)0.587524,(浮动)0.574677,(浮动)0.561768,(浮动)0.548798,(浮动)0.535828,(浮动)0.525035,(浮动,(浮点数)0.483704,(浮点数)0.470673,(浮点数)0.457672,(浮点数)0.444702,(浮点数)0.431763,(浮点数)0.418884,(浮点数)0.406067,(浮点数)0.393280,(浮点数)0.380585,(浮点数)0.367981,(浮点数)0.355438,(浮点数)0.330688,(浮点数)0.318481,(浮点数)0.306396,(浮点数)0.294464,(浮点数)0.282654,(浮点数)0.270966,(浮点数)0.258100,(浮点数)248108,(浮点数)0.236938,(浮点数)0.225952,(浮点数)0.215149,(浮点数)0.204529,(浮点数)0.194122,(浮点数)0.183899,(浮点数)0.173920,(浮点数)0.164154,(浮点数)0.154602,(浮点数)0.145294,(浮点数)0.136230,(浮点数)0.127411,(浮点数)0.118835,(浮点数)0.110535,(浮点数)0.102509,(浮点数)0.094727,(浮点数)0.087219,(浮点数)0.080017,(浮点数)0.0637,(浮点数,(浮动)0.054047,(浮动)0.048309,(浮动)0.042877,(浮动)0.037750,(浮动)0.032928,(浮动)0.028442,(浮动)0.024261,(浮动)0.020416,(浮动)0.016907,(浮动)0.013702,(浮动)0.010834,(浮动)0.008301,(浮动)0.006104,(浮动)0.004242,(浮动)0.002716,(浮动)0.001526,(浮动)0.000671,(浮动)0.000183};
/* Asymmetric LPC window */ float lpc_asymwinTbl[BLOCKL_MAX]={ (float)0.000061, (float)0.000214, (float)0.000458, (float)0.000824, (float)0.001282, (float)0.001831, (float)0.002472, (float)0.003235, (float)0.004120, (float)0.005066, (float)0.006134, (float)0.007294, (float)0.008545, (float)0.009918, (float)0.011383, (float)0.012939, (float)0.014587, (float)0.016357, (float)0.018219, (float)0.020172, (float)0.022217, (float)0.024353, (float)0.026611, (float)0.028961, (float)0.031372, (float)0.033905, (float)0.036530, (float)0.039276, (float)0.042084, (float)0.044983, (float)0.047974, (float)0.051086, (float)0.054260, (float)0.057526, (float)0.060883, (float)0.064331, (float)0.067871, (float)0.071503, (float)0.075226, (float)0.079010, (float)0.082916, (float)0.086884, (float)0.090942, (float)0.095062, (float)0.099304, (float)0.103607, (float)0.107971, (float)0.112427, (float)0.116974, (float)0.121582, (float)0.126282, (float)0.131073, (float)0.135895, (float)0.140839, (float)0.145813, (float)0.150879, (float)0.156006, (float)0.161224, (float)0.166504, (float)0.171844, (float)0.177246, (float)0.182709, (float)0.188263, (float)0.193848, (float)0.199524, (float)0.205231, (float)0.211029, (float)0.216858, (float)0.222778, (float)0.228729, (float)0.234741, (float)0.240814, (float)0.246918, (float)0.253082, (float)0.259308, (float)0.265564, (float)0.271881, (float)0.278259, (float)0.284668, (float)0.291107, (float)0.297607, (float)0.304138, (float)0.310730, (float)0.317322, (float)0.323975, (float)0.330658, (float)0.337372, (float)0.344147, (float)0.350922, (float)0.357727, (float)0.364594, (float)0.371460, (float)0.378357, (float)0.385284, (float)0.392212, (float)0.399170, (float)0.406158, (float)0.413177, (float)0.420197, (float)0.427246, (float)0.434296, (float)0.441376, (float)0.448456, (float)0.455536, (float)0.462646, (float)0.469757, (float)0.476868, (float)0.483978, (float)0.491089, (float)0.498230, (float)0.505341, (float)0.512451, (float)0.519592, (float)0.526703, (float)0.533813, (float)0.540924, (float)0.548004, (float)0.555084, (float)0.562164, (float)0.569244, (float)0.576294, (float)0.583313, (float)0.590332, (float)0.597321, (float)0.604309, (float)0.611267, (float)0.618195, (float)0.625092, (float)0.631989, (float)0.638855, (float)0.645660, (float)0.652466, (float)0.659241, (float)0.665985, (float)0.672668, (float)0.679352, (float)0.685974, (float)0.692566,
/* Asymmetric LPC window */ float lpc_asymwinTbl[BLOCKL_MAX]={ (float)0.000061, (float)0.000214, (float)0.000458, (float)0.000824, (float)0.001282, (float)0.001831, (float)0.002472, (float)0.003235, (float)0.004120, (float)0.005066, (float)0.006134, (float)0.007294, (float)0.008545, (float)0.009918, (float)0.011383, (float)0.012939, (float)0.014587, (float)0.016357, (float)0.018219, (float)0.020172, (float)0.022217, (float)0.024353, (float)0.026611, (float)0.028961, (float)0.031372, (float)0.033905, (float)0.036530, (float)0.039276, (float)0.042084, (float)0.044983, (float)0.047974, (float)0.051086, (float)0.054260, (float)0.057526, (float)0.060883, (float)0.064331, (float)0.067871, (float)0.071503, (float)0.075226, (float)0.079010, (float)0.082916, (float)0.086884, (float)0.090942, (float)0.095062, (float)0.099304, (float)0.103607, (float)0.107971, (float)0.112427, (float)0.116974, (float)0.121582, (float)0.126282, (float)0.131073, (float)0.135895, (float)0.140839, (float)0.145813, (float)0.150879, (float)0.156006, (float)0.161224, (float)0.166504, (float)0.171844, (float)0.177246, (float)0.182709, (float)0.188263, (float)0.193848, (float)0.199524, (float)0.205231, (float)0.211029, (float)0.216858, (float)0.222778, (float)0.228729, (float)0.234741, (float)0.240814, (float)0.246918, (float)0.253082, (float)0.259308, (float)0.265564, (float)0.271881, (float)0.278259, (float)0.284668, (float)0.291107, (float)0.297607, (float)0.304138, (float)0.310730, (float)0.317322, (float)0.323975, (float)0.330658, (float)0.337372, (float)0.344147, (float)0.350922, (float)0.357727, (float)0.364594, (float)0.371460, (float)0.378357, (float)0.385284, (float)0.392212, (float)0.399170, (float)0.406158, (float)0.413177, (float)0.420197, (float)0.427246, (float)0.434296, (float)0.441376, (float)0.448456, (float)0.455536, (float)0.462646, (float)0.469757, (float)0.476868, (float)0.483978, (float)0.491089, (float)0.498230, (float)0.505341, (float)0.512451, (float)0.519592, (float)0.526703, (float)0.533813, (float)0.540924, (float)0.548004, (float)0.555084, (float)0.562164, (float)0.569244, (float)0.576294, (float)0.583313, (float)0.590332, (float)0.597321, (float)0.604309, (float)0.611267, (float)0.618195, (float)0.625092, (float)0.631989, (float)0.638855, (float)0.645660, (float)0.652466, (float)0.659241, (float)0.665985, (float)0.672668, (float)0.679352, (float)0.685974, (float)0.692566,
(float)0.699127, (float)0.705658, (float)0.712128, (float)0.718536, (float)0.724945, (float)0.731262, (float)0.737549, (float)0.743805, (float)0.750000, (float)0.756134, (float)0.762238, (float)0.768280, (float)0.774261, (float)0.780182, (float)0.786072, (float)0.791870, (float)0.797638, (float)0.803314, (float)0.808960, (float)0.814514, (float)0.820038, (float)0.825470, (float)0.830841, (float)0.836151, (float)0.841400, (float)0.846558, (float)0.851654, (float)0.856689, (float)0.861633, (float)0.866516, (float)0.871338, (float)0.876068, (float)0.880737, (float)0.885315, (float)0.889801, (float)0.894226, (float)0.898560, (float)0.902832, (float)0.907013, (float)0.911102, (float)0.915100, (float)0.919037, (float)0.922882, (float)0.926636, (float)0.930328, (float)0.933899, (float)0.937408, (float)0.940796, (float)0.944122, (float)0.947357, (float)0.950470, (float)0.953522, (float)0.956482, (float)0.959351, (float)0.962097, (float)0.964783, (float)0.967377, (float)0.969849, (float)0.972229, (float)0.974518, (float)0.976715, (float)0.978821, (float)0.980835, (float)0.982727, (float)0.984528, (float)0.986237, (float)0.987854, (float)0.989380, (float)0.990784, (float)0.992096, (float)0.993317, (float)0.994415, (float)0.995422, (float)0.996338, (float)0.997162, (float)0.997864, (float)0.998474, (float)0.998962, (float)0.999390, (float)0.999695, (float)0.999878, (float)0.999969, (float)0.999969, (float)0.996918, (float)0.987701, (float)0.972382, (float)0.951050, (float)0.923889, (float)0.891022, (float)0.852631, (float)0.809021, (float)0.760406, (float)0.707092, (float)0.649445, (float)0.587799, (float)0.522491, (float)0.453979, (float)0.382690, (float)0.309021, (float)0.233459, (float)0.156433, (float)0.078461 };
(浮动)0.699127,(浮动)0.705658,(浮动)0.712128,(浮动)0.718536,(浮动)0.724945,(浮动)0.731262,(浮动)0.737549,(浮动)0.743805,(浮动)0.750000,(浮动)0.756134,(浮动)0.762238,(浮动)0.768280,(浮动)0.774261,(浮动)0.780182,(浮动)0.786072,(浮动)0.791870,(浮动)0.797638,(浮动)0.808145,(浮动)0.820038,(浮点数)0.825470,(浮点数)0.830841,(浮点数)0.836151,(浮点数)0.841400,(浮点数)0.846558,(浮点数)0.851654,(浮点数)0.856689,(浮点数)0.861633,(浮点数)0.866516,(浮点数)0.871338,(浮点数)0.876068,(浮点数)0.880737,(浮点数)0.885315,(浮点数)0.889801,(浮点数)0.894226,(浮点数)0.898560,(浮点数)0.902832,(浮点数)0.907013,(浮点数),浮点数,(浮动)0.919037,(浮动)0.922882,(浮动)0.926636,(浮动)0.930328,(浮动)0.933899,(浮动)0.937408,(浮动)0.940796,(浮动)0.944122,(浮动)0.947357,(浮动)0.950470,(浮动)0.953522,(浮动)0.956482,(浮动)0.959351,(浮动)0.962097,(浮动)0.964783,(浮动)0.967377,(浮动)0.969849,(浮动)0.972229,(浮动)0.974515,(浮动)0.978821,(浮子)0.980835,(浮子)0.982727,(浮子)0.984528,(浮子)0.986237,(浮子)0.987854,(浮子)0.989380,(浮子)0.990784,(浮子)0.992096,(浮子)0.993317,(浮子)0.994415,(浮子)0.995422,(浮子)0.996338,(浮子)0.997162,(浮子)0.997864,(浮子)0.998474,(浮子)0.998962,(浮子)0.99990,(浮子)0.99969,(浮子,(浮动)0.999969,(浮动)0.999918,(浮动)0.987701,(浮动)0.972382,(浮动)0.951050,(浮动)0.923889,(浮动)0.891022,(浮动)0.852631,(浮动)0.809021,(浮动)0.760406,(浮动)0.70707092,(浮动)0.649445,(浮动)0.587799,(浮动)0.522491,(浮动)0.453979,(浮动)0.382690,(浮动)0,(浮动)0.30921,(浮动)0.233459,(浮动)0.076461,(浮动);
/* Lag window for LPC */ float lpc_lagwinTbl[LPC_FILTERORDER + 1]={ (float)1.000100, (float)0.998890, (float)0.995569, (float)0.990057, (float)0.982392, (float)0.972623, (float)0.960816, (float)0.947047, (float)0.931405, (float)0.913989, (float)0.894909};
/* Lag window for LPC */ float lpc_lagwinTbl[LPC_FILTERORDER + 1]={ (float)1.000100, (float)0.998890, (float)0.995569, (float)0.990057, (float)0.982392, (float)0.972623, (float)0.960816, (float)0.947047, (float)0.931405, (float)0.913989, (float)0.894909};
/* LSF quantization*/ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = { (float)0.155396, (float)0.273193, (float)0.451172, (float)0.390503, (float)0.648071, (float)1.002075, (float)0.440186, (float)0.692261, (float)0.955688,
/* LSF quantization*/ float lsfCbTbl[64 * 3 + 128 * 3 + 128 * 4] = { (float)0.155396, (float)0.273193, (float)0.451172, (float)0.390503, (float)0.648071, (float)1.002075, (float)0.440186, (float)0.692261, (float)0.955688,
(float)0.343628, (float)0.642334, (float)1.071533, (float)0.318359, (float)0.491577, (float)0.670532, (float)0.193115, (float)0.375488, (float)0.725708, (float)0.364136, (float)0.510376, (float)0.658691, (float)0.297485, (float)0.527588, (float)0.842529, (float)0.227173, (float)0.365967, (float)0.563110, (float)0.244995, (float)0.396729, (float)0.636475, (float)0.169434, (float)0.300171, (float)0.520264, (float)0.312866, (float)0.464478, (float)0.643188, (float)0.248535, (float)0.429932, (float)0.626099, (float)0.236206, (float)0.491333, (float)0.817139, (float)0.334961, (float)0.625122, (float)0.895752, (float)0.343018, (float)0.518555, (float)0.698608, (float)0.372803, (float)0.659790, (float)0.945435, (float)0.176880, (float)0.316528, (float)0.581421, (float)0.416382, (float)0.625977, (float)0.805176, (float)0.303223, (float)0.568726, (float)0.915039, (float)0.203613, (float)0.351440, (float)0.588135, (float)0.221191, (float)0.375000, (float)0.614746, (float)0.199951, (float)0.323364, (float)0.476074, (float)0.300781, (float)0.433350, (float)0.566895, (float)0.226196, (float)0.354004, (float)0.507568, (float)0.300049, (float)0.508179, (float)0.711670, (float)0.312012, (float)0.492676, (float)0.763428, (float)0.329956, (float)0.541016, (float)0.795776, (float)0.373779, (float)0.604614, (float)0.928833, (float)0.210571, (float)0.452026, (float)0.755249, (float)0.271118, (float)0.473267, (float)0.662476, (float)0.285522, (float)0.436890, (float)0.634399, (float)0.246704, (float)0.565552, (float)0.859009, (float)0.270508, (float)0.406250, (float)0.553589, (float)0.361450, (float)0.578491, (float)0.813843, (float)0.342651, (float)0.482788, (float)0.622437, (float)0.340332, (float)0.549438, (float)0.743164, (float)0.200439, (float)0.336304, (float)0.540894, (float)0.407837, (float)0.644775, (float)0.895142, (float)0.294678, (float)0.454834, (float)0.699097, (float)0.193115, (float)0.344482, (float)0.643188, (float)0.275757, (float)0.420776, (float)0.598755, (float)0.380493, (float)0.608643, (float)0.861084, (float)0.222778, (float)0.426147, (float)0.676514, (float)0.407471, (float)0.700195, (float)1.053101, (float)0.218384, (float)0.377197, (float)0.669922, (float)0.313232, (float)0.454102, (float)0.600952, (float)0.347412, (float)0.571533, (float)0.874146, (float)0.238037, (float)0.405396, (float)0.729492, (float)0.223877, (float)0.412964, (float)0.822021, (float)0.395264, (float)0.582153, (float)0.743896,
(浮动)0.343628,(浮动)0.642334,(浮动)1.071533,(浮动)0.318359,(浮动)0.491577,(浮动)0.670532,(浮动)0.193115,(浮动)0.375488,(浮动)0.725708,(浮动)0.364136,(浮动)0.510376,(浮动)0.658691,(浮动)0.297485,(浮动)0.527588,(浮动)0.842529,(浮动)0.227173,(浮动)0.365967,(浮动)0.563110,(浮动)0.243995,(浮动)0.636475,(浮点数)0.169434,(浮点数)0.300171,(浮点数)0.520264,(浮点数)0.312866,(浮点数)0.464478,(浮点数)0.643188,(浮点数)0.248535,(浮点数)0.429932,(浮点数)0.626099,(浮点数)0.236206,(浮点数)0.491333,(浮点数)0.817139,(浮点数)0.3349961,(浮点数)0.6251122,(浮点数)0.895752,(浮点数)0.343018,(浮点数)0.518555,(浮点数)0.698603790,(浮点数,(浮点数)0.945435,(浮点数)0.176880,(浮点数)0.316528,(浮点数)0.581421,(浮点数)0.416382,(浮点数)0.625977,(浮点数)0.805176,(浮点数)0.303223,(浮点数)0.568726,(浮点数)0.915039,(浮点数)0.203613,(浮点数)0.351440,(浮点数)0.588135,(浮点数)0.22191,(浮点数)0.375000,(浮点数)0.614746,(浮点数)0.199951,(浮点数)0.607874,(浮点数)0.433350,(浮动)0.566895,(浮动)0.226196,(浮动)0.354004,(浮动)0.507568,(浮动)0.300049,(浮动)0.508179,(浮动)0.711670,(浮动)0.312012,(浮动)0.492676,(浮动)0.763428,(浮动)0.329956,(浮动)0.541016,(浮动)0.795776,(浮动)0.373779,(浮动)0.604614,(浮动)0.928833,(浮动)0.210571,(浮动)0.455218,(浮动,(浮动)0.473267,(浮动)0.662476,(浮动)0.285522,(浮动)0.436890,(浮动)0.634399,(浮动)0.246704,(浮动)0.565552,(浮动)0.859009,(浮动)0.270508,(浮动)0.406250,(浮动)0.553589,(浮动)0.361450,(浮动)0.578491,(浮动)0.813843,(浮动)0.342651,(浮动)0.482788,(浮动)0.622437,(浮动)0.3400332,(浮动)3160.744,(浮动)0.200439,(浮点数)0.336304,(浮点数)0.540894,(浮点数)0.407837,(浮点数)0.644775,(浮点数)0.895142,(浮点数)0.294678,(浮点数)0.454834,(浮点数)0.699097,(浮点数)0.193115,(浮点数)0.344482,(浮点数)0.643188,(浮点数)0.275757,(浮点数)0.420776,(浮点数)0.598755,(浮点数)0.380493,(浮点数)0.60861083,(浮点数)0.861084,(浮点数)0.226714,(浮点数,(浮点数)0.407471,(浮点数)0.700195,(浮点数)1.053101,(浮点数)0.218384,(浮点数)0.377197,(浮点数)0.669922,(浮点数)0.313232,(浮点数)0.454102,(浮点数)0.600952,(浮点数)0.347412,(浮点数)0.571533,(浮点数)0.874146,(浮点数)0.238037,(浮点数)0.405396,(浮点数)0.729492,(浮点数)0.223877,(浮点数)0.412964,(浮点数)0.822021,(浮点数)0.39526,(浮点数)浮点数,(浮点数,(浮点数)2553)0.743896,
(float)0.247925, (float)0.485596, (float)0.720581, (float)0.229126, (float)0.496582, (float)0.907715, (float)0.260132, (float)0.566895, (float)1.012695, (float)0.337402, (float)0.611572, (float)0.978149, (float)0.267822, (float)0.447632, (float)0.769287, (float)0.250610, (float)0.381714, (float)0.530029, (float)0.430054, (float)0.805054, (float)1.221924, (float)0.382568, (float)0.544067, (float)0.701660, (float)0.383545, (float)0.710327, (float)1.149170, (float)0.271362, (float)0.529053, (float)0.775513, (float)0.246826, (float)0.393555, (float)0.588623, (float)0.266846, (float)0.422119, (float)0.676758, (float)0.311523, (float)0.580688, (float)0.838623, (float)1.331177, (float)1.576782, (float)1.779541, (float)1.160034, (float)1.401978, (float)1.768188, (float)1.161865, (float)1.525146, (float)1.715332, (float)0.759521, (float)0.913940, (float)1.119873, (float)0.947144, (float)1.121338, (float)1.282471, (float)1.015015, (float)1.557007, (float)1.804932, (float)1.172974, (float)1.402100, (float)1.692627, (float)1.087524, (float)1.474243, (float)1.665405, (float)0.899536, (float)1.105225, (float)1.406250, (float)1.148438, (float)1.484741, (float)1.796265, (float)0.785645, (float)1.209839, (float)1.567749, (float)0.867798, (float)1.166504, (float)1.450684, (float)0.922485, (float)1.229858, (float)1.420898, (float)0.791260, (float)1.123291, (float)1.409546, (float)0.788940, (float)0.966064, (float)1.340332, (float)1.051147, (float)1.272827, (float)1.556641, (float)0.866821, (float)1.181152, (float)1.538818, (float)0.906738, (float)1.373535, (float)1.607910, (float)1.244751, (float)1.581421, (float)1.933838, (float)0.913940, (float)1.337280, (float)1.539673, (float)0.680542, (float)0.959229, (float)1.662720, (float)0.887207, (float)1.430542, (float)1.800781, (float)0.912598, (float)1.433594, (float)1.683960, (float)0.860474, (float)1.060303, (float)1.455322, (float)1.005127, (float)1.381104, (float)1.706909, (float)0.800781, (float)1.363892, (float)1.829102, (float)0.781860, (float)1.124390, (float)1.505981, (float)1.003662, (float)1.471436, (float)1.684692, (float)0.981323, (float)1.309570, (float)1.618042, (float)1.228760, (float)1.554321, (float)1.756470, (float)0.734375, (float)0.895752, (float)1.225586, (float)0.841797, (float)1.055664, (float)1.249268, (float)0.920166, (float)1.119385, (float)1.486206, (float)0.894409, (float)1.539063, (float)1.828979, (float)1.283691, (float)1.543335, (float)1.858276,
(浮动)0.247925,(浮动)0.485596,(浮动)0.720581,(浮动)0.229126,(浮动)0.496582,(浮动)0.907715,(浮动)0.260132,(浮动)0.566895,(浮动)1.012695,(浮动)0.337402,(浮动)0.611572,(浮动)0.978149,(浮动)0.267822,(浮动)0.44769287,(浮动)0.250610,(浮动)0.381714,(浮动)0.530029,(浮动)0.430804,(浮动)1.221924,(浮点数)0.382568,(浮点数)0.544067,(浮点数)0.701660,(浮点数)0.383545,(浮点数)0.710327,(浮点数)1.149170,(浮点数)0.271362,(浮点数)0.529053,(浮点数)0.775513,(浮点数)0.246826,(浮点数)0.393555,(浮点数)0.588623,(浮点数)0.266846,(浮点数)0.422119,(浮点数)0.676758,(浮点数)0.311523,(浮点数)0.58068838,(浮点数)0.371,(浮点数)17782,(浮点数)1.779541,(浮点数)1.160034,(浮点数)1.401978,(浮点数)1.282471,(浮点数)1.015015,(浮点数)1.525146,(浮点数)1.715332,(浮点数)0.759521,(浮点数)0.913940,(浮点数)1.119873,(浮点数)0.947144,(浮点数)1.121338,(浮点数)1.282471,(浮点数)1.015015,(浮点数)1.557007,(浮点数)1.804932,(浮点数)1.172974,(浮点数)1.402100,(浮点数)1.697524,(浮点数)1.474243,(浮动)1.665405,(浮动)0.899536,(浮动)1.105225,(浮动)1.406250,(浮动)1.148438,(浮动)1.484741,(浮动)1.796265,(浮动)0.785645,(浮动)1.209839,(浮动)1.567749,(浮动)0.867798,(浮动)1.166504,(浮动)1.450684,(浮动)0.922485,(浮动)1.229858,(浮动)1.420898,(浮动)1.791260,(浮动)1.2940,(浮动,(浮点数)0.966064,(浮点数)1.340332,(浮点数)1.051147,(浮点数)1.272827,(浮点数)1.556641,(浮点数)0.866821,(浮点数)1.181152,(浮点数)1.538818,(浮点数)0.906738,(浮点数)1.373535,(浮点数)1.607910,(浮点数)1.244751,(浮点数)1.581421,(浮点数)1.933838,(浮点数)0.913940,(浮点数)1.337280,(浮点数)1.539673,(浮点数)0.6805542,(浮点数)0.9220,(浮点数)0.887207,(浮点数)1.430542,(浮点数)1.800781,(浮点数)0.912598,(浮点数)1.433594,(浮点数)1.683960,(浮点数)0.860474,(浮点数)1.060303,(浮点数)1.455322,(浮点数)1.005127,(浮点数)1.381104,(浮点数)1.706909,(浮点数)0.800781,(浮点数)1.363892,(浮点数)1.829102,(浮点数)0.781860,(浮点数)1.124390,(浮点数)1.505981,(浮点数)1.461,(浮点数)4636,(浮点数,(浮点数)0.981323,(浮点数)1.309570,(浮点数)1.618042,(浮点数)1.228760,(浮点数)1.554321,(浮点数)1.756470,(浮点数)0.734375,(浮点数)0.895752,(浮点数)1.225586,(浮点数)0.841797,(浮点数)1.055664,(浮点数)1.24920166,(浮点数)1.119385,(浮点数)1.486206,(浮点数)0.894409,(浮点数)1.539063,(浮点数)1.8289691,(浮点数)28335,(浮点数)1.858276,
(float)0.676025, (float)0.933105, (float)1.490845, (float)0.821289, (float)1.491821, (float)1.739868, (float)0.923218, (float)1.144653, (float)1.580566, (float)1.057251, (float)1.345581, (float)1.635864, (float)0.888672, (float)1.074951, (float)1.353149, (float)0.942749, (float)1.195435, (float)1.505493, (float)1.492310, (float)1.788086, (float)2.039673, (float)1.070313, (float)1.634399, (float)1.860962, (float)1.253296, (float)1.488892, (float)1.686035, (float)0.647095, (float)0.864014, (float)1.401855, (float)0.866699, (float)1.254883, (float)1.453369, (float)1.063965, (float)1.532593, (float)1.731323, (float)1.167847, (float)1.521484, (float)1.884033, (float)0.956055, (float)1.502075, (float)1.745605, (float)0.928711, (float)1.288574, (float)1.479614, (float)1.088013, (float)1.380737, (float)1.570801, (float)0.905029, (float)1.186768, (float)1.371948, (float)1.057861, (float)1.421021, (float)1.617432, (float)1.108276, (float)1.312500, (float)1.501465, (float)0.979492, (float)1.416992, (float)1.624268, (float)1.276001, (float)1.661011, (float)2.007935, (float)0.993042, (float)1.168579, (float)1.331665, (float)0.778198, (float)0.944946, (float)1.235962, (float)1.223755, (float)1.491333, (float)1.815674, (float)0.852661, (float)1.350464, (float)1.722290, (float)1.134766, (float)1.593140, (float)1.787354, (float)1.051392, (float)1.339722, (float)1.531006, (float)0.803589, (float)1.271240, (float)1.652100, (float)0.755737, (float)1.143555, (float)1.639404, (float)0.700928, (float)0.837280, (float)1.130371, (float)0.942749, (float)1.197876, (float)1.669800, (float)0.993286, (float)1.378296, (float)1.566528, (float)0.801025, (float)1.095337, (float)1.298950, (float)0.739990, (float)1.032959, (float)1.383667, (float)0.845703, (float)1.072266, (float)1.543823, (float)0.915649, (float)1.072266, (float)1.224487, (float)1.021973, (float)1.226196, (float)1.481323, (float)0.999878, (float)1.204102, (float)1.555908, (float)0.722290, (float)0.913940, (float)1.340210, (float)0.673340, (float)0.835938, (float)1.259521, (float)0.832397, (float)1.208374, (float)1.394165, (float)0.962158, (float)1.576172, (float)1.912842, (float)1.166748, (float)1.370850, (float)1.556763, (float)0.946289, (float)1.138550, (float)1.400391, (float)1.035034, (float)1.218262, (float)1.386475, (float)1.393799, (float)1.717773, (float)2.000244, (float)0.972656, (float)1.260986, (float)1.760620, (float)1.028198, (float)1.288452, (float)1.484619,
(浮点数)0.676025,(浮点数)0.933105,(浮点数)1.490845,(浮点数)0.821289,(浮点数)1.491821,(浮点数)1.739868,(浮点数)0.923218,(浮点数)1.144653,(浮点数)1.580566,(浮点数)1.057251,(浮点数)1.345581,(浮点数)1.635864,(浮点数)0.888672,(浮点数)1.074951,(浮点数)1.353149,(浮点数)0.942749,(浮点数)1.195,(浮点数)1.505493,(浮点数)2318086,(浮点数)2.039673,(浮点数)1.070313,(浮点数)1.634399,(浮点数)1.860962,(浮点数)1.253296,(浮点数)1.488892,(浮点数)1.686035,(浮点数)0.647095,(浮点数)0.86401855,(浮点数)0.866699,(浮点数)1.254883,(浮点数)1.453369,(浮点数)1.063965,(浮点数)1.532593,(浮点数)1.731323,(浮点数)1.167847,(浮点数)1.52148403,(浮点数)1.5025,(浮点数),浮点数,(浮点数)1.745605,(浮点数)0.928711,(浮点数)1.288574,(浮点数)1.479614,(浮点数)1.088013,(浮点数)1.380737,(浮点数)1.570801,(浮点数)0.905029,(浮点数)1.186768,(浮点数)1.371948,(浮点数)1.057861,(浮点数)1.421021,(浮点数)1.617432,(浮点数)1.108276,(浮点数)1.312500,(浮点数)1.501465,(浮点数)0.979492,(浮点数)1.626001,(浮点数)浮点数,(浮点数)1.661011,(浮点数)2.007935,(浮点数)0.993042,(浮点数)1.168579,(浮点数)1.331665,(浮点数)0.778198,(浮点数)0.944946,(浮点数)1.235962,(浮点数)1.223755,(浮点数)1.491333,(浮点数)1.815674,(浮点数)0.852661,(浮点数)1.350464,(浮点数)1.722290,(浮点数)1.134766,(浮点数)1.593140,(浮点数)1.787354,(浮点数)1.051392,(浮点数)1.3397536,(浮点数)8030.589,(浮点数,(浮点数)1.271240,(浮点数)1.652100,(浮点数)0.755737,(浮点数)1.143555,(浮点数)1.639404,(浮点数)0.700928,(浮点数)0.837280,(浮点数)1.130371,(浮点数)0.942749,(浮点数)1.197876,(浮点数)1.669800,(浮点数)0.993286,(浮点数)1.378296,(浮点数)1.566528,(浮点数)0.801025,(浮点数)1.095337,(浮点数)1.298950,(浮点数)0.739990,(浮点数)1.033867,(浮点数)0.845703,(浮动)1.072266,(浮动)1.543823,(浮动)0.915649,(浮动)1.072266,(浮动)1.224487,(浮动)1.021973,(浮动)1.226196,(浮动)1.481323,(浮动)0.999878,(浮动)1.204102,(浮动)1.555908,(浮动)0.722290,(浮动)0.913940,(浮动)1.340210,(浮动)0.673340,(浮动)0,(浮动)0.835938,(浮动)1.259521,(浮动)0.239274,(浮动),浮动,(浮动)0.962158,(浮动)1.576172,(浮动)1.912842,(浮动)1.166748,(浮动)1.370850,(浮动)1.556763,(浮动)0.946289,(浮动)1.138550,(浮动)1.400391,(浮动)1.035034,(浮动)1.28821622,(浮动)1.386475,(浮动)1.393799,(浮动)1.717773,(浮动)2.000244,(浮动)0.972656,(浮动)1.260986,(浮动)1.0281452,(浮动)1.484619,
(float)0.773560, (float)1.258057, (float)1.756714, (float)1.080322, (float)1.328003, (float)1.742676, (float)0.823975, (float)1.450806, (float)1.917725, (float)0.859009, (float)1.016602, (float)1.191895, (float)0.843994, (float)1.131104, (float)1.645020, (float)1.189697, (float)1.702759, (float)1.894409, (float)1.346680, (float)1.763184, (float)2.066040, (float)0.980469, (float)1.253784, (float)1.441650, (float)1.338135, (float)1.641968, (float)1.932739, (float)1.223267, (float)1.424194, (float)1.626465, (float)0.765747, (float)1.004150, (float)1.579102, (float)1.042847, (float)1.269165, (float)1.647461, (float)0.968750, (float)1.257568, (float)1.555786, (float)0.826294, (float)0.993408, (float)1.275146, (float)0.742310, (float)0.950439, (float)1.430542, (float)1.054321, (float)1.439819, (float)1.828003, (float)1.072998, (float)1.261719, (float)1.441895, (float)0.859375, (float)1.036377, (float)1.314819, (float)0.895752, (float)1.267212, (float)1.605591, (float)0.805420, (float)0.962891, (float)1.142334, (float)0.795654, (float)1.005493, (float)1.468506, (float)1.105347, (float)1.313843, (float)1.584839, (float)0.792236, (float)1.221802, (float)1.465698, (float)1.170532, (float)1.467651, (float)1.664063, (float)0.838257, (float)1.153198, (float)1.342163, (float)0.968018, (float)1.198242, (float)1.391235, (float)1.250122, (float)1.623535, (float)1.823608, (float)0.711670, (float)1.058350, (float)1.512085, (float)1.204834, (float)1.454468, (float)1.739136, (float)1.137451, (float)1.421753, (float)1.620117, (float)0.820435, (float)1.322754, (float)1.578247, (float)0.798706, (float)1.005005, (float)1.213867, (float)0.980713, (float)1.324951, (float)1.512939, (float)1.112305, (float)1.438843, (float)1.735596, (float)1.135498, (float)1.356689, (float)1.635742, (float)1.101318, (float)1.387451, (float)1.686523, (float)0.849854, (float)1.276978, (float)1.523438, (float)1.377930, (float)1.627563, (float)1.858154, (float)0.884888, (float)1.095459, (float)1.287476, (float)1.289795, (float)1.505859, (float)1.756592, (float)0.817505, (float)1.384155, (float)1.650513, (float)1.446655, (float)1.702148, (float)1.931885, (float)0.835815, (float)1.023071, (float)1.385376, (float)0.916626, (float)1.139038, (float)1.335327, (float)0.980103, (float)1.174072, (float)1.453735, (float)1.705688, (float)2.153809, (float)2.398315, (float)2.743408, (float)1.797119, (float)2.016846, (float)2.445679, (float)2.701904, (float)1.990356, (float)2.219116, (float)2.576416, (float)2.813477,
(浮点数)0.773560,(浮点数)1.258057,(浮点数)1.756714,(浮点数)1.080322,(浮点数)1.328003,(浮点数)1.742676,(浮点数)0.823975,(浮点数)1.450806,(浮点数)1.917725,(浮点数)0.859009,(浮点数)1.016602,(浮点数)1.191895,(浮点数)0.843994,(浮点数)1.131104,(浮点数)1.645020,(浮点数)1.189697,(浮点数)1.702759,(浮点数)1.89668,(浮点数)31874,(浮点数)2.066040,(浮点数)0.980469,(浮点数)1.253784,(浮点数)1.441650,(浮点数)1.338135,(浮点数)1.641968,(浮点数)1.932739,(浮点数)1.223267,(浮点数)1.424194,(浮点数)1.626465,(浮点数)0.765747,(浮点数)1.004150,(浮点数)1.579102,(浮点数)1.042847,(浮点数)1.269165,(浮点数)1.647461,(浮点数)0.968750,(浮点数)1.257568,(浮点数)1.5557829408,(浮点数,(浮点数)1.275146,(浮点数)0.742310,(浮点数)0.950439,(浮点数)1.430542,(浮点数)1.054321,(浮点数)1.439819,(浮点数)1.828003,(浮点数)1.072998,(浮点数)1.261719,(浮点数)1.441895,(浮点数)0.859375,(浮点数)1.036377,(浮点数)1.314819,(浮点数)0.895752,(浮点数)1.267212,(浮点数)1.605591,(浮点数)0.805420,(浮点数)1.567954,(浮点数)1.005493,(浮点数)1.468506,(浮点数)1.105347,(浮点数)1.313843,(浮点数)1.584839,(浮点数)0.792236,(浮点数)1.221802,(浮点数)1.465698,(浮点数)1.170532,(浮点数)1.467651,(浮点数)1.664063,(浮点数)0.838257,(浮点数)1.153198,(浮点数)1.342163,(浮点数)0.968018,(浮点数)1.198242,(浮点数)1.391235,(浮点数)1.250122,(浮点数)1.6235828,(浮点数)1670,(浮点数,(浮点数)1.058350,(浮点数)1.512085,(浮点数)1.204834,(浮点数)1.454468,(浮点数)1.739136,(浮点数)1.137451,(浮点数)1.421753,(浮点数)1.620117,(浮点数)0.820435,(浮点数)1.322754,(浮点数)1.578247,(浮点数)0.798706,(浮点数)1.005005,(浮点数)1.213867,(浮点数)0.980713,(浮点数)1.324951,(浮点数)1.512939,(浮点数)1.112885596,(浮点数)浮点数,(浮点数)1.135498,(浮点数)1.356689,(浮点数)1.635742,(浮点数)1.101318,(浮点数)1.387451,(浮点数)1.686523,(浮点数)0.849854,(浮点数)1.276978,(浮点数)1.523438,(浮点数)1.377930,(浮点数)1.627563,(浮点数)1.858154,(浮点数)0.884888,(浮点数)1.095459,(浮点数)1.287476,(浮点数)1.289795,(浮点数)1.505859,(浮点数)1.756592,(浮点数)0.75815,(浮点数),浮点数,(浮动)1.446655,(浮动)1.702148,(浮动)1.931885,(浮动)0.835815,(浮动)1.023071,(浮动)1.385376,(浮动)0.916626,(浮动)1.139038,(浮动)1.335327,(浮动)0.980103,(浮动)1.174072,(浮动)1.453735,(浮动)1.705688,(浮动)2.153809,(浮动)2.398315,(浮动)2.743408,(浮动)1.797119,(浮动)2.016446,(浮动)2.701904,(浮动)1.990356,(浮动)2.219116,(浮动)2.576416,(浮动)2.813477,
(float)1.849365, (float)2.190918, (float)2.611572, (float)2.835083, (float)1.657959, (float)1.854370, (float)2.159058, (float)2.726196, (float)1.437744, (float)1.897705, (float)2.253174, (float)2.655396, (float)2.028687, (float)2.247314, (float)2.542358, (float)2.875854, (float)1.736938, (float)1.922119, (float)2.185913, (float)2.743408, (float)1.521606, (float)1.870972, (float)2.526855, (float)2.786987, (float)1.841431, (float)2.050659, (float)2.463623, (float)2.857666, (float)1.590088, (float)2.067261, (float)2.427979, (float)2.794434, (float)1.746826, (float)2.057373, (float)2.320190, (float)2.800781, (float)1.734619, (float)1.940552, (float)2.306030, (float)2.826416, (float)1.786255, (float)2.204468, (float)2.457520, (float)2.795288, (float)1.861084, (float)2.170532, (float)2.414551, (float)2.763672, (float)2.001465, (float)2.307617, (float)2.552734, (float)2.811890, (float)1.784424, (float)2.124146, (float)2.381592, (float)2.645508, (float)1.888794, (float)2.135864, (float)2.418579, (float)2.861206, (float)2.301147, (float)2.531250, (float)2.724976, (float)2.913086, (float)1.837769, (float)2.051270, (float)2.261963, (float)2.553223, (float)2.012939, (float)2.221191, (float)2.440186, (float)2.678101, (float)1.429565, (float)1.858276, (float)2.582275, (float)2.845703, (float)1.622803, (float)1.897705, (float)2.367310, (float)2.621094, (float)1.581543, (float)1.960449, (float)2.515869, (float)2.736450, (float)1.419434, (float)1.933960, (float)2.394653, (float)2.746704, (float)1.721924, (float)2.059570, (float)2.421753, (float)2.769653, (float)1.911011, (float)2.220703, (float)2.461060, (float)2.740723, (float)1.581177, (float)1.860840, (float)2.516968, (float)2.874634, (float)1.870361, (float)2.098755, (float)2.432373, (float)2.656494, (float)2.059692, (float)2.279785, (float)2.495605, (float)2.729370, (float)1.815674, (float)2.181519, (float)2.451538, (float)2.680542, (float)1.407959, (float)1.768311, (float)2.343018, (float)2.668091, (float)2.168701, (float)2.394653, (float)2.604736, (float)2.829346, (float)1.636230, (float)1.865723, (float)2.329102, (float)2.824219, (float)1.878906, (float)2.139526, (float)2.376709, (float)2.679810, (float)1.765381, (float)1.971802, (float)2.195435, (float)2.586914, (float)2.164795, (float)2.410889, (float)2.673706, (float)2.903198, (float)2.071899, (float)2.331055, (float)2.645874, (float)2.907104, (float)2.026001, (float)2.311523, (float)2.594849, (float)2.863892, (float)1.948975, (float)2.180786, (float)2.514893, (float)2.797852, (float)1.881836, (float)2.130859, (float)2.478149, (float)2.804199, (float)2.238159, (float)2.452759, (float)2.652832, (float)2.868286, (float)1.897949, (float)2.101685, (float)2.524292, (float)2.880127, (float)1.856445, (float)2.074585, (float)2.541016, (float)2.791748, (float)1.695557, (float)2.199097, (float)2.506226, (float)2.742676, (float)1.612671, (float)1.877075, (float)2.435425, (float)2.732910, (float)1.568848, (float)1.786499, (float)2.194580, (float)2.768555, (float)1.953369, (float)2.164551, (float)2.486938, (float)2.874023, (float)1.388306, (float)1.725342, (float)2.384521, (float)2.771851, (float)2.115356, (float)2.337769, (float)2.592896, (float)2.864014, (float)1.905762, (float)2.111328, (float)2.363525, (float)2.789307,
(浮点数)1.849365,(浮点数)2.190918,(浮点数)2.611572,(浮点数)2.835083,(浮点数)1.657959,(浮点数)1.854370,(浮点数)2.159058,(浮点数)2.726196,(浮点数)1.437744,(浮点数)1.897705,(浮点数)2.253174,(浮点数)2.028687,(浮点数)2.2473314,(浮点数)2.875854,(浮点数)1.736938,(浮点数)1.922119,(浮点数)2.748,(浮点数)1853408,(浮点数)1.521606,(浮动)1.870972,(浮动)2.526855,(浮动)2.786987,(浮动)1.841431,(浮动)2.050659,(浮动)2.463623,(浮动)2.857666,(浮动)1.590088,(浮动)2.067261,(浮动)2.427979,(浮动)2.794434,(浮动)1.746826,(浮动)2.057373,(浮动)2.320190,(浮动)2.800781,(浮动)1.734619,(浮动)1.940552,(浮动)2.3068216,(浮动,(浮点数)2.204468,(浮点数)2.457520,(浮点数)2.795288,(浮点数)1.861084,(浮点数)2.170532,(浮点数)2.414551,(浮点数)2.763672,(浮点数)2.001465,(浮点数)2.307617,(浮点数)2.552734,(浮点数)2.811890,(浮点数)1.784424,(浮点数)2.124146,(浮点数)2.381592,(浮点数)2.645508,(浮点数)1.888794,(浮点数)2.135864,(浮点数)2.4185707,(浮点数)2.114307,(浮点数)2.531250,(浮点数)2.724976,(浮点数)2.913086,(浮点数)1.837769,(浮点数)2.051270,(浮点数)2.261963,(浮点数)2.553223,(浮点数)2.012939,(浮点数)2.221191,(浮点数)2.440186,(浮点数)2.678101,(浮点数)1.429565,(浮点数)1.858276,(浮点数)2.582275,(浮点数)2.845703,(浮点数)1.622803,(浮点数)1.897705,(浮点数)2.367310,(浮点数)2.621094,(浮点数)9601,(浮点数,(浮点数)2.515869,(浮点数)2.736450,(浮点数)1.419434,(浮点数)1.933960,(浮点数)2.394653,(浮点数)2.746704,(浮点数)1.721924,(浮点数)2.059570,(浮点数)2.421753,(浮点数)2.769653,(浮点数)1.911011,(浮点数)2.220703,(浮点数)2.461060,(浮点数)2.740723,(浮点数)1.581177,(浮点数)1.860,(浮点数)2.516968,(浮点数)2.87461,(浮点数)368755,(浮点数)2.432373,(浮点数)2.656494,(浮点数)2.059692,(浮点数)2.279785,(浮点数)2.495605,(浮点数)2.729370,(浮点数)1.815674,(浮点数)2.181519,(浮点数)2.451538,(浮点数)2.680542,(浮点数)1.407959,(浮点数)1.768311,(浮点数)2.343018,(浮点数)2.668091,(浮点数)2.168701,(浮点数)2.394653,(浮点数)2.604736,(浮点数)2.829346,(浮点数)1.57263622,(浮点数)329102,(浮点数,(浮动)2.824219,(浮动)1.878906,(浮动)2.139526,(浮动)2.376709,(浮动)2.679810,(浮动)1.765381,(浮动)1.971802,(浮动)2.195435,(浮动)2.586914,(浮动)2.164795,(浮动)2.410889,(浮动)2.673706,(浮动)2.903198,(浮动)2.071899,(浮动)2.331055,(浮动)2.645874,(浮动)2.907104,(浮动)2.026001,(浮动)2.1523149,(浮动)2.863892,(浮点数)1.948975,(浮点数)2.180786,(浮点数)2.514893,(浮点数)2.797852,(浮点数)1.881836,(浮点数)2.130859,(浮点数)2.478149,(浮点数)2.804199,(浮点数)2.238159,(浮点数)2.452759,(浮点数)2.652832,(浮点数)2.868286,(浮点数)1.897949,(浮点数)2.101685,(浮点数)2.524292,(浮点数)2.8801227,(浮点数)1.856445,(浮点数)2.0745542,(浮点数)1742,(浮点数,(浮点数)1.695557,(浮点数)2.199097,(浮点数)2.506226,(浮点数)2.742676,(浮点数)1.612671,(浮点数)1.877075,(浮点数)2.435425,(浮点数)2.732910,(浮点数)1.568848,(浮点数)1.786499,(浮点数)2.194580,(浮点数)2.768555,(浮点数)1.953369,(浮点数)2.164551,(浮点数)2.486938,(浮点数)2.874023,(浮点数)1.725342,(浮点数)2.38772,(浮点数)1851,(浮点数)2.115356,(浮动)2.337769,(浮动)2.592896,(浮动)2.864014,(浮动)1.905762,(浮动)2.111328,(浮动)2.363525,(浮动)2.789307,
(float)1.882568, (float)2.332031, (float)2.598267, (float)2.827637, (float)1.683594, (float)2.088745, (float)2.361938, (float)2.608643, (float)1.874023, (float)2.182129, (float)2.536133, (float)2.766968, (float)1.861938, (float)2.070435, (float)2.309692, (float)2.700562, (float)1.722168, (float)2.107422, (float)2.477295, (float)2.837646, (float)1.926880, (float)2.184692, (float)2.442627, (float)2.663818, (float)2.123901, (float)2.337280, (float)2.553101, (float)2.777466, (float)1.588135, (float)1.911499, (float)2.212769, (float)2.543945, (float)2.053955, (float)2.370850, (float)2.712158, (float)2.939941, (float)2.210449, (float)2.519653, (float)2.770386, (float)2.958618, (float)2.199463, (float)2.474731, (float)2.718262, (float)2.919922, (float)1.960083, (float)2.175415, (float)2.608032, (float)2.888794, (float)1.953735, (float)2.185181, (float)2.428223, (float)2.809570, (float)1.615234, (float)2.036499, (float)2.576538, (float)2.834595, (float)1.621094, (float)2.028198, (float)2.431030, (float)2.664673, (float)1.824951, (float)2.267456, (float)2.514526, (float)2.747925, (float)1.994263, (float)2.229126, (float)2.475220, (float)2.833984, (float)1.746338, (float)2.011353, (float)2.588257, (float)2.826904, (float)1.562866, (float)2.135986, (float)2.471680, (float)2.687256, (float)1.748901, (float)2.083496, (float)2.460938, (float)2.686279, (float)1.758057, (float)2.131470, (float)2.636597, (float)2.891602, (float)2.071289, (float)2.299072, (float)2.550781, (float)2.814331, (float)1.839600, (float)2.094360, (float)2.496460, (float)2.723999, (float)1.882202, (float)2.088257, (float)2.636841, (float)2.923096, (float)1.957886, (float)2.153198, (float)2.384399, (float)2.615234, (float)1.992920, (float)2.351196, (float)2.654419, (float)2.889771, (float)2.012817, (float)2.262451, (float)2.643799, (float)2.903076, (float)2.025635, (float)2.254761, (float)2.508423, (float)2.784058, (float)2.316040, (float)2.589355, (float)2.794189, (float)2.963623, (float)1.741211, (float)2.279541, (float)2.578491, (float)2.816284, (float)1.845337, (float)2.055786, (float)2.348511, (float)2.822021, (float)1.679932, (float)1.926514, (float)2.499756, (float)2.835693, (float)1.722534, (float)1.946899, (float)2.448486, (float)2.728760, (float)1.829834, (float)2.043213, (float)2.580444, (float)2.867676, (float)1.676636, (float)2.071655, (float)2.322510, (float)2.704834, (float)1.791504, (float)2.113525, (float)2.469727, (float)2.784058, (float)1.977051, (float)2.215088, (float)2.497437, (float)2.726929, (float)1.800171, (float)2.106689, (float)2.357788, (float)2.738892, (float)1.827759, (float)2.170166, (float)2.525879, (float)2.852417, (float)1.918335, (float)2.132813, (float)2.488403, (float)2.728149, (float)1.916748, (float)2.225098, (float)2.542603, (float)2.857666, (float)1.761230, (float)1.976074, (float)2.507446, (float)2.884521, (float)2.053711, (float)2.367432, (float)2.608032, (float)2.837646, (float)1.595337, (float)2.000977, (float)2.307129, (float)2.578247, (float)1.470581, (float)2.031250, (float)2.375854, (float)2.647583, (float)1.801392, (float)2.128052, (float)2.399780, (float)2.822876, (float)1.853638, (float)2.066650, (float)2.429199, (float)2.751465, (float)1.956299, (float)2.163696, (float)2.394775, (float)2.734253,
(浮点数)1.882568,(浮点数)2.332031,(浮点数)2.598267,(浮点数)2.827637,(浮点数)1.683594,(浮点数)2.088745,(浮点数)2.361938,(浮点数)2.608643,(浮点数)1.874023,(浮点数)2.182129,(浮点数)2.536133,(浮点数)2.766968,(浮点数)1.861938,(浮点数)2.070435,(浮点数)2.3096992,(浮点数)2.700562,(浮点数)1.722168,(浮点数)2.107422,(浮点数)2.7676767646,(浮点数)1.926880,(浮子)2.184692,(浮子)2.442627,(浮子)2.663818,(浮子)2.123901,(浮子)2.337280,(浮子)2.553101,(浮子)2.777466,(浮子)1.588135,(浮子)1.911499,(浮子)2.212769,(浮子)2.543945,(浮子)2.053955,(浮子)2.370850,(浮子)2.712158,(浮子)2.939941,(浮子)2.210449,(浮子)2.519653,(浮子)2.38862,(浮子),浮子,(浮点数)2.474731,(浮点数)2.718262,(浮点数)2.919922,(浮点数)1.960083,(浮点数)2.175415,(浮点数)2.608032,(浮点数)2.888794,(浮点数)1.953735,(浮点数)2.185181,(浮点数)2.428223,(浮点数)2.809570,(浮点数)1.615234,(浮点数)2.036499,(浮点数)2.576538,(浮点数)2.834595,(浮点数)1.621094,(浮点数)2.028198,(浮点数)2.431036651,(浮点数,(浮点数)498273)2.267456,(浮子)2.514526,(浮子)2.747925,(浮子)1.994263,(浮子)2.229126,(浮子)2.475220,(浮子)2.833984,(浮子)1.746338,(浮子)2.011353,(浮子)2.588257,(浮子)2.826904,(浮子)1.562866,(浮子)2.135986,(浮子)2.471680,(浮子)2.687256,(浮子)1.748901,(浮子)2.083496,(浮子)2.460938,(浮子)2.75628057,(浮子),浮子,(浮点数)2.636597,(浮点数)2.891602,(浮点数)2.071289,(浮点数)2.299072,(浮点数)2.550781,(浮点数)2.814331,(浮点数)1.839600,(浮点数)2.094360,(浮点数)2.496460,(浮点数)2.723999,(浮点数)1.882202,(浮点数)2.088257,(浮点数)2.636841,(浮点数)2.923096,(浮点数)1.957886,(浮点数)2.153198,(浮点数)2.384399,(浮点数)2.615234,(浮点数)1.992,(浮点数)119356,(浮点数)2.654419,(浮子)2.889771,(浮子)2.012817,(浮子)2.262451,(浮子)2.643799,(浮子)2.903076,(浮子)2.025635,(浮子)2.254761,(浮子)2.508423,(浮子)2.784058,(浮子)2.316040,(浮子)2.589355,(浮子)2.794189,(浮子)2.963623,(浮子)1.741211,(浮子)2.279541,(浮子)2.578491,(浮子)2.816284,(浮子)1,(浮子)1.84535311,(浮子,(浮动)2.822021,(浮动)1.679932,(浮动)1.926514,(浮动)2.499756,(浮动)2.835693,(浮动)1.722534,(浮动)1.946899,(浮动)2.448486,(浮动)2.728760,(浮动)1.829834,(浮动)2.043213,(浮动)2.580444,(浮动)2.867676,(浮动)1.676636,(浮动)2.071655,(浮动)2.322510,(浮动)2.704834,(浮动)1.791504,(浮动)2.1134627,(浮动)2.784058,(浮点数)1.977051,(浮点数)2.215088,(浮点数)2.497437,(浮点数)2.726929,(浮点数)1.800171,(浮点数)2.106689,(浮点数)2.357788,(浮点数)2.738892,(浮点数)1.827759,(浮点数)2.170166,(浮点数)2.525879,(浮点数)2.852417,(浮点数)1.918335,(浮点数)2.132813,(浮点数)2.488403,(浮点数)2.728149,(浮点数)1.916748,(浮点数)2.225542698,(浮点数)浮点数,(浮点数)1.761230,(浮点数)1.976074,(浮点数)2.507446,(浮点数)2.884521,(浮点数)2.053711,(浮点数)2.367432,(浮点数)2.608032,(浮点数)2.837646,(浮点数)1.595337,(浮点数)2.000977,(浮点数)2.307129,(浮点数)2.578247,(浮点数)1.470581,(浮点数)2.031250,(浮点数)2.375854,(浮点数)2.647583,(浮点数)1.801392,(浮点数)2.392876,(浮点数)1.853638,(浮动)2.066650,(浮动)2.429199,(浮动)2.751465,(浮动)1.956299,(浮动)2.163696,(浮动)2.394775,(浮动)2.734253,
(float)1.963623, (float)2.275757, (float)2.585327, (float)2.865234, (float)1.887451, (float)2.105469, (float)2.331787, (float)2.587402, (float)2.120117, (float)2.443359, (float)2.733887, (float)2.941406, (float)1.506348, (float)1.766968, (float)2.400513, (float)2.851807, (float)1.664551, (float)1.981079, (float)2.375732, (float)2.774414, (float)1.720703, (float)1.978882, (float)2.391479, (float)2.640991, (float)1.483398, (float)1.814819, (float)2.434448, (float)2.722290, (float)1.769043, (float)2.136597, (float)2.563721, (float)2.774414, (float)1.810791, (float)2.049316, (float)2.373901, (float)2.613647, (float)1.788330, (float)2.005981, (float)2.359131, (float)2.723145, (float)1.785156, (float)1.993164, (float)2.399780, (float)2.832520, (float)1.695313, (float)2.022949, (float)2.522583, (float)2.745117, (float)1.584106, (float)1.965576, (float)2.299927, (float)2.715576, (float)1.894897, (float)2.249878, (float)2.655884, (float)2.897705, (float)1.720581, (float)1.995728, (float)2.299438, (float)2.557007, (float)1.619385, (float)2.173950, (float)2.574219, (float)2.787964, (float)1.883179, (float)2.220459, (float)2.474365, (float)2.825073, (float)1.447632, (float)2.045044, (float)2.555542, (float)2.744873, (float)1.502686, (float)2.156616, (float)2.653320, (float)2.846558, (float)1.711548, (float)1.944092, (float)2.282959, (float)2.685791, (float)1.499756, (float)1.867554, (float)2.341064, (float)2.578857, (float)1.916870, (float)2.135132, (float)2.568237, (float)2.826050, (float)1.498047, (float)1.711182, (float)2.223267, (float)2.755127, (float)1.808716, (float)1.997559, (float)2.256470, (float)2.758545, (float)2.088501, (float)2.402710, (float)2.667358, (float)2.890259, (float)1.545044, (float)1.819214, (float)2.324097, (float)2.692993, (float)1.796021, (float)2.012573, (float)2.505737, (float)2.784912, (float)1.786499, (float)2.041748, (float)2.290405, (float)2.650757, (float)1.938232, (float)2.264404, (float)2.529053, (float)2.796143 };
(浮动)1.963623,(浮动)2.275757,(浮动)2.585327,(浮动)2.865234,(浮动)1.887451,(浮动)2.105469,(浮动)2.331787,(浮动)2.587402,(浮动)2.120117,(浮动)2.443359,(浮动)2.733887,(浮动)2.941406,(浮动)1.506348,(浮动)1.766968,(浮动)2.400513,(浮动)2.851807,(浮动)1.664551,(浮动)1.981079,(浮动)2.377732,(浮动)1.720703,(浮子)1.978882,(浮子)2.391479,(浮子)2.640991,(浮子)1.483398,(浮子)1.814819,(浮子)2.434448,(浮子)2.722290,(浮子)1.769043,(浮子)2.136597,(浮子)2.563721,(浮子)2.774414,(浮子)1.810791,(浮子)2.049316,(浮子)2.373901,(浮子)2.613647,(浮子)1.788330,(浮子)2.005981,(浮子)2.35913145,(浮子),浮子,(浮子)1.993164,(浮子)2.399780,(浮子)2.832520,(浮子)1.695313,(浮子)2.022949,(浮子)2.522583,(浮子)2.745117,(浮子)1.584106,(浮子)1.965576,(浮子)2.299927,(浮子)2.715576,(浮子)1.894897,(浮子)2.249878,(浮子)2.655884,(浮子)2.897705,(浮子)1.720581,(浮子)1,(浮子)1.995728,(浮子)2.299438,(浮子)2.937007,(浮子)2.173950,(浮点数)2.574219,(浮点数)2.787964,(浮点数)1.883179,(浮点数)2.220459,(浮点数)2.474365,(浮点数)2.825073,(浮点数)1.447632,(浮点数)2.045044,(浮点数)2.555542,(浮点数)2.744873,(浮点数)1.502686,(浮点数)2.653320,(浮点数)2.84656558,(浮点数)1.711548,(浮点数)1.944092,(浮点数)2.282959,(浮点数)2.2829959,(浮点数)2.86751,(浮点数)86751,(浮点数,(浮点数)2.341064,(浮点数)2.578857,(浮点数)1.916870,(浮点数)2.135132,(浮点数)2.568237,(浮点数)2.826050,(浮点数)1.498047,(浮点数)1.711182,(浮点数)2.223267,(浮点数)2.755127,(浮点数)1.808716,(浮点数)1.9975757559,(浮点数)2.256470,(浮点数)2.088501,(浮点数)2.402710,(浮点数)2.667358,(浮点数)2.890259,(浮点数)1.504814,(浮点数)2.324097,(浮动)2.692993,(浮动)1.796021,(浮动)2.012573,(浮动)2.505737,(浮动)2.784912,(浮动)1.786499,(浮动)2.041748,(浮动)2.290405,(浮动)2.650757,(浮动)1.938232,(浮动)2.264404,(浮动)2.529053,(浮动)2.796143};
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
anaFilter.h
anaFilter.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_ANAFILTER_H #define __iLBC_ANAFILTER_H
#ifndef __iLBC_ANAFILTER_H #define __iLBC_ANAFILTER_H
void anaFilter(
空滤器(
float *In, /* (i) Signal to be filtered */ float *a, /* (i) LP parameters */ int len,/* (i) Length of signal */ float *Out, /* (o) Filtered signal */ float *mem /* (i/o) Filter state */ );
float *In, /* (i) Signal to be filtered */ float *a, /* (i) LP parameters */ int len,/* (i) Length of signal */ float *Out, /* (o) Filtered signal */ float *mem /* (i/o) Filter state */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
anaFilter.c
anaFilter.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <string.h> #include "iLBC_define.h"
#include <string.h> #include "iLBC_define.h"
/*----------------------------------------------------------------* * LP analysis filter. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * LP analysis filter. *---------------------------------------------------------------*/
void anaFilter( float *In, /* (i) Signal to be filtered */ float *a, /* (i) LP parameters */ int len,/* (i) Length of signal */ float *Out, /* (o) Filtered signal */ float *mem /* (i/o) Filter state */ ){ int i, j; float *po, *pi, *pm, *pa;
void anaFilter( float *In, /* (i) Signal to be filtered */ float *a, /* (i) LP parameters */ int len,/* (i) Length of signal */ float *Out, /* (o) Filtered signal */ float *mem /* (i/o) Filter state */ ){ int i, j; float *po, *pi, *pm, *pa;
po = Out;
po=Out;
/* Filter first part using memory from past */
/* Filter first part using memory from past */
for (i=0; i<LPC_FILTERORDER; i++) { pi = &In[i]; pm = &mem[LPC_FILTERORDER-1]; pa = a; *po=0.0;
for (i=0; i<LPC_FILTERORDER; i++) { pi = &In[i]; pm = &mem[LPC_FILTERORDER-1]; pa = a; *po=0.0;
for (j=0; j<=i; j++) { *po+=(*pa++)*(*pi--); } for (j=i+1; j<LPC_FILTERORDER+1; j++) {
for (j=0; j<=i; j++) { *po+=(*pa++)*(*pi--); } for (j=i+1; j<LPC_FILTERORDER+1; j++) {
*po+=(*pa++)*(*pm--); } po++; }
*po+=(*pa++)*(*pm--); } po++; }
/* Filter last part where the state is entirely in the input vector */
/* Filter last part where the state is entirely in the input vector */
for (i=LPC_FILTERORDER; i<len; i++) { pi = &In[i]; pa = a; *po=0.0; for (j=0; j<LPC_FILTERORDER+1; j++) { *po+=(*pa++)*(*pi--); } po++; }
for (i=LPC_FILTERORDER; i<len; i++) { pi = &In[i]; pa = a; *po=0.0; for (j=0; j<LPC_FILTERORDER+1; j++) { *po+=(*pa++)*(*pi--); } po++; }
/* Update state vector */
/* Update state vector */
memcpy(mem, &In[len-LPC_FILTERORDER], LPC_FILTERORDER*sizeof(float)); }
memcpy(mem, &In[len-LPC_FILTERORDER], LPC_FILTERORDER*sizeof(float)); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
createCB.h
createCB.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_CREATECB_H #define __iLBC_CREATECB_H
#ifndef __iLBC_CREATECB_H #define __iLBC_CREATECB_H
void filteredCBvecs( float *cbvectors, /* (o) Codebook vector for the higher section */
void filteredCBvecs( float *cbvectors, /* (o) Codebook vector for the higher section */
float *mem, /* (i) Buffer to create codebook vectors from */ int lMem /* (i) Length of buffer */ );
float *mem, /* (i) Buffer to create codebook vectors from */ int lMem /* (i) Length of buffer */ );
void searchAugmentedCB( int low, /* (i) Start index for the search */ int high, /* (i) End index for the search */ int stage, /* (i) Current stage */ int startIndex, /* (i) CB index for the first augmented vector */ float *target, /* (i) Target vector for encoding */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *max_measure, /* (i/o) Currently maximum measure */ int *best_index,/* (o) Currently the best index */ float *gain, /* (o) Currently the best gain */ float *energy, /* (o) Energy of augmented codebook vectors */ float *invenergy/* (o) Inv energy of aug codebook vectors */ );
void searchAugmentedCB( int low, /* (i) Start index for the search */ int high, /* (i) End index for the search */ int stage, /* (i) Current stage */ int startIndex, /* (i) CB index for the first augmented vector */ float *target, /* (i) Target vector for encoding */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *max_measure, /* (i/o) Currently maximum measure */ int *best_index,/* (o) Currently the best index */ float *gain, /* (o) Currently the best gain */ float *energy, /* (o) Energy of augmented codebook vectors */ float *invenergy/* (o) Inv energy of aug codebook vectors */ );
void createAugmentedVec( int index, /* (i) Index for the aug vector to be created */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *cbVec /* (o) The construced codebook vector */ );
void createAugmentedVec( int index, /* (i) Index for the aug vector to be created */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *cbVec /* (o) The construced codebook vector */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
createCB.c
createCB.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "iLBC_define.h" #include "constants.h" #include <string.h> #include <math.h>
#include "iLBC_define.h" #include "constants.h" #include <string.h> #include <math.h>
/*----------------------------------------------------------------* * Construct an additional codebook vector by filtering the * initial codebook buffer. This vector is then used to expand * the codebook with an additional section. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Construct an additional codebook vector by filtering the * initial codebook buffer. This vector is then used to expand * the codebook with an additional section. *---------------------------------------------------------------*/
void filteredCBvecs( float *cbvectors, /* (o) Codebook vectors for the higher section */ float *mem, /* (i) Buffer to create codebook vector from */ int lMem /* (i) Length of buffer */ ){ int j, k; float *pp, *pp1; float tempbuff2[CB_MEML+CB_FILTERLEN]; float *pos;
void filteredCBvecs( float *cbvectors, /* (o) Codebook vectors for the higher section */ float *mem, /* (i) Buffer to create codebook vector from */ int lMem /* (i) Length of buffer */ ){ int j, k; float *pp, *pp1; float tempbuff2[CB_MEML+CB_FILTERLEN]; float *pos;
memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float)); memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0, (CB_HALFFILTERLEN+1)*sizeof(float));
memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float)); memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0, (CB_HALFFILTERLEN+1)*sizeof(float));
/* Create codebook vector for higher section by filtering */
/* Create codebook vector for higher section by filtering */
/* do filtering */ pos=cbvectors; memset(pos, 0, lMem*sizeof(float)); for (k=0; k<lMem; k++) { pp=&tempbuff2[k]; pp1=&cbfiltersTbl[CB_FILTERLEN-1]; for (j=0;j<CB_FILTERLEN;j++) { (*pos)+=(*pp++)*(*pp1--); } pos++; } }
/* do filtering */ pos=cbvectors; memset(pos, 0, lMem*sizeof(float)); for (k=0; k<lMem; k++) { pp=&tempbuff2[k]; pp1=&cbfiltersTbl[CB_FILTERLEN-1]; for (j=0;j<CB_FILTERLEN;j++) { (*pos)+=(*pp++)*(*pp1--); } pos++; } }
/*----------------------------------------------------------------* * Search the augmented part of the codebook to find the best * measure. *----------------------------------------------------------------*/
/*----------------------------------------------------------------* * Search the augmented part of the codebook to find the best * measure. *----------------------------------------------------------------*/
void searchAugmentedCB( int low, /* (i) Start index for the search */ int high, /* (i) End index for the search */ int stage, /* (i) Current stage */ int startIndex, /* (i) Codebook index for the first aug vector */ float *target, /* (i) Target vector for encoding */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *max_measure, /* (i/o) Currently maximum measure */ int *best_index,/* (o) Currently the best index */ float *gain, /* (o) Currently the best gain */ float *energy, /* (o) Energy of augmented codebook vectors */ float *invenergy/* (o) Inv energy of augmented codebook vectors */ ) { int icount, ilow, j, tmpIndex; float *pp, *ppo, *ppi, *ppe, crossDot, alfa; float weighted, measure, nrjRecursive; float ftmp;
void searchAugmentedCB( int low, /* (i) Start index for the search */ int high, /* (i) End index for the search */ int stage, /* (i) Current stage */ int startIndex, /* (i) Codebook index for the first aug vector */ float *target, /* (i) Target vector for encoding */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *max_measure, /* (i/o) Currently maximum measure */ int *best_index,/* (o) Currently the best index */ float *gain, /* (o) Currently the best gain */ float *energy, /* (o) Energy of augmented codebook vectors */ float *invenergy/* (o) Inv energy of augmented codebook vectors */ ) { int icount, ilow, j, tmpIndex; float *pp, *ppo, *ppi, *ppe, crossDot, alfa; float weighted, measure, nrjRecursive; float ftmp;
/* Compute the energy for the first (low-5) noninterpolated samples */ nrjRecursive = (float) 0.0; pp = buffer - low + 1; for (j=0; j<(low-5); j++) { nrjRecursive += ( (*pp)*(*pp) ); pp++; } ppe = buffer - low;
/* Compute the energy for the first (low-5) noninterpolated samples */ nrjRecursive = (float) 0.0; pp = buffer - low + 1; for (j=0; j<(low-5); j++) { nrjRecursive += ( (*pp)*(*pp) ); pp++; } ppe = buffer - low;
for (icount=low; icount<=high; icount++) {
for (icount=low; icount<=high; icount++) {
/* Index of the codebook vector used for retrieving energy values */ tmpIndex = startIndex+icount-20;
/* Index of the codebook vector used for retrieving energy values */ tmpIndex = startIndex+icount-20;
ilow = icount-4;
ilow=icount-4;
/* Update the energy recursively to save complexity */ nrjRecursive = nrjRecursive + (*ppe)*(*ppe); ppe--; energy[tmpIndex] = nrjRecursive;
/* Update the energy recursively to save complexity */ nrjRecursive = nrjRecursive + (*ppe)*(*ppe); ppe--; energy[tmpIndex] = nrjRecursive;
/* Compute cross dot product for the first (low-5) samples */
/* Compute cross dot product for the first (low-5) samples */
crossDot = (float) 0.0; pp = buffer-icount; for (j=0; j<ilow; j++) { crossDot += target[j]*(*pp++); }
crossDot = (float) 0.0; pp = buffer-icount; for (j=0; j<ilow; j++) { crossDot += target[j]*(*pp++); }
/* interpolation */ alfa = (float) 0.2; ppo = buffer-4; ppi = buffer-icount-4; for (j=ilow; j<icount; j++) { weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); ppo++; ppi++; energy[tmpIndex] += weighted*weighted; crossDot += target[j]*weighted; alfa += (float)0.2; }
/* interpolation */ alfa = (float) 0.2; ppo = buffer-4; ppi = buffer-icount-4; for (j=ilow; j<icount; j++) { weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); ppo++; ppi++; energy[tmpIndex] += weighted*weighted; crossDot += target[j]*weighted; alfa += (float)0.2; }
/* Compute energy and cross dot product for the remaining samples */ pp = buffer - icount; for (j=icount; j<SUBL; j++) { energy[tmpIndex] += (*pp)*(*pp); crossDot += target[j]*(*pp++); }
/* Compute energy and cross dot product for the remaining samples */ pp = buffer - icount; for (j=icount; j<SUBL; j++) { energy[tmpIndex] += (*pp)*(*pp); crossDot += target[j]*(*pp++); }
if (energy[tmpIndex]>0.0) { invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS); } else { invenergy[tmpIndex] = (float) 0.0; }
if (energy[tmpIndex]>0.0) { invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS); } else { invenergy[tmpIndex] = (float) 0.0; }
if (stage==0) { measure = (float)-10000000.0;
if (stage==0) { measure = (float)-10000000.0;
if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[tmpIndex]; } } else { measure = crossDot*crossDot*invenergy[tmpIndex]; }
if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[tmpIndex]; } } else { measure = crossDot*crossDot*invenergy[tmpIndex]; }
/* check if measure is better */ ftmp = crossDot*invenergy[tmpIndex];
/* check if measure is better */ ftmp = crossDot*invenergy[tmpIndex];
if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
*best_index = tmpIndex; *max_measure = measure; *gain = ftmp; } } }
*best_index = tmpIndex; *max_measure = measure; *gain = ftmp; } } }
/*----------------------------------------------------------------* * Recreate a specific codebook vector from the augmented part. * *----------------------------------------------------------------*/
/*----------------------------------------------------------------* * Recreate a specific codebook vector from the augmented part. * *----------------------------------------------------------------*/
void createAugmentedVec( int index, /* (i) Index for the augmented vector to be created */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *cbVec/* (o) The construced codebook vector */ ) { int ilow, j; float *pp, *ppo, *ppi, alfa, alfa1, weighted;
void createAugmentedVec( int index, /* (i) Index for the augmented vector to be created */ float *buffer, /* (i) Pointer to the end of the buffer for augmented codebook construction */ float *cbVec/* (o) The construced codebook vector */ ) { int ilow, j; float *pp, *ppo, *ppi, alfa, alfa1, weighted;
ilow = index-5;
ilow=指数-5;
/* copy the first noninterpolated part */
/* copy the first noninterpolated part */
pp = buffer-index; memcpy(cbVec,pp,sizeof(float)*index);
pp = buffer-index; memcpy(cbVec,pp,sizeof(float)*index);
/* interpolation */
/* interpolation */
alfa1 = (float)0.2; alfa = 0.0; ppo = buffer-5; ppi = buffer-index-5; for (j=ilow; j<index; j++) { weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); ppo++; ppi++; cbVec[j] = weighted; alfa += alfa1; }
alfa1 = (float)0.2; alfa = 0.0; ppo = buffer-5; ppi = buffer-index-5; for (j=ilow; j<index; j++) { weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); ppo++; ppi++; cbVec[j] = weighted; alfa += alfa1; }
/* copy the second noninterpolated part */
/* copy the second noninterpolated part */
pp = buffer - index; memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));
pp = buffer - index; memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));
}
}
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
doCPLC.h
doCPLC.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_DOLPC_H #define __iLBC_DOLPC_H
#ifndef __iLBC_DOLPC_H #define __iLBC_DOLPC_H
void doThePLC( float *PLCresidual, /* (o) concealed residual */ float *PLClpc, /* (o) concealed LP parameters */ int PLI, /* (i) packet loss indicator 0 - no PL, 1 = PL */ float *decresidual, /* (i) decoded residual */ float *lpc, /* (i) decoded LPC (only used for no PL) */ int inlag, /* (i) pitch lag */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) decoder instance */ );
void doThePLC( float *PLCresidual, /* (o) concealed residual */ float *PLClpc, /* (o) concealed LP parameters */ int PLI, /* (i) packet loss indicator 0 - no PL, 1 = PL */ float *decresidual, /* (i) decoded residual */ float *lpc, /* (i) decoded LPC (only used for no PL) */ int inlag, /* (i) pitch lag */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) decoder instance */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
doCPLC.c
doCPLC.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <string.h> #include <stdio.h>
#include <math.h> #include <string.h> #include <stdio.h>
#include "iLBC_define.h"
#包括“iLBC_define.h”
/*----------------------------------------------------------------* * Compute cross correlation and pitch gain for pitch prediction * of last subframe at given lag. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Compute cross correlation and pitch gain for pitch prediction * of last subframe at given lag. *---------------------------------------------------------------*/
void compCorr( float *cc, /* (o) cross correlation coefficient */ float *gc, /* (o) gain */ float *pm, float *buffer, /* (i) signal buffer */ int lag, /* (i) pitch lag */ int bLen, /* (i) length of buffer */ int sRange /* (i) correlation search length */ ){ int i; float ftmp1, ftmp2, ftmp3;
void compCorr( float *cc, /* (o) cross correlation coefficient */ float *gc, /* (o) gain */ float *pm, float *buffer, /* (i) signal buffer */ int lag, /* (i) pitch lag */ int bLen, /* (i) length of buffer */ int sRange /* (i) correlation search length */ ){ int i; float ftmp1, ftmp2, ftmp3;
/* Guard against getting outside buffer */ if ((bLen-sRange-lag)<0) { sRange=bLen-lag; }
/* Guard against getting outside buffer */ if ((bLen-sRange-lag)<0) { sRange=bLen-lag; }
ftmp1 = 0.0; ftmp2 = 0.0; ftmp3 = 0.0; for (i=0; i<sRange; i++) { ftmp1 += buffer[bLen-sRange+i] * buffer[bLen-sRange+i-lag]; ftmp2 += buffer[bLen-sRange+i-lag] * buffer[bLen-sRange+i-lag]; ftmp3 += buffer[bLen-sRange+i] * buffer[bLen-sRange+i]; }
ftmp1 = 0.0; ftmp2 = 0.0; ftmp3 = 0.0; for (i=0; i<sRange; i++) { ftmp1 += buffer[bLen-sRange+i] * buffer[bLen-sRange+i-lag]; ftmp2 += buffer[bLen-sRange+i-lag] * buffer[bLen-sRange+i-lag]; ftmp3 += buffer[bLen-sRange+i] * buffer[bLen-sRange+i]; }
if (ftmp2 > 0.0) { *cc = ftmp1*ftmp1/ftmp2; *gc = (float)fabs(ftmp1/ftmp2); *pm=(float)fabs(ftmp1)/ ((float)sqrt(ftmp2)*(float)sqrt(ftmp3)); } else { *cc = 0.0; *gc = 0.0; *pm=0.0; } }
if (ftmp2 > 0.0) { *cc = ftmp1*ftmp1/ftmp2; *gc = (float)fabs(ftmp1/ftmp2); *pm=(float)fabs(ftmp1)/ ((float)sqrt(ftmp2)*(float)sqrt(ftmp3)); } else { *cc = 0.0; *gc = 0.0; *pm=0.0; } }
/*----------------------------------------------------------------* * Packet loss concealment routine. Conceals a residual signal * and LP parameters. If no packet loss, update state. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Packet loss concealment routine. Conceals a residual signal * and LP parameters. If no packet loss, update state. *---------------------------------------------------------------*/
void doThePLC( float *PLCresidual, /* (o) concealed residual */ float *PLClpc, /* (o) concealed LP parameters */ int PLI, /* (i) packet loss indicator 0 - no PL, 1 = PL */ float *decresidual, /* (i) decoded residual */ float *lpc, /* (i) decoded LPC (only used for no PL) */ int inlag, /* (i) pitch lag */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) decoder instance */ ){ int lag=20, randlag; float gain, maxcc; float use_gain; float gain_comp, maxcc_comp, per, max_per; int i, pick, use_lag; float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
void doThePLC( float *PLCresidual, /* (o) concealed residual */ float *PLClpc, /* (o) concealed LP parameters */ int PLI, /* (i) packet loss indicator 0 - no PL, 1 = PL */ float *decresidual, /* (i) decoded residual */ float *lpc, /* (i) decoded LPC (only used for no PL) */ int inlag, /* (i) pitch lag */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) decoder instance */ ){ int lag=20, randlag; float gain, maxcc; float use_gain; float gain_comp, maxcc_comp, per, max_per; int i, pick, use_lag; float ftmp, randvec[BLOCKL_MAX], pitchfact, energy;
/* Packet Loss */
/* Packet Loss */
if (PLI == 1) {
if (PLI == 1) {
iLBCdec_inst->consPLICount += 1;
iLBCdec_inst->consPLICount += 1;
/* if previous frame not lost, determine pitch pred. gain */
/* if previous frame not lost, determine pitch pred. gain */
if (iLBCdec_inst->prevPLI != 1) {
if (iLBCdec_inst->prevPLI != 1) {
/* Search around the previous lag to find the best pitch period */
/* Search around the previous lag to find the best pitch period */
lag=inlag-3; compCorr(&maxcc, &gain, &max_per, iLBCdec_inst->prevResidual, lag, iLBCdec_inst->blockl, 60); for (i=inlag-2;i<=inlag+3;i++) { compCorr(&maxcc_comp, &gain_comp, &per, iLBCdec_inst->prevResidual, i, iLBCdec_inst->blockl, 60);
lag=inlag-3; compCorr(&maxcc, &gain, &max_per, iLBCdec_inst->prevResidual, lag, iLBCdec_inst->blockl, 60); for (i=inlag-2;i<=inlag+3;i++) { compCorr(&maxcc_comp, &gain_comp, &per, iLBCdec_inst->prevResidual, i, iLBCdec_inst->blockl, 60);
if (maxcc_comp>maxcc) { maxcc=maxcc_comp;
if (maxcc_comp>maxcc) { maxcc=maxcc_comp;
gain=gain_comp; lag=i; max_per=per; } }
gain=gain_comp; lag=i; max_per=per; } }
}
}
/* previous frame lost, use recorded lag and periodicity */
/* previous frame lost, use recorded lag and periodicity */
else { lag=iLBCdec_inst->prevLag; max_per=iLBCdec_inst->per; }
else { lag=iLBCdec_inst->prevLag; max_per=iLBCdec_inst->per; }
/* downscaling */
/* downscaling */
use_gain=1.0; if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320) use_gain=(float)0.9; else if (iLBCdec_inst->consPLICount* iLBCdec_inst->blockl>2*320) use_gain=(float)0.7; else if (iLBCdec_inst->consPLICount* iLBCdec_inst->blockl>3*320) use_gain=(float)0.5; else if (iLBCdec_inst->consPLICount* iLBCdec_inst->blockl>4*320) use_gain=(float)0.0;
use_gain=1.0; if (iLBCdec_inst->consPLICount*iLBCdec_inst->blockl>320) use_gain=(float)0.9; else if (iLBCdec_inst->consPLICount* iLBCdec_inst->blockl>2*320) use_gain=(float)0.7; else if (iLBCdec_inst->consPLICount* iLBCdec_inst->blockl>3*320) use_gain=(float)0.5; else if (iLBCdec_inst->consPLICount* iLBCdec_inst->blockl>4*320) use_gain=(float)0.0;
/* mix noise and pitch repeatition */ ftmp=(float)sqrt(max_per); if (ftmp>(float)0.7) pitchfact=(float)1.0; else if (ftmp>(float)0.4) pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4); else pitchfact=0.0;
/* mix noise and pitch repeatition */ ftmp=(float)sqrt(max_per); if (ftmp>(float)0.7) pitchfact=(float)1.0; else if (ftmp>(float)0.4) pitchfact=(ftmp-(float)0.4)/((float)0.7-(float)0.4); else pitchfact=0.0;
/* avoid repetition of same pitch cycle */ use_lag=lag; if (lag<80) { use_lag=2*lag; }
/* avoid repetition of same pitch cycle */ use_lag=lag; if (lag<80) { use_lag=2*lag; }
/* compute concealed residual */
/* compute concealed residual */
energy = 0.0; for (i=0; i<iLBCdec_inst->blockl; i++) {
energy = 0.0; for (i=0; i<iLBCdec_inst->blockl; i++) {
/* noise component */
/* noise component */
iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) & (0x80000000L-1); randlag = 50 + ((signed long) iLBCdec_inst->seed)%70; pick = i - randlag;
iLBCdec_inst->seed=(iLBCdec_inst->seed*69069L+1) & (0x80000000L-1); randlag = 50 + ((signed long) iLBCdec_inst->seed)%70; pick = i - randlag;
if (pick < 0) { randvec[i] = iLBCdec_inst->prevResidual[ iLBCdec_inst->blockl+pick]; } else { randvec[i] = randvec[pick]; }
if (pick < 0) { randvec[i] = iLBCdec_inst->prevResidual[ iLBCdec_inst->blockl+pick]; } else { randvec[i] = randvec[pick]; }
/* pitch repeatition component */ pick = i - use_lag;
/* pitch repeatition component */ pick = i - use_lag;
if (pick < 0) { PLCresidual[i] = iLBCdec_inst->prevResidual[ iLBCdec_inst->blockl+pick]; } else { PLCresidual[i] = PLCresidual[pick]; }
if (pick < 0) { PLCresidual[i] = iLBCdec_inst->prevResidual[ iLBCdec_inst->blockl+pick]; } else { PLCresidual[i] = PLCresidual[pick]; }
/* mix random and periodicity component */
/* mix random and periodicity component */
if (i<80) PLCresidual[i] = use_gain*(pitchfact * PLCresidual[i] + ((float)1.0 - pitchfact) * randvec[i]); else if (i<160) PLCresidual[i] = (float)0.95*use_gain*(pitchfact * PLCresidual[i] + ((float)1.0 - pitchfact) * randvec[i]); else PLCresidual[i] = (float)0.9*use_gain*(pitchfact * PLCresidual[i] + ((float)1.0 - pitchfact) * randvec[i]);
if (i<80) PLCresidual[i] = use_gain*(pitchfact * PLCresidual[i] + ((float)1.0 - pitchfact) * randvec[i]); else if (i<160) PLCresidual[i] = (float)0.95*use_gain*(pitchfact * PLCresidual[i] + ((float)1.0 - pitchfact) * randvec[i]); else PLCresidual[i] = (float)0.9*use_gain*(pitchfact * PLCresidual[i] + ((float)1.0 - pitchfact) * randvec[i]);
energy += PLCresidual[i] * PLCresidual[i]; }
energy += PLCresidual[i] * PLCresidual[i]; }
/* less than 30 dB, use only noise */
/* less than 30 dB, use only noise */
if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) { gain=0.0; for (i=0; i<iLBCdec_inst->blockl; i++) { PLCresidual[i] = randvec[i]; } }
if (sqrt(energy/(float)iLBCdec_inst->blockl) < 30.0) { gain=0.0; for (i=0; i<iLBCdec_inst->blockl; i++) { PLCresidual[i] = randvec[i]; } }
/* use old LPC */
/* use old LPC */
memcpy(PLClpc,iLBCdec_inst->prevLpc, (LPC_FILTERORDER+1)*sizeof(float));
memcpy(PLClpc,iLBCdec_inst->prevLpc, (LPC_FILTERORDER+1)*sizeof(float));
}
}
/* no packet loss, copy input */
/* no packet loss, copy input */
else { memcpy(PLCresidual, decresidual, iLBCdec_inst->blockl*sizeof(float)); memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float)); iLBCdec_inst->consPLICount = 0; }
else { memcpy(PLCresidual, decresidual, iLBCdec_inst->blockl*sizeof(float)); memcpy(PLClpc, lpc, (LPC_FILTERORDER+1)*sizeof(float)); iLBCdec_inst->consPLICount = 0; }
/* update state */
/* update state */
if (PLI) { iLBCdec_inst->prevLag = lag; iLBCdec_inst->per=max_per; }
if (PLI) { iLBCdec_inst->prevLag = lag; iLBCdec_inst->per=max_per; }
iLBCdec_inst->prevPLI = PLI; memcpy(iLBCdec_inst->prevLpc, PLClpc, (LPC_FILTERORDER+1)*sizeof(float)); memcpy(iLBCdec_inst->prevResidual, PLCresidual, iLBCdec_inst->blockl*sizeof(float)); }
iLBCdec_inst->prevPLI = PLI; memcpy(iLBCdec_inst->prevLpc, PLClpc, (LPC_FILTERORDER+1)*sizeof(float)); memcpy(iLBCdec_inst->prevResidual, PLCresidual, iLBCdec_inst->blockl*sizeof(float)); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
enhancer.h
增强子
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __ENHANCER_H #define __ENHANCER_H
#ifndef __ENHANCER_H #define __ENHANCER_H
#include "iLBC_define.h"
#包括“iLBC_define.h”
float xCorrCoef( float *target, /* (i) first array */ float *regressor, /* (i) second array */ int subl /* (i) dimension arrays */ );
float xCorrCoef( float *target, /* (i) first array */ float *regressor, /* (i) second array */ int subl /* (i) dimension arrays */ );
int enhancerInterface( float *out, /* (o) the enhanced recidual signal */ float *in, /* (i) the recidual signal to enhance */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) the decoder state structure */ );
int enhancerInterface( float *out, /* (o) the enhanced recidual signal */ float *in, /* (i) the recidual signal to enhance */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i/o) the decoder state structure */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
enhancer.c
增强子c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <string.h> #include "iLBC_define.h" #include "constants.h" #include "filter.h"
#include <math.h> #include <string.h> #include "iLBC_define.h" #include "constants.h" #include "filter.h"
/*----------------------------------------------------------------* * Find index in array such that the array element with said * index is the element of said array closest to "value" * according to the squared-error criterion *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Find index in array such that the array element with said * index is the element of said array closest to "value" * according to the squared-error criterion *---------------------------------------------------------------*/
void NearestNeighbor(
近邻空洞(
int *index, /* (o) index of array element closest to value */ float *array, /* (i) data array */ float value,/* (i) value */ int arlength/* (i) dimension of data array */ ){ int i; float bestcrit,crit;
int *index, /* (o) index of array element closest to value */ float *array, /* (i) data array */ float value,/* (i) value */ int arlength/* (i) dimension of data array */ ){ int i; float bestcrit,crit;
crit=array[0]-value; bestcrit=crit*crit; *index=0; for (i=1; i<arlength; i++) { crit=array[i]-value; crit=crit*crit;
crit=array[0]-value; bestcrit=crit*crit; *index=0; for (i=1; i<arlength; i++) { crit=array[i]-value; crit=crit*crit;
if (crit<bestcrit) { bestcrit=crit; *index=i; } } }
if (crit<bestcrit) { bestcrit=crit; *index=i; } } }
/*----------------------------------------------------------------* * compute cross correlation between sequences *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * compute cross correlation between sequences *---------------------------------------------------------------*/
void mycorr1( float* corr, /* (o) correlation of seq1 and seq2 */ float* seq1, /* (i) first sequence */ int dim1, /* (i) dimension first seq1 */ const float *seq2, /* (i) second sequence */ int dim2 /* (i) dimension seq2 */ ){ int i,j;
void mycorr1( float* corr, /* (o) correlation of seq1 and seq2 */ float* seq1, /* (i) first sequence */ int dim1, /* (i) dimension first seq1 */ const float *seq2, /* (i) second sequence */ int dim2 /* (i) dimension seq2 */ ){ int i,j;
for (i=0; i<=dim1-dim2; i++) { corr[i]=0.0; for (j=0; j<dim2; j++) { corr[i] += seq1[i+j] * seq2[j]; } } }
for (i=0; i<=dim1-dim2; i++) { corr[i]=0.0; for (j=0; j<dim2; j++) { corr[i] += seq1[i+j] * seq2[j]; } } }
/*----------------------------------------------------------------* * upsample finite array assuming zeros outside bounds *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * upsample finite array assuming zeros outside bounds *---------------------------------------------------------------*/
void enh_upsample( float* useq1, /* (o) upsampled output sequence */ float* seq1,/* (i) unupsampled sequence */ int dim1, /* (i) dimension seq1 */ int hfl /* (i) polyphase filter length=2*hfl+1 */ ){ float *pu,*ps; int i,j,k,q,filterlength,hfl2; const float *polyp[ENH_UPS0]; /* pointers to polyphase columns */ const float *pp;
void enh_upsample( float* useq1, /* (o) upsampled output sequence */ float* seq1,/* (i) unupsampled sequence */ int dim1, /* (i) dimension seq1 */ int hfl /* (i) polyphase filter length=2*hfl+1 */ ){ float *pu,*ps; int i,j,k,q,filterlength,hfl2; const float *polyp[ENH_UPS0]; /* pointers to polyphase columns */ const float *pp;
/* define pointers for filter */
/* define pointers for filter */
filterlength=2*hfl+1;
filterlength=2*hfl+1;
if ( filterlength > dim1 ) { hfl2=(int) (dim1/2); for (j=0; j<ENH_UPS0; j++) { polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2; } hfl=hfl2; filterlength=2*hfl+1; } else { for (j=0; j<ENH_UPS0; j++) { polyp[j]=polyphaserTbl+j*filterlength; } }
if ( filterlength > dim1 ) { hfl2=(int) (dim1/2); for (j=0; j<ENH_UPS0; j++) { polyp[j]=polyphaserTbl+j*filterlength+hfl-hfl2; } hfl=hfl2; filterlength=2*hfl+1; } else { for (j=0; j<ENH_UPS0; j++) { polyp[j]=polyphaserTbl+j*filterlength; } }
/* filtering: filter overhangs left side of sequence */
/* filtering: filter overhangs left side of sequence */
pu=useq1; for (i=hfl; i<filterlength; i++) { for (j=0; j<ENH_UPS0; j++) { *pu=0.0; pp = polyp[j]; ps = seq1+i; for (k=0; k<=i; k++) { *pu += *ps-- * *pp++; } pu++; } }
pu=useq1; for (i=hfl; i<filterlength; i++) { for (j=0; j<ENH_UPS0; j++) { *pu=0.0; pp = polyp[j]; ps = seq1+i; for (k=0; k<=i; k++) { *pu += *ps-- * *pp++; } pu++; } }
/* filtering: simple convolution=inner products */
/* filtering: simple convolution=inner products */
for (i=filterlength; i<dim1; i++) {
for (i=filterlength; i<dim1; i++) {
for (j=0;j<ENH_UPS0; j++){ *pu=0.0; pp = polyp[j]; ps = seq1+i; for (k=0; k<filterlength; k++) { *pu += *ps-- * *pp++; } pu++; } }
for (j=0;j<ENH_UPS0; j++){ *pu=0.0; pp = polyp[j]; ps = seq1+i; for (k=0; k<filterlength; k++) { *pu += *ps-- * *pp++; } pu++; } }
/* filtering: filter overhangs right side of sequence */
/* filtering: filter overhangs right side of sequence */
for (q=1; q<=hfl; q++) { for (j=0; j<ENH_UPS0; j++) { *pu=0.0; pp = polyp[j]+q; ps = seq1+dim1-1; for (k=0; k<filterlength-q; k++) { *pu += *ps-- * *pp++; } pu++; } } }
for (q=1; q<=hfl; q++) { for (j=0; j<ENH_UPS0; j++) { *pu=0.0; pp = polyp[j]+q; ps = seq1+dim1-1; for (k=0; k<filterlength-q; k++) { *pu += *ps-- * *pp++; } pu++; } } }
/*----------------------------------------------------------------* * find segment starting near idata+estSegPos that has highest * correlation with idata+centerStartPos through * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a * resolution of ENH_UPSO times the original of the original * sampling rate *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * find segment starting near idata+estSegPos that has highest * correlation with idata+centerStartPos through * idata+centerStartPos+ENH_BLOCKL-1 segment is found at a * resolution of ENH_UPSO times the original of the original * sampling rate *---------------------------------------------------------------*/
void refiner( float *seg, /* (o) segment array */ float *updStartPos, /* (o) updated start point */ float* idata, /* (i) original data buffer */ int idatal, /* (i) dimension of idata */ int centerStartPos, /* (i) beginning center segment */ float estSegPos,/* (i) estimated beginning other segment */ float period /* (i) estimated pitch period */ ){ int estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim; int tloc,tloc2,i,st,en,fraction; float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv; float corrVecUps[ENH_CORRDIM*ENH_UPS0];
void refiner( float *seg, /* (o) segment array */ float *updStartPos, /* (o) updated start point */ float* idata, /* (i) original data buffer */ int idatal, /* (i) dimension of idata */ int centerStartPos, /* (i) beginning center segment */ float estSegPos,/* (i) estimated beginning other segment */ float period /* (i) estimated pitch period */ ){ int estSegPosRounded,searchSegStartPos,searchSegEndPos,corrdim; int tloc,tloc2,i,st,en,fraction; float vect[ENH_VECTL],corrVec[ENH_CORRDIM],maxv; float corrVecUps[ENH_CORRDIM*ENH_UPS0];
/* defining array bounds */
/* defining array bounds */
estSegPosRounded=(int)(estSegPos - 0.5);
estSegPosRounded=(int)(estSegPos - 0.5);
searchSegStartPos=estSegPosRounded-ENH_SLOP;
searchSegStartPos=estSegPosRounded-ENH_SLOP;
if (searchSegStartPos<0) { searchSegStartPos=0; } searchSegEndPos=estSegPosRounded+ENH_SLOP;
if (searchSegStartPos<0) { searchSegStartPos=0; } searchSegEndPos=estSegPosRounded+ENH_SLOP;
if (searchSegEndPos+ENH_BLOCKL >= idatal) { searchSegEndPos=idatal-ENH_BLOCKL-1; } corrdim=searchSegEndPos-searchSegStartPos+1;
if (searchSegEndPos+ENH_BLOCKL >= idatal) { searchSegEndPos=idatal-ENH_BLOCKL-1; } corrdim=searchSegEndPos-searchSegStartPos+1;
/* compute upsampled correlation (corr33) and find location of max */
/* compute upsampled correlation (corr33) and find location of max */
mycorr1(corrVec,idata+searchSegStartPos, corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL); enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0); tloc=0; maxv=corrVecUps[0]; for (i=1; i<ENH_UPS0*corrdim; i++) {
mycorr1(corrVec,idata+searchSegStartPos, corrdim+ENH_BLOCKL-1,idata+centerStartPos,ENH_BLOCKL); enh_upsample(corrVecUps,corrVec,corrdim,ENH_FL0); tloc=0; maxv=corrVecUps[0]; for (i=1; i<ENH_UPS0*corrdim; i++) {
if (corrVecUps[i]>maxv) { tloc=i; maxv=corrVecUps[i]; } }
if (corrVecUps[i]>maxv) { tloc=i; maxv=corrVecUps[i]; } }
/* make vector can be upsampled without ever running outside bounds */
/* make vector can be upsampled without ever running outside bounds */
*updStartPos= (float)searchSegStartPos + (float)tloc/(float)ENH_UPS0+(float)1.0; tloc2=(int)(tloc/ENH_UPS0);
*updStartPos= (float)searchSegStartPos + (float)tloc/(float)ENH_UPS0+(float)1.0; tloc2=(int)(tloc/ENH_UPS0);
if (tloc>tloc2*ENH_UPS0) { tloc2++; } st=searchSegStartPos+tloc2-ENH_FL0;
if (tloc>tloc2*ENH_UPS0) { tloc2++; } st=searchSegStartPos+tloc2-ENH_FL0;
if (st<0) { memset(vect,0,-st*sizeof(float)); memcpy(&vect[-st],idata, (ENH_VECTL+st)*sizeof(float)); } else {
if (st<0) { memset(vect,0,-st*sizeof(float)); memcpy(&vect[-st],idata, (ENH_VECTL+st)*sizeof(float)); } else {
en=st+ENH_VECTL;
en=st+ENH_VECTL;
if (en>idatal) { memcpy(vect, &idata[st], (ENH_VECTL-(en-idatal))*sizeof(float)); memset(&vect[ENH_VECTL-(en-idatal)], 0, (en-idatal)*sizeof(float)); } else { memcpy(vect, &idata[st], ENH_VECTL*sizeof(float)); } } fraction=tloc2*ENH_UPS0-tloc;
if (en>idatal) { memcpy(vect, &idata[st], (ENH_VECTL-(en-idatal))*sizeof(float)); memset(&vect[ENH_VECTL-(en-idatal)], 0, (en-idatal)*sizeof(float)); } else { memcpy(vect, &idata[st], ENH_VECTL*sizeof(float)); } } fraction=tloc2*ENH_UPS0-tloc;
/* compute the segment (this is actually a convolution) */
/* compute the segment (this is actually a convolution) */
mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction, 2*ENH_FL0+1); }
mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction, 2*ENH_FL0+1); }
/*----------------------------------------------------------------* * find the smoothed output data *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * find the smoothed output data *---------------------------------------------------------------*/
void smath( float *odata, /* (o) smoothed output */ float *sseq,/* (i) said second sequence of waveforms */ int hl, /* (i) 2*hl+1 is sseq dimension */ float alpha0/* (i) max smoothing energy fraction */ ){ int i,k; float w00,w10,w11,A,B,C,*psseq,err,errs; float surround[BLOCKL_MAX]; /* shape contributed by other than current */ float wt[2*ENH_HL+1]; /* waveform weighting to get surround shape */ float denom;
void smath( float *odata, /* (o) smoothed output */ float *sseq,/* (i) said second sequence of waveforms */ int hl, /* (i) 2*hl+1 is sseq dimension */ float alpha0/* (i) max smoothing energy fraction */ ){ int i,k; float w00,w10,w11,A,B,C,*psseq,err,errs; float surround[BLOCKL_MAX]; /* shape contributed by other than current */ float wt[2*ENH_HL+1]; /* waveform weighting to get surround shape */ float denom;
/* create shape of contribution from all waveforms except the current one */
/* create shape of contribution from all waveforms except the current one */
for (i=1; i<=2*hl+1; i++) { wt[i-1] = (float)0.5*(1 - (float)cos(2*PI*i/(2*hl+2))); } wt[hl]=0.0; /* for clarity, not used */ for (i=0; i<ENH_BLOCKL; i++) { surround[i]=sseq[i]*wt[0]; }
for (i=1; i<=2*hl+1; i++) { wt[i-1] = (float)0.5*(1 - (float)cos(2*PI*i/(2*hl+2))); } wt[hl]=0.0; /* for clarity, not used */ for (i=0; i<ENH_BLOCKL; i++) { surround[i]=sseq[i]*wt[0]; }
for (k=1; k<hl; k++) { psseq=sseq+k*ENH_BLOCKL; for(i=0;i<ENH_BLOCKL; i++) { surround[i]+=psseq[i]*wt[k]; } } for (k=hl+1; k<=2*hl; k++) { psseq=sseq+k*ENH_BLOCKL; for(i=0;i<ENH_BLOCKL; i++) { surround[i]+=psseq[i]*wt[k]; } }
for (k=1; k<hl; k++) { psseq=sseq+k*ENH_BLOCKL; for(i=0;i<ENH_BLOCKL; i++) { surround[i]+=psseq[i]*wt[k]; } } for (k=hl+1; k<=2*hl; k++) { psseq=sseq+k*ENH_BLOCKL; for(i=0;i<ENH_BLOCKL; i++) { surround[i]+=psseq[i]*wt[k]; } }
/* compute some inner products */
/* compute some inner products */
w00 = w10 = w11 = 0.0; psseq=sseq+hl*ENH_BLOCKL; /* current block */ for (i=0; i<ENH_BLOCKL;i++) { w00+=psseq[i]*psseq[i]; w11+=surround[i]*surround[i]; w10+=surround[i]*psseq[i]; }
w00 = w10 = w11 = 0.0; psseq=sseq+hl*ENH_BLOCKL; /* current block */ for (i=0; i<ENH_BLOCKL;i++) { w00+=psseq[i]*psseq[i]; w11+=surround[i]*surround[i]; w10+=surround[i]*psseq[i]; }
if (fabs(w11) < 1.0) { w11=1.0; } C = (float)sqrt( w00/w11);
if (fabs(w11) < 1.0) { w11=1.0; } C = (float)sqrt( w00/w11);
/* first try enhancement without power-constraint */
/* first try enhancement without power-constraint */
errs=0.0; psseq=sseq+hl*ENH_BLOCKL; for (i=0; i<ENH_BLOCKL; i++) { odata[i]=C*surround[i]; err=psseq[i]-odata[i]; errs+=err*err; }
errs=0.0; psseq=sseq+hl*ENH_BLOCKL; for (i=0; i<ENH_BLOCKL; i++) { odata[i]=C*surround[i]; err=psseq[i]-odata[i]; errs+=err*err; }
/* if constraint violated by first try, add constraint */
/* if constraint violated by first try, add constraint */
if (errs > alpha0 * w00) { if ( w00 < 1) { w00=1; } denom = (w11*w00-w10*w10)/(w00*w00);
if (errs > alpha0 * w00) { if ( w00 < 1) { w00=1; } denom = (w11*w00-w10*w10)/(w00*w00);
if (denom > 0.0001) { /* eliminates numerical problems for if smooth */
if (denom > 0.0001) { /* eliminates numerical problems for if smooth */
A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom); B = -alpha0/2 - A * w10/w00; B = B+1; } else { /* essentially no difference between cycles; smoothing not needed */ A= 0.0; B= 1.0; }
A = (float)sqrt( (alpha0- alpha0*alpha0/4)/denom); B = -alpha0/2 - A * w10/w00; B = B+1; } else { /* essentially no difference between cycles; smoothing not needed */ A= 0.0; B= 1.0; }
/* create smoothed sequence */
/* create smoothed sequence */
psseq=sseq+hl*ENH_BLOCKL; for (i=0; i<ENH_BLOCKL; i++) { odata[i]=A*surround[i]+B*psseq[i]; } } }
psseq=sseq+hl*ENH_BLOCKL; for (i=0; i<ENH_BLOCKL; i++) { odata[i]=A*surround[i]+B*psseq[i]; } } }
/*----------------------------------------------------------------* * get the pitch-synchronous sample sequence *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * get the pitch-synchronous sample sequence *---------------------------------------------------------------*/
void getsseq( float *sseq, /* (o) the pitch-synchronous sequence */ float *idata, /* (i) original data */ int idatal, /* (i) dimension of data */ int centerStartPos, /* (i) where current block starts */ float *period, /* (i) rough-pitch-period array */ float *plocs, /* (i) where periods of period array are taken */ int periodl, /* (i) dimension period array */ int hl /* (i) 2*hl+1 is the number of sequences */ ){ int i,centerEndPos,q; float blockStartPos[2*ENH_HL+1]; int lagBlock[2*ENH_HL+1]; float plocs2[ENH_PLOCSL]; float *psseq;
void getsseq( float *sseq, /* (o) the pitch-synchronous sequence */ float *idata, /* (i) original data */ int idatal, /* (i) dimension of data */ int centerStartPos, /* (i) where current block starts */ float *period, /* (i) rough-pitch-period array */ float *plocs, /* (i) where periods of period array are taken */ int periodl, /* (i) dimension period array */ int hl /* (i) 2*hl+1 is the number of sequences */ ){ int i,centerEndPos,q; float blockStartPos[2*ENH_HL+1]; int lagBlock[2*ENH_HL+1]; float plocs2[ENH_PLOCSL]; float *psseq;
centerEndPos=centerStartPos+ENH_BLOCKL-1;
centerEndPos=centerStartPos+ENH_BLOCKL-1;
/* present */
/* present */
NearestNeighbor(lagBlock+hl,plocs, (float)0.5*(centerStartPos+centerEndPos),periodl);
NearestNeighbor(lagBlock+hl,plocs, (float)0.5*(centerStartPos+centerEndPos),periodl);
blockStartPos[hl]=(float)centerStartPos;
blockStartPos[hl]=(浮动)centerStartPos;
psseq=sseq+ENH_BLOCKL*hl; memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float));
psseq=sseq+ENH_BLOCKL*hl; memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float));
/* past */
/* past */
for (q=hl-1; q>=0; q--) { blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]]; NearestNeighbor(lagBlock+q,plocs, blockStartPos[q]+ ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl);
for (q=hl-1; q>=0; q--) { blockStartPos[q]=blockStartPos[q+1]-period[lagBlock[q+1]]; NearestNeighbor(lagBlock+q,plocs, blockStartPos[q]+ ENH_BLOCKL_HALF-period[lagBlock[q+1]], periodl);
if (blockStartPos[q]-ENH_OVERHANG>=0) { refiner(sseq+q*ENH_BLOCKL, blockStartPos+q, idata, idatal, centerStartPos, blockStartPos[q], period[lagBlock[q+1]]); } else { psseq=sseq+q*ENH_BLOCKL; memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } }
if (blockStartPos[q]-ENH_OVERHANG>=0) { refiner(sseq+q*ENH_BLOCKL, blockStartPos+q, idata, idatal, centerStartPos, blockStartPos[q], period[lagBlock[q+1]]); } else { psseq=sseq+q*ENH_BLOCKL; memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } }
/* future */
/* future */
for (i=0; i<periodl; i++) { plocs2[i]=plocs[i]-period[i]; } for (q=hl+1; q<=2*hl; q++) { NearestNeighbor(lagBlock+q,plocs2, blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl);
for (i=0; i<periodl; i++) { plocs2[i]=plocs[i]-period[i]; } for (q=hl+1; q<=2*hl; q++) { NearestNeighbor(lagBlock+q,plocs2, blockStartPos[q-1]+ENH_BLOCKL_HALF,periodl);
blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]]; if (blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) { refiner(sseq+ENH_BLOCKL*q, blockStartPos+q, idata, idatal, centerStartPos, blockStartPos[q], period[lagBlock[q]]); } else { psseq=sseq+q*ENH_BLOCKL; memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } } }
blockStartPos[q]=blockStartPos[q-1]+period[lagBlock[q]]; if (blockStartPos[q]+ENH_BLOCKL+ENH_OVERHANG<idatal) { refiner(sseq+ENH_BLOCKL*q, blockStartPos+q, idata, idatal, centerStartPos, blockStartPos[q], period[lagBlock[q]]); } else { psseq=sseq+q*ENH_BLOCKL; memset(psseq, 0, ENH_BLOCKL*sizeof(float)); } } }
/*----------------------------------------------------------------* * perform enhancement on idata+centerStartPos through * idata+centerStartPos+ENH_BLOCKL-1 *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * perform enhancement on idata+centerStartPos through * idata+centerStartPos+ENH_BLOCKL-1 *---------------------------------------------------------------*/
void enhancer( float *odata, /* (o) smoothed block, dimension blockl */ float *idata, /* (i) data buffer used for enhancing */ int idatal, /* (i) dimension idata */ int centerStartPos, /* (i) first sample current block within idata */ float alpha0, /* (i) max correction-energy-fraction (in [0,1]) */ float *period, /* (i) pitch period array */ float *plocs, /* (i) locations where period array values valid */ int periodl /* (i) dimension of period and plocs */ ){ float sseq[(2*ENH_HL+1)*ENH_BLOCKL];
void enhancer( float *odata, /* (o) smoothed block, dimension blockl */ float *idata, /* (i) data buffer used for enhancing */ int idatal, /* (i) dimension idata */ int centerStartPos, /* (i) first sample current block within idata */ float alpha0, /* (i) max correction-energy-fraction (in [0,1]) */ float *period, /* (i) pitch period array */ float *plocs, /* (i) locations where period array values valid */ int periodl /* (i) dimension of period and plocs */ ){ float sseq[(2*ENH_HL+1)*ENH_BLOCKL];
/* get said second sequence of segments */
/* get said second sequence of segments */
getsseq(sseq,idata,idatal,centerStartPos,period, plocs,periodl,ENH_HL);
getsseq(sseq、idata、idatal、centerStartPos、period、plocs、periodl、ENH_HL);
/* compute the smoothed output from said second sequence */
/* compute the smoothed output from said second sequence */
smath(odata,sseq,ENH_HL,alpha0);
smath(odata、sseq、ENH_HL、alpha0);
}
}
/*----------------------------------------------------------------* * cross correlation *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * cross correlation *---------------------------------------------------------------*/
float xCorrCoef( float *target, /* (i) first array */ float *regressor, /* (i) second array */ int subl /* (i) dimension arrays */ ){ int i; float ftmp1, ftmp2;
float xCorrCoef( float *target, /* (i) first array */ float *regressor, /* (i) second array */ int subl /* (i) dimension arrays */ ){ int i; float ftmp1, ftmp2;
ftmp1 = 0.0; ftmp2 = 0.0; for (i=0; i<subl; i++) { ftmp1 += target[i]*regressor[i]; ftmp2 += regressor[i]*regressor[i]; }
ftmp1 = 0.0; ftmp2 = 0.0; for (i=0; i<subl; i++) { ftmp1 += target[i]*regressor[i]; ftmp2 += regressor[i]*regressor[i]; }
if (ftmp1 > 0.0) { return (float)(ftmp1*ftmp1/ftmp2); }
if (ftmp1 > 0.0) { return (float)(ftmp1*ftmp1/ftmp2); }
else { return (float)0.0; } }
else { return (float)0.0; } }
/*----------------------------------------------------------------* * interface for enhancer *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * interface for enhancer *---------------------------------------------------------------*/
int enhancerInterface( float *out, /* (o) enhanced signal */ float *in, /* (i) unenhanced signal */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */ ){ float *enh_buf, *enh_period; int iblock, isample; int lag=0, ilag, i, ioffset; float cc, maxcc; float ftmp1, ftmp2; float *inPtr, *enh_bufPtr1, *enh_bufPtr2; float plc_pred[ENH_BLOCKL];
int enhancerInterface( float *out, /* (o) enhanced signal */ float *in, /* (i) unenhanced signal */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) buffers etc */ ){ float *enh_buf, *enh_period; int iblock, isample; int lag=0, ilag, i, ioffset; float cc, maxcc; float ftmp1, ftmp2; float *inPtr, *enh_bufPtr1, *enh_bufPtr2; float plc_pred[ENH_BLOCKL];
float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2]; int inLen=ENH_NBLOCKS*ENH_BLOCKL+120; int start, plc_blockl, inlag;
float lpState[6], downsampled[(ENH_NBLOCKS*ENH_BLOCKL+120)/2]; int inLen=ENH_NBLOCKS*ENH_BLOCKL+120; int start, plc_blockl, inlag;
enh_buf=iLBCdec_inst->enh_buf; enh_period=iLBCdec_inst->enh_period;
enh_buf=iLBCdec_inst->enh_buf; enh_period=iLBCdec_inst->enh_period;
memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl], (ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float));
memmove(enh_buf, &enh_buf[iLBCdec_inst->blockl], (ENH_BUFL-iLBCdec_inst->blockl)*sizeof(float));
memcpy(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in, iLBCdec_inst->blockl*sizeof(float));
memcpy(&enh_buf[ENH_BUFL-iLBCdec_inst->blockl], in, iLBCdec_inst->blockl*sizeof(float));
if (iLBCdec_inst->mode==30) plc_blockl=ENH_BLOCKL; else plc_blockl=40;
if (iLBCdec_inst->mode==30) plc_blockl=ENH_BLOCKL; else plc_blockl=40;
/* when 20 ms frame, move processing one block */ ioffset=0; if (iLBCdec_inst->mode==20) ioffset=1;
/* when 20 ms frame, move processing one block */ ioffset=0; if (iLBCdec_inst->mode==20) ioffset=1;
i=3-ioffset; memmove(enh_period, &enh_period[i], (ENH_NBLOCKS_TOT-i)*sizeof(float));
i=3-ioffset; memmove(enh_period, &enh_period[i], (ENH_NBLOCKS_TOT-i)*sizeof(float));
/* Set state information to the 6 samples right before the samples to be downsampled. */
/* Set state information to the 6 samples right before the samples to be downsampled. */
memcpy(lpState, enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126, 6*sizeof(float));
memcpy(lpState, enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126, 6*sizeof(float));
/* Down sample a factor 2 to save computations */
/* Down sample a factor 2 to save computations */
DownSample(enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-120, lpFilt_coefsTbl, inLen-ioffset*ENH_BLOCKL, lpState, downsampled);
DownSample(enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-120, lpFilt_coefsTbl, inLen-ioffset*ENH_BLOCKL, lpState, downsampled);
/* Estimate the pitch in the down sampled domain. */ for (iblock = 0; iblock<ENH_NBLOCKS-ioffset; iblock++) {
/* Estimate the pitch in the down sampled domain. */ for (iblock = 0; iblock<ENH_NBLOCKS-ioffset; iblock++) {
lag = 10; maxcc = xCorrCoef(downsampled+60+iblock* ENH_BLOCKL_HALF, downsampled+60+iblock* ENH_BLOCKL_HALF-lag, ENH_BLOCKL_HALF); for (ilag=11; ilag<60; ilag++) { cc = xCorrCoef(downsampled+60+iblock* ENH_BLOCKL_HALF, downsampled+60+iblock* ENH_BLOCKL_HALF-ilag, ENH_BLOCKL_HALF);
lag = 10; maxcc = xCorrCoef(downsampled+60+iblock* ENH_BLOCKL_HALF, downsampled+60+iblock* ENH_BLOCKL_HALF-lag, ENH_BLOCKL_HALF); for (ilag=11; ilag<60; ilag++) { cc = xCorrCoef(downsampled+60+iblock* ENH_BLOCKL_HALF, downsampled+60+iblock* ENH_BLOCKL_HALF-ilag, ENH_BLOCKL_HALF);
if (cc > maxcc) { maxcc = cc; lag = ilag; } }
if (cc > maxcc) { maxcc = cc; lag = ilag; } }
/* Store the estimated lag in the non-downsampled domain */ enh_period[iblock+ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2;
/* Store the estimated lag in the non-downsampled domain */ enh_period[iblock+ENH_NBLOCKS_EXTRA+ioffset] = (float)lag*2;
}
}
/* PLC was performed on the previous packet */ if (iLBCdec_inst->prev_enh_pl==1) {
/* PLC was performed on the previous packet */ if (iLBCdec_inst->prev_enh_pl==1) {
inlag=(int)enh_period[ENH_NBLOCKS_EXTRA+ioffset];
inlag=(int)enh_period[ENH_NBLOCKS_EXTRA+ioffset];
lag = inlag-1; maxcc = xCorrCoef(in, in+lag, plc_blockl); for (ilag=inlag; ilag<=inlag+1; ilag++) { cc = xCorrCoef(in, in+ilag, plc_blockl);
lag = inlag-1; maxcc = xCorrCoef(in, in+lag, plc_blockl); for (ilag=inlag; ilag<=inlag+1; ilag++) { cc = xCorrCoef(in, in+ilag, plc_blockl);
if (cc > maxcc) { maxcc = cc; lag = ilag; } }
if (cc > maxcc) { maxcc = cc; lag = ilag; } }
enh_period[ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag;
enh_period[ENH_NBLOCKS_EXTRA+ioffset-1]=(float)lag;
/* compute new concealed residual for the old lookahead, mix the forward PLC with a backward PLC from the new frame */
/* compute new concealed residual for the old lookahead, mix the forward PLC with a backward PLC from the new frame */
inPtr=&in[lag-1];
inPtr=&in[lag-1];
enh_bufPtr1=&plc_pred[plc_blockl-1];
enh_bufPtr1=&plc_pred[plc_blockl-1];
if (lag>plc_blockl) { start=plc_blockl; } else { start=lag; }
if (lag>plc_blockl) { start=plc_blockl; } else { start=lag; }
for (isample = start; isample>0; isample--) { *enh_bufPtr1-- = *inPtr--; }
for (isample = start; isample>0; isample--) { *enh_bufPtr1-- = *inPtr--; }
enh_bufPtr2=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl]; for (isample = (plc_blockl-1-lag); isample>=0; isample--) { *enh_bufPtr1-- = *enh_bufPtr2--; }
enh_bufPtr2=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl]; for (isample = (plc_blockl-1-lag); isample>=0; isample--) { *enh_bufPtr1-- = *enh_bufPtr2--; }
/* limit energy change */ ftmp2=0.0; ftmp1=0.0; for (i=0;i<plc_blockl;i++) { ftmp2+=enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]* enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]; ftmp1+=plc_pred[i]*plc_pred[i]; } ftmp1=(float)sqrt(ftmp1/(float)plc_blockl); ftmp2=(float)sqrt(ftmp2/(float)plc_blockl); if (ftmp1>(float)2.0*ftmp2 && ftmp1>0.0) { for (i=0;i<plc_blockl-10;i++) { plc_pred[i]*=(float)2.0*ftmp2/ftmp1; } for (i=plc_blockl-10;i<plc_blockl;i++) { plc_pred[i]*=(float)(i-plc_blockl+10)* ((float)1.0-(float)2.0*ftmp2/ftmp1)/(float)(10)+
/* limit energy change */ ftmp2=0.0; ftmp1=0.0; for (i=0;i<plc_blockl;i++) { ftmp2+=enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]* enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl-i]; ftmp1+=plc_pred[i]*plc_pred[i]; } ftmp1=(float)sqrt(ftmp1/(float)plc_blockl); ftmp2=(float)sqrt(ftmp2/(float)plc_blockl); if (ftmp1>(float)2.0*ftmp2 && ftmp1>0.0) { for (i=0;i<plc_blockl-10;i++) { plc_pred[i]*=(float)2.0*ftmp2/ftmp1; } for (i=plc_blockl-10;i<plc_blockl;i++) { plc_pred[i]*=(float)(i-plc_blockl+10)* ((float)1.0-(float)2.0*ftmp2/ftmp1)/(float)(10)+
(float)2.0*ftmp2/ftmp1; } }
(float)2.0*ftmp2/ftmp1; } }
enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl]; for (i=0; i<plc_blockl; i++) { ftmp1 = (float) (i+1) / (float) (plc_blockl+1); *enh_bufPtr1 *= ftmp1; *enh_bufPtr1 += ((float)1.0-ftmp1)* plc_pred[plc_blockl-1-i]; enh_bufPtr1--; } }
enh_bufPtr1=&enh_buf[ENH_BUFL-1-iLBCdec_inst->blockl]; for (i=0; i<plc_blockl; i++) { ftmp1 = (float) (i+1) / (float) (plc_blockl+1); *enh_bufPtr1 *= ftmp1; *enh_bufPtr1 += ((float)1.0-ftmp1)* plc_pred[plc_blockl-1-i]; enh_bufPtr1--; } }
if (iLBCdec_inst->mode==20) { /* Enhancer with 40 samples delay */ for (iblock = 0; iblock<2; iblock++) { enhancer(out+iblock*ENH_BLOCKL, enh_buf, ENH_BUFL, (5+iblock)*ENH_BLOCKL+40, ENH_ALPHA0, enh_period, enh_plocsTbl, ENH_NBLOCKS_TOT); } } else if (iLBCdec_inst->mode==30) { /* Enhancer with 80 samples delay */ for (iblock = 0; iblock<3; iblock++) { enhancer(out+iblock*ENH_BLOCKL, enh_buf, ENH_BUFL, (4+iblock)*ENH_BLOCKL, ENH_ALPHA0, enh_period, enh_plocsTbl, ENH_NBLOCKS_TOT); } }
if (iLBCdec_inst->mode==20) { /* Enhancer with 40 samples delay */ for (iblock = 0; iblock<2; iblock++) { enhancer(out+iblock*ENH_BLOCKL, enh_buf, ENH_BUFL, (5+iblock)*ENH_BLOCKL+40, ENH_ALPHA0, enh_period, enh_plocsTbl, ENH_NBLOCKS_TOT); } } else if (iLBCdec_inst->mode==30) { /* Enhancer with 80 samples delay */ for (iblock = 0; iblock<3; iblock++) { enhancer(out+iblock*ENH_BLOCKL, enh_buf, ENH_BUFL, (4+iblock)*ENH_BLOCKL, ENH_ALPHA0, enh_period, enh_plocsTbl, ENH_NBLOCKS_TOT); } }
return (lag*2); }
return (lag*2); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
filter.h
过滤器.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_FILTER_H #define __iLBC_FILTER_H
#ifndef __iLBC_FILTER_H #define __iLBC_FILTER_H
void AllPoleFilter( float *InOut, /* (i/o) on entrance InOut[-orderCoef] to InOut[-1] contain the state of the filter (delayed samples). InOut[0] to InOut[lengthInOut-1] contain the filter input, on en exit InOut[-orderCoef] to InOut[-1] is unchanged and InOut[0] to InOut[lengthInOut-1] contain filtered samples */ float *Coef,/* (i) filter coefficients, Coef[0] is assumed to be 1.0 */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef /* (i) number of filter coefficients */ );
void AllPoleFilter( float *InOut, /* (i/o) on entrance InOut[-orderCoef] to InOut[-1] contain the state of the filter (delayed samples). InOut[0] to InOut[lengthInOut-1] contain the filter input, on en exit InOut[-orderCoef] to InOut[-1] is unchanged and InOut[0] to InOut[lengthInOut-1] contain filtered samples */ float *Coef,/* (i) filter coefficients, Coef[0] is assumed to be 1.0 */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef /* (i) number of filter coefficients */ );
void AllZeroFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples */ float *Coef,/* (i) filter coefficients (Coef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain the filter state, on exit Out[0] to Out[lengthInOut-1] contain filtered samples */ );
void AllZeroFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples */ float *Coef,/* (i) filter coefficients (Coef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain the filter state, on exit Out[0] to Out[lengthInOut-1] contain filtered samples */ );
void ZeroPoleFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples In[-orderCoef] to In[-1] contain state of all-zero section */ float *ZeroCoef,/* (i) filter coefficients for all-zero section (ZeroCoef[0] is assumed to be 1.0) */ float *PoleCoef,/* (i) filter coefficients for all-pole section (ZeroCoef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain state of all-pole section. On exit Out[0] to Out[lengthInOut-1] contain filtered samples */ );
void ZeroPoleFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples In[-orderCoef] to In[-1] contain state of all-zero section */ float *ZeroCoef,/* (i) filter coefficients for all-zero section (ZeroCoef[0] is assumed to be 1.0) */ float *PoleCoef,/* (i) filter coefficients for all-pole section (ZeroCoef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain state of all-pole section. On exit Out[0] to Out[lengthInOut-1] contain filtered samples */ );
void DownSample ( float *In, /* (i) input samples */ float *Coef, /* (i) filter coefficients */ int lengthIn, /* (i) number of input samples */ float *state, /* (i) filter state */ float *Out /* (o) downsampled output */ );
void DownSample ( float *In, /* (i) input samples */ float *Coef, /* (i) filter coefficients */ int lengthIn, /* (i) number of input samples */ float *state, /* (i) filter state */ float *Out /* (o) downsampled output */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
filter.c
过滤器c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#包括“iLBC_define.h”
/*----------------------------------------------------------------* * all-pole filter *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * all-pole filter *---------------------------------------------------------------*/
void AllPoleFilter( float *InOut, /* (i/o) on entrance InOut[-orderCoef] to InOut[-1] contain the state of the filter (delayed samples). InOut[0] to InOut[lengthInOut-1] contain the filter input, on en exit InOut[-orderCoef] to InOut[-1] is unchanged and InOut[0] to InOut[lengthInOut-1] contain filtered samples */ float *Coef,/* (i) filter coefficients, Coef[0] is assumed to be 1.0 */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef /* (i) number of filter coefficients */ ){ int n,k;
void AllPoleFilter( float *InOut, /* (i/o) on entrance InOut[-orderCoef] to InOut[-1] contain the state of the filter (delayed samples). InOut[0] to InOut[lengthInOut-1] contain the filter input, on en exit InOut[-orderCoef] to InOut[-1] is unchanged and InOut[0] to InOut[lengthInOut-1] contain filtered samples */ float *Coef,/* (i) filter coefficients, Coef[0] is assumed to be 1.0 */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef /* (i) number of filter coefficients */ ){ int n,k;
for(n=0;n<lengthInOut;n++){ for(k=1;k<=orderCoef;k++){ *InOut -= Coef[k]*InOut[-k];
for(n=0;n<lengthInOut;n++){ for(k=1;k<=orderCoef;k++){ *InOut -= Coef[k]*InOut[-k];
} InOut++; } }
} InOut++; } }
/*----------------------------------------------------------------* * all-zero filter *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * all-zero filter *---------------------------------------------------------------*/
void AllZeroFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples */ float *Coef,/* (i) filter coefficients (Coef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain the filter state, on exit Out[0] to Out[lengthInOut-1] contain filtered samples */ ){ int n,k;
void AllZeroFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples */ float *Coef,/* (i) filter coefficients (Coef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */ int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain the filter state, on exit Out[0] to Out[lengthInOut-1] contain filtered samples */ ){ int n,k;
for(n=0;n<lengthInOut;n++){ *Out = Coef[0]*In[0]; for(k=1;k<=orderCoef;k++){ *Out += Coef[k]*In[-k]; } Out++; In++; } }
for(n=0;n<lengthInOut;n++){ *Out = Coef[0]*In[0]; for(k=1;k<=orderCoef;k++){ *Out += Coef[k]*In[-k]; } Out++; In++; } }
/*----------------------------------------------------------------* * pole-zero filter *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * pole-zero filter *---------------------------------------------------------------*/
void ZeroPoleFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples In[-orderCoef] to In[-1] contain state of all-zero section */ float *ZeroCoef,/* (i) filter coefficients for all-zero section (ZeroCoef[0] is assumed to be 1.0) */ float *PoleCoef,/* (i) filter coefficients for all-pole section (ZeroCoef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */
void ZeroPoleFilter( float *In, /* (i) In[0] to In[lengthInOut-1] contain filter input samples In[-orderCoef] to In[-1] contain state of all-zero section */ float *ZeroCoef,/* (i) filter coefficients for all-zero section (ZeroCoef[0] is assumed to be 1.0) */ float *PoleCoef,/* (i) filter coefficients for all-pole section (ZeroCoef[0] is assumed to be 1.0) */ int lengthInOut,/* (i) number of input/output samples */
int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain state of all-pole section. On exit Out[0] to Out[lengthInOut-1] contain filtered samples */ ){ AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out); AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef); }
int orderCoef, /* (i) number of filter coefficients */ float *Out /* (i/o) on entrance Out[-orderCoef] to Out[-1] contain state of all-pole section. On exit Out[0] to Out[lengthInOut-1] contain filtered samples */ ){ AllZeroFilter(In,ZeroCoef,lengthInOut,orderCoef,Out); AllPoleFilter(Out,PoleCoef,lengthInOut,orderCoef); }
/*----------------------------------------------------------------* * downsample (LP filter and decimation) *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * downsample (LP filter and decimation) *---------------------------------------------------------------*/
void DownSample ( float *In, /* (i) input samples */ float *Coef, /* (i) filter coefficients */ int lengthIn, /* (i) number of input samples */ float *state, /* (i) filter state */ float *Out /* (o) downsampled output */ ){ float o; float *Out_ptr = Out; float *Coef_ptr, *In_ptr; float *state_ptr; int i, j, stop;
void DownSample ( float *In, /* (i) input samples */ float *Coef, /* (i) filter coefficients */ int lengthIn, /* (i) number of input samples */ float *state, /* (i) filter state */ float *Out /* (o) downsampled output */ ){ float o; float *Out_ptr = Out; float *Coef_ptr, *In_ptr; float *state_ptr; int i, j, stop;
/* LP filter and decimate at the same time */
/* LP filter and decimate at the same time */
for (i = DELAY_DS; i < lengthIn; i+=FACTOR_DS) { Coef_ptr = &Coef[0]; In_ptr = &In[i]; state_ptr = &state[FILTERORDER_DS-2];
for (i = DELAY_DS; i < lengthIn; i+=FACTOR_DS) { Coef_ptr = &Coef[0]; In_ptr = &In[i]; state_ptr = &state[FILTERORDER_DS-2];
o = (float)0.0;
o = (float)0.0;
stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS;
stop = (i < FILTERORDER_DS) ? i + 1 : FILTERORDER_DS;
for (j = 0; j < stop; j++) { o += *Coef_ptr++ * (*In_ptr--); } for (j = i + 1; j < FILTERORDER_DS; j++) { o += *Coef_ptr++ * (*state_ptr--); }
for (j = 0; j < stop; j++) { o += *Coef_ptr++ * (*In_ptr--); } for (j = i + 1; j < FILTERORDER_DS; j++) { o += *Coef_ptr++ * (*state_ptr--); }
*Out_ptr++ = o; }
*Out_ptr++ = o; }
/* Get the last part (use zeros as input for the future) */
/* Get the last part (use zeros as input for the future) */
for (i=(lengthIn+FACTOR_DS); i<(lengthIn+DELAY_DS); i+=FACTOR_DS) {
for (i=(lengthIn+FACTOR_DS); i<(lengthIn+DELAY_DS); i+=FACTOR_DS) {
o=(float)0.0;
o=(浮动)0.0;
if (i<lengthIn) { Coef_ptr = &Coef[0]; In_ptr = &In[i]; for (j=0; j<FILTERORDER_DS; j++) { o += *Coef_ptr++ * (*Out_ptr--); } } else { Coef_ptr = &Coef[i-lengthIn]; In_ptr = &In[lengthIn-1]; for (j=0; j<FILTERORDER_DS-(i-lengthIn); j++) { o += *Coef_ptr++ * (*In_ptr--); } } *Out_ptr++ = o; } }
if (i<lengthIn) { Coef_ptr = &Coef[0]; In_ptr = &In[i]; for (j=0; j<FILTERORDER_DS; j++) { o += *Coef_ptr++ * (*Out_ptr--); } } else { Coef_ptr = &Coef[i-lengthIn]; In_ptr = &In[lengthIn-1]; for (j=0; j<FILTERORDER_DS-(i-lengthIn); j++) { o += *Coef_ptr++ * (*In_ptr--); } } *Out_ptr++ = o; } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
FrameClassify.h
框架分类
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_FRAMECLASSIFY_H #define __iLBC_FRAMECLASSIFY_H
#ifndef __iLBC_FRAMECLASSIFY_H #define __iLBC_FRAMECLASSIFY_H
int FrameClassify( /* index to the max-energy sub-frame */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) the encoder state structure */ float *residual /* (i) lpc residual signal */ );
int FrameClassify( /* index to the max-energy sub-frame */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) the encoder state structure */ float *residual /* (i) lpc residual signal */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
FrameClassify.c
框架分类
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#包括“iLBC_define.h”
/*---------------------------------------------------------------* * Classification of subframes to localize start state *--------------------------------------------------------------*/
/*---------------------------------------------------------------* * Classification of subframes to localize start state *--------------------------------------------------------------*/
int FrameClassify( /* index to the max-energy sub-frame */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) the encoder state structure */ float *residual /* (i) lpc residual signal */ ) { float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp; int n, l, max_ssqEn_n; const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9, (float)1.0,(float)0.9,(float)0.8}; const float sampEn_win[5]={(float)1.0/(float)6.0, (float)2.0/(float)6.0, (float)3.0/(float)6.0, (float)4.0/(float)6.0, (float)5.0/(float)6.0};
int FrameClassify( /* index to the max-energy sub-frame */ iLBC_Enc_Inst_t *iLBCenc_inst, /* (i/o) the encoder state structure */ float *residual /* (i) lpc residual signal */ ) { float max_ssqEn, fssqEn[NSUB_MAX], bssqEn[NSUB_MAX], *pp; int n, l, max_ssqEn_n; const float ssqEn_win[NSUB_MAX-1]={(float)0.8,(float)0.9, (float)1.0,(float)0.9,(float)0.8}; const float sampEn_win[5]={(float)1.0/(float)6.0, (float)2.0/(float)6.0, (float)3.0/(float)6.0, (float)4.0/(float)6.0, (float)5.0/(float)6.0};
/* init the front and back energies to zero */
/* init the front and back energies to zero */
memset(fssqEn, 0, NSUB_MAX*sizeof(float)); memset(bssqEn, 0, NSUB_MAX*sizeof(float));
memset(fssqEn, 0, NSUB_MAX*sizeof(float)); memset(bssqEn, 0, NSUB_MAX*sizeof(float));
/* Calculate front of first seqence */
/* Calculate front of first seqence */
n=0; pp=residual; for (l=0; l<5; l++) { fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); pp++; } for (l=5; l<SUBL; l++) {
n=0; pp=residual; for (l=0; l<5; l++) { fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); pp++; } for (l=5; l<SUBL; l++) {
fssqEn[n] += (*pp) * (*pp); pp++; }
fssqEn[n] += (*pp) * (*pp); pp++; }
/* Calculate front and back of all middle sequences */
/* Calculate front and back of all middle sequences */
for (n=1; n<iLBCenc_inst->nsub-1; n++) { pp=residual+n*SUBL; for (l=0; l<5; l++) { fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp); pp++; } for (l=5; l<SUBL-5; l++) { fssqEn[n] += (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp); pp++; } for (l=SUBL-5; l<SUBL; l++) { fssqEn[n] += (*pp) * (*pp); bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); pp++; } }
for (n=1; n<iLBCenc_inst->nsub-1; n++) { pp=residual+n*SUBL; for (l=0; l<5; l++) { fssqEn[n] += sampEn_win[l] * (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp); pp++; } for (l=5; l<SUBL-5; l++) { fssqEn[n] += (*pp) * (*pp); bssqEn[n] += (*pp) * (*pp); pp++; } for (l=SUBL-5; l<SUBL; l++) { fssqEn[n] += (*pp) * (*pp); bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); pp++; } }
/* Calculate back of last seqence */
/* Calculate back of last seqence */
n=iLBCenc_inst->nsub-1; pp=residual+n*SUBL; for (l=0; l<SUBL-5; l++) { bssqEn[n] += (*pp) * (*pp); pp++; } for (l=SUBL-5; l<SUBL; l++) { bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); pp++; }
n=iLBCenc_inst->nsub-1; pp=residual+n*SUBL; for (l=0; l<SUBL-5; l++) { bssqEn[n] += (*pp) * (*pp); pp++; } for (l=SUBL-5; l<SUBL; l++) { bssqEn[n] += sampEn_win[SUBL-l-1] * (*pp) * (*pp); pp++; }
/* find the index to the weighted 80 sample with most energy */
/* find the index to the weighted 80 sample with most energy */
if (iLBCenc_inst->mode==20) l=1; else l=0;
if (iLBCenc_inst->mode==20) l=1; else l=0;
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l]; max_ssqEn_n=1; for (n=2; n<iLBCenc_inst->nsub; n++) {
max_ssqEn=(fssqEn[0]+bssqEn[1])*ssqEn_win[l]; max_ssqEn_n=1; for (n=2; n<iLBCenc_inst->nsub; n++) {
l++; if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) { max_ssqEn=(fssqEn[n-1]+bssqEn[n]) * ssqEn_win[l]; max_ssqEn_n=n; } }
l++; if ((fssqEn[n-1]+bssqEn[n])*ssqEn_win[l] > max_ssqEn) { max_ssqEn=(fssqEn[n-1]+bssqEn[n]) * ssqEn_win[l]; max_ssqEn_n=n; } }
return max_ssqEn_n; }
return max_ssqEn_n; }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
gainquant.h
Gainquent.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_GAINQUANT_H #define __iLBC_GAINQUANT_H
#ifndef __iLBC_GAINQUANT_H #define __iLBC_GAINQUANT_H
float gainquant(/* (o) quantized gain value */ float in, /* (i) gain value */ float maxIn,/* (i) maximum of gain value */ int cblen, /* (i) number of quantization indices */ int *index /* (o) quantization index */ );
float gainquant(/* (o) quantized gain value */ float in, /* (i) gain value */ float maxIn,/* (i) maximum of gain value */ int cblen, /* (i) number of quantization indices */ int *index /* (o) quantization index */ );
float gaindequant( /* (o) quantized gain value */ int index, /* (i) quantization index */ float maxIn,/* (i) maximum of unquantized gain */ int cblen /* (i) number of quantization indices */ );
float gaindequant( /* (o) quantized gain value */ int index, /* (i) quantization index */ float maxIn,/* (i) maximum of unquantized gain */ int cblen /* (i) number of quantization indices */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
gainquant.c
Gainquent.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <string.h> #include <math.h> #include "constants.h" #include "filter.h"
#include <string.h> #include <math.h> #include "constants.h" #include "filter.h"
/*----------------------------------------------------------------* * quantizer for the gain in the gain-shape coding of residual *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * quantizer for the gain in the gain-shape coding of residual *---------------------------------------------------------------*/
float gainquant(/* (o) quantized gain value */ float in, /* (i) gain value */ float maxIn,/* (i) maximum of gain value */ int cblen, /* (i) number of quantization indices */ int *index /* (o) quantization index */ ){ int i, tindex; float minmeasure,measure, *cb, scale;
float gainquant(/* (o) quantized gain value */ float in, /* (i) gain value */ float maxIn,/* (i) maximum of gain value */ int cblen, /* (i) number of quantization indices */ int *index /* (o) quantization index */ ){ int i, tindex; float minmeasure,measure, *cb, scale;
/* ensure a lower bound on the scaling factor */
/* ensure a lower bound on the scaling factor */
scale=maxIn;
比例=最大值;
if (scale<0.1) { scale=(float)0.1; }
if (scale<0.1) { scale=(float)0.1; }
/* select the quantization table */
/* select the quantization table */
if (cblen == 8) { cb = gain_sq3Tbl; } else if (cblen == 16) { cb = gain_sq4Tbl; } else { cb = gain_sq5Tbl; }
if (cblen == 8) { cb = gain_sq3Tbl; } else if (cblen == 16) { cb = gain_sq4Tbl; } else { cb = gain_sq5Tbl; }
/* select the best index in the quantization table */
/* select the best index in the quantization table */
minmeasure=10000000.0; tindex=0; for (i=0; i<cblen; i++) {
minmeasure=10000000.0; tindex=0; for (i=0; i<cblen; i++) {
measure=(in-scale*cb[i])*(in-scale*cb[i]);
measure=(in-scale*cb[i])*(in-scale*cb[i]);
if (measure<minmeasure) { tindex=i; minmeasure=measure; } } *index=tindex;
if (measure<minmeasure) { tindex=i; minmeasure=measure; } } *index=tindex;
/* return the quantized value */
/* return the quantized value */
return scale*cb[tindex]; }
return scale*cb[tindex]; }
/*----------------------------------------------------------------* * decoder for quantized gains in the gain-shape coding of * residual *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * decoder for quantized gains in the gain-shape coding of * residual *---------------------------------------------------------------*/
float gaindequant( /* (o) quantized gain value */ int index, /* (i) quantization index */ float maxIn,/* (i) maximum of unquantized gain */ int cblen /* (i) number of quantization indices */ ){ float scale;
float gaindequant( /* (o) quantized gain value */ int index, /* (i) quantization index */ float maxIn,/* (i) maximum of unquantized gain */ int cblen /* (i) number of quantization indices */ ){ float scale;
/* obtain correct scale factor */
/* obtain correct scale factor */
scale=(float)fabs(maxIn);
scale=(float)fabs(maxIn);
if (scale<0.1) { scale=(float)0.1; }
if (scale<0.1) { scale=(float)0.1; }
/* select the quantization table and return the decoded value */
/* select the quantization table and return the decoded value */
if (cblen==8) { return scale*gain_sq3Tbl[index]; } else if (cblen==16) { return scale*gain_sq4Tbl[index]; } else if (cblen==32) { return scale*gain_sq5Tbl[index]; }
if (cblen==8) { return scale*gain_sq3Tbl[index]; } else if (cblen==16) { return scale*gain_sq4Tbl[index]; } else if (cblen==32) { return scale*gain_sq5Tbl[index]; }
return 0.0; }
return 0.0; }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
getCBvec.h
getCBvec.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_GETCBVEC_H #define __iLBC_GETCBVEC_H
#ifndef __iLBC_GETCBVEC_H #define __iLBC_GETCBVEC_H
void getCBvec( float *cbvec, /* (o) Constructed codebook vector */ float *mem, /* (i) Codebook buffer */ int index, /* (i) Codebook index */ int lMem, /* (i) Length of codebook buffer */ int cbveclen/* (i) Codebook vector length */ );
void getCBvec( float *cbvec, /* (o) Constructed codebook vector */ float *mem, /* (i) Codebook buffer */ int index, /* (i) Codebook index */ int lMem, /* (i) Length of codebook buffer */ int cbveclen/* (i) Codebook vector length */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
getCBvec.c
getCBvec.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "iLBC_define.h" #include "constants.h" #include <string.h>
#include "iLBC_define.h" #include "constants.h" #include <string.h>
/*----------------------------------------------------------------* * Construct codebook vector for given index. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Construct codebook vector for given index. *---------------------------------------------------------------*/
void getCBvec(
void getCBvec(
float *cbvec, /* (o) Constructed codebook vector */ float *mem, /* (i) Codebook buffer */ int index, /* (i) Codebook index */ int lMem, /* (i) Length of codebook buffer */ int cbveclen/* (i) Codebook vector length */ ){ int j, k, n, memInd, sFilt; float tmpbuf[CB_MEML]; int base_size; int ilow, ihigh; float alfa, alfa1;
float *cbvec, /* (o) Constructed codebook vector */ float *mem, /* (i) Codebook buffer */ int index, /* (i) Codebook index */ int lMem, /* (i) Length of codebook buffer */ int cbveclen/* (i) Codebook vector length */ ){ int j, k, n, memInd, sFilt; float tmpbuf[CB_MEML]; int base_size; int ilow, ihigh; float alfa, alfa1;
/* Determine size of codebook sections */
/* Determine size of codebook sections */
base_size=lMem-cbveclen+1;
base_size=lMem-cbveclen+1;
if (cbveclen==SUBL) { base_size+=cbveclen/2; }
if (cbveclen==SUBL) { base_size+=cbveclen/2; }
/* No filter -> First codebook section */
/* No filter -> First codebook section */
if (index<lMem-cbveclen+1) {
if (index<lMem-cbveclen+1) {
/* first non-interpolated vectors */
/* first non-interpolated vectors */
k=index+cbveclen; /* get vector */ memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float));
k=index+cbveclen; /* get vector */ memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float));
} else if (index < base_size) {
} else if (index < base_size) {
k=2*(index-(lMem-cbveclen+1))+cbveclen;
k=2*(index-(lMem-cbveclen+1))+cbveclen;
ihigh=k/2; ilow=ihigh-5;
ihigh=k/2; ilow=ihigh-5;
/* Copy first noninterpolated part */
/* Copy first noninterpolated part */
memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float));
memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float));
/* interpolation */
/* interpolation */
alfa1=(float)0.2; alfa=0.0; for (j=ilow; j<ihigh; j++) { cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+ alfa*mem[lMem-k+j];
alfa1=(float)0.2; alfa=0.0; for (j=ilow; j<ihigh; j++) { cbvec[j]=((float)1.0-alfa)*mem[lMem-k/2+j]+ alfa*mem[lMem-k+j];
alfa+=alfa1; }
alfa+=alfa1; }
/* Copy second noninterpolated part */
/* Copy second noninterpolated part */
memcpy(cbvec+ihigh, mem+lMem-k+ihigh, (cbveclen-ihigh)*sizeof(float));
memcpy(cbvec+ihigh, mem+lMem-k+ihigh, (cbveclen-ihigh)*sizeof(float));
}
}
/* Higher codebook section based on filtering */
/* Higher codebook section based on filtering */
else {
否则{
/* first non-interpolated vectors */
/* first non-interpolated vectors */
if (index-base_size<lMem-cbveclen+1) { float tempbuff2[CB_MEML+CB_FILTERLEN+1]; float *pos; float *pp, *pp1;
if (index-base_size<lMem-cbveclen+1) { float tempbuff2[CB_MEML+CB_FILTERLEN+1]; float *pos; float *pp, *pp1;
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, lMem*sizeof(float)); memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, (CB_HALFFILTERLEN+1)*sizeof(float));
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, lMem*sizeof(float)); memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, (CB_HALFFILTERLEN+1)*sizeof(float));
k=index-base_size+cbveclen; sFilt=lMem-k; memInd=sFilt+1-CB_HALFFILTERLEN;
k=index-base_size+cbveclen; sFilt=lMem-k; memInd=sFilt+1-CB_HALFFILTERLEN;
/* do filtering */ pos=cbvec; memset(pos, 0, cbveclen*sizeof(float)); for (n=0; n<cbveclen; n++) { pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN]; pp1=&cbfiltersTbl[CB_FILTERLEN-1]; for (j=0; j<CB_FILTERLEN; j++) { (*pos)+=(*pp++)*(*pp1--); } pos++; } }
/* do filtering */ pos=cbvec; memset(pos, 0, cbveclen*sizeof(float)); for (n=0; n<cbveclen; n++) { pp=&tempbuff2[memInd+n+CB_HALFFILTERLEN]; pp1=&cbfiltersTbl[CB_FILTERLEN-1]; for (j=0; j<CB_FILTERLEN; j++) { (*pos)+=(*pp++)*(*pp1--); } pos++; } }
/* interpolated vectors */
/* interpolated vectors */
else {
否则{
float tempbuff2[CB_MEML+CB_FILTERLEN+1];
float tempbuff2[CB_MEML+CB_FILTERLEN+1];
float *pos; float *pp, *pp1; int i;
float *pos; float *pp, *pp1; int i;
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, lMem*sizeof(float)); memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, (CB_HALFFILTERLEN+1)*sizeof(float));
memset(tempbuff2, 0, CB_HALFFILTERLEN*sizeof(float)); memcpy(&tempbuff2[CB_HALFFILTERLEN], mem, lMem*sizeof(float)); memset(&tempbuff2[lMem+CB_HALFFILTERLEN], 0, (CB_HALFFILTERLEN+1)*sizeof(float));
k=2*(index-base_size- (lMem-cbveclen+1))+cbveclen; sFilt=lMem-k; memInd=sFilt+1-CB_HALFFILTERLEN;
k=2*(index-base_size- (lMem-cbveclen+1))+cbveclen; sFilt=lMem-k; memInd=sFilt+1-CB_HALFFILTERLEN;
/* do filtering */ pos=&tmpbuf[sFilt]; memset(pos, 0, k*sizeof(float)); for (i=0; i<k; i++) { pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN]; pp1=&cbfiltersTbl[CB_FILTERLEN-1]; for (j=0; j<CB_FILTERLEN; j++) { (*pos)+=(*pp++)*(*pp1--); } pos++; }
/* do filtering */ pos=&tmpbuf[sFilt]; memset(pos, 0, k*sizeof(float)); for (i=0; i<k; i++) { pp=&tempbuff2[memInd+i+CB_HALFFILTERLEN]; pp1=&cbfiltersTbl[CB_FILTERLEN-1]; for (j=0; j<CB_FILTERLEN; j++) { (*pos)+=(*pp++)*(*pp1--); } pos++; }
ihigh=k/2; ilow=ihigh-5;
ihigh=k/2; ilow=ihigh-5;
/* Copy first noninterpolated part */
/* Copy first noninterpolated part */
memcpy(cbvec, tmpbuf+lMem-k/2, ilow*sizeof(float));
memcpy(cbvec, tmpbuf+lMem-k/2, ilow*sizeof(float));
/* interpolation */
/* interpolation */
alfa1=(float)0.2; alfa=0.0; for (j=ilow; j<ihigh; j++) { cbvec[j]=((float)1.0-alfa)* tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j]; alfa+=alfa1; }
alfa1=(float)0.2; alfa=0.0; for (j=ilow; j<ihigh; j++) { cbvec[j]=((float)1.0-alfa)* tmpbuf[lMem-k/2+j]+alfa*tmpbuf[lMem-k+j]; alfa+=alfa1; }
/* Copy second noninterpolated part */
/* Copy second noninterpolated part */
memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh, (cbveclen-ihigh)*sizeof(float)); } } }
memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh, (cbveclen-ihigh)*sizeof(float)); } } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
helpfun.h
helpfun.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_HELPFUN_H #define __iLBC_HELPFUN_H
#ifndef __iLBC_HELPFUN_H #define __iLBC_HELPFUN_H
void autocorr( float *r, /* (o) autocorrelation vector */ const float *x, /* (i) data vector */ int N, /* (i) length of data vector */ int order /* largest lag for calculated autocorrelations */ );
void autocorr( float *r, /* (o) autocorrelation vector */ const float *x, /* (i) data vector */ int N, /* (i) length of data vector */ int order /* largest lag for calculated autocorrelations */ );
void window( float *z, /* (o) the windowed data */ const float *x, /* (i) the original data vector */ const float *y, /* (i) the window */ int N /* (i) length of all vectors */ );
void window( float *z, /* (o) the windowed data */ const float *x, /* (i) the original data vector */ const float *y, /* (i) the window */ int N /* (i) length of all vectors */ );
void levdurb( float *a, /* (o) lpc coefficient vector starting with 1.0 */ float *k, /* (o) reflection coefficients */ float *r, /* (i) autocorrelation vector */ int order /* (i) order of lpc filter */ );
void levdurb( float *a, /* (o) lpc coefficient vector starting with 1.0 */ float *k, /* (o) reflection coefficients */ float *r, /* (i) autocorrelation vector */ int order /* (i) order of lpc filter */ );
void interpolate(
空洞插值(
float *out, /* (o) the interpolated vector */ float *in1, /* (i) the first vector for the interpolation */ float *in2, /* (i) the second vector for the interpolation */ float coef, /* (i) interpolation weights */ int length /* (i) length of all vectors */ );
float *out, /* (o) the interpolated vector */ float *in1, /* (i) the first vector for the interpolation */ float *in2, /* (i) the second vector for the interpolation */ float coef, /* (i) interpolation weights */ int length /* (i) length of all vectors */ );
void bwexpand( float *out, /* (o) the bandwidth expanded lpc coefficients */ float *in, /* (i) the lpc coefficients before bandwidth expansion */ float coef, /* (i) the bandwidth expansion factor */ int length /* (i) the length of lpc coefficient vectors */ );
void bwexpand( float *out, /* (o) the bandwidth expanded lpc coefficients */ float *in, /* (i) the lpc coefficients before bandwidth expansion */ float coef, /* (i) the bandwidth expansion factor */ int length /* (i) the length of lpc coefficient vectors */ );
void vq( float *Xq, /* (o) the quantized vector */ int *index, /* (o) the quantization index */ const float *CB,/* (i) the vector quantization codebook */ float *X, /* (i) the vector to quantize */ int n_cb, /* (i) the number of vectors in the codebook */ int dim /* (i) the dimension of all vectors */ );
void vq( float *Xq, /* (o) the quantized vector */ int *index, /* (o) the quantization index */ const float *CB,/* (i) the vector quantization codebook */ float *X, /* (i) the vector to quantize */ int n_cb, /* (i) the number of vectors in the codebook */ int dim /* (i) the dimension of all vectors */ );
void SplitVQ( float *qX, /* (o) the quantized vector */ int *index, /* (o) a vector of indexes for all vector codebooks in the split */ float *X, /* (i) the vector to quantize */ const float *CB,/* (i) the quantizer codebook */ int nsplit, /* the number of vector splits */ const int *dim, /* the dimension of X and qX */ const int *cbsize /* the number of vectors in the codebook */ );
void SplitVQ( float *qX, /* (o) the quantized vector */ int *index, /* (o) a vector of indexes for all vector codebooks in the split */ float *X, /* (i) the vector to quantize */ const float *CB,/* (i) the quantizer codebook */ int nsplit, /* the number of vector splits */ const int *dim, /* the dimension of X and qX */ const int *cbsize /* the number of vectors in the codebook */ );
void sort_sq( float *xq, /* (o) the quantized value */ int *index, /* (o) the quantization index */ float x, /* (i) the value to quantize */ const float *cb,/* (i) the quantization codebook */ int cb_size /* (i) the size of the quantization codebook */ );
void sort_sq( float *xq, /* (o) the quantized value */ int *index, /* (o) the quantization index */ float x, /* (i) the value to quantize */ const float *cb,/* (i) the quantization codebook */ int cb_size /* (i) the size of the quantization codebook */ );
int LSF_check( /* (o) 1 for stable lsf vectors and 0 for
int LSF_check( /* (o) 1 for stable lsf vectors and 0 for
nonstable ones */ float *lsf, /* (i) a table of lsf vectors */ int dim, /* (i) the dimension of each lsf vector */ int NoAn /* (i) the number of lsf vectors in the table */ );
nonstable ones */ float *lsf, /* (i) a table of lsf vectors */ int dim, /* (i) the dimension of each lsf vector */ int NoAn /* (i) the number of lsf vectors in the table */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
helpfun.c
helpfun.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h>
#include "iLBC_define.h" #include "constants.h"
#包括“iLBC_define.h”#包括“constants.h”
/*----------------------------------------------------------------* * calculation of auto correlation *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * calculation of auto correlation *---------------------------------------------------------------*/
void autocorr( float *r, /* (o) autocorrelation vector */ const float *x, /* (i) data vector */ int N, /* (i) length of data vector */ int order /* largest lag for calculated autocorrelations */ ){ int lag, n; float sum;
void autocorr( float *r, /* (o) autocorrelation vector */ const float *x, /* (i) data vector */ int N, /* (i) length of data vector */ int order /* largest lag for calculated autocorrelations */ ){ int lag, n; float sum;
for (lag = 0; lag <= order; lag++) { sum = 0; for (n = 0; n < N - lag; n++) { sum += x[n] * x[n+lag]; } r[lag] = sum; }
for (lag = 0; lag <= order; lag++) { sum = 0; for (n = 0; n < N - lag; n++) { sum += x[n] * x[n+lag]; } r[lag] = sum; }
}
}
/*----------------------------------------------------------------* * window multiplication *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * window multiplication *---------------------------------------------------------------*/
void window( float *z, /* (o) the windowed data */ const float *x, /* (i) the original data vector */ const float *y, /* (i) the window */ int N /* (i) length of all vectors */ ){ int i;
void window( float *z, /* (o) the windowed data */ const float *x, /* (i) the original data vector */ const float *y, /* (i) the window */ int N /* (i) length of all vectors */ ){ int i;
for (i = 0; i < N; i++) { z[i] = x[i] * y[i]; } }
for (i = 0; i < N; i++) { z[i] = x[i] * y[i]; } }
/*----------------------------------------------------------------* * levinson-durbin solution for lpc coefficients *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * levinson-durbin solution for lpc coefficients *---------------------------------------------------------------*/
void levdurb( float *a, /* (o) lpc coefficient vector starting with 1.0 */ float *k, /* (o) reflection coefficients */ float *r, /* (i) autocorrelation vector */ int order /* (i) order of lpc filter */ ){ float sum, alpha; int m, m_h, i;
void levdurb( float *a, /* (o) lpc coefficient vector starting with 1.0 */ float *k, /* (o) reflection coefficients */ float *r, /* (i) autocorrelation vector */ int order /* (i) order of lpc filter */ ){ float sum, alpha; int m, m_h, i;
a[0] = 1.0;
a[0]=1.0;
if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ for (i = 0; i < order; i++) { k[i] = 0; a[i+1] = 0; } } else { a[1] = k[0] = -r[1]/r[0]; alpha = r[0] + r[1] * k[0]; for (m = 1; m < order; m++){ sum = r[m + 1]; for (i = 0; i < m; i++){ sum += a[i+1] * r[m - i]; }
if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ for (i = 0; i < order; i++) { k[i] = 0; a[i+1] = 0; } } else { a[1] = k[0] = -r[1]/r[0]; alpha = r[0] + r[1] * k[0]; for (m = 1; m < order; m++){ sum = r[m + 1]; for (i = 0; i < m; i++){ sum += a[i+1] * r[m - i]; }
k[m] = -sum / alpha; alpha += k[m] * sum; m_h = (m + 1) >> 1; for (i = 0; i < m_h; i++){ sum = a[i+1] + k[m] * a[m - i]; a[m - i] += k[m] * a[i+1]; a[i+1] = sum; } a[m+1] = k[m]; } } }
k[m] = -sum / alpha; alpha += k[m] * sum; m_h = (m + 1) >> 1; for (i = 0; i < m_h; i++){ sum = a[i+1] + k[m] * a[m - i]; a[m - i] += k[m] * a[i+1]; a[i+1] = sum; } a[m+1] = k[m]; } } }
/*----------------------------------------------------------------* * interpolation between vectors *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * interpolation between vectors *---------------------------------------------------------------*/
void interpolate( float *out, /* (o) the interpolated vector */ float *in1, /* (i) the first vector for the interpolation */ float *in2, /* (i) the second vector for the interpolation */ float coef, /* (i) interpolation weights */ int length /* (i) length of all vectors */ ){ int i; float invcoef;
void interpolate( float *out, /* (o) the interpolated vector */ float *in1, /* (i) the first vector for the interpolation */ float *in2, /* (i) the second vector for the interpolation */ float coef, /* (i) interpolation weights */ int length /* (i) length of all vectors */ ){ int i; float invcoef;
invcoef = (float)1.0 - coef; for (i = 0; i < length; i++) { out[i] = coef * in1[i] + invcoef * in2[i]; } }
invcoef = (float)1.0 - coef; for (i = 0; i < length; i++) { out[i] = coef * in1[i] + invcoef * in2[i]; } }
/*----------------------------------------------------------------* * lpc bandwidth expansion *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * lpc bandwidth expansion *---------------------------------------------------------------*/
void bwexpand( float *out, /* (o) the bandwidth expanded lpc coefficients */ float *in, /* (i) the lpc coefficients before bandwidth expansion */ float coef, /* (i) the bandwidth expansion factor */ int length /* (i) the length of lpc coefficient vectors */ ){ int i;
void bwexpand( float *out, /* (o) the bandwidth expanded lpc coefficients */ float *in, /* (i) the lpc coefficients before bandwidth expansion */ float coef, /* (i) the bandwidth expansion factor */ int length /* (i) the length of lpc coefficient vectors */ ){ int i;
float chirp;
浮动啁啾;
chirp = coef;
啁啾=系数;
out[0] = in[0]; for (i = 1; i < length; i++) { out[i] = chirp * in[i]; chirp *= coef; } }
out[0] = in[0]; for (i = 1; i < length; i++) { out[i] = chirp * in[i]; chirp *= coef; } }
/*----------------------------------------------------------------* * vector quantization *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * vector quantization *---------------------------------------------------------------*/
void vq( float *Xq, /* (o) the quantized vector */ int *index, /* (o) the quantization index */ const float *CB,/* (i) the vector quantization codebook */ float *X, /* (i) the vector to quantize */ int n_cb, /* (i) the number of vectors in the codebook */ int dim /* (i) the dimension of all vectors */ ){ int i, j; int pos, minindex; float dist, tmp, mindist;
void vq( float *Xq, /* (o) the quantized vector */ int *index, /* (o) the quantization index */ const float *CB,/* (i) the vector quantization codebook */ float *X, /* (i) the vector to quantize */ int n_cb, /* (i) the number of vectors in the codebook */ int dim /* (i) the dimension of all vectors */ ){ int i, j; int pos, minindex; float dist, tmp, mindist;
pos = 0; mindist = FLOAT_MAX; minindex = 0; for (j = 0; j < n_cb; j++) { dist = X[0] - CB[pos]; dist *= dist; for (i = 1; i < dim; i++) { tmp = X[i] - CB[pos + i]; dist += tmp*tmp; }
pos = 0; mindist = FLOAT_MAX; minindex = 0; for (j = 0; j < n_cb; j++) { dist = X[0] - CB[pos]; dist *= dist; for (i = 1; i < dim; i++) { tmp = X[i] - CB[pos + i]; dist += tmp*tmp; }
if (dist < mindist) { mindist = dist; minindex = j; } pos += dim; } for (i = 0; i < dim; i++) { Xq[i] = CB[minindex*dim + i]; } *index = minindex;
if (dist < mindist) { mindist = dist; minindex = j; } pos += dim; } for (i = 0; i < dim; i++) { Xq[i] = CB[minindex*dim + i]; } *index = minindex;
}
}
/*----------------------------------------------------------------* * split vector quantization *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * split vector quantization *---------------------------------------------------------------*/
void SplitVQ( float *qX, /* (o) the quantized vector */ int *index, /* (o) a vector of indexes for all vector codebooks in the split */ float *X, /* (i) the vector to quantize */ const float *CB,/* (i) the quantizer codebook */ int nsplit, /* the number of vector splits */ const int *dim, /* the dimension of X and qX */ const int *cbsize /* the number of vectors in the codebook */ ){ int cb_pos, X_pos, i;
void SplitVQ( float *qX, /* (o) the quantized vector */ int *index, /* (o) a vector of indexes for all vector codebooks in the split */ float *X, /* (i) the vector to quantize */ const float *CB,/* (i) the quantizer codebook */ int nsplit, /* the number of vector splits */ const int *dim, /* the dimension of X and qX */ const int *cbsize /* the number of vectors in the codebook */ ){ int cb_pos, X_pos, i;
cb_pos = 0; X_pos= 0; for (i = 0; i < nsplit; i++) { vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, cbsize[i], dim[i]); X_pos += dim[i]; cb_pos += dim[i] * cbsize[i]; } }
cb_pos = 0; X_pos= 0; for (i = 0; i < nsplit; i++) { vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, cbsize[i], dim[i]); X_pos += dim[i]; cb_pos += dim[i] * cbsize[i]; } }
/*----------------------------------------------------------------* * scalar quantization *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * scalar quantization *---------------------------------------------------------------*/
void sort_sq( float *xq, /* (o) the quantized value */ int *index, /* (o) the quantization index */ float x, /* (i) the value to quantize */ const float *cb,/* (i) the quantization codebook */ int cb_size /* (i) the size of the quantization codebook */ ){ int i;
void sort_sq( float *xq, /* (o) the quantized value */ int *index, /* (o) the quantization index */ float x, /* (i) the value to quantize */ const float *cb,/* (i) the quantization codebook */ int cb_size /* (i) the size of the quantization codebook */ ){ int i;
if (x <= cb[0]) { *index = 0; *xq = cb[0]; } else { i = 0; while ((x > cb[i]) && i < cb_size - 1) { i++;
if (x <= cb[0]) { *index = 0; *xq = cb[0]; } else { i = 0; while ((x > cb[i]) && i < cb_size - 1) { i++;
}
}
if (x > ((cb[i] + cb[i - 1])/2)) { *index = i; *xq = cb[i]; } else { *index = i - 1; *xq = cb[i - 1]; } } }
if (x > ((cb[i] + cb[i - 1])/2)) { *index = i; *xq = cb[i]; } else { *index = i - 1; *xq = cb[i - 1]; } } }
/*----------------------------------------------------------------* * check for stability of lsf coefficients *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * check for stability of lsf coefficients *---------------------------------------------------------------*/
int LSF_check( /* (o) 1 for stable lsf vectors and 0 for nonstable ones */ float *lsf, /* (i) a table of lsf vectors */ int dim, /* (i) the dimension of each lsf vector */ int NoAn /* (i) the number of lsf vectors in the table */ ){ int k,n,m, Nit=2, change=0,pos; float tmp; static float eps=(float)0.039; /* 50 Hz */ static float eps2=(float)0.0195; static float maxlsf=(float)3.14; /* 4000 Hz */ static float minlsf=(float)0.01; /* 0 Hz */
int LSF_check( /* (o) 1 for stable lsf vectors and 0 for nonstable ones */ float *lsf, /* (i) a table of lsf vectors */ int dim, /* (i) the dimension of each lsf vector */ int NoAn /* (i) the number of lsf vectors in the table */ ){ int k,n,m, Nit=2, change=0,pos; float tmp; static float eps=(float)0.039; /* 50 Hz */ static float eps2=(float)0.0195; static float maxlsf=(float)3.14; /* 4000 Hz */ static float minlsf=(float)0.01; /* 0 Hz */
/* LSF separation check*/
/* LSF separation check*/
for (n=0; n<Nit; n++) { /* Run through a couple of times */ for (m=0; m<NoAn; m++) { /* Number of analyses per frame */ for (k=0; k<(dim-1); k++) { pos=m*dim+k;
for (n=0; n<Nit; n++) { /* Run through a couple of times */ for (m=0; m<NoAn; m++) { /* Number of analyses per frame */ for (k=0; k<(dim-1); k++) { pos=m*dim+k;
if ((lsf[pos+1]-lsf[pos])<eps) {
if ((lsf[pos+1]-lsf[pos])<eps) {
if (lsf[pos+1]<lsf[pos]) { tmp=lsf[pos+1]; lsf[pos+1]= lsf[pos]+eps2; lsf[pos]= lsf[pos+1]-eps2; } else { lsf[pos]-=eps2; lsf[pos+1]+=eps2; } change=1;
if (lsf[pos+1]<lsf[pos]) { tmp=lsf[pos+1]; lsf[pos+1]= lsf[pos]+eps2; lsf[pos]= lsf[pos+1]-eps2; } else { lsf[pos]-=eps2; lsf[pos+1]+=eps2; } change=1;
}
}
if (lsf[pos]<minlsf) { lsf[pos]=minlsf; change=1; }
if (lsf[pos]<minlsf) { lsf[pos]=minlsf; change=1; }
if (lsf[pos]>maxlsf) { lsf[pos]=maxlsf; change=1; } } } }
if (lsf[pos]>maxlsf) { lsf[pos]=maxlsf; change=1; } } } }
return change; }
return change; }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
hpInput.h
hpInput.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_HPINPUT_H #define __iLBC_HPINPUT_H
#ifndef __iLBC_HPINPUT_H #define __iLBC_HPINPUT_H
void hpInput( float *In, /* (i) vector to filter */ int len, /* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ );
void hpInput( float *In, /* (i) vector to filter */ int len, /* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
hpInput.c
hpInput.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "constants.h"
#包括“constants.h”
/*----------------------------------------------------------------* * Input high-pass filter *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Input high-pass filter *---------------------------------------------------------------*/
void hpInput( float *In, /* (i) vector to filter */ int len, /* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ ){ int i; float *pi, *po;
void hpInput( float *In, /* (i) vector to filter */ int len, /* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ ){ int i; float *pi, *po;
/* all-zero section*/
/* all-zero section*/
pi = &In[0]; po = &Out[0]; for (i=0; i<len; i++) { *po = hpi_zero_coefsTbl[0] * (*pi); *po += hpi_zero_coefsTbl[1] * mem[0]; *po += hpi_zero_coefsTbl[2] * mem[1];
pi = &In[0]; po = &Out[0]; for (i=0; i<len; i++) { *po = hpi_zero_coefsTbl[0] * (*pi); *po += hpi_zero_coefsTbl[1] * mem[0]; *po += hpi_zero_coefsTbl[2] * mem[1];
mem[1] = mem[0]; mem[0] = *pi; po++; pi++;
mem[1] = mem[0]; mem[0] = *pi; po++; pi++;
}
}
/* all-pole section*/
/* all-pole section*/
po = &Out[0]; for (i=0; i<len; i++) { *po -= hpi_pole_coefsTbl[1] * mem[2]; *po -= hpi_pole_coefsTbl[2] * mem[3];
po = &Out[0]; for (i=0; i<len; i++) { *po -= hpi_pole_coefsTbl[1] * mem[2]; *po -= hpi_pole_coefsTbl[2] * mem[3];
mem[3] = mem[2]; mem[2] = *po; po++;
mem[3] = mem[2]; mem[2] = *po; po++;
} }
} }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
hpOutput.h
hpOutput.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_HPOUTPUT_H #define __iLBC_HPOUTPUT_H
#ifndef __iLBC_HPOUTPUT_H #define __iLBC_HPOUTPUT_H
void hpOutput( float *In, /* (i) vector to filter */ int len,/* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ );
void hpOutput( float *In, /* (i) vector to filter */ int len,/* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
hpOutput.c
hpOutput.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "constants.h"
#包括“constants.h”
/*----------------------------------------------------------------* * Output high-pass filter *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Output high-pass filter *---------------------------------------------------------------*/
void hpOutput(
无效hpOutput(
float *In, /* (i) vector to filter */ int len,/* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ ){ int i; float *pi, *po;
float *In, /* (i) vector to filter */ int len,/* (i) length of vector to filter */ float *Out, /* (o) the resulting filtered vector */ float *mem /* (i/o) the filter state */ ){ int i; float *pi, *po;
/* all-zero section*/
/* all-zero section*/
pi = &In[0]; po = &Out[0]; for (i=0; i<len; i++) { *po = hpo_zero_coefsTbl[0] * (*pi); *po += hpo_zero_coefsTbl[1] * mem[0]; *po += hpo_zero_coefsTbl[2] * mem[1];
pi = &In[0]; po = &Out[0]; for (i=0; i<len; i++) { *po = hpo_zero_coefsTbl[0] * (*pi); *po += hpo_zero_coefsTbl[1] * mem[0]; *po += hpo_zero_coefsTbl[2] * mem[1];
mem[1] = mem[0]; mem[0] = *pi; po++; pi++;
mem[1] = mem[0]; mem[0] = *pi; po++; pi++;
}
}
/* all-pole section*/
/* all-pole section*/
po = &Out[0]; for (i=0; i<len; i++) { *po -= hpo_pole_coefsTbl[1] * mem[2]; *po -= hpo_pole_coefsTbl[2] * mem[3];
po = &Out[0]; for (i=0; i<len; i++) { *po -= hpo_pole_coefsTbl[1] * mem[2]; *po -= hpo_pole_coefsTbl[2] * mem[3];
mem[3] = mem[2]; mem[2] = *po; po++; } }
mem[3] = mem[2]; mem[2] = *po; po++; } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iCBConstruct.h
iCBConstruct.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_ICBCONSTRUCT_H #define __iLBC_ICBCONSTRUCT_H
#ifndef __iLBC_ICBCONSTRUCT_H #define __iLBC_ICBCONSTRUCT_H
void index_conv_enc( int *index /* (i/o) Codebook indexes */ );
void index_conv_enc( int *index /* (i/o) Codebook indexes */ );
void index_conv_dec( int *index /* (i/o) Codebook indexes */ );
void index_conv_dec( int *index /* (i/o) Codebook indexes */ );
void iCBConstruct( float *decvector, /* (o) Decoded vector */ int *index, /* (i) Codebook indices */ int *gain_index,/* (i) Gain quantization indices */ float *mem, /* (i) Buffer for codevector construction */ int lMem, /* (i) Length of buffer */ int veclen, /* (i) Length of vector */ int nStages /* (i) Number of codebook stages */ );
void iCBConstruct( float *decvector, /* (o) Decoded vector */ int *index, /* (i) Codebook indices */ int *gain_index,/* (i) Gain quantization indices */ float *mem, /* (i) Buffer for codevector construction */ int lMem, /* (i) Length of buffer */ int veclen, /* (i) Length of vector */ int nStages /* (i) Number of codebook stages */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iCBConstruct.c
iCBConstruct.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h>
#include <math.h>
#include "iLBC_define.h" #include "gainquant.h" #include "getCBvec.h"
#包括“iLBC_define.h”#包括“gainquint.h”#包括“getCBvec.h”
/*----------------------------------------------------------------* * Convert the codebook indexes to make the search easier *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Convert the codebook indexes to make the search easier *---------------------------------------------------------------*/
void index_conv_enc( int *index /* (i/o) Codebook indexes */ ){ int k;
void index_conv_enc( int *index /* (i/o) Codebook indexes */ ){ int k;
for (k=1; k<CB_NSTAGES; k++) {
for (k=1; k<CB_NSTAGES; k++) {
if ((index[k]>=108)&&(index[k]<172)) { index[k]-=64; } else if (index[k]>=236) { index[k]-=128; } else { /* ERROR */ } } }
if ((index[k]>=108)&&(index[k]<172)) { index[k]-=64; } else if (index[k]>=236) { index[k]-=128; } else { /* ERROR */ } } }
void index_conv_dec( int *index /* (i/o) Codebook indexes */ ){ int k;
void index_conv_dec( int *index /* (i/o) Codebook indexes */ ){ int k;
for (k=1; k<CB_NSTAGES; k++) {
for (k=1; k<CB_NSTAGES; k++) {
if ((index[k]>=44)&&(index[k]<108)) { index[k]+=64; } else if ((index[k]>=108)&&(index[k]<128)) { index[k]+=128; } else { /* ERROR */ } } }
if ((index[k]>=44)&&(index[k]<108)) { index[k]+=64; } else if ((index[k]>=108)&&(index[k]<128)) { index[k]+=128; } else { /* ERROR */ } } }
/*----------------------------------------------------------------* * Construct decoded vector from codebook and gains. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Construct decoded vector from codebook and gains. *---------------------------------------------------------------*/
void iCBConstruct( float *decvector, /* (o) Decoded vector */ int *index, /* (i) Codebook indices */ int *gain_index,/* (i) Gain quantization indices */ float *mem, /* (i) Buffer for codevector construction */ int lMem, /* (i) Length of buffer */ int veclen, /* (i) Length of vector */ int nStages /* (i) Number of codebook stages */ ){ int j,k;
void iCBConstruct( float *decvector, /* (o) Decoded vector */ int *index, /* (i) Codebook indices */ int *gain_index,/* (i) Gain quantization indices */ float *mem, /* (i) Buffer for codevector construction */ int lMem, /* (i) Length of buffer */ int veclen, /* (i) Length of vector */ int nStages /* (i) Number of codebook stages */ ){ int j,k;
float gain[CB_NSTAGES]; float cbvec[SUBL];
float gain[CB_NSTAGES]; float cbvec[SUBL];
/* gain de-quantization */
/* gain de-quantization */
gain[0] = gaindequant(gain_index[0], 1.0, 32); if (nStages > 1) { gain[1] = gaindequant(gain_index[1], (float)fabs(gain[0]), 16); } if (nStages > 2) { gain[2] = gaindequant(gain_index[2], (float)fabs(gain[1]), 8); }
gain[0] = gaindequant(gain_index[0], 1.0, 32); if (nStages > 1) { gain[1] = gaindequant(gain_index[1], (float)fabs(gain[0]), 16); } if (nStages > 2) { gain[2] = gaindequant(gain_index[2], (float)fabs(gain[1]), 8); }
/* codebook vector construction and construction of total vector */
/* codebook vector construction and construction of total vector */
getCBvec(cbvec, mem, index[0], lMem, veclen); for (j=0;j<veclen;j++){ decvector[j] = gain[0]*cbvec[j]; } if (nStages > 1) { for (k=1; k<nStages; k++) { getCBvec(cbvec, mem, index[k], lMem, veclen); for (j=0;j<veclen;j++) { decvector[j] += gain[k]*cbvec[j]; } } } }
getCBvec(cbvec, mem, index[0], lMem, veclen); for (j=0;j<veclen;j++){ decvector[j] = gain[0]*cbvec[j]; } if (nStages > 1) { for (k=1; k<nStages; k++) { getCBvec(cbvec, mem, index[k], lMem, veclen); for (j=0;j<veclen;j++) { decvector[j] += gain[k]*cbvec[j]; } } } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iCBSearch.h
iCBSearch.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_ICBSEARCH_H #define __iLBC_ICBSEARCH_H
#ifndef __iLBC_ICBSEARCH_H #define __iLBC_ICBSEARCH_H
void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) the encoder state structure */ int *index, /* (o) Codebook indices */ int *gain_index,/* (o) Gain quantization indices */ float *intarget,/* (i) Target vector for encoding */ float *mem, /* (i) Buffer for codebook construction */ int lMem, /* (i) Length of buffer */ int lTarget, /* (i) Length of vector */ int nStages, /* (i) Number of codebook stages */ float *weightDenum, /* (i) weighting filter coefficients */ float *weightState, /* (i) weighting filter state */ int block /* (i) the sub-block number */ );
void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) the encoder state structure */ int *index, /* (o) Codebook indices */ int *gain_index,/* (o) Gain quantization indices */ float *intarget,/* (i) Target vector for encoding */ float *mem, /* (i) Buffer for codebook construction */ int lMem, /* (i) Length of buffer */ int lTarget, /* (i) Length of vector */ int nStages, /* (i) Number of codebook stages */ float *weightDenum, /* (i) weighting filter coefficients */ float *weightState, /* (i) weighting filter state */ int block /* (i) the sub-block number */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
iCBSearch.c
ICB研究中心
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <string.h>
#include <math.h> #include <string.h>
#include "iLBC_define.h" #include "gainquant.h" #include "createCB.h" #include "filter.h" #include "constants.h"
#包括“iLBC_define.h”#包括“gainquint.h”#包括“createCB.h”#包括“filter.h”#包括“constants.h”
/*----------------------------------------------------------------* * Search routine for codebook encoding and gain quantization. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * Search routine for codebook encoding and gain quantization. *---------------------------------------------------------------*/
void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) the encoder state structure */ int *index, /* (o) Codebook indices */ int *gain_index,/* (o) Gain quantization indices */
void iCBSearch( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) the encoder state structure */ int *index, /* (o) Codebook indices */ int *gain_index,/* (o) Gain quantization indices */
float *intarget,/* (i) Target vector for encoding */ float *mem, /* (i) Buffer for codebook construction */ int lMem, /* (i) Length of buffer */ int lTarget, /* (i) Length of vector */ int nStages, /* (i) Number of codebook stages */ float *weightDenum, /* (i) weighting filter coefficients */ float *weightState, /* (i) weighting filter state */ int block /* (i) the sub-block number */ ){ int i, j, icount, stage, best_index, range, counter; float max_measure, gain, measure, crossDot, ftmp; float gains[CB_NSTAGES]; float target[SUBL]; int base_index, sInd, eInd, base_size; int sIndAug=0, eIndAug=0; float buf[CB_MEML+SUBL+2*LPC_FILTERORDER]; float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128]; float *pp, *ppi=0, *ppo=0, *ppe=0; float cbvectors[CB_MEML]; float tene, cene, cvec[SUBL]; float aug_vec[SUBL];
float *intarget,/* (i) Target vector for encoding */ float *mem, /* (i) Buffer for codebook construction */ int lMem, /* (i) Length of buffer */ int lTarget, /* (i) Length of vector */ int nStages, /* (i) Number of codebook stages */ float *weightDenum, /* (i) weighting filter coefficients */ float *weightState, /* (i) weighting filter state */ int block /* (i) the sub-block number */ ){ int i, j, icount, stage, best_index, range, counter; float max_measure, gain, measure, crossDot, ftmp; float gains[CB_NSTAGES]; float target[SUBL]; int base_index, sInd, eInd, base_size; int sIndAug=0, eIndAug=0; float buf[CB_MEML+SUBL+2*LPC_FILTERORDER]; float invenergy[CB_EXPAND*128], energy[CB_EXPAND*128]; float *pp, *ppi=0, *ppo=0, *ppe=0; float cbvectors[CB_MEML]; float tene, cene, cvec[SUBL]; float aug_vec[SUBL];
memset(cvec,0,SUBL*sizeof(float));
memset(cvec,0,SUBL*sizeof(float));
/* Determine size of codebook sections */
/* Determine size of codebook sections */
base_size=lMem-lTarget+1;
base_size=lMem-lTarget+1;
if (lTarget==SUBL) { base_size=lMem-lTarget+1+lTarget/2; }
if (lTarget==SUBL) { base_size=lMem-lTarget+1+lTarget/2; }
/* setup buffer for weighting */
/* setup buffer for weighting */
memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER); memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float)); memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float));
memcpy(buf,weightState,sizeof(float)*LPC_FILTERORDER); memcpy(buf+LPC_FILTERORDER,mem,lMem*sizeof(float)); memcpy(buf+LPC_FILTERORDER+lMem,intarget,lTarget*sizeof(float));
/* weighting */
/* weighting */
AllPoleFilter(buf+LPC_FILTERORDER, weightDenum, lMem+lTarget, LPC_FILTERORDER);
AllPoleFilter(buf+LPC_FILTERORDER, weightDenum, lMem+lTarget, LPC_FILTERORDER);
/* Construct the codebook and target needed */
/* Construct the codebook and target needed */
memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
tene=0.0;
tene=0.0;
for (i=0; i<lTarget; i++) { tene+=target[i]*target[i]; }
for (i=0; i<lTarget; i++) { tene+=target[i]*target[i]; }
/* Prepare search over one more codebook section. This section is created by filtering the original buffer with a filter. */
/* Prepare search over one more codebook section. This section is created by filtering the original buffer with a filter. */
filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);
filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);
/* The Main Loop over stages */
/* The Main Loop over stages */
for (stage=0; stage<nStages; stage++) {
for (stage=0; stage<nStages; stage++) {
range = search_rangeTbl[block][stage];
范围=搜索范围[block][stage];
/* initialize search measure */
/* initialize search measure */
max_measure = (float)-10000000.0; gain = (float)0.0; best_index = 0;
max_measure = (float)-10000000.0; gain = (float)0.0; best_index = 0;
/* Compute cross dot product between the target and the CB memory */
/* Compute cross dot product between the target and the CB memory */
crossDot=0.0; pp=buf+LPC_FILTERORDER+lMem-lTarget; for (j=0; j<lTarget; j++) { crossDot += target[j]*(*pp++); }
crossDot=0.0; pp=buf+LPC_FILTERORDER+lMem-lTarget; for (j=0; j<lTarget; j++) { crossDot += target[j]*(*pp++); }
if (stage==0) {
if (stage==0) {
/* Calculate energy in the first block of 'lTarget' samples. */ ppe = energy; ppi = buf+LPC_FILTERORDER+lMem-lTarget-1; ppo = buf+LPC_FILTERORDER+lMem-1;
/* Calculate energy in the first block of 'lTarget' samples. */ ppe = energy; ppi = buf+LPC_FILTERORDER+lMem-lTarget-1; ppo = buf+LPC_FILTERORDER+lMem-1;
*ppe=0.0; pp=buf+LPC_FILTERORDER+lMem-lTarget; for (j=0; j<lTarget; j++) { *ppe+=(*pp)*(*pp++); }
*ppe=0.0; pp=buf+LPC_FILTERORDER+lMem-lTarget; for (j=0; j<lTarget; j++) { *ppe+=(*pp)*(*pp++); }
if (*ppe>0.0) { invenergy[0] = (float) 1.0 / (*ppe + EPS); } else { invenergy[0] = (float) 0.0;
if (*ppe>0.0) { invenergy[0] = (float) 1.0 / (*ppe + EPS); } else { invenergy[0] = (float) 0.0;
} ppe++;
} ppe++;
measure=(float)-10000000.0;
度量=(浮动)-10000000.0;
if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[0]; } } else { measure = crossDot*crossDot*invenergy[0]; }
if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[0]; } } else { measure = crossDot*crossDot*invenergy[0]; }
/* check if measure is better */ ftmp = crossDot*invenergy[0];
/* check if measure is better */ ftmp = crossDot*invenergy[0];
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = 0; max_measure = measure; gain = ftmp; }
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = 0; max_measure = measure; gain = ftmp; }
/* loop over the main first codebook section, full search */
/* loop over the main first codebook section, full search */
for (icount=1; icount<range; icount++) {
for (icount=1; icount<range; icount++) {
/* calculate measure */
/* calculate measure */
crossDot=0.0; pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
crossDot=0.0; pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
for (j=0; j<lTarget; j++) { crossDot += target[j]*(*pp++); }
for (j=0; j<lTarget; j++) { crossDot += target[j]*(*pp++); }
if (stage==0) { *ppe++ = energy[icount-1] + (*ppi)*(*ppi) - (*ppo)*(*ppo); ppo--; ppi--;
if (stage==0) { *ppe++ = energy[icount-1] + (*ppi)*(*ppi) - (*ppo)*(*ppo); ppo--; ppi--;
if (energy[icount]>0.0) { invenergy[icount] = (float)1.0/(energy[icount]+EPS); } else { invenergy[icount] = (float) 0.0; }
if (energy[icount]>0.0) { invenergy[icount] = (float)1.0/(energy[icount]+EPS); } else { invenergy[icount] = (float) 0.0; }
measure=(float)-10000000.0;
度量=(浮动)-10000000.0;
if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[icount]; } } else { measure = crossDot*crossDot*invenergy[icount]; }
if (crossDot > 0.0) { measure = crossDot*crossDot*invenergy[icount]; } } else { measure = crossDot*crossDot*invenergy[icount]; }
/* check if measure is better */ ftmp = crossDot*invenergy[icount];
/* check if measure is better */ ftmp = crossDot*invenergy[icount];
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = icount; max_measure = measure; gain = ftmp; } }
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = icount; max_measure = measure; gain = ftmp; } }
/* Loop over augmented part in the first codebook * section, full search. * The vectors are interpolated. */
/* Loop over augmented part in the first codebook * section, full search. * The vectors are interpolated. */
if (lTarget==SUBL) {
if (lTarget==SUBL) {
/* Search for best possible cb vector and compute the CB-vectors' energy. */ searchAugmentedCB(20, 39, stage, base_size-lTarget/2, target, buf+LPC_FILTERORDER+lMem, &max_measure, &best_index, &gain, energy, invenergy); }
/* Search for best possible cb vector and compute the CB-vectors' energy. */ searchAugmentedCB(20, 39, stage, base_size-lTarget/2, target, buf+LPC_FILTERORDER+lMem, &max_measure, &best_index, &gain, energy, invenergy); }
/* set search range for following codebook sections */
/* set search range for following codebook sections */
base_index=best_index;
基本指数=最佳指数;
/* unrestricted search */
/* unrestricted search */
if (CB_RESRANGE == -1) { sInd=0; eInd=range-1; sIndAug=20; eIndAug=39; }
if (CB_RESRANGE == -1) { sInd=0; eInd=range-1; sIndAug=20; eIndAug=39; }
/* restricted search around best index from first codebook section */
/* restricted search around best index from first codebook section */
else { /* Initialize search indices */ sIndAug=0; eIndAug=0; sInd=base_index-CB_RESRANGE/2; eInd=sInd+CB_RESRANGE;
else { /* Initialize search indices */ sIndAug=0; eIndAug=0; sInd=base_index-CB_RESRANGE/2; eInd=sInd+CB_RESRANGE;
if (lTarget==SUBL) {
if (lTarget==SUBL) {
if (sInd<0) {
if(sInd<0){
sIndAug = 40 + sInd; eIndAug = 39; sInd=0;
sIndAug = 40 + sInd; eIndAug = 39; sInd=0;
} else if ( base_index < (base_size-20) ) {
} else if ( base_index < (base_size-20) ) {
if (eInd > range) { sInd -= (eInd-range); eInd = range; } } else { /* base_index >= (base_size-20) */
if (eInd > range) { sInd -= (eInd-range); eInd = range; } } else { /* base_index >= (base_size-20) */
if (sInd < (base_size-20)) { sIndAug = 20; sInd = 0; eInd = 0; eIndAug = 19 + CB_RESRANGE;
if (sInd < (base_size-20)) { sIndAug = 20; sInd = 0; eInd = 0; eIndAug = 19 + CB_RESRANGE;
if(eIndAug > 39) { eInd = eIndAug-39; eIndAug = 39; } } else { sIndAug = 20 + sInd - (base_size-20); eIndAug = 39; sInd = 0; eInd = CB_RESRANGE - (eIndAug-sIndAug+1); } }
if(eIndAug > 39) { eInd = eIndAug-39; eIndAug = 39; } } else { sIndAug = 20 + sInd - (base_size-20); eIndAug = 39; sInd = 0; eInd = CB_RESRANGE - (eIndAug-sIndAug+1); } }
} else { /* lTarget = 22 or 23 */
} else { /* lTarget = 22 or 23 */
if (sInd < 0) { eInd -= sInd;
if (sInd < 0) { eInd -= sInd;
sInd = 0; }
sInd = 0; }
if(eInd > range) { sInd -= (eInd - range); eInd = range; } } }
if(eInd > range) { sInd -= (eInd - range); eInd = range; } } }
/* search of higher codebook section */
/* search of higher codebook section */
/* index search range */ counter = sInd; sInd += base_size; eInd += base_size;
/* index search range */ counter = sInd; sInd += base_size; eInd += base_size;
if (stage==0) { ppe = energy+base_size; *ppe=0.0;
if (stage==0) { ppe = energy+base_size; *ppe=0.0;
pp=cbvectors+lMem-lTarget; for (j=0; j<lTarget; j++) { *ppe+=(*pp)*(*pp++); }
pp=cbvectors+lMem-lTarget; for (j=0; j<lTarget; j++) { *ppe+=(*pp)*(*pp++); }
ppi = cbvectors + lMem - 1 - lTarget; ppo = cbvectors + lMem - 1;
ppi = cbvectors + lMem - 1 - lTarget; ppo = cbvectors + lMem - 1;
for (j=0; j<(range-1); j++) { *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo); ppo--; ppi--; ppe++; } }
for (j=0; j<(range-1); j++) { *(ppe+1) = *ppe + (*ppi)*(*ppi) - (*ppo)*(*ppo); ppo--; ppi--; ppe++; } }
/* loop over search range */
/* loop over search range */
for (icount=sInd; icount<eInd; icount++) {
for (icount=sInd; icount<eInd; icount++) {
/* calculate measure */
/* calculate measure */
crossDot=0.0; pp=cbvectors + lMem - (counter++) - lTarget;
crossDot=0.0; pp=cbvectors + lMem - (counter++) - lTarget;
for (j=0;j<lTarget;j++) {
for (j=0;j<lTarget;j++) {
crossDot += target[j]*(*pp++); }
crossDot += target[j]*(*pp++); }
if (energy[icount]>0.0) { invenergy[icount] =(float)1.0/(energy[icount]+EPS); } else { invenergy[icount] =(float)0.0; }
if (energy[icount]>0.0) { invenergy[icount] =(float)1.0/(energy[icount]+EPS); } else { invenergy[icount] =(float)0.0; }
if (stage==0) {
if (stage==0) {
measure=(float)-10000000.0;
度量=(浮动)-10000000.0;
if (crossDot > 0.0) { measure = crossDot*crossDot* invenergy[icount]; } } else { measure = crossDot*crossDot*invenergy[icount]; }
if (crossDot > 0.0) { measure = crossDot*crossDot* invenergy[icount]; } } else { measure = crossDot*crossDot*invenergy[icount]; }
/* check if measure is better */ ftmp = crossDot*invenergy[icount];
/* check if measure is better */ ftmp = crossDot*invenergy[icount];
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = icount; max_measure = measure; gain = ftmp; } }
if ((measure>max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { best_index = icount; max_measure = measure; gain = ftmp; } }
/* Search the augmented CB inside the limited range. */
/* Search the augmented CB inside the limited range. */
if ((lTarget==SUBL)&&(sIndAug!=0)) { searchAugmentedCB(sIndAug, eIndAug, stage, 2*base_size-20, target, cbvectors+lMem, &max_measure, &best_index, &gain, energy, invenergy); }
if ((lTarget==SUBL)&&(sIndAug!=0)) { searchAugmentedCB(sIndAug, eIndAug, stage, 2*base_size-20, target, cbvectors+lMem, &max_measure, &best_index, &gain, energy, invenergy); }
/* record best index */
/* record best index */
index[stage] = best_index;
指数[阶段]=最佳指数;
/* gain quantization */
/* gain quantization */
if (stage==0){
if (stage==0){
if (gain<0.0){ gain = 0.0; }
if (gain<0.0){ gain = 0.0; }
if (gain>CB_MAXGAIN) { gain = (float)CB_MAXGAIN; } gain = gainquant(gain, 1.0, 32, &gain_index[stage]); } else { if (stage==1) { gain = gainquant(gain, (float)fabs(gains[stage-1]), 16, &gain_index[stage]); } else { gain = gainquant(gain, (float)fabs(gains[stage-1]), 8, &gain_index[stage]); } }
if (gain>CB_MAXGAIN) { gain = (float)CB_MAXGAIN; } gain = gainquant(gain, 1.0, 32, &gain_index[stage]); } else { if (stage==1) { gain = gainquant(gain, (float)fabs(gains[stage-1]), 16, &gain_index[stage]); } else { gain = gainquant(gain, (float)fabs(gains[stage-1]), 8, &gain_index[stage]); } }
/* Extract the best (according to measure) codebook vector */
/* Extract the best (according to measure) codebook vector */
if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
if (lTarget==(STATE_LEN-iLBCenc_inst->state_short_len)) {
if (index[stage]<base_size) { pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; } else { pp=cbvectors+lMem-lTarget- index[stage]+base_size; } } else {
if (index[stage]<base_size) { pp=buf+LPC_FILTERORDER+lMem-lTarget-index[stage]; } else { pp=cbvectors+lMem-lTarget- index[stage]+base_size; } } else {
if (index[stage]<base_size) { if (index[stage]<(base_size-20)) { pp=buf+LPC_FILTERORDER+lMem- lTarget-index[stage]; } else { createAugmentedVec(index[stage]-base_size+40, buf+LPC_FILTERORDER+lMem,aug_vec); pp=aug_vec; } } else { int filterno, position;
if (index[stage]<base_size) { if (index[stage]<(base_size-20)) { pp=buf+LPC_FILTERORDER+lMem- lTarget-index[stage]; } else { createAugmentedVec(index[stage]-base_size+40, buf+LPC_FILTERORDER+lMem,aug_vec); pp=aug_vec; } } else { int filterno, position;
filterno=index[stage]/base_size; position=index[stage]-filterno*base_size;
filterno=index[stage]/base_size; position=index[stage]-filterno*base_size;
if (position<(base_size-20)) { pp=cbvectors+filterno*lMem-lTarget- index[stage]+filterno*base_size; } else { createAugmentedVec( index[stage]-(filterno+1)*base_size+40, cbvectors+filterno*lMem,aug_vec); pp=aug_vec; } } }
if (position<(base_size-20)) { pp=cbvectors+filterno*lMem-lTarget- index[stage]+filterno*base_size; } else { createAugmentedVec( index[stage]-(filterno+1)*base_size+40, cbvectors+filterno*lMem,aug_vec); pp=aug_vec; } } }
/* Subtract the best codebook vector, according to measure, from the target vector */
/* Subtract the best codebook vector, according to measure, from the target vector */
for (j=0;j<lTarget;j++) { cvec[j] += gain*(*pp); target[j] -= gain*(*pp++); }
for (j=0;j<lTarget;j++) { cvec[j] += gain*(*pp); target[j] -= gain*(*pp++); }
/* record quantized gain */
/* record quantized gain */
gains[stage]=gain;
增益[阶段]=增益;
}/* end of Main Loop. for (stage=0;... */
}/* end of Main Loop. for (stage=0;... */
/* Gain adjustment for energy matching */ cene=0.0; for (i=0; i<lTarget; i++) { cene+=cvec[i]*cvec[i]; } j=gain_index[0];
/* Gain adjustment for energy matching */ cene=0.0; for (i=0; i<lTarget; i++) { cene+=cvec[i]*cvec[i]; } j=gain_index[0];
for (i=gain_index[0]; i<32; i++) { ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
for (i=gain_index[0]; i<32; i++) { ftmp=cene*gain_sq5Tbl[i]*gain_sq5Tbl[i];
if ((ftmp<(tene*gains[0]*gains[0])) && (gain_sq5Tbl[j]<(2.0*gains[0]))) { j=i; } } gain_index[0]=j; }
if ((ftmp<(tene*gains[0]*gains[0])) && (gain_sq5Tbl[j]<(2.0*gains[0]))) { j=i; } } gain_index[0]=j; }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
LPC_decode.h
LPC_解码.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_LPC_DECODE_H #define __iLBC_LPC_DECODE_H
#ifndef __iLBC_LPC_DECODE_H #define __iLBC_LPC_DECODE_H
void LSFinterpolate2a_dec( float *a, /* (o) lpc coefficients for a sub-frame */ float *lsf1, /* (i) first lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */ float coef, /* (i) interpolation weight */ int length /* (i) length of lsf vectors */ );
void LSFinterpolate2a_dec( float *a, /* (o) lpc coefficients for a sub-frame */ float *lsf1, /* (i) first lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */ float coef, /* (i) interpolation weight */ int length /* (i) length of lsf vectors */ );
void SimplelsfDEQ( float *lsfdeq, /* (o) dequantized lsf coefficients */ int *index, /* (i) quantization index */ int lpc_n /* (i) number of LPCs */ );
void SimplelsfDEQ( float *lsfdeq, /* (o) dequantized lsf coefficients */ int *index, /* (i) quantization index */ int lpc_n /* (i) number of LPCs */ );
void DecoderInterpolateLSF( float *syntdenum, /* (o) synthesis filter coefficients */ float *weightdenum, /* (o) weighting denumerator coefficients */ float *lsfdeq, /* (i) dequantized lsf coefficients */ int length, /* (i) length of lsf coefficient vector */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) the decoder state structure */ );
void DecoderInterpolateLSF( float *syntdenum, /* (o) synthesis filter coefficients */ float *weightdenum, /* (o) weighting denumerator coefficients */ float *lsfdeq, /* (i) dequantized lsf coefficients */ int length, /* (i) length of lsf coefficient vector */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) the decoder state structure */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
LPC_decode.c
LPC_decode.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <string.h>
#include <math.h> #include <string.h>
#include "helpfun.h" #include "lsf.h" #include "iLBC_define.h" #include "constants.h"
#包括“helpfun.h”#包括“lsf.h”#包括“iLBC_define.h”#包括“constants.h”
/*---------------------------------------------------------------* * interpolation of lsf coefficients for the decoder *--------------------------------------------------------------*/
/*---------------------------------------------------------------* * interpolation of lsf coefficients for the decoder *--------------------------------------------------------------*/
void LSFinterpolate2a_dec( float *a, /* (o) lpc coefficients for a sub-frame */ float *lsf1, /* (i) first lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */ float coef, /* (i) interpolation weight */ int length /* (i) length of lsf vectors */ ){ float lsftmp[LPC_FILTERORDER];
void LSFinterpolate2a_dec( float *a, /* (o) lpc coefficients for a sub-frame */ float *lsf1, /* (i) first lsf coefficient vector */ float *lsf2, /* (i) second lsf coefficient vector */ float coef, /* (i) interpolation weight */ int length /* (i) length of lsf vectors */ ){ float lsftmp[LPC_FILTERORDER];
interpolate(lsftmp, lsf1, lsf2, coef, length); lsf2a(a, lsftmp); }
interpolate(lsftmp, lsf1, lsf2, coef, length); lsf2a(a, lsftmp); }
/*---------------------------------------------------------------* * obtain dequantized lsf coefficients from quantization index *--------------------------------------------------------------*/
/*---------------------------------------------------------------* * obtain dequantized lsf coefficients from quantization index *--------------------------------------------------------------*/
void SimplelsfDEQ( float *lsfdeq, /* (o) dequantized lsf coefficients */ int *index, /* (i) quantization index */ int lpc_n /* (i) number of LPCs */ ){ int i, j, pos, cb_pos;
void SimplelsfDEQ( float *lsfdeq, /* (o) dequantized lsf coefficients */ int *index, /* (i) quantization index */ int lpc_n /* (i) number of LPCs */ ){ int i, j, pos, cb_pos;
/* decode first LSF */
/* decode first LSF */
pos = 0; cb_pos = 0; for (i = 0; i < LSF_NSPLIT; i++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) { lsfdeq[pos + j] = lsfCbTbl[cb_pos + (long)(index[i])*dim_lsfCbTbl[i] + j]; } pos += dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; }
pos = 0; cb_pos = 0; for (i = 0; i < LSF_NSPLIT; i++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) { lsfdeq[pos + j] = lsfCbTbl[cb_pos + (long)(index[i])*dim_lsfCbTbl[i] + j]; } pos += dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; }
if (lpc_n>1) {
如果(lpc_n>1){
/* decode last LSF */
/* decode last LSF */
pos = 0; cb_pos = 0; for (i = 0; i < LSF_NSPLIT; i++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) { lsfdeq[LPC_FILTERORDER + pos + j] = lsfCbTbl[cb_pos + (long)(index[LSF_NSPLIT + i])* dim_lsfCbTbl[i] + j]; } pos += dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; } } }
pos = 0; cb_pos = 0; for (i = 0; i < LSF_NSPLIT; i++) { for (j = 0; j < dim_lsfCbTbl[i]; j++) { lsfdeq[LPC_FILTERORDER + pos + j] = lsfCbTbl[cb_pos + (long)(index[LSF_NSPLIT + i])* dim_lsfCbTbl[i] + j]; } pos += dim_lsfCbTbl[i]; cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i]; } } }
/*----------------------------------------------------------------* * obtain synthesis and weighting filters form lsf coefficients *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * obtain synthesis and weighting filters form lsf coefficients *---------------------------------------------------------------*/
void DecoderInterpolateLSF( float *syntdenum, /* (o) synthesis filter coefficients */ float *weightdenum, /* (o) weighting denumerator coefficients */ float *lsfdeq, /* (i) dequantized lsf coefficients */ int length, /* (i) length of lsf coefficient vector */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) the decoder state structure */ ){ int i, pos, lp_length; float lp[LPC_FILTERORDER + 1], *lsfdeq2;
void DecoderInterpolateLSF( float *syntdenum, /* (o) synthesis filter coefficients */ float *weightdenum, /* (o) weighting denumerator coefficients */ float *lsfdeq, /* (i) dequantized lsf coefficients */ int length, /* (i) length of lsf coefficient vector */ iLBC_Dec_Inst_t *iLBCdec_inst /* (i) the decoder state structure */ ){ int i, pos, lp_length; float lp[LPC_FILTERORDER + 1], *lsfdeq2;
lsfdeq2 = lsfdeq + length; lp_length = length + 1;
lsfdeq2 = lsfdeq + length; lp_length = length + 1;
if (iLBCdec_inst->mode==30) { /* sub-frame 1: Interpolation between old and first */
if (iLBCdec_inst->mode==30) { /* sub-frame 1: Interpolation between old and first */
LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, lsf_weightTbl_30ms[0], length); memcpy(syntdenum,lp,lp_length*sizeof(float)); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, lsf_weightTbl_30ms[0], length); memcpy(syntdenum,lp,lp_length*sizeof(float)); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
/* sub-frames 2 to 6: interpolation between first and last LSF */
/* sub-frames 2 to 6: interpolation between first and last LSF */
pos = lp_length; for (i = 1; i < 6; i++) { LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, lsf_weightTbl_30ms[i], length); memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } } else { pos = 0; for (i = 0; i < iLBCdec_inst->nsub; i++) { LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, lsf_weightTbl_20ms[i], length); memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } }
pos = lp_length; for (i = 1; i < 6; i++) { LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, lsf_weightTbl_30ms[i], length); memcpy(syntdenum + pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } } else { pos = 0; for (i = 0; i < iLBCdec_inst->nsub; i++) { LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, lsf_weightTbl_20ms[i], length); memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } }
/* update memory */
/* update memory */
if (iLBCdec_inst->mode==30) memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, length*sizeof(float)); else memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, length*sizeof(float));
if (iLBCdec_inst->mode==30) memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, length*sizeof(float)); else memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, length*sizeof(float));
}
}
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
LPCencode.h
LPCencode.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_LPCENCOD_H #define __iLBC_LPCENCOD_H
#ifndef __iLBC_LPCENCOD_H #define __iLBC_LPCENCOD_H
void LPCencode( float *syntdenum, /* (i/o) synthesis filter coefficients before/after encoding */ float *weightdenum, /* (i/o) weighting denumerator coefficients before/after encoding */ int *lsf_index, /* (o) lsf quantization index */ float *data, /* (i) lsf coefficients to quantize */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ );
void LPCencode( float *syntdenum, /* (i/o) synthesis filter coefficients before/after encoding */ float *weightdenum, /* (i/o) weighting denumerator coefficients before/after encoding */ int *lsf_index, /* (o) lsf quantization index */ float *data, /* (i) lsf coefficients to quantize */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
LPCencode.c
LPCencode.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <string.h>
#include <string.h>
#include "iLBC_define.h" #include "helpfun.h" #include "lsf.h" #include "constants.h"
#包括“iLBC_define.h”#包括“helpfun.h”#包括“lsf.h”#包括“constants.h”
/*----------------------------------------------------------------* * lpc analysis (subrutine to LPCencode) *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * lpc analysis (subrutine to LPCencode) *---------------------------------------------------------------*/
void SimpleAnalysis( float *lsf, /* (o) lsf coefficients */ float *data, /* (i) new data vector */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ int k, is; float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1]; float lp2[LPC_FILTERORDER + 1]; float r[LPC_FILTERORDER + 1];
void SimpleAnalysis( float *lsf, /* (o) lsf coefficients */ float *data, /* (i) new data vector */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ int k, is; float temp[BLOCKL_MAX], lp[LPC_FILTERORDER + 1]; float lp2[LPC_FILTERORDER + 1]; float r[LPC_FILTERORDER + 1];
is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; memcpy(iLBCenc_inst->lpc_buffer+is,data, iLBCenc_inst->blockl*sizeof(float));
is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; memcpy(iLBCenc_inst->lpc_buffer+is,data, iLBCenc_inst->blockl*sizeof(float));
/* No lookahead, last window is asymmetric */
/* No lookahead, last window is asymmetric */
for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
is = LPC_LOOKBACK;
is=LPC_回望;
if (k < (iLBCenc_inst->lpc_n - 1)) { window(temp, lpc_winTbl, iLBCenc_inst->lpc_buffer, BLOCKL_MAX); } else { window(temp, lpc_asymwinTbl, iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX); }
if (k < (iLBCenc_inst->lpc_n - 1)) { window(temp, lpc_winTbl, iLBCenc_inst->lpc_buffer, BLOCKL_MAX); } else { window(temp, lpc_asymwinTbl, iLBCenc_inst->lpc_buffer + is, BLOCKL_MAX); }
autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER); window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);
autocorr(r, temp, BLOCKL_MAX, LPC_FILTERORDER); window(r, r, lpc_lagwinTbl, LPC_FILTERORDER + 1);
levdurb(lp, temp, r, LPC_FILTERORDER); bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);
levdurb(lp, temp, r, LPC_FILTERORDER); bwexpand(lp2, lp, LPC_CHIRP_SYNTDENUM, LPC_FILTERORDER+1);
a2lsf(lsf + k*LPC_FILTERORDER, lp2); } is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; memmove(iLBCenc_inst->lpc_buffer, iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is*sizeof(float)); }
a2lsf(lsf + k*LPC_FILTERORDER, lp2); } is=LPC_LOOKBACK+BLOCKL_MAX-iLBCenc_inst->blockl; memmove(iLBCenc_inst->lpc_buffer, iLBCenc_inst->lpc_buffer+LPC_LOOKBACK+BLOCKL_MAX-is, is*sizeof(float)); }
/*----------------------------------------------------------------*
/*----------------------------------------------------------------*
* lsf interpolator and conversion from lsf to a coefficients * (subrutine to SimpleInterpolateLSF) *---------------------------------------------------------------*/
* lsf插值器和从lsf到a系数的转换*(subrutine到SimpleInterpolateLSF)*---------------------------------------------------------------*/
void LSFinterpolate2a_enc( float *a, /* (o) lpc coefficients */ float *lsf1,/* (i) first set of lsf coefficients */ float *lsf2,/* (i) second set of lsf coefficients */ float coef, /* (i) weighting coefficient to use between lsf1 and lsf2 */ long length /* (i) length of coefficient vectors */ ){ float lsftmp[LPC_FILTERORDER];
void LSFinterpolate2a_enc( float *a, /* (o) lpc coefficients */ float *lsf1,/* (i) first set of lsf coefficients */ float *lsf2,/* (i) second set of lsf coefficients */ float coef, /* (i) weighting coefficient to use between lsf1 and lsf2 */ long length /* (i) length of coefficient vectors */ ){ float lsftmp[LPC_FILTERORDER];
interpolate(lsftmp, lsf1, lsf2, coef, length); lsf2a(a, lsftmp); }
interpolate(lsftmp, lsf1, lsf2, coef, length); lsf2a(a, lsftmp); }
/*----------------------------------------------------------------* * lsf interpolator (subrutine to LPCencode) *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * lsf interpolator (subrutine to LPCencode) *---------------------------------------------------------------*/
void SimpleInterpolateLSF( float *syntdenum, /* (o) the synthesis filter denominator resulting from the quantized interpolated lsf */ float *weightdenum, /* (o) the weighting filter denominator resulting from the unquantized interpolated lsf */ float *lsf, /* (i) the unquantized lsf coefficients */ float *lsfdeq, /* (i) the dequantized lsf coefficients */ float *lsfold, /* (i) the unquantized lsf coefficients of the previous signal frame */ float *lsfdeqold, /* (i) the dequantized lsf coefficients of the previous signal frame */ int length, /* (i) should equate LPC_FILTERORDER */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ int i, pos, lp_length; float lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2;
void SimpleInterpolateLSF( float *syntdenum, /* (o) the synthesis filter denominator resulting from the quantized interpolated lsf */ float *weightdenum, /* (o) the weighting filter denominator resulting from the unquantized interpolated lsf */ float *lsf, /* (i) the unquantized lsf coefficients */ float *lsfdeq, /* (i) the dequantized lsf coefficients */ float *lsfold, /* (i) the unquantized lsf coefficients of the previous signal frame */ float *lsfdeqold, /* (i) the dequantized lsf coefficients of the previous signal frame */ int length, /* (i) should equate LPC_FILTERORDER */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ int i, pos, lp_length; float lp[LPC_FILTERORDER + 1], *lsf2, *lsfdeq2;
lsf2 = lsf + length; lsfdeq2 = lsfdeq + length; lp_length = length + 1;
lsf2 = lsf + length; lsfdeq2 = lsfdeq + length; lp_length = length + 1;
if (iLBCenc_inst->mode==30) { /* sub-frame 1: Interpolation between old and first
if (iLBCenc_inst->mode==30) { /* sub-frame 1: Interpolation between old and first
set of lsf coefficients */
set of lsf coefficients */
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq, lsf_weightTbl_30ms[0], length); memcpy(syntdenum,lp,lp_length*sizeof(float)); LSFinterpolate2a_enc(lp, lsfold, lsf, lsf_weightTbl_30ms[0], length); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq, lsf_weightTbl_30ms[0], length); memcpy(syntdenum,lp,lp_length*sizeof(float)); LSFinterpolate2a_enc(lp, lsfold, lsf, lsf_weightTbl_30ms[0], length); bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, lp_length);
/* sub-frame 2 to 6: Interpolation between first and second set of lsf coefficients */
/* sub-frame 2 to 6: Interpolation between first and second set of lsf coefficients */
pos = lp_length; for (i = 1; i < iLBCenc_inst->nsub; i++) { LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2, lsf_weightTbl_30ms[i], length); memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
pos = lp_length; for (i = 1; i < iLBCenc_inst->nsub; i++) { LSFinterpolate2a_enc(lp, lsfdeq, lsfdeq2, lsf_weightTbl_30ms[i], length); memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
LSFinterpolate2a_enc(lp, lsf, lsf2, lsf_weightTbl_30ms[i], length); bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } } else { pos = 0; for (i = 0; i < iLBCenc_inst->nsub; i++) { LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq, lsf_weightTbl_20ms[i], length); memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); LSFinterpolate2a_enc(lp, lsfold, lsf, lsf_weightTbl_20ms[i], length); bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } }
LSFinterpolate2a_enc(lp, lsf, lsf2, lsf_weightTbl_30ms[i], length); bwexpand(weightdenum + pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } } else { pos = 0; for (i = 0; i < iLBCenc_inst->nsub; i++) { LSFinterpolate2a_enc(lp, lsfdeqold, lsfdeq, lsf_weightTbl_20ms[i], length); memcpy(syntdenum+pos,lp,lp_length*sizeof(float)); LSFinterpolate2a_enc(lp, lsfold, lsf, lsf_weightTbl_20ms[i], length); bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM, lp_length); pos += lp_length; } }
/* update memory */
/* update memory */
if (iLBCenc_inst->mode==30) { memcpy(lsfold, lsf2, length*sizeof(float)); memcpy(lsfdeqold, lsfdeq2, length*sizeof(float)); } else { memcpy(lsfold, lsf, length*sizeof(float)); memcpy(lsfdeqold, lsfdeq, length*sizeof(float));
if (iLBCenc_inst->mode==30) { memcpy(lsfold, lsf2, length*sizeof(float)); memcpy(lsfdeqold, lsfdeq2, length*sizeof(float)); } else { memcpy(lsfold, lsf, length*sizeof(float)); memcpy(lsfdeqold, lsfdeq, length*sizeof(float));
} }
} }
/*----------------------------------------------------------------* * lsf quantizer (subrutine to LPCencode) *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * lsf quantizer (subrutine to LPCencode) *---------------------------------------------------------------*/
void SimplelsfQ( float *lsfdeq, /* (o) dequantized lsf coefficients (dimension FILTERORDER) */ int *index, /* (o) quantization index */ float *lsf, /* (i) the lsf coefficient vector to be quantized (dimension FILTERORDER ) */ int lpc_n /* (i) number of lsf sets to quantize */ ){ /* Quantize first LSF with memoryless split VQ */ SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT, dim_lsfCbTbl, size_lsfCbTbl);
void SimplelsfQ( float *lsfdeq, /* (o) dequantized lsf coefficients (dimension FILTERORDER) */ int *index, /* (o) quantization index */ float *lsf, /* (i) the lsf coefficient vector to be quantized (dimension FILTERORDER ) */ int lpc_n /* (i) number of lsf sets to quantize */ ){ /* Quantize first LSF with memoryless split VQ */ SplitVQ(lsfdeq, index, lsf, lsfCbTbl, LSF_NSPLIT, dim_lsfCbTbl, size_lsfCbTbl);
if (lpc_n==2) { /* Quantize second LSF with memoryless split VQ */ SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT, lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT, dim_lsfCbTbl, size_lsfCbTbl); } }
if (lpc_n==2) { /* Quantize second LSF with memoryless split VQ */ SplitVQ(lsfdeq + LPC_FILTERORDER, index + LSF_NSPLIT, lsf + LPC_FILTERORDER, lsfCbTbl, LSF_NSPLIT, dim_lsfCbTbl, size_lsfCbTbl); } }
/*----------------------------------------------------------------* * lpc encoder *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * lpc encoder *---------------------------------------------------------------*/
void LPCencode( float *syntdenum, /* (i/o) synthesis filter coefficients before/after encoding */ float *weightdenum, /* (i/o) weighting denumerator coefficients before/after encoding */ int *lsf_index, /* (o) lsf quantization index */ float *data, /* (i) lsf coefficients to quantize */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ float lsf[LPC_FILTERORDER * LPC_N_MAX]; float lsfdeq[LPC_FILTERORDER * LPC_N_MAX]; int change=0;
void LPCencode( float *syntdenum, /* (i/o) synthesis filter coefficients before/after encoding */ float *weightdenum, /* (i/o) weighting denumerator coefficients before/after encoding */ int *lsf_index, /* (o) lsf quantization index */ float *data, /* (i) lsf coefficients to quantize */ iLBC_Enc_Inst_t *iLBCenc_inst /* (i/o) the encoder state structure */ ){ float lsf[LPC_FILTERORDER * LPC_N_MAX]; float lsfdeq[LPC_FILTERORDER * LPC_N_MAX]; int change=0;
SimpleAnalysis(lsf, data, iLBCenc_inst); SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);
SimpleAnalysis(lsf, data, iLBCenc_inst); SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);
change=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n); SimpleInterpolateLSF(syntdenum, weightdenum, lsf, lsfdeq, iLBCenc_inst->lsfold, iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst); }
change=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n); SimpleInterpolateLSF(syntdenum, weightdenum, lsf, lsfdeq, iLBCenc_inst->lsfold, iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
lsf.h
lsf.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_LSF_H #define __iLBC_LSF_H
#ifndef __iLBC_LSF_H #define __iLBC_LSF_H
void a2lsf( float *freq,/* (o) lsf coefficients */ float *a /* (i) lpc coefficients */ );
void a2lsf( float *freq,/* (o) lsf coefficients */ float *a /* (i) lpc coefficients */ );
void lsf2a( float *a_coef, /* (o) lpc coefficients */ float *freq /* (i) lsf coefficients */ );
void lsf2a( float *a_coef, /* (o) lpc coefficients */ float *freq /* (i) lsf coefficients */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
lsf.c
lsf.c
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <string.h>
#include <string.h>
#include <math.h>
#include <math.h>
#include "iLBC_define.h"
#包括“iLBC_define.h”
/*----------------------------------------------------------------* * conversion from lpc coefficients to lsf coefficients *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * conversion from lpc coefficients to lsf coefficients *---------------------------------------------------------------*/
void a2lsf( float *freq,/* (o) lsf coefficients */ float *a /* (i) lpc coefficients */ ){ float steps[LSF_NUMBER_OF_STEPS] = {(float)0.00635, (float)0.003175, (float)0.0015875, (float)0.00079375}; float step; int step_idx; int lsp_index; float p[LPC_HALFORDER]; float q[LPC_HALFORDER]; float p_pre[LPC_HALFORDER]; float q_pre[LPC_HALFORDER]; float old_p, old_q, *old; float *pq_coef; float omega, old_omega; int i; float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;
void a2lsf( float *freq,/* (o) lsf coefficients */ float *a /* (i) lpc coefficients */ ){ float steps[LSF_NUMBER_OF_STEPS] = {(float)0.00635, (float)0.003175, (float)0.0015875, (float)0.00079375}; float step; int step_idx; int lsp_index; float p[LPC_HALFORDER]; float q[LPC_HALFORDER]; float p_pre[LPC_HALFORDER]; float q_pre[LPC_HALFORDER]; float old_p, old_q, *old; float *pq_coef; float omega, old_omega; int i; float hlp, hlp1, hlp2, hlp3, hlp4, hlp5;
for (i=0; i<LPC_HALFORDER; i++) { p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]); q[i] = a[LPC_FILTERORDER - i] - a[i + 1]; }
for (i=0; i<LPC_HALFORDER; i++) { p[i] = (float)-1.0 * (a[i + 1] + a[LPC_FILTERORDER - i]); q[i] = a[LPC_FILTERORDER - i] - a[i + 1]; }
p_pre[0] = (float)-1.0 - p[0]; p_pre[1] = - p_pre[0] - p[1]; p_pre[2] = - p_pre[1] - p[2]; p_pre[3] = - p_pre[2] - p[3]; p_pre[4] = - p_pre[3] - p[4]; p_pre[4] = p_pre[4] / 2;
p_pre[0] = (float)-1.0 - p[0]; p_pre[1] = - p_pre[0] - p[1]; p_pre[2] = - p_pre[1] - p[2]; p_pre[3] = - p_pre[2] - p[3]; p_pre[4] = - p_pre[3] - p[4]; p_pre[4] = p_pre[4] / 2;
q_pre[0] = (float)1.0 - q[0]; q_pre[1] = q_pre[0] - q[1]; q_pre[2] = q_pre[1] - q[2]; q_pre[3] = q_pre[2] - q[3]; q_pre[4] = q_pre[3] - q[4]; q_pre[4] = q_pre[4] / 2;
q_pre[0] = (float)1.0 - q[0]; q_pre[1] = q_pre[0] - q[1]; q_pre[2] = q_pre[1] - q[2]; q_pre[3] = q_pre[2] - q[3]; q_pre[4] = q_pre[3] - q[4]; q_pre[4] = q_pre[4] / 2;
omega = 0.0;
ω=0.0;
old_omega = 0.0;
old_ω=0.0;
old_p = FLOAT_MAX; old_q = FLOAT_MAX;
old_p = FLOAT_MAX; old_q = FLOAT_MAX;
/* Here we loop through lsp_index to find all the LPC_FILTERORDER roots for omega. */
/* Here we loop through lsp_index to find all the LPC_FILTERORDER roots for omega. */
for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) {
for (lsp_index = 0; lsp_index<LPC_FILTERORDER; lsp_index++) {
/* Depending on lsp_index being even or odd, we alternatively solve the roots for the two LSP equations. */
/* Depending on lsp_index being even or odd, we alternatively solve the roots for the two LSP equations. */
if ((lsp_index & 0x1) == 0) { pq_coef = p_pre; old = &old_p; } else { pq_coef = q_pre; old = &old_q; }
if ((lsp_index & 0x1) == 0) { pq_coef = p_pre; old = &old_p; } else { pq_coef = q_pre; old = &old_q; }
/* Start with low resolution grid */
/* Start with low resolution grid */
for (step_idx = 0, step = steps[step_idx]; step_idx < LSF_NUMBER_OF_STEPS;){
for (step_idx = 0, step = steps[step_idx]; step_idx < LSF_NUMBER_OF_STEPS;){
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) + pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
/* cos(10piw) + pq(0)cos(8piw) + pq(1)cos(6piw) + pq(2)cos(4piw) + pq(3)cod(2piw) + pq(4) */
hlp = (float)cos(omega * TWO_PI); hlp1 = (float)2.0 * hlp + pq_coef[0]; hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 + pq_coef[1]; hlp3 = (float)2.0 * hlp * hlp2 - hlp1 + pq_coef[2]; hlp4 = (float)2.0 * hlp * hlp3 - hlp2 + pq_coef[3]; hlp5 = hlp * hlp4 - hlp3 + pq_coef[4];
hlp = (float)cos(omega * TWO_PI); hlp1 = (float)2.0 * hlp + pq_coef[0]; hlp2 = (float)2.0 * hlp * hlp1 - (float)1.0 + pq_coef[1]; hlp3 = (float)2.0 * hlp * hlp2 - hlp1 + pq_coef[2]; hlp4 = (float)2.0 * hlp * hlp3 - hlp2 + pq_coef[3]; hlp5 = hlp * hlp4 - hlp3 + pq_coef[4];
if (((hlp5 * (*old)) <= 0.0) || (omega >= 0.5)){
if (((hlp5 * (*old)) <= 0.0) || (omega >= 0.5)){
if (step_idx == (LSF_NUMBER_OF_STEPS - 1)){
if (step_idx == (LSF_NUMBER_OF_STEPS - 1)){
if (fabs(hlp5) >= fabs(*old)) { freq[lsp_index] = omega - step; } else { freq[lsp_index] = omega; }
if (fabs(hlp5) >= fabs(*old)) { freq[lsp_index] = omega - step; } else { freq[lsp_index] = omega; }
if ((*old) >= 0.0){ *old = (float)-1.0 * FLOAT_MAX; } else { *old = FLOAT_MAX; }
if ((*old) >= 0.0){ *old = (float)-1.0 * FLOAT_MAX; } else { *old = FLOAT_MAX; }
omega = old_omega; step_idx = 0;
omega = old_omega; step_idx = 0;
step_idx = LSF_NUMBER_OF_STEPS; } else {
step_idx = LSF_NUMBER_OF_STEPS; } else {
if (step_idx == 0) { old_omega = omega; }
if (step_idx == 0) { old_omega = omega; }
step_idx++; omega -= steps[step_idx];
step_idx++; omega -= steps[step_idx];
/* Go back one grid step */
/* Go back one grid step */
step = steps[step_idx]; } } else {
step = steps[step_idx]; } } else {
/* increment omega until they are of different sign, and we know there is at least one root between omega and old_omega */ *old = hlp5; omega += step; } } }
/* increment omega until they are of different sign, and we know there is at least one root between omega and old_omega */ *old = hlp5; omega += step; } } }
for (i = 0; i<LPC_FILTERORDER; i++) { freq[i] = freq[i] * TWO_PI; } }
for (i = 0; i<LPC_FILTERORDER; i++) { freq[i] = freq[i] * TWO_PI; } }
/*----------------------------------------------------------------* * conversion from lsf coefficients to lpc coefficients *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * conversion from lsf coefficients to lpc coefficients *---------------------------------------------------------------*/
void lsf2a( float *a_coef, /* (o) lpc coefficients */ float *freq /* (i) lsf coefficients */
void lsf2a( float *a_coef, /* (o) lpc coefficients */ float *freq /* (i) lsf coefficients */
){ int i, j; float hlp; float p[LPC_HALFORDER], q[LPC_HALFORDER]; float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER], a2[LPC_HALFORDER]; float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER], b2[LPC_HALFORDER];
){ int i, j; float hlp; float p[LPC_HALFORDER], q[LPC_HALFORDER]; float a[LPC_HALFORDER + 1], a1[LPC_HALFORDER], a2[LPC_HALFORDER]; float b[LPC_HALFORDER + 1], b1[LPC_HALFORDER], b2[LPC_HALFORDER];
for (i=0; i<LPC_FILTERORDER; i++) { freq[i] = freq[i] * PI2; }
for (i=0; i<LPC_FILTERORDER; i++) { freq[i] = freq[i] * PI2; }
/* Check input for ill-conditioned cases. This part is not found in the TIA standard. It involves the following 2 IF blocks. If "freq" is judged ill-conditioned, then we first modify freq[0] and freq[LPC_HALFORDER-1] (normally LPC_HALFORDER = 10 for LPC applications), then we adjust the other "freq" values slightly */
/* Check input for ill-conditioned cases. This part is not found in the TIA standard. It involves the following 2 IF blocks. If "freq" is judged ill-conditioned, then we first modify freq[0] and freq[LPC_HALFORDER-1] (normally LPC_HALFORDER = 10 for LPC applications), then we adjust the other "freq" values slightly */
if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){
if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){
if (freq[0] <= 0.0) { freq[0] = (float)0.022; }
if (freq[0] <= 0.0) { freq[0] = (float)0.022; }
if (freq[LPC_FILTERORDER - 1] >= 0.5) { freq[LPC_FILTERORDER - 1] = (float)0.499; }
if (freq[LPC_FILTERORDER - 1] >= 0.5) { freq[LPC_FILTERORDER - 1] = (float)0.499; }
hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) / (float) (LPC_FILTERORDER - 1);
hlp = (freq[LPC_FILTERORDER - 1] - freq[0]) / (float) (LPC_FILTERORDER - 1);
for (i=1; i<LPC_FILTERORDER; i++) { freq[i] = freq[i - 1] + hlp; } }
for (i=1; i<LPC_FILTERORDER; i++) { freq[i] = freq[i - 1] + hlp; } }
memset(a1, 0, LPC_HALFORDER*sizeof(float)); memset(a2, 0, LPC_HALFORDER*sizeof(float)); memset(b1, 0, LPC_HALFORDER*sizeof(float)); memset(b2, 0, LPC_HALFORDER*sizeof(float)); memset(a, 0, (LPC_HALFORDER+1)*sizeof(float)); memset(b, 0, (LPC_HALFORDER+1)*sizeof(float));
memset(a1, 0, LPC_HALFORDER*sizeof(float)); memset(a2, 0, LPC_HALFORDER*sizeof(float)); memset(b1, 0, LPC_HALFORDER*sizeof(float)); memset(b2, 0, LPC_HALFORDER*sizeof(float)); memset(a, 0, (LPC_HALFORDER+1)*sizeof(float)); memset(b, 0, (LPC_HALFORDER+1)*sizeof(float));
/* p[i] and q[i] compute cos(2*pi*omega_{2j}) and cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2. Note that for this code p[i] specifies the coefficients used in .Q_A(z) while q[i] specifies the coefficients used in .P_A(z) */
/* p[i] and q[i] compute cos(2*pi*omega_{2j}) and cos(2*pi*omega_{2j-1} in eqs. 4.2.2.2-1 and 4.2.2.2-2. Note that for this code p[i] specifies the coefficients used in .Q_A(z) while q[i] specifies the coefficients used in .P_A(z) */
for (i=0; i<LPC_HALFORDER; i++) { p[i] = (float)cos(TWO_PI * freq[2 * i]); q[i] = (float)cos(TWO_PI * freq[2 * i + 1]); }
for (i=0; i<LPC_HALFORDER; i++) { p[i] = (float)cos(TWO_PI * freq[2 * i]); q[i] = (float)cos(TWO_PI * freq[2 * i + 1]); }
a[0] = 0.25; b[0] = 0.25;
a[0] = 0.25; b[0] = 0.25;
for (i= 0; i<LPC_HALFORDER; i++) { a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a2[i] = a1[i]; a1[i] = a[i]; b2[i] = b1[i]; b1[i] = b[i]; }
for (i= 0; i<LPC_HALFORDER; i++) { a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a2[i] = a1[i]; a1[i] = a[i]; b2[i] = b1[i]; b1[i] = b[i]; }
for (j=0; j<LPC_FILTERORDER; j++) {
for (j=0; j<LPC_FILTERORDER; j++) {
if (j == 0) { a[0] = 0.25; b[0] = -0.25; } else { a[0] = b[0] = 0.0; }
if (j == 0) { a[0] = 0.25; b[0] = -0.25; } else { a[0] = b[0] = 0.0; }
for (i=0; i<LPC_HALFORDER; i++) { a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a2[i] = a1[i]; a1[i] = a[i]; b2[i] = b1[i]; b1[i] = b[i]; }
for (i=0; i<LPC_HALFORDER; i++) { a[i + 1] = a[i] - 2 * p[i] * a1[i] + a2[i]; b[i + 1] = b[i] - 2 * q[i] * b1[i] + b2[i]; a2[i] = a1[i]; a1[i] = a[i]; b2[i] = b1[i]; b1[i] = b[i]; }
a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]); }
a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]); }
a_coef[0] = 1.0; }
a_coef[0] = 1.0; }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
packing.h
包装
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __PACKING_H #define __PACKING_H
#ifndef __PACKING_H #define __PACKING_H
void packsplit( int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most significant bits */ int *rest, /* (o) the value specified by least significant bits */ int bitno_firstpart, /* (i) number of bits in most significant part */ int bitno_total /* (i) number of bits in full range of value */ );
void packsplit( int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most significant bits */ int *rest, /* (o) the value specified by least significant bits */ int bitno_firstpart, /* (i) number of bits in most significant part */ int bitno_total /* (i) number of bits in full range of value */ );
void packcombine( int *index, /* (i/o) the msb value in the combined value out */ int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the lsb part */ );
void packcombine( int *index, /* (i/o) the msb value in the combined value out */ int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the lsb part */ );
void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to pack new data, on exit pointer to place in bitstream to pack future data */ int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the value will fit within */ int *pos /* (i/o) write position in the current byte */ );
void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to pack new data, on exit pointer to place in bitstream to pack future data */ int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the value will fit within */ int *pos /* (i/o) write position in the current byte */ );
void unpack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to unpack new data from, on exit pointer to place in bitstream to unpack future data from */ int *index, /* (o) resulting value */ int bitno, /* (i) number of bits used to represent the value */ int *pos /* (i/o) read position in the current byte */ );
void unpack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to unpack new data from, on exit pointer to place in bitstream to unpack future data from */ int *index, /* (o) resulting value */ int bitno, /* (i) number of bits used to represent the value */ int *pos /* (i/o) read position in the current byte */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
packing.c
包装
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <stdlib.h>
#include <math.h> #include <stdlib.h>
#include "iLBC_define.h" #include "constants.h" #include "helpfun.h" #include "string.h"
#包括“iLBC_define.h”#包括“constants.h”#包括“helpfun.h”#包括“string.h”
/*----------------------------------------------------------------* * splitting an integer into first most significant bits and * remaining least significant bits *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * splitting an integer into first most significant bits and * remaining least significant bits *---------------------------------------------------------------*/
void packsplit( int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most significant bits */ int *rest, /* (o) the value specified by least significant bits */
void packsplit( int *index, /* (i) the value to split */ int *firstpart, /* (o) the value specified by most significant bits */ int *rest, /* (o) the value specified by least significant bits */
int bitno_firstpart, /* (i) number of bits in most significant part */ int bitno_total /* (i) number of bits in full range of value */ ){ int bitno_rest = bitno_total-bitno_firstpart;
int bitno_firstpart, /* (i) number of bits in most significant part */ int bitno_total /* (i) number of bits in full range of value */ ){ int bitno_rest = bitno_total-bitno_firstpart;
*firstpart = *index>>(bitno_rest); *rest = *index-(*firstpart<<(bitno_rest)); }
*firstpart = *index>>(bitno_rest); *rest = *index-(*firstpart<<(bitno_rest)); }
/*----------------------------------------------------------------* * combining a value corresponding to msb's with a value * corresponding to lsb's *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * combining a value corresponding to msb's with a value * corresponding to lsb's *---------------------------------------------------------------*/
void packcombine( int *index, /* (i/o) the msb value in the combined value out */ int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the lsb part */ ){ *index = *index<<bitno_rest; *index += rest; }
void packcombine( int *index, /* (i/o) the msb value in the combined value out */ int rest, /* (i) the lsb value */ int bitno_rest /* (i) the number of bits in the lsb part */ ){ *index = *index<<bitno_rest; *index += rest; }
/*----------------------------------------------------------------* * packing of bits into bitstream, i.e., vector of bytes *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * packing of bits into bitstream, i.e., vector of bytes *---------------------------------------------------------------*/
void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to pack new data, on exit pointer to place in bitstream to pack future data */ int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the value will fit within */ int *pos /* (i/o) write position in the current byte */ ){ int posLeft;
void dopack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to pack new data, on exit pointer to place in bitstream to pack future data */ int index, /* (i) the value to pack */ int bitno, /* (i) the number of bits that the value will fit within */ int *pos /* (i/o) write position in the current byte */ ){ int posLeft;
/* Clear the bits before starting in a new byte */
/* Clear the bits before starting in a new byte */
if ((*pos)==0) {
if ((*pos)==0) {
**bitstream=0; }
**bitstream=0; }
while (bitno>0) {
而(位号>0){
/* Jump to the next byte if end of this byte is reached*/
/* Jump to the next byte if end of this byte is reached*/
if (*pos==8) { *pos=0; (*bitstream)++; **bitstream=0; }
if (*pos==8) { *pos=0; (*bitstream)++; **bitstream=0; }
posLeft=8-(*pos);
posLeft=8-(*pos);
/* Insert index into the bitstream */
/* Insert index into the bitstream */
if (bitno <= posLeft) { **bitstream |= (unsigned char)(index<<(posLeft-bitno)); *pos+=bitno; bitno=0; } else { **bitstream |= (unsigned char)(index>>(bitno-posLeft));
if (bitno <= posLeft) { **bitstream |= (unsigned char)(index<<(posLeft-bitno)); *pos+=bitno; bitno=0; } else { **bitstream |= (unsigned char)(index>>(bitno-posLeft));
*pos=8; index-=((index>>(bitno-posLeft))<<(bitno-posLeft));
*pos=8; index-=((index>>(bitno-posLeft))<<(bitno-posLeft));
bitno-=posLeft; } } }
bitno-=posLeft; } } }
/*----------------------------------------------------------------* * unpacking of bits from bitstream, i.e., vector of bytes *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * unpacking of bits from bitstream, i.e., vector of bytes *---------------------------------------------------------------*/
void unpack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to unpack new data from, on exit pointer to place in bitstream to unpack future data from */ int *index, /* (o) resulting value */ int bitno, /* (i) number of bits used to represent the value */ int *pos /* (i/o) read position in the current byte */
void unpack( unsigned char **bitstream, /* (i/o) on entrance pointer to place in bitstream to unpack new data from, on exit pointer to place in bitstream to unpack future data from */ int *index, /* (o) resulting value */ int bitno, /* (i) number of bits used to represent the value */ int *pos /* (i/o) read position in the current byte */
){ int BitsLeft;
){ int BitsLeft;
*index=0;
*index=0;
while (bitno>0) {
而(位号>0){
/* move forward in bitstream when the end of the byte is reached */
/* move forward in bitstream when the end of the byte is reached */
if (*pos==8) { *pos=0; (*bitstream)++; }
if (*pos==8) { *pos=0; (*bitstream)++; }
BitsLeft=8-(*pos);
BitsLeft=8-(*pos);
/* Extract bits to index */
/* Extract bits to index */
if (BitsLeft>=bitno) { *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));
if (BitsLeft>=bitno) { *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));
*pos+=bitno; bitno=0; } else {
*pos+=bitno; bitno=0; } else {
if ((8-bitno)>0) { *index+=((((**bitstream)<<(*pos)) & 0xFF)>> (8-bitno)); *pos=8; } else { *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<< (bitno-8)); *pos=8; } bitno-=BitsLeft; } } }
if ((8-bitno)>0) { *index+=((((**bitstream)<<(*pos)) & 0xFF)>> (8-bitno)); *pos=8; } else { *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<< (bitno-8)); *pos=8; } bitno-=BitsLeft; } } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
StateConstructW.h
州立大学
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_STATECONSTRUCTW_H #define __iLBC_STATECONSTRUCTW_H
#ifndef __iLBC_STATECONSTRUCTW_H #define __iLBC_STATECONSTRUCTW_H
void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */ int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */ float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */ );
void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */ int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */ float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
StateConstructW.c
华盛顿州
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <string.h>
#include <math.h> #include <string.h>
#include "iLBC_define.h" #include "constants.h" #include "filter.h"
#包括“iLBC_define.h”#包括“constants.h”#包括“filter.h”
/*----------------------------------------------------------------* * decoding of the start state *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * decoding of the start state *---------------------------------------------------------------*/
void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */ int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */
void StateConstructW( int idxForMax, /* (i) 6-bit index for the quantization of max amplitude */ int *idxVec, /* (i) vector of quantization indexes */ float *syntDenum, /* (i) synthesis filter denumerator */
float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */ ){ float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp, numerator[LPC_FILTERORDER+1]; float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout; int k,tmpi;
float *out, /* (o) the decoded state vector */ int len /* (i) length of a state vector */ ){ float maxVal, tmpbuf[LPC_FILTERORDER+2*STATE_LEN], *tmp, numerator[LPC_FILTERORDER+1]; float foutbuf[LPC_FILTERORDER+2*STATE_LEN], *fout; int k,tmpi;
/* decoding of the maximum value */
/* decoding of the maximum value */
maxVal = state_frgqTbl[idxForMax]; maxVal = (float)pow(10,maxVal)/(float)4.5;
maxVal = state_frgqTbl[idxForMax]; maxVal = (float)pow(10,maxVal)/(float)4.5;
/* initialization of buffers and coefficients */
/* initialization of buffers and coefficients */
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k<LPC_FILTERORDER; k++) { numerator[k]=syntDenum[LPC_FILTERORDER-k]; } numerator[LPC_FILTERORDER]=syntDenum[0]; tmp = &tmpbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER];
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k<LPC_FILTERORDER; k++) { numerator[k]=syntDenum[LPC_FILTERORDER-k]; } numerator[LPC_FILTERORDER]=syntDenum[0]; tmp = &tmpbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER];
/* decoding of the sample values */
/* decoding of the sample values */
for (k=0; k<len; k++) { tmpi = len-1-k; /* maxVal = 1/scal */ tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]]; }
for (k=0; k<len; k++) { tmpi = len-1-k; /* maxVal = 1/scal */ tmp[k] = maxVal*state_sq3Tbl[idxVec[tmpi]]; }
/* circular convolution with all-pass filter */
/* circular convolution with all-pass filter */
memset(tmp+len, 0, len*sizeof(float)); ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, LPC_FILTERORDER, fout); for (k=0;k<len;k++) { out[k] = fout[len-1-k]+fout[2*len-1-k]; } }
memset(tmp+len, 0, len*sizeof(float)); ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, LPC_FILTERORDER, fout); for (k=0;k<len;k++) { out[k] = fout[len-1-k]+fout[2*len-1-k]; } }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
StateSearchW.h
StateSearch W.h
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_STATESEARCHW_H #define __iLBC_STATESEARCHW_H
#ifndef __iLBC_STATESEARCHW_H #define __iLBC_STATESEARCHW_H
void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *in, /* (i) vector to encode */ float *syntDenum, /* (i) denominator of synthesis filter */ float *weightDenum, /* (i) denominator of weighting filter */ int *out, /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ );
void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *in, /* (i) vector to encode */ float *syntDenum, /* (i) denominator of synthesis filter */ float *weightDenum, /* (i) denominator of weighting filter */ int *out, /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ );
void StateSearchW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *residual,/* (i) target residual vector */ float *syntDenum, /* (i) lpc synthesis filter */ float *weightDenum, /* (i) weighting filter denuminator */ int *idxForMax, /* (o) quantizer index for maximum amplitude */ int *idxVec, /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first /* (i) position of start state in the 80 vec */ );
void StateSearchW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *residual,/* (i) target residual vector */ float *syntDenum, /* (i) lpc synthesis filter */ float *weightDenum, /* (i) weighting filter denuminator */ int *idxForMax, /* (o) quantizer index for maximum amplitude */ int *idxVec, /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first /* (i) position of start state in the 80 vec */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
StateSearchW.c
华盛顿州
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include <math.h> #include <string.h>
#include <math.h> #include <string.h>
#include "iLBC_define.h" #include "constants.h" #include "filter.h" #include "helpfun.h"
#包括“iLBC_define.h”#包括“constants.h”#包括“filter.h”#包括“helpfun.h”
/*----------------------------------------------------------------* * predictive noise shaping encoding of scaled start state * (subrutine for StateSearchW) *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * predictive noise shaping encoding of scaled start state * (subrutine for StateSearchW) *---------------------------------------------------------------*/
void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *in, /* (i) vector to encode */ float *syntDenum, /* (i) denominator of synthesis filter */ float *weightDenum, /* (i) denominator of weighting filter */ int *out, /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ ){ float *syntOut; float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS]; float toQ, xq; int n; int index;
void AbsQuantW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *in, /* (i) vector to encode */ float *syntDenum, /* (i) denominator of synthesis filter */ float *weightDenum, /* (i) denominator of weighting filter */ int *out, /* (o) vector of quantizer indexes */ int len, /* (i) length of vector to encode and vector of quantizer indexes */ int state_first /* (i) position of start state in the 80 vec */ ){ float *syntOut; float syntOutBuf[LPC_FILTERORDER+STATE_SHORT_LEN_30MS]; float toQ, xq; int n; int index;
/* initialization of buffer for filtering */
/* initialization of buffer for filtering */
memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
/* initialization of pointer for filtering */
/* initialization of pointer for filtering */
syntOut = &syntOutBuf[LPC_FILTERORDER];
syntOut = &syntOutBuf[LPC_FILTERORDER];
/* synthesis and weighting filters on input */
/* synthesis and weighting filters on input */
if (state_first) { AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER); } else { AllPoleFilter (in, weightDenum, iLBCenc_inst->state_short_len-SUBL, LPC_FILTERORDER); }
if (state_first) { AllPoleFilter (in, weightDenum, SUBL, LPC_FILTERORDER); } else { AllPoleFilter (in, weightDenum, iLBCenc_inst->state_short_len-SUBL, LPC_FILTERORDER); }
/* encoding loop */
/* encoding loop */
for (n=0; n<len; n++) {
for (n=0; n<len; n++) {
/* time update of filter coefficients */
/* time update of filter coefficients */
if ((state_first)&&(n==SUBL)){ syntDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1);
if ((state_first)&&(n==SUBL)){ syntDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1);
/* synthesis and weighting filters on input */ AllPoleFilter (&in[n], weightDenum, len-n, LPC_FILTERORDER);
/* synthesis and weighting filters on input */ AllPoleFilter (&in[n], weightDenum, len-n, LPC_FILTERORDER);
} else if ((state_first==0)&& (n==(iLBCenc_inst->state_short_len-SUBL))) { syntDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1);
} else if ((state_first==0)&& (n==(iLBCenc_inst->state_short_len-SUBL))) { syntDenum += (LPC_FILTERORDER+1); weightDenum += (LPC_FILTERORDER+1);
/* synthesis and weighting filters on input */ AllPoleFilter (&in[n], weightDenum, len-n, LPC_FILTERORDER);
/* synthesis and weighting filters on input */ AllPoleFilter (&in[n], weightDenum, len-n, LPC_FILTERORDER);
}
}
/* prediction of synthesized and weighted input */
/* prediction of synthesized and weighted input */
syntOut[n] = 0.0; AllPoleFilter (&syntOut[n], weightDenum, 1, LPC_FILTERORDER);
syntOut[n] = 0.0; AllPoleFilter (&syntOut[n], weightDenum, 1, LPC_FILTERORDER);
/* quantization */
/* quantization */
toQ = in[n]-syntOut[n];
toQ=in[n]-合成醇[n];
sort_sq(&xq, &index, toQ, state_sq3Tbl, 8); out[n]=index; syntOut[n] = state_sq3Tbl[out[n]];
sort_sq(&xq, &index, toQ, state_sq3Tbl, 8); out[n]=index; syntOut[n] = state_sq3Tbl[out[n]];
/* update of the prediction filter */
/* update of the prediction filter */
AllPoleFilter(&syntOut[n], weightDenum, 1, LPC_FILTERORDER); } }
AllPoleFilter(&syntOut[n], weightDenum, 1, LPC_FILTERORDER); } }
/*----------------------------------------------------------------* * encoding of start state *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * encoding of start state *---------------------------------------------------------------*/
void StateSearchW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *residual,/* (i) target residual vector */ float *syntDenum, /* (i) lpc synthesis filter */ float *weightDenum, /* (i) weighting filter denuminator */ int *idxForMax, /* (o) quantizer index for maximum amplitude */ int *idxVec, /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first /* (i) position of start state in the 80 vec */ ){ float dtmp, maxVal; float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS]; float *tmp, numerator[1+LPC_FILTERORDER]; float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout; int k; float qmax, scal;
void StateSearchW( iLBC_Enc_Inst_t *iLBCenc_inst, /* (i) Encoder instance */ float *residual,/* (i) target residual vector */ float *syntDenum, /* (i) lpc synthesis filter */ float *weightDenum, /* (i) weighting filter denuminator */ int *idxForMax, /* (o) quantizer index for maximum amplitude */ int *idxVec, /* (o) vector of quantization indexes */ int len, /* (i) length of all vectors */ int state_first /* (i) position of start state in the 80 vec */ ){ float dtmp, maxVal; float tmpbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS]; float *tmp, numerator[1+LPC_FILTERORDER]; float foutbuf[LPC_FILTERORDER+2*STATE_SHORT_LEN_30MS], *fout; int k; float qmax, scal;
/* initialization of buffers and filter coefficients */
/* initialization of buffers and filter coefficients */
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k<LPC_FILTERORDER; k++) { numerator[k]=syntDenum[LPC_FILTERORDER-k]; } numerator[LPC_FILTERORDER]=syntDenum[0]; tmp = &tmpbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER];
memset(tmpbuf, 0, LPC_FILTERORDER*sizeof(float)); memset(foutbuf, 0, LPC_FILTERORDER*sizeof(float)); for (k=0; k<LPC_FILTERORDER; k++) { numerator[k]=syntDenum[LPC_FILTERORDER-k]; } numerator[LPC_FILTERORDER]=syntDenum[0]; tmp = &tmpbuf[LPC_FILTERORDER]; fout = &foutbuf[LPC_FILTERORDER];
/* circular convolution with the all-pass filter */
/* circular convolution with the all-pass filter */
memcpy(tmp, residual, len*sizeof(float)); memset(tmp+len, 0, len*sizeof(float)); ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, LPC_FILTERORDER, fout); for (k=0; k<len; k++) { fout[k] += fout[k+len]; }
memcpy(tmp, residual, len*sizeof(float)); memset(tmp+len, 0, len*sizeof(float)); ZeroPoleFilter(tmp, numerator, syntDenum, 2*len, LPC_FILTERORDER, fout); for (k=0; k<len; k++) { fout[k] += fout[k+len]; }
/* identification of the maximum amplitude value */
/* identification of the maximum amplitude value */
maxVal = fout[0]; for (k=1; k<len; k++) {
maxVal = fout[0]; for (k=1; k<len; k++) {
if (fout[k]*fout[k] > maxVal*maxVal){ maxVal = fout[k]; } } maxVal=(float)fabs(maxVal);
if (fout[k]*fout[k] > maxVal*maxVal){ maxVal = fout[k]; } } maxVal=(float)fabs(maxVal);
/* encoding of the maximum amplitude value */
/* encoding of the maximum amplitude value */
if (maxVal < 10.0) { maxVal = 10.0; } maxVal = (float)log10(maxVal); sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64);
if (maxVal < 10.0) { maxVal = 10.0; } maxVal = (float)log10(maxVal); sort_sq(&dtmp, idxForMax, maxVal, state_frgqTbl, 64);
/* decoding of the maximum amplitude representation value, and corresponding scaling of start state */
/* decoding of the maximum amplitude representation value, and corresponding scaling of start state */
maxVal=state_frgqTbl[*idxForMax]; qmax = (float)pow(10,maxVal); scal = (float)(4.5)/qmax; for (k=0; k<len; k++){ fout[k] *= scal; }
maxVal=state_frgqTbl[*idxForMax]; qmax = (float)pow(10,maxVal); scal = (float)(4.5)/qmax; for (k=0; k<len; k++){ fout[k] *= scal; }
/* predictive noise shaping encoding of scaled start state */
/* predictive noise shaping encoding of scaled start state */
AbsQuantW(iLBCenc_inst, fout,syntDenum, weightDenum,idxVec, len, state_first); }
AbsQuantW(iLBCenc_inst, fout,syntDenum, weightDenum,idxVec, len, state_first); }
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
syntFilter.h
合成过滤器
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#ifndef __iLBC_SYNTFILTER_H #define __iLBC_SYNTFILTER_H
#ifndef __iLBC_SYNTFILTER_H #define __iLBC_SYNTFILTER_H
void syntFilter( float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */ float *mem /* (i/o) Filter state */ );
void syntFilter( float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */ float *mem /* (i/o) Filter state */ );
#endif
#恩迪夫
/******************************************************************
/******************************************************************
iLBC Speech Coder ANSI-C Source Code
iLBC语音编码器ANSI-C源代码
syntFilter.c
合成过滤器
Copyright (C) The Internet Society (2004). All Rights Reserved.
版权所有(C)互联网协会(2004年)。版权所有。
******************************************************************/
******************************************************************/
#include "iLBC_define.h"
#包括“iLBC_define.h”
/*----------------------------------------------------------------* * LP synthesis filter. *---------------------------------------------------------------*/
/*----------------------------------------------------------------* * LP synthesis filter. *---------------------------------------------------------------*/
void syntFilter( float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */
void syntFilter( float *Out, /* (i/o) Signal to be filtered */ float *a, /* (i) LP parameters */ int len, /* (i) Length of signal */
float *mem /* (i/o) Filter state */ ){ int i, j; float *po, *pi, *pa, *pm;
float *mem /* (i/o) Filter state */ ){ int i, j; float *po, *pi, *pa, *pm;
po=Out;
po=Out;
/* Filter first part using memory from past */
/* Filter first part using memory from past */
for (i=0; i<LPC_FILTERORDER; i++) { pi=&Out[i-1]; pa=&a[1]; pm=&mem[LPC_FILTERORDER-1]; for (j=1; j<=i; j++) { *po-=(*pa++)*(*pi--); } for (j=i+1; j<LPC_FILTERORDER+1; j++) { *po-=(*pa++)*(*pm--); } po++; }
for (i=0; i<LPC_FILTERORDER; i++) { pi=&Out[i-1]; pa=&a[1]; pm=&mem[LPC_FILTERORDER-1]; for (j=1; j<=i; j++) { *po-=(*pa++)*(*pi--); } for (j=i+1; j<LPC_FILTERORDER+1; j++) { *po-=(*pa++)*(*pm--); } po++; }
/* Filter last part where the state is entirely in the output vector */
/* Filter last part where the state is entirely in the output vector */
for (i=LPC_FILTERORDER; i<len; i++) { pi=&Out[i-1]; pa=&a[1]; for (j=1; j<LPC_FILTERORDER+1; j++) { *po-=(*pa++)*(*pi--); } po++; }
for (i=LPC_FILTERORDER; i<len; i++) { pi=&Out[i-1]; pa=&a[1]; for (j=1; j<LPC_FILTERORDER+1; j++) { *po-=(*pa++)*(*pi--); } po++; }
/* Update state vector */
/* Update state vector */
memcpy(mem, &Out[len-LPC_FILTERORDER], LPC_FILTERORDER*sizeof(float)); }
memcpy(mem, &Out[len-LPC_FILTERORDER], LPC_FILTERORDER*sizeof(float)); }
Authors' Addresses
作者地址
Soren Vang Andersen Department of Communication Technology Aalborg University Fredrik Bajers Vej 7A 9200 Aalborg Denmark
索伦·万安徒生通讯技术系奥尔堡大学弗雷德里克·巴杰斯Vej 7A 9200丹麦奥尔堡
Phone: ++45 9 6358627 EMail: sva@kom.auc.dk
Phone: ++45 9 6358627 EMail: sva@kom.auc.dk
Alan Duric Telio AS Stoperigt. 2 Oslo, N-0250 Norway
阿兰·杜里奇·泰利奥饰演斯托佩里格特。挪威奥斯陆,N-0250
Phone: +47 21673555 EMail: alan.duric@telio.no
Phone: +47 21673555 EMail: alan.duric@telio.no
Henrik Astrom Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden
Henrik Astrom全球IP Sound AB Olandsgatan 42斯德哥尔摩S-11663瑞典
Phone: +46 8 54553040 EMail: henrik.astrom@globalipsound.com
Phone: +46 8 54553040 EMail: henrik.astrom@globalipsound.com
Roar Hagen Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden
瑞典斯德哥尔摩,S-11663,奥兰斯加坦42号,Roar Hagen Global IP Sound AB Olandsgatan
Phone: +46 8 54553040 EMail: roar.hagen@globalipsound.com
Phone: +46 8 54553040 EMail: roar.hagen@globalipsound.com
W. Bastiaan Kleijn Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden
W.Bastian Kleijn全球IP Sound AB Olandsgatan 42斯德哥尔摩,S-11663瑞典
Phone: +46 8 54553040 EMail: bastiaan.kleijn@globalipsound.com
Phone: +46 8 54553040 EMail: bastiaan.kleijn@globalipsound.com
Jan Linden Global IP Sound Inc. 900 Kearny Street, suite 500 San Francisco, CA-94133 USA
简林登全球IP音响公司900凯尔街,套房500旧金山,CA-94133美国
Phone: +1 415 397 2555 EMail: jan.linden@globalipsound.com
Phone: +1 415 397 2555 EMail: jan.linden@globalipsound.com
Full Copyright Statement
完整版权声明
Copyright (C) The Internet Society (2004).
版权所有(C)互联网协会(2004年)。
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.
本文件受BCP 78中包含的权利、许可和限制的约束,除其中规定外,作者保留其所有权利。
This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
本文件及其包含的信息是按“原样”提供的,贡献者、他/她所代表或赞助的组织(如有)、互联网协会和互联网工程任务组不承担任何明示或暗示的担保,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。
Intellectual Property
知识产权
The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the IETF's procedures with respect to rights in IETF Documents can be found in BCP 78 and BCP 79.
IETF对可能声称与本文件所述技术的实施或使用有关的任何知识产权或其他权利的有效性或范围,或此类权利下的任何许可可能或可能不可用的程度,不采取任何立场;它也不表示它已作出任何独立努力来确定任何此类权利。有关IETF文件中权利的IETF程序信息,请参见BCP 78和BCP 79。
Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.
向IETF秘书处披露的知识产权副本和任何许可证保证,或本规范实施者或用户试图获得使用此类专有权利的一般许可证或许可的结果,可从IETF在线知识产权存储库获取,网址为http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.
IETF邀请任何相关方提请其注意任何版权、专利或专利申请,或其他可能涵盖实施本标准所需技术的专有权利。请将信息发送至IETF的IETF-ipr@ietf.org.
Acknowledgement
确认
Funding for the RFC Editor function is currently provided by the Internet Society.
RFC编辑功能的资金目前由互联网协会提供。