[要約] RFC 3951は、インターネット上での低ビットレート音声通信を可能にするiLBCコーデックに関するものです。その目的は、低帯域幅環境での高品質な音声通信を実現することです。

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 上の堅牢な音声通信に適した音声コーデックを指定します。コーデックは Global IP Sound (GIPS) によって開発されました。狭帯域音声用に設計されており、ペイロード ビット レートは 30 ms フレームで 13.33 kbit/s、20 ms フレームで 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
                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
        
1. Introduction
1. はじめに

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) アルゴリズムを使用し、2 つの基本フレーム長 (15.2 kbit/s で 20 ms と 13.33 kbit/s で 30 ms) をサポートします。コーデックが 20 ミリ秒のブロック長で動作する場合、ブロックあたり 304 ビットが生成され、[1] のようにパケット化する必要があります (SHOULD)。同様に、ブロック長が 30 ミリ秒の場合、ブロックあたり 400 ビットが生成され、[1] のようにパケット化する必要があります。異なるフレーム サイズの 2 つのモードは、非常に似た方法で動作します。異なる場合は、通常は x/y という表記で本文に明示的に記載されます。x は 20 ms モードを指し、y は 30 ms モードを指します。

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].

説明されているアルゴリズムにより、ITU-T G.711 標準 [4] などのパケット損失隠蔽 (PLC) を備えたパルス符号変調 (PCM) で知られているものと同様に、パケット損失に対する制御された応答を備えた音声符号化システムが実現されます。64 kbit/s の固定ビット レートで動作します。同時に、説明したアルゴリズムにより、品質とビット レートのトレードオフが最先端に近い固定ビット レート コーディングが可能になります。iLBC コーデックに適した RTP ペイロード形式は、[1] で指定されています。

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].

Cable Television Laboratories (CableLabs(R)) は、VoIP over Cable アプリケーションの必須 PacketCable(TM) オーディオ コーデック標準として iLBC を採用しました [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] に記載されているように解釈されます。

2. Outline of the Codec
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 (20 ms/30 ms) サンプルであり、残差信号の既に符号化された部分から構築された動的コードブックの開始状態を形成します。これらの動的コードブックは、残差信号の残りの部分をコーディングするために使用されます。この方法により、ブロック間の符号化の独立性が達成され、パケット損失による知覚劣化の伝播が排除されます。この方法により、高品質のパケット損失隠蔽 (PLC) が容易になります。

2.1. Encoder
2.1. エンコーダ

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 サンプルのブロックに分割されるべきです (SHOULD)。各ブロックは、それぞれ SUBL=40 サンプルの NSUB=4/6 の連続したサブブロックに分割されます。30 ミリ秒のフレーム サイズの場合、エンコーダは 2 つの LPC_FILTERORDER=10 線形予測コーディング (LPC) 分析を実行します。最初の分析では、2 番目のサブブロックを中心とし、5 番目のサブブロックの中央まで拡張するスムーズ ウィンドウを適用します。2 番目の LPC 分析は、5 番目のサブブロックを中心にして 6 番目のサブブロックの終わりまで広がる滑らかな非対称ウィンドウを適用します。20 ms フレーム サイズの場合、1 回の LPC_FILTERORDER=10 線形予測コーディング (LPC) 分析が、3 番目のサブフレームの中央にあるスムーズ ウィンドウで実行されます。

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.

最大の重み付けされたエネルギーを示す残差の 2 つの連続するサブブロックが識別されます。これら 2 つのサブブロック内で、開始状態 (セグメント) は 2 つの選択肢から選択されます: 2 つの連続するサブブロックの最初の 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) 開始状態を含む 2 つのサブブロック内の残りの 23/22 (20 ミリ秒/30 ミリ秒) サンプルを符号化します。2) 開始状態の後のサブブロック。3) 開始状態の前のサブブロック。したがって、符号化ターゲットは、開始状態を含む 2 つのサブブロックの残りの 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 ステージで使用され、結果として得られる 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 コードブック セクションの 1 つから取得されます。最初のセクションは、遅延された、すでにエンコードされた残差ベクトルで埋められています。コードブックの 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.

二乗誤差マッチングを使用したコードブック符号化は、スカラー量子化された開始状態信号よりも低い電力の符号化信号を生成することが知られているため、電力の観点からより適切なコードブック ゲインのセットを絞り込んだ検索によってゲイン再スケーリング方法が実装されます。エンコード後のマッチング。これは、後続ステージのコードブックのゲインが第 1 ステージのゲインによって調整されるため、第 1 ステージのコードブックのゲイン係数のより高い値を検索することによって行われます。

2.2. Decoder
2.2. デコーダ

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.

コードブックでエンコードされたセグメントの場合、各セグメントは、エンコーダでコード ベクトルが構築されたのと同じ方法で、受信したコードブック インデックスによって指定された 3 つのコード ベクトルを構築することによってデコードされます。3 つのゲイン係数もデコードされ、結果としてデコードされた信号は、それぞれのゲインでスケーリングされた 3 つのコードブック ベクトルの合計によって得られます。

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残差信号を取得することに基づくことができる。

3. Encoder Principles
3. エンコーダの原理

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  | ->
             +-----------+    +---------+    +---------+
        
             +---------------+   +--------------+
          -> | 4. Start Sel  | ->| 5. Scalar Qu | ->
             +---------------+   +--------------+
        
             +--------------+    +---------------+
          -> |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 サンプルのブロックに分割する必要があります (SHOULD)。エンコーダへの各ブロック入力は、それぞれ SUBL=40 サンプルの NSUB=4/6 の連続したサブブロックに分割されます。

             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).
        
3.1. Pre-processing
3.1. 前処理

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.

アプリケーションによっては、録音された音声信号に DC レベルや 50/60 Hz ノイズが含まれる場合があります。これらのコンポーネントがエンコーダ呼び出しの前に削除されていない場合は、ハイパス フィルターによって削除する必要があります。カットオフ周波数 90 Hz のフィルターを使用したこのリファレンス実装は、付録 A.28 にあります。

3.2. LPC Analysis and Quantization
3.2. LPC 分析と量子化

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 分析は、自己相関法とレビンソン・ダービン再帰を使用して、LPC_FILTERORDER=10 個の LPC フィルター係数の 1 つまたは 2 つのセットを計算します。これらの係数は線スペクトル周波数表現に変換されます。20 ms の場合、単一の lsf セットは 3 番目のサブブロックの中心で測定されたスペクトル特性を表します。30 ms フレームの場合、最初のセット lsf1 は 2 番目のサブブロックの中心での入力信号のスペクトル特性を表し、もう 1 つのセット lsf2 は 5 番目のサブブロックの中心で測定されたスペクトル特性を表します。ブロック。30 ms フレームの計算の詳細については、セクション 3.2.1 ~ 3.2.6 で説明します。セクション 3.2.7 では、20 ms フレームの LPC 分析と量子化がどのように異なるかを説明します。

3.2.1. Computation of Autocorrelation Coefficients
3.2.1. 自己相関係数の計算

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 分析手順の最初のステップは、ウィンドウ化された音声サンプルを使用して自己相関係数を計算することです。このウィンドウ処理が、2 つの係数セットに対する LPC 分析手順の唯一の違いです。最初のセットでは、240 サンプル長の標準対称ハニング ウィンドウが入力データのサンプル 0 ~ 239 に適用されます。最初のウィンドウ 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
        

The windowed speech speech_hp_win1 is then obtained by multiplying the first 240 samples of the input speech buffer with the window coefficients:

次に、ウィンドウ化された音声 speech_hp_win1 は、入力音声バッファの最初の 240 サンプルにウィンドウ係数を乗算して取得されます。

      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
        

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 係数が計算される前に自己相関係数をウィンドウ処理することによってスペクトル平滑化手順が適用されます。また、ホワイト ノイズ フロアは、係数ゼロに 1.0001 (ウィンドウ処理された音声信号のエネルギーより 40dB 低い) を乗算することによって自己相関関数に追加されます。これら 2 つのステップは、次のウィンドウで自己相関係数を乗算することによって実装されます。

      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
        

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 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

2 番目の自己相関係数セット acf2_win も同様の方法で取得されます。ウィンドウ lpc_asymwinTbl は、サンプル 60 から 299、つまり現在のブロック全体に適用されます。ウィンドウは 2 つのセグメントで構成され、最初のセグメント (サンプル 0 ~ 219) は長さ 440 のハニング ウィンドウの半分であり、2 番目のセグメントは余弦波の 4 分の 1 サイクルです。この非対称ウィンドウを使用することにより、遅延を追加する先読みを必要とせずに、5 番目のサブブロックを中心とする LPC 分析が得られます。非対称ウィンドウは次のように定義されます。

      lpc_asymwinTbl[i] = (sin(PI * (i + 1) / 441))^2; i=0,...,219
        
      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
        

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.

ウィンドウ lpc_winTbl、lpc_asymwinTbl、および lpc_lagwinTbl の生成は通常、事前に行われ、ブロックごとに計算を繰り返すのではなく、配列が ROM に保存されます。

3.2.2. Computation of LPC Coefficients
3.2.2. LPC 係数の計算

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 から、2 x 11 LPC 係数 lp1 および lp2 は、よく知られているレビンソン・ダービン再帰法を使用して、両方の分析位置で同じ方法で計算されます。最初の LPC 係数は常に 1.0 であり、結果として 10 個の一意の係数が得られます。

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
        

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 を使用することが推奨されます。

3.2.3. Computation of LSF Coefficients from LPC Coefficients
3.2.3. LPC 係数からの LSF 係数の計算

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 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).

これまでのところ、現在のブロック内の 2 つの異なる時間位置における音声信号の短期スペクトル特性を表す 2 組の LPC 係数が決定されています。これらの係数は量子化され、補間されるべきです(SHOULD)。これを行う前に、LPC パラメータを線スペクトル周波数 (LSF) と呼ばれる別のタイプの表現に変換すると有利です。LSF パラメータが使用されるのは、通常の LPC 係数よりも量子化と補間に適しているためです。LPC 係数から LSF を計算するための計算効率の高い方法が文献で多数提案されています。適用可能な 1 つのメソッドの詳細な実装については、付録 A.26 を参照してください。取得された LSF 係数の 2 つの配列 lsf1 と lsf2 は、次元 10 (LPC_FILTERORDER) です。

3.2.4. Quantization of LSF Coefficients
3.2.4. LSF 係数の量子化

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.

2 つの LSF セットによって定義された LPC フィルターもデコーダで必要となるため、LSF パラメータを量子化し、サイド情報として送信する必要があります。1 つの音声ブロックの 2 つの LSF 表現の量子化を表すのに必要なビットの総数は 40 で、lsf1 と lsf2 のそれぞれに 20 ビットが使用されます。

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.

計算およびストレージ上の理由から、LSF ベクトルは 3 分割ベクトル量子化 (VQ) を使用して量子化されます。つまり、LSF ベクトルは 3 つのサブベクトルに分割され、それぞれが通常の VQ で量子化されます。lsf1 と lsf2 の量子化バージョン、qlsf1 と qlsf2 は、同じメモリレス分割 VQ を使用して取得されます。これら 2 つの LSF ベクトルの長さはそれぞれ 10 で、それぞれ 3、3、および 4 の値を含む 3 つのサブベクトルに分割されます。

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 トレーニング方法を使用して設計されています。上記の分割定義に関連付けられた 3 つのコードブックのそれぞれのサイズは次のとおりです。

      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 は両方とも、二乗誤差を使用する標準のメモリレス分割ベクトル量子化 (VQ) 構造で量子化されます。LSF ドメインの基準。分割 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) 最初の 3 つの LSF 係数 (1 ~ 3) をサイズ 64 の VQ コードブックで量子化します。 2) 次の 3 つの LSF 係数 4 ~ 6 を、サイズ 128 の VQ コードブックで量子化します。 3) 最後の 4 つの LSF 係数 (7 ~ 10) を量子化します。) サイズ 128 の VQ コードブックを使用します。

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 に対して繰り返すと、6 つの量子化インデックスと量子化された LSF 係数のセット qlsf1 と qlsf2 が得られます。3 つのインデックスの各セットは 6 7 7 = 20 ビットでエンコードされます。したがって、ブロック内の LSF 量子化に使用されるビットの総数は 40 ビットになります。

3.2.5. Stability Check of LSF Coefficients
3.2.5. LSF 係数の安定性チェック

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 表現が使用されることが保証されます。

3.2.6. Interpolation of LSF Coefficients
3.2.6. 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.

音声のブロックごとに計算された 2 つの LSF 係数セットから、補間によってサブブロックごとに異なる LSF が取得されます。この手順は、元の LSF (lsf1 および lsf2) だけでなく、量子化バージョン qlsf1 および qlsf2 に対しても実行されます。これは、両方のバージョンがエンコーダーで使用されるためです。以下に補間スキームの簡単な概要を示します。詳細は付録 A の C コードを参照してください。最初のサブブロックでは、前のブロックの 2 番目の 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}
        

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 係数と量子化された LPC 係数は、それぞれ 2 組のフィルターを形成します。サブブロック k の非量子化分析フィルターは次のように定義されます。

                ___
                \
      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
        

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.

lsf エンコーディングのリファレンス実装は、付録 A.38 に記載されています。対応するデコードのリファレンス実装は、付録 A.36 にあります。

3.2.7. LPC Analysis and Quantization for 20 ms Frames
3.2.7. 20 ms フレームの LPC 分析と量子化

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).

前述したように、コーデックは、30 ms フレームの場合は 2 セットの LPC パラメータを計算するのに対し、20 ms フレーム サイズでは 1 セットの LPC パラメータのみを計算します。自己相関係数の単一セットは、LPC_LOOKBACK BLOCKL = 80 160 = 240 サンプルで計算されます。これらのサンプルは、3 番目のサブフレームを中心とする非対称ウィンドウ lpc_asymwinTbl でウィンドウ処理され、speech_hp_win を形成します。自己相関係数 acf は speech_hp_win の 240 サンプルで計算され、セクション 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.

このウィンドウ処理された自己相関係数の単一セットは、セクション 3.2.3 から 3.2.4 とまったく同じ方法で、LPC 係数、LSF 係数、および量子化 LSF 係数を計算するために使用されます。30 ms のフレーム サイズに関しては、10 個の LSF 係数がサイズ 3、3、および 4 の 3 つのサブベクトルに分割され、セクション 3.2.4 と同じスキームとコードブックを使用して量子化され、最終的に 3 つの量子化インデックスが得られます。量子化された LSF 係数は、セクション 3.2.5 で説明されているアルゴリズムで安定化されます。

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- 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 係数のセットと前のブロックからの LSF 係数のセットから、補間によってサブブロックごとに異なる LSF が取得されます。補間は 4 つのサブブロックにわたる LSF ドメインで線形に行われるため、n 番目のサブフレームでは古いフレームからの LSF の重み (4-n)/4 と LSF の重み n/4 が使用されます。現在のフレームから。一番最初のブロックでは、平均 LSF lsfmeanTbl が前のブロックの LSF として使用されます。同様に、セクション 3.2.6 で見られるように、非量子化 A(z) と量子化 A~(z) の両方の分析フィルターが 4 つのサブブロックのそれぞれに対して計算されます。

3.3. Calculation of the Residual
3.3. 残差の計算

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.

LPC 分析フィルターのリファレンス実装は、付録 A.10 に記載されています。

3.4. Perceptual Weighting Filter
3.4. 知覚重み付けフィルター

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
        

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 に対して取得されたフィルターです。

3.5. Start State Encoder
3.5. 開始状態エンコーダー

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 ビット スカラー量子化器を使用して量子化されます。以下では、状態エンコーディングについて詳しく説明します。

3.5.1. Start State Estimation
3.5.1. 状態推定の開始

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):

開始状態を含む 2 つのサブブロックは、ブロック内で最も高い電力を持つ 2 つの連続するサブブロックを見つけることによって決定されます。有利なことに、ダウン重み付けはサブフレームの最初と最後で使用されます。つまり、次の尺度が計算されます(20/30 ms フレーム サイズでは 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];
        

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]の最大値に対応するサブフレーム番号が開始状態指示子として選択される。30 ミリ秒フレームの場合は ssqEn_win[]={0.8,0.9,1.0,0.9,0.8}、20 ミリ秒フレームの場合は 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

20 ms フレームの場合、2 サブブロック長の最大パワー セグメントには 3 つの可能な位置があります。開始状態の位置は 2 ビットでエンコードされます。開始状態の位置 start は、次のようにエンコードされなければなりません (MUST)。

      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

30 ms フレームの場合、2 サブブロック長の最大パワー セグメントの可能な位置は 5 つあり、開始状態の位置は 3 ビットでエンコードされます。開始状態の位置 start は、次のようにエンコードされなければなりません (MUST)。

      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 ms フレームの場合は STATE_SHORT_LEN=57 サンプル、30 ms フレームの場合は STATE_SHORT_LEN=58 サンプルに引き下げられます。上記で識別された 2 つのサブフレーム ブロックの最初の 23/22 サンプルと最後の 23/22 サンプルのパワーは、二乗信号サンプル値の合計として計算され、最も低いパワーを持つ 23/22 サンプル セグメントは除外されます。開始状態。1 ビットが送信され、2 つの可能な 57/58 サンプル セグメントのどれが使用されるかを示します。上記で決定された 2 つのサブフレーム内の開始状態位置、state_first は、次のようにエンコードされなければなりません (MUST)。

      state_first=1: start state is first STATE_SHORT_LEN samples
      state_first=0: start state is last STATE_SHORT_LEN samples
        
3.5.2. All-Pass Filtering and Scale Quantization
3.5.2. オールパスフィルタリングとスケール量子化

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
        
      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
        
      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.

オールパス フィルター処理されたブロックで最大の大きさのサンプルが検索されます。この大きさの 10 対数は、最も近い表現を見つけることによって 6 ビット量子化器 state_frgqTbl で量子化されます。

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.

これにより、量子化値 qmax に対応するインデックス idxForMax が生成されます。次に、ブロック内のオールパス フィルター処理された残差サンプルにスケーリング係数 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}
        
3.5.3. Scalar Quantization
3.5.3. スカラー量子化

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

正規化されたサンプルは、図 3.3 に示すように、サンプルごとのスカラー DPCM 量子化によって、知覚的に重み付けされた音声ドメインで量子化されます。ブロック内の各サンプルは、セクション 3.4 で指定された重み付けフィルター Wk(z) によってフィルター処理され、重み付けされた音声サンプル x[n] が形成されます。ターゲット サンプル d[n] は、予測サンプル y[n] を減算することによって形成されます。ここで、予測フィルターは次の式で与えられます。

Pk(z) = 1 - 1 / Wk(z).

Pk(z) = 1 - 1 / Wk(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}
        

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 にあります。

3.6. Encoding the Remaining Samples
3.6. 残りのサンプルのエンコード

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) 開始状態を含む 2 つのサブブロック内の残りの 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であり、これは2/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. | ->
         +------------+    +---------------+    +-------------+
        
         +------------+    +-----------------+
      -> | 4. Search  | -> | 5. Upd. Target  | ------------------>
       | +------------+    +------------------ |
       ----<-------------<-----------<----------
                     stage=0..2
        
         +----------------+
      -> | 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. 知覚的に重み付けされたメモリから選択されたコードブック ベクトルからの寄与を減算することにより、知覚的に重み付けされたターゲットを更新します (量子化ゲインと選択したベクトルの積)。追加の 2 つのステージに対して 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 のさまざまなブロックについて詳しく説明します。

3.6.1. Codebook Memory
3.6.1. コードブックメモリ

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 サンプルにある場合に、30 ミリ秒のフレーム サイズでサブブロックがエンコードされる順序の例を示しています。

   +-----------------------------------------------------+
   |  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 |
   +-------------------------
        

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   |
   +-----------------------------------
        

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    |
   +------------------------------------------
        

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    |
   +------------------------------------------
        

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    |
   +-------------------------------------------
        

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.

20 ms フレームの場合、エンコード手順はほぼ同じになります。唯一の違いは、開始状態のサイズが 57 サンプルであり、エンコードされるサブブロックが 3 つだけであることです。エンコード順序は上記と同じで、23 サンプルのターゲットから開始して、残りの 2 つの 40 サンプルのサブブロックをエンコードします。最初は時間的に順方向に進み、次に開始状態に対して時間的に逆方向に進みます。

3.6.2. Perceptual Weighting of Codebook Memory and Target
3.6.2. コードブックメモリとターゲットの知覚的重み付け

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 -> 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))
        

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.

コードブックの検索は重み付けされたコードブック メモリと重み付けされたターゲットを使用して実行されますが、デコードとコードブック メモリの更新は重み付けされていないコードブック メモリを使用します。

3.6.3. Codebook Creation
3.6.3. コードブックの作成

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.

検索用のコードブックは、知覚的に重み付けされたコードブック メモリから作成されます。これは 2 つのセクションで構成されており、最初のセクションは基本コードブックと呼ばれ、2 番目のセクションは最初のコードブックの線形結合によって作成されるため、拡張コードブックと呼ばれます。これら 2 つのセクションにはそれぞれ、拡張コードブックと呼ばれるサブセクションもあります。拡張コードブックは、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
        

Table 3.1. Codebook sizes for the 30 ms mode.

表3.1。30 ms モードのコードブック サイズ。

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 は、30 ms フレームのさまざまなサブブロックとステージのコードブック サイズを示しています。括弧内は、2 つのセクション内で、基本/拡張コードブックと拡張基本/拡張コードブックの間でコードブック ベクトルの数がどのように配分されるかを示しています。これは次のように解釈する必要があります: (ベース/拡張 CB 拡張ベース/拡張 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.

20 ms フレームの図 3.1 に対応する値は、わずかに変更されているだけです。短いサブブロックは 22 サンプルではなく 23 サンプルであり、3 番目と 4 番目のサブフレームは存在しません。

3.6.3.1. Creation of a Base Codebook
3.6.3.1. 基本コードブックの作成

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 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).

基本コードブックは、セクション 3.5.3 で説明されている知覚的に重み付けされたコードブック メモリによって与えられます。異なるコードブック ベクトルは、変数 lTarget で指定される長さ 23/22 または 40 のウィンドウを、lMem の長さの知覚的に重み付けされたコードブック メモリ上でスライドさせることによって指定されます。インデックスは、コードブック メモリ ベクトルのサンプル (lMem-lTarget-n) から (lMem-n-1) を含むコードブック ベクトルがインデックス n を持つように順序付けされます (n=0..lMem-lTarget)。したがって、基本コードブック ベクトルの総数は lMem - lTarget 1 であり、インデックスはサンプル遅延 lTarget (23/22 または 40) から lMem 1 (86 または 148) までの順序になります。

3.6.3.2. Codebook Expansion
3.6.3.2. コードブックの拡張

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 フィルターによって導入された 4 つのサンプルの遅延が補償されます。

   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)
        
      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 とそのインデックスは、ベース コードブックについて上で説明したのと同じ方法で取得されます。

3.6.3.3. Codebook Augmentation
3.6.3.3. コードブックの拡張

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 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 は、ポインター pp 以降の 15 個のサンプルで構成されます。セグメント ii は、pi 以降および po 以降の 5 つの補間サンプルで構成されます。サンプルは、pi の重み [0.0、0.2、0.4、0.6、0.8]、po の重み [1.0、0.8、0.6、0.4、0.2] で線形補間されます。セグメント iii は、pp 以降の 20 個のサンプルで構成されます。サンプル遅延 21 に対応する拡張コードブック ベクトルは、ポインタ pp および pi を時間的に 1 サンプル後方に移動することによって生成されます。これにより、次の図が得られます。

       - - ------------------------|
    codebook memory                |
       - - ------------------------|
                  |-5-|---16---|-5-|
                  pi  pp       po
        
                      |        |                       Codebook vector
                      |---16---|-5-|-----19-----|   <- corresponding to
                          i     ii      iii            sample delay 21
        

Figure 3.12. Generation of the second augmented codebook.

図3.122 番目の拡張コードブックの生成。

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 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.

図 3.12 は、ポインタ pi、pp、po を持つコードブック メモリを示しています。ここで、pi はサンプル 26、pp はサンプル 21、po はサンプル 5 を指します。コードブック メモリの下には、サンプル遅延 21 に対応する拡張コードブック ベクトルが描画されます。セグメント i は、pp 以降の 16 個のサンプルで構成されています。セグメント ii は、pi 以降および po 以降の 5 つの補間サンプルで構成され、補間重みは手順全体を通じて同じです。セグメント iii は、pp 以降の 19 個のサンプルで構成されます。2つのポインタを移動する同じ手順は、サンプル遅延39に対応する最後の拡張ベクトルが作成されるまで継続される。これにより、合計 20 個の新しいコードブック ベクトルが 2 つのセクションのそれぞれに与えられます。したがって、拡張コードブックを含む場合、2 つのセクションのそれぞれのコードブック ベクトルの総数は、lMem-SUBL 1 SUBL/2 になります。これは、拡張が呼び出される場合、つまり lTarget=SUBL が条件となります。

3.6.4. コードブックの検索

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).

たとえば、2 番目の 40 サンプルのサブブロックが符号化される場合、インデックス 0 ~ 107 は基本コードブックに対応し、108 ~ 127 は拡張基本コードブックに対応し、128 ~ 235 は拡張コードブックに対応し、インデックス 236 ~ 255 は拡張コードブックに対応します。拡張された拡張コードブックに。この例では、インデックスはすべてのステージで同じ方法で分割されています。最初の 40 サンプルのサブブロックを符号化する場合にのみ、ステージ間に違いがあります (表 3.1 を参照)。

3.6.4.1. Codebook Search at Each Stage
3.6.4.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:

コードブックは、各段階でターゲットに最もよく一致するものを見つけるために検索されます。最適な一致が見つかると、ターゲットが更新され、次の段階の検索が開始されます。選択された 3 つのコードブック ベクトルとそれらに対応するゲインは、符号化されたサブブロックを構成します。最適な一致は、次の 3 つの基準によって決定されます。

1. Compute the measure

1. メジャーを計算する

      (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_MAXGAIN

where the gain is computed in the following way:

ここで、ゲインは次の方法で計算されます。

            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) を満たすコードブック ベクトルがない場合は、最初のコードブック ベクトルが選択されます。

3.6.4.2. Gain Quantization at Each Stage
3.6.4.2. 各段階でのゲイン量子化

The gain follows as a result of the computation

計算の結果としてゲインが得られます

      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.

3 つのステージでは、それぞれ 5、4、3 ビットを使用してゲインを量子化します。最初の段階では、ゲインは正の値に制限されます。このゲインは、量子化テーブル Gain_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}

ゲイン_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}

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 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.

後続の 2 つのステージのゲインは、正または負のいずれかになります。ゲインは、量子化テーブルにスケール係数を掛けたものを使用して量子化されます。2 番目のステージではテーブル Gain_sq4Tbl が使用され、3 番目のステージでは Gain_sq3Tbl が使用されます。スケールファクタは、0.1 または前段で得られた量子化ゲイン表現値の絶対値のいずれか大きい方に相当します。繰り返しますが、結果として得られるゲイン インデックスは、量子化テーブルの最も近い値のインデックスにスケール ファクターを掛けたものになります。

gainQ = scaleFact * gain_sqXTbl[index]

ゲインQ = スケールファクト * ゲイン_sqXTbl[インデックス]

   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}
        
3.6.4.3. Preparation of Target for Next Stage
3.6.4.3. 次のステージに向けた目標の準備

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];
        

A reference implementation of the codebook encoding is found in Appendix A.34.

コードブックエンコーディングの参照実装は、付録 A.34 にあります。

3.7. Gain Correction Encoding
3.7. ゲイン補正エンコーディング

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 ビットを使用して、比較的モデルに依存しない方法で量子化されます。対照的に、ブロックの残りの部分は適応コードブックを使用してエンコードされます。このコードブックは、ターゲットと最適なコードブック ベクトルの間に高い相関がある場合に、高いマッチング精度を生成します。無声音声セグメントや背景雑音の場合、これは必ずしもそうではありません。二乗誤差基準の性質により、コード化された信号のパワーがターゲット信号よりも低くなります。符号化された開始状態のパワーはターゲットと良好に一致しているため、結果として、符号化されたフレーム内でパワーが変動します。知覚的には、これに関する主な問題は、信号エネルギーの時間エンベロープが不安定になることです。この問題を解決するために、コードブックのゲインは、より優れた電力マッチングを提供する第 1 段階のコードブックの新しいゲイン係数を検索することによって、コードブックのエンコード後に再スケーリングされます。

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 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

まず、ターゲット信号のエネルギー tene が、3 つのゲイン スケーリング コードブック ベクトルの加算によって得られるコード化信号 cene のエネルギーとともに計算されます。2 番目と 3 番目のステージのゲインは 1 番目のステージのゲインに合わせて調整されるため、最初のステージのゲインが Gain[0] から Gain_sq5Tbl[i] に変更されると、コード化された信号のエネルギーは cene から cene に変化します。

      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.

ここで、gain[0] は、元のコードブック検索で見つかった最初のステージのゲインです。洗練された検索は、ゲイン インデックス i=0 ~ 31 をテストすることによって実行され、上記の新しいコードブック エネルギーが 10 未満である限り、ステージ 1 のゲイン インデックスは増加します。ステージ 1 の新しいゲイン値が、コードブック検索で見つかった元の値の 2 倍を超えてはいけないという制限が適用されます。この方法を使用すると、エンコードされたベクトルの形状は変更されず、ゲインまたは振幅のみが変更されることに注意してください。

3.8. Bitstream Definition
3.8. ビットストリームの定義

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 ミリ秒の音声の 1 フレームを記述するために使用されるビットの総数は 304 で、これは 38 バイトに収まり、ビット レートは 15.20 kbit/s になります。フレーム長が 30 ms の音声の場合、使用されるビットの総数は 400 で、50 バイトに収まり、ビット レートは 13.33 kbit/s になります。ビットストリーム定義では、ビットはビットエラーまたは損失感度に応じて 3 つのクラスに分類されます。最も機密性の高いビット (クラス 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 [1] のペイロード フォーマット定義で活用されているような、不均等レベル保護 (ULP) の使用が可能になります。詳細なビット割り当てを次の表に示します。量子化インデックスがより多くのクラスに分散される場合、より重要なビットは最下位のクラスに属します。

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>   |
                   ------------------+---------------+---------------+
        
                            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.220 ms フレーム サイズ モードと 30 ms フレーム サイズ モードの両方の iLBC のビットストリーム定義。

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 ビット。最後のビットである空フレームインジケーターは、エンコーダーによってゼロに設定されるべきです(SHOULD)。このビットが 1 に設定されている場合、デコーダはデータを失われたフレームとして扱うべきです(SHOULD)。たとえば、[1] のように、このビットを 1 に設定すると、ファイル ストレージ フォーマットのフレームが失われたことを示すことができます。

4. Decoder Principles
4. デコーダの原理

This section describes the principles of each component of the decoder algorithm.

このセクションでは、デコーダ アルゴリズムの各コンポーネントの原理について説明します。

              +-------------+    +--------+    +---------------+
   payload -> | 1. Get para | -> | 2. LPC | -> | 3. Sc Dequant | ->
              +-------------+    +--------+    +---------------+
        
              +-------------+    +------------------+
           -> | 4. Mem setup| -> | 5. Construct res |------->
           |  +-------------+    +-------------------   |
           ---------<-----------<-----------<------------
                     Sub-frame 0...2/4 (20 ms/30 ms)
        
              +----------------+    +----------+
           -> | 6. Enhance res | -> | 7. Synth | ------------>
              +----------------+    +----------+
        
              +-----------------+
           -> | 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 アルゴリズムに置き換えるべきです (SHOULD)。

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. このサブフレームの残差を構築します (gain[0]*cbvec[0]、gain[1]*cbvec[1]、gain[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)。

4.1. LPC Filter Reconstruction
4.1. LPC フィルターの再構築

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 フィルター パラメーターのデコードは非常に簡単です。3 つまたは 6 つのインデックスのセットの場合、対応する LSF ベクトルは単純なテーブル検索によって見つかります。各 LSF ベクトルについて、3 つの分割ベクトルが連結されて、それぞれ qlsf1 と qlsf2 が得られます (20 ms モードでは、1 つの LSF ベクトル qlsf のみが構築されます)。次のステップは、セクション 3.2.5 で説明されている安定性チェックであり、その後、セクション 3.2.6 (20 ms フレームの場合は 3.2.7) で説明されている補間スキームが続きます。唯一の違いは、量子化された LSF のみがデコーダで認識されるため、量子化されていない LSF は処理されないことです。

A reference implementation of the LPC filter reconstruction is given in Appendix A.36.

LPC フィルタ再構成の参照実装は、付録 A.36 に記載されています。

4.2. Start State Reconstruction
4.2. 状態の再構築を開始する

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.

スカラー エンコードされた STATE_SHORT_LEN=58 (20 ミリ秒モードでは STATE_SHORT_LEN=57) 状態サンプルは、1) インデックス ストリーム idxVec[n] から (テーブル ルックアップによって) サンプルのセットを形成し、2) セットに 1/ を乗算することによって再構築されます。scal=(10^qmax)/4.5、3) 57/58 サンプルの時間を反転、4) エンコーダで使用される分散 (オールパス) フィルターで時間反転ブロックをフィルター処理 (セクション 3.5.2 で説明)。これにより、前のフィルタ操作の位相歪みが補償され、前のステップからの 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
        
   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
        
   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 サンプルであるかを決定します。残りの 23/22 サンプルが最初のサンプルである場合、スカラー エンコードされた STATE_SHORT_LEN 状態サンプルは、適応コードブック メモリ ベクトルの初期化前に時間反転されます。

A reference implementation of the start state reconstruction is given in Appendix A.44.

開始状態再構築の参照実装は、付録 A.44 に記載されています。

4.3. Excitation Decoding Loop
4.3. 励起デコードループ

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 の適応コードブック メモリの最後の STATE_LEN=80 サンプルが状態ベクトルのサンプルで満たされます。後続の前方サブブロックでは、適応コードブック メモリの最初の SUBL=40 サンプルが破棄され、残りのサンプルがベクトルの先頭に向かって SUBL サンプルずつシフトされ、新しくデコードされた SUBL=40 サンプルがベクトルの最後に配置されます。適応コードブックメモリ。逆方向サブブロックの場合、関係するサンプルのすべてのベクトルが最初に反転されることを除いて、構築は同様です。

A reference implementation of the excitation decoding loop is found in Appendix A.5.

励起復号化ループの参照実装は付録 A.5 にあります。

4.4. Multistage Adaptive Codebook Decoding
4.4. 多段階適応コードブック復号化

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.

マルチステージ適応コードブック復号モジュールは、送信側 (エンコーダー) と受信側 (デコーダー) の両方で使用され、最終的に合成音声の生成に使用される残差領域で合成信号を生成します。モジュールは、スケーリングおよび合計されてモジュールの出力である合成信号を生成するベクトルを構築するために使用されるインデックス値を取得します。

4.4.1. Construction of the Decoded Excitation Signal
4.4.1. デコードされた励起信号の構築

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 つのインデックスは、3 つのコードブック ベクトルを検索するために使用されます。アンパックされた 3 つのゲイン インデックスは、対応する 3 つのゲインをデコードするために使用されます。このデコードでは、セクション 3.6.4.2 で説明されているように、逐次再スケーリングが適用されます。

A reference implementation of the adaptive codebook decoding is listed in Appendix A.32.

適応コードブック復号化の参照実装は、付録 A.32 にリストされています。

4.5. Packet Loss Concealment
4.5. パケットロスの隠蔽

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 実装を使用してもよい(MAY)。

The PLC described operates on the LP filters and the excitation signals and is based on the following principles:

説明した PLC は LP フィルターと励起信号で動作し、次の原理に基づいています。

4.5.1. Block Received Correctly and Previous Block Also Received
4.5.1. ブロックは正しく受信され、前のブロックも受信されました

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 フィルター係数と復号化された励振信号全体は、すべてデコーダー状態構造に保存されます。次のブロックが失われた場合、この情報はすべて必要になります。

4.5.2. Block Not Received
4.5.2. ブロックが受信されませんでした

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).

ピッチ周期性の量とピッチ値を検出するために、前のブロックの励起信号に対して相関分析が実行されます。相関測定は、有声レベル (前のブロックの励起が有声信号またはほぼ周期的な信号であった程度) を決定するためにも使用されます。前のブロックの励振は、前のブロックのピッチが維持されるように、置換されるブロックの励振を作成するために使用されます。したがって、新しい励振はピッチ同期方式で構築されます。ブンジーなサウンドの置換ブロックを回避するために、ランダムな励振が新しいピッチ周期的な励振と混合され、2 つの成分の相対的な使用が相関尺度 (有声レベル) から計算されます。

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 フィルターも再度使用されます。連続的に失われたブロックの代替励起のエネルギーは減少し、励起の減衰につながり、したがって音声の減衰につながります。

4.5.3. Block Received Correctly When Previous Block Not Received
4.5.3. 前のブロックが受信されなかった場合でもブロックは正しく受信されました

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.

前のブロックが正しく受信されなかったときにブロックが正しく受信された場合、正しく受信されたブロックの直接デコードされた音声 (受信ブロックのみに基づく) は実際の出力として使用されません。その理由は、直接デコードされた音声が、以前の失われたブロックに対して生成された合成音声に必ずしもスムーズにマージするとは限らないためです。2 つの信号がスムーズにマージされないと、誤って聞こえる不連続性が発生します。したがって、励起信号の 2 つのブロック (前の隠蔽されたブロックの励起と現在の受信ブロックの励起) 間の相関分析が実行され、最良の位相一致が見つかります。次に、単純なオーバーラップ加算手順が実行され、前の励起が現在のブロックの励起にスムーズにマージされます。

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 で提案されています。リファレンス実装がコーデック仕様全体と完全に互換性を持つためには、この推奨アルゴリズムに厳密に準拠する必要はありません。

4.6. Enhancement
4.6. 強化

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 ms フレーム サイズ モードと 30 ms フレーム サイズ モードの両方で非常に同様に機能します。

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 フレーム サイズのモードの場合、エンハンサーは、時間的に前の 6 つの 80 サンプル励起ブロックのメモリと、2 つの新しい 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.

フレーム サイズが 30 ms のモードの場合、エンハンサーは、時間的に前の 5 つの 80 サンプル励起ブロックと、3 つの新しい 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 サンプルのサブブロックで動作します。これは、フレームごとに 2 つまたは 3 つの 80 サンプルのサブブロックがあることを意味します。これら 2 つまたは 3 つのサブブロックはそれぞれ個別に強化されますが、同様の方法で強化されます。

   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
        

Figure 4.2. Flow chart of the enhancer.

図4.2。エンハンサーのフローチャート。

1. Pitch estimation of each of the two/three new 80-sample blocks.

1. 2 つまたは 3 つの新しい 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. 前のステップからの 6 つのピッチ周期同期シーケンスによって生成された平滑化された残差を計算します。

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.

エンハンサーの主なアイデアは、分析された非エンハンス サブブロックの前に 3 つの 80 サンプル ブロックとその後に 3 つの 80 サンプル ブロックを見つけ、これらを使用してそのサブブロックの励起の品質を向上させることです。6 つのブロックは、強化されている未強化のサブブロックとの相関が最も高くなるように選択されます。換言すれば、6つのブロックは、非強化サブブロックに対するピッチ周期同期シーケンスである。

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.

サブブロックを近似する 6 つのピッチ周期同期シーケンスの線形結合が計算されます。近似値と非強化サブブロック間の二乗誤差が十分に小さい場合、強化された残差はこの近似値に等しく設定されます。二乗誤差基準が満たされない場合、近似と非強化残差の線形結合により強化残差が形成されます。

4.6.1. Estimating the Pitch
4.6.1. ピッチの推定

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.

ピッチ推定は、複雑さを効率的に行う方法でピッチ周期同期シーケンスの位置を決定するために必要である。新しい 2 つまたは 3 つのサブブロックのそれぞれについて、ラグ 20 からラグ 120 までの範囲で最大の相関を見つけることによってピッチ推定値が計算されます。これらのピッチ推定値は、可能な限り最良のピッチ周期の検索を絞り込むために使用されます。同期シーケンス。

4.6.2. Determination of the Pitch-Synchronous Sequences
4.6.2. ピッチ同期シーケンスの決定

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:

前のステップからピッチ推定を受け取ると、エンハンサーは一度に 1 つの 80 サンプルのサブブロックを分析してエンハンスします。ピッチ周期同期シーケンス pssq(n) は、それぞれが現在のサブブロックから n*lag サンプルだけシフトされた長さ 80 サンプルのベクトルとして見ることができます。6 つのピッチ周期同期シーケンス pssq(-3) から pssq(-1) および pssq(1) から pssq(3) は、以下の手順で一度に 1 つずつ見つかります。

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(0) の前にある pssq(n) (n > 0) の場合、pssq(n) の位置は、pssq(n-1) の正確な位置から時間的に 1 ピッチ推定値を前方に移動することによって推定されます。同様に、pssq(0) の後ろの pssq(n) (n < 0) は、pssq(n 1) の正確な位置から時間的に 1 ピッチ推定値を後方に移動することによって推定されます。推定された pssq(n) ベクトルの位置が完全にエンハンサー メモリ内にある場合 (図 4.3)、ステップ 2、3、および 4 が実行されます。それ以外の場合、pssq(n) は 0 に設定されます。

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 サンプルの間隔で計算されます。これにより、5 つの相関値が得られます。

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) 5 つの相関値は、4 つの単純なアップサンプリング フィルター (係数 upsFilter1.. upsFilter4 を持つ MA フィルター) を使用して、係数 4 でアップサンプリングされます。これらの中で最大値が見つかり、これはサンプルの 4 分の 1 の解像度で最適なピッチ周期を指定します。

      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(0) から時間的に後方に移動し、次に pssq(0) から時間的に順方向に移動して、すべての pssq(n) を反復的に見つけることができます。

   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 ms フレーム サイズの拡張。

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 サンプル ブロックのエンハンスメントにおけるピッチ周期同期シーケンスを示しています。強化されていない信号入力は最後の 2 つのサブブロック (1 ~ 2) に格納され、他の 6 つのサブブロックには強化されていない残差の時間前が含まれます。80 サンプルの 2 つのブロックに対して拡張アルゴリズムを実行します。2 つのブロックのうち最初のブロックは、サブブロック 0 の最後の 40 サンプルとサブブロック 1 の最初の 40 サンプルで構成されます。2 番目の 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 |
        

Figure 4.4. Enhancement for 30 ms frame size.

図4.4。30 ms フレーム サイズの拡張。

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 は、30 ms フレーム サイズ モードでの最初の 80 サンプル ブロックのエンハンスメントにおけるピッチ周期同期シーケンスを示しています。強化されていない信号入力は、最後の 3 つのサブブロック (1 ~ 3) に保存されます。他の 5 つのサブブロックには、拡張されていない残差事前時間情報が含まれています。エンハンスメント アルゴリズムは、3 つの 80 サンプル サブブロック 0、1、2 に対して実行されます。

4.6.3. Calculation of the Smoothed Excitation
4.6.3. 平滑化励振の計算

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).

6 つの 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
        
   pssq_weight(i) = 0.5*(1-cos(2*pi*(i+4)/(2*3+2)))
        
   z = C * y, where C = ||pssq(0)||/||y||
        
4.6.4. Enhancer Criterion
4.6.4. エンハンサー基準

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 = (pssq(0)-z)*(pssq(0)-z), and "*" means the dot product
        
4.6.5. Enhancing the excitation
4.6.5. 興奮を高める

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)
        

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.

最適化のために 2 つのソリューション領域を区別します。1) 最初の制約が満たされる領域、2) 最初の制約が満たされず 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.

2 番目の制約が必要ない最初のケースでは、最適化された再推定ベクトルは単に z (y のエネルギースケール版) になります。

In the second case, where the second constraint is activated and becomes an equality constraint, we have

2 番目のケースでは、2 番目の制約がアクティブ化され、等価制約になります。

      z= A*y + B*pssq(0)
        

where

ただし

      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)
        

and

そしてと及びアンド並びに且つ兼又共それですると亦だからそれからはたまた

      B = 1 - b/2 - A * w10/w00
        

Appendix A.16 contains a listing of a reference implementation for the enhancement method.

付録 A.16 には、拡張メソッドの参照実装のリストが含まれています。

4.7. Synthesis Filtering
4.7. 合成フィルタリング

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) を実行することによって取得されます。エンハンサーの遅延を補償するには、合成フィルターをシフトする必要があります。20 ms フレーム サイズ モードの場合は 40 サンプル サブブロック 1 つシフトする必要があり、30 ms フレーム サイズ モードの場合は 40 サンプル サブブロック 2 つシフトする必要があります。LP 係数は、フィルタの状態を維持しながら、すべてのサブブロックの最初のサンプルで変更されるべきです (SHOULD)。PLC ブロックの場合、解決策の 1 つは、最後に復号された音声ブロックの最後の LP 係数をすべてのサブブロックに適用することです。

The reference implementation for the synthesis filtering can be found in Appendix A.48.

合成フィルタリングのリファレンス実装は、付録 A.48 にあります。

4.8. Post Filtering
4.8. ポストフィルタリング

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.

必要に応じて、デコードされたブロックをハイパス フィルターでフィルター処理できます。これにより、デコードされた信号の低周波数が除去されます。65 Hz でカットオフするこのリファレンス実装を付録 A.30 に示します。

5. Security Considerations
5. セキュリティに関する考慮事項

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] などの外部メカニズムをその目的に使用してもよい(MAY)。

6. Evaluation of the iLBC Implementations
6. iLBC 実装の評価

It is possible and suggested to evaluate certain iLBC implementation by utilizing methodology and tools available at http://www.ilbcfreeware.org/evaluation.html

http://www.ilbcfreeware.org/evaluation.html で入手可能な方法論とツールを利用して、特定の iLBC 実装を評価することが可能であり、推奨されています。

7. References
7. 参考文献
7.1. Normative References
7.1. 引用文献

[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) オーディオ/ビデオ コーデック仕様、Cable Television Laboratories, Inc.

7.2. Informative References
7.2. 参考引用

[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 3711、2004 年 3 月。

8. Acknowledgements
8. 謝辞

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 (Global IP Sound)。

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.

Peter Vary、Frank Mertz、Christoph Erdmann (アーヘン工科大学)。ウラジミール・クペルマン (Niftybox LLC);Thomas Eriksson (Chalmers 工科大学) と Gernot Kubin (グラーツ工科大学) には、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: グローバル定義 constants.h: グローバル定数ヘッダー constants.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 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

anaFilter.h: lpc 分析フィルターヘッダー anaFilter.c: lpc 分析フィルター関数 createCB.h: コードブック構築ヘッダー createCB.c: コードブック構築関数 doCPLC.h: パケット損失隠蔽ヘッダー doCPLC.c: パケット損失隠蔽関数Enhancer.h:信号強調ヘッダー extender.c: 信号強調関数 filter.h: 一般的なフィルター ヘッダー filter.c: 一般的なフィルター関数 FrameClassify.h: 開始状態分類ヘッダー FrameClassify.c: 開始状態分類関数 Gainquant.h: ゲイン量子化ヘッダー Gainquant.c: ゲイン量子化関数 getCBvec.h: コードブック ベクトル構築ヘッダ getCBvec.c: コードブック ベクトル構築関数 helpfun.h: 汎用ヘッダ helpfun.c: 汎用関数 hpInput.h: 入力ハイパス フィルタ ヘッダ hpInput.c: 入力ハイパスフィルタ関数 hpOutput.h: 出力ハイパス フィルタ ヘッダ hpOutput.c: 出力ハイパス フィルタ関数 iCBConstruct.h: 励振デコード ヘッダ iCBConstruct.c: 励振デコード関数 iCBSearch.h: 励振エンコード ヘッダ iCBSearch.c: 励振エンコード関数 LPCdecode。h: lpc デコード ヘッダー LPCdecode.c: lpc デコード関数 LPCencode.h: lpc エンコード ヘッダー LPCencode.c: lpc エンコード関数 lsf.h: 線スペクトル周波数ヘッダー lsf.c: 線スペクトル周波数関数Packing.h: ビットストリーム パケット化ヘッダー パッキング.c: ビットストリーム パケット化関数 StateConstructW.h: 状態デコード ヘッダー 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.

この実装は移植可能であり、さまざまなプラットフォームで動作するはずです。ただし、特定のプラットフォームでの実装を最適化することは難しくありません。これは読者に任せてください。

A.1. iLBC_test.c
A.1. iLBC_test.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

iLBC_test.c

iLBC_test.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"
        
   /* Runtime statistics */
   #include <time.h>
        

#define ILBCNOOFWORDS_MAX (NO_OF_BYTES_30MS/2)

#define ILBCNOOFWORDS_MAX (NO_OF_BYTES_30MS/2)

   /*----------------------------------------------------------------*
    *  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;
        
       /* convert signal to float */
        
       for (k=0; k<iLBCenc_inst->blockl; k++)
           block[k] = (float)data[k];
        
       /* do the actual encoding */
        
       iLBC_encode((unsigned char *)encoded_data, block, iLBCenc_inst);
        

return (iLBCenc_inst->no_of_bytes); }

return (iLBCenc_inst->no_of_bytes);}

   /*----------------------------------------------------------------*
    *  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;
        
       /* check if mode is valid */
        
       if (mode<0 || mode>1) {
           printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);}
        
       /* do actual decoding of block */
        

iLBC_decode(decblock, (unsigned char *)encoded_data, iLBCdec_inst, mode);

iLBC_decode(decblock, (unsigned char *)encoded_data, iLBCdec_inst, mode);

       /* convert to short */
              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;
       }
        

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
    *
    *--------------------------------------------------------------*/
        

int main(int argc, char* argv[]) {

int main(int argc, char* argv[]) {

       /* Runtime statistics */
        
       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;
        
       /* Create structs */
       iLBC_Enc_Inst_t Enc_Inst;
       iLBC_Dec_Inst_t Dec_Inst;
        
       /* 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",
        
                   argv[5]);
               exit(1);
           }
       } else {
           cfileid=NULL;
       }
        
       /* 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");
        
       /* Initialization */
        
       initEncode(&Enc_Inst, mode);
       initDecode(&Dec_Inst, mode, 1);
        
       /* Runtime statistics */
        
       starttime=clock()/(float)CLOCKS_PER_SEC;
        
       /* loop over input blocks */
        
       while (fread(data,sizeof(short),Enc_Inst.blockl,ifileid)==
               Enc_Inst.blockl) {
        
           blockcount++;
        
           /* encoding */
                      fprintf(stderr, "--- Encoding block %i --- ",blockcount);
           len=encode(&Enc_Inst, encoded_data, data);
           fprintf(stderr, "\r");
        
           /* write byte file */
        
           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;
           }
        
           /* decoding */
        
           fprintf(stderr, "--- Decoding block %i --- ",blockcount);
        
           len=decode(&Dec_Inst, decoded_data, encoded_data, pli);
           fprintf(stderr, "\r");
        
           /* write output file */
        
           fwrite(decoded_data,sizeof(short),len,ofileid);
       }
        
       /* 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);
        
       printf("Time to run iLBC     :");
       printf(" %.1f s (%.1f %% of realtime)\n\n", runtime,
           (100*runtime/outtime));
        
       /* close files */
        
       fclose(ifileid);  fclose(efileid); fclose(ofileid);
       if (argc==6) {
           fclose(cfileid);
       }
       return(0);
   }
        
A.2. iLBC_encode.h
A.2. iLBC_エンコード.h
   /******************************************************************
        

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"

#include "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 */
   );
        

void iLBC_encode(

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 */
   );
        

#endif

#endif

A.3. iLBC_encode.c
A.3. iLBC_エンコード.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

iLBC_encode.c

iLBC_エンコード.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #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"

#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"

   /*----------------------------------------------------------------*
    *  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;
        
           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));
        

return (iLBCenc_inst->no_of_bytes); }

return (iLBCenc_inst->no_of_bytes);}

   /*----------------------------------------------------------------*
    *  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 */
   ){
        

float data[BLOCKL_MAX]; float residual[BLOCKL_MAX], reverseResidual[BLOCKL_MAX];

浮動小数点データ[BLOCKL_MAX];float 残差[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];
        
       /* 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);
        
       /* otherwise simply copy */
        
       /*memcpy(data,block,iLBCenc_inst->blockl*sizeof(float));*/
        
       /* 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 */
        
       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 */
        
       start = FrameClassify(iLBCenc_inst, residual);
        
       /* 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;
        
       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;
       }
        
       /* 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);
        
       StateConstructW(idxForMax, idxVec,
           &syntdenum[(start-1)*(LPC_FILTERORDER+1)],
           &decresidual[start_pos], iLBCenc_inst->state_short_len);
        
       /* predictive quantization in state */
        
       if (state_first) { /* put adaptive part in the end */
        
           /* 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));
        
           /* 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,

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,

&weightdenum[start*(LPC_FILTERORDER+1)], weightState, 0);

&weightdenum[start*(LPC_FILTERORDER 1)],weightState, 0);

           /* 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( &decresidual[start_pos iLBCenc_inst->state_short_len], extra_cb_index, extra_gain_index, mem CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);

       }
       else { /* put adaptive part in the beginning */
        
           /* create reversed vectors for prediction */
        
           for (k=0; k<diff; k++) {
               reverseResidual[k] = residual[(start+1)*SUBL-1
                   -(k+iLBCenc_inst->state_short_len)];
           }
        
           /* 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));
        
           /* 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);

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);

           /* construct decoded vector */
        

iCBConstruct(reverseDecresidual, extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);

iCBConstruct(reverseDecresidual, extra_cb_index, extra_gain_index, mem CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);

           /* get decoded residual from reversed vector */
        
           for (k=0; k<diff; k++) {
               decresidual[start_pos-1-k] = reverseDecresidual[k];
        
           }
       }
        
       /* counter for predicted sub-frames */
        

subcount=0;

サブカウント=0;

       /* forward prediction of sub-frames */
        
       Nfor = iLBCenc_inst->nsub-start-1;
        

if ( Nfor > 0 ) {

if ( Nfor > 0 ) {

           /* 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));
        
           /* loop over sub-frames to encode */
        
           for (subframe=0; subframe<Nfor; subframe++) {
        
               /* 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);
        
               /* 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);
        
               /* 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));
        
               subcount++;
           }
       }
        
       /* backward prediction of sub-frames */
        

Nback = start-1;

Nback = 開始-1;

if ( Nback > 0 ) {

if ( Nback > 0 ) {

           /* 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];
               }
           }
        
           /* setup memory */
        
           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));
        
           /* loop over sub-frames to encode */
        
           for (subframe=0; subframe<Nback; subframe++) {
        
               /* encode sub-frame */
        

iCBSearch(iLBCenc_inst, cb_index+subcount*CB_NSTAGES,

iCBSearch(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);
        
               /* 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);
        
               /* 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));
        
               subcount++;
        

}

}

           /* get decoded residual from reversed vector */
        
           for (i=0; i<SUBL*Nback; i++) {
               decresidual[SUBL*Nback - i - 1] =
                   reverseDecresidual[i];
           }
       }
       /* end encoding part */
        
       /* adjust index */
       index_conv_enc(cb_index);
        
       /* pack bytes */
        
       pbytes=bytes;
       pos=0;
        
       /* loop over the 3 ULP classes */
        
       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);
           }
        
           /* 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(&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);
        
           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 */
        
           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);
           }
        
           /* 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(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);
               }
           }
       }
        
       /* set the last bit to zero (otherwise the decoder
          will treat it as a lost frame) */
       dopack( &pbytes, 0, 1, &pos);
   }
        
A.4. iLBC_decode.h
A.4. iLBC_デコード.h
   /******************************************************************
        

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"

#include "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 */
   );
        
   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

#endif

A.5. iLBC_decode.c
A.5. iLBC_デコード.c
   /******************************************************************
        

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 "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"

#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"

   /*----------------------------------------------------------------*
    *  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;
        
       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);
       }
        
       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;
        
       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;
        
       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->prev_enh_pl = 0;
        

return (iLBCdec_inst->blockl); }

return (iLBCdec_inst->blockl);}

   /*----------------------------------------------------------------*
    *  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;
        
       diff = STATE_LEN - iLBCdec_inst->state_short_len;
        
       if (state_first == 1) {
           start_pos = (start-1)*SUBL;
       } else {
           start_pos = (start-1)*SUBL + diff;
       }
        
       /* decode scalar part of start state */
        
       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 */
        
           /* 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));
        
           /* 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_pos iLBCdec_inst->state_short_len], extra_cb_index, extra_gain_index, mem CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);

       }
       else {/* put adaptive part in the beginning */
        
           /* create reversed vectors for prediction */
        
           for (k=0; k<diff; k++) {
               reverseDecresidual[k] =
                   decresidual[(start+1)*SUBL-1-
                           (k+iLBCdec_inst->state_short_len)];
           }
        
           /* 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];
        
           }
           memset(mem, 0, (CB_MEML-k)*sizeof(float));
        
           /* construct decoded vector */
        

iCBConstruct(reverseDecresidual, extra_cb_index, extra_gain_index, mem+CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);

iCBConstruct(reverseDecresidual, extra_cb_index, extra_gain_index, mem CB_MEML-stMemLTbl, stMemLTbl, diff, CB_NSTAGES);

           /* get decoded residual from reversed vector */
        
           for (k=0; k<diff; k++) {
               decresidual[start_pos-1-k] = reverseDecresidual[k];
           }
       }
        
       /* counter for predicted sub-frames */
        

subcount=0;

サブカウント=0;

       /* forward prediction of sub-frames */
        
       Nfor = iLBCdec_inst->nsub-start-1;
        

if ( Nfor > 0 ){

if ( Nfor > 0 ){

           /* 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));
        
           /* loop over sub-frames to encode */
        
           for (subframe=0; subframe<Nfor; subframe++) {
        
               /* 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);
        
               /* 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));
        
               subcount++;
        

}

}

}

}

       /* backward prediction of sub-frames */
        

Nback = start-1;

Nback = 開始-1;

if ( Nback > 0 ) {

if ( Nback > 0 ) {

           /* setup memory */
        
           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));
        
           /* loop over subframes to decode */
        
           for (subframe=0; subframe<Nback; subframe++) {
        
               /* 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);
        
               /* update memory */
        
               memcpy(mem, mem+SUBL, (CB_MEML-SUBL)*sizeof(float));
               memcpy(mem+CB_MEML-SUBL,
                   &reverseDecresidual[subframe*SUBL],
                   SUBL*sizeof(float));
        
               subcount++;
           }
        
           /* get decoded residual from reversed vector */
        
           for (i=0; i<SUBL*Nback; i++)
               decresidual[SUBL*Nback - i - 1] =
               reverseDecresidual[i];
       }
   }
        
   /*----------------------------------------------------------------*
    *  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];
        
       if (mode>0) { /* the data are good */
        
           /* decode data */
        
           pbytes=bytes;
           pos=0;
        
           /* 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;
               }
           }
        
           /* loop over ULP classes */
        
           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]);
               }
        
               /* 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,

unpack( &pbytes, &lastpart,

                   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]);
        
               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 */
        
               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 */
        
               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_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;
        
           if (mode==1) { /* No bit errors was detected,
                             continue decoding */
        
               /* adjust index */
               index_conv_dec(cb_index);
        
               /* 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);
        

Decode(iLBCdec_inst, decresidual, start, idxForMax, idxVec, syntdenum, cb_index, gain_index, extra_cb_index, extra_gain_index, state_first);

Decode(iLBCdec_inst、decresidual、start、idxForMax、idxVec、syntdenum、cb_index、gain_index、extra_cb_index、extra_gain_index、state_first);

               /* 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);
        
               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)
            */
        
           /* packet loss conceal */
        
           memset(zeros, 0, BLOCKL_MAX*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));
        
           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) {
        
           /* post filtering */
        
           iLBCdec_inst->last_lag =
               enhancerInterface(data, decresidual, iLBCdec_inst);
        
           /* 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);
        
               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);
        
           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;
        
           /* 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);
           }
        

}

}

       /* high pass filtering on output if desired, otherwise
          copy to out */
        
       hpOutput(data, iLBCdec_inst->blockl,
                   decblock,iLBCdec_inst->hpomem);
        
       /* 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->prev_enh_pl=0;
        
       if (mode==0) { /* PLC was used */
           iLBCdec_inst->prev_enh_pl=1;
       }
   }
        
A.6. iLBC_define.h
A.6. iLBC_define.h
   /******************************************************************
        

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>
        

#ifndef __iLBC_ILBCDEFINE_H #define __iLBC_ILBCDEFINE_H

#ifndef __iLBC_ILBCDEFINE_H #define __iLBC_ILBCDEFINE_H

   /* 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
        
   #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
        
   /* 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)
        
   /* 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
        
   /* 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_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 */
        
   #define FILTERORDER_DS          7
   #define DELAY_DS            3
   #define FACTOR_DS               2
        
   /* 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
        
   /* 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

#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 (fフロート)6.283185307 #define 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_Enc_Inst_t_ {
        
       /* 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;
        
       /* analysis filter state */
       float anaMem[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];
        
       /* state of input HP filter */
       float hpimem[4];
        

} iLBC_Enc_Inst_t;

iLBC_Enc_Inst_t;

   /* type definition decoder instance */
   typedef struct iLBC_Dec_Inst_t_ {
        
       /* 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;
        
       /* synthesis filter state */
       float syntMem[LPC_FILTERORDER];
        
       /* old LSF for interpolation */
              float lsfdeqold[LPC_FILTERORDER];
        
       /* 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;
        
       /* previous synthesis filter parameters */
       float old_syntdenum[(LPC_FILTERORDER + 1)*NSUB_MAX];
        
       /* 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];
        

} iLBC_Dec_Inst_t;

iLBC_Dec_Inst_t;

#endif

#endif

A.7. constants.h
A.7. 定数.h
   /******************************************************************
        

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"

#include "iLBC_define.h"

   /* ULP bit allocation */
      extern const iLBC_ULP_Inst_t ULP_20msTbl;
   extern const iLBC_ULP_Inst_t ULP_30msTbl;
        
   /* high pass filters */
        
   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[];
        
   /* 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[];
        
   /* state quantization tables */
        

extern float state_sq3Tbl[]; extern float state_frgqTbl[];

extern float state_sq3Tbl[];extern float state_frgqTbl[];

   /* gain quantization tables */
        
   extern float gain_sq3Tbl[];
   extern float gain_sq4Tbl[];
   extern float gain_sq5Tbl[];
        
   /* adaptive codebook definitions */
        
   extern int search_rangeTbl[5][CB_NSTAGES];
   extern int memLfTbl[];
   extern int stMemLTbl;
   extern float cbfiltersTbl[CB_FILTERLEN];
        
   /* enhancer definitions */
        

extern float polyphaserTbl[]; extern float enh_plocsTbl[];

extern float ポリフェイザーTbl[];extern float enh_plocsTbl[];

#endif

#endif

A.8. constants.c
A.8. 定数.c
   /******************************************************************
        

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"

#include "iLBC_define.h"

   /* ULP bit allocation */
        
       /* 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}}}
   };
        
       /* 30 ms frame */
        
   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}}}
   };
        
   /* 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
   };
        
   /* 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 */
        
   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
   };
        
   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 */
        
   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) */
        

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, (flo) at)-0.033691};

   /* Gain Quantization */
        

float gain_sq3Tbl[8]={ (float)-1.000000, (float)-0.659973, (float)-0.330017, (float)0.000000, (float)0.250000, (float)0.500000, (float)0.750000, (float)1.00000};

float Gain_sq3Tbl[8]={ (float)-1.000000, (float)-0.659973, (float)-0.330017, (float)0.000000, (float)0.250000, (float)0.500000, (float)0.750000, (float)1.0 0000};

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, (浮動小数点)0.000000、(浮動小数点)0.150024、(浮動小数点)0.299988、(浮動小数点)0.450012、(浮動小数点)0.599976、(浮動小数点)0.750000、(浮動小数点)0.900024、(浮動小数点)1.049988、(浮動小数点)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]={ (浮動小数点)0.037476, (浮動小数点)0.075012, (浮動小数点)0.112488, (浮動小数点)0.150024, (浮動小数点)0.187500, (浮動小数点)0.224976, (浮動小数点)0.262512, (浮動小数点)0.299 988、(浮動小数点数)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};

   /* 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};
        
   /* LPC analysis and quantization */
        
   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 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)};
        
   /* 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
   };
        
   /* 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
   };
        
   /* 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,
      (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,
      (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,
      (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,
      (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,
      (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,
      (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,
      (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
   };
        
A.9. anaFilter.h
A.9. anaFilter.h
   /******************************************************************
        

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(

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 */
   );
        

#endif

#endif

A.10. anaFilter.c
A.10. anaFilter.c
   /******************************************************************
        

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"
        
   /*----------------------------------------------------------------*
    *  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;
        

po = Out;

po = アウト;

       /* 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 (j=0; 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 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++;
       }
        
       /* Update state vector */
        
       memcpy(mem, &In[len-LPC_FILTERORDER],
           LPC_FILTERORDER*sizeof(float));
   }
        
A.11. createCB.h
A.11. createCB.h
   /******************************************************************
        

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 */
        
       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 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

#endif

A.12. createCB.c
A.12. createCB.c
   /******************************************************************
        

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>
        
   /*----------------------------------------------------------------*
    *  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;
        
       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 */
        
       /* 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.
    *----------------------------------------------------------------*/
        
   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;
        
       for (icount=low; icount<=high; icount++) {
        
           /* 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;
        
           /* 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++);
           }
        
           /* 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++);
           }
        
           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 (crossDot > 0.0) {
                   measure = crossDot*crossDot*invenergy[tmpIndex];
               }
           }
           else {
               measure = crossDot*crossDot*invenergy[tmpIndex];
           }
        
           /* check if measure is better */
           ftmp = crossDot*invenergy[tmpIndex];
        
           if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
        
               *best_index = tmpIndex;
               *max_measure = measure;
               *gain = ftmp;
           }
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        

ilow = index-5;

ilow = インデックス-5;

       /* copy the first noninterpolated part */
        
       pp = buffer-index;
       memcpy(cbVec,pp,sizeof(float)*index);
        
       /* 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;
       }
        
       /* copy the second noninterpolated part */
        
       pp = buffer - index;
       memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));
        

}

}

A.13. doCPLC.h
A.13. doCPLC.h
   /******************************************************************
        

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 */
   );
        

#endif

#endif

A.14. doCPLC.c
A.14. doCPLC.c
   /******************************************************************
        

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 "iLBC_define.h"

#include "iLBC_define.h"

   /*----------------------------------------------------------------*
    *  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;
        
       /* 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];
       }
        
       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.
    *---------------------------------------------------------------*/
        
   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 */
        
       if (PLI == 1) {
        
           iLBCdec_inst->consPLICount += 1;
        
           /* if previous frame not lost,
              determine pitch pred. gain */
        
           if (iLBCdec_inst->prevPLI != 1) {
        
               /* 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);
        
                   if (maxcc_comp>maxcc) {
                       maxcc=maxcc_comp;
        
                       gain=gain_comp;
                       lag=i;
                       max_per=per;
                   }
               }
        

}

}

           /* previous frame lost, use recorded lag and periodicity */
        
           else {
               lag=iLBCdec_inst->prevLag;
               max_per=iLBCdec_inst->per;
           }
        
           /* 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;
        
           /* 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;
           }
        
           /* compute concealed residual */
                      energy = 0.0;
           for (i=0; i<iLBCdec_inst->blockl; i++) {
        
               /* noise component */
        
               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];
               }
        
               /* pitch repeatition component */
               pick = i - use_lag;
        
               if (pick < 0) {
                   PLCresidual[i] =
                       iLBCdec_inst->prevResidual[
                                   iLBCdec_inst->blockl+pick];
               } else {
                   PLCresidual[i] = PLCresidual[pick];
               }
        
               /* 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]);
        
               energy += PLCresidual[i] * PLCresidual[i];
           }
        
           /* 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];
               }
           }
        
           /* use old LPC */
        
           memcpy(PLClpc,iLBCdec_inst->prevLpc,
               (LPC_FILTERORDER+1)*sizeof(float));
        

}

}

       /* 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;
       }
        
       /* update state */
        
       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));
   }
        
A.15. enhancer.h
A.15. エンハンサー.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

enhancer.h

エンハンサー.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"

#include "iLBC_define.h"

   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 */
   );
        

#endif

#endif

A.16. enhancer.c
A.16. エンハンサー.c
   /******************************************************************
        

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"
        
   /*----------------------------------------------------------------*
    * 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(

void 最近隣(

       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;
        
           if (crit<bestcrit) {
               bestcrit=crit;
               *index=i;
           }
       }
   }
        
   /*----------------------------------------------------------------*
    * 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;
        
       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
    *---------------------------------------------------------------*/
        
   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 */
        
       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;
           }
       }
        
       /* 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++;
           }
       }
        
       /* filtering: simple convolution=inner products */
        
       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++;
           }
       }
        
       /* 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++;
           }
       }
   }
        
   /*----------------------------------------------------------------*
    * 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];
        
       /* defining array bounds */
        
       estSegPosRounded=(int)(estSegPos - 0.5);
        

searchSegStartPos=estSegPosRounded-ENH_SLOP;

searchSegStartPos=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;
        
       /* 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++) {
        
           if (corrVecUps[i]>maxv) {
               tloc=i;
               maxv=corrVecUps[i];
           }
       }
        
       /* 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);
        
       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 {
        
           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;
        
       /* compute the segment (this is actually a convolution) */
        
       mycorr1(seg,vect,ENH_VECTL,polyphaserTbl+(2*ENH_FL0+1)*fraction,
           2*ENH_FL0+1);
   }
        
   /*----------------------------------------------------------------*
    * 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;
        
       /* 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 (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 */
        
       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);
        
       /* 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;
       }
        
       /* 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 (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;
           }
        
           /* create smoothed sequence */
        
           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
    *---------------------------------------------------------------*/
        
   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;
        
       /* present */
        
       NearestNeighbor(lagBlock+hl,plocs,
           (float)0.5*(centerStartPos+centerEndPos),periodl);
        

blockStartPos[hl]=(float)centerStartPos;

blockStartPos[hl]=(float)centerStartPos;

       psseq=sseq+ENH_BLOCKL*hl;
       memcpy(psseq, idata+centerStartPos, ENH_BLOCKL*sizeof(float));
        
       /* 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);
        
           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 */
        
       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));
           }
       }
   }
        
   /*----------------------------------------------------------------*
    * 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];
        
       /* get said second sequence of segments */
        

getsseq(sseq,idata,idatal,centerStartPos,period, plocs,periodl,ENH_HL);

getseq(sseq,idata,idatal,centerStartPos,period,plocs,periodl,ENH_HL);

       /* compute the smoothed output from said second sequence */
        

smath(odata,sseq,ENH_HL,alpha0);

smath(odata,sseq,ENH_HL,alpha0);

}

}

   /*----------------------------------------------------------------*
    * cross correlation
    *---------------------------------------------------------------*/
        
   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];
       }
        
       if (ftmp1 > 0.0) {
           return (float)(ftmp1*ftmp1/ftmp2);
       }
          else {
           return (float)0.0;
       }
   }
        
   /*----------------------------------------------------------------*
    * 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];
        
       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;
        
       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));
        
       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;
        
       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. */
        
       memcpy(lpState,
           enh_buf+(ENH_NBLOCKS_EXTRA+ioffset)*ENH_BLOCKL-126,
           6*sizeof(float));
        
       /* 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);
        
       /* 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);
        
               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;
        

}

}

       /* PLC was performed on the previous packet */
       if (iLBCdec_inst->prev_enh_pl==1) {
        
           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);
        
               if (cc > maxcc) {
                   maxcc = cc;
                   lag = ilag;
               }
           }
        
           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 */
        

inPtr=&in[lag-1];

intPtr=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;
           }
        
           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--;
           }
        
           /* 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;
               }
           }
        
           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);
           }
       }
        

return (lag*2); }

リターン (ラグ*2);}

A.17. filter.h
A.17. フィルター.h
   /******************************************************************
        

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 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 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

#endif

A.18. filter.c
A.18. フィルター.c
   /******************************************************************
        

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"

#include "iLBC_define.h"

   /*----------------------------------------------------------------*
    *  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;
        
       for(n=0;n<lengthInOut;n++){
           for(k=1;k<=orderCoef;k++){
               *InOut -= Coef[k]*InOut[-k];
        
           }
           InOut++;
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       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
    *---------------------------------------------------------------*/
        
   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);
   }
        
   /*----------------------------------------------------------------*
    * 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;
        
       /* 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];
        
           o = (float)0.0;
        
           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--);
           }
        
           *Out_ptr++ = o;
       }
        
       /* Get the last part (use zeros as input for the future) */
        
       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;
       }
   }
        
A.19. FrameClassify.h
A.19. FrameClassify.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

FrameClassify.h

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 */
   );
        

#endif

#endif

A.20. FrameClassify.c
A.20. FrameClassify.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

FrameClassify.c

FrameClassify.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        

#include "iLBC_define.h"

#include "iLBC_define.h"

   /*---------------------------------------------------------------*
    *  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};
        
       /* init the front and back energies to zero */
        
       memset(fssqEn, 0, NSUB_MAX*sizeof(float));
       memset(bssqEn, 0, NSUB_MAX*sizeof(float));
        
       /* 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++) {
        
           fssqEn[n] += (*pp) * (*pp);
           pp++;
       }
        
       /* 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++;
           }
       }
        
       /* 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++;
       }
        
       /* find the index to the weighted 80 sample with
          most energy */
        
       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++) {
        
           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; }

max_ssqEn_n を返します。}

A.21. gainquant.h
A.21. ゲインクォント.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

gainquant.h

ゲインクォント.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 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

#endif

A.22. gainquant.c
A.22. ゲインクオント.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code gainquant.c

iLBC スピーチ コーダー ANSI-C ソース コード Gainquant.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #include <string.h>
   #include <math.h>
   #include "constants.h"
   #include "filter.h"
        
   /*----------------------------------------------------------------*
    *  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;
        
       /* ensure a lower bound on the scaling factor */
        

scale=maxIn;

スケール=最大値;

       if (scale<0.1) {
           scale=(float)0.1;
       }
        
       /* select the quantization table */
        
       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 */
        
       minmeasure=10000000.0;
       tindex=0;
       for (i=0; i<cblen; i++) {
        
           measure=(in-scale*cb[i])*(in-scale*cb[i]);
        
           if (measure<minmeasure) {
               tindex=i;
               minmeasure=measure;
           }
       }
       *index=tindex;
        
       /* return the quantized value */
        

return scale*cb[tindex]; }

スケール*cb[tindex]を返します;}

   /*----------------------------------------------------------------*
    *  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;
        
       /* obtain correct scale factor */
        
       scale=(float)fabs(maxIn);
        
       if (scale<0.1) {
           scale=(float)0.1;
       }
        
       /* 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];
       }
        

return 0.0; }

0.0を返します。}

A.23. getCBvec.h
A.23. getCBvec.h
   /******************************************************************
        

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 */
   );
        

#endif

#endif

A.24. getCBvec.c
A.24. getCBvec.c
   /******************************************************************
        

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>
        
   /*----------------------------------------------------------------*
    *  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;
        
       /* Determine size of codebook sections */
        
       base_size=lMem-cbveclen+1;
        
       if (cbveclen==SUBL) {
           base_size+=cbveclen/2;
       }
        
       /* No filter -> First codebook section */
        
       if (index<lMem-cbveclen+1) {
        
           /* first non-interpolated vectors */
        
           k=index+cbveclen;
           /* get vector */
           memcpy(cbvec, mem+lMem-k, cbveclen*sizeof(float));
        
       } else if (index < base_size) {
        
           k=2*(index-(lMem-cbveclen+1))+cbveclen;
        
           ihigh=k/2;
           ilow=ihigh-5;
        
           /* Copy first noninterpolated part */
        
           memcpy(cbvec, mem+lMem-k/2, ilow*sizeof(float));
        
           /* 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];
        
               alfa+=alfa1;
           }
        
           /* Copy second noninterpolated part */
        
           memcpy(cbvec+ihigh, mem+lMem-k+ihigh,
               (cbveclen-ihigh)*sizeof(float));
        

}

}

       /* Higher codebook section based on filtering */
        

else {

それ以外 {

           /* first non-interpolated vectors */
        
           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));
        
               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++;
               }
           }
        
           /* interpolated vectors */
        

else {

それ以外 {

               float tempbuff2[CB_MEML+CB_FILTERLEN+1];
        
               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));
        
               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++;
               }
        
               ihigh=k/2;
               ilow=ihigh-5;
        
               /* Copy first noninterpolated part */
        
               memcpy(cbvec, tmpbuf+lMem-k/2,
                   ilow*sizeof(float));
        
               /* 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;
               }
        
               /* Copy second noninterpolated part */
        
               memcpy(cbvec+ihigh, tmpbuf+lMem-k+ihigh,
                   (cbveclen-ihigh)*sizeof(float));
           }
       }
   }
        
A.25. helpfun.h
A.25. ヘルプファン.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

helpfun.h

ヘルプファン.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 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 interpolate(

void 補間(

       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 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 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
        
                              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

#endif

A.26. helpfun.c
A.26. ヘルプファン.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

helpfun.c

ヘルプファン.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #include <math.h>
        

#include "iLBC_define.h" #include "constants.h"

#include "iLBC_define.h" #include "constants.h"

   /*----------------------------------------------------------------*
    *  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;
        
       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
    *---------------------------------------------------------------*/
        
   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];
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        

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];
               }
                  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
    *---------------------------------------------------------------*/
        
   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];
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        

float chirp;

フロートチャープ。

chirp = coef;

チャープ = 係数;

       out[0] = in[0];
       for (i = 1; i < length; i++) {
           out[i] = chirp * in[i];
           chirp *= coef;
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       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;
        

}

}

   /*----------------------------------------------------------------*
    *  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;
        
       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
    *---------------------------------------------------------------*/
        
   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[i] + cb[i - 1])/2)) {
               *index = i;
               *xq = cb[i];
           } else {
               *index = i - 1;
               *xq = cb[i - 1];
           }
       }
   }
        
   /*----------------------------------------------------------------*
    *  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 */
        
       /* 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;
        
                   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]<minlsf) {
                       lsf[pos]=minlsf;
                       change=1;
                   }
        
                   if (lsf[pos]>maxlsf) {
                       lsf[pos]=maxlsf;
                       change=1;
                   }
               }
           }
       }
        

return change; }

釣り銭を返す。}

A.27. hpInput.h
A.27. hpInput.h
   /******************************************************************
        

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 */
   );
        

#endif

#endif

A.28. hpInput.c
A.28. hpInput.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code hpInput.c

iLBC スピーチ コーダー ANSI-C ソース コード hpInput.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        

#include "constants.h"

#include "定数.h"

   /*----------------------------------------------------------------*
    *  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;
        
       /* 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];
        
           mem[1] = mem[0];
           mem[0] = *pi;
           po++;
           pi++;
        

}

}

       /* 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];
        
           mem[3] = mem[2];
           mem[2] = *po;
           po++;
        
       }
   }
        
A.29. hpOutput.h
A.29. hp出力.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

hpOutput.h

hp出力.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 */
   );
        

#endif

#endif

A.30. hpOutput.c
A.30. hp出力.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

hpOutput.c

hp出力.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        

#include "constants.h"

#include "定数.h"

   /*----------------------------------------------------------------*
    *  Output high-pass filter
    *---------------------------------------------------------------*/
        

void hpOutput(

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 */
   ){
       int i;
       float *pi, *po;
        
       /* 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];
        
           mem[1] = mem[0];
           mem[0] = *pi;
           po++;
           pi++;
        

}

}

       /* 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];
        
           mem[3] = mem[2];
           mem[2] = *po;
           po++;
       }
   }
        
A.31. iCBConstruct.h
A.31. iCBConstruct.h
   /******************************************************************
        

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_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 */
   );
        

#endif

#endif

A.32. iCBConstruct.c
A.32. iCBConstruct.c
   /******************************************************************
        

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 "iLBC_define.h" #include "gainquant.h" #include "getCBvec.h"

#include "iLBC_define.h" #include "gainquant.h" #include "getCBvec.h"

   /*----------------------------------------------------------------*
    *  Convert the codebook indexes to make the search easier
    *---------------------------------------------------------------*/
        
   void index_conv_enc(
       int *index          /* (i/o) Codebook indexes */
   ){
       int 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 */
           }
       }
   }
        
   void index_conv_dec(
       int *index          /* (i/o) Codebook indexes */
   ){
       int 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 */
           }
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        

float gain[CB_NSTAGES]; float cbvec[SUBL];

浮動小数点ゲイン[CB_NSTAGES];float cbvec[SUBL];

       /* 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);
       }
        
       /* 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];
               }
           }
       }
   }
        
A.33. iCBSearch.h
A.33. iCBSearch.h
   /******************************************************************
        

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
      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

#endif

A.34. iCBSearch.c
A.34. iCBSearch.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

iCBSearch.c

iCBSearch.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #include <math.h>
   #include <string.h>
        

#include "iLBC_define.h" #include "gainquant.h" #include "createCB.h" #include "filter.h" #include "constants.h"

#include "iLBC_define.h" #include "gainquant.h" #include "createCB.h" #include "filter.h" #include "constants.h"

   /*----------------------------------------------------------------*
    *  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 */
          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));
        
       /* Determine size of codebook sections */
        
       base_size=lMem-lTarget+1;
        
       if (lTarget==SUBL) {
           base_size=lMem-lTarget+1+lTarget/2;
       }
        
       /* 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));
        
       /* weighting */
        
       AllPoleFilter(buf+LPC_FILTERORDER, weightDenum,
           lMem+lTarget, LPC_FILTERORDER);
        
       /* Construct the codebook and target needed */
        
       memcpy(target, buf+LPC_FILTERORDER+lMem, lTarget*sizeof(float));
        

tene=0.0;

10 = 0.0;

       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. */
        
       filteredCBvecs(cbvectors, buf+LPC_FILTERORDER, lMem);
        
       /* The Main Loop over stages */
        
       for (stage=0; stage<nStages; stage++) {
        

range = search_rangeTbl[block][stage];

range = search_rangeTbl[ブロック][ステージ];

           /* initialize search measure */
        
           max_measure = (float)-10000000.0;
           gain = (float)0.0;
           best_index = 0;
        
           /* 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++);
           }
        
           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;
        
               *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;
        
               }
               ppe++;
        

measure=(float)-10000000.0;

メジャー = (浮動小数点数)-10000000.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];
        
           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 */
        
           for (icount=1; icount<range; icount++) {
        
               /* calculate measure */
        
               crossDot=0.0;
               pp = buf+LPC_FILTERORDER+lMem-lTarget-icount;
        
               for (j=0; j<lTarget; j++) {
                   crossDot += target[j]*(*pp++);
               }
        
               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;
                   }
                                      measure=(float)-10000000.0;
        
                   if (crossDot > 0.0) {
                       measure = crossDot*crossDot*invenergy[icount];
                   }
               }
               else {
                   measure = crossDot*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;
               }
           }
        
           /* Loop over augmented part in the first codebook
            * section, full search.
            * The vectors are interpolated.
            */
        
           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);
           }
        
           /* set search range for following codebook sections */
        

base_index=best_index;

ベースインデックス=ベストインデックス;

           /* unrestricted search */
        
           if (CB_RESRANGE == -1) {
               sInd=0;
               eInd=range-1;
               sIndAug=20;
               eIndAug=39;
           }
        
           /* 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;
        
               if (lTarget==SUBL) {
        

if (sInd<0) {

if (sInd<0) {

                       sIndAug = 40 + sInd;
                       eIndAug = 39;
                       sInd=0;
        
                   } else if ( 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(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 */
        
                   if (sInd < 0) {
                       eInd -= sInd;
        

sInd = 0; }

sInd = 0;}

                   if(eInd > range) {
                       sInd -= (eInd - range);
                       eInd = range;
                   }
               }
           }
        
           /* search of higher codebook section */
        
           /* index search range */
           counter = sInd;
           sInd += base_size;
           eInd += base_size;
        
           if (stage==0) {
               ppe = energy+base_size;
               *ppe=0.0;
        
               pp=cbvectors+lMem-lTarget;
               for (j=0; j<lTarget; j++) {
                   *ppe+=(*pp)*(*pp++);
               }
        
               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++;
               }
           }
        
           /* loop over search range */
        
           for (icount=sInd; icount<eInd; icount++) {
        
               /* calculate measure */
        
               crossDot=0.0;
               pp=cbvectors + lMem - (counter++) - lTarget;
        
               for (j=0;j<lTarget;j++) {
        
                   crossDot += target[j]*(*pp++);
               }
        
               if (energy[icount]>0.0) {
                   invenergy[icount] =(float)1.0/(energy[icount]+EPS);
               } else {
                   invenergy[icount] =(float)0.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];
               }
        
               /* 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;
               }
           }
        
           /* 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);
           }
        
           /* record best index */
        

index[stage] = best_index;

インデックス[ステージ] = best_index;

           /* gain quantization */
        
           if (stage==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]);
               }
           }
        
           /* Extract the best (according to measure)
              codebook vector */
        
           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) {
                   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;
        
                   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 */
        
           for (j=0;j<lTarget;j++) {
               cvec[j] += gain*(*pp);
               target[j] -= gain*(*pp++);
           }
        
           /* record quantized gain */
        

gains[stage]=gain;

ゲイン[段階]=ゲイン;

       }/* 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];
        
       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;
   }
        
A.35. LPCdecode.h
A.35. LPCdecode.h
   /******************************************************************
        

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 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 */
   );
        

#endif

#endif

A.36. LPCdecode.c
A.36. LPCデコード.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

LPC_decode.c

LPC_デコード.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #include <math.h>
   #include <string.h>
        

#include "helpfun.h" #include "lsf.h" #include "iLBC_define.h" #include "constants.h"

#include "helpfun.h" #include "lsf.h" #include "iLBC_define.h" #include "constants.h"

   /*---------------------------------------------------------------*
    *  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];
        
       interpolate(lsftmp, lsf1, lsf2, coef, length);
       lsf2a(a, lsftmp);
   }
        
   /*---------------------------------------------------------------*
    *  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;
        
       /* 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];
       }
        

if (lpc_n>1) {

if (lpc_n>1) {

           /* 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];
           }
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       lsfdeq2 = lsfdeq + length;
       lp_length = length + 1;
        
       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);
        
           /* 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;
           }
       }
        
       /* update memory */
        
       if (iLBCdec_inst->mode==30)
           memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2,
                       length*sizeof(float));
       else
           memcpy(iLBCdec_inst->lsfdeqold, lsfdeq,
                       length*sizeof(float));
        

}

}

A.37. LPCencode.h
A.37. LPEncode.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

LPCencode.h

LPEncode.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 */
   );
        

#endif

#endif

A.38. LPCencode.c
A.38. LPエンコード.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

LPCencode.c

LPエンコード.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #include <string.h>
        

#include "iLBC_define.h" #include "helpfun.h" #include "lsf.h" #include "constants.h"

#include "iLBC_define.h" #include "helpfun.h" #include "lsf.h" #include "constants.h"

   /*----------------------------------------------------------------*
    *  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];
        
       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 */
        
       for (k = 0; k < iLBCenc_inst->lpc_n; k++) {
        

is = LPC_LOOKBACK;

= LPC_LOOKBACK;

           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);
        
           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));
   }
        
   /*----------------------------------------------------------------*
        

* lsf interpolator and conversion from lsf to a coefficients * (subrutine to SimpleInterpolateLSF) *---------------------------------------------------------------*/

* LSF 補間器と LSF から係数への変換 * (サブルーチンから 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];
        
       interpolate(lsftmp, lsf1, lsf2, coef, length);
       lsf2a(a, lsftmp);
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       lsf2 = lsf + length;
       lsfdeq2 = lsfdeq + length;
       lp_length = length + 1;
        
       if (iLBCenc_inst->mode==30) {
           /* sub-frame 1: Interpolation between old and first
        
              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);
        
           /* 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));
        
               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 */
        
       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)
    *---------------------------------------------------------------*/
        
   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);
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       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);
   }
        
A.39. lsf.h
A.39. lsf.h
   /******************************************************************
        

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 lsf2a(
       float *a_coef,  /* (o) lpc coefficients */
       float *freq     /* (i) lsf coefficients */
   );
        

#endif

#endif

A.40. lsf.c
A.40. lsf.c
   /******************************************************************
        

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 <math.h>
        

#include "iLBC_define.h"

#include "iLBC_define.h"

   /*----------------------------------------------------------------*
    *  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;
        
       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;
        
       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;

古いオメガ = 0.0;

       old_p = FLOAT_MAX;
       old_q = FLOAT_MAX;
        
       /* 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++) {
        
           /* 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;
           }
        
           /* Start with low resolution grid */
        
           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) */
        
               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 (step_idx == (LSF_NUMBER_OF_STEPS - 1)){
        
                       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;
                       }
        
                       omega = old_omega;
                       step_idx = 0;
        
                       step_idx = LSF_NUMBER_OF_STEPS;
                   } else {
        
                       if (step_idx == 0) {
                           old_omega = omega;
                       }
        
                       step_idx++;
                       omega -= steps[step_idx];
        
                       /* Go back one grid step */
        
                       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;
               }
           }
       }
        
       for (i = 0; i<LPC_FILTERORDER; i++) {
           freq[i] = freq[i] * TWO_PI;
       }
   }
        
   /*----------------------------------------------------------------*
    *  conversion from lsf coefficients to lpc 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];
        
       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 */
        
       if ((freq[0] <= 0.0) || (freq[LPC_FILTERORDER - 1] >= 0.5)){
        
           if (freq[0] <= 0.0) {
               freq[0] = (float)0.022;
           }
        
           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);
        
           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));
        
       /* 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]);
       }
        
       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 (j=0; j<LPC_FILTERORDER; j++) {
        
           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];
           }
        
           a_coef[j + 1] = 2 * (a[LPC_HALFORDER] + b[LPC_HALFORDER]);
       }
        

a_coef[0] = 1.0; }

a_coef[0] = 1.0;}

A.41. packing.h
A.41. パッキング.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

packing.h

パッキング.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 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 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

#endif

A.42. packing.c
A.42. 梱包.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

packing.c

梱包.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        
   #include <math.h>
   #include <stdlib.h>
        

#include "iLBC_define.h" #include "constants.h" #include "helpfun.h" #include "string.h"

#include "iLBC_define.h" #include "constants.h" #include "helpfun.h" #include "string.h"

   /*----------------------------------------------------------------*
    *  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 */
        
       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));
   }
        
   /*----------------------------------------------------------------*
    *  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;
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       /* Clear the bits before starting in a new byte */
        
       if ((*pos)==0) {
        
           **bitstream=0;
       }
        

while (bitno>0) {

while (ビット番号 > 0) {

           /* Jump to the next byte if end of this byte is reached*/
        
           if (*pos==8) {
               *pos=0;
               (*bitstream)++;
               **bitstream=0;
           }
        
           posLeft=8-(*pos);
        
           /* 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));
        
               *pos=8;
               index-=((index>>(bitno-posLeft))<<(bitno-posLeft));
        
               bitno-=posLeft;
           }
       }
   }
        
   /*----------------------------------------------------------------*
    *  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 */
        

){ int BitsLeft;

){ int BitsLeft;

       *index=0;
        

while (bitno>0) {

while (ビット番号 > 0) {

           /* move forward in bitstream when the end of the
              byte is reached */
        
           if (*pos==8) {
               *pos=0;
               (*bitstream)++;
           }
        
           BitsLeft=8-(*pos);
        
           /* Extract bits to index */
        
           if (BitsLeft>=bitno) {
               *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno));
        
               *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;
           }
       }
   }
        
A.43. StateConstructW.h
A.43. StateConstructWh.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

StateConstructW.h Copyright (C) The Internet Society (2004). All Rights Reserved.

StateConstructW.h 著作権 (C) The Internet Society (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 */
   );
        

#endif

#endif

A.44. StateConstructW.c
A.44. StateConstructW.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

StateConstructW.c

StateConstructW.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 "iLBC_define.h" #include "constants.h" #include "filter.h"

   /*----------------------------------------------------------------*
    *  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 */
          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 */
        
       maxVal = state_frgqTbl[idxForMax];
       maxVal = (float)pow(10,maxVal)/(float)4.5;
        
       /* 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];
        
       /* 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]];
       }
        
       /* 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];
       }
   }
        
A.45. StateSearchW.h
A.45. 州検索WH
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

StateSearchW.h

州検索WH

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 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

#endif

A.46. StateSearchW.c
A.46. 州検索W.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

StateSearchW.c

州検索W.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 "helpfun.h"

#include "iLBC_define.h" #include "constants.h" #include "filter.h" #include "helpfun.h"

   /*----------------------------------------------------------------*
    *  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;
        
       /* initialization of buffer for filtering */
        
       memset(syntOutBuf, 0, LPC_FILTERORDER*sizeof(float));
        
       /* initialization of pointer for filtering */
        
       syntOut = &syntOutBuf[LPC_FILTERORDER];
        
       /* 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);
       }
        
       /* encoding loop */
        
       for (n=0; n<len; n++) {
        
           /* time update of filter coefficients */
        
           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);
        
           } 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);
        

}

}

           /* 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 */
        

toQ = in[n]-syntOut[n];

toQ = in[n]-syntOut[n];

           sort_sq(&xq, &index, toQ, state_sq3Tbl, 8);
           out[n]=index;
           syntOut[n] = state_sq3Tbl[out[n]];
        
           /* update of the prediction filter */
        
           AllPoleFilter(&syntOut[n], weightDenum, 1,
               LPC_FILTERORDER);
       }
   }
        
   /*----------------------------------------------------------------*
    *  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;
        
       /* 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];
        
       /* 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];
       }
        
       /* identification of the maximum amplitude value */
        
       maxVal = fout[0];
       for (k=1; k<len; k++) {
        
           if (fout[k]*fout[k] > maxVal*maxVal){
               maxVal = fout[k];
           }
       }
       maxVal=(float)fabs(maxVal);
        
       /* 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);
        
       /* 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;
       }
        
       /* 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);}

A.47. syntFilter.h
A.47. syntFilter.h
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

syntFilter.h

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 */
   );
        

#endif

#endif

A.48. syntFilter.c
A.48. syntFilter.c
   /******************************************************************
        

iLBC Speech Coder ANSI-C Source Code

iLBC スピーチ コーダー ANSI-C ソース コード

syntFilter.c

syntFilter.c

Copyright (C) The Internet Society (2004). All Rights Reserved.

著作権 (C) インターネット協会 (2004)。無断転載を禁じます。

   ******************************************************************/
        

#include "iLBC_define.h"

#include "iLBC_define.h"

   /*----------------------------------------------------------------*
    *  LP synthesis filter.
    *---------------------------------------------------------------*/
        
   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;
        

po=Out;

po=アウト;

       /* 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++;
       }
        
       /* 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++;
       }
        
       /* Update state vector */
        
       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

Soren Vang Andersen コミュニケーション技術学部 オールボー大学 Fredrik Bajers Vej 7A 9200 オールボー デンマーク

   Phone:  ++45 9 6358627
   EMail:  sva@kom.auc.dk
        

Alan Duric Telio AS Stoperigt. 2 Oslo, N-0250 Norway

アラン・デュリック・テリオ AS ストペリグト。2 オスロ、N-0250 ノルウェー

   Phone:  +47 21673555
   EMail:  alan.duric@telio.no
        

Henrik Astrom Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden

Henrik Astrom Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 スウェーデン

   Phone:  +46 8 54553040
   EMail:  henrik.astrom@globalipsound.com
        

Roar Hagen Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden

Roar Hagen Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 スウェーデン

Phone: +46 8 54553040 EMail: roar.hagen@globalipsound.com W. Bastiaan Kleijn Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 Sweden

電話: 46 8 54553040 電子メール: Roar.hagen@globalipsound.com W. Bastiaan Kleijn Global IP Sound AB Olandsgatan 42 Stockholm, S-11663 スウェーデン

   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

Jan Linden Global IP Sound Inc. 900 Kearny Street, suite 500 San Francisco, CA-94133 USA

   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 事務局に提出された IPR 開示のコピー、および利用可能になるライセンスの保証、またはこの仕様の実装者またはユーザーによるそのような所有権の使用に対する一般ライセンスまたは許可を取得しようとする試みの結果を入手できます。IETF オンライン IPR リポジトリ (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 エディター機能の資金は現在、インターネット協会によって提供されています。