Added fixed point iSAC codec implementation.

- Added fixed-point iSAC audio codec implementation (from stable r2699).
- Updated system wrappers (from stable r2699).
- Some cosmetic makefile changes.

Change-Id: If75d503698c11a4e4ceb851529127aadfe52f255
diff --git a/Android.mk b/Android.mk
index a6e7a49..7b046d6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -12,6 +12,8 @@
 include $(MY_WEBRTC_ROOT_PATH)/src/common_audio/resampler/Android.mk
 include $(MY_WEBRTC_ROOT_PATH)/src/common_audio/signal_processing/Android.mk
 include $(MY_WEBRTC_ROOT_PATH)/src/common_audio/vad/Android.mk
+include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_coding/codecs/isac/fix/source/Android.mk
+include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_coding/codecs/isac/main/source/Android.mk
 include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_processing/aec/Android.mk
 include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_processing/aecm/Android.mk
 include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_processing/agc/Android.mk
@@ -20,7 +22,6 @@
 include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_processing/utility/Android.mk
 #include $(MY_WEBRTC_ROOT_PATH)/src/modules/utility/source/Android.mk
 include $(MY_WEBRTC_ROOT_PATH)/src/system_wrappers/source/Android.mk
-include $(MY_WEBRTC_ROOT_PATH)/src/modules/audio_coding/codecs/isac/main/source/Android.mk
 
 # build .so
 LOCAL_PATH := $(call my-dir)
@@ -75,9 +76,15 @@
 
 LOCAL_WHOLE_STATIC_LIBRARIES := \
     libwebrtc_isac \
+    libwebrtc_isacfix \
     libwebrtc_spl \
     libwebrtc_system_wrappers
 
+ifeq ($(WEBRTC_BUILD_NEON_LIBS),true)
+LOCAL_WHOLE_STATIC_LIBRARIES += \
+    libwebrtc_isacfix_neon
+endif
+
 LOCAL_STATIC_LIBRARIES := \
     libprotobuf-cpp-2.3.0-lite
 
diff --git a/src/modules/audio_coding/codecs/isac/fix/interface/isacfix.h b/src/modules/audio_coding/codecs/isac/fix/interface/isacfix.h
new file mode 100644
index 0000000..28e9429
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/interface/isacfix.h
@@ -0,0 +1,633 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_
+
+/*
+ * Define the fixpoint numeric formats
+ */
+#include "typedefs.h"
+
+
+typedef struct {
+  void *dummy;
+} ISACFIX_MainStruct;
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+  /**************************************************************************
+   * WebRtcIsacfix_AssignSize(...)
+   *
+   *  Functions used when malloc is not allowed
+   *  Output the number of bytes needed to allocate for iSAC struct.
+   *
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_AssignSize(int *sizeinbytes);
+
+  /**************************************************************************
+   * WebRtcIsacfix_Assign(...)
+   *
+   * Functions used when malloc is not allowed, it
+   * places a struct at the given address.
+   *
+   * Input:
+   *      - *ISAC_main_inst   : a pointer to the coder instance.
+   *      - ISACFIX_inst_Addr : address of the memory where a space is
+   *                            for iSAC structure.
+   *
+   * Return value             : 0 - Ok
+   *                           -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst,
+                                     void *ISACFIX_inst_Addr);
+
+  /****************************************************************************
+   * WebRtcIsacfix_Create(...)
+   *
+   * This function creates an ISAC instance, which will contain the state
+   * information for one coding/decoding channel.
+   *
+   * Input:
+   *      - *ISAC_main_inst   : a pointer to the coder instance.
+   *
+   * Return value             : 0 - Ok
+   *                           -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_Free(...)
+   *
+   * This function frees the ISAC instance created at the beginning.
+   *
+   * Input:
+   *      - ISAC_main_inst    : a ISAC instance.
+   *
+   * Return value             :  0 - Ok
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_EncoderInit(...)
+   *
+   * This function initializes an ISAC instance prior to the encoder calls.
+   *
+   * Input:
+   *     - ISAC_main_inst     : ISAC instance.
+   *     - CodingMode         : 0 - Bit rate and frame length are automatically
+   *                                adjusted to available bandwidth on
+   *                                transmission channel.
+   *                            1 - User sets a frame length and a target bit
+   *                                rate which is taken as the maximum short-term
+   *                                average bit rate.
+   *
+   * Return value             :  0 - Ok
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
+                                          WebRtc_Word16  CodingMode);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_Encode(...)
+   *
+   * This function encodes 10ms frame(s) and inserts it into a package.
+   * Input speech length has to be 160 samples (10ms). The encoder buffers those
+   * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
+   * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - speechIn          : input speech vector.
+   *
+   * Output:
+   *      - encoded           : the encoded data vector
+   *
+   * Return value             : >0 - Length (in bytes) of coded data
+   *                             0 - The buffer didn't reach the chosen framesize
+   *                                 so it keeps buffering speech samples.
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
+                                     const WebRtc_Word16 *speechIn,
+                                     WebRtc_Word16 *encoded);
+
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_EncodeNb(...)
+   *
+   * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
+   * it into a package. Input speech length has to be 80 samples (10ms). The encoder
+   * interpolates into wide-band (16 kHz sampling) buffers those
+   * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
+   * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
+   *
+   * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - speechIn          : input speech vector.
+   *
+   * Output:
+   *      - encoded           : the encoded data vector
+   *
+   * Return value             : >0 - Length (in bytes) of coded data
+   *                             0 - The buffer didn't reach the chosen framesize
+   *                                 so it keeps buffering speech samples.
+   *                            -1 - Error
+   */
+
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  WebRtc_Word16 WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
+                                       const WebRtc_Word16 *speechIn,
+                                       WebRtc_Word16 *encoded);
+#endif //  WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_DecoderInit(...)
+   *
+   * This function initializes an ISAC instance prior to the decoder calls.
+   *
+   * Input:
+   *  - ISAC_main_inst : ISAC instance.
+   *
+   * Return value
+   *       :  0 - Ok
+   *         -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_UpdateBwEstimate1(...)
+   *
+   * This function updates the estimate of the bandwidth.
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - encoded           : encoded ISAC frame(s).
+   *      - packet_size       : size of the packet.
+   *      - rtp_seq_number    : the RTP number of the packet.
+   *      - arr_ts            : the arrival time of the packet (from NetEq)
+   *                            in samples.
+   *
+   * Return value             : 0 - Ok
+   *                           -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
+                                                const WebRtc_UWord16 *encoded,
+                                                WebRtc_Word32  packet_size,
+                                                WebRtc_UWord16 rtp_seq_number,
+                                                WebRtc_UWord32 arr_ts);
+
+  /****************************************************************************
+   * WebRtcIsacfix_UpdateBwEstimate(...)
+   *
+   * This function updates the estimate of the bandwidth.
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - encoded           : encoded ISAC frame(s).
+   *      - packet_size       : size of the packet.
+   *      - rtp_seq_number    : the RTP number of the packet.
+   *      - send_ts           : the send time of the packet from RTP header,
+   *                            in samples.
+   *      - arr_ts            : the arrival time of the packet (from NetEq)
+   *                            in samples.
+   *
+   * Return value             :  0 - Ok
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
+                                               const WebRtc_UWord16   *encoded,
+                                               WebRtc_Word32          packet_size,
+                                               WebRtc_UWord16         rtp_seq_number,
+                                               WebRtc_UWord32         send_ts,
+                                               WebRtc_UWord32         arr_ts);
+
+  /****************************************************************************
+   * WebRtcIsacfix_Decode(...)
+   *
+   * This function decodes an ISAC frame. Output speech length
+   * will be a multiple of 480 samples: 480 or 960 samples,
+   * depending on the framesize (30 or 60 ms).
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - encoded           : encoded ISAC frame(s)
+   *      - len               : bytes in encoded vector
+   *
+   * Output:
+   *      - decoded           : The decoded vector
+   *
+   * Return value             : >0 - number of samples in decoded vector
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
+                                     const WebRtc_UWord16 *encoded,
+                                     WebRtc_Word16 len,
+                                     WebRtc_Word16 *decoded,
+                                     WebRtc_Word16 *speechType);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_DecodeNb(...)
+   *
+   * This function decodes a ISAC frame in narrow-band (8 kHz sampling).
+   * Output speech length will be a multiple of 240 samples: 240 or 480 samples,
+   * depending on the framesize (30 or 60 ms).
+   *
+   * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - encoded           : encoded ISAC frame(s)
+   *      - len               : bytes in encoded vector
+   *
+   * Output:
+   *      - decoded           : The decoded vector
+   *
+   * Return value             : >0 - number of samples in decoded vector
+   *                            -1 - Error
+   */
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  WebRtc_Word16 WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
+                                       const WebRtc_UWord16 *encoded,
+                                       WebRtc_Word16 len,
+                                       WebRtc_Word16 *decoded,
+                                       WebRtc_Word16 *speechType);
+#endif //  WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_DecodePlcNb(...)
+   *
+   * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
+   * Output speech length  will be "240*noOfLostFrames" samples
+   * that equevalent of "30*noOfLostFrames" millisecond.
+   *
+   * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - noOfLostFrames    : Number of PLC frames (240 sample=30ms) to produce
+   *                            NOTE! Maximum number is 2 (480 samples = 60ms)
+   *
+   * Output:
+   *      - decoded           : The decoded vector
+   *
+   * Return value             : >0 - number of samples in decoded PLC vector
+   *                            -1 - Error
+   */
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  WebRtc_Word16 WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst,
+                                          WebRtc_Word16 *decoded,
+                                          WebRtc_Word16 noOfLostFrames );
+#endif // WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+
+
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_DecodePlc(...)
+   *
+   * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
+   * Output speech length  will be "480*noOfLostFrames" samples
+   * that is equevalent of "30*noOfLostFrames" millisecond.
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - noOfLostFrames    : Number of PLC frames (480sample = 30ms)
+   *                            to produce
+   *                            NOTE! Maximum number is 2 (960 samples = 60ms)
+   *
+   * Output:
+   *      - decoded           : The decoded vector
+   *
+   * Return value             : >0 - number of samples in decoded PLC vector
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst,
+                                        WebRtc_Word16 *decoded,
+                                        WebRtc_Word16 noOfLostFrames );
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_ReadFrameLen(...)
+   *
+   * This function returns the length of the frame represented in the packet.
+   *
+   * Input:
+   *      - encoded           : Encoded bitstream
+   *
+   * Output:
+   *      - frameLength       : Length of frame in packet (in samples)
+   *
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_ReadFrameLen(const WebRtc_Word16* encoded,
+                                           WebRtc_Word16* frameLength);
+
+  /****************************************************************************
+   * WebRtcIsacfix_Control(...)
+   *
+   * This function sets the limit on the short-term average bit rate and the
+   * frame length. Should be used only in Instantaneous mode.
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - rate              : limit on the short-term average bit rate,
+   *                            in bits/second (between 10000 and 32000)
+   *      - framesize         : number of milliseconds per frame (30 or 60)
+   *
+   * Return value             : 0  - ok
+   *                           -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
+                                      WebRtc_Word16          rate,
+                                      WebRtc_Word16          framesize);
+
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_ControlBwe(...)
+   *
+   * This function sets the initial values of bottleneck and frame-size if
+   * iSAC is used in channel-adaptive mode. Through this API, users can
+   * enforce a frame-size for all values of bottleneck. Then iSAC will not
+   * automatically change the frame-size.
+   *
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - rateBPS           : initial value of bottleneck in bits/second
+   *                            10000 <= rateBPS <= 32000 is accepted
+   *      - frameSizeMs       : number of milliseconds per frame (30 or 60)
+   *      - enforceFrameSize  : 1 to enforce the given frame-size through out
+   *                            the adaptation process, 0 to let iSAC change
+   *                            the frame-size if required.
+   *
+   * Return value             : 0  - ok
+   *                           -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
+                                         WebRtc_Word16 rateBPS,
+                                         WebRtc_Word16 frameSizeMs,
+                                         WebRtc_Word16 enforceFrameSize);
+
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_version(...)
+   *
+   * This function returns the version number.
+   *
+   * Output:
+   *      - version      : Pointer to character string
+   *
+   */
+
+  void WebRtcIsacfix_version(char *version);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_GetErrorCode(...)
+   *
+   * This function can be used to check the error code of an iSAC instance. When
+   * a function returns -1 a error code will be set for that instance. The
+   * function below extract the code of the last error that occured in the
+   * specified instance.
+   *
+   * Input:
+   *  - ISAC_main_inst        : ISAC instance
+   *
+   * Return value             : Error code
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_GetUplinkBw(...)
+   *
+   * This function return iSAC send bitrate
+   *
+   * Input:
+   *      - ISAC_main_inst    : iSAC instance
+   *
+   * Return value             : <0 Error code
+   *                            else bitrate
+   */
+
+  WebRtc_Word32 WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_SetMaxPayloadSize(...)
+   *
+   * This function sets a limit for the maximum payload size of iSAC. The same
+   * value is used both for 30 and 60 msec packets.
+   * The absolute max will be valid until next time the function is called.
+   * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
+   *
+   * Input:
+   *      - ISAC_main_inst    : iSAC instance
+   *      - maxPayloadBytes   : maximum size of the payload in bytes
+   *                            valid values are between 100 and 400 bytes
+   *
+   *
+   * Return value             : 0 if sucessful
+   *                           -1 if error happens
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
+                                                WebRtc_Word16 maxPayloadBytes);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_SetMaxRate(...)
+   *
+   * This function sets the maximum rate which the codec may not exceed for a
+   * singel packet. The maximum rate is set in bits per second.
+   * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
+   * per 30 msec).
+   * It is possible to set a maximum rate between 32000 and 53400 bits per second.
+   *
+   * The rate limit is valid until next time the function is called.
+   *
+   * NOTE! Packet size will never go above the value set if calling
+   * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
+   *
+   * Input:
+   *      - ISAC_main_inst    : iSAC instance
+   *      - maxRateInBytes    : maximum rate in bits per second,
+   *                            valid values are 32000 to 53400 bits
+   *
+   * Return value             : 0 if sucessful
+   *                           -1 if error happens
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
+                                         WebRtc_Word32 maxRate);
+
+  /****************************************************************************
+   * WebRtcIsacfix_CreateInternal(...)
+   *
+   * This function creates the memory that is used to store data in the encoder
+   *
+   * Input:
+   *      - *ISAC_main_inst   : a pointer to the coder instance.
+   *
+   * Return value             : 0 - Ok
+   *                           -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_FreeInternal(...)
+   *
+   * This function frees the internal memory for storing encoder data.
+   *
+   * Input:
+   *      - ISAC_main_inst        : an ISAC instance.
+   *
+   * Return value                 :  0 - Ok
+   *                                -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_GetNewBitStream(...)
+   *
+   * This function returns encoded data, with the recieved bwe-index in the
+   * stream. It should always return a complete packet, i.e. only called once
+   * even for 60 msec frames
+   *
+   * Input:
+   *      - ISAC_main_inst    : ISAC instance.
+   *      - bweIndex          : index of bandwidth estimate to put in new bitstream
+   *      - scale             : factor for rate change (0.4 ~=> half the rate, 1 no change).
+   *
+   * Output:
+   *      - encoded           : the encoded data vector
+   *
+   * Return value             : >0 - Length (in bytes) of coded data
+   *                            -1 - Error
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
+                                              WebRtc_Word16          bweIndex,
+                                              float              scale,
+                                              WebRtc_Word16        *encoded);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_GetDownLinkBwIndex(...)
+   *
+   * This function returns index representing the Bandwidth estimate from
+   * other side to this side.
+   *
+   * Input:
+   *      - ISAC_main_inst    : iSAC struct
+   *
+   * Output:
+   *      - rateIndex         : Bandwidth estimate to transmit to other side.
+   *
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
+                                                 WebRtc_Word16*     rateIndex);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_UpdateUplinkBw(...)
+   *
+   * This function takes an index representing the Bandwidth estimate from
+   * this side to other side and updates BWE.
+   *
+   * Input:
+   *      - ISAC_main_inst    : iSAC struct
+   *      - rateIndex         : Bandwidth estimate from other side.
+   *
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
+                                             WebRtc_Word16     rateIndex);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_ReadBwIndex(...)
+   *
+   * This function returns the index of the Bandwidth estimate from the bitstream.
+   *
+   * Input:
+   *      - encoded           : Encoded bitstream
+   *
+   * Output:
+   *      - rateIndex         : Bandwidth estimate in bitstream
+   *
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_ReadBwIndex(const WebRtc_Word16* encoded,
+                                          WebRtc_Word16* rateIndex);
+
+
+  /****************************************************************************
+   * WebRtcIsacfix_GetNewFrameLen(...)
+   *
+   * This function return the next frame length (in samples) of iSAC.
+   *
+   * Input:
+   *      -ISAC_main_inst     : iSAC instance
+   *
+   * Return value             : frame lenght in samples
+   */
+
+  WebRtc_Word16 WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_INTERFACE_ISACFIX_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/Android.mk b/src/modules/audio_coding/codecs/isac/fix/source/Android.mk
new file mode 100644
index 0000000..bd2a91d
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/Android.mk
@@ -0,0 +1,149 @@
+# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS.  All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+#############################
+# Build the non-neon library.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+include $(LOCAL_PATH)/../../../../../../../android-webrtc.mk
+
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := libwebrtc_isacfix
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := \
+    arith_routines.c \
+    arith_routines_hist.c \
+    arith_routines_logist.c \
+    bandwidth_estimator.c \
+    decode.c \
+    decode_bwe.c \
+    decode_plc.c \
+    encode.c \
+    entropy_coding.c \
+    fft.c \
+    filterbank_tables.c \
+    filterbanks.c \
+    filters.c \
+    initialize.c \
+    isacfix.c \
+    lattice.c \
+    lpc_masking_model.c \
+    lpc_tables.c \
+    pitch_estimator.c \
+    pitch_filter.c \
+    pitch_gain_tables.c \
+    pitch_lag_tables.c \
+    spectrum_ar_model_tables.c \
+    transform.c
+
+ifeq ($(ARCH_ARM_HAVE_ARMV7A),true)
+# Using .S (instead of .s) extention is to include a C header file in assembly.
+LOCAL_SRC_FILES += \
+    lattice_armv7.S \
+    pitch_filter_armv6.S
+else
+LOCAL_SRC_FILES += \
+    lattice_c.c
+endif
+
+# Flags passed to both C and C++ files.
+LOCAL_CFLAGS := \
+    $(MY_WEBRTC_COMMON_DEFS)
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/../interface \
+    $(LOCAL_PATH)/../../../../../.. \
+    $(LOCAL_PATH)/../../../../../../common_audio/signal_processing/include
+
+LOCAL_STATIC_LIBRARIES += libwebrtc_system_wrappers
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libdl \
+    libstlport
+
+ifndef NDK_ROOT
+include external/stlport/libstlport.mk
+endif
+include $(BUILD_STATIC_LIBRARY)
+
+#########################
+# Build the neon library.
+ifeq ($(WEBRTC_BUILD_NEON_LIBS),true)
+
+include $(CLEAR_VARS)
+
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+LOCAL_MODULE := libwebrtc_isacfix_neon
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := \
+    filters_neon.c \
+    lattice_neon.S \
+    lpc_masking_model_neon.S
+
+# Flags passed to both C and C++ files.
+LOCAL_CFLAGS := \
+    $(MY_WEBRTC_COMMON_DEFS) \
+    -mfpu=neon \
+    -mfloat-abi=softfp \
+    -flax-vector-conversions
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/../interface \
+    $(LOCAL_PATH)/../../../../../.. \
+    $(LOCAL_PATH)/../../../../../../common_audio/signal_processing/include
+
+
+ifndef NDK_ROOT
+include external/stlport/libstlport.mk
+endif
+include $(BUILD_STATIC_LIBRARY)
+
+endif # ifeq ($(WEBRTC_BUILD_NEON_LIBS),true)
+
+###########################
+# isac test app
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_SRC_FILES:= ../test/kenny.c
+
+# Flags passed to both C and C++ files.
+LOCAL_CFLAGS := $(MY_WEBRTC_COMMON_DEFS)
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/../interface \
+    $(LOCAL_PATH)/../../../../../..
+
+LOCAL_STATIC_LIBRARIES := \
+    libwebrtc_isacfix \
+    libwebrtc_spl \
+    libwebrtc_system_wrappers
+
+ifeq ($(WEBRTC_BUILD_NEON_LIBS),true)
+LOCAL_STATIC_LIBRARIES += \
+    libwebrtc_isacfix_neon
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+    libutils
+
+LOCAL_MODULE:= webrtc_isac_test
+
+ifdef NDK_ROOT
+include $(BUILD_EXECUTABLE)
+else
+include $(BUILD_NATIVE_TEST)
+endif
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/arith_routines.c b/src/modules/audio_coding/codecs/isac/fix/source/arith_routines.c
new file mode 100644
index 0000000..ee62bad
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/arith_routines.c
@@ -0,0 +1,124 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * arith_routins.c
+ *
+ * This C file contains a function for finalizing the bitstream
+ * after arithmetic coding.
+ *
+ */
+
+#include "arith_routins.h"
+
+
+/****************************************************************************
+ * WebRtcIsacfix_EncTerminate(...)
+ *
+ * Final call to the arithmetic coder for an encoder call. This function
+ * terminates and return byte stream.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *
+ * Return value             : number of bytes in the stream
+ */
+WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData)
+{
+  WebRtc_UWord16 *streamPtr;
+  WebRtc_UWord16 negCarry;
+
+  /* point to the right place in the stream buffer */
+  streamPtr = streamData->stream + streamData->stream_index;
+
+  /* find minimum length (determined by current interval width) */
+  if ( streamData->W_upper > 0x01FFFFFF )
+  {
+    streamData->streamval += 0x01000000;
+
+    /* if result is less than the added value we must take care of the carry */
+    if (streamData->streamval < 0x01000000)
+    {
+      /* propagate carry */
+      if (streamData->full == 0) {
+        /* Add value to current value */
+        negCarry = *streamPtr;
+        negCarry += 0x0100;
+        *streamPtr = negCarry;
+
+        /* if value is too big, propagate carry to next byte, and so on */
+        while (!(negCarry))
+        {
+          negCarry = *--streamPtr;
+          negCarry++;
+          *streamPtr = negCarry;
+        }
+      } else {
+        /* propagate carry by adding one to the previous byte in the
+         * stream if that byte is 0xFFFF we need to propagate the carry
+         * furhter back in the stream */
+        while ( !(++(*--streamPtr)) );
+      }
+
+      /* put pointer back to the old value */
+      streamPtr = streamData->stream + streamData->stream_index;
+    }
+    /* write remaining data to bitstream, if "full == 0" first byte has data */
+    if (streamData->full == 0) {
+      *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
+      streamData->full = 1;
+    } else {
+      *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
+          WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
+      streamData->full = 0;
+    }
+  }
+  else
+  {
+    streamData->streamval += 0x00010000;
+
+    /* if result is less than the added value we must take care of the carry */
+    if (streamData->streamval < 0x00010000)
+    {
+      /* propagate carry */
+      if (streamData->full == 0) {
+        /* Add value to current value */
+        negCarry = *streamPtr;
+        negCarry += 0x0100;
+        *streamPtr = negCarry;
+
+        /* if value to big, propagate carry to next byte, and so on */
+        while (!(negCarry))
+        {
+          negCarry = *--streamPtr;
+          negCarry++;
+          *streamPtr = negCarry;
+        }
+      } else {
+        /* Add carry to previous byte */
+        while ( !(++(*--streamPtr)) );
+      }
+
+      /* put pointer back to the old value */
+      streamPtr = streamData->stream + streamData->stream_index;
+    }
+    /* write remaining data (2 bytes) to bitstream */
+    if (streamData->full) {
+      *streamPtr++ = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 16);
+    } else {
+      *streamPtr++ |= (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
+      *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 8)
+          & 0xFF00;
+    }
+  }
+
+  /* calculate stream length in bytes */
+  return (((streamPtr - streamData->stream)<<1) + !(streamData->full));
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c b/src/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c
new file mode 100644
index 0000000..14f1add
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/arith_routines_hist.c
@@ -0,0 +1,404 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * arith_routinshist.c
+ *
+ * This C file contains arithmetic encoding and decoding.
+ *
+ */
+
+#include "arith_routins.h"
+
+
+/****************************************************************************
+ * WebRtcIsacfix_EncHistMulti(...)
+ *
+ * Encode the histogram interval
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - data              : data vector
+ *      - cdf               : array of cdf arrays
+ *      - lenData           : data vector length
+ *
+ * Return value             : 0 if ok
+ *                            <0 if error detected
+ */
+int WebRtcIsacfix_EncHistMulti(Bitstr_enc *streamData,
+                              const WebRtc_Word16 *data,
+                              const WebRtc_UWord16 **cdf,
+                              const WebRtc_Word16 lenData)
+{
+  WebRtc_UWord32 W_lower;
+  WebRtc_UWord32 W_upper;
+  WebRtc_UWord32 W_upper_LSB;
+  WebRtc_UWord32 W_upper_MSB;
+  WebRtc_UWord16 *streamPtr;
+  WebRtc_UWord16 negCarry;
+  WebRtc_UWord16 *maxStreamPtr;
+  WebRtc_UWord16 *streamPtrCarry;
+  WebRtc_UWord32 cdfLo;
+  WebRtc_UWord32 cdfHi;
+  int k;
+
+
+  /* point to beginning of stream buffer
+   * and set maximum streamPtr value */
+  streamPtr = streamData->stream + streamData->stream_index;
+  maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1;
+
+  W_upper = streamData->W_upper;
+
+  for (k = lenData; k > 0; k--)
+  {
+    /* fetch cdf_lower and cdf_upper from cdf tables */
+    cdfLo = (WebRtc_UWord32) *(*cdf + (WebRtc_UWord32)*data);
+    cdfHi = (WebRtc_UWord32) *(*cdf++ + (WebRtc_UWord32)*data++ + 1);
+
+    /* update interval */
+    W_upper_LSB = W_upper & 0x0000FFFF;
+    W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
+    W_lower = WEBRTC_SPL_UMUL(W_upper_MSB, cdfLo);
+    W_lower += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfLo);
+    W_upper = WEBRTC_SPL_UMUL(W_upper_MSB, cdfHi);
+    W_upper += WEBRTC_SPL_UMUL_RSFT16(W_upper_LSB, cdfHi);
+
+    /* shift interval such that it begins at zero */
+    W_upper -= ++W_lower;
+
+    /* add integer to bitstream */
+    streamData->streamval += W_lower;
+
+    /* handle carry */
+    if (streamData->streamval < W_lower)
+    {
+      /* propagate carry */
+      streamPtrCarry = streamPtr;
+      if (streamData->full == 0) {
+        negCarry = *streamPtrCarry;
+        negCarry += 0x0100;
+        *streamPtrCarry = negCarry;
+        while (!(negCarry))
+        {
+          negCarry = *--streamPtrCarry;
+          negCarry++;
+          *streamPtrCarry = negCarry;
+        }
+      } else {
+        while ( !(++(*--streamPtrCarry)) );
+      }
+    }
+
+    /* renormalize interval, store most significant byte of streamval and update streamval
+     * W_upper < 2^24 */
+    while ( !(W_upper & 0xFF000000) )
+    {
+      W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
+      if (streamData->full == 0) {
+        *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24);
+        streamData->full = 1;
+      } else {
+        *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_W32(
+            WEBRTC_SPL_RSHIFT_W32(streamData->streamval, 24), 8);
+        streamData->full = 0;
+      }
+
+      if( streamPtr > maxStreamPtr ) {
+        return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
+      }
+      streamData->streamval = WEBRTC_SPL_LSHIFT_W32(streamData->streamval, 8);
+    }
+  }
+
+  /* calculate new stream_index */
+  streamData->stream_index = streamPtr - streamData->stream;
+  streamData->W_upper = W_upper;
+
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecHistBisectMulti(...)
+ *
+ * Function to decode more symbols from the arithmetic bytestream, using
+ * method of bisection cdf tables should be of size 2^k-1 (which corresponds
+ * to an alphabet size of 2^k-2)
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - cdf               : array of cdf arrays
+ *      - cdfSize           : array of cdf table sizes+1 (power of two: 2^k)
+ *      - lenData           : data vector length
+ *
+ * Output:
+ *      - data              : data vector
+ *
+ * Return value             : number of bytes in the stream
+ *                            <0 if error detected
+ */
+WebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti(WebRtc_Word16 *data,
+                                              Bitstr_dec *streamData,
+                                              const WebRtc_UWord16 **cdf,
+                                              const WebRtc_UWord16 *cdfSize,
+                                              const WebRtc_Word16 lenData)
+{
+  WebRtc_UWord32    W_lower = 0;
+  WebRtc_UWord32    W_upper;
+  WebRtc_UWord32    W_tmp;
+  WebRtc_UWord32    W_upper_LSB;
+  WebRtc_UWord32    W_upper_MSB;
+  WebRtc_UWord32    streamval;
+  const WebRtc_UWord16 *streamPtr;
+  const WebRtc_UWord16 *cdfPtr;
+  WebRtc_Word16     sizeTmp;
+  int             k;
+
+
+  streamPtr = streamData->stream + streamData->stream_index;
+  W_upper = streamData->W_upper;
+
+  /* Error check: should not be possible in normal operation */
+  if (W_upper == 0) {
+    return -2;
+  }
+
+  /* first time decoder is called for this stream */
+  if (streamData->stream_index == 0)
+  {
+    /* read first word from bytestream */
+    streamval = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)*streamPtr++, 16);
+    streamval |= *streamPtr++;
+  } else {
+    streamval = streamData->streamval;
+  }
+
+  for (k = lenData; k > 0; k--)
+  {
+    /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
+    W_upper_LSB = W_upper & 0x0000FFFF;
+    W_upper_MSB = WEBRTC_SPL_RSHIFT_W32(W_upper, 16);
+
+    /* start halfway the cdf range */
+    sizeTmp = WEBRTC_SPL_RSHIFT_W16(*cdfSize++, 1);
+    cdfPtr = *cdf + (sizeTmp - 1);
+
+    /* method of bisection */
+    for ( ;; )
+    {
+      W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
+      W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
+      sizeTmp = WEBRTC_SPL_RSHIFT_W16(sizeTmp, 1);
+      if (sizeTmp == 0) {
+        break;
+      }
+
+      if (streamval > W_tmp)
+      {
+        W_lower = W_tmp;
+        cdfPtr += sizeTmp;
+      } else {
+        W_upper = W_tmp;
+        cdfPtr -= sizeTmp;
+      }
+    }
+    if (streamval > W_tmp)
+    {
+      W_lower = W_tmp;
+      *data++ = cdfPtr - *cdf++;
+    } else {
+      W_upper = W_tmp;
+      *data++ = cdfPtr - *cdf++ - 1;
+    }
+
+    /* shift interval to start at zero */
+    W_upper -= ++W_lower;
+
+    /* add integer to bitstream */
+    streamval -= W_lower;
+
+    /* renormalize interval and update streamval */
+    /* W_upper < 2^24 */
+    while ( !(W_upper & 0xFF000000) )
+    {
+      /* read next byte from stream */
+      if (streamData->full == 0) {
+        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) |
+            (*streamPtr++ & 0x00FF);
+        streamData->full = 1;
+      } else {
+        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) |
+            WEBRTC_SPL_RSHIFT_W16(*streamPtr, 8);
+        streamData->full = 0;
+      }
+      W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
+    }
+
+
+    /* Error check: should not be possible in normal operation */
+    if (W_upper == 0) {
+      return -2;
+    }
+
+  }
+
+  streamData->stream_index = streamPtr - streamData->stream;
+  streamData->W_upper = W_upper;
+  streamData->streamval = streamval;
+
+  if ( W_upper > 0x01FFFFFF ) {
+    return (streamData->stream_index*2 - 3 + !streamData->full);
+  } else {
+    return (streamData->stream_index*2 - 2 + !streamData->full);
+  }
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecHistOneStepMulti(...)
+ *
+ * Function to decode more symbols from the arithmetic bytestream, taking
+ * single step up or down at a time.
+ * cdf tables can be of arbitrary size, but large tables may take a lot of
+ * iterations.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - cdf               : array of cdf arrays
+ *      - initIndex         : vector of initial cdf table search entries
+ *      - lenData           : data vector length
+ *
+ * Output:
+ *      - data              : data vector
+ *
+ * Return value             : number of bytes in original stream
+ *                            <0 if error detected
+ */
+WebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti(WebRtc_Word16 *data,
+                                               Bitstr_dec *streamData,
+                                               const WebRtc_UWord16 **cdf,
+                                               const WebRtc_UWord16 *initIndex,
+                                               const WebRtc_Word16 lenData)
+{
+  WebRtc_UWord32    W_lower;
+  WebRtc_UWord32    W_upper;
+  WebRtc_UWord32    W_tmp;
+  WebRtc_UWord32    W_upper_LSB;
+  WebRtc_UWord32    W_upper_MSB;
+  WebRtc_UWord32    streamval;
+  const WebRtc_UWord16 *streamPtr;
+  const WebRtc_UWord16 *cdfPtr;
+  int             k;
+
+
+  streamPtr = streamData->stream + streamData->stream_index;
+  W_upper = streamData->W_upper;
+  /* Error check: Should not be possible in normal operation */
+  if (W_upper == 0) {
+    return -2;
+  }
+
+  /* Check if it is the first time decoder is called for this stream */
+  if (streamData->stream_index == 0)
+  {
+    /* read first word from bytestream */
+    streamval = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16);
+    streamval |= *streamPtr++;
+  } else {
+    streamval = streamData->streamval;
+  }
+
+  for (k = lenData; k > 0; k--)
+  {
+    /* find the integer *data for which streamval lies in [W_lower+1, W_upper] */
+    W_upper_LSB = W_upper & 0x0000FFFF;
+    W_upper_MSB = WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
+
+    /* start at the specified table entry */
+    cdfPtr = *cdf + (*initIndex++);
+    W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
+    W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
+
+    if (streamval > W_tmp)
+    {
+      for ( ;; )
+      {
+        W_lower = W_tmp;
+
+        /* range check */
+        if (cdfPtr[0] == 65535) {
+          return -3;
+        }
+
+        W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *++cdfPtr);
+        W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
+
+        if (streamval <= W_tmp) {
+          break;
+        }
+      }
+      W_upper = W_tmp;
+      *data++ = cdfPtr - *cdf++ - 1;
+    } else {
+      for ( ;; )
+      {
+        W_upper = W_tmp;
+        --cdfPtr;
+
+        /* range check */
+        if (cdfPtr < *cdf) {
+          return -3;
+        }
+
+        W_tmp = WEBRTC_SPL_UMUL_32_16(W_upper_MSB, *cdfPtr);
+        W_tmp += WEBRTC_SPL_UMUL_32_16_RSFT16(W_upper_LSB, *cdfPtr);
+
+        if (streamval > W_tmp) {
+          break;
+        }
+      }
+      W_lower = W_tmp;
+      *data++ = cdfPtr - *cdf++;
+    }
+
+    /* shift interval to start at zero */
+    W_upper -= ++W_lower;
+
+    /* add integer to bitstream */
+    streamval -= W_lower;
+
+    /* renormalize interval and update streamval */
+    /* W_upper < 2^24 */
+    while ( !(W_upper & 0xFF000000) )
+    {
+      /* read next byte from stream */
+      if (streamData->full == 0) {
+        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr++ & 0x00FF);
+        streamData->full = 1;
+      } else {
+        streamval = WEBRTC_SPL_LSHIFT_W32(streamval, 8) | (*streamPtr >> 8);
+        streamData->full = 0;
+      }
+      W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
+    }
+  }
+
+  streamData->stream_index = streamPtr - streamData->stream;
+  streamData->W_upper = W_upper;
+  streamData->streamval = streamval;
+
+  /* find number of bytes in original stream (determined by current interval width) */
+  if ( W_upper > 0x01FFFFFF ) {
+    return (streamData->stream_index*2 - 3 + !streamData->full);
+  } else {
+    return (streamData->stream_index*2 - 2 + !streamData->full);
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c b/src/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
new file mode 100644
index 0000000..39c437e
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
@@ -0,0 +1,404 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * arith_routinslogist.c
+ *
+ * This C file contains arithmetic encode and decode logistic
+ *
+ */
+
+#include "arith_routins.h"
+
+
+/* Tables for piecewise linear cdf functions: y = k*x */
+
+/* x Points for function piecewise() in Q15 */
+static const WebRtc_Word32 kHistEdges[51] = {
+  -327680, -314573, -301466, -288359, -275252, -262144, -249037, -235930, -222823, -209716,
+  -196608, -183501, -170394, -157287, -144180, -131072, -117965, -104858,  -91751,  -78644,
+  -65536,  -52429,  -39322,  -26215,  -13108,       0,   13107,   26214,   39321,   52428,
+  65536,   78643,   91750,  104857,  117964,  131072,  144179,  157286,  170393,  183500,
+  196608,  209715,  222822,  235929,  249036,  262144,  275251,  288358,  301465,  314572,
+  327680
+};
+
+
+/* k Points for function piecewise() in Q0 */
+static const WebRtc_UWord16 kCdfSlope[51] = {
+  5,    5,     5,     5,     5,     5,     5,     5,    5,    5,
+  5,    5,    13,    23,    47,    87,   154,   315,  700, 1088,
+  2471, 6064, 14221, 21463, 36634, 36924, 19750, 13270, 5806, 2312,
+  1095,  660,   316,   145,    86,    41,    32,     5,    5,    5,
+  5,    5,     5,     5,     5,     5,     5,     5,    5,    2,
+  0
+};
+
+/* y Points for function piecewise() in Q0 */
+static const WebRtc_UWord16 kCdfLogistic[51] = {
+  0,     2,     4,     6,     8,    10,    12,    14,    16,    18,
+  20,    22,    24,    29,    38,    57,    92,   153,   279,   559,
+  994,  1983,  4408, 10097, 18682, 33336, 48105, 56005, 61313, 63636,
+  64560, 64998, 65262, 65389, 65447, 65481, 65497, 65510, 65512, 65514,
+  65516, 65518, 65520, 65522, 65524, 65526, 65528, 65530, 65532, 65534,
+  65535
+};
+
+
+/****************************************************************************
+ * WebRtcIsacfix_Piecewise(...)
+ *
+ * Piecewise linear function
+ *
+ * Input:
+ *      - xinQ15           : input value x in Q15
+ *
+ * Return value            : korresponding y-value in Q0
+ */
+
+
+static __inline WebRtc_UWord16 WebRtcIsacfix_Piecewise(WebRtc_Word32 xinQ15) {
+  WebRtc_Word32 ind;
+  WebRtc_Word32 qtmp1;
+  WebRtc_UWord16 qtmp2;
+
+  /* Find index for x-value */
+  qtmp1 = WEBRTC_SPL_SAT(kHistEdges[50],xinQ15,kHistEdges[0]);
+  ind = WEBRTC_SPL_MUL(5, qtmp1 - kHistEdges[0]);
+  ind =  WEBRTC_SPL_RSHIFT_W32(ind, 16);
+
+  /* Calculate corresponding y-value ans return*/
+  qtmp1 = qtmp1 - kHistEdges[ind];
+  qtmp2 = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(
+      WEBRTC_SPL_UMUL_32_16(qtmp1,kCdfSlope[ind]), 15);
+  return (kCdfLogistic[ind] + qtmp2);
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_EncLogisticMulti2(...)
+ *
+ * Arithmetic coding of spectrum.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - dataQ7            : data vector in Q7
+ *      - envQ8             : side info vector defining the width of the pdf
+ *                            in Q8
+ *      - lenData           : data vector length
+ *
+ * Return value             :  0 if ok,
+ *                            <0 otherwise.
+ */
+int WebRtcIsacfix_EncLogisticMulti2(Bitstr_enc *streamData,
+                                   WebRtc_Word16 *dataQ7,
+                                   const WebRtc_UWord16 *envQ8,
+                                   const WebRtc_Word16 lenData)
+{
+  WebRtc_UWord32 W_lower;
+  WebRtc_UWord32 W_upper;
+  WebRtc_UWord16 W_upper_LSB;
+  WebRtc_UWord16 W_upper_MSB;
+  WebRtc_UWord16 *streamPtr;
+  WebRtc_UWord16 *maxStreamPtr;
+  WebRtc_UWord16 *streamPtrCarry;
+  WebRtc_UWord16 negcarry;
+  WebRtc_UWord32 cdfLo;
+  WebRtc_UWord32 cdfHi;
+  int k;
+
+  /* point to beginning of stream buffer
+   * and set maximum streamPtr value */
+  streamPtr = streamData->stream + streamData->stream_index;
+  maxStreamPtr = streamData->stream + STREAM_MAXW16_60MS - 1;
+  W_upper = streamData->W_upper;
+
+  for (k = 0; k < lenData; k++)
+  {
+    /* compute cdf_lower and cdf_upper by evaluating the
+     * WebRtcIsacfix_Piecewise linear cdf */
+    cdfLo = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8));
+    cdfHi = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8));
+
+    /* test and clip if probability gets too small */
+    while ((cdfLo + 1) >= cdfHi) {
+      /* clip */
+      if (*dataQ7 > 0) {
+        *dataQ7 -= 128;
+        cdfHi = cdfLo;
+        cdfLo = WebRtcIsacfix_Piecewise(
+            WEBRTC_SPL_MUL_16_U16(*dataQ7 - 64, *envQ8));
+      } else {
+        *dataQ7 += 128;
+        cdfLo = cdfHi;
+        cdfHi = WebRtcIsacfix_Piecewise(
+            WEBRTC_SPL_MUL_16_U16(*dataQ7 + 64, *envQ8));
+      }
+    }
+
+    dataQ7++;
+    /* increment only once per 4 iterations */
+    envQ8 += (k & 1) & (k >> 1);
+
+
+    /* update interval */
+    W_upper_LSB = (WebRtc_UWord16)W_upper;
+    W_upper_MSB = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
+    W_lower = WEBRTC_SPL_UMUL_32_16(cdfLo, W_upper_MSB);
+    W_lower += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfLo, W_upper_LSB);
+    W_upper = WEBRTC_SPL_UMUL_32_16(cdfHi, W_upper_MSB);
+    W_upper += WEBRTC_SPL_UMUL_32_16_RSFT16(cdfHi, W_upper_LSB);
+
+    /* shift interval such that it begins at zero */
+    W_upper -= ++W_lower;
+
+    /* add integer to bitstream */
+    streamData->streamval += W_lower;
+
+    /* handle carry */
+    if (streamData->streamval < W_lower)
+    {
+      /* propagate carry */
+      streamPtrCarry = streamPtr;
+      if (streamData->full == 0) {
+        negcarry = *streamPtrCarry;
+        negcarry += 0x0100;
+        *streamPtrCarry = negcarry;
+        while (!(negcarry))
+        {
+          negcarry = *--streamPtrCarry;
+          negcarry++;
+          *streamPtrCarry = negcarry;
+        }
+      } else {
+        while (!(++(*--streamPtrCarry)));
+      }
+    }
+
+    /* renormalize interval, store most significant byte of streamval and update streamval
+     * W_upper < 2^24 */
+    while ( !(W_upper & 0xFF000000) )
+    {
+      W_upper = WEBRTC_SPL_LSHIFT_U32(W_upper, 8);
+      if (streamData->full == 0) {
+        *streamPtr++ += (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32(
+            streamData->streamval, 24);
+        streamData->full = 1;
+      } else {
+        *streamPtr = (WebRtc_UWord16) WEBRTC_SPL_LSHIFT_U32(
+            WEBRTC_SPL_RSHIFT_U32(streamData->streamval, 24), 8);
+        streamData->full = 0;
+      }
+
+      if( streamPtr > maxStreamPtr )
+        return -ISAC_DISALLOWED_BITSTREAM_LENGTH;
+
+      streamData->streamval = WEBRTC_SPL_LSHIFT_U32(streamData->streamval, 8);
+    }
+  }
+
+  /* calculate new stream_index */
+  streamData->stream_index = streamPtr - streamData->stream;
+  streamData->W_upper = W_upper;
+
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecLogisticMulti2(...)
+ *
+ * Arithmetic decoding of spectrum.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - envQ8             : side info vector defining the width of the pdf
+ *                            in Q8
+ *      - lenData           : data vector length
+ *
+ * Input/Output:
+ *      - dataQ7            : input: dither vector, output: data vector
+ *
+ * Return value             : number of bytes in the stream so far
+ *                            -1 if error detected
+ */
+WebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2(WebRtc_Word16 *dataQ7,
+                                             Bitstr_dec *streamData,
+                                             const WebRtc_Word32 *envQ8,
+                                             const WebRtc_Word16 lenData)
+{
+  WebRtc_UWord32    W_lower;
+  WebRtc_UWord32    W_upper;
+  WebRtc_UWord32    W_tmp;
+  WebRtc_UWord16    W_upper_LSB;
+  WebRtc_UWord16    W_upper_MSB;
+  WebRtc_UWord32    streamVal;
+  WebRtc_UWord16    cdfTmp;
+  WebRtc_Word32     res;
+  WebRtc_Word32     inSqrt;
+  WebRtc_Word32     newRes;
+  const WebRtc_UWord16 *streamPtr;
+  WebRtc_Word16     candQ7;
+  WebRtc_Word16     envCount;
+  WebRtc_UWord16    tmpARSpecQ8 = 0;
+  int             k, i;
+
+
+  /* point to beginning of stream buffer */
+  streamPtr = streamData->stream + streamData->stream_index;
+  W_upper = streamData->W_upper;
+
+  /* Check if it is first time decoder is called for this stream */
+  if (streamData->stream_index == 0)
+  {
+    /* read first word from bytestream */
+    streamVal = WEBRTC_SPL_LSHIFT_U32(*streamPtr++, 16);
+    streamVal |= *streamPtr++;
+
+  } else {
+    streamVal = streamData->streamval;
+  }
+
+
+  res = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1,
+                               WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(envQ8[0]), 1));
+  envCount = 0;
+
+  /* code assumes lenData%4 == 0 */
+  for (k = 0; k < lenData; k += 4)
+  {
+    int k4;
+
+    /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */
+    inSqrt = envQ8[envCount];
+    i = 10;
+
+    /* For safty reasons */
+    if (inSqrt < 0)
+      inSqrt=-inSqrt;
+
+    newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1);
+    do
+    {
+      res = newRes;
+      newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1);
+    } while (newRes != res && i-- > 0);
+
+    tmpARSpecQ8 = (WebRtc_UWord16)newRes;
+
+    for(k4 = 0; k4 < 4; k4++)
+    {
+      /* find the integer *data for which streamVal lies in [W_lower+1, W_upper] */
+      W_upper_LSB = (WebRtc_UWord16) (W_upper & 0x0000FFFF);
+      W_upper_MSB = (WebRtc_UWord16) WEBRTC_SPL_RSHIFT_U32(W_upper, 16);
+
+      /* find first candidate by inverting the logistic cdf
+       * Input dither value collected from io-stream */
+      candQ7 = - *dataQ7 + 64;
+      cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
+
+      W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+      W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
+
+      if (streamVal > W_tmp)
+      {
+        W_lower = W_tmp;
+        candQ7 += 128;
+        cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
+
+        W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+        W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
+
+        while (streamVal > W_tmp)
+        {
+          W_lower = W_tmp;
+          candQ7 += 128;
+          cdfTmp = WebRtcIsacfix_Piecewise(
+              WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
+
+          W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+          W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
+
+          /* error check */
+          if (W_lower == W_tmp) {
+            return -1;
+          }
+        }
+        W_upper = W_tmp;
+
+        /* Output value put in dataQ7: another sample decoded */
+        *dataQ7 = candQ7 - 64;
+      }
+      else
+      {
+        W_upper = W_tmp;
+        candQ7 -= 128;
+        cdfTmp = WebRtcIsacfix_Piecewise(WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
+
+        W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+        W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
+
+        while ( !(streamVal > W_tmp) )
+        {
+          W_upper = W_tmp;
+          candQ7 -= 128;
+          cdfTmp = WebRtcIsacfix_Piecewise(
+              WEBRTC_SPL_MUL_16_U16(candQ7, tmpARSpecQ8));
+
+          W_tmp = WEBRTC_SPL_UMUL_16_16(cdfTmp, W_upper_MSB);
+          W_tmp += WEBRTC_SPL_UMUL_16_16_RSFT16(cdfTmp, W_upper_LSB);
+
+          /* error check */
+          if (W_upper == W_tmp){
+            return -1;
+          }
+        }
+        W_lower = W_tmp;
+
+        /* Output value put in dataQ7: another sample decoded */
+        *dataQ7 = candQ7 + 64;
+      }
+
+      dataQ7++;
+
+      /* shift interval to start at zero */
+      W_upper -= ++W_lower;
+
+      /* add integer to bitstream */
+      streamVal -= W_lower;
+
+      /* renormalize interval and update streamVal
+       * W_upper < 2^24 */
+      while ( !(W_upper & 0xFF000000) )
+      {
+        /* read next byte from stream */
+        if (streamData->full == 0) {
+          streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | (*streamPtr++ & 0x00FF);
+          streamData->full = 1;
+        } else {
+          streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) |
+              WEBRTC_SPL_RSHIFT_U16(*streamPtr, 8);
+          streamData->full = 0;
+        }
+        W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
+      }
+    }
+    envCount++;
+  }
+
+  streamData->stream_index = streamPtr - streamData->stream;
+  streamData->W_upper = W_upper;
+  streamData->streamval = streamVal;
+
+  /* find number of bytes in original stream (determined by current interval width) */
+  if ( W_upper > 0x01FFFFFF )
+    return (streamData->stream_index*2 - 3 + !streamData->full);
+  else
+    return (streamData->stream_index*2 - 2 + !streamData->full);
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/arith_routins.h b/src/modules/audio_coding/codecs/isac/fix/source/arith_routins.h
new file mode 100644
index 0000000..9aa49da
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/arith_routins.h
@@ -0,0 +1,160 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * arith_routins.h
+ *
+ * Functions for arithmetic coding.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_
+
+#include "structs.h"
+
+
+/****************************************************************************
+ * WebRtcIsacfix_EncLogisticMulti2(...)
+ *
+ * Arithmetic coding of spectrum.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - dataQ7            : data vector in Q7
+ *      - envQ8             : side info vector defining the width of the pdf
+ *                            in Q8
+ *      - lenData           : data vector length
+ *
+ * Return value             :  0 if ok,
+ *                             <0 otherwise.
+ */
+int WebRtcIsacfix_EncLogisticMulti2(
+    Bitstr_enc *streamData,
+    WebRtc_Word16 *dataQ7,
+    const WebRtc_UWord16 *env,
+    const WebRtc_Word16 lenData);
+
+
+/****************************************************************************
+ * WebRtcIsacfix_EncTerminate(...)
+ *
+ * Final call to the arithmetic coder for an encoder call. This function
+ * terminates and return byte stream.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *
+ * Return value             : number of bytes in the stream
+ */
+WebRtc_Word16 WebRtcIsacfix_EncTerminate(Bitstr_enc *streamData);
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecLogisticMulti2(...)
+ *
+ * Arithmetic decoding of spectrum.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - envQ8             : side info vector defining the width of the pdf
+ *                            in Q8
+ *      - lenData           : data vector length
+ *
+ * Input/Output:
+ *      - dataQ7            : input: dither vector, output: data vector, in Q7
+ *
+ * Return value             : number of bytes in the stream so far
+ *                            <0 if error detected
+ */
+WebRtc_Word16 WebRtcIsacfix_DecLogisticMulti2(
+    WebRtc_Word16 *data,
+    Bitstr_dec *streamData,
+    const WebRtc_Word32 *env,
+    const WebRtc_Word16 lenData);
+
+
+/****************************************************************************
+ * WebRtcIsacfix_EncHistMulti(...)
+ *
+ * Encode the histogram interval
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - data              : data vector
+ *      - cdf               : array of cdf arrays
+ *      - lenData           : data vector length
+ *
+ * Return value             : 0 if ok
+ *                            <0 if error detected
+ */
+int WebRtcIsacfix_EncHistMulti(
+    Bitstr_enc *streamData,
+    const WebRtc_Word16 *data,
+    const WebRtc_UWord16 **cdf,
+    const WebRtc_Word16 lenData);
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecHistBisectMulti(...)
+ *
+ * Function to decode more symbols from the arithmetic bytestream, using
+ * method of bisection.
+ * C df tables should be of size 2^k-1 (which corresponds to an
+ * alphabet size of 2^k-2)
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - cdf               : array of cdf arrays
+ *      - cdfSize           : array of cdf table sizes+1 (power of two: 2^k)
+ *      - lenData           : data vector length
+ *
+ * Output:
+ *      - data              : data vector
+ *
+ * Return value             : number of bytes in the stream
+ *                            <0 if error detected
+ */
+WebRtc_Word16 WebRtcIsacfix_DecHistBisectMulti(
+    WebRtc_Word16 *data,
+    Bitstr_dec *streamData,
+    const WebRtc_UWord16 **cdf,
+    const WebRtc_UWord16 *cdfSize,
+    const WebRtc_Word16 lenData);
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecHistOneStepMulti(...)
+ *
+ * Function to decode more symbols from the arithmetic bytestream, taking
+ * single step up or down at a time.
+ * cdf tables can be of arbitrary size, but large tables may take a lot of
+ * iterations.
+ *
+ * Input:
+ *      - streamData        : in-/output struct containing bitstream
+ *      - cdf               : array of cdf arrays
+ *      - initIndex         : vector of initial cdf table search entries
+ *      - lenData           : data vector length
+ *
+ * Output:
+ *      - data              : data vector
+ *
+ * Return value             : number of bytes in original stream
+ *                            <0 if error detected
+ */
+WebRtc_Word16 WebRtcIsacfix_DecHistOneStepMulti(
+    WebRtc_Word16 *data,
+    Bitstr_dec *streamData,
+    const WebRtc_UWord16 **cdf,
+    const WebRtc_UWord16 *initIndex,
+    const WebRtc_Word16 lenData);
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ARITH_ROUTINS_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c b/src/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c
new file mode 100644
index 0000000..a274b66
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.c
@@ -0,0 +1,1022 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * bandwidth_estimator.c
+ *
+ * This file contains the code for the Bandwidth Estimator designed
+ * for iSAC.
+ *
+ * NOTE! Castings needed for C55, do not remove!
+ *
+ */
+
+#include "bandwidth_estimator.h"
+#include "settings.h"
+
+
+/* array of quantization levels for bottle neck info; Matlab code: */
+/* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
+static const WebRtc_Word16 kQRateTable[12] = {
+  10000, 11115, 12355, 13733, 15265, 16967,
+  18860, 20963, 23301, 25900, 28789, 32000
+};
+
+/* 0.1 times the values in the table kQRateTable */
+/* values are in Q16                                         */
+static const WebRtc_Word32 KQRate01[12] = {
+  65536000,  72843264,  80969728,  90000589,  100040704, 111194931,
+  123600896, 137383117, 152705434, 169738240, 188671590, 209715200
+};
+
+/* Bits per Bytes Seconds
+ * 8 bits/byte * 1000 msec/sec * 1/framelength (in msec)->bits/byte*sec
+ * frame length will either be 30 or 60 msec. 8738 is 1/60 in Q19 and 1/30 in Q18
+ * The following number is either in Q15 or Q14 depending on the current frame length */
+static const WebRtc_Word32 kBitsByteSec = 4369000;
+
+/* Received header rate. First value is for 30 ms packets and second for 60 ms */
+static const WebRtc_Word16 kRecHeaderRate[2] = {
+  9333, 4666
+};
+
+/* Inverted minimum and maximum bandwidth in Q30.
+   minBwInv 30 ms, maxBwInv 30 ms,
+   minBwInv 60 ms, maxBwInv 69 ms
+*/
+static const WebRtc_Word32 kInvBandwidth[4] = {
+  55539, 25978,
+  73213, 29284
+};
+
+/* Number of samples in 25 msec */
+static const WebRtc_Word32 kSamplesIn25msec = 400;
+
+
+/****************************************************************************
+ * WebRtcIsacfix_InitBandwidthEstimator(...)
+ *
+ * This function initializes the struct for the bandwidth estimator
+ *
+ * Input/Output:
+ *      - bweStr        : Struct containing bandwidth information.
+ *
+ * Return value            : 0
+ */
+WebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bweStr)
+{
+  bweStr->prevFrameSizeMs       = INIT_FRAME_LEN;
+  bweStr->prevRtpNumber         = 0;
+  bweStr->prevSendTime          = 0;
+  bweStr->prevArrivalTime       = 0;
+  bweStr->prevRtpRate           = 1;
+  bweStr->lastUpdate            = 0;
+  bweStr->lastReduction         = 0;
+  bweStr->countUpdates          = -9;
+
+  /* INIT_BN_EST = 20000
+   * INIT_BN_EST_Q7 = 2560000
+   * INIT_HDR_RATE = 4666
+   * INIT_REC_BN_EST_Q5 = 789312
+   *
+   * recBwInv = 1/(INIT_BN_EST + INIT_HDR_RATE) in Q30
+   * recBwAvg = INIT_BN_EST + INIT_HDR_RATE in Q5
+   */
+  bweStr->recBwInv              = 43531;
+  bweStr->recBw                 = INIT_BN_EST;
+  bweStr->recBwAvgQ             = INIT_BN_EST_Q7;
+  bweStr->recBwAvg              = INIT_REC_BN_EST_Q5;
+  bweStr->recJitter             = (WebRtc_Word32) 327680;   /* 10 in Q15 */
+  bweStr->recJitterShortTerm    = 0;
+  bweStr->recJitterShortTermAbs = (WebRtc_Word32) 40960;    /* 5 in Q13 */
+  bweStr->recMaxDelay           = (WebRtc_Word32) 10;
+  bweStr->recMaxDelayAvgQ       = (WebRtc_Word32) 5120;     /* 10 in Q9 */
+  bweStr->recHeaderRate         = INIT_HDR_RATE;
+  bweStr->countRecPkts          = 0;
+  bweStr->sendBwAvg             = INIT_BN_EST_Q7;
+  bweStr->sendMaxDelayAvg       = (WebRtc_Word32) 5120;     /* 10 in Q9 */
+
+  bweStr->countHighSpeedRec     = 0;
+  bweStr->highSpeedRec          = 0;
+  bweStr->countHighSpeedSent    = 0;
+  bweStr->highSpeedSend         = 0;
+  bweStr->inWaitPeriod          = 0;
+
+  /* Find the inverse of the max bw and min bw in Q30
+   *  (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30
+   *  (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30
+   */
+  bweStr->maxBwInv              = kInvBandwidth[3];
+  bweStr->minBwInv              = kInvBandwidth[2];
+
+  return 0;
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_UpdateUplinkBwImpl(...)
+ *
+ * This function updates bottle neck rate received from other side in payload
+ * and calculates a new bottle neck to send to the other side.
+ *
+ * Input/Output:
+ *      - bweStr           : struct containing bandwidth information.
+ *      - rtpNumber        : value from RTP packet, from NetEq
+ *      - frameSize        : length of signal frame in ms, from iSAC decoder
+ *      - sendTime         : value in RTP header giving send time in samples
+ *      - arrivalTime      : value given by timeGetTime() time of arrival in
+ *                           samples of packet from NetEq
+ *      - pksize           : size of packet in bytes, from NetEq
+ *      - Index            : integer (range 0...23) indicating bottle neck &
+ *                           jitter as estimated by other side
+ *
+ * Return value            : 0 if everything went fine,
+ *                           -1 otherwise
+ */
+WebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
+                                               const WebRtc_UWord16 rtpNumber,
+                                               const WebRtc_Word16  frameSize,
+                                               const WebRtc_UWord32 sendTime,
+                                               const WebRtc_UWord32 arrivalTime,
+                                               const WebRtc_Word16  pksize,
+                                               const WebRtc_UWord16 Index)
+{
+  WebRtc_UWord16  weight = 0;
+  WebRtc_UWord32  currBwInv = 0;
+  WebRtc_UWord16  recRtpRate;
+  WebRtc_UWord32  arrTimeProj;
+  WebRtc_Word32   arrTimeDiff;
+  WebRtc_Word32   arrTimeNoise;
+  WebRtc_Word32   arrTimeNoiseAbs;
+  WebRtc_Word32   sendTimeDiff;
+
+  WebRtc_Word32 delayCorrFactor = DELAY_CORRECTION_MED;
+  WebRtc_Word32 lateDiff = 0;
+  WebRtc_Word16 immediateSet = 0;
+  WebRtc_Word32 frameSizeSampl;
+
+  WebRtc_Word32  temp;
+  WebRtc_Word32  msec;
+  WebRtc_UWord32 exponent;
+  WebRtc_UWord32 reductionFactor;
+  WebRtc_UWord32 numBytesInv;
+  WebRtc_Word32  sign;
+
+  WebRtc_UWord32 byteSecondsPerBit;
+  WebRtc_UWord32 tempLower;
+  WebRtc_UWord32 tempUpper;
+  WebRtc_Word32 recBwAvgInv;
+  WebRtc_Word32 numPktsExpected;
+
+  WebRtc_Word16 errCode;
+
+  /* UPDATE ESTIMATES FROM OTHER SIDE */
+
+  /* The function also checks if Index has a valid value */
+  errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index);
+  if (errCode <0) {
+    return(errCode);
+  }
+
+
+  /* UPDATE ESTIMATES ON THIS SIDE */
+
+  /* Bits per second per byte * 1/30 or 1/60 */
+  if (frameSize == 60) {
+    /* If frameSize changed since last call, from 30 to 60, recalculate some values */
+    if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
+      bweStr->countUpdates = 10;
+      bweStr->recHeaderRate = kRecHeaderRate[1];
+
+      bweStr->maxBwInv = kInvBandwidth[3];
+      bweStr->minBwInv = kInvBandwidth[2];
+      bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
+    }
+
+    /* kBitsByteSec is in Q15 */
+    recRtpRate = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
+                                                                     (WebRtc_Word32)pksize), 15) + bweStr->recHeaderRate;
+
+  } else {
+    /* If frameSize changed since last call, from 60 to 30, recalculate some values */
+    if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
+      bweStr->countUpdates = 10;
+      bweStr->recHeaderRate = kRecHeaderRate[0];
+
+      bweStr->maxBwInv = kInvBandwidth[1];
+      bweStr->minBwInv = kInvBandwidth[0];
+      bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
+    }
+
+    /* kBitsByteSec is in Q14 */
+    recRtpRate = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
+                                                                      (WebRtc_Word32)pksize), 14) + bweStr->recHeaderRate;
+  }
+
+
+  /* Check for timer wrap-around */
+  if (arrivalTime < bweStr->prevArrivalTime) {
+    bweStr->prevArrivalTime = arrivalTime;
+    bweStr->lastUpdate      = arrivalTime;
+    bweStr->lastReduction   = arrivalTime + FS3;
+
+    bweStr->countRecPkts      = 0;
+
+    /* store frame size */
+    bweStr->prevFrameSizeMs = frameSize;
+
+    /* store far-side transmission rate */
+    bweStr->prevRtpRate = recRtpRate;
+
+    /* store far-side RTP time stamp */
+    bweStr->prevRtpNumber = rtpNumber;
+
+    return 0;
+  }
+
+  bweStr->countRecPkts++;
+
+  /* Calculate framesize in msec */
+  frameSizeSampl = WEBRTC_SPL_MUL_16_16((WebRtc_Word16)SAMPLES_PER_MSEC, frameSize);
+
+  /* Check that it's not one of the first 9 packets */
+  if ( bweStr->countUpdates > 0 ) {
+
+    /* Stay in Wait Period for 1.5 seconds (no updates in wait period) */
+    if(bweStr->inWaitPeriod) {
+      if ((arrivalTime - bweStr->startWaitPeriod)> FS_1_HALF) {
+        bweStr->inWaitPeriod = 0;
+      }
+    }
+
+    /* If not been updated for a long time, reduce the BN estimate */
+
+    /* Check send time difference between this packet and previous received      */
+    sendTimeDiff = sendTime - bweStr->prevSendTime;
+    if (sendTimeDiff <= WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1)) {
+
+      /* Only update if 3 seconds has past since last update */
+      if ((arrivalTime - bweStr->lastUpdate) > FS3) {
+
+        /* Calculate expected number of received packets since last update */
+        numPktsExpected =  WEBRTC_SPL_UDIV(arrivalTime - bweStr->lastUpdate, frameSizeSampl);
+
+        /* If received number of packets is more than 90% of expected (922 = 0.9 in Q10): */
+        /* do the update, else not                                                        */
+        if(WEBRTC_SPL_LSHIFT_W32(bweStr->countRecPkts, 10)  > WEBRTC_SPL_MUL_16_16(922, numPktsExpected)) {
+          /* Q4 chosen to approx dividing by 16 */
+          msec = (arrivalTime - bweStr->lastReduction);
+
+          /* the number below represents 13 seconds, highly unlikely
+             but to insure no overflow when reduction factor is multiplied by recBw inverse */
+          if (msec > 208000) {
+            msec = 208000;
+          }
+
+          /* Q20 2^(negative number: - 76/1048576) = .99995
+             product is Q24 */
+          exponent = WEBRTC_SPL_UMUL(0x0000004C, msec);
+
+          /* do the approx with positive exponent so that value is actually rf^-1
+             and multiply by bw inverse */
+          reductionFactor = WEBRTC_SPL_RSHIFT_U32(0x01000000 | (exponent & 0x00FFFFFF),
+                                                  WEBRTC_SPL_RSHIFT_U32(exponent, 24));
+
+          /* reductionFactor in Q13 */
+          reductionFactor = WEBRTC_SPL_RSHIFT_U32(reductionFactor, 11);
+
+          if ( reductionFactor != 0 ) {
+            bweStr->recBwInv = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recBwInv, (WebRtc_Word32)reductionFactor);
+            bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwInv, 13);
+
+          } else {
+            /* recBwInv = 1 / (INIT_BN_EST + INIT_HDR_RATE) in Q26 (Q30??)*/
+            bweStr->recBwInv = WEBRTC_SPL_DIV((1073741824 +
+                                               WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)INIT_BN_EST + INIT_HDR_RATE), 1)), INIT_BN_EST + INIT_HDR_RATE);
+          }
+
+          /* reset time-since-update counter */
+          bweStr->lastReduction = arrivalTime;
+        } else {
+          /* Delay last reduction with 3 seconds */
+          bweStr->lastReduction = arrivalTime + FS3;
+          bweStr->lastUpdate    = arrivalTime;
+          bweStr->countRecPkts  = 0;
+        }
+      }
+    } else {
+      bweStr->lastReduction = arrivalTime + FS3;
+      bweStr->lastUpdate    = arrivalTime;
+      bweStr->countRecPkts  = 0;
+    }
+
+
+    /*   update only if previous packet was not lost */
+    if ( rtpNumber == bweStr->prevRtpNumber + 1 ) {
+      arrTimeDiff = arrivalTime - bweStr->prevArrivalTime;
+
+      if (!(bweStr->highSpeedSend && bweStr->highSpeedRec)) {
+        if (arrTimeDiff > frameSizeSampl) {
+          if (sendTimeDiff > 0) {
+            lateDiff = arrTimeDiff - sendTimeDiff -
+                WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1);
+          } else {
+            lateDiff = arrTimeDiff - frameSizeSampl;
+          }
+
+          /* 8000 is 1/2 second (in samples at FS) */
+          if (lateDiff > 8000) {
+            delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MAX;
+            bweStr->inWaitPeriod = 1;
+            bweStr->startWaitPeriod = arrivalTime;
+            immediateSet = 1;
+          } else if (lateDiff > 5120) {
+            delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MED;
+            immediateSet = 1;
+            bweStr->inWaitPeriod = 1;
+            bweStr->startWaitPeriod = arrivalTime;
+          }
+        }
+      }
+
+      if ((bweStr->prevRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->recBwAvg, 5)) &&
+          (recRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwAvg, 5)) &&
+          !bweStr->inWaitPeriod) {
+
+        /* test if still in initiation period and increment counter */
+        if (bweStr->countUpdates++ > 99) {
+          /* constant weight after initiation part, 0.01 in Q13 */
+          weight = (WebRtc_UWord16) 82;
+        } else {
+          /* weight decreases with number of updates, 1/countUpdates in Q13  */
+          weight = (WebRtc_UWord16) WebRtcSpl_DivW32W16(
+              (WebRtc_Word32)(8192 + WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->countUpdates, 1)),
+              (WebRtc_Word16)bweStr->countUpdates);
+        }
+
+        /* Bottle Neck Estimation */
+
+        /* limit outliers, if more than 25 ms too much */
+        if (arrTimeDiff > frameSizeSampl + kSamplesIn25msec) {
+          arrTimeDiff = frameSizeSampl + kSamplesIn25msec;
+        }
+
+        /* don't allow it to be less than frame rate - 10 ms */
+        if (arrTimeDiff < frameSizeSampl - FRAMESAMPLES_10ms) {
+          arrTimeDiff = frameSizeSampl - FRAMESAMPLES_10ms;
+        }
+
+        /* compute inverse receiving rate for last packet, in Q19 */
+        numBytesInv = (WebRtc_UWord16) WebRtcSpl_DivW32W16(
+            (WebRtc_Word32)(524288 + WEBRTC_SPL_RSHIFT_W32(((WebRtc_Word32)pksize + HEADER_SIZE), 1)),
+            (WebRtc_Word16)(pksize + HEADER_SIZE));
+
+        /* 8389 is  ~ 1/128000 in Q30 */
+        byteSecondsPerBit = WEBRTC_SPL_MUL_16_16(arrTimeDiff, 8389);
+
+        /* get upper N bits */
+        tempUpper = WEBRTC_SPL_RSHIFT_U32(byteSecondsPerBit, 15);
+
+        /* get lower 15 bits */
+        tempLower = byteSecondsPerBit & 0x00007FFF;
+
+        tempUpper = WEBRTC_SPL_MUL(tempUpper, numBytesInv);
+        tempLower = WEBRTC_SPL_MUL(tempLower, numBytesInv);
+        tempLower = WEBRTC_SPL_RSHIFT_U32(tempLower, 15);
+
+        currBwInv = tempUpper + tempLower;
+        currBwInv = WEBRTC_SPL_RSHIFT_U32(currBwInv, 4);
+
+        /* Limit inv rate. Note that minBwInv > maxBwInv! */
+        if(currBwInv < bweStr->maxBwInv) {
+          currBwInv = bweStr->maxBwInv;
+        } else if(currBwInv > bweStr->minBwInv) {
+          currBwInv = bweStr->minBwInv;
+        }
+
+        /* update bottle neck rate estimate */
+        bweStr->recBwInv = WEBRTC_SPL_UMUL(weight, currBwInv) +
+            WEBRTC_SPL_UMUL((WebRtc_UWord32) 8192 - weight, bweStr->recBwInv);
+
+        /* Shift back to Q30 from Q40 (actual used bits shouldn't be more than 27 based on minBwInv)
+           up to 30 bits used with Q13 weight */
+        bweStr->recBwInv = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwInv, 13);
+
+        /* reset time-since-update counter */
+        bweStr->lastUpdate    = arrivalTime;
+        bweStr->lastReduction = arrivalTime + FS3;
+        bweStr->countRecPkts  = 0;
+
+        /* to save resolution compute the inverse of recBwAvg in Q26 by left shifting numerator to 2^31
+           and NOT right shifting recBwAvg 5 bits to an integer
+           At max 13 bits are used
+           shift to Q5 */
+        recBwAvgInv = WEBRTC_SPL_UDIV((WebRtc_UWord32)(0x80000000 + WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 1)),
+                                      bweStr->recBwAvg);
+
+        /* Calculate Projected arrival time difference */
+
+        /* The numerator of the quotient can be 22 bits so right shift inv by 4 to avoid overflow
+           result in Q22 */
+        arrTimeProj = WEBRTC_SPL_MUL((WebRtc_Word32)8000, recBwAvgInv);
+        /* shift to Q22 */
+        arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 4);
+        /* complete calulation */
+        arrTimeProj = WEBRTC_SPL_MUL(((WebRtc_Word32)pksize + HEADER_SIZE), arrTimeProj);
+        /* shift to Q10 */
+        arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 12);
+
+        /* difference between projected and actual arrival time differences */
+        /* Q9 (only shift arrTimeDiff by 5 to simulate divide by 16 (need to revisit if change sampling rate) DH */
+        if (WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) > (WebRtc_Word32)arrTimeProj) {
+          arrTimeNoise = WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) -  arrTimeProj;
+          sign = 1;
+        } else {
+          arrTimeNoise = arrTimeProj - WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6);
+          sign = -1;
+        }
+
+        /* Q9 */
+        arrTimeNoiseAbs = arrTimeNoise;
+
+        /* long term averaged absolute jitter, Q15 */
+        weight = WEBRTC_SPL_RSHIFT_W32(weight, 3);
+        bweStr->recJitter = WEBRTC_SPL_MUL(weight, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 5))
+            +  WEBRTC_SPL_MUL(1024 - weight, bweStr->recJitter);
+
+        /* remove the fractional portion */
+        bweStr->recJitter = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitter, 10);
+
+        /* Maximum jitter is 10 msec in Q15 */
+        if (bweStr->recJitter > (WebRtc_Word32)327680) {
+          bweStr->recJitter = (WebRtc_Word32)327680;
+        }
+
+        /* short term averaged absolute jitter */
+        /* Calculation in Q13 products in Q23 */
+        bweStr->recJitterShortTermAbs = WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 3)) +
+            WEBRTC_SPL_MUL(973, bweStr->recJitterShortTermAbs);
+        bweStr->recJitterShortTermAbs = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTermAbs , 10);
+
+        /* short term averaged jitter */
+        /* Calculation in Q13 products in Q23 */
+        bweStr->recJitterShortTerm = WEBRTC_SPL_MUL(205, WEBRTC_SPL_LSHIFT_W32(arrTimeNoise, 3)) * sign +
+            WEBRTC_SPL_MUL(3891, bweStr->recJitterShortTerm);
+
+        if (bweStr->recJitterShortTerm < 0) {
+          temp = -bweStr->recJitterShortTerm;
+          temp = WEBRTC_SPL_RSHIFT_W32(temp, 12);
+          bweStr->recJitterShortTerm = -temp;
+        } else {
+          bweStr->recJitterShortTerm = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 12);
+        }
+      }
+    }
+  } else {
+    /* reset time-since-update counter when receiving the first 9 packets */
+    bweStr->lastUpdate    = arrivalTime;
+    bweStr->lastReduction = arrivalTime + FS3;
+    bweStr->countRecPkts  = 0;
+    bweStr->countUpdates++;
+  }
+
+  /* Limit to minimum or maximum bottle neck rate (in Q30) */
+  if (bweStr->recBwInv > bweStr->minBwInv) {
+    bweStr->recBwInv = bweStr->minBwInv;
+  } else if (bweStr->recBwInv < bweStr->maxBwInv) {
+    bweStr->recBwInv = bweStr->maxBwInv;
+  }
+
+
+  /* store frame length */
+  bweStr->prevFrameSizeMs = frameSize;
+
+  /* store far-side transmission rate */
+  bweStr->prevRtpRate = recRtpRate;
+
+  /* store far-side RTP time stamp */
+  bweStr->prevRtpNumber = rtpNumber;
+
+  /* Replace bweStr->recMaxDelay by the new value (atomic operation) */
+  if (bweStr->prevArrivalTime != 0xffffffff) {
+    bweStr->recMaxDelay = WEBRTC_SPL_MUL(3, bweStr->recJitter);
+  }
+
+  /* store arrival time stamp */
+  bweStr->prevArrivalTime = arrivalTime;
+  bweStr->prevSendTime = sendTime;
+
+  /* Replace bweStr->recBw by the new value */
+  bweStr->recBw = WEBRTC_SPL_UDIV(1073741824, bweStr->recBwInv) - bweStr->recHeaderRate;
+
+  if (immediateSet) {
+    /* delay correction factor is in Q10 */
+    bweStr->recBw = WEBRTC_SPL_UMUL(delayCorrFactor, bweStr->recBw);
+    bweStr->recBw = WEBRTC_SPL_RSHIFT_U32(bweStr->recBw, 10);
+
+    if (bweStr->recBw < (WebRtc_Word32) MIN_ISAC_BW) {
+      bweStr->recBw = (WebRtc_Word32) MIN_ISAC_BW;
+    }
+
+    bweStr->recBwAvg = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw + bweStr->recHeaderRate, 5);
+
+    bweStr->recBwAvgQ = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw, 7);
+
+    bweStr->recJitterShortTerm = 0;
+
+    bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, bweStr->recBw + bweStr->recHeaderRate);
+
+    immediateSet = 0;
+  }
+
+
+  return 0;
+}
+
+/* This function updates the send bottle neck rate                                                   */
+/* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
+/* returns 0 if everything went fine, -1 otherwise                                                   */
+WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr,
+                                              const WebRtc_Word16 Index)
+{
+  WebRtc_UWord16 RateInd;
+
+  if ( (Index < 0) || (Index > 23) ) {
+    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
+  }
+
+  /* UPDATE ESTIMATES FROM OTHER SIDE */
+
+  if ( Index > 11 ) {
+    RateInd = Index - 12;
+    /* compute the jitter estimate as decoded on the other side in Q9 */
+    /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */
+    bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
+        WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MAX_ISAC_MD, 9));
+    bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
+
+  } else {
+    RateInd = Index;
+    /* compute the jitter estimate as decoded on the other side in Q9 */
+    /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MIN_ISAC_MD */
+    bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
+        WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MIN_ISAC_MD,9));
+    bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
+
+  }
+
+
+  /* compute the BN estimate as decoded on the other side */
+  /* sendBwAvg = 0.9 * sendBwAvg + 0.1 * kQRateTable[RateInd]; */
+  bweStr->sendBwAvg = WEBRTC_SPL_UMUL(461, bweStr->sendBwAvg) +
+      WEBRTC_SPL_UMUL(51, WEBRTC_SPL_LSHIFT_U32(kQRateTable[RateInd], 7));
+  bweStr->sendBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 9);
+
+
+  if (WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7) > 28000 && !bweStr->highSpeedSend) {
+    bweStr->countHighSpeedSent++;
+
+    /* approx 2 seconds with 30ms frames */
+    if (bweStr->countHighSpeedSent >= 66) {
+      bweStr->highSpeedSend = 1;
+    }
+  } else if (!bweStr->highSpeedSend) {
+    bweStr->countHighSpeedSent = 0;
+  }
+
+  return 0;
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_GetDownlinkBwIndexImpl(...)
+ *
+ * This function calculates and returns the bandwidth/jitter estimation code
+ * (integer 0...23) to put in the sending iSAC payload.
+ *
+ * Input:
+ *      - bweStr       : BWE struct
+ *
+ * Return:
+ *      bandwith and jitter index (0..23)
+ */
+WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
+{
+  WebRtc_Word32  rate;
+  WebRtc_Word32  maxDelay;
+  WebRtc_UWord16 rateInd;
+  WebRtc_UWord16 maxDelayBit;
+  WebRtc_Word32  tempTerm1;
+  WebRtc_Word32  tempTerm2;
+  WebRtc_Word32  tempTermX;
+  WebRtc_Word32  tempTermY;
+  WebRtc_Word32  tempMin;
+  WebRtc_Word32  tempMax;
+
+  /* Get Rate Index */
+
+  /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */
+  rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr);
+
+  /* Compute the averaged BN estimate on this side */
+
+  /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0.1 in Q9 */
+  bweStr->recBwAvg = WEBRTC_SPL_UMUL(922, bweStr->recBwAvg) +
+      WEBRTC_SPL_UMUL(102, WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)rate + bweStr->recHeaderRate, 5));
+  bweStr->recBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 10);
+
+  /* find quantization index that gives the closest rate after averaging */
+  for (rateInd = 1; rateInd < 12; rateInd++) {
+    if (rate <= kQRateTable[rateInd]){
+      break;
+    }
+  }
+
+  /* find closest quantization index, and update quantized average by taking: */
+  /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
+
+  /* 0.9 times recBwAvgQ in Q16 */
+  /* 461/512 - 25/65536 =0.900009 */
+  tempTerm1 = WEBRTC_SPL_MUL(bweStr->recBwAvgQ, 25);
+  tempTerm1 = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 7);
+  tempTermX = WEBRTC_SPL_UMUL(461, bweStr->recBwAvgQ) - tempTerm1;
+
+  /* rate in Q16 */
+  tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)rate, 16);
+
+  /* 0.1 * kQRateTable[rateInd] = KQRate01[rateInd] */
+  tempTerm1 = tempTermX + KQRate01[rateInd] - tempTermY;
+  tempTerm2 = tempTermY - tempTermX - KQRate01[rateInd-1];
+
+  /* Compare (0.9 * recBwAvgQ + 0.1 * kQRateTable[rateInd] - rate) >
+     (rate - 0.9 * recBwAvgQ - 0.1 * kQRateTable[rateInd-1]) */
+  if (tempTerm1  > tempTerm2) {
+    rateInd--;
+  }
+
+  /* Update quantized average by taking:                  */
+  /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
+
+  /* Add 0.1 times kQRateTable[rateInd], in Q16 */
+  tempTermX += KQRate01[rateInd];
+
+  /* Shift back to Q7 */
+  bweStr->recBwAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTermX, 9);
+
+  /* Count consecutive received bandwidth above 28000 kbps (28000 in Q7 = 3584000) */
+  /* If 66 high estimates in a row, set highSpeedRec to one */
+  /* 66 corresponds to ~2 seconds in 30 msec mode */
+  if ((bweStr->recBwAvgQ > 3584000) && !bweStr->highSpeedRec) {
+    bweStr->countHighSpeedRec++;
+    if (bweStr->countHighSpeedRec >= 66) {
+      bweStr->highSpeedRec = 1;
+    }
+  } else if (!bweStr->highSpeedRec)    {
+    bweStr->countHighSpeedRec = 0;
+  }
+
+  /* Get Max Delay Bit */
+
+  /* get unquantized max delay */
+  maxDelay = WebRtcIsacfix_GetDownlinkMaxDelay(bweStr);
+
+  /* Update quantized max delay average */
+  tempMax = 652800; /* MAX_ISAC_MD * 0.1 in Q18 */
+  tempMin = 130560; /* MIN_ISAC_MD * 0.1 in Q18 */
+  tempTermX = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recMaxDelayAvgQ, (WebRtc_Word32)461);
+  tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)maxDelay, 18);
+
+  tempTerm1 = tempTermX + tempMax - tempTermY;
+  tempTerm2 = tempTermY - tempTermX - tempMin;
+
+  if ( tempTerm1 > tempTerm2) {
+    maxDelayBit = 0;
+    tempTerm1 = tempTermX + tempMin;
+
+    /* update quantized average, shift back to Q9 */
+    bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
+  } else {
+    maxDelayBit = 12;
+    tempTerm1 =  tempTermX + tempMax;
+
+    /* update quantized average, shift back to Q9 */
+    bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
+  }
+
+  /* Return bandwitdh and jitter index (0..23) */
+  return (WebRtc_UWord16)(rateInd + maxDelayBit);
+}
+
+/* get the bottle neck rate from far side to here, as estimated on this side */
+WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr)
+{
+  WebRtc_UWord32  recBw;
+  WebRtc_Word32   jitter_sign; /* Q8 */
+  WebRtc_Word32   bw_adjust;   /* Q16 */
+  WebRtc_Word32   rec_jitter_short_term_abs_inv; /* Q18 */
+  WebRtc_Word32   temp;
+
+  /* Q18  rec jitter short term abs is in Q13, multiply it by 2^13 to save precision
+     2^18 then needs to be shifted 13 bits to 2^31 */
+  rec_jitter_short_term_abs_inv = WEBRTC_SPL_UDIV(0x80000000, bweStr->recJitterShortTermAbs);
+
+  /* Q27 = 9 + 18 */
+  jitter_sign = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 4), (WebRtc_Word32)rec_jitter_short_term_abs_inv);
+
+  if (jitter_sign < 0) {
+    temp = -jitter_sign;
+    temp = WEBRTC_SPL_RSHIFT_W32(temp, 19);
+    jitter_sign = -temp;
+  } else {
+    jitter_sign = WEBRTC_SPL_RSHIFT_W32(jitter_sign, 19);
+  }
+
+  /* adjust bw proportionally to negative average jitter sign */
+  //bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
+  //Q8 -> Q16 .15 +.15 * jitter^2 first term is .15 in Q16 latter term is Q8*Q8*Q8
+  //38 in Q8 ~.15 9830 in Q16 ~.15
+  temp = 9830  + WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL(38, WEBRTC_SPL_MUL(jitter_sign, jitter_sign))), 8);
+
+  if (jitter_sign < 0) {
+    temp = WEBRTC_SPL_MUL(jitter_sign, temp);
+    temp = -temp;
+    temp = WEBRTC_SPL_RSHIFT_W32(temp, 8);
+    bw_adjust = (WebRtc_UWord32)65536 + temp; /* (1 << 16) + temp; */
+  } else {
+    bw_adjust = (WebRtc_UWord32)65536 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(jitter_sign, temp), 8);/* (1 << 16) - ((jitter_sign * temp) >> 8); */
+  }
+
+  //make sure following multiplication won't overflow
+  //bw adjust now Q14
+  bw_adjust = WEBRTC_SPL_RSHIFT_W32(bw_adjust, 2);//see if good resolution is maintained
+
+  /* adjust Rate if jitter sign is mostly constant */
+  recBw = WEBRTC_SPL_UMUL(bweStr->recBw, bw_adjust);
+
+  recBw = WEBRTC_SPL_RSHIFT_W32(recBw, 14);
+
+  /* limit range of bottle neck rate */
+  if (recBw < MIN_ISAC_BW) {
+    recBw = MIN_ISAC_BW;
+  } else if (recBw > MAX_ISAC_BW) {
+    recBw = MAX_ISAC_BW;
+  }
+
+  return  (WebRtc_UWord16) recBw;
+}
+
+/* Returns the mmax delay (in ms) */
+WebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr)
+{
+  WebRtc_Word16 recMaxDelay;
+
+  recMaxDelay = (WebRtc_Word16)  WEBRTC_SPL_RSHIFT_W32(bweStr->recMaxDelay, 15);
+
+  /* limit range of jitter estimate */
+  if (recMaxDelay < MIN_ISAC_MD) {
+    recMaxDelay = MIN_ISAC_MD;
+  } else if (recMaxDelay > MAX_ISAC_MD) {
+    recMaxDelay = MAX_ISAC_MD;
+  }
+
+  return recMaxDelay;
+}
+
+/* get the bottle neck rate from here to far side, as estimated by far side */
+WebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr)
+{
+  WebRtc_Word16 send_bw;
+
+  send_bw = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7);
+
+  /* limit range of bottle neck rate */
+  if (send_bw < MIN_ISAC_BW) {
+    send_bw = MIN_ISAC_BW;
+  } else if (send_bw > MAX_ISAC_BW) {
+    send_bw = MAX_ISAC_BW;
+  }
+
+  return send_bw;
+}
+
+
+
+/* Returns the max delay value from the other side in ms */
+WebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr)
+{
+  WebRtc_Word16 send_max_delay;
+
+  send_max_delay = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
+
+  /* limit range of jitter estimate */
+  if (send_max_delay < MIN_ISAC_MD) {
+    send_max_delay = MIN_ISAC_MD;
+  } else if (send_max_delay > MAX_ISAC_MD) {
+    send_max_delay = MAX_ISAC_MD;
+  }
+
+  return send_max_delay;
+}
+
+
+
+
+/*
+ * update long-term average bitrate and amount of data in buffer
+ * returns minimum payload size (bytes)
+ */
+WebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State,
+                                         WebRtc_Word16 StreamSize,                    /* bytes in bitstream */
+                                         const WebRtc_Word16 FrameSamples,            /* samples per frame */
+                                         const WebRtc_Word16 BottleNeck,        /* bottle neck rate; excl headers (bps) */
+                                         const WebRtc_Word16 DelayBuildUp)      /* max delay from bottle neck buffering (ms) */
+{
+  WebRtc_Word32 MinRate = 0;
+  WebRtc_UWord16    MinBytes;
+  WebRtc_Word16 TransmissionTime;
+  WebRtc_Word32 inv_Q12;
+  WebRtc_Word32 den;
+
+
+  /* first 10 packets @ low rate, then INIT_BURST_LEN packets @ fixed rate of INIT_RATE bps */
+  if (State->InitCounter > 0) {
+    if (State->InitCounter-- <= INIT_BURST_LEN) {
+      MinRate = INIT_RATE;
+    } else {
+      MinRate = 0;
+    }
+  } else {
+    /* handle burst */
+    if (State->BurstCounter) {
+      if (State->StillBuffered < WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL((512 - WEBRTC_SPL_DIV(512, BURST_LEN)), DelayBuildUp), 9)) {
+        /* max bps derived from BottleNeck and DelayBuildUp values */
+        inv_Q12 = WEBRTC_SPL_DIV(4096, WEBRTC_SPL_MUL(BURST_LEN, FrameSamples));
+        MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
+      } else {
+        /* max bps derived from StillBuffered and DelayBuildUp values */
+        inv_Q12 = WEBRTC_SPL_DIV(4096, FrameSamples);
+        if (DelayBuildUp > State->StillBuffered) {
+          MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
+        } else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
+          /* MinRate will be negative here */
+          MinRate = 0;
+        } else {
+          MinRate = WEBRTC_SPL_MUL((512 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(den, inv_Q12), 3)), BottleNeck);
+        }
+        //if (MinRate < 1.04 * BottleNeck)
+        //    MinRate = 1.04 * BottleNeck;
+        //Q9
+        if (MinRate < WEBRTC_SPL_MUL(532, BottleNeck)) {
+          MinRate += WEBRTC_SPL_MUL(22, BottleNeck);
+        }
+      }
+
+      State->BurstCounter--;
+    }
+  }
+
+
+  /* convert rate from bits/second to bytes/packet */
+  //round and shift before conversion
+  MinRate += 256;
+  MinRate = WEBRTC_SPL_RSHIFT_W32(MinRate, 9);
+  MinBytes = (WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_MUL(MinRate, FrameSamples), FS8);
+
+  /* StreamSize will be adjusted if less than MinBytes */
+  if (StreamSize < MinBytes) {
+    StreamSize = MinBytes;
+  }
+
+  /* keep track of when bottle neck was last exceeded by at least 1% */
+  //517/512 ~ 1.01
+  if (WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, FS8), FrameSamples) > (WEBRTC_SPL_MUL(517, BottleNeck) >> 9)) {
+    if (State->PrevExceed) {
+      /* bottle_neck exceded twice in a row, decrease ExceedAgo */
+      State->ExceedAgo -= WEBRTC_SPL_DIV(BURST_INTERVAL, BURST_LEN - 1);
+      if (State->ExceedAgo < 0) {
+        State->ExceedAgo = 0;
+      }
+    } else {
+      State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);       /* ms */
+      State->PrevExceed = 1;
+    }
+  } else {
+    State->PrevExceed = 0;
+    State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);           /* ms */
+  }
+
+  /* set burst flag if bottle neck not exceeded for long time */
+  if ((State->ExceedAgo > BURST_INTERVAL) && (State->BurstCounter == 0)) {
+    if (State->PrevExceed) {
+      State->BurstCounter = BURST_LEN - 1;
+    } else {
+      State->BurstCounter = BURST_LEN;
+    }
+  }
+
+
+  /* Update buffer delay */
+  TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, 8000), BottleNeck);    /* ms */
+  State->StillBuffered += TransmissionTime;
+  State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);  //>>4 =  SAMPLES_PER_MSEC        /* ms */
+  if (State->StillBuffered < 0) {
+    State->StillBuffered = 0;
+  }
+
+  if (State->StillBuffered > 2000) {
+    State->StillBuffered = 2000;
+  }
+
+  return MinBytes;
+}
+
+
+/*
+ * update long-term average bitrate and amount of data in buffer
+ */
+void WebRtcIsacfix_UpdateRateModel(RateModel *State,
+                                   WebRtc_Word16 StreamSize,                    /* bytes in bitstream */
+                                   const WebRtc_Word16 FrameSamples,            /* samples per frame */
+                                   const WebRtc_Word16 BottleNeck)        /* bottle neck rate; excl headers (bps) */
+{
+  WebRtc_Word16 TransmissionTime;
+
+  /* avoid the initial "high-rate" burst */
+  State->InitCounter = 0;
+
+  /* Update buffer delay */
+  TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(WEBRTC_SPL_MUL(StreamSize, 8), 1000), BottleNeck);    /* ms */
+  State->StillBuffered += TransmissionTime;
+  State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);            /* ms */
+  if (State->StillBuffered < 0) {
+    State->StillBuffered = 0;
+  }
+
+}
+
+
+void WebRtcIsacfix_InitRateModel(RateModel *State)
+{
+  State->PrevExceed      = 0;                        /* boolean */
+  State->ExceedAgo       = 0;                        /* ms */
+  State->BurstCounter    = 0;                        /* packets */
+  State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
+  State->StillBuffered   = 1;                    /* ms */
+}
+
+
+
+
+
+WebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framesamples)
+{
+  WebRtc_Word16 new_framesamples;
+
+  new_framesamples = current_framesamples;
+
+  /* find new framelength */
+  switch(current_framesamples) {
+    case 480:
+      if (bottle_neck < Thld_30_60) {
+        new_framesamples = 960;
+      }
+      break;
+    case 960:
+      if (bottle_neck >= Thld_60_30) {
+        new_framesamples = 480;
+      }
+      break;
+    default:
+      new_framesamples = -1; /* Error */
+  }
+
+  return new_framesamples;
+}
+
+WebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples)
+{
+  WebRtc_Word16 s2nr = 0;
+
+  /* find new SNR value */
+  //consider BottleNeck to be in Q10 ( * 1 in Q10)
+  switch(framesamples) {
+    case 480:
+      /*s2nr = -1*(a_30 << 10) + ((b_30 * bottle_neck) >> 10);*/
+      s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
+      break;
+    case 960:
+      /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/
+      s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
+      break;
+    default:
+      s2nr = -1; /* Error */
+  }
+
+  return s2nr; //return in Q10
+
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h b/src/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h
new file mode 100644
index 0000000..76a50f8
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * bandwidth_estimator.h
+ *
+ * This header file contains the API for the Bandwidth Estimator
+ * designed for iSAC.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_
+
+#include "structs.h"
+
+
+/****************************************************************************
+ * WebRtcIsacfix_InitBandwidthEstimator(...)
+ *
+ * This function initializes the struct for the bandwidth estimator
+ *
+ * Input/Output:
+ *      - bwest_str        : Struct containing bandwidth information.
+ *
+ * Return value            : 0
+ */
+
+WebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bwest_str);
+
+
+/****************************************************************************
+ * WebRtcIsacfix_UpdateUplinkBwImpl(...)
+ *
+ * This function updates bottle neck rate received from other side in payload
+ * and calculates a new bottle neck to send to the other side.
+ *
+ * Input/Output:
+ *      - bweStr           : struct containing bandwidth information.
+ *      - rtpNumber        : value from RTP packet, from NetEq
+ *      - frameSize        : length of signal frame in ms, from iSAC decoder
+ *      - sendTime         : value in RTP header giving send time in samples
+ *      - arrivalTime      : value given by timeGetTime() time of arrival in
+ *                           samples of packet from NetEq
+ *      - pksize           : size of packet in bytes, from NetEq
+ *      - Index            : integer (range 0...23) indicating bottle neck &
+ *                           jitter as estimated by other side
+ *
+ * Return value            : 0 if everything went fine,
+ *                           -1 otherwise
+ */
+
+WebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr            *bwest_str,
+                                               const WebRtc_UWord16        rtp_number,
+                                               const WebRtc_Word16         frameSize,
+                                               const WebRtc_UWord32    send_ts,
+                                               const WebRtc_UWord32        arr_ts,
+                                               const WebRtc_Word16         pksize,
+                                               const WebRtc_UWord16        Index);
+
+/* Update receiving estimates. Used when we only receive BWE index, no iSAC data packet. */
+WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bwest_str,
+                                              const WebRtc_Word16 Index);
+
+/****************************************************************************
+ * WebRtcIsacfix_GetDownlinkBwIndexImpl(...)
+ *
+ * This function calculates and returns the bandwidth/jitter estimation code
+ * (integer 0...23) to put in the sending iSAC payload.
+ *
+ * Input:
+ *      - bweStr       : BWE struct
+ *
+ * Return:
+ *      bandwith and jitter index (0..23)
+ */
+WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bwest_str);
+
+/* Returns the bandwidth estimation (in bps) */
+WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bwest_str);
+
+/* Returns the bandwidth that iSAC should send with in bps */
+WebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bwest_str);
+
+/* Returns the max delay (in ms) */
+WebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str);
+
+/* Returns the max delay value from the other side in ms */
+WebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str);
+
+/*
+ * update amount of data in bottle neck buffer and burst handling
+ * returns minimum payload size (bytes)
+ */
+WebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State,
+                                         WebRtc_Word16 StreamSize,     /* bytes in bitstream */
+                                         const WebRtc_Word16 FrameLen,    /* ms per frame */
+                                         const WebRtc_Word16 BottleNeck,        /* bottle neck rate; excl headers (bps) */
+                                         const WebRtc_Word16 DelayBuildUp);     /* max delay from bottle neck buffering (ms) */
+
+/*
+ * update long-term average bitrate and amount of data in buffer
+ */
+void WebRtcIsacfix_UpdateRateModel(RateModel *State,
+                                   WebRtc_Word16 StreamSize,    /* bytes in bitstream */
+                                   const WebRtc_Word16 FrameSamples,  /* samples per frame */
+                                   const WebRtc_Word16 BottleNeck);       /* bottle neck rate; excl headers (bps) */
+
+
+void WebRtcIsacfix_InitRateModel(RateModel *State);
+
+/* Returns the new framelength value (input argument: bottle_neck) */
+WebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framelength);
+
+/* Returns the new SNR value (input argument: bottle_neck) */
+//returns snr in Q10
+WebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples);
+
+
+#endif /*  WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_BANDWIDTH_ESTIMATOR_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/codec.h b/src/modules/audio_coding/codecs/isac/fix/source/codec.h
new file mode 100644
index 0000000..1b4f987
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/codec.h
@@ -0,0 +1,179 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * codec.h
+ *
+ * This header file contains the calls to the internal encoder
+ * and decoder functions.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_
+
+#include "structs.h"
+
+
+int WebRtcIsacfix_EstimateBandwidth(BwEstimatorstr   *bwest_str,
+                                    Bitstr_dec       *streamdata,
+                                    WebRtc_Word32      packet_size,
+                                    WebRtc_UWord16     rtp_seq_number,
+                                    WebRtc_UWord32     send_ts,
+                                    WebRtc_UWord32     arr_ts);
+
+WebRtc_Word16 WebRtcIsacfix_DecodeImpl(WebRtc_Word16   *signal_out16,
+                                       ISACFIX_DecInst_t  *ISACdec_obj,
+                                       WebRtc_Word16        *current_framesamples);
+
+WebRtc_Word16 WebRtcIsacfix_DecodePlcImpl(WebRtc_Word16       *decoded,
+                                          ISACFIX_DecInst_t *ISACdec_obj,
+                                          WebRtc_Word16       *current_framesample );
+
+int WebRtcIsacfix_EncodeImpl(WebRtc_Word16      *in,
+                             ISACFIX_EncInst_t  *ISACenc_obj,
+                             BwEstimatorstr      *bw_estimatordata,
+                             WebRtc_Word16         CodingMode);
+
+int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t  *ISACenc_obj,
+                                   int     BWnumber,
+                                   float              scale);
+
+/* initialization functions */
+
+void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata);
+void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata);
+
+void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata);
+
+void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata);
+
+void WebRtcIsacfix_InitPitchFilter(PitchFiltstr *pitchfiltdata);
+
+void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State);
+
+void WebRtcIsacfix_InitPlc( PLCstr *State );
+
+
+/* transform functions */
+
+void WebRtcIsacfix_InitTransform();
+
+
+void WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9,
+                             WebRtc_Word16 *inre2Q9,
+                             WebRtc_Word16 *outre,
+                             WebRtc_Word16 *outim);
+
+
+
+void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7,
+                             WebRtc_Word16 *inimQ7,
+                             WebRtc_Word32 *outre1Q16,
+                             WebRtc_Word32 *outre2Q16);
+
+
+
+
+/* filterbank functions */
+
+void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16    *in,
+                                   WebRtc_Word16    *LP16,
+                                   WebRtc_Word16    *HP16,
+                                   PreFiltBankstr *prefiltdata);
+
+void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16     *tempin_ch1,
+                                     WebRtc_Word16     *tempin_ch2,
+                                     WebRtc_Word16     *out16,
+                                     PostFiltBankstr *postfiltdata);
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+
+void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16    *in,
+                                   WebRtc_Word16    *LP16,
+                                   WebRtc_Word16    *HP16,
+                                   PreFiltBankstr *prefiltdata);
+
+void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16     *tempin_ch1,
+                                     WebRtc_Word16     *tempin_ch2,
+                                     WebRtc_Word16     *out16,
+                                     PostFiltBankstr *postfiltdata,
+                                     WebRtc_Word16     len);
+
+#endif
+
+/* normalized lattice filters */
+
+void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef,
+                                       WebRtc_Word32 *stateGQ15,
+                                       WebRtc_Word16 *lat_inQ0,
+                                       WebRtc_Word16 *filt_coefQ15,
+                                       WebRtc_Word32 *gain_lo_hiQ17,
+                                       WebRtc_Word16 lo_hi,
+                                       WebRtc_Word16 *lat_outQ9);
+
+void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef,
+                                       WebRtc_Word16 *stateGQ0,
+                                       WebRtc_Word32 *lat_inQ25,
+                                       WebRtc_Word16 *filt_coefQ15,
+                                       WebRtc_Word32 *gain_lo_hiQ17,
+                                       WebRtc_Word16 lo_hi,
+                                       WebRtc_Word16 *lat_outQ0);
+
+/* TODO(kma): Remove the following functions into individual header files. */
+
+/* Internal functions in both C and ARM Neon versions */
+
+int WebRtcIsacfix_AutocorrC(WebRtc_Word32* __restrict r,
+                            const WebRtc_Word16* __restrict x,
+                            WebRtc_Word16 N,
+                            WebRtc_Word16 order,
+                            WebRtc_Word16* __restrict scale);
+
+void WebRtcIsacfix_FilterMaLoopC(int16_t input0,
+                                 int16_t input1,
+                                 int32_t input2,
+                                 int32_t* ptr0,
+                                 int32_t* ptr1,
+                                 int32_t* ptr2);
+
+#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
+int WebRtcIsacfix_AutocorrNeon(WebRtc_Word32* __restrict r,
+                               const WebRtc_Word16* __restrict x,
+                               WebRtc_Word16 N,
+                               WebRtc_Word16 order,
+                               WebRtc_Word16* __restrict scale);
+
+void WebRtcIsacfix_FilterMaLoopNeon(int16_t input0,
+                                    int16_t input1,
+                                    int32_t input2,
+                                    int32_t* ptr0,
+                                    int32_t* ptr1,
+                                    int32_t* ptr2);
+#endif
+
+/* Function pointers associated with the above functions. */
+
+typedef int (*AutocorrFix)(WebRtc_Word32* __restrict r,
+                           const WebRtc_Word16* __restrict x,
+                           WebRtc_Word16 N,
+                           WebRtc_Word16 order,
+                           WebRtc_Word16* __restrict scale);
+extern AutocorrFix WebRtcIsacfix_AutocorrFix;
+
+typedef void (*FilterMaLoopFix)(int16_t input0,
+                                int16_t input1,
+                                int32_t input2,
+                                int32_t* ptr0,
+                                int32_t* ptr1,
+                                int32_t* ptr2);
+extern FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_CODEC_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/decode.c b/src/modules/audio_coding/codecs/isac/fix/source/decode.c
new file mode 100644
index 0000000..2e15e7a
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/decode.c
@@ -0,0 +1,217 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * decode.c
+ *
+ * This C file contains the internal decoding function.
+ *
+ */
+
+#include <string.h>
+
+#include "bandwidth_estimator.h"
+#include "codec.h"
+#include "entropy_coding.h"
+#include "pitch_estimator.h"
+#include "settings.h"
+#include "structs.h"
+
+
+
+
+WebRtc_Word16 WebRtcIsacfix_DecodeImpl(WebRtc_Word16       *signal_out16,
+                                       ISACFIX_DecInst_t *ISACdec_obj,
+                                       WebRtc_Word16       *current_framesamples)
+{
+  int k;
+  int err;
+  WebRtc_Word16 BWno;
+  WebRtc_Word16 len = 0;
+
+  WebRtc_Word16 model;
+
+
+  WebRtc_Word16 Vector_Word16_1[FRAMESAMPLES/2];
+  WebRtc_Word16 Vector_Word16_2[FRAMESAMPLES/2];
+
+  WebRtc_Word32 Vector_Word32_1[FRAMESAMPLES/2];
+  WebRtc_Word32 Vector_Word32_2[FRAMESAMPLES/2];
+
+  WebRtc_Word16 lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
+  WebRtc_Word16 hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
+  WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];
+
+  WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES];
+  WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES];
+  WebRtc_Word16 AvgPitchGain_Q12;
+
+  WebRtc_Word16 tmp_1, tmp_2;
+  WebRtc_Word32 tmp32a, tmp32b;
+  WebRtc_Word16 gainQ13;
+
+
+  WebRtc_Word16 frame_nb; /* counter */
+  WebRtc_Word16 frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */
+  WebRtc_Word16 processed_samples;
+
+  /* PLC */
+  WebRtc_Word16 overlapWin[ 240 ];
+
+  (ISACdec_obj->bitstr_obj).W_upper = 0xFFFFFFFF;
+  (ISACdec_obj->bitstr_obj).streamval = 0;
+  (ISACdec_obj->bitstr_obj).stream_index = 0;
+  (ISACdec_obj->bitstr_obj).full = 1;
+
+
+  /* decode framelength and BW estimation - not used, only for stream pointer*/
+  err = WebRtcIsacfix_DecodeFrameLen(&ISACdec_obj->bitstr_obj, current_framesamples);
+  if (err<0)  // error check
+    return err;
+
+  frame_mode = (WebRtc_Word16)WEBRTC_SPL_DIV(*current_framesamples, MAX_FRAMESAMPLES); /* 0, or 1 */
+  processed_samples = (WebRtc_Word16)WEBRTC_SPL_DIV(*current_framesamples, frame_mode+1); /* either 320 (20ms) or 480 (30, 60 ms) */
+
+  err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
+  if (err<0)  // error check
+    return err;
+
+  /* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames bundled together (60ms) */
+  for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
+
+    /* decode & dequantize pitch parameters */
+    err = WebRtcIsacfix_DecodePitchGain(&(ISACdec_obj->bitstr_obj), PitchGains_Q12);
+    if (err<0)  // error check
+      return err;
+
+    err = WebRtcIsacfix_DecodePitchLag(&ISACdec_obj->bitstr_obj, PitchGains_Q12, PitchLags_Q7);
+    if (err<0)  // error check
+      return err;
+
+    AvgPitchGain_Q12 = (WebRtc_Word16)(((WebRtc_Word32)PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2);
+
+    /* decode & dequantize FiltCoef */
+    err = WebRtcIsacfix_DecodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
+                                  &ISACdec_obj->bitstr_obj, &model);
+
+    if (err<0)  // error check
+      return err;
+
+    /* decode & dequantize spectrum */
+    len = WebRtcIsacfix_DecodeSpec(&ISACdec_obj->bitstr_obj, Vector_Word16_1, Vector_Word16_2, AvgPitchGain_Q12);
+    if (len < 0)  // error check
+      return len;
+
+    // Why does this need Q16 in and out? /JS
+    WebRtcIsacfix_Spec2Time(Vector_Word16_1, Vector_Word16_2, Vector_Word32_1, Vector_Word32_2);
+
+    for (k=0; k<FRAMESAMPLES/2; k++) {
+      Vector_Word16_1[k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(Vector_Word32_1[k]+64, 7); //Q16 -> Q9
+    }
+
+    /* ----  If this is recovery frame ---- */
+    if( (ISACdec_obj->plcstr_obj).used == PLC_WAS_USED )
+    {
+      (ISACdec_obj->plcstr_obj).used = PLC_NOT_USED;
+      if( (ISACdec_obj->plcstr_obj).B < 1000 )
+      {
+        (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 4000;
+      }
+
+      ISACdec_obj->plcstr_obj.decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
+      ISACdec_obj->plcstr_obj.decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;    /* DECAY_RATE is in Q15 */
+      ISACdec_obj->plcstr_obj.pitchCycles = 0;
+
+      PitchGains_Q12[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[0], 700, 10 );
+
+      /* ---- Add-overlap ---- */
+      WebRtcSpl_GetHanningWindow( overlapWin, RECOVERY_OVERLAP );
+      for( k = 0; k < RECOVERY_OVERLAP; k++ )
+        Vector_Word16_1[k] = WEBRTC_SPL_ADD_SAT_W16(
+            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( (ISACdec_obj->plcstr_obj).overlapLP[k], overlapWin[RECOVERY_OVERLAP - k - 1], 14),
+            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( Vector_Word16_1[k], overlapWin[k], 14) );
+
+
+
+    }
+
+    /* --- Store side info --- */
+    if( frame_nb == frame_mode )
+    {
+      /* --- LPC info */
+      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).lofilt_coefQ15, &lofilt_coefQ15[(SUBFRAMES-1)*ORDERLO], ORDERLO );
+      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).hifilt_coefQ15, &hifilt_coefQ15[(SUBFRAMES-1)*ORDERHI], ORDERHI );
+      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0] = gain_lo_hiQ17[(SUBFRAMES-1) * 2];
+      (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1] = gain_lo_hiQ17[(SUBFRAMES-1) * 2 + 1];
+
+      /* --- LTP info */
+      (ISACdec_obj->plcstr_obj).AvgPitchGain_Q12 = PitchGains_Q12[3];
+      (ISACdec_obj->plcstr_obj).lastPitchGain_Q12 = PitchGains_Q12[3];
+      (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = PitchLags_Q7[3];
+
+      if( PitchLags_Q7[3] < 3000 )
+        (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 += PitchLags_Q7[3];
+
+      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvIn, Vector_Word16_1, FRAMESAMPLES/2 );
+
+    }
+    /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+    /* inverse pitch filter */
+    WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2, &ISACdec_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 4);
+
+    if( frame_nb == frame_mode )
+    {
+      WEBRTC_SPL_MEMCPY_W16( (ISACdec_obj->plcstr_obj).prevPitchInvOut, &(Vector_Word16_2[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10)]), PITCH_MAX_LAG );
+    }
+
+
+    /* reduce gain to compensate for pitch enhancer */
+    /* gain = 1.0f - 0.45f * AvgPitchGain; */
+    tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(AvgPitchGain_Q12, 29, 0); // Q18
+    tmp32b = 262144 - tmp32a;  // Q18
+    gainQ13 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q13
+
+    for (k = 0; k < FRAMESAMPLES/2; k++)
+    {
+      Vector_Word32_1[k] = (WebRtc_Word32) WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(Vector_Word16_2[k], gainQ13), 3); // Q25
+    }
+
+
+    /* perceptual post-filtering (using normalized lattice filter) */
+    WebRtcIsacfix_NormLatticeFilterAr(ORDERLO, (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
+                                      Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
+
+    /* --- Store Highpass Residual --- */
+    for (k = 0; k < FRAMESAMPLES/2; k++)
+      Vector_Word32_1[k]    = WEBRTC_SPL_LSHIFT_W32(Vector_Word32_2[k], 9); // Q16 -> Q25
+
+    for( k = 0; k < PITCH_MAX_LAG + 10; k++ )
+      (ISACdec_obj->plcstr_obj).prevHP[k] = Vector_Word32_1[FRAMESAMPLES/2 - (PITCH_MAX_LAG + 10) + k];
+
+
+    WebRtcIsacfix_NormLatticeFilterAr(ORDERHI, (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
+                                      Vector_Word32_1, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
+
+    /* recombine the 2 bands */
+
+    /* Form the polyphase signals, and compensate for DC offset */
+    for (k=0;k<FRAMESAMPLES/2;k++) {
+      tmp_1 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(((WebRtc_Word32)Vector_Word16_1[k]+Vector_Word16_2[k] + 1)); /* Construct a new upper channel signal*/
+      tmp_2 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(((WebRtc_Word32)Vector_Word16_1[k]-Vector_Word16_2[k])); /* Construct a new lower channel signal*/
+      Vector_Word16_1[k] = tmp_1;
+      Vector_Word16_2[k] = tmp_2;
+    }
+
+    WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, Vector_Word16_2, signal_out16 + frame_nb * processed_samples, &ISACdec_obj->postfiltbankstr_obj);
+
+  }
+  return len;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/decode_bwe.c b/src/modules/audio_coding/codecs/isac/fix/source/decode_bwe.c
new file mode 100644
index 0000000..68c6003
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/decode_bwe.c
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * decode_bwe.c
+ *
+ * This C file contains the internal decode bandwidth estimate function.
+ *
+ */
+
+
+#include "bandwidth_estimator.h"
+#include "codec.h"
+#include "entropy_coding.h"
+#include "structs.h"
+
+
+
+
+int WebRtcIsacfix_EstimateBandwidth(BwEstimatorstr *bwest_str,
+                                    Bitstr_dec  *streamdata,
+                                    WebRtc_Word32  packet_size,
+                                    WebRtc_UWord16 rtp_seq_number,
+                                    WebRtc_UWord32 send_ts,
+                                    WebRtc_UWord32 arr_ts)
+{
+  WebRtc_Word16 index;
+  WebRtc_Word16 frame_samples;
+  int err;
+
+  /* decode framelength */
+  err = WebRtcIsacfix_DecodeFrameLen(streamdata, &frame_samples);
+  /* error check */
+  if (err<0) {
+    return err;
+  }
+
+  /* decode BW estimation */
+  err = WebRtcIsacfix_DecodeSendBandwidth(streamdata, &index);
+  /* error check */
+  if (err<0) {
+    return err;
+  }
+
+  /* Update BWE with received data */
+  err = WebRtcIsacfix_UpdateUplinkBwImpl(
+      bwest_str,
+      rtp_seq_number,
+      (WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_UMUL(frame_samples,1000), FS),
+      send_ts,
+      arr_ts,
+      (WebRtc_Word16) packet_size,  /* in bytes */
+      index);
+
+  /* error check */
+  if (err<0) {
+    return err;
+  }
+
+  /* Succesful */
+  return 0;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/decode_plc.c b/src/modules/audio_coding/codecs/isac/fix/source/decode_plc.c
new file mode 100644
index 0000000..de51658
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/decode_plc.c
@@ -0,0 +1,830 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * decode_plc.c
+ *
+ * Packet Loss Concealment.
+ *
+ */
+
+#include <string.h>
+
+#include "settings.h"
+#include "entropy_coding.h"
+#include "pitch_estimator.h"
+#include "bandwidth_estimator.h"
+#include "structs.h"
+#include "codec.h"
+
+
+#define NO_OF_PRIMES 8
+#define NOISE_FILTER_LEN 30
+
+/*
+ * function to decode the bitstream
+ * returns the total number of bytes in the stream
+ */
+
+static WebRtc_Word16 plc_filterma_Fast(
+    WebRtc_Word16 *In,  /* (i)   Vector to be filtered. InOut[-orderCoef+1]
+                           to InOut[-1] contains state */
+    WebRtc_Word16 *Out,  /* (o)   Filtered vector */
+    WebRtc_Word16 *B,   /* (i)   The filter coefficients (in Q0) */
+    WebRtc_Word16 Blen,  /* (i)   Number of B coefficients */
+    WebRtc_Word16 len,   /* (i)  Number of samples to be filtered */
+    WebRtc_Word16 reduceDecay,
+    WebRtc_Word16 decay,
+    WebRtc_Word16 rshift )
+{
+  int i, j;
+  WebRtc_Word32 o;
+  WebRtc_Word32 lim;
+
+  lim = WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 15 + rshift )-1;
+
+  for (i = 0; i < len; i++)
+  {
+    G_CONST WebRtc_Word16 *b_ptr = &B[0];
+    G_CONST WebRtc_Word16 *x_ptr = &In[i];
+
+    o = (WebRtc_Word32)0;
+
+    for (j = 0;j < Blen; j++)
+    {
+      o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_MUL_16_16( *b_ptr, *x_ptr) );
+      b_ptr++;
+      x_ptr--;
+    }
+
+    /* to round off correctly */
+    o = WEBRTC_SPL_ADD_SAT_W32( o, WEBRTC_SPL_LSHIFT_W32( 1, (rshift-1) ) );
+
+    /* saturate according to the domain of the filter coefficients */
+    o = WEBRTC_SPL_SAT((WebRtc_Word32)lim, o, (WebRtc_Word32)-lim);
+
+    /* o should be in the range of WebRtc_Word16 */
+    o = WEBRTC_SPL_RSHIFT_W32( o, rshift );
+
+    /* decay the output signal; this is specific to plc */
+    *Out++ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16)o, decay, 15); // ((o + (WebRtc_Word32)2048) >> 12);
+
+    /* change the decay */
+    decay -= reduceDecay;
+    if( decay < 0 )
+      decay = 0;
+  }
+  return( decay );
+}
+
+
+
+
+
+
+
+
+static __inline WebRtc_Word32 log2_Q8_T( WebRtc_UWord32 x ) {
+
+  WebRtc_Word32 zeros, lg2;
+  WebRtc_Word16 frac;
+
+  zeros=WebRtcSpl_NormU32(x);
+  frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);
+  /* log2(magn(i)) */
+
+  lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac);
+  return lg2;
+
+}
+
+static __inline WebRtc_Word16  exp2_Q10_T(WebRtc_Word16 x) { // Both in and out in Q10
+
+  WebRtc_Word16 tmp16_1, tmp16_2;
+
+  tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF));
+  tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10);
+  if(tmp16_1>0)
+    return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
+  else
+    return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
+
+}
+
+
+/*
+  This is a fixed-point version of the above code with limLow = 700 and limHigh = 5000,
+  hard-coded. The values 700 and 5000 were experimentally obtained.
+
+  The function implements membership values for two sets. The mebership functions are
+  of second orders corresponding to half-bell-shapped pulses.
+*/
+static void MemshipValQ15( WebRtc_Word16 in, WebRtc_Word16 *A, WebRtc_Word16 *B )
+{
+  WebRtc_Word16 x;
+
+  in -= 700;    /* translate the lowLim to 0, limHigh = 5000 - 700, M = 2150 */
+
+  if( in <= 2150 )
+  {
+    if( in > 0 )
+    {
+      /* b = in^2 / (2 * M^2), a = 1 - b in Q0.
+         We have to compute in Q15 */
+
+      /* x = in / 2150 {in Q15} = x * 15.2409 {in Q15} =
+         x*15 + (x*983)/(2^12); note that 983/2^12 = 0.23999     */
+
+      /* we are sure that x is in the range of WebRtc_Word16            */
+      x = (WebRtc_Word16)( WEBRTC_SPL_MUL_16_16( in, 15 ) +
+                           WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
+      /* b = x^2 / 2 {in Q15} so a shift of 16 is required to
+         be in correct domain and one more for the division by 2 */
+      *B = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
+      *A = WEBRTC_SPL_WORD16_MAX - *B;
+    }
+    else
+    {
+      *B = 0;
+      *A = WEBRTC_SPL_WORD16_MAX;
+    }
+  }
+  else
+  {
+    if( in < 4300 )
+    {
+      /* This is a mirror case of the above */
+      in = 4300 - in;
+      x = (WebRtc_Word16)( WEBRTC_SPL_MUL_16_16( in, 15 ) +
+                           WEBRTC_SPL_MUL_16_16_RSFT( in, 983, 12) );
+      /* b = x^2 / 2 {in Q15} so a shift of 16 is required to
+         be in correct domain and one more for the division by 2 */
+      *A = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32( WEBRTC_SPL_MUL_16_16( x, x ) + 0x00010000, 17 );
+      *B = WEBRTC_SPL_WORD16_MAX - *A;
+
+    }
+    else
+    {
+      *A = 0;
+      *B = WEBRTC_SPL_WORD16_MAX;
+    }
+  }
+}
+
+
+
+
+static void LinearResampler( WebRtc_Word16 *in, WebRtc_Word16 *out, WebRtc_Word16 lenIn, WebRtc_Word16 lenOut )
+{
+  WebRtc_Word32 n;
+  WebRtc_Word16 resOut, i, j, relativePos, diff; /* */
+  WebRtc_UWord16 udiff;
+
+  if( lenIn == lenOut )
+  {
+    WEBRTC_SPL_MEMCPY_W16( out, in, lenIn );
+    return;
+  }
+
+  n = WEBRTC_SPL_MUL_16_16( (WebRtc_Word16)(lenIn-1), RESAMP_RES );
+  resOut = WebRtcSpl_DivW32W16ResW16( n, (WebRtc_Word16)(lenOut-1) );
+
+  out[0] = in[0];
+  for( i = 1, j = 0, relativePos = 0; i < lenOut; i++ )
+  {
+
+    relativePos += resOut;
+    while( relativePos > RESAMP_RES )
+    {
+      j++;
+      relativePos -= RESAMP_RES;
+    }
+
+
+    /* an overflow may happen and the differce in sample values may
+     * require more than 16 bits. We like to avoid 32 bit arithmatic
+     * as much as possible */
+
+    if( (in[ j ] > 0) && (in[j + 1] < 0) )
+    {
+      udiff = (WebRtc_UWord16)(in[ j ] - in[j + 1]);
+      out[ i ] = in[ j ] - (WebRtc_UWord16)( ((WebRtc_Word32)( udiff * relativePos )) >> RESAMP_RES_BIT);
+    }
+    else
+    {
+      if( (in[j] < 0) && (in[j+1] > 0) )
+      {
+        udiff = (WebRtc_UWord16)( in[j + 1] - in[ j ] );
+        out[ i ] = in[ j ] + (WebRtc_UWord16)( ((WebRtc_Word32)( udiff * relativePos )) >> RESAMP_RES_BIT);
+      }
+      else
+      {
+        diff = in[ j + 1 ] - in[ j ];
+        out[ i ] = in[ j ] + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT( diff, relativePos, RESAMP_RES_BIT );
+      }
+    }
+  }
+}
+
+
+
+
+
+WebRtc_Word16 WebRtcIsacfix_DecodePlcImpl(WebRtc_Word16 *signal_out16,
+                                          ISACFIX_DecInst_t *ISACdec_obj,
+                                          WebRtc_Word16 *current_framesamples )
+{
+  int subframecnt;
+  WebRtc_Word16 len = 0;
+
+  WebRtc_Word16* Vector_Word16_1;
+  WebRtc_Word16  Vector_Word16_Extended_1[FRAMESAMPLES_HALF + NOISE_FILTER_LEN];
+  WebRtc_Word16* Vector_Word16_2;
+  WebRtc_Word16  Vector_Word16_Extended_2[FRAMESAMPLES_HALF + NOISE_FILTER_LEN];
+
+  WebRtc_Word32 Vector_Word32_1[FRAMESAMPLES_HALF];
+  WebRtc_Word32 Vector_Word32_2[FRAMESAMPLES_HALF];
+
+  WebRtc_Word16 lofilt_coefQ15[ORDERLO*SUBFRAMES]; //refl. coeffs
+  WebRtc_Word16 hifilt_coefQ15[ORDERHI*SUBFRAMES]; //refl. coeffs
+
+  WebRtc_Word16 pitchLags_Q7[PITCH_SUBFRAMES];
+  WebRtc_Word16 pitchGains_Q12[PITCH_SUBFRAMES];
+
+  WebRtc_Word16 tmp_1, tmp_2;
+  WebRtc_Word32 tmp32a, tmp32b;
+  WebRtc_Word16 gainQ13;
+
+  WebRtc_Word16 myDecayRate;
+
+  /* ---------- PLC variables ------------ */
+  WebRtc_Word16 lag0, i, k, noiseIndex;
+  WebRtc_Word16 stretchPitchLP[PITCH_MAX_LAG + 10], stretchPitchLP1[PITCH_MAX_LAG + 10];
+
+  WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];
+
+  WebRtc_Word16 nLP, pLP, wNoisyLP, wPriodicLP, tmp16, minIdx;
+  WebRtc_Word32 nHP, pHP, wNoisyHP, wPriodicHP, corr, minCorr, maxCoeff;
+  WebRtc_Word16 noise1, rshift;
+
+
+  WebRtc_Word16 ltpGain, pitchGain, myVoiceIndicator, myAbs, maxAbs;
+  WebRtc_Word32 varIn, varOut, logVarIn, logVarOut, Q, logMaxAbs;
+  int rightShiftIn, rightShiftOut;
+
+
+  /* ------------------------------------- */
+
+
+  myDecayRate = (DECAY_RATE);
+  Vector_Word16_1 = &Vector_Word16_Extended_1[NOISE_FILTER_LEN];
+  Vector_Word16_2 = &Vector_Word16_Extended_2[NOISE_FILTER_LEN];
+
+
+  /* ----- Simply Copy Previous LPC parameters ------ */
+  for( subframecnt = 0; subframecnt < SUBFRAMES; subframecnt++ )
+  {
+    /* lower Band */
+    WEBRTC_SPL_MEMCPY_W16(&lofilt_coefQ15[ subframecnt * ORDERLO ],
+                          (ISACdec_obj->plcstr_obj).lofilt_coefQ15, ORDERLO);
+    gain_lo_hiQ17[2*subframecnt] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[0];
+
+    /* Upper Band */
+    WEBRTC_SPL_MEMCPY_W16(&hifilt_coefQ15[ subframecnt * ORDERHI ],
+                          (ISACdec_obj->plcstr_obj).hifilt_coefQ15, ORDERHI);
+    gain_lo_hiQ17[2*subframecnt + 1] = (ISACdec_obj->plcstr_obj).gain_lo_hiQ17[1];
+  }
+
+
+
+
+  lag0 = WEBRTC_SPL_RSHIFT_W16(
+      (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 + 64, 7 ) + 1;
+
+
+  if( (ISACdec_obj->plcstr_obj).used != PLC_WAS_USED )
+  {
+    (ISACdec_obj->plcstr_obj).pitchCycles = 0;
+
+    (ISACdec_obj->plcstr_obj).lastPitchLP =
+        &((ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0]);
+    minCorr = WEBRTC_SPL_WORD32_MAX;
+
+    if ( (FRAMESAMPLES_HALF - 2*lag0 - 10) > 0 )
+    {
+      minIdx = 11;
+      for( i = 0; i < 21; i++ )
+      {
+        corr = 0;
+        for( k = 0; k < lag0; k++ )
+        {
+          corr = WEBRTC_SPL_ADD_SAT_W32( corr, WEBRTC_SPL_ABS_W32(
+              WEBRTC_SPL_SUB_SAT_W16(
+                  (ISACdec_obj->plcstr_obj).lastPitchLP[k],
+                  (ISACdec_obj->plcstr_obj).prevPitchInvIn[
+                      FRAMESAMPLES_HALF - 2*lag0 - 10 + i + k ] ) ) );
+        }
+        if( corr < minCorr )
+        {
+          minCorr = corr;
+          minIdx = i;
+        }
+      }
+      (ISACdec_obj->plcstr_obj).prevPitchLP =
+          &( (ISACdec_obj->plcstr_obj).prevPitchInvIn[
+              FRAMESAMPLES_HALF - lag0*2 - 10 + minIdx] );
+    }
+    else
+    {
+      (ISACdec_obj->plcstr_obj).prevPitchLP =
+          (ISACdec_obj->plcstr_obj).lastPitchLP;
+    }
+    pitchGain = (ISACdec_obj->plcstr_obj).lastPitchGain_Q12;
+
+    WebRtcSpl_AutoCorrelation(
+        &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF - lag0],
+        lag0, 0, &varIn, &rightShiftIn);
+    WebRtcSpl_AutoCorrelation(
+        &(ISACdec_obj->plcstr_obj).prevPitchInvOut[PITCH_MAX_LAG + 10 - lag0],
+        lag0, 0, &varOut, &rightShiftOut);
+
+    maxAbs = 0;
+    for( i = 0; i< lag0; i++)
+    {
+      myAbs = WEBRTC_SPL_ABS_W16(
+          (ISACdec_obj->plcstr_obj).prevPitchInvOut[
+              PITCH_MAX_LAG + 10 - lag0 + i] );
+      maxAbs = (myAbs > maxAbs)? myAbs:maxAbs;
+    }
+    logVarIn = log2_Q8_T( (WebRtc_UWord32)( varIn ) ) +
+        (WebRtc_Word32)(rightShiftIn << 8);
+    logVarOut = log2_Q8_T( (WebRtc_UWord32)( varOut ) ) +
+        (WebRtc_Word32)(rightShiftOut << 8);
+    logMaxAbs = log2_Q8_T( (WebRtc_UWord32)( maxAbs ) );
+
+    ltpGain = (WebRtc_Word16)(logVarOut - logVarIn);
+    Q = 2 * logMaxAbs - ( logVarOut - 1512 );
+
+    /*
+     * ---
+     * We are computing sqrt( (VarIn/lag0) / var( noise ) )
+     * var( noise ) is almost 256. we have already computed log2( VarIn ) in Q8
+     * so we actually compute 2^( 0.5*(log2( VarIn ) - log2( lag0 ) - log2( var(noise ) )  ).
+     * Note that put log function is in Q8 but the exponential function is in Q10.
+     * --
+     */
+
+    logVarIn -= log2_Q8_T( (WebRtc_UWord32)( lag0 ) );
+    tmp16 = (WebRtc_Word16)((logVarIn<<1) - (4<<10) );
+    rightShiftIn = 0;
+    if( tmp16 > 4096 )
+    {
+      tmp16 -= 4096;
+      tmp16 = exp2_Q10_T( tmp16 );
+      tmp16 >>= 6;
+    }
+    else
+      tmp16 = exp2_Q10_T( tmp16 )>>10;
+
+    (ISACdec_obj->plcstr_obj).std = tmp16 - 4;
+
+    if( (ltpGain < 110) || (ltpGain > 230) )
+    {
+      if( ltpGain < 100 && (pitchGain < 1800) )
+      {
+        (ISACdec_obj->plcstr_obj).A = WEBRTC_SPL_WORD16_MAX;
+      }
+      else
+      {
+        (ISACdec_obj->plcstr_obj).A = ((ltpGain < 110) && (Q < 800)
+                                       )? WEBRTC_SPL_WORD16_MAX:0;
+      }
+      (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX -
+          (ISACdec_obj->plcstr_obj).A;
+    }
+    else
+    {
+      if( (pitchGain < 450) || (pitchGain > 1600) )
+      {
+        (ISACdec_obj->plcstr_obj).A = ((pitchGain < 450)
+                                       )? WEBRTC_SPL_WORD16_MAX:0;
+        (ISACdec_obj->plcstr_obj).B = WEBRTC_SPL_WORD16_MAX -
+            (ISACdec_obj->plcstr_obj).A;
+      }
+      else
+      {
+        myVoiceIndicator = ltpGain * 2 + pitchGain;
+        MemshipValQ15( myVoiceIndicator,
+                       &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B );
+      }
+    }
+
+
+
+    myVoiceIndicator = ltpGain * 16 + pitchGain * 2 + (pitchGain >> 8);
+    MemshipValQ15( myVoiceIndicator,
+                   &(ISACdec_obj->plcstr_obj).A, &(ISACdec_obj->plcstr_obj).B );
+
+
+
+    (ISACdec_obj->plcstr_obj).stretchLag = lag0;
+    (ISACdec_obj->plcstr_obj).pitchIndex = 0;
+
+  }
+  else
+  {
+    myDecayRate = (DECAY_RATE<<2);
+  }
+
+  if( (ISACdec_obj->plcstr_obj).B < 1000 )
+  {
+    myDecayRate += (DECAY_RATE<<3);
+  }
+
+  /* ------------ reconstructing the residual signal ------------------ */
+
+  LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP,
+                   stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
+  /* inverse pitch filter */
+
+  pitchLags_Q7[0] = pitchLags_Q7[1] = pitchLags_Q7[2] = pitchLags_Q7[3] =
+      ((ISACdec_obj->plcstr_obj).stretchLag<<7);
+  pitchGains_Q12[3] = ( (ISACdec_obj->plcstr_obj).lastPitchGain_Q12);
+  pitchGains_Q12[2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+      pitchGains_Q12[3], 1010, 10 );
+  pitchGains_Q12[1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+      pitchGains_Q12[2], 1010, 10 );
+  pitchGains_Q12[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+      pitchGains_Q12[1], 1010, 10 );
+
+
+  /* most of the time either B or A are zero so seperating */
+  if( (ISACdec_obj->plcstr_obj).B == 0 )
+  {
+    for( i = 0; i < FRAMESAMPLES_HALF; i++ )
+    {
+      /* --- Low Pass                                             */
+      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
+          (ISACdec_obj->plcstr_obj).seed );
+      Vector_Word16_1[i] = WEBRTC_SPL_RSHIFT_W16(
+          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
+
+      /* --- Highpass                                              */
+      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
+          (ISACdec_obj->plcstr_obj).seed );
+      Vector_Word16_2[i] = WEBRTC_SPL_RSHIFT_W16(
+          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
+
+    }
+    for( i = 1; i < NOISE_FILTER_LEN; i++ )
+    {
+      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
+          (ISACdec_obj->plcstr_obj).seed );
+      Vector_Word16_Extended_1[ i ] = WEBRTC_SPL_RSHIFT_W16(
+          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
+
+      (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
+          (ISACdec_obj->plcstr_obj).seed );
+      Vector_Word16_Extended_2[ i ] = WEBRTC_SPL_RSHIFT_W16(
+          (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
+    }
+    plc_filterma_Fast(Vector_Word16_1, Vector_Word16_Extended_1,
+                      &(ISACdec_obj->plcstr_obj).prevPitchInvIn[FRAMESAMPLES_HALF -
+                                                                NOISE_FILTER_LEN], (WebRtc_Word16) NOISE_FILTER_LEN,
+                      (WebRtc_Word16) FRAMESAMPLES_HALF, (WebRtc_Word16)(5),
+                      (ISACdec_obj->plcstr_obj).decayCoeffNoise, (WebRtc_Word16)(6));
+
+    maxCoeff = WebRtcSpl_MaxAbsValueW32(
+        &(ISACdec_obj->plcstr_obj).prevHP[
+            PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN], NOISE_FILTER_LEN );
+
+    rshift = 0;
+    while( maxCoeff > WEBRTC_SPL_WORD16_MAX )
+    {
+      maxCoeff = WEBRTC_SPL_RSHIFT_W32(maxCoeff, 1);
+      rshift++;
+    }
+    for( i = 0; i < NOISE_FILTER_LEN; i++ ) {
+      Vector_Word16_1[ FRAMESAMPLES_HALF - NOISE_FILTER_LEN + i] =
+          (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(
+              (ISACdec_obj->plcstr_obj).prevHP[
+                  PITCH_MAX_LAG + 10 - NOISE_FILTER_LEN + i], rshift);
+    }
+    (ISACdec_obj->plcstr_obj).decayCoeffNoise = plc_filterma_Fast(
+        Vector_Word16_2,
+        Vector_Word16_Extended_2,
+        &Vector_Word16_1[FRAMESAMPLES_HALF - NOISE_FILTER_LEN],
+        (WebRtc_Word16) NOISE_FILTER_LEN,
+        (WebRtc_Word16) FRAMESAMPLES_HALF,
+        (WebRtc_Word16) (5),
+        (ISACdec_obj->plcstr_obj).decayCoeffNoise,
+        (WebRtc_Word16) (7) );
+
+    for( i = 0; i < FRAMESAMPLES_HALF; i++ )
+      Vector_Word32_2[i] = WEBRTC_SPL_LSHIFT_W32(
+          (WebRtc_Word32)Vector_Word16_Extended_2[i], rshift );
+
+    Vector_Word16_1 = Vector_Word16_Extended_1;
+  }
+  else
+  {
+    if( (ISACdec_obj->plcstr_obj).A == 0 )
+    {
+      /* ------ Periodic Vector ---                                */
+      for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ )
+      {
+        /* --- Lowpass                                               */
+        pLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+            stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex],
+            (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 );
+
+        /* --- Highpass                                              */
+        pHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15(
+            (ISACdec_obj->plcstr_obj).decayCoeffPriodic,
+            (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 -
+                                             (ISACdec_obj->plcstr_obj).stretchLag +
+                                             (ISACdec_obj->plcstr_obj).pitchIndex] );
+
+        /* --- lower the muliplier (more decay at next sample) --- */
+        (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate);
+        if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 )
+          (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0;
+
+        (ISACdec_obj->plcstr_obj).pitchIndex++;
+
+        if( (ISACdec_obj->plcstr_obj).pitchIndex ==
+            (ISACdec_obj->plcstr_obj).stretchLag )
+        {
+          (ISACdec_obj->plcstr_obj).pitchIndex = 0;
+          (ISACdec_obj->plcstr_obj).pitchCycles++;
+
+          if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) )
+          {
+            (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1;
+          }
+          else
+          {
+            (ISACdec_obj->plcstr_obj).stretchLag = lag0;
+          }
+
+          (ISACdec_obj->plcstr_obj).stretchLag = (
+              (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG
+                                                  )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag;
+
+          LinearResampler( (ISACdec_obj->plcstr_obj).lastPitchLP,
+                           stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
+
+          LinearResampler( (ISACdec_obj->plcstr_obj).prevPitchLP,
+                           stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
+
+          switch( (ISACdec_obj->plcstr_obj).pitchCycles )
+          {
+            case 1:
+              {
+                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
+                {
+                  stretchPitchLP[k] = (WebRtc_Word16)((
+                      (WebRtc_Word32)stretchPitchLP[k]* 3 +
+                      (WebRtc_Word32)stretchPitchLP1[k])>>2);
+                }
+                break;
+              }
+            case 2:
+              {
+                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
+                {
+                  stretchPitchLP[k] = (WebRtc_Word16)((
+                      (WebRtc_Word32)stretchPitchLP[k] +
+                      (WebRtc_Word32)stretchPitchLP1[k] )>>1);
+                }
+                break;
+              }
+            case 3:
+              {
+                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
+                {
+                  stretchPitchLP[k] = (WebRtc_Word16)((stretchPitchLP[k] +
+                                                       (WebRtc_Word32)stretchPitchLP1[k]*3 )>>2);
+                }
+                break;
+              }
+          }
+
+          if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 )
+          {
+            myDecayRate += 35; //(myDecayRate>>1);
+            (ISACdec_obj->plcstr_obj).pitchCycles = 0;
+          }
+
+        }
+
+        /* ------ Sum the noisy and periodic signals  ------ */
+        Vector_Word16_1[i] = pLP;
+        Vector_Word32_2[i] = pHP;
+      }
+    }
+    else
+    {
+      for( i = 0, noiseIndex = 0; i < FRAMESAMPLES_HALF; i++, noiseIndex++ )
+      {
+
+        (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
+            (ISACdec_obj->plcstr_obj).seed );
+
+        noise1 = WEBRTC_SPL_RSHIFT_W16(
+            (ISACdec_obj->plcstr_obj).seed, 10 ) - 16;
+
+        nLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+            (WebRtc_Word16)((noise1)*(ISACdec_obj->plcstr_obj).std),
+            (ISACdec_obj->plcstr_obj).decayCoeffNoise, 15 );
+
+        /* --- Highpass                                              */
+        (ISACdec_obj->plcstr_obj).seed = WEBRTC_SPL_RAND(
+            (ISACdec_obj->plcstr_obj).seed );
+        noise1 = WEBRTC_SPL_RSHIFT_W16(
+            (ISACdec_obj->plcstr_obj).seed, 11 ) - 8;
+
+        nHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15(
+            (ISACdec_obj->plcstr_obj).decayCoeffNoise,
+            (WebRtc_Word32)(noise1*(ISACdec_obj->plcstr_obj).std) );
+
+        /* --- lower the muliplier (more decay at next sample) --- */
+        (ISACdec_obj->plcstr_obj).decayCoeffNoise -= (myDecayRate);
+        if( (ISACdec_obj->plcstr_obj).decayCoeffNoise < 0 )
+          (ISACdec_obj->plcstr_obj).decayCoeffNoise = 0;
+
+        /* ------ Periodic Vector ---                                */
+        /* --- Lowpass                                               */
+        pLP = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+            stretchPitchLP[(ISACdec_obj->plcstr_obj).pitchIndex],
+            (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15 );
+
+        /* --- Highpass                                              */
+        pHP = (WebRtc_Word32)WEBRTC_SPL_MUL_16_32_RSFT15(
+            (ISACdec_obj->plcstr_obj).decayCoeffPriodic,
+            (ISACdec_obj->plcstr_obj).prevHP[PITCH_MAX_LAG + 10 -
+                                             (ISACdec_obj->plcstr_obj).stretchLag +
+                                             (ISACdec_obj->plcstr_obj).pitchIndex] );
+
+        /* --- lower the muliplier (more decay at next sample) --- */
+        (ISACdec_obj->plcstr_obj).decayCoeffPriodic -= (myDecayRate);
+        if( (ISACdec_obj->plcstr_obj).decayCoeffPriodic < 0 )
+        {
+          (ISACdec_obj->plcstr_obj).decayCoeffPriodic = 0;
+        }
+
+        /* ------ Weighting the noisy and periodic vectors -------   */
+        wNoisyLP = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT(
+            (ISACdec_obj->plcstr_obj).A, nLP, 15 ) );
+        wNoisyHP = (WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT15(
+            (ISACdec_obj->plcstr_obj).A, (nHP) ) );
+
+        wPriodicLP = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16_RSFT(
+            (ISACdec_obj->plcstr_obj).B, pLP, 15));
+        wPriodicHP = (WebRtc_Word32)(WEBRTC_SPL_MUL_16_32_RSFT15(
+            (ISACdec_obj->plcstr_obj).B, pHP));
+
+        (ISACdec_obj->plcstr_obj).pitchIndex++;
+
+        if((ISACdec_obj->plcstr_obj).pitchIndex ==
+           (ISACdec_obj->plcstr_obj).stretchLag)
+        {
+          (ISACdec_obj->plcstr_obj).pitchIndex = 0;
+          (ISACdec_obj->plcstr_obj).pitchCycles++;
+
+          if( (ISACdec_obj->plcstr_obj).stretchLag != (lag0 + 1) )
+            (ISACdec_obj->plcstr_obj).stretchLag = lag0 + 1;
+          else
+            (ISACdec_obj->plcstr_obj).stretchLag = lag0;
+
+          (ISACdec_obj->plcstr_obj).stretchLag = (
+              (ISACdec_obj->plcstr_obj).stretchLag > PITCH_MAX_LAG
+                                                  )? (PITCH_MAX_LAG):(ISACdec_obj->plcstr_obj).stretchLag;
+          LinearResampler(
+              (ISACdec_obj->plcstr_obj).lastPitchLP,
+              stretchPitchLP, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
+
+          LinearResampler((ISACdec_obj->plcstr_obj).prevPitchLP,
+                          stretchPitchLP1, lag0, (ISACdec_obj->plcstr_obj).stretchLag );
+
+          switch((ISACdec_obj->plcstr_obj).pitchCycles)
+          {
+            case 1:
+              {
+                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
+                {
+                  stretchPitchLP[k] = (WebRtc_Word16)((
+                      (WebRtc_Word32)stretchPitchLP[k]* 3 +
+                      (WebRtc_Word32)stretchPitchLP1[k] )>>2);
+                }
+                break;
+              }
+            case 2:
+              {
+                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
+                {
+                  stretchPitchLP[k] = (WebRtc_Word16)((
+                      (WebRtc_Word32)stretchPitchLP[k] +
+                      (WebRtc_Word32)stretchPitchLP1[k])>>1);
+                }
+                break;
+              }
+            case 3:
+              {
+                for( k=0; k<(ISACdec_obj->plcstr_obj).stretchLag; k++ )
+                {
+                  stretchPitchLP[k] = (WebRtc_Word16)(
+                      (stretchPitchLP[k] +
+                       (WebRtc_Word32)stretchPitchLP1[k]*3 )>>2);
+                }
+                break;
+              }
+          }
+
+          if( (ISACdec_obj->plcstr_obj).pitchCycles == 3 )
+          {
+            myDecayRate += 55; //(myDecayRate>>1);
+            (ISACdec_obj->plcstr_obj).pitchCycles = 0;
+          }
+        }
+
+        /* ------ Sum the noisy and periodic signals  ------ */
+        Vector_Word16_1[i] = (WebRtc_Word16)WEBRTC_SPL_ADD_SAT_W16(
+            wNoisyLP, wPriodicLP );
+        Vector_Word32_2[i] = (WebRtc_Word32)WEBRTC_SPL_ADD_SAT_W32(
+            wNoisyHP, wPriodicHP );
+      }
+    }
+  }
+  /* ----------------- residual signal is reconstructed ------------------ */
+
+  k = (ISACdec_obj->plcstr_obj).pitchIndex;
+  /* --- Write one pitch cycle for recovery block --- */
+
+  for( i = 0; i < RECOVERY_OVERLAP; i++ )
+  {
+    (ISACdec_obj->plcstr_obj).overlapLP[i] = (WebRtc_Word16)(
+        WEBRTC_SPL_MUL_16_16_RSFT(stretchPitchLP[k],
+                                  (ISACdec_obj->plcstr_obj).decayCoeffPriodic, 15) );
+    k = ( k < ((ISACdec_obj->plcstr_obj).stretchLag - 1) )? (k+1):0;
+  }
+
+  (ISACdec_obj->plcstr_obj).lastPitchLag_Q7 = (ISACdec_obj->plcstr_obj).stretchLag << 7;
+
+
+  /* --- Inverse Pitch Filter --- */
+  WebRtcIsacfix_PitchFilter(Vector_Word16_1, Vector_Word16_2,
+                            &ISACdec_obj->pitchfiltstr_obj, pitchLags_Q7, pitchGains_Q12, 4);
+
+  /* reduce gain to compensate for pitch enhancer */
+  /* gain = 1.0f - 0.45f * AvgPitchGain; */
+  tmp32a = WEBRTC_SPL_MUL_16_16_RSFT((ISACdec_obj->plcstr_obj).AvgPitchGain_Q12,
+                                     29, 0); // Q18
+  tmp32b = 262144 - tmp32a;  // Q18
+  gainQ13 = (WebRtc_Word16) (tmp32b >> 5); // Q13
+
+  /* perceptual post-filtering (using normalized lattice filter) */
+  for (k = 0; k < FRAMESAMPLES_HALF; k++)
+    Vector_Word32_1[k] = (WebRtc_Word32) WEBRTC_SPL_MUL_16_16(
+        Vector_Word16_2[k], gainQ13) << 3; // Q25
+
+
+  WebRtcIsacfix_NormLatticeFilterAr(ORDERLO,
+                                    (ISACdec_obj->maskfiltstr_obj).PostStateLoGQ0,
+                                    Vector_Word32_1, lofilt_coefQ15, gain_lo_hiQ17, 0, Vector_Word16_1);
+
+  WebRtcIsacfix_NormLatticeFilterAr(ORDERHI,
+                                    (ISACdec_obj->maskfiltstr_obj).PostStateHiGQ0,
+                                    Vector_Word32_2, hifilt_coefQ15, gain_lo_hiQ17, 1, Vector_Word16_2);
+
+  /* recombine the 2 bands */
+
+  /* Form the polyphase signals, and compensate for DC offset */
+  for (k=0;k<FRAMESAMPLES_HALF;k++)
+  {
+    /* Construct a new upper channel signal*/
+    tmp_1 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(
+                                           ((WebRtc_Word32)Vector_Word16_1[k]+Vector_Word16_2[k] + 1));
+    /* Construct a new lower channel signal*/
+    tmp_2 = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(
+                                           ((WebRtc_Word32)Vector_Word16_1[k]-Vector_Word16_2[k]));
+    Vector_Word16_1[k] = tmp_1;
+    Vector_Word16_2[k] = tmp_2;
+  }
+
+
+  WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
+                                  Vector_Word16_2, signal_out16, &ISACdec_obj->postfiltbankstr_obj);
+
+  (ISACdec_obj->plcstr_obj).used = PLC_WAS_USED;
+  *current_framesamples = 480;
+
+  return len;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/encode.c b/src/modules/audio_coding/codecs/isac/fix/source/encode.c
new file mode 100644
index 0000000..cb531e5
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/encode.c
@@ -0,0 +1,626 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * encode.c
+ *
+ * Encoding function for the iSAC coder.
+ *
+ */
+
+#include "arith_routins.h"
+#include "bandwidth_estimator.h"
+#include "codec.h"
+#include "pitch_gain_tables.h"
+#include "pitch_lag_tables.h"
+#include "entropy_coding.h"
+#include "lpc_tables.h"
+#include "lpc_masking_model.h"
+#include "pitch_estimator.h"
+#include "structs.h"
+#include <stdio.h>
+
+
+int WebRtcIsacfix_EncodeImpl(WebRtc_Word16      *in,
+                         ISACFIX_EncInst_t  *ISACenc_obj,
+                         BwEstimatorstr      *bw_estimatordata,
+                         WebRtc_Word16         CodingMode)
+{
+  WebRtc_Word16 stream_length = 0;
+  WebRtc_Word16 usefulstr_len = 0;
+  int k;
+  WebRtc_Word16 BWno;
+
+  WebRtc_Word16 lofilt_coefQ15[(ORDERLO)*SUBFRAMES];
+  WebRtc_Word16 hifilt_coefQ15[(ORDERHI)*SUBFRAMES];
+  WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES];
+
+  WebRtc_Word16 LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD];
+  WebRtc_Word16 LP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
+  WebRtc_Word16 HP16a[FRAMESAMPLES/2 + QLOOKAHEAD];
+
+  WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES];
+  WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES];
+  WebRtc_Word16 AvgPitchGain_Q12;
+
+  WebRtc_Word16 frame_mode; /* 0 for 30ms, 1 for 60ms */
+  WebRtc_Word16 processed_samples;
+  int status;
+
+  WebRtc_Word32 bits_gainsQ11;
+  WebRtc_Word16 MinBytes;
+  WebRtc_Word16 bmodel;
+
+  transcode_obj transcodingParam;
+  WebRtc_Word16 payloadLimitBytes;
+  WebRtc_Word16 arithLenBeforeEncodingDFT;
+  WebRtc_Word16 iterCntr;
+
+  /* copy new frame length and bottle neck rate only for the first 10 ms data */
+  if (ISACenc_obj->buffer_index == 0) {
+    /* set the framelength for the next packet */
+    ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength;
+  }
+
+  frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms)  */
+  processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */
+
+  /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */
+  /**************************************************************************************/
+  /* fill the buffer with 10ms input data */
+  for(k=0; k<FRAMESAMPLES_10ms; k++) {
+    ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k];
+  }
+  /* if buffersize is not equal to current framesize, and end of file is not reached yet, */
+  /* increase index and go back to main to get more speech samples */
+  if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) {
+    ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms;
+    return 0;
+  }
+  /* if buffer reached the right size, reset index and continue with encoding the frame */
+  ISACenc_obj->buffer_index = 0;
+
+  /* end of buffer function */
+  /**************************/
+
+  /* encoding */
+  /************/
+
+  if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 )
+  {
+    /* reset bitstream */
+    ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
+    ISACenc_obj->bitstr_obj.streamval = 0;
+    ISACenc_obj->bitstr_obj.stream_index = 0;
+    ISACenc_obj->bitstr_obj.full = 1;
+
+    if (CodingMode == 0) {
+      ISACenc_obj->BottleNeck =  WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata);
+      ISACenc_obj->MaxDelay =  WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata);
+    }
+    if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
+      ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
+                                                                     ISACenc_obj->current_framesamples);
+    }
+
+    // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT
+    // 901/1024 is 0.87988281250000
+    ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr((WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ISACenc_obj->BottleNeck, 901, 10),
+                                             ISACenc_obj->current_framesamples);
+
+    /* encode frame length */
+    status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj);
+    if (status < 0)
+    {
+      /* Wrong frame size */
+      if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+      {
+        // If this is the second 30ms of a 60ms frame reset this such that in the next call
+        // encoder starts fresh.
+        ISACenc_obj->frame_nb = 0;
+      }
+      return status;
+    }
+
+    /* Save framelength for multiple packets memory */
+    if (ISACenc_obj->SaveEnc_ptr != NULL) {
+      (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples;
+    }
+
+    /* bandwidth estimation and coding */
+    BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata);
+    status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
+    if (status < 0)
+    {
+      if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+      {
+        // If this is the second 30ms of a 60ms frame reset this such that in the next call
+        // encoder starts fresh.
+        ISACenc_obj->frame_nb = 0;
+      }
+      return status;
+    }
+  }
+
+  /* split signal in two bands */
+  WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj );
+
+  /* estimate pitch parameters and pitch-filter lookahead signal */
+  WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP,
+                              &ISACenc_obj->pitchanalysisstr_obj,  PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */
+
+  /* Set where to store data in multiple packets memory */
+  if (ISACenc_obj->SaveEnc_ptr != NULL) {
+    if (frame_mode == 0 || ISACenc_obj->frame_nb == 0)
+    {
+      (ISACenc_obj->SaveEnc_ptr)->startIdx = 0;
+    }
+    else
+    {
+      (ISACenc_obj->SaveEnc_ptr)->startIdx = 1;
+    }
+  }
+
+  /* quantize & encode pitch parameters */
+  status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
+  if (status < 0)
+  {
+    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+    {
+      // If this is the second 30ms of a 60ms frame reset this such that in the next call
+      // encoder starts fresh.
+      ISACenc_obj->frame_nb = 0;
+    }
+    return status;
+  }
+  status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj,  ISACenc_obj->SaveEnc_ptr);
+  if (status < 0)
+  {
+    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+    {
+      // If this is the second 30ms of a 60ms frame reset this such that in the next call
+      // encoder starts fresh.
+      ISACenc_obj->frame_nb = 0;
+    }
+    return status;
+  }
+  AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2);
+
+  /* find coefficients for perceptual pre-filters */
+  WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj,
+                           ISACenc_obj->s2nr, PitchGains_Q12,
+                           gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/
+
+  // record LPC Gains for possible bit-rate reduction
+  for(k = 0; k < KLT_ORDER_GAIN; k++)
+  {
+    transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
+  }
+
+  /* code LPC model and shape - gains not quantized yet */
+  status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15,
+                                   &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam);
+  if (status < 0)
+  {
+    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+    {
+      // If this is the second 30ms of a 60ms frame reset this such that in the next call
+      // encoder starts fresh.
+      ISACenc_obj->frame_nb = 0;
+    }
+    return status;
+  }
+  arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
+
+  /* low-band filtering */
+  WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15,
+                                    LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */
+
+  /* pitch filter */
+  WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */
+
+  /* high-band filtering */
+  WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15,
+                                    HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/
+
+  /* transform */
+  WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/
+
+  /* Save data for multiple packets memory */
+  if (ISACenc_obj->SaveEnc_ptr != NULL) {
+    for (k = 0; k < FRAMESAMPLES_HALF; k++) {
+      (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
+      (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
+    }
+    (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12;
+  }
+
+  /* quantization and lossless coding */
+  status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
+  if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
+  {
+    if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+    {
+      // If this is the second 30ms of a 60ms frame reset this such that in the next call
+      // encoder starts fresh.
+      ISACenc_obj->frame_nb = 0;
+    }
+    return status;
+  }
+
+  if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
+  {
+    // it is a 60ms and we are in the first 30ms
+    // then the limit at this point should be half of the assigned value
+    payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1;
+  }
+  else if (frame_mode == 0)
+  {
+    // it is a 30ms frame
+    payloadLimitBytes = (ISACenc_obj->payloadLimitBytes30) - 3;
+  }
+  else
+  {
+    // this is the second half of a 60ms frame.
+    payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 - 3; // subract 3 because termination process may add 3 bytes
+  }
+
+  iterCntr = 0;
+  while((((ISACenc_obj->bitstr_obj.stream_index) << 1) > payloadLimitBytes) ||
+        (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH))
+  {
+    WebRtc_Word16 arithLenDFTByte;
+    WebRtc_Word16 bytesLeftQ5;
+    WebRtc_Word16 ratioQ5[8] = {0, 6, 9, 12, 16, 19, 22, 25};
+
+    // According to experiments on TIMIT the following is proper for audio, but it is not agressive enough for tonal inputs
+    // such as DTMF, sweep-sine, ...
+    //
+    // (0.55 - (0.8 - ratio[i]/32) * 5 / 6) * 2^14
+    // WebRtc_Word16 scaleQ14[8] = {0, 648, 1928, 3208, 4915, 6195, 7475, 8755};
+
+
+    // This is a supper-agressive scaling passed the tests (tonal inputs) tone with one iteration for payload limit
+    // of 120 (32kbps bottleneck), number of frames needed a rate-reduction was 58403
+    //
+    WebRtc_Word16 scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500};
+    WebRtc_Word16 idx;
+
+    if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION)
+    {
+      // We were not able to limit the payload size
+
+      if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0))
+      {
+        // This was the first 30ms of a 60ms frame. Although the payload is larger than it
+        // should be but we let the second 30ms be encoded. Maybe togetehr we won't exceed
+        // the limit.
+        ISACenc_obj->frame_nb = 1;
+        return 0;
+      }
+      else if((frame_mode == 1) && (ISACenc_obj->frame_nb == 1))
+      {
+        ISACenc_obj->frame_nb = 0;
+      }
+
+      if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
+      {
+        return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
+      }
+      else
+      {
+        return status;
+      }
+    }
+    if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)
+    {
+      arithLenDFTByte = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full) - arithLenBeforeEncodingDFT;
+      bytesLeftQ5 = (payloadLimitBytes - arithLenBeforeEncodingDFT) << 5;
+
+      // bytesLeft / arithLenDFTBytes indicates how much scaling is required a rough estimate (agressive)
+      // scale = 0.55 - (0.8 - bytesLeft / arithLenDFTBytes) * 5 / 6
+      // bytesLeft / arithLenDFTBytes below 0.2 will have a scale of zero and above 0.8 are treated as 0.8
+      // to avoid division we do more simplification.
+      //
+      // values of (bytesLeft / arithLenDFTBytes)*32 between ratioQ5[i] and ratioQ5[i+1] are rounded to ratioQ5[i]
+      // and the corresponding scale is chosen
+
+      // we compare bytesLeftQ5 with ratioQ5[]*arithLenDFTByte;
+      idx = 4;
+      idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 2:-2;
+      idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 1:-1;
+      idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 0:-1;
+    }
+    else
+    {
+      // we are here because the bit-stream did not fit into the buffer, in this case, the stream_index is not
+      // trustable, especially if the is the first 30ms of a packet. Thereforem, we will go for the most agressive
+      // case.
+      idx = 0;
+    }
+    // scale FFT coefficients to reduce the bit-rate
+    for(k = 0; k < FRAMESAMPLES_HALF; k++)
+    {
+      LP16a[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LP16a[k], scaleQ14[idx], 14);
+      LPandHP[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LPandHP[k], scaleQ14[idx], 14);
+    }
+
+    // Save data for multiple packets memory
+    if (ISACenc_obj->SaveEnc_ptr != NULL)
+    {
+      for(k = 0; k < FRAMESAMPLES_HALF; k++)
+      {
+        (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k];
+        (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k];
+      }
+    }
+
+    // scale the unquantized LPC gains and save the scaled version for the future use
+    for(k = 0; k < KLT_ORDER_GAIN; k++)
+    {
+      gain_lo_hiQ17[k] = WEBRTC_SPL_MUL_16_32_RSFT14(scaleQ14[idx], transcodingParam.lpcGains[k]);//transcodingParam.lpcGains[k]; //
+      transcodingParam.lpcGains[k] = gain_lo_hiQ17[k];
+    }
+
+    // reset the bit-stream object to the state which it had before encoding LPC Gains
+    ISACenc_obj->bitstr_obj.full = transcodingParam.full;
+    ISACenc_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
+    ISACenc_obj->bitstr_obj.streamval = transcodingParam.streamval;
+    ISACenc_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
+    ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index-1] = transcodingParam.beforeLastWord;
+    ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.lastWord;
+
+
+    // quantize and encode LPC gain
+    WebRtcIsacfix_EstCodeLpcGain(gain_lo_hiQ17, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr);
+    arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full);
+    status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12);
+    if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/
+    {
+      if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+      {
+        // If this is the second 30ms of a 60ms frame reset this such that in the next call
+        // encoder starts fresh.
+        ISACenc_obj->frame_nb = 0;
+      }
+      return status;
+    }
+    iterCntr++;
+  }
+
+  if (frame_mode == 1 && ISACenc_obj->frame_nb == 0)
+    /* i.e. 60 ms framesize and just processed the first 30ms, */
+    /* go back to main function to buffer the other 30ms speech frame */
+  {
+    ISACenc_obj->frame_nb = 1;
+    return 0;
+  }
+  else if (frame_mode == 1 && ISACenc_obj->frame_nb == 1)
+  {
+    ISACenc_obj->frame_nb = 0;
+    /* also update the framelength for next packet, in Adaptive mode only */
+    if (CodingMode == 0 && (ISACenc_obj->enforceFrameSize == 0)) {
+      ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck,
+                                                                     ISACenc_obj->current_framesamples);
+    }
+  }
+
+
+  /* complete arithmetic coding */
+  stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
+  /* can this be negative? */
+
+  if(CodingMode == 0)
+  {
+
+    /* update rate model and get minimum number of bytes in this packet */
+    MinBytes = WebRtcIsacfix_GetMinBytes(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length,
+                                         ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck, ISACenc_obj->MaxDelay);
+
+    /* if bitstream is too short, add garbage at the end */
+
+    /* Store length of coded data */
+    usefulstr_len = stream_length;
+
+    /* Make sure MinBytes does not exceed packet size limit */
+    if ((ISACenc_obj->frame_nb == 0) && (MinBytes > ISACenc_obj->payloadLimitBytes30)) {
+      MinBytes = ISACenc_obj->payloadLimitBytes30;
+    } else if ((ISACenc_obj->frame_nb == 1) && (MinBytes > ISACenc_obj->payloadLimitBytes60)) {
+      MinBytes = ISACenc_obj->payloadLimitBytes60;
+    }
+
+    /* Make sure we don't allow more than 255 bytes of garbage data.
+       We store the length of the garbage data in 8 bits in the bitstream,
+       255 is the max garbage lenght we can signal using 8 bits. */
+    if( MinBytes > usefulstr_len + 255 ) {
+      MinBytes = usefulstr_len + 255;
+    }
+
+    /* Save data for creation of multiple bitstreams */
+    if (ISACenc_obj->SaveEnc_ptr != NULL) {
+      (ISACenc_obj->SaveEnc_ptr)->minBytes = MinBytes;
+    }
+
+    while (stream_length < MinBytes)
+    {
+      if (stream_length & 0x0001){
+        ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
+        ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] |= (WebRtc_UWord16)(ISACenc_obj->bitstr_seed & 0xFF);
+      } else {
+        ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed );
+        ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] = WEBRTC_SPL_LSHIFT_U16(ISACenc_obj->bitstr_seed, 8);
+      }
+      stream_length++;
+    }
+
+    /* to get the real stream_length, without garbage */
+    if (usefulstr_len & 0x0001) {
+      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0xFF00;
+      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += (MinBytes - usefulstr_len) & 0x00FF;
+    }
+    else {
+      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0x00FF;
+      ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += WEBRTC_SPL_LSHIFT_U16((MinBytes - usefulstr_len) & 0x00FF, 8);
+    }
+  }
+  else
+  {
+    /* update rate model */
+    WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length,
+                                  ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck);
+  }
+  return stream_length;
+}
+
+/* This function is used to create a new bitstream with new BWE.
+   The same data as previously encoded with the fucntion WebRtcIsacfix_EncodeImpl()
+   is used. The data needed is taken from the struct, where it was stored
+   when calling the encoder. */
+int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t  *ISACenc_obj,
+                                   int     BWnumber,
+                                   float              scale)
+{
+  int ii;
+  int status;
+  WebRtc_Word16 BWno = BWnumber;
+  int stream_length = 0;
+
+  WebRtc_Word16 model;
+  const WebRtc_UWord16 *Q_PitchGain_cdf_ptr[1];
+  const WebRtc_UWord16 **cdf;
+  const ISAC_SaveEncData_t *SaveEnc_str;
+  WebRtc_Word32 tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1];
+  WebRtc_Word16 tmpLPCindex_g[KLT_ORDER_GAIN<<1];
+  WebRtc_Word16 tmp_fre[FRAMESAMPLES];
+  WebRtc_Word16 tmp_fim[FRAMESAMPLES];
+
+  SaveEnc_str = ISACenc_obj->SaveEnc_ptr;
+
+  /* Check if SaveEnc memory exists */
+  if (SaveEnc_str == NULL) {
+    return (-1);
+  }
+
+  /* Sanity Check - possible values for BWnumber is 0 - 23 */
+  if ((BWnumber < 0) || (BWnumber > 23)) {
+    return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
+  }
+
+  /* reset bitstream */
+  ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF;
+  ISACenc_obj->bitstr_obj.streamval = 0;
+  ISACenc_obj->bitstr_obj.stream_index = 0;
+  ISACenc_obj->bitstr_obj.full = 1;
+
+  /* encode frame length */
+  status = WebRtcIsacfix_EncodeFrameLen(SaveEnc_str->framelength, &ISACenc_obj->bitstr_obj);
+  if (status < 0) {
+    /* Wrong frame size */
+    return status;
+  }
+
+  /* encode bandwidth estimate */
+  status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj);
+  if (status < 0) {
+    return status;
+  }
+
+  /* Transcoding                                                 */
+  /* If scale < 1, rescale data to produce lower bitrate signal  */
+  if ((0.0 < scale) && (scale < 1.0)) {
+    /* Compensate LPC gain */
+    for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
+      tmpLPCcoeffs_g[ii] = (WebRtc_Word32) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]);
+    }
+
+    /* Scale DFT */
+    for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
+      tmp_fre[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fre[ii]) ;
+      tmp_fim[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fim[ii]) ;
+    }
+  } else {
+    for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) {
+      tmpLPCindex_g[ii] =  SaveEnc_str->LPCindex_g[ii];
+    }
+
+    for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) {
+      tmp_fre[ii] = SaveEnc_str->fre[ii];
+      tmp_fim[ii] = SaveEnc_str->fim[ii];
+    }
+  }
+
+  /* Loop over number of 30 msec */
+  for (ii = 0; ii <= SaveEnc_str->startIdx; ii++)
+  {
+
+    /* encode pitch gains */
+    *Q_PitchGain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
+    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->pitchGain_index[ii],
+                                       Q_PitchGain_cdf_ptr, 1);
+    if (status < 0) {
+      return status;
+    }
+
+    /* entropy coding of quantization pitch lags */
+    /* voicing classificiation */
+    if (SaveEnc_str->meanGain[ii] <= 819) {
+      cdf = WebRtcIsacfix_kPitchLagPtrLo;
+    } else if (SaveEnc_str->meanGain[ii] <= 1638) {
+      cdf = WebRtcIsacfix_kPitchLagPtrMid;
+    } else {
+      cdf = WebRtcIsacfix_kPitchLagPtrHi;
+    }
+    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,
+                                       &SaveEnc_str->pitchIndex[PITCH_SUBFRAMES*ii], cdf, PITCH_SUBFRAMES);
+    if (status < 0) {
+      return status;
+    }
+
+    /* LPC */
+    /* entropy coding of model number */
+    model = 0;
+    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj,  &model,
+                                       WebRtcIsacfix_kModelCdfPtr, 1);
+    if (status < 0) {
+      return status;
+    }
+
+    /* entropy coding of quantization indices - LPC shape only */
+    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->LPCindex_s[KLT_ORDER_SHAPE*ii],
+                                       WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
+    if (status < 0) {
+      return status;
+    }
+
+    /* If transcoding, get new LPC gain indices */
+    if (scale < 1.0) {
+      WebRtcIsacfix_TranscodeLpcCoef(&tmpLPCcoeffs_g[KLT_ORDER_GAIN*ii], &tmpLPCindex_g[KLT_ORDER_GAIN*ii]);
+    }
+
+    /* entropy coding of quantization indices - LPC gain */
+    status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii],
+                                       WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
+    if (status < 0) {
+      return status;
+    }
+
+    /* quantization and lossless coding */
+    status = WebRtcIsacfix_EncodeSpec(&tmp_fre[ii*FRAMESAMPLES_HALF], &tmp_fim[ii*FRAMESAMPLES_HALF],
+                                      &ISACenc_obj->bitstr_obj, SaveEnc_str->AvgPitchGain[ii]);
+    if (status < 0) {
+      return status;
+    }
+  }
+
+  /* complete arithmetic coding */
+  stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj);
+
+  return stream_length;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c b/src/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c
new file mode 100644
index 0000000..0b64d83
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/entropy_coding.c
@@ -0,0 +1,2072 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * entropy_coding.c
+ *
+ * This file contains all functions used to arithmetically
+ * encode the iSAC bistream.
+ *
+ */
+
+#include <stddef.h>
+
+#include "arith_routins.h"
+#include "spectrum_ar_model_tables.h"
+#include "pitch_gain_tables.h"
+#include "pitch_lag_tables.h"
+#include "entropy_coding.h"
+#include "lpc_tables.h"
+#include "settings.h"
+#include "signal_processing_library.h"
+
+
+/*
+  This function implements the fix-point correspondant function to lrint.
+
+  FLP: (WebRtc_Word32)floor(flt+.499999999999)
+  FIP: (fixVal+roundVal)>>qDomain
+
+  where roundVal = 2^(qDomain-1) = 1<<(qDomain-1)
+
+*/
+static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal, WebRtc_Word16 qDomain) {
+  WebRtc_Word32 intgr;
+  WebRtc_Word32 roundVal;
+
+  roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, qDomain-1);
+  intgr = WEBRTC_SPL_RSHIFT_W32(fixVal+roundVal, qDomain);
+
+  return intgr;
+}
+
+/*
+  __inline WebRtc_UWord32 stepwise(WebRtc_Word32 dinQ10) {
+
+  WebRtc_Word32 ind, diQ10, dtQ10;
+
+  diQ10 = dinQ10;
+  if (diQ10 < DPMIN_Q10)
+  diQ10 = DPMIN_Q10;
+  if (diQ10 >= DPMAX_Q10)
+  diQ10 = DPMAX_Q10 - 1;
+
+  dtQ10 = diQ10 - DPMIN_Q10;*/ /* Q10 + Q10 = Q10 */
+/* ind = (dtQ10 * 5) >> 10;  */ /* 2^10 / 5 = 0.2 in Q10  */
+/* Q10 -> Q0 */
+
+/* return rpointsFIX_Q10[ind];
+
+   }
+*/
+
+/* logN(x) = logN(2)*log2(x) = 0.6931*log2(x). Output in Q8. */
+/* The input argument X to logN(X) is 2^17 times higher than the
+   input floating point argument Y to log(Y), since the X value
+   is a Q17 value. This can be compensated for after the call, by
+   subraction a value Z for each Q-step. One Q-step means that
+   X gets 2 thimes higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
+   177.445678 should be subtracted (since logN() returns a Q8 value).
+   For a X value in Q17, the value 177.445678*17 = 3017 should be
+   subtracted */
+static WebRtc_Word16 CalcLogN(WebRtc_Word32 arg) {
+  WebRtc_Word16 zeros, log2, frac, logN;
+
+  zeros=WebRtcSpl_NormU32(arg);
+  frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(WEBRTC_SPL_LSHIFT_W32(arg, zeros)&0x7FFFFFFF, 23);
+  log2=(WebRtc_Word16)(WEBRTC_SPL_LSHIFT_W32(31-zeros, 8)+frac); // log2(x) in Q8
+  logN=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(log2,22713,15); //Q8*Q15 log(2) = 0.693147 = 22713 in Q15
+  logN=logN+11; //Scalar compensation which minimizes the (log(x)-logN(x))^2 error over all x.
+
+  return logN;
+}
+
+
+/*
+  expN(x) = 2^(a*x), where a = log2(e) ~= 1.442695
+
+  Input:  Q8  (WebRtc_Word16)
+  Output: Q17 (WebRtc_Word32)
+
+  a = log2(e) = log2(exp(1)) ~= 1.442695  ==>  a = 23637 in Q14 (1.442688)
+  To this value, 700 is added or subtracted in order to get an average error
+  nearer zero, instead of always same-sign.
+*/
+
+static WebRtc_Word32 CalcExpN(WebRtc_Word16 x) {
+  WebRtc_Word16 ax, axINT, axFRAC;
+  WebRtc_Word16 exp16;
+  WebRtc_Word32 exp;
+
+  if (x>=0) {
+    //  ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637-700, 14); //Q8
+    ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8
+    axINT = WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0
+    axFRAC = ax&0x00FF;
+    exp16 = WEBRTC_SPL_LSHIFT_W32(1, axINT); //Q0
+    axFRAC = axFRAC+256; //Q8
+    exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q0*Q8 = Q8
+    exp = WEBRTC_SPL_LSHIFT_W32(exp, 9); //Q17
+  } else {
+    //  ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637+700, 14); //Q8
+    ax=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(x, 23637, 14); //Q8
+    ax = -ax;
+    axINT = 1 + WEBRTC_SPL_RSHIFT_W16(ax, 8); //Q0
+    axFRAC = 0x00FF - (ax&0x00FF);
+    exp16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(32768, axINT); //Q15
+    axFRAC = axFRAC+256; //Q8
+    exp = WEBRTC_SPL_MUL_16_16(exp16, axFRAC); // Q15*Q8 = Q23
+    exp = WEBRTC_SPL_RSHIFT_W32(exp, 6); //Q17
+  }
+
+  return exp;
+}
+
+
+/* compute correlation from power spectrum */
+static void CalcCorrelation(WebRtc_Word32 *PSpecQ12, WebRtc_Word32 *CorrQ7)
+{
+  WebRtc_Word32 summ[FRAMESAMPLES/8];
+  WebRtc_Word32 diff[FRAMESAMPLES/8];
+  WebRtc_Word32 sum;
+  int k, n;
+
+  for (k = 0; k < FRAMESAMPLES/8; k++) {
+    summ[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] + PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
+    diff[k] = WEBRTC_SPL_RSHIFT_W32(PSpecQ12[k] - PSpecQ12[FRAMESAMPLES/4-1 - k] + 16, 5);
+  }
+
+  sum = 2;
+  for (n = 0; n < FRAMESAMPLES/8; n++)
+    sum += summ[n];
+  CorrQ7[0] = sum;
+
+  for (k = 0; k < AR_ORDER; k += 2) {
+    sum = 0;
+    for (n = 0; n < FRAMESAMPLES/8; n++)
+      sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], diff[n]) + 256, 9);
+    CorrQ7[k+1] = sum;
+  }
+
+  for (k=1; k<AR_ORDER; k+=2) {
+    sum = 0;
+    for (n = 0; n < FRAMESAMPLES/8; n++)
+      sum += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], summ[n]) + 256, 9);
+    CorrQ7[k+1] = sum;
+  }
+}
+
+
+/* compute inverse AR power spectrum */
+static void CalcInvArSpec(const WebRtc_Word16 *ARCoefQ12,
+                          const WebRtc_Word32 gainQ10,
+                          WebRtc_Word32 *CurveQ16)
+{
+  WebRtc_Word32 CorrQ11[AR_ORDER+1];
+  WebRtc_Word32 sum, tmpGain;
+  WebRtc_Word32 diffQ16[FRAMESAMPLES/8];
+  const WebRtc_Word16 *CS_ptrQ9;
+  int k, n;
+  WebRtc_Word16 round, shftVal = 0, sh;
+
+  sum = 0;
+  for (n = 0; n < AR_ORDER+1; n++)
+    sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]);    /* Q24 */
+  sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16);    /* result in Q8 */
+  CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
+
+  /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
+  if(gainQ10>400000){
+    tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
+    round = 32;
+    shftVal = 6;
+  } else {
+    tmpGain = gainQ10;
+    round = 256;
+    shftVal = 9;
+  }
+
+  for (k = 1; k < AR_ORDER+1; k++) {
+    sum = 16384;
+    for (n = k; n < AR_ORDER+1; n++)
+      sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]);  /* Q24 */
+    sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
+    CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
+  }
+  sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
+  for (n = 0; n < FRAMESAMPLES/8; n++)
+    CurveQ16[n] = sum;
+
+  for (k = 1; k < AR_ORDER; k += 2) {
+    for (n = 0; n < FRAMESAMPLES/8; n++)
+      CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WebRtcIsacfix_kCos[k][n], CorrQ11[k+1]) + 2, 2);
+  }
+
+  CS_ptrQ9 = WebRtcIsacfix_kCos[0];
+
+  /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */
+  sh=WebRtcSpl_NormW32(CorrQ11[1]);
+  if (CorrQ11[1]==0) /* Use next correlation */
+    sh=WebRtcSpl_NormW32(CorrQ11[2]);
+
+  if (sh<9)
+    shftVal = 9 - sh;
+  else
+    shftVal = 0;
+
+  for (n = 0; n < FRAMESAMPLES/8; n++)
+    diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
+  for (k = 2; k < AR_ORDER; k += 2) {
+    CS_ptrQ9 = WebRtcIsacfix_kCos[k];
+    for (n = 0; n < FRAMESAMPLES/8; n++)
+      diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
+  }
+
+  for (k=0; k<FRAMESAMPLES/8; k++) {
+    CurveQ16[FRAMESAMPLES/4-1 - k] = CurveQ16[k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
+    CurveQ16[k] += WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
+  }
+}
+
+static void CalcRootInvArSpec(const WebRtc_Word16 *ARCoefQ12,
+                              const WebRtc_Word32 gainQ10,
+                              WebRtc_UWord16 *CurveQ8)
+{
+  WebRtc_Word32 CorrQ11[AR_ORDER+1];
+  WebRtc_Word32 sum, tmpGain;
+  WebRtc_Word32 summQ16[FRAMESAMPLES/8];
+  WebRtc_Word32 diffQ16[FRAMESAMPLES/8];
+
+  const WebRtc_Word16 *CS_ptrQ9;
+  int k, n, i;
+  WebRtc_Word16 round, shftVal = 0, sh;
+  WebRtc_Word32 res, in_sqrt, newRes;
+
+  sum = 0;
+  for (n = 0; n < AR_ORDER+1; n++)
+    sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]);    /* Q24 */
+  sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16);    /* result in Q8 */
+  CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9);
+
+  /* To avoid overflow, we shift down gainQ10 if it is large. We will not lose any precision */
+  if(gainQ10>400000){
+    tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3);
+    round = 32;
+    shftVal = 6;
+  } else {
+    tmpGain = gainQ10;
+    round = 256;
+    shftVal = 9;
+  }
+
+  for (k = 1; k < AR_ORDER+1; k++) {
+    sum = 16384;
+    for (n = k; n < AR_ORDER+1; n++)
+      sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]);  /* Q24 */
+    sum = WEBRTC_SPL_RSHIFT_W32(sum, 15);
+    CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal);
+  }
+  sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7);
+  for (n = 0; n < FRAMESAMPLES/8; n++)
+    summQ16[n] = sum;
+
+  for (k = 1; k < (AR_ORDER); k += 2) {
+    for (n = 0; n < FRAMESAMPLES/8; n++)
+      summQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_32_16(CorrQ11[k+1],WebRtcIsacfix_kCos[k][n]) + 2, 2);
+  }
+
+  CS_ptrQ9 = WebRtcIsacfix_kCos[0];
+
+  /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shifting */
+  sh=WebRtcSpl_NormW32(CorrQ11[1]);
+  if (CorrQ11[1]==0) /* Use next correlation */
+    sh=WebRtcSpl_NormW32(CorrQ11[2]);
+
+  if (sh<9)
+    shftVal = 9 - sh;
+  else
+    shftVal = 0;
+
+  for (n = 0; n < FRAMESAMPLES/8; n++)
+    diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2);
+  for (k = 2; k < AR_ORDER; k += 2) {
+    CS_ptrQ9 = WebRtcIsacfix_kCos[k];
+    for (n = 0; n < FRAMESAMPLES/8; n++)
+      diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2);
+  }
+
+  in_sqrt = summQ16[0] + WEBRTC_SPL_LSHIFT_W32(diffQ16[0], shftVal);
+
+  /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB)  */
+  res = WEBRTC_SPL_LSHIFT_W32(1, WEBRTC_SPL_RSHIFT_W16(WebRtcSpl_GetSizeInBits(in_sqrt), 1));
+
+  for (k = 0; k < FRAMESAMPLES/8; k++)
+  {
+    in_sqrt = summQ16[k] + WEBRTC_SPL_LSHIFT_W32(diffQ16[k], shftVal);
+    i = 10;
+
+    /* make in_sqrt positive to prohibit sqrt of negative values */
+    if(in_sqrt<0)
+      in_sqrt=-in_sqrt;
+
+    newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
+    do
+    {
+      res = newRes;
+      newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
+    } while (newRes != res && i-- > 0);
+
+    CurveQ8[k] = (WebRtc_Word16)newRes;
+  }
+  for (k = FRAMESAMPLES/8; k < FRAMESAMPLES/4; k++) {
+
+    in_sqrt = summQ16[FRAMESAMPLES/4-1 - k] - WEBRTC_SPL_LSHIFT_W32(diffQ16[FRAMESAMPLES/4-1 - k], shftVal);
+    i = 10;
+
+    /* make in_sqrt positive to prohibit sqrt of negative values */
+    if(in_sqrt<0)
+      in_sqrt=-in_sqrt;
+
+    newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
+    do
+    {
+      res = newRes;
+      newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
+    } while (newRes != res && i-- > 0);
+
+    CurveQ8[k] = (WebRtc_Word16)newRes;
+  }
+
+}
+
+
+
+/* generate array of dither samples in Q7 */
+static void GenerateDitherQ7(WebRtc_Word16 *bufQ7,
+                             WebRtc_UWord32 seed,
+                             WebRtc_Word16 length,
+                             WebRtc_Word16 AvgPitchGain_Q12)
+{
+  int   k;
+  WebRtc_Word16 dither1_Q7, dither2_Q7, dither_gain_Q14, shft;
+
+  if (AvgPitchGain_Q12 < 614)  /* this threshold should be equal to that in decode_spec() */
+  {
+    for (k = 0; k < length-2; k += 3)
+    {
+      /* new random unsigned WebRtc_Word32 */
+      seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
+
+      /* fixed-point dither sample between -64 and 64 (Q7) */
+      dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25); // * 128/4294967295
+
+      /* new random unsigned WebRtc_Word32 */
+      seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
+
+      /* fixed-point dither sample between -64 and 64 */
+      dither2_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(seed + 16777216, 25);
+
+      shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 15);
+      if (shft < 5)
+      {
+        bufQ7[k]   = dither1_Q7;
+        bufQ7[k+1] = dither2_Q7;
+        bufQ7[k+2] = 0;
+      }
+      else if (shft < 10)
+      {
+        bufQ7[k]   = dither1_Q7;
+        bufQ7[k+1] = 0;
+        bufQ7[k+2] = dither2_Q7;
+      }
+      else
+      {
+        bufQ7[k]   = 0;
+        bufQ7[k+1] = dither1_Q7;
+        bufQ7[k+2] = dither2_Q7;
+      }
+    }
+  }
+  else
+  {
+    dither_gain_Q14 = (WebRtc_Word16)(22528 - WEBRTC_SPL_MUL(10, AvgPitchGain_Q12));
+
+    /* dither on half of the coefficients */
+    for (k = 0; k < length-1; k += 2)
+    {
+      /* new random unsigned WebRtc_Word32 */
+      seed = WEBRTC_SPL_UMUL(seed, 196314165) + 907633515;
+
+      /* fixed-point dither sample between -64 and 64 */
+      dither1_Q7 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)seed + 16777216, 25);
+
+      /* dither sample is placed in either even or odd index */
+      shft = (WebRtc_Word16)(WEBRTC_SPL_RSHIFT_U32(seed, 25) & 1);     /* either 0 or 1 */
+
+      bufQ7[k + shft] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(dither_gain_Q14, dither1_Q7) + 8192, 14);
+      bufQ7[k + 1 - shft] = 0;
+    }
+  }
+}
+
+
+
+
+/*
+ * function to decode the complex spectrum from the bitstream
+ * returns the total number of bytes in the stream
+ */
+WebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec *streamdata,
+                                       WebRtc_Word16 *frQ7,
+                                       WebRtc_Word16 *fiQ7,
+                                       WebRtc_Word16 AvgPitchGain_Q12)
+{
+  WebRtc_Word16  data[FRAMESAMPLES];
+  WebRtc_Word32  invARSpec2_Q16[FRAMESAMPLES/4];
+  WebRtc_Word16  ARCoefQ12[AR_ORDER+1];
+  WebRtc_Word16  RCQ15[AR_ORDER];
+  WebRtc_Word16  gainQ10;
+  WebRtc_Word32  gain2_Q10;
+  WebRtc_Word16  len;
+  int          k;
+
+  /* create dither signal */
+  GenerateDitherQ7(data, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); /* Dither is output in vector 'Data' */
+
+  /* decode model parameters */
+  if (WebRtcIsacfix_DecodeRcCoef(streamdata, RCQ15) < 0)
+    return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
+
+
+  WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
+
+  if (WebRtcIsacfix_DecodeGain2(streamdata, &gain2_Q10) < 0)
+    return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
+
+  /* compute inverse AR power spectrum */
+  CalcInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
+
+  /* arithmetic decoding of spectrum */
+  /* 'data' input and output. Input = Dither */
+  len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (WebRtc_Word16)FRAMESAMPLES);
+
+  if (len<1)
+    return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
+
+  /* subtract dither and scale down spectral samples with low SNR */
+  if (AvgPitchGain_Q12 <= 614)
+  {
+    for (k = 0; k < FRAMESAMPLES; k += 4)
+    {
+      gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)30, 10),
+                                              (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2195456, 16));
+      *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
+      *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
+      *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
+      *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
+    }
+  }
+  else
+  {
+    for (k = 0; k < FRAMESAMPLES; k += 4)
+    {
+      gainQ10 = WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)36, 10),
+                                              (WebRtc_Word16)WEBRTC_SPL_RSHIFT_U32(invARSpec2_Q16[k>>2] + (WebRtc_UWord32)2654208, 16));
+      *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[ k ], gainQ10) + 512, 10);
+      *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+1], gainQ10) + 512, 10);
+      *frQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+2], gainQ10) + 512, 10);
+      *fiQ7++ = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(data[k+3], gainQ10) + 512, 10);
+    }
+  }
+
+  return len;
+}
+
+
+int WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr,
+                             const WebRtc_Word16 *fi,
+                             Bitstr_enc *streamdata,
+                             WebRtc_Word16 AvgPitchGain_Q12)
+{
+  WebRtc_Word16  dataQ7[FRAMESAMPLES];
+  WebRtc_Word32  PSpec[FRAMESAMPLES/4];
+  WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES/4];
+  WebRtc_Word32  CorrQ7[AR_ORDER+1];
+  WebRtc_Word32  CorrQ7_norm[AR_ORDER+1];
+  WebRtc_Word16  RCQ15[AR_ORDER];
+  WebRtc_Word16  ARCoefQ12[AR_ORDER+1];
+  WebRtc_Word32  gain2_Q10;
+  WebRtc_Word16  val;
+  WebRtc_Word32  nrg;
+  WebRtc_UWord32 sum;
+  WebRtc_Word16  lft_shft;
+  WebRtc_Word16  status;
+  int          k, n, j;
+
+
+  /* create dither_float signal */
+  GenerateDitherQ7(dataQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12);
+
+  /* add dither and quantize, and compute power spectrum */
+  /* Vector dataQ7 contains Dither in Q7 */
+  for (k = 0; k < FRAMESAMPLES; k += 4)
+  {
+    val = ((*fr++ + dataQ7[k]   + 64) & 0xFF80) - dataQ7[k]; /* Data = Dither */
+    dataQ7[k] = val;            /* New value in Data */
+    sum = WEBRTC_SPL_UMUL(val, val);
+
+    val = ((*fi++ + dataQ7[k+1] + 64) & 0xFF80) - dataQ7[k+1]; /* Data = Dither */
+    dataQ7[k+1] = val;            /* New value in Data */
+    sum += WEBRTC_SPL_UMUL(val, val);
+
+    val = ((*fr++ + dataQ7[k+2] + 64) & 0xFF80) - dataQ7[k+2]; /* Data = Dither */
+    dataQ7[k+2] = val;            /* New value in Data */
+    sum += WEBRTC_SPL_UMUL(val, val);
+
+    val = ((*fi++ + dataQ7[k+3] + 64) & 0xFF80) - dataQ7[k+3]; /* Data = Dither */
+    dataQ7[k+3] = val;            /* New value in Data */
+    sum += WEBRTC_SPL_UMUL(val, val);
+
+    PSpec[k>>2] = WEBRTC_SPL_RSHIFT_U32(sum, 2);
+  }
+
+  /* compute correlation from power spectrum */
+  CalcCorrelation(PSpec, CorrQ7);
+
+
+  /* find AR coefficients */
+  /* number of bit shifts to 14-bit normalize CorrQ7[0] (leaving room for sign) */
+  lft_shft = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
+
+  if (lft_shft > 0) {
+    for (k=0; k<AR_ORDER+1; k++)
+      CorrQ7_norm[k] = WEBRTC_SPL_LSHIFT_W32(CorrQ7[k], lft_shft);
+  } else {
+    for (k=0; k<AR_ORDER+1; k++)
+      CorrQ7_norm[k] = WEBRTC_SPL_RSHIFT_W32(CorrQ7[k], -lft_shft);
+  }
+
+  /* find RC coefficients */
+  WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15);
+
+  /* quantize & code RC Coef */
+  status = WebRtcIsacfix_EncodeRcCoef(RCQ15, streamdata);
+  if (status < 0) {
+    return status;
+  }
+
+  /* RC -> AR coefficients */
+  WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
+
+  /* compute ARCoef' * Corr * ARCoef in Q19 */
+  nrg = 0;
+  for (j = 0; j <= AR_ORDER; j++) {
+    for (n = 0; n <= j; n++)
+      nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[j-n], ARCoefQ12[n]) + 256, 9)) + 4, 3);
+    for (n = j+1; n <= AR_ORDER; n++)
+      nrg += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(ARCoefQ12[j], WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(CorrQ7_norm[n-j], ARCoefQ12[n]) + 256, 9)) + 4, 3);
+  }
+
+  if (lft_shft > 0)
+    nrg = WEBRTC_SPL_RSHIFT_W32(nrg, lft_shft);
+  else
+    nrg = WEBRTC_SPL_LSHIFT_W32(nrg, -lft_shft);
+
+  if(nrg>131072)
+    gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES >> 2, nrg);  /* also shifts 31 bits to the left! */
+  else
+    gain2_Q10 = WEBRTC_SPL_RSHIFT_W32(FRAMESAMPLES, 2);
+
+  /* quantize & code gain2_Q10 */
+  if (WebRtcIsacfix_EncodeGain2(&gain2_Q10, streamdata))
+    return -1;
+
+  /* compute inverse AR magnitude spectrum */
+  CalcRootInvArSpec(ARCoefQ12, gain2_Q10, invARSpecQ8);
+
+
+  /* arithmetic coding of spectrum */
+  status = WebRtcIsacfix_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, (WebRtc_Word16)FRAMESAMPLES);
+  if ( status )
+    return( status );
+
+  return 0;
+}
+
+
+/* Matlab's LAR definition */
+static void Rc2LarFix(const WebRtc_Word16 *rcQ15, WebRtc_Word32 *larQ17, WebRtc_Word16 order) {
+
+  /*
+
+    This is a piece-wise implemenetation of a rc2lar-function (all values in the comment
+    are Q15 values and  are based on [0 24956/32768 30000/32768 32500/32768], i.e.
+    [0.76159667968750   0.91552734375000   0.99182128906250]
+
+    x0  x1           a                 k              x0(again)         b
+    ==================================================================================
+    0.00 0.76:   0                  2.625997508581   0                  0
+    0.76 0.91:   2.000012018559     7.284502668663   0.761596679688    -3.547841027073
+    0.91 0.99:   3.121320351712    31.115835041229   0.915527343750   -25.366077452148
+    0.99 1.00:   5.495270168700   686.663805654056   0.991821289063  -675.552510708011
+
+    The implementation is y(x)= a + (x-x0)*k, but this can be simplified to
+
+    y(x) = a-x0*k + x*k = b + x*k, where b = a-x0*k
+
+    akx=[0                 2.625997508581   0
+    2.000012018559     7.284502668663   0.761596679688
+    3.121320351712    31.115835041229   0.915527343750
+    5.495270168700   686.663805654056   0.991821289063];
+
+    b = akx(:,1) - akx(:,3).*akx(:,2)
+
+    [ 0.0
+    -3.547841027073
+    -25.366077452148
+    -675.552510708011]
+
+  */
+
+  int k;
+  WebRtc_Word16 rc;
+  WebRtc_Word32 larAbsQ17;
+
+  for (k = 0; k < order; k++) {
+
+    rc = WEBRTC_SPL_ABS_W16(rcQ15[k]); //Q15
+
+    /* Calculate larAbsQ17 in Q17 from rc in Q15 */
+
+    if (rc<24956) {  //0.7615966 in Q15
+      // (Q15*Q13)>>11 = Q17
+      larAbsQ17 = WEBRTC_SPL_MUL_16_16_RSFT(rc, 21512, 11);
+    } else if (rc<30000) { //0.91552734375 in Q15
+      // Q17 + (Q15*Q12)>>10 = Q17
+      larAbsQ17 = -465024 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 29837, 10);
+    } else if (rc<32500) { //0.99182128906250 in Q15
+      // Q17 + (Q15*Q10)>>8 = Q17
+      larAbsQ17 = -3324784 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 31863, 8);
+    } else  {
+      // Q17 + (Q15*Q5)>>3 = Q17
+      larAbsQ17 = -88546020 + WEBRTC_SPL_MUL_16_16_RSFT(rc, 21973, 3);
+    }
+
+    if (rcQ15[k]>0) {
+      larQ17[k] = larAbsQ17;
+    } else {
+      larQ17[k] = -larAbsQ17;
+    }
+  }
+}
+
+
+static void Lar2RcFix(const WebRtc_Word32 *larQ17, WebRtc_Word16 *rcQ15,  WebRtc_Word16 order) {
+
+  /*
+    This is a piece-wise implemenetation of a lar2rc-function
+    See comment in Rc2LarFix() about details.
+  */
+
+  int k;
+  WebRtc_Word16 larAbsQ11;
+  WebRtc_Word32 rc;
+
+  for (k = 0; k < order; k++) {
+
+    larAbsQ11 = (WebRtc_Word16) WEBRTC_SPL_ABS_W32(WEBRTC_SPL_RSHIFT_W32(larQ17[k]+32,6)); //Q11
+
+    if (larAbsQ11<4097) { //2.000012018559 in Q11
+      // Q11*Q16>>12 = Q15
+      rc = WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24957, 12);
+    } else if (larAbsQ11<6393) { //3.121320351712 in Q11
+      // (Q11*Q17 + Q13)>>13 = Q15
+      rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 17993) + 130738688), 13);
+    } else if (larAbsQ11<11255) { //5.495270168700 in Q11
+      // (Q11*Q19 + Q30)>>15 = Q15
+      rc = WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL_16_16(larAbsQ11, 16850) + 875329820), 15);
+    } else  {
+      // (Q11*Q24>>16 + Q19)>>4 = Q15
+      rc = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16_RSFT(larAbsQ11, 24433, 16)) + 515804), 4);
+    }
+
+    if (larQ17[k]<=0) {
+      rc = -rc;
+    }
+
+    rcQ15[k] = (WebRtc_Word16) rc;  // Q15
+  }
+}
+
+static void Poly2LarFix(WebRtc_Word16 *lowbandQ15,
+                        WebRtc_Word16 orderLo,
+                        WebRtc_Word16 *hibandQ15,
+                        WebRtc_Word16 orderHi,
+                        WebRtc_Word16 Nsub,
+                        WebRtc_Word32 *larsQ17) {
+
+  int k, n;
+  WebRtc_Word32 *outpQ17;
+  WebRtc_Word16 orderTot;
+  WebRtc_Word32 larQ17[MAX_ORDER];   // Size 7+6 is enough
+
+  orderTot = (orderLo + orderHi);
+  outpQ17 = larsQ17;
+  for (k = 0; k < Nsub; k++) {
+
+    Rc2LarFix(lowbandQ15, larQ17, orderLo);
+
+    for (n = 0; n < orderLo; n++)
+      outpQ17[n] = larQ17[n]; //Q17
+
+    Rc2LarFix(hibandQ15, larQ17, orderHi);
+
+    for (n = 0; n < orderHi; n++)
+      outpQ17[n + orderLo] = larQ17[n]; //Q17;
+
+    outpQ17 += orderTot;
+    lowbandQ15 += orderLo;
+    hibandQ15 += orderHi;
+  }
+}
+
+
+static void Lar2polyFix(WebRtc_Word32 *larsQ17,
+                        WebRtc_Word16 *lowbandQ15,
+                        WebRtc_Word16 orderLo,
+                        WebRtc_Word16 *hibandQ15,
+                        WebRtc_Word16 orderHi,
+                        WebRtc_Word16 Nsub) {
+
+  int k, n;
+  WebRtc_Word16 orderTot;
+  WebRtc_Word16 *outplQ15, *outphQ15;
+  WebRtc_Word32 *inpQ17;
+  WebRtc_Word16 rcQ15[7+6];
+
+  orderTot = (orderLo + orderHi);
+  outplQ15 = lowbandQ15;
+  outphQ15 = hibandQ15;
+  inpQ17 = larsQ17;
+  for (k = 0; k < Nsub; k++) {
+
+    /* gains not handled here as in the FLP version */
+
+    /* Low band */
+    Lar2RcFix(&inpQ17[0], rcQ15, orderLo);
+    for (n = 0; n < orderLo; n++)
+      outplQ15[n] = rcQ15[n]; // Refl. coeffs
+
+    /* High band */
+    Lar2RcFix(&inpQ17[orderLo], rcQ15, orderHi);
+    for (n = 0; n < orderHi; n++)
+      outphQ15[n] = rcQ15[n]; // Refl. coeffs
+
+    inpQ17 += orderTot;
+    outplQ15 += orderLo;
+    outphQ15 += orderHi;
+  }
+}
+
+int WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
+                            WebRtc_Word16 *LPCCoef_loQ15,
+                            WebRtc_Word16 *LPCCoef_hiQ15,
+                            Bitstr_dec *streamdata,
+                            WebRtc_Word16 *outmodel) {
+
+  WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_GAIN+KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES
+  int err;
+
+  err = WebRtcIsacfix_DecodeLpcCoef(streamdata, larsQ17, gain_lo_hiQ17, outmodel);
+  if (err<0)  // error check
+    return -ISAC_RANGE_ERROR_DECODE_LPC;
+
+  Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES);
+
+  return 0;
+}
+
+/* decode & dequantize LPC Coef */
+int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec *streamdata,
+                                WebRtc_Word32 *LPCCoefQ17,
+                                WebRtc_Word32 *gain_lo_hiQ17,
+                                WebRtc_Word16 *outmodel)
+{
+  int j, k, n;
+  int err;
+  WebRtc_Word16 pos, pos2, posg, poss, offsg, offss, offs2;
+  WebRtc_Word16 gainpos;
+  WebRtc_Word16 model;
+  WebRtc_Word16 index_QQ[KLT_ORDER_SHAPE];
+  WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
+  WebRtc_Word16 tmpcoeffs_sQ10[KLT_ORDER_SHAPE];
+  WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE];
+  WebRtc_Word32 tmpcoeffs2_sQ18[KLT_ORDER_SHAPE];
+  WebRtc_Word32 sumQQ;
+  WebRtc_Word16 sumQQ16;
+  WebRtc_Word32 tmp32;
+
+
+
+  /* entropy decoding of model number */
+  err = WebRtcIsacfix_DecHistOneStepMulti(&model, streamdata, WebRtcIsacfix_kModelCdfPtr, WebRtcIsacfix_kModelInitIndex, 1);
+  if (err<0)  // error check
+    return err;
+
+  /* entropy decoding of quantization indices */
+  err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfShapePtr[model], WebRtcIsacfix_kInitIndexShape[model], KLT_ORDER_SHAPE);
+  if (err<0)  // error check
+    return err;
+  /* find quantization levels for coefficients */
+  for (k=0; k<KLT_ORDER_SHAPE; k++) {
+    tmpcoeffs_sQ10[WebRtcIsacfix_kSelIndShape[k]] = WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[model]+WebRtcIsacfix_kOffsetShape[model][k] + index_QQ[k]];
+  }
+
+  err = WebRtcIsacfix_DecHistOneStepMulti(index_QQ, streamdata, WebRtcIsacfix_kCdfGainPtr[model], WebRtcIsacfix_kInitIndexGain[model], KLT_ORDER_GAIN);
+  if (err<0)  // error check
+    return err;
+  /* find quantization levels for coefficients */
+  for (k=0; k<KLT_ORDER_GAIN; k++) {
+    tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[model]+ WebRtcIsacfix_kOffsetGain[model][k] + index_QQ[k]];
+  }
+
+
+  /* inverse KLT  */
+
+  /* left transform */  // Transpose matrix!
+  offsg = 0;
+  offss = 0;
+  posg = 0;
+  poss = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    offs2 = 0;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = offsg;
+      pos2 = offs2;
+      for (n=0; n<2; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[model][pos2], tmpcoeffs_gQ17[pos]<<5)); // (Q15*Q17)>>(16-5) = Q21
+        pos++;
+        pos2++;
+      }
+      tmpcoeffs2_gQ21[posg] = sumQQ; //Q21
+      posg++;
+      offs2 += 2;
+    }
+    offs2 = 0;
+
+    for (k=0; k<LPC_SHAPE_ORDER; k++) {
+      sumQQ = 0;
+      pos = offss;
+      pos2 = offs2;
+      for (n=0; n<LPC_SHAPE_ORDER; n++) {
+        sumQQ += WEBRTC_SPL_MUL_16_16_RSFT(tmpcoeffs_sQ10[pos], WebRtcIsacfix_kT1ShapeQ15[model][pos2], 7); // (Q10*Q15)>>7 = Q18
+        pos++;
+        pos2++;
+      }
+      tmpcoeffs2_sQ18[poss] = sumQQ; //Q18
+      poss++;
+      offs2 += LPC_SHAPE_ORDER;
+    }
+    offsg += 2;
+    offss += LPC_SHAPE_ORDER;
+  }
+
+  /* right transform */ // Transpose matrix
+  offsg = 0;
+  offss = 0;
+  posg = 0;
+  poss = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = j;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[model][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
+        pos += 2;
+        pos2 += SUBFRAMES;
+
+      }
+      tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
+      posg++;
+    }
+    poss = offss;
+    for (k=0; k<LPC_SHAPE_ORDER; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = j;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[model][pos2], tmpcoeffs2_sQ18[pos])); // (Q15*Q18)>>16 = Q17
+        pos += LPC_SHAPE_ORDER;
+        pos2 += SUBFRAMES;
+      }
+      tmpcoeffs_sQ17[poss] = sumQQ;
+      poss++;
+    }
+    offsg += 2;
+    offss += LPC_SHAPE_ORDER;
+  }
+
+  /* scaling, mean addition, and gain restoration */
+  gainpos = 0;
+  posg = 0;poss = 0;pos=0;
+  for (k=0; k<SUBFRAMES; k++) {
+
+    /* log gains */
+    sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
+    sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
+    sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
+    gain_lo_hiQ17[gainpos] = sumQQ; //Q17
+    gainpos++;
+    posg++;
+
+    sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
+    sumQQ16 += WebRtcIsacfix_kMeansGainQ8[model][posg];
+    sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
+    gain_lo_hiQ17[gainpos] = sumQQ; //Q17
+    gainpos++;
+    posg++;
+
+    /* lo band LAR coeffs */
+    for (n=0; n<ORDERLO; n++, pos++, poss++) {
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16
+      tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17
+      LPCCoefQ17[pos] = tmp32;
+    }
+
+    /* hi band LAR coeffs */
+    for (n=0; n<ORDERHI; n++, pos++, poss++) {
+      tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13
+      tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[model][poss]; // Q17+Q17 = Q17
+      LPCCoefQ17[pos] = tmp32;
+    }
+  }
+
+
+  *outmodel=model;
+
+  return 0;
+}
+
+/* estimate codel length of LPC Coef */
+static int EstCodeLpcCoef(WebRtc_Word32 *LPCCoefQ17,
+                          WebRtc_Word32 *gain_lo_hiQ17,
+                          WebRtc_Word16 *model,
+                          WebRtc_Word32 *sizeQ11,
+                          Bitstr_enc *streamdata,
+                          ISAC_SaveEncData_t* encData,
+                          transcode_obj *transcodingParam) {
+  int j, k, n;
+  WebRtc_Word16 posQQ, pos2QQ, gainpos;
+  WebRtc_Word16  pos, pos2, poss, posg, offsg, offss, offs2;
+  WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN], index_sQQ[KLT_ORDER_SHAPE];
+  WebRtc_Word16 index_ovr_gQQ[KLT_ORDER_GAIN], index_ovr_sQQ[KLT_ORDER_SHAPE];
+  WebRtc_Word32 BitsQQ;
+
+  WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs_sQ17[KLT_ORDER_SHAPE];
+  WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs2_sQ17[KLT_ORDER_SHAPE];
+  WebRtc_Word32 sumQQ;
+  WebRtc_Word32 tmp32;
+  WebRtc_Word16 sumQQ16;
+  int status = 0;
+
+  /* write LAR coefficients to statistics file */
+  /* Save data for creation of multiple bitstreams (and transcoding) */
+  if (encData != NULL) {
+    for (k=0; k<KLT_ORDER_GAIN; k++) {
+      encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k];
+    }
+  }
+
+  /* log gains, mean removal and scaling */
+  posg = 0;poss = 0;pos=0; gainpos=0;
+
+  for (k=0; k<SUBFRAMES; k++) {
+    /* log gains */
+
+    /* The input argument X to logN(X) is 2^17 times higher than the
+       input floating point argument Y to log(Y), since the X value
+       is a Q17 value. This can be compensated for after the call, by
+       subraction a value Z for each Q-step. One Q-step means that
+       X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
+       177.445678 should be subtracted (since logN() returns a Q8 value).
+       For a X value in Q17, the value 177.445678*17 = 3017 should be
+       subtracted */
+    tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
+    tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
+    posg++; gainpos++;
+
+    tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
+    tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
+    posg++; gainpos++;
+
+    /* lo band LAR coeffs */
+    for (n=0; n<ORDERLO; n++, poss++, pos++) {
+      tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(17203, tmp32<<3); // tmp32 = 2.1*tmp32
+      tmpcoeffs_sQ17[poss] = tmp32; //Q17
+    }
+
+    /* hi band LAR coeffs */
+    for (n=0; n<ORDERHI; n++, poss++, pos++) {
+      tmp32 = LPCCoefQ17[pos] - WebRtcIsacfix_kMeansShapeQ17[0][poss]; //Q17
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(14746, tmp32<<1); // tmp32 = 0.45*tmp32
+      tmpcoeffs_sQ17[poss] = tmp32; //Q17
+    }
+
+  }
+
+
+  /* KLT  */
+
+  /* left transform */
+  offsg = 0;
+  offss = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = offsg;
+      pos2 = k;
+      for (n=0; n<2; n++) {
+        sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15
+        pos++;
+        pos2 += 2;
+      }
+      tmpcoeffs2_gQ21[posg] = sumQQ;
+      posg++;
+    }
+    poss = offss;
+    for (k=0; k<LPC_SHAPE_ORDER; k++) {
+      sumQQ = 0;
+      pos = offss;
+      pos2 = k;
+      for (n=0; n<LPC_SHAPE_ORDER; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1ShapeQ15[0][pos2], tmpcoeffs_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
+        pos++;
+        pos2 += LPC_SHAPE_ORDER;
+      }
+      tmpcoeffs2_sQ17[poss] = sumQQ; //Q17
+      poss++;
+    }
+    offsg += 2;
+    offss += LPC_SHAPE_ORDER;
+  }
+
+  /* right transform */
+  offsg = 0;
+  offss = 0;
+  offs2 = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = offs2;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
+        pos += 2;
+        pos2++;
+      }
+      tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
+      posg++;
+    }
+    poss = offss;
+    for (k=0; k<LPC_SHAPE_ORDER; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = offs2;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[0][pos2], tmpcoeffs2_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
+        pos += LPC_SHAPE_ORDER;
+        pos2++;
+      }
+      tmpcoeffs_sQ17[poss] = sumQQ;
+      poss++;
+    }
+    offs2 += SUBFRAMES;
+    offsg += 2;
+    offss += LPC_SHAPE_ORDER;
+  }
+
+  /* quantize coefficients */
+
+  BitsQQ = 0;
+  for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
+  {
+    posQQ = WebRtcIsacfix_kSelIndGain[k];
+    pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
+
+    index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
+    if (index_gQQ[k] < 0) {
+      index_gQQ[k] = 0;
+    }
+    else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
+      index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
+    }
+    index_ovr_gQQ[k] = WebRtcIsacfix_kOffsetGain[0][k]+index_gQQ[k];
+    posQQ = WebRtcIsacfix_kOfLevelsGain[0] + index_ovr_gQQ[k];
+
+    /* Save data for creation of multiple bitstreams */
+    if (encData != NULL) {
+      encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k];
+    }
+
+    /* determine number of bits */
+    sumQQ = WebRtcIsacfix_kCodeLenGainQ11[posQQ]; //Q11
+    BitsQQ += sumQQ;
+  }
+
+  for (k=0; k<KLT_ORDER_SHAPE; k++) //ATTN: ok?
+  {
+    index_sQQ[k] = (WebRtc_Word16)(CalcLrIntQ(tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]], 17) + WebRtcIsacfix_kQuantMinShape[k]); //ATTN: ok?
+
+    if (index_sQQ[k] < 0)
+      index_sQQ[k] = 0;
+    else if (index_sQQ[k] > WebRtcIsacfix_kMaxIndShape[k])
+      index_sQQ[k] = WebRtcIsacfix_kMaxIndShape[k];
+    index_ovr_sQQ[k] = WebRtcIsacfix_kOffsetShape[0][k]+index_sQQ[k];
+
+    posQQ = WebRtcIsacfix_kOfLevelsShape[0] + index_ovr_sQQ[k];
+    sumQQ = WebRtcIsacfix_kCodeLenShapeQ11[posQQ]; //Q11
+    BitsQQ += sumQQ;
+  }
+
+
+
+  *model = 0;
+  *sizeQ11=BitsQQ;
+
+  /* entropy coding of model number */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, model, WebRtcIsacfix_kModelCdfPtr, 1);
+  if (status < 0) {
+    return status;
+  }
+
+  /* entropy coding of quantization indices - shape only */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, index_sQQ, WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE);
+  if (status < 0) {
+    return status;
+  }
+
+  /* Save data for creation of multiple bitstreams */
+  if (encData != NULL) {
+    for (k=0; k<KLT_ORDER_SHAPE; k++)
+    {
+      encData->LPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_sQQ[k];
+    }
+  }
+  /* save the state of the bitstream object 'streamdata' for the possible bit-rate reduction */
+  transcodingParam->full         = streamdata->full;
+  transcodingParam->stream_index = streamdata->stream_index;
+  transcodingParam->streamval    = streamdata->streamval;
+  transcodingParam->W_upper      = streamdata->W_upper;
+  transcodingParam->beforeLastWord     = streamdata->stream[streamdata->stream_index-1];
+  transcodingParam->lastWord     = streamdata->stream[streamdata->stream_index];
+
+  /* entropy coding of index */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
+  if (status < 0) {
+    return status;
+  }
+
+  /* find quantization levels for shape coefficients */
+  for (k=0; k<KLT_ORDER_SHAPE; k++) {
+    tmpcoeffs_sQ17[WebRtcIsacfix_kSelIndShape[k]] = WEBRTC_SPL_MUL(128, WebRtcIsacfix_kLevelsShapeQ10[WebRtcIsacfix_kOfLevelsShape[0]+index_ovr_sQQ[k]]);
+
+  }
+  /* inverse KLT  */
+
+  /* left transform */  // Transpose matrix!
+  offss = 0;
+  poss = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    offs2 = 0;
+    for (k=0; k<LPC_SHAPE_ORDER; k++) {
+      sumQQ = 0;
+      pos = offss;
+      pos2 = offs2;
+      for (n=0; n<LPC_SHAPE_ORDER; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1ShapeQ15[0][pos2], tmpcoeffs_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
+        pos++;
+        pos2++;
+      }
+      tmpcoeffs2_sQ17[poss] = sumQQ;
+
+      poss++;
+      offs2 += LPC_SHAPE_ORDER;
+    }
+    offss += LPC_SHAPE_ORDER;
+  }
+
+
+  /* right transform */ // Transpose matrix
+  offss = 0;
+  poss = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    poss = offss;
+    for (k=0; k<LPC_SHAPE_ORDER; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = j;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2ShapeQ15[0][pos2], tmpcoeffs2_sQ17[pos]<<1)); // (Q15*Q17)>>(16-1) = Q17
+        pos += LPC_SHAPE_ORDER;
+        pos2 += SUBFRAMES;
+      }
+      tmpcoeffs_sQ17[poss] = sumQQ;
+      poss++;
+    }
+    offss += LPC_SHAPE_ORDER;
+  }
+
+  /* scaling, mean addition, and gain restoration */
+  poss = 0;pos=0;
+  for (k=0; k<SUBFRAMES; k++) {
+
+    /* lo band LAR coeffs */
+    for (n=0; n<ORDERLO; n++, pos++, poss++) {
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(31208, tmpcoeffs_sQ17[poss]); // (Q16*Q17)>>16 = Q17, with 1/2.1 = 0.47619047619 ~= 31208 in Q16
+      tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17
+      LPCCoefQ17[pos] = tmp32;
+    }
+
+    /* hi band LAR coeffs */
+    for (n=0; n<ORDERHI; n++, pos++, poss++) {
+      tmp32 = WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(18204, tmpcoeffs_sQ17[poss]), 3); // ((Q13*Q17)>>16)<<3 = Q17, with 1/0.45 = 2.222222222222 ~= 18204 in Q13
+      tmp32 = tmp32 + WebRtcIsacfix_kMeansShapeQ17[0][poss]; // Q17+Q17 = Q17
+      LPCCoefQ17[pos] = tmp32;
+    }
+
+  }
+
+  //to update tmpcoeffs_gQ17 to the proper state
+  for (k=0; k<KLT_ORDER_GAIN; k++) {
+    tmpcoeffs_gQ17[WebRtcIsacfix_kSelIndGain[k]] = WebRtcIsacfix_kLevelsGainQ17[WebRtcIsacfix_kOfLevelsGain[0]+index_ovr_gQQ[k]];
+  }
+
+
+
+  /* find quantization levels for coefficients */
+
+  /* left transform */
+  offsg = 0;
+  posg = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    offs2 = 0;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = offsg;
+      pos2 = offs2;
+      for (n=0; n<2; n++) {
+        sumQQ += (WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT1GainQ15[0][pos2], tmpcoeffs_gQ17[pos])<<1); // (Q15*Q17)>>(16-1) = Q17
+        pos++;
+        pos2++;
+      }
+      tmpcoeffs2_gQ21[posg] = WEBRTC_SPL_LSHIFT_W32(sumQQ, 4); //Q17<<4 = Q21
+      posg++;
+      offs2 += 2;
+    }
+    offsg += 2;
+  }
+
+  /* right transform */ // Transpose matrix
+  offsg = 0;
+  posg = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = j;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
+        pos += 2;
+        pos2 += SUBFRAMES;
+      }
+      tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
+      posg++;
+    }
+    offsg += 2;
+  }
+
+  /* scaling, mean addition, and gain restoration */
+  posg = 0;
+  gainpos = 0;
+  for (k=0; k<2*SUBFRAMES; k++) {
+
+    sumQQ16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpcoeffs_gQ17[posg], 2+9); //Divide by 4 and get Q17 to Q8, i.e. shift 2+9
+    sumQQ16 += WebRtcIsacfix_kMeansGainQ8[0][posg];
+    sumQQ = CalcExpN(sumQQ16); // Q8 in and Q17 out
+    gain_lo_hiQ17[gainpos] = sumQQ; //Q17
+
+    gainpos++;
+    pos++;posg++;
+  }
+
+  return 0;
+}
+
+int WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17,
+                                 Bitstr_enc *streamdata,
+                                 ISAC_SaveEncData_t* encData) {
+  int j, k, n;
+  WebRtc_Word16 posQQ, pos2QQ, gainpos;
+  WebRtc_Word16  pos, pos2, posg, offsg, offs2;
+  WebRtc_Word16 index_gQQ[KLT_ORDER_GAIN];
+
+  WebRtc_Word16 tmpcoeffs_gQ6[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
+  WebRtc_Word32 sumQQ;
+  int status = 0;
+
+  /* write LAR coefficients to statistics file */
+  /* Save data for creation of multiple bitstreams (and transcoding) */
+  if (encData != NULL) {
+    for (k=0; k<KLT_ORDER_GAIN; k++) {
+      encData->LPCcoeffs_g[KLT_ORDER_GAIN*encData->startIdx + k] = gain_lo_hiQ17[k];
+    }
+  }
+
+  /* log gains, mean removal and scaling */
+  posg = 0; pos = 0; gainpos = 0;
+
+  for (k=0; k<SUBFRAMES; k++) {
+    /* log gains */
+
+    /* The input argument X to logN(X) is 2^17 times higher than the
+       input floating point argument Y to log(Y), since the X value
+       is a Q17 value. This can be compensated for after the call, by
+       subraction a value Z for each Q-step. One Q-step means that
+       X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
+       177.445678 should be subtracted (since logN() returns a Q8 value).
+       For a X value in Q17, the value 177.445678*17 = 3017 should be
+       subtracted */
+    tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
+    tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
+    posg++; gainpos++;
+
+    tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
+    tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
+    posg++; gainpos++;
+  }
+
+
+  /* KLT  */
+
+  /* left transform */
+  offsg = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = offsg;
+      pos2 = k;
+      for (n=0; n<2; n++) {
+        sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15
+        pos++;
+        pos2 += 2;
+      }
+      tmpcoeffs2_gQ21[posg] = sumQQ;
+      posg++;
+    }
+    offsg += 2;
+  }
+
+  /* right transform */
+  offsg = 0;
+  offs2 = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = offs2;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
+        pos += 2;
+        pos2++;
+      }
+      tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
+      posg++;
+    }
+    offsg += 2;
+    offs2 += SUBFRAMES;
+  }
+
+  /* quantize coefficients */
+
+  for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
+  {
+    posQQ = WebRtcIsacfix_kSelIndGain[k];
+    pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
+
+    index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
+    if (index_gQQ[k] < 0) {
+      index_gQQ[k] = 0;
+    }
+    else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
+      index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
+    }
+
+    /* Save data for creation of multiple bitstreams */
+    if (encData != NULL) {
+      encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_gQQ[k];
+    }
+  }
+
+  /* entropy coding of index */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, index_gQQ, WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN);
+  if (status < 0) {
+    return status;
+  }
+
+  return 0;
+}
+
+
+int WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
+                            WebRtc_Word16 *LPCCoef_loQ15,
+                            WebRtc_Word16 *LPCCoef_hiQ15,
+                            WebRtc_Word16 *model,
+                            WebRtc_Word32 *sizeQ11,
+                            Bitstr_enc *streamdata,
+                            ISAC_SaveEncData_t* encData,
+                            transcode_obj *transcodeParam)
+{
+  int status = 0;
+  WebRtc_Word32 larsQ17[KLT_ORDER_SHAPE]; // KLT_ORDER_SHAPE == (ORDERLO+ORDERHI)*SUBFRAMES
+  // = (6+12)*6 == 108
+
+  Poly2LarFix(LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES, larsQ17);
+
+  status = EstCodeLpcCoef(larsQ17, gain_lo_hiQ17, model, sizeQ11, streamdata, encData, transcodeParam);
+  if (status < 0) {
+    return (status);
+  }
+
+  Lar2polyFix(larsQ17, LPCCoef_loQ15, ORDERLO, LPCCoef_hiQ15, ORDERHI, SUBFRAMES);
+
+  return 0;
+}
+
+
+/* decode & dequantize RC */
+int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata, WebRtc_Word16 *RCQ15)
+{
+  int k, err;
+  WebRtc_Word16 index[AR_ORDER];
+
+  /* entropy decoding of quantization indices */
+  err = WebRtcIsacfix_DecHistOneStepMulti(index, streamdata, WebRtcIsacfix_kRcCdfPtr, WebRtcIsacfix_kRcInitInd, AR_ORDER);
+  if (err<0)  // error check
+    return err;
+
+  /* find quantization levels for reflection coefficients */
+  for (k=0; k<AR_ORDER; k++)
+  {
+    RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]);
+  }
+
+  return 0;
+}
+
+
+
+/* quantize & code RC */
+int WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15, Bitstr_enc *streamdata)
+{
+  int k;
+  WebRtc_Word16 index[AR_ORDER];
+  int status;
+
+  /* quantize reflection coefficients (add noise feedback?) */
+  for (k=0; k<AR_ORDER; k++)
+  {
+    index[k] = WebRtcIsacfix_kRcInitInd[k];
+
+    if (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k]])
+    {
+      while (RCQ15[k] > WebRtcIsacfix_kRcBound[index[k] + 1])
+        index[k]++;
+    }
+    else
+    {
+      while (RCQ15[k] < WebRtcIsacfix_kRcBound[--index[k]]) ;
+    }
+
+    RCQ15[k] = *(WebRtcIsacfix_kRcLevPtr[k] + index[k]);
+  }
+
+
+  /* entropy coding of quantization indices */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, index, WebRtcIsacfix_kRcCdfPtr, AR_ORDER);
+
+  /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
+  return status;
+}
+
+
+/* decode & dequantize squared Gain */
+int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata, WebRtc_Word32 *gainQ10)
+{
+  int err;
+  WebRtc_Word16 index;
+
+  /* entropy decoding of quantization index */
+  err = WebRtcIsacfix_DecHistOneStepMulti(
+      &index,
+      streamdata,
+      WebRtcIsacfix_kGainPtr,
+      WebRtcIsacfix_kGainInitInd,
+      1);
+  /* error check */
+  if (err<0) {
+    return err;
+  }
+
+  /* find quantization level */
+  *gainQ10 = WebRtcIsacfix_kGain2Lev[index];
+
+  return 0;
+}
+
+
+
+/* quantize & code squared Gain */
+int WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr_enc *streamdata)
+{
+  WebRtc_Word16 index;
+  int status = 0;
+
+  /* find quantization index */
+  index = WebRtcIsacfix_kGainInitInd[0];
+  if (*gainQ10 > WebRtcIsacfix_kGain2Bound[index])
+  {
+    while (*gainQ10 > WebRtcIsacfix_kGain2Bound[index + 1])
+      index++;
+  }
+  else
+  {
+    while (*gainQ10 < WebRtcIsacfix_kGain2Bound[--index]) ;
+  }
+
+  /* dequantize */
+  *gainQ10 = WebRtcIsacfix_kGain2Lev[index];
+
+  /* entropy coding of quantization index */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, &index, WebRtcIsacfix_kGainPtr, 1);
+
+  /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
+  return status;
+}
+
+
+/* code and decode Pitch Gains and Lags functions */
+
+/* decode & dequantize Pitch Gains */
+int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata, WebRtc_Word16 *PitchGains_Q12)
+{
+  int err;
+  WebRtc_Word16 index_comb;
+  const WebRtc_UWord16 *pitch_gain_cdf_ptr[1];
+
+  /* entropy decoding of quantization indices */
+  *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
+  err = WebRtcIsacfix_DecHistBisectMulti(&index_comb, streamdata, pitch_gain_cdf_ptr, WebRtcIsacfix_kCdfTableSizeGain, 1);
+  /* error check, Q_mean_Gain.. tables are of size 144 */
+  if ((err<0) || (index_comb<0) || (index_comb>144))
+    return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN;
+
+  /* unquantize back to pitch gains by table look-up */
+  PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb];
+  PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb];
+  PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb];
+  PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb];
+
+  return 0;
+}
+
+
+/* quantize & code Pitch Gains */
+int WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData)
+{
+  int k,j;
+  WebRtc_Word16 SQ15[PITCH_SUBFRAMES];
+  WebRtc_Word16 index[3];
+  WebRtc_Word16 index_comb;
+  const WebRtc_UWord16 *pitch_gain_cdf_ptr[1];
+  WebRtc_Word32 CQ17;
+  int status = 0;
+
+
+  /* get the approximate arcsine (almost linear)*/
+  for (k=0; k<PITCH_SUBFRAMES; k++)
+    SQ15[k] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(PitchGains_Q12[k],33,2); //Q15
+
+
+  /* find quantization index; only for the first three transform coefficients */
+  for (k=0; k<3; k++)
+  {
+    /*  transform */
+    CQ17=0;
+    for (j=0; j<PITCH_SUBFRAMES; j++) {
+      CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], SQ15[j],10); // Q17
+    }
+
+    index[k] = (WebRtc_Word16)((CQ17 + 8192)>>14); // Rounding and scaling with stepsize (=1/0.125=8)
+
+    /* check that the index is not outside the boundaries of the table */
+    if (index[k] < WebRtcIsacfix_kLowerlimiGain[k]) index[k] = WebRtcIsacfix_kLowerlimiGain[k];
+    else if (index[k] > WebRtcIsacfix_kUpperlimitGain[k]) index[k] = WebRtcIsacfix_kUpperlimitGain[k];
+    index[k] -= WebRtcIsacfix_kLowerlimiGain[k];
+  }
+
+  /* calculate unique overall index */
+  index_comb = (WebRtc_Word16)(WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[0], index[0]) +
+                               WEBRTC_SPL_MUL(WebRtcIsacfix_kMultsGain[1], index[1]) + index[2]);
+
+  /* unquantize back to pitch gains by table look-up */
+  // (Y)
+  PitchGains_Q12[0] = WebRtcIsacfix_kPitchGain1[index_comb];
+  PitchGains_Q12[1] = WebRtcIsacfix_kPitchGain2[index_comb];
+  PitchGains_Q12[2] = WebRtcIsacfix_kPitchGain3[index_comb];
+  PitchGains_Q12[3] = WebRtcIsacfix_kPitchGain4[index_comb];
+
+
+  /* entropy coding of quantization pitch gains */
+  *pitch_gain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf;
+  status = WebRtcIsacfix_EncHistMulti(streamdata, &index_comb, pitch_gain_cdf_ptr, 1);
+  if (status < 0) {
+    return status;
+  }
+
+  /* Save data for creation of multiple bitstreams */
+  if (encData != NULL) {
+    encData->pitchGain_index[encData->startIdx] = index_comb;
+  }
+
+  return 0;
+}
+
+
+
+/* Pitch LAG */
+
+
+/* decode & dequantize Pitch Lags */
+int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
+                                 WebRtc_Word16 *PitchGain_Q12,
+                                 WebRtc_Word16 *PitchLags_Q7)
+{
+  int k, err;
+  WebRtc_Word16 index[PITCH_SUBFRAMES];
+  const WebRtc_Word16 *mean_val2Q10, *mean_val4Q10;
+
+  const WebRtc_Word16 *lower_limit;
+  const WebRtc_UWord16 *init_index;
+  const WebRtc_UWord16 *cdf_size;
+  const WebRtc_UWord16 **cdf;
+
+  WebRtc_Word32 meangainQ12;
+  WebRtc_Word32 CQ11, CQ10,tmp32a,tmp32b;
+  WebRtc_Word16 shft,tmp16a,tmp16c;
+
+  meangainQ12=0;
+  for (k = 0; k < 4; k++)
+    meangainQ12 += PitchGain_Q12[k];
+
+  meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2);  // Get average
+
+  /* voicing classificiation */
+  if (meangainQ12 <= 819) {                 // mean_gain < 0.2
+    shft = -1;        // StepSize=2.0;
+    cdf = WebRtcIsacfix_kPitchLagPtrLo;
+    cdf_size = WebRtcIsacfix_kPitchLagSizeLo;
+    mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo;
+    mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo;
+    lower_limit = WebRtcIsacfix_kLowerLimitLo;
+    init_index = WebRtcIsacfix_kInitIndLo;
+  } else if (meangainQ12 <= 1638) {            // mean_gain < 0.4
+    shft = 0;        // StepSize=1.0;
+    cdf = WebRtcIsacfix_kPitchLagPtrMid;
+    cdf_size = WebRtcIsacfix_kPitchLagSizeMid;
+    mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid;
+    mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid;
+    lower_limit = WebRtcIsacfix_kLowerLimitMid;
+    init_index = WebRtcIsacfix_kInitIndMid;
+  } else {
+    shft = 1;        // StepSize=0.5;
+    cdf = WebRtcIsacfix_kPitchLagPtrHi;
+    cdf_size = WebRtcIsacfix_kPitchLagSizeHi;
+    mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi;
+    mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi;
+    lower_limit = WebRtcIsacfix_kLowerLimitHi;
+    init_index = WebRtcIsacfix_kInitIndHi;
+  }
+
+  /* entropy decoding of quantization indices */
+  err = WebRtcIsacfix_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1);
+  if ((err<0) || (index[0]<0))  // error check
+    return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
+
+  err = WebRtcIsacfix_DecHistOneStepMulti(index+1, streamdata, cdf+1, init_index, 3);
+  if (err<0)  // error check
+    return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
+
+
+  /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */
+  CQ11 = ((WebRtc_Word32)index[0] + lower_limit[0]);  // Q0
+  CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
+  for (k=0; k<PITCH_SUBFRAMES; k++) {
+    tmp32a =  WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11);
+    tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);
+    PitchLags_Q7[k] = tmp16a;
+  }
+
+  CQ10 = mean_val2Q10[index[1]];
+  for (k=0; k<PITCH_SUBFRAMES; k++) {
+    tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10);
+    tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
+    PitchLags_Q7[k] += tmp16c;
+  }
+
+  CQ10 = mean_val4Q10[index[3]];
+  for (k=0; k<PITCH_SUBFRAMES; k++) {
+    tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10);
+    tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5);
+    PitchLags_Q7[k] += tmp16c;
+  }
+
+  return 0;
+}
+
+
+
+/* quantize & code Pitch Lags */
+int WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagsQ7,WebRtc_Word16 *PitchGain_Q12,
+                                 Bitstr_enc *streamdata, ISAC_SaveEncData_t* encData)
+{
+  int k, j;
+  WebRtc_Word16 index[PITCH_SUBFRAMES];
+  WebRtc_Word32 meangainQ12, CQ17;
+  WebRtc_Word32 CQ11, CQ10,tmp32a;
+
+  const WebRtc_Word16 *mean_val2Q10,*mean_val4Q10;
+  const WebRtc_Word16 *lower_limit, *upper_limit;
+  const WebRtc_UWord16 **cdf;
+  WebRtc_Word16 shft, tmp16a, tmp16b, tmp16c;
+  WebRtc_Word32 tmp32b;
+  int status = 0;
+
+  /* compute mean pitch gain */
+  meangainQ12=0;
+  for (k = 0; k < 4; k++)
+    meangainQ12 += PitchGain_Q12[k];
+
+  meangainQ12 = WEBRTC_SPL_RSHIFT_W32(meangainQ12, 2);
+
+  /* Save data for creation of multiple bitstreams */
+  if (encData != NULL) {
+    encData->meanGain[encData->startIdx] = meangainQ12;
+  }
+
+  /* voicing classificiation */
+  if (meangainQ12 <= 819) {                 // mean_gain < 0.2
+    shft = -1;        // StepSize=2.0;
+    cdf = WebRtcIsacfix_kPitchLagPtrLo;
+    mean_val2Q10 = WebRtcIsacfix_kMeanLag2Lo;
+    mean_val4Q10 = WebRtcIsacfix_kMeanLag4Lo;
+    lower_limit = WebRtcIsacfix_kLowerLimitLo;
+    upper_limit = WebRtcIsacfix_kUpperLimitLo;
+  } else if (meangainQ12 <= 1638) {            // mean_gain < 0.4
+    shft = 0;        // StepSize=1.0;
+    cdf = WebRtcIsacfix_kPitchLagPtrMid;
+    mean_val2Q10 = WebRtcIsacfix_kMeanLag2Mid;
+    mean_val4Q10 = WebRtcIsacfix_kMeanLag4Mid;
+    lower_limit = WebRtcIsacfix_kLowerLimitMid;
+    upper_limit = WebRtcIsacfix_kUpperLimitMid;
+  } else {
+    shft = 1;        // StepSize=0.5;
+    cdf = WebRtcIsacfix_kPitchLagPtrHi;
+    mean_val2Q10 = WebRtcIsacfix_kMeanLag2Hi;
+    mean_val4Q10 = WebRtcIsacfix_kMeanLag4Hi;
+    lower_limit = WebRtcIsacfix_kLowerLimitHi;
+    upper_limit = WebRtcIsacfix_kUpperLimitHi;
+  }
+
+  /* find quantization index */
+  for (k=0; k<4; k++)
+  {
+    /*  transform */
+    CQ17=0;
+    for (j=0; j<PITCH_SUBFRAMES; j++)
+      CQ17 += WEBRTC_SPL_MUL_16_16_RSFT(WebRtcIsacfix_kTransform[k][j], PitchLagsQ7[j],2); // Q17
+
+    CQ17 = WEBRTC_SPL_SHIFT_W32(CQ17,shft); // Scale with StepSize
+
+    /* quantize */
+    tmp16b = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(CQ17 + 65536, 17 );
+    index[k] =  tmp16b;
+
+    /* check that the index is not outside the boundaries of the table */
+    if (index[k] < lower_limit[k]) index[k] = lower_limit[k];
+    else if (index[k] > upper_limit[k]) index[k] = upper_limit[k];
+    index[k] -= lower_limit[k];
+
+    /* Save data for creation of multiple bitstreams */
+    if(encData != NULL) {
+      encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k];
+    }
+  }
+
+  /* unquantize back to transform coefficients and do the inverse transform: S = T'*C */
+  CQ11 = (index[0] + lower_limit[0]);  // Q0
+  CQ11 = WEBRTC_SPL_SHIFT_W32(CQ11,11-shft); // Scale with StepSize, Q11
+
+  for (k=0; k<PITCH_SUBFRAMES; k++) {
+    tmp32a =  WEBRTC_SPL_MUL_16_32_RSFT11(WebRtcIsacfix_kTransform[0][k], CQ11); // Q12
+    tmp16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32a, 5);// Q7
+    PitchLagsQ7[k] = tmp16a;
+  }
+
+  CQ10 = mean_val2Q10[index[1]];
+  for (k=0; k<PITCH_SUBFRAMES; k++) {
+    tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[1][k], (WebRtc_Word16) CQ10,10);
+    tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
+    PitchLagsQ7[k] += tmp16c;
+  }
+
+  CQ10 = mean_val4Q10[index[3]];
+  for (k=0; k<PITCH_SUBFRAMES; k++) {
+    tmp32b =  (WebRtc_Word32) WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) WebRtcIsacfix_kTransform[3][k], (WebRtc_Word16) CQ10,10);
+    tmp16c = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32b, 5); // Q7
+    PitchLagsQ7[k] += tmp16c;
+  }
+
+  /* entropy coding of quantization pitch lags */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES);
+
+  /* If error in WebRtcIsacfix_EncHistMulti(), status will be negative, otherwise 0 */
+  return status;
+}
+
+
+
+/* Routines for inband signaling of bandwitdh estimation */
+/* Histograms based on uniform distribution of indices */
+/* Move global variables later! */
+
+
+/* cdf array for frame length indicator */
+const WebRtc_UWord16 kFrameLenCdf[4] = {
+  0, 21845, 43690, 65535};
+
+/* pointer to cdf array for frame length indicator */
+const WebRtc_UWord16 *kFrameLenCdfPtr[1] = {kFrameLenCdf};
+
+/* initial cdf index for decoder of frame length indicator */
+const WebRtc_UWord16 kFrameLenInitIndex[1] = {1};
+
+
+int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata,
+                                 WebRtc_Word16 *framesamples)
+{
+
+  int err;
+  WebRtc_Word16 frame_mode;
+
+  err = 0;
+  /* entropy decoding of frame length [1:30ms,2:60ms] */
+  err = WebRtcIsacfix_DecHistOneStepMulti(&frame_mode, streamdata, kFrameLenCdfPtr, kFrameLenInitIndex, 1);
+  if (err<0)  // error check
+    return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH;
+
+  switch(frame_mode) {
+    case 1:
+      *framesamples = 480; /* 30ms */
+      break;
+    case 2:
+      *framesamples = 960; /* 60ms */
+      break;
+    default:
+      err = -ISAC_DISALLOWED_FRAME_MODE_DECODER;
+  }
+
+  return err;
+}
+
+
+int WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framesamples, Bitstr_enc *streamdata) {
+
+  int status;
+  WebRtc_Word16 frame_mode;
+
+  status = 0;
+  frame_mode = 0;
+  /* entropy coding of frame length [1:480 samples,2:960 samples] */
+  switch(framesamples) {
+    case 480:
+      frame_mode = 1;
+      break;
+    case 960:
+      frame_mode = 2;
+      break;
+    default:
+      status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER;
+  }
+
+  if (status < 0)
+    return status;
+
+  status = WebRtcIsacfix_EncHistMulti(streamdata, &frame_mode, kFrameLenCdfPtr, 1);
+
+  return status;
+}
+
+/* cdf array for estimated bandwidth */
+const WebRtc_UWord16 kBwCdf[25] = {
+  0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037,
+  32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074,
+  62804, 65535};
+
+/* pointer to cdf array for estimated bandwidth */
+const WebRtc_UWord16 *kBwCdfPtr[1] = {kBwCdf};
+
+/* initial cdf index for decoder of estimated bandwidth*/
+const WebRtc_UWord16 kBwInitIndex[1] = {7};
+
+
+int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata, WebRtc_Word16 *BWno) {
+
+  int err;
+  WebRtc_Word16 BWno32;
+
+  /* entropy decoding of sender's BW estimation [0..23] */
+  err = WebRtcIsacfix_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr, kBwInitIndex, 1);
+  if (err<0)  // error check
+    return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH;
+  *BWno = (WebRtc_Word16)BWno32;
+  return err;
+
+}
+
+
+int WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno, Bitstr_enc *streamdata)
+{
+  int status = 0;
+  /* entropy encoding of receiver's BW estimation [0..23] */
+  status = WebRtcIsacfix_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1);
+
+  return status;
+}
+
+/* estimate codel length of LPC Coef */
+void WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *gain_lo_hiQ17,
+                                    WebRtc_Word16 *index_gQQ) {
+  int j, k, n;
+  WebRtc_Word16 posQQ, pos2QQ;
+  WebRtc_Word16  pos, pos2, posg, offsg, offs2, gainpos;
+  WebRtc_Word32 tmpcoeffs_gQ6[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs_gQ17[KLT_ORDER_GAIN];
+  WebRtc_Word32 tmpcoeffs2_gQ21[KLT_ORDER_GAIN];
+  WebRtc_Word32 sumQQ;
+
+
+  /* log gains, mean removal and scaling */
+  posg = 0;pos=0; gainpos=0;
+
+  for (k=0; k<SUBFRAMES; k++) {
+    /* log gains */
+
+    /* The input argument X to logN(X) is 2^17 times higher than the
+       input floating point argument Y to log(Y), since the X value
+       is a Q17 value. This can be compensated for after the call, by
+       subraction a value Z for each Q-step. One Q-step means that
+       X gets 2 times higher, i.e. Z = logN(2)*256 = 0.693147180559*256 =
+       177.445678 should be subtracted (since logN() returns a Q8 value).
+       For a X value in Q17, the value 177.445678*17 = 3017 should be
+       subtracted */
+    tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
+    tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
+    posg++; gainpos++;
+
+    tmpcoeffs_gQ6[posg] = CalcLogN(gain_lo_hiQ17[gainpos])-3017; //Q8
+    tmpcoeffs_gQ6[posg] -= WebRtcIsacfix_kMeansGainQ8[0][posg]; //Q8, but Q6 after not-needed mult. by 4
+    posg++; gainpos++;
+
+  }
+
+
+  /* KLT  */
+
+  /* left transform */
+  offsg = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = offsg;
+      pos2 = k;
+      for (n=0; n<2; n++) {
+        sumQQ += WEBRTC_SPL_MUL_16_16(tmpcoeffs_gQ6[pos], WebRtcIsacfix_kT1GainQ15[0][pos2]); //Q21 = Q6*Q15
+        pos++;
+        pos2 += 2;
+      }
+      tmpcoeffs2_gQ21[posg] = sumQQ;
+      posg++;
+    }
+
+    offsg += 2;
+  }
+
+  /* right transform */
+  offsg = 0;
+  offs2 = 0;
+  for (j=0; j<SUBFRAMES; j++) {
+    posg = offsg;
+    for (k=0; k<2; k++) {
+      sumQQ = 0;
+      pos = k;
+      pos2 = offs2;
+      for (n=0; n<SUBFRAMES; n++) {
+        sumQQ += WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(WebRtcIsacfix_kT2GainQ15[0][pos2], tmpcoeffs2_gQ21[pos]), 1); // (Q15*Q21)>>(16-1) = Q21
+        pos += 2;
+        pos2++;
+      }
+      tmpcoeffs_gQ17[posg] = WEBRTC_SPL_RSHIFT_W32(sumQQ, 4);
+      posg++;
+    }
+    offsg += 2;
+    offs2 += SUBFRAMES;
+  }
+
+  /* quantize coefficients */
+  for (k=0; k<KLT_ORDER_GAIN; k++) //ATTN: ok?
+  {
+    posQQ = WebRtcIsacfix_kSelIndGain[k];
+    pos2QQ= (WebRtc_Word16)CalcLrIntQ(tmpcoeffs_gQ17[posQQ], 17);
+
+    index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok?
+    if (index_gQQ[k] < 0) {
+      index_gQQ[k] = 0;
+    }
+    else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) {
+      index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k];
+    }
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h b/src/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h
new file mode 100644
index 0000000..298ea22
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h
@@ -0,0 +1,111 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * entropy_coding.h
+ *
+ * This header file contains all of the functions used to arithmetically
+ * encode the iSAC bistream
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_
+
+#include "structs.h"
+
+/* decode complex spectrum (return number of bytes in stream) */
+WebRtc_Word16 WebRtcIsacfix_DecodeSpec(Bitstr_dec  *streamdata,
+                                       WebRtc_Word16 *frQ7,
+                                       WebRtc_Word16 *fiQ7,
+                                       WebRtc_Word16 AvgPitchGain_Q12);
+
+/* encode complex spectrum */
+int WebRtcIsacfix_EncodeSpec(const WebRtc_Word16 *fr,
+                             const WebRtc_Word16 *fi,
+                             Bitstr_enc *streamdata,
+                             WebRtc_Word16 AvgPitchGain_Q12);
+
+
+/* decode & dequantize LPC Coef */
+int WebRtcIsacfix_DecodeLpcCoef(Bitstr_dec  *streamdata,
+                                WebRtc_Word32 *LPCCoefQ17,
+                                WebRtc_Word32 *gain_lo_hiQ17,
+                                WebRtc_Word16 *outmodel);
+
+int WebRtcIsacfix_DecodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
+                            WebRtc_Word16 *LPCCoef_loQ15,
+                            WebRtc_Word16 *LPCCoef_hiQ15,
+                            Bitstr_dec  *streamdata,
+                            WebRtc_Word16 *outmodel);
+
+/* quantize & code LPC Coef */
+int WebRtcIsacfix_EncodeLpc(WebRtc_Word32 *gain_lo_hiQ17,
+                            WebRtc_Word16 *LPCCoef_loQ15,
+                            WebRtc_Word16 *LPCCoef_hiQ15,
+                            WebRtc_Word16 *model,
+                            WebRtc_Word32 *sizeQ11,
+                            Bitstr_enc *streamdata,
+                            ISAC_SaveEncData_t* encData,
+                            transcode_obj *transcodeParam);
+
+int WebRtcIsacfix_EstCodeLpcGain(WebRtc_Word32 *gain_lo_hiQ17,
+                                 Bitstr_enc *streamdata,
+                                 ISAC_SaveEncData_t* encData);
+/* decode & dequantize RC */
+int WebRtcIsacfix_DecodeRcCoef(Bitstr_dec *streamdata,
+                               WebRtc_Word16 *RCQ15);
+
+/* quantize & code RC */
+int WebRtcIsacfix_EncodeRcCoef(WebRtc_Word16 *RCQ15,
+                               Bitstr_enc *streamdata);
+
+/* decode & dequantize squared Gain */
+int WebRtcIsacfix_DecodeGain2(Bitstr_dec *streamdata,
+                              WebRtc_Word32 *Gain2);
+
+/* quantize & code squared Gain (input is squared gain) */
+int WebRtcIsacfix_EncodeGain2(WebRtc_Word32 *gain2,
+                              Bitstr_enc *streamdata);
+
+int WebRtcIsacfix_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12,
+                                  Bitstr_enc *streamdata,
+                                  ISAC_SaveEncData_t* encData);
+
+int WebRtcIsacfix_EncodePitchLag(WebRtc_Word16 *PitchLagQ7,
+                                 WebRtc_Word16 *PitchGain_Q12,
+                                 Bitstr_enc *streamdata,
+                                 ISAC_SaveEncData_t* encData);
+
+int WebRtcIsacfix_DecodePitchGain(Bitstr_dec *streamdata,
+                                  WebRtc_Word16 *PitchGain_Q12);
+
+int WebRtcIsacfix_DecodePitchLag(Bitstr_dec *streamdata,
+                                 WebRtc_Word16 *PitchGain_Q12,
+                                 WebRtc_Word16 *PitchLagQ7);
+
+int WebRtcIsacfix_DecodeFrameLen(Bitstr_dec *streamdata,
+                                 WebRtc_Word16 *framelength);
+
+
+int WebRtcIsacfix_EncodeFrameLen(WebRtc_Word16 framelength,
+                                 Bitstr_enc *streamdata);
+
+int WebRtcIsacfix_DecodeSendBandwidth(Bitstr_dec *streamdata,
+                                      WebRtc_Word16 *BWno);
+
+
+int WebRtcIsacfix_EncodeReceiveBandwidth(WebRtc_Word16 *BWno,
+                                         Bitstr_enc *streamdata);
+
+void WebRtcIsacfix_TranscodeLpcCoef(WebRtc_Word32 *tmpcoeffs_gQ6,
+                                    WebRtc_Word16 *index_gQQ);
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_ENTROPY_CODING_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/fft.c b/src/modules/audio_coding/codecs/isac/fix/source/fft.c
new file mode 100644
index 0000000..fff35c4
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/fft.c
@@ -0,0 +1,415 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * fft.c
+ *
+ * Fast Fourier Transform
+ *
+ */
+
+
+#include "fft.h"
+
+const WebRtc_Word16 kSortTabFft[240] = {
+  0, 60, 120, 180, 20, 80, 140, 200, 40, 100, 160, 220,
+  4, 64, 124, 184, 24, 84, 144, 204, 44, 104, 164, 224,
+  8, 68, 128, 188, 28, 88, 148, 208, 48, 108, 168, 228,
+  12, 72, 132, 192, 32, 92, 152, 212, 52, 112, 172, 232,
+  16, 76, 136, 196, 36, 96, 156, 216, 56, 116, 176, 236,
+  1, 61, 121, 181, 21, 81, 141, 201, 41, 101, 161, 221,
+  5, 65, 125, 185, 25, 85, 145, 205, 45, 105, 165, 225,
+  9, 69, 129, 189, 29, 89, 149, 209, 49, 109, 169, 229,
+  13, 73, 133, 193, 33, 93, 153, 213, 53, 113, 173, 233,
+  17, 77, 137, 197, 37, 97, 157, 217, 57, 117, 177, 237,
+  2, 62, 122, 182, 22, 82, 142, 202, 42, 102, 162, 222,
+  6, 66, 126, 186, 26, 86, 146, 206, 46, 106, 166, 226,
+  10, 70, 130, 190, 30, 90, 150, 210, 50, 110, 170, 230,
+  14, 74, 134, 194, 34, 94, 154, 214, 54, 114, 174, 234,
+  18, 78, 138, 198, 38, 98, 158, 218, 58, 118, 178, 238,
+  3, 63, 123, 183, 23, 83, 143, 203, 43, 103, 163, 223,
+  7, 67, 127, 187, 27, 87, 147, 207, 47, 107, 167, 227,
+  11, 71, 131, 191, 31, 91, 151, 211, 51, 111, 171, 231,
+  15, 75, 135, 195, 35, 95, 155, 215, 55, 115, 175, 235,
+  19, 79, 139, 199, 39, 99, 159, 219, 59, 119, 179, 239
+};
+
+/* Cosine table in Q14 */
+const WebRtc_Word16 kCosTabFfftQ14[240] = {
+  16384,  16378, 16362,   16333,  16294,  16244,  16182,  16110,  16026,  15931,  15826,  15709,
+  15582,  15444, 15296,   15137,  14968,  14788,  14598,  14399,  14189,  13970,  13741,  13502,
+  13255,  12998, 12733,   12458,  12176,  11885,  11585,  11278,  10963,  10641,  10311,   9974,
+  9630,   9280,  8923,    8561,   8192,   7818,   7438,   7053,   6664,   6270,   5872,   5469,
+  5063,   4653,  4240,    3825,   3406,   2986,   2563,   2139,   1713,   1285,    857,    429,
+  0,   -429,  -857,   -1285,  -1713,  -2139,  -2563,  -2986,  -3406,  -3825,  -4240,  -4653,
+  -5063,  -5469, -5872,   -6270,  -6664,  -7053,  -7438,  -7818,  -8192,  -8561,  -8923,  -9280,
+  -9630,  -9974, -10311, -10641, -10963, -11278, -11585, -11885, -12176, -12458, -12733, -12998,
+  -13255, -13502, -13741, -13970, -14189, -14399, -14598, -14788, -14968, -15137, -15296, -15444,
+  -15582, -15709, -15826, -15931, -16026, -16110, -16182, -16244, -16294, -16333, -16362, -16378,
+  -16384, -16378, -16362, -16333, -16294, -16244, -16182, -16110, -16026, -15931, -15826, -15709,
+  -15582, -15444, -15296, -15137, -14968, -14788, -14598, -14399, -14189, -13970, -13741, -13502,
+  -13255, -12998, -12733, -12458, -12176, -11885, -11585, -11278, -10963, -10641, -10311,  -9974,
+  -9630,  -9280,  -8923,  -8561,  -8192,  -7818,  -7438,  -7053,  -6664,  -6270,  -5872,  -5469,
+  -5063,  -4653,  -4240,  -3825,  -3406,  -2986,  -2563,  -2139,  -1713,  -1285,   -857,   -429,
+  0,    429,    857,   1285,   1713,   2139,   2563,   2986,   3406,   3825,   4240,   4653,
+  5063,   5469,   5872,   6270,   6664,   7053,   7438,   7818,   8192,   8561,   8923,   9280,
+  9630,   9974,  10311,  10641,  10963,  11278,  11585,  11885,  12176,  12458,  12733,  12998,
+  13255,  13502,  13741,  13970,  14189,  14399,  14598,  14788,  14968,  15137,  15296,  15444,
+  15582,  15709,  15826,  15931,  16026,  16110,  16182,  16244,  16294,  16333,  16362,  16378
+};
+
+
+
+/* Uses 16x16 mul, without rounding, which is faster. Uses WEBRTC_SPL_MUL_16_16_RSFT */
+WebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign) {
+
+  WebRtc_Word16 dd, ee, ff, gg, hh, ii;
+  WebRtc_Word16 k0, k1, k2, k3, k4, kk;
+  WebRtc_Word16 tmp116, tmp216;
+
+  WebRtc_Word16 ccc1Q14, ccc2Q14, ccc3Q14, sss1Q14, sss2Q14, sss3Q14;
+  WebRtc_Word16 sss60Q14, ccc72Q14, sss72Q14;
+  WebRtc_Word16 aaQx, ajQx, akQx, ajmQx, ajpQx, akmQx, akpQx;
+  WebRtc_Word16 bbQx, bjQx, bkQx, bjmQx, bjpQx, bkmQx, bkpQx;
+
+  WebRtc_Word16 ReDATAQx[240],  ImDATAQx[240];
+
+  sss60Q14 = kCosTabFfftQ14[20];
+  ccc72Q14 = kCosTabFfftQ14[48];
+  sss72Q14 = kCosTabFfftQ14[12];
+
+  if (iSign < 0) {
+    sss72Q14 = -sss72Q14;
+    sss60Q14 = -sss60Q14;
+  }
+  /* Complexity is: 10 cycles */
+
+  /* compute fourier transform */
+
+  // transform for factor of 4
+  for (kk=0; kk<60; kk++) {
+    k0 = kk;
+    k1 = k0 + 60;
+    k2 = k1 + 60;
+    k3 = k2 + 60;
+
+    akpQx = RexQx[k0] + RexQx[k2];
+    akmQx = RexQx[k0] - RexQx[k2];
+    ajpQx = RexQx[k1] + RexQx[k3];
+    ajmQx = RexQx[k1] - RexQx[k3];
+    bkpQx = ImxQx[k0] + ImxQx[k2];
+    bkmQx = ImxQx[k0] - ImxQx[k2];
+    bjpQx = ImxQx[k1] + ImxQx[k3];
+    bjmQx = ImxQx[k1] - ImxQx[k3];
+
+    RexQx[k0] = akpQx + ajpQx;
+    ImxQx[k0] = bkpQx + bjpQx;
+    ajpQx = akpQx - ajpQx;
+    bjpQx = bkpQx - bjpQx;
+    if (iSign < 0) {
+      akpQx = akmQx + bjmQx;
+      bkpQx = bkmQx - ajmQx;
+      akmQx -= bjmQx;
+      bkmQx += ajmQx;
+    } else {
+      akpQx = akmQx - bjmQx;
+      bkpQx = bkmQx + ajmQx;
+      akmQx += bjmQx;
+      bkmQx -= ajmQx;
+    }
+
+    ccc1Q14 = kCosTabFfftQ14[kk];
+    ccc2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)];
+    ccc3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)];
+    sss1Q14 = kCosTabFfftQ14[kk+60];
+    sss2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)+60];
+    sss3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)+60];
+    if (iSign==1) {
+      sss1Q14 = -sss1Q14;
+      sss2Q14 = -sss2Q14;
+      sss3Q14 = -sss3Q14;
+    }
+
+    //Do several multiplications like Q14*Q16>>14 = Q16
+    // RexQ16[k1] = akpQ16 * ccc1Q14 - bkpQ16 * sss1Q14;
+    // RexQ16[k2] = ajpQ16 * ccc2Q14 - bjpQ16 * sss2Q14;
+    // RexQ16[k3] = akmQ16 * ccc3Q14 - bkmQ16 * sss3Q14;
+    // ImxQ16[k1] = akpQ16 * sss1Q14 + bkpQ16 * ccc1Q14;
+    // ImxQ16[k2] = ajpQ16 * sss2Q14 + bjpQ16 * ccc2Q14;
+    // ImxQ16[k3] = akmQ16 * sss3Q14 + bkmQ16 * ccc3Q14;
+
+    RexQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, akpQx, 14) -
+        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, bkpQx, 14); // 6 non-mul + 2 mul cycles, i.e. 8 cycles (6+2*7=20 cycles if 16x32mul)
+    RexQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) -
+        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjpQx, 14);
+    RexQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, akmQx, 14) -
+        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, bkmQx, 14);
+    ImxQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, akpQx, 14) +
+        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, bkpQx, 14);
+    ImxQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajpQx, 14) +
+        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14);
+    ImxQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, akmQx, 14) +
+        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, bkmQx, 14);
+    //This mul segment needs 6*8 = 48 cycles for 16x16 muls, but 6*20 = 120 cycles for 16x32 muls
+
+
+  }
+  /* Complexity is: 51+48 = 99 cycles for 16x16 muls, but 51+120 = 171 cycles for 16x32 muls*/
+
+  // transform for factor of 3
+  kk=0;
+  k1=20;
+  k2=40;
+
+  for (hh=0; hh<4; hh++) {
+    for (ii=0; ii<20; ii++) {
+      akQx = RexQx[kk];
+      bkQx = ImxQx[kk];
+      ajQx = RexQx[k1] + RexQx[k2];
+      bjQx = ImxQx[k1] + ImxQx[k2];
+      RexQx[kk] = akQx + ajQx;
+      ImxQx[kk] = bkQx + bjQx;
+      tmp116 = WEBRTC_SPL_RSHIFT_W16(ajQx, 1);
+      tmp216 = WEBRTC_SPL_RSHIFT_W16(bjQx, 1);
+      akQx = akQx - tmp116;
+      bkQx = bkQx - tmp216;
+      tmp116 = RexQx[k1] - RexQx[k2];
+      tmp216 = ImxQx[k1] - ImxQx[k2];
+
+      ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp116, 14); // Q14*Qx>>14 = Qx
+      bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp216, 14); // Q14*Qx>>14 = Qx
+      RexQx[k1] = akQx - bjQx;
+      RexQx[k2] = akQx + bjQx;
+      ImxQx[k1] = bkQx + ajQx;
+      ImxQx[k2] = bkQx - ajQx;
+
+      kk++;
+      k1++;
+      k2++;
+    }
+    /* Complexity : (31+6)*20 = 740 cycles for 16x16 muls, but (31+18)*20 = 980 cycles for 16x32 muls*/
+    kk=kk+40;
+    k1=k1+40;
+    k2=k2+40;
+  }
+  /* Complexity : 4*(740+3) = 2972 cycles for 16x16 muls, but 4*(980+3) = 3932 cycles for 16x32 muls*/
+
+  /* multiply by rotation factor for odd factor 3 or 5 (not for 4)
+     Same code (duplicated) for both ii=2 and ii=3 */
+  kk = 1;
+  ee = 0;
+  ff = 0;
+
+  for (gg=0; gg<19; gg++) {
+    kk += 20;
+    ff = ff+4;
+    for (hh=0; hh<2; hh++) {
+      ee = ff + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(hh, ff);
+      dd = ee + 60;
+      ccc2Q14 = kCosTabFfftQ14[ee];
+      sss2Q14 = kCosTabFfftQ14[dd];
+      if (iSign==1) {
+        sss2Q14 = -sss2Q14;
+      }
+      for (ii=0; ii<4; ii++) {
+        akQx = RexQx[kk];
+        bkQx = ImxQx[kk];
+        RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) - // Q14*Qx>>14 = Qx
+            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
+        ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) + // Q14*Qx>>14 = Qx
+            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);
+
+
+        kk += 60;
+      }
+      kk = kk - 220;
+    }
+    // Complexity: 2*(13+5+4*13+2) = 144 for 16x16 muls, but 2*(13+5+4*33+2) = 304 cycles for 16x32 muls
+    kk = kk - 59;
+  }
+  // Complexity: 19*144 = 2736 for 16x16 muls, but 19*304 = 5776 cycles for 16x32 muls
+
+  // transform for factor of 5
+  kk = 0;
+  ccc2Q14 = kCosTabFfftQ14[96];
+  sss2Q14 = kCosTabFfftQ14[84];
+  if (iSign==1) {
+    sss2Q14 = -sss2Q14;
+  }
+
+  for (hh=0; hh<4; hh++) {
+    for (ii=0; ii<12; ii++) {
+      k1 = kk + 4;
+      k2 = k1 + 4;
+      k3 = k2 + 4;
+      k4 = k3 + 4;
+
+      akpQx = RexQx[k1] + RexQx[k4];
+      akmQx = RexQx[k1] - RexQx[k4];
+      bkpQx = ImxQx[k1] + ImxQx[k4];
+      bkmQx = ImxQx[k1] - ImxQx[k4];
+      ajpQx = RexQx[k2] + RexQx[k3];
+      ajmQx = RexQx[k2] - RexQx[k3];
+      bjpQx = ImxQx[k2] + ImxQx[k3];
+      bjmQx = ImxQx[k2] - ImxQx[k3];
+      aaQx = RexQx[kk];
+      bbQx = ImxQx[kk];
+      RexQx[kk] = aaQx + akpQx + ajpQx;
+      ImxQx[kk] = bbQx + bkpQx + bjpQx;
+
+      akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, akpQx, 14) +
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14)  + aaQx;
+      bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bkpQx, 14) +
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14)  + bbQx;
+      ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, akmQx, 14) +
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajmQx, 14);
+      bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bkmQx, 14) +
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjmQx, 14);
+      // 32+4*8=64 or 32+4*20=112
+
+      RexQx[k1] = akQx - bjQx;
+      RexQx[k4] = akQx + bjQx;
+      ImxQx[k1] = bkQx + ajQx;
+      ImxQx[k4] = bkQx - ajQx;
+
+      akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akpQx, 14)  +
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, ajpQx, 14) + aaQx;
+      bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkpQx, 14)  +
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bjpQx, 14) + bbQx;
+      ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akmQx, 14) -
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, ajmQx, 14);
+      bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkmQx, 14) -
+          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bjmQx, 14);
+      // 8+4*8=40 or 8+4*20=88
+
+      RexQx[k2] = akQx - bjQx;
+      RexQx[k3] = akQx + bjQx;
+      ImxQx[k2] = bkQx + ajQx;
+      ImxQx[k3] = bkQx - ajQx;
+
+      kk = k4 + 4;
+    }
+    // Complexity: 12*(64+40+10) = 1368 for 16x16 muls, but 12*(112+88+10) = 2520 cycles for 16x32 muls
+    kk -= 239;
+  }
+  // Complexity: 4*1368 = 5472 for 16x16 muls, but 4*2520 = 10080 cycles for 16x32 muls
+
+  /* multiply by rotation factor for odd factor 3 or 5 (not for 4)
+     Same code (duplicated) for both ii=2 and ii=3 */
+  kk = 1;
+  ee=0;
+
+  for (gg=0; gg<3; gg++) {
+    kk += 4;
+    dd = 12 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(12, gg);
+    ff = 0;
+    for (hh=0; hh<4; hh++) {
+      ff = ff+dd;
+      ee = ff+60;
+      for (ii=0; ii<12; ii++) {
+        akQx = RexQx[kk];
+        bkQx = ImxQx[kk];
+
+        ccc2Q14 = kCosTabFfftQ14[ff];
+        sss2Q14 = kCosTabFfftQ14[ee];
+
+        if (iSign==1) {
+          sss2Q14 = -sss2Q14;
+        }
+
+        RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) -
+            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
+        ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) +
+            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);
+
+        kk += 20;
+      }
+      kk = kk - 236;
+      // Complexity: 12*(12+12) = 288 for 16x16 muls, but 12*(12+32) = 528 cycles for 16x32 muls
+    }
+    kk = kk - 19;
+    // Complexity: 4*288+6 for 16x16 muls, but 4*528+6 cycles for 16x32 muls
+  }
+  // Complexity: 3*4*288+6 = 3462 for 16x16 muls, but 3*4*528+6 = 6342 cycles for 16x32 muls
+
+
+  // last transform for factor of 4 */
+  for (kk=0; kk<240; kk=kk+4) {
+    k1 = kk + 1;
+    k2 = k1 + 1;
+    k3 = k2 + 1;
+
+    akpQx = RexQx[kk] + RexQx[k2];
+    akmQx = RexQx[kk] - RexQx[k2];
+    ajpQx = RexQx[k1] + RexQx[k3];
+    ajmQx = RexQx[k1] - RexQx[k3];
+    bkpQx = ImxQx[kk] + ImxQx[k2];
+    bkmQx = ImxQx[kk] - ImxQx[k2];
+    bjpQx = ImxQx[k1] + ImxQx[k3];
+    bjmQx = ImxQx[k1] - ImxQx[k3];
+    RexQx[kk] = akpQx + ajpQx;
+    ImxQx[kk] = bkpQx + bjpQx;
+    ajpQx = akpQx - ajpQx;
+    bjpQx = bkpQx - bjpQx;
+    if (iSign < 0) {
+      akpQx = akmQx + bjmQx;
+      bkpQx = bkmQx - ajmQx;
+      akmQx -= bjmQx;
+      bkmQx += ajmQx;
+    } else {
+      akpQx = akmQx - bjmQx;
+      bkpQx = bkmQx + ajmQx;
+      akmQx += bjmQx;
+      bkmQx -= ajmQx;
+    }
+    RexQx[k1] = akpQx;
+    RexQx[k2] = ajpQx;
+    RexQx[k3] = akmQx;
+    ImxQx[k1] = bkpQx;
+    ImxQx[k2] = bjpQx;
+    ImxQx[k3] = bkmQx;
+  }
+  // Complexity: 60*45 = 2700 for 16x16 muls, but 60*45 = 2700 cycles for 16x32 muls
+
+  /* permute the results to normal order */
+  for (ii=0; ii<240; ii++) {
+    ReDATAQx[ii]=RexQx[ii];
+    ImDATAQx[ii]=ImxQx[ii];
+  }
+  // Complexity: 240*2=480 cycles
+
+  for (ii=0; ii<240; ii++) {
+    RexQx[ii]=ReDATAQx[kSortTabFft[ii]];
+    ImxQx[ii]=ImDATAQx[kSortTabFft[ii]];
+  }
+  // Complexity: 240*2*2=960 cycles
+
+  // Total complexity:
+  //            16x16 16x32
+  // Complexity:   10    10
+  // Complexity:   99   171
+  // Complexity: 2972  3932
+  // Complexity: 2736  5776
+  // Complexity: 5472 10080
+  // Complexity: 3462  6342
+  // Complexity: 2700  2700
+  // Complexity:  480   480
+  // Complexity:  960   960
+  // =======================
+  //            18891 30451
+  //
+  // If this FFT is called 2 time each frame, i.e. 67 times per second, it will correspond to
+  // a C54 complexity of 67*18891/1000000 = 1.27 MIPS with 16x16-muls, and 67*30451/1000000 =
+  // = 2.04 MIPS with 16x32-muls. Note that this routine somtimes is called 6 times during the
+  // encoding of a frame, i.e. the max complexity would be 7/2*1.27 = 4.4 MIPS for the 16x16 mul case.
+
+
+  return 0;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/fft.h b/src/modules/audio_coding/codecs/isac/fix/source/fft.h
new file mode 100644
index 0000000..efa116e
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/fft.h
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*--------------------------------*-C-*---------------------------------*
+ * File:
+ * fft.h
+ * ---------------------------------------------------------------------*
+ * Re[]: real value array
+ * Im[]: imaginary value array
+ * nTotal: total number of complex values
+ * nPass: number of elements involved in this pass of transform
+ * nSpan: nspan/nPass = number of bytes to increment pointer
+ *  in Re[] and Im[]
+ * isign: exponent: +1 = forward  -1 = reverse
+ * scaling: normalizing constant by which the final result is *divided*
+ * scaling == -1, normalize by total dimension of the transform
+ * scaling <  -1, normalize by the square-root of the total dimension
+ *
+ * ----------------------------------------------------------------------
+ * See the comments in the code for correct usage!
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_
+
+
+#include "structs.h"
+
+
+WebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign);
+
+
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FFT_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h b/src/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h
new file mode 100644
index 0000000..d5d9efb
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_INTERNAL_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_INTERNAL_H_
+
+#include "typedefs.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Arguments:
+ *   io:  Input/output, in Q0.
+ *   len: Input, sample length.
+ *   coefficient: Input.
+ *   state: Input/output, filter state, in Q4.
+ */
+void WebRtcIsacfix_HighpassFilterFixDec32(int16_t *io,
+                                          int16_t len,
+                                          const int16_t *coefficient,
+                                          int32_t *state);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
+/* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_INTERNAL_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.c b/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.c
new file mode 100644
index 0000000..732611b
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.c
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * filterbank_tables.c
+ *
+ * This file contains variables that are used in
+ * filterbanks.c
+ *
+ */
+
+#include "filterbank_tables.h"
+
+/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
+ * In float, they are: {-1.94895953203325f, 0.94984516000000f,
+ * -0.05101826139794f, 0.05015484000000f};
+ */
+const int16_t WebRtcIsacfix_kHpStCoeffInQ30[8] = {
+  16189, -31932,  /* Q30 lo/hi pair */
+  17243, 15562,  /* Q30 lo/hi pair */
+  -17186, -26748,  /* Q35 lo/hi pair */
+  -27476, 26296  /* Q35 lo/hi pair */
+};
+
+/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
+ * In float, they are: {-1.99701049409000f, 0.99714204490000f,
+ * 0.01701049409000f, -0.01704204490000f};
+ */
+const int16_t WebRtcIsacfix_kHPStCoeffOut1Q30[8] = {
+  -1306, -32719,  /* Q30 lo/hi pair */
+  11486, 16337,  /* Q30 lo/hi pair */
+  26078, 8918,  /* Q35 lo/hi pair */
+  3956, -8935  /* Q35 lo/hi pair */
+};
+
+/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2};
+ * In float, they are: {-1.98645294509837f, 0.98672435560000f,
+ * 0.00645294509837f, -0.00662435560000f};
+ */
+const int16_t WebRtcIsacfix_kHPStCoeffOut2Q30[8] = {
+  -2953, -32546,  /* Q30 lo/hi pair */
+  32233, 16166,  /* Q30 lo/hi pair */
+  13217, 3383,  /* Q35 lo/hi pair */
+  -4597, -3473  /* Q35 lo/hi pair */
+};
+
+/* The upper channel all-pass filter factors */
+const int16_t WebRtcIsacfix_kUpperApFactorsQ15[2] = {
+  1137, 12537
+};
+
+/* The lower channel all-pass filter factors */
+const int16_t WebRtcIsacfix_kLowerApFactorsQ15[2] = {
+  5059, 24379
+};
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h b/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h
new file mode 100644
index 0000000..9a888e4
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * filterbank_tables.h
+ *
+ * Header file for variables that are defined in
+ * filterbank_tables.c.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_
+
+#include "typedefs.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/********************* Coefficient Tables ************************/
+
+/* HPstcoeff_in_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
+/* [Q30lo Q30hi Q30lo Q30hi Q35lo Q35hi Q35lo Q35hi] */
+extern const int16_t WebRtcIsacfix_kHpStCoeffInQ30[8];
+
+/* HPstcoeff_out_1_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
+/* [Q30lo Q30hi Q30lo Q30hi Q35lo Q35hi Q35lo Q35hi] */
+extern const int16_t WebRtcIsacfix_kHPStCoeffOut1Q30[8];
+
+/* HPstcoeff_out_2_Q14 = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
+/* [Q30lo Q30hi Q30lo Q30hi Q35lo Q35hi Q35lo Q35hi] */
+extern const int16_t WebRtcIsacfix_kHPStCoeffOut2Q30[8];
+
+/* The upper channel all-pass filter factors */
+extern const int16_t WebRtcIsacfix_kUpperApFactorsQ15[2];
+
+/* The lower channel all-pass filter factors */
+extern const int16_t WebRtcIsacfix_kLowerApFactorsQ15[2];
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/filterbanks.c b/src/modules/audio_coding/codecs/isac/fix/source/filterbanks.c
new file mode 100644
index 0000000..949e7cf
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/filterbanks.c
@@ -0,0 +1,354 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * filterbanks.c
+ *
+ * This file contains function 
+ * WebRtcIsacfix_SplitAndFilter, and WebRtcIsacfix_FilterAndCombine
+ * which implement filterbanks that produce decimated lowpass and
+ * highpass versions of a signal, and performs reconstruction.
+ *
+ */
+
+#include "codec.h"
+#include "filterbank_internal.h"
+#include "filterbank_tables.h"
+#include "settings.h"
+
+
+static void AllpassFilter2FixDec16(WebRtc_Word16 *InOut16, //Q0
+                                   const WebRtc_Word16 *APSectionFactors, //Q15
+                                   WebRtc_Word16 lengthInOut,
+                                   WebRtc_Word16 NumberOfSections,
+                                   WebRtc_Word32 *FilterState) //Q16
+{
+  int n, j;
+  WebRtc_Word32 a, b;
+
+  for (j=0; j<NumberOfSections; j++) {
+    for (n=0;n<lengthInOut;n++) {
+
+
+      a = WEBRTC_SPL_MUL_16_16(APSectionFactors[j], InOut16[n]); //Q15*Q0=Q15
+      a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
+      b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16
+      a = WEBRTC_SPL_MUL_16_16_RSFT(-APSectionFactors[j], (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16), 0); //Q15*Q0=Q15
+      FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(WEBRTC_SPL_LSHIFT_W32(a,1), WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n],16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
+      InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
+
+    }
+  }
+
+}
+
+
+void WebRtcIsacfix_HighpassFilterFixDec32(int16_t *io,
+                                          int16_t len,
+                                          const int16_t *coefficient,
+                                          int32_t *state)
+{
+  int k;
+  WebRtc_Word32 a1 = 0, b1 = 0, c = 0, in = 0;
+  WebRtc_Word32 a2 = 0, b2 = 0;
+  WebRtc_Word32 state0 = state[0];
+  WebRtc_Word32 state1 = state[1];
+
+  for (k=0; k<len; k++) {
+    in = (WebRtc_Word32)io[k];
+
+#ifdef WEBRTC_ARCH_ARM_V7
+    {
+      int tmp_coeff0 = 0;
+      int tmp_coeff1 = 0;
+      __asm __volatile(
+        "ldr %[tmp_coeff0], [%[coeff]]\n\t"
+        "ldr %[tmp_coeff1], [%[coeff], #4]\n\t"
+        "smmulr %[a2], %[tmp_coeff0], %[state0]\n\t"
+        "smmulr %[b2], %[tmp_coeff1], %[state1]\n\t"
+        "ldr %[tmp_coeff0], [%[coeff], #8]\n\t"
+        "ldr %[tmp_coeff1], [%[coeff], #12]\n\t"
+        "smmulr %[a1], %[tmp_coeff0], %[state0]\n\t"
+        "smmulr %[b1], %[tmp_coeff1], %[state1]\n\t"
+        :[a2]"+r"(a2),
+         [b2]"+r"(b2),
+         [a1]"+r"(a1),
+         [b1]"+r"(b1),
+         [tmp_coeff0]"+r"(tmp_coeff0),
+         [tmp_coeff1]"+r"(tmp_coeff1)
+        :[coeff]"r"(coefficient),
+         [state0]"r"(state0),
+         [state1]"r"(state1)
+      );
+    }
+#else
+    /* Q35 * Q4 = Q39 ; shift 32 bit => Q7 */
+    a1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[5], coefficient[4], state0);
+    b1 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[7], coefficient[6], state1);
+
+    /* Q30 * Q4 = Q34 ; shift 32 bit => Q2 */
+    a2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[1], coefficient[0], state0);
+    b2 = WEBRTC_SPL_MUL_32_32_RSFT32(coefficient[3], coefficient[2], state1);
+#endif
+
+    c = ((WebRtc_Word32)in) + WEBRTC_SPL_RSHIFT_W32(a1+b1, 7);  // Q0
+    io[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(c);  // Write output as Q0.
+
+    c = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)in, 2) - a2 - b2;  // In Q2.
+    c = (WebRtc_Word32)WEBRTC_SPL_SAT(536870911, c, -536870912);
+
+    state1 = state0;
+    state0 = WEBRTC_SPL_LSHIFT_W32(c, 2); // Write state as Q4
+  }
+  state[0] = state0;
+  state[1] = state1;
+}
+
+
+void WebRtcIsacfix_SplitAndFilter1(WebRtc_Word16 *pin,
+                                   WebRtc_Word16 *LP16,
+                                   WebRtc_Word16 *HP16,
+                                   PreFiltBankstr *prefiltdata)
+{
+  /* Function WebRtcIsacfix_SplitAndFilter */
+  /* This function creates low-pass and high-pass decimated versions of part of
+     the input signal, and part of the signal in the input 'lookahead buffer'. */
+
+  int k;
+
+  WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2 + QLOOKAHEAD];
+  WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2 + QLOOKAHEAD];
+  WebRtc_Word32 tmpState[WEBRTC_SPL_MUL_16_16(2,(QORDER-1))]; /* 4 */
+
+
+  /* High pass filter */
+  WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
+
+
+  /* First Channel */
+  for (k=0;k<FRAMESAMPLES/2;k++) {
+    tempin_ch1[QLOOKAHEAD + k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
+  }
+  for (k=0;k<QLOOKAHEAD;k++) {
+    tempin_ch1[k]=prefiltdata->INLABUF1_fix[k];
+    prefiltdata->INLABUF1_fix[k]=pin[FRAMESAMPLES+1-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
+  }
+
+  /* Second Channel.  This is exactly like the first channel, except that the
+     even samples are now filtered instead (lower channel). */
+  for (k=0;k<FRAMESAMPLES/2;k++) {
+    tempin_ch2[QLOOKAHEAD+k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
+  }
+  for (k=0;k<QLOOKAHEAD;k++) {
+    tempin_ch2[k]=prefiltdata->INLABUF2_fix[k];
+    prefiltdata->INLABUF2_fix[k]=pin[FRAMESAMPLES-WEBRTC_SPL_MUL_16_16(2, QLOOKAHEAD)+WEBRTC_SPL_MUL_16_16(2, k)];
+  }
+
+
+  /*obtain polyphase components by forward all-pass filtering through each channel */
+  /* The all pass filtering automatically updates the filter states which are exported in the
+     prefiltdata structure */
+  AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix);
+  AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix);
+
+  for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++)
+    tmpState[k] = prefiltdata->INSTAT1_fix[k];
+  AllpassFilter2FixDec16(tempin_ch1 + FRAMESAMPLES/2,WebRtcIsacfix_kUpperApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState);
+  for (k=0;k<WEBRTC_SPL_MUL_16_16(2, (QORDER-1));k++)
+    tmpState[k] = prefiltdata->INSTAT2_fix[k];
+  AllpassFilter2FixDec16(tempin_ch2 + FRAMESAMPLES/2,WebRtcIsacfix_kLowerApFactorsQ15, QLOOKAHEAD , NUMBEROFCHANNELAPSECTIONS, tmpState);
+
+
+  /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
+  for (k=0; k<FRAMESAMPLES/2 + QLOOKAHEAD; k++) {
+    WebRtc_Word32 tmp1, tmp2, tmp3;
+    tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0
+    tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0
+    tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
+    LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
+    tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
+    HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
+  }
+
+}/*end of WebRtcIsacfix_SplitAndFilter */
+
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+
+/* Without lookahead */
+void WebRtcIsacfix_SplitAndFilter2(WebRtc_Word16 *pin,
+                                   WebRtc_Word16 *LP16,
+                                   WebRtc_Word16 *HP16,
+                                   PreFiltBankstr *prefiltdata)
+{
+  /* Function WebRtcIsacfix_SplitAndFilter2 */
+  /* This function creates low-pass and high-pass decimated versions of part of
+     the input signal. */
+
+  int k;
+
+  WebRtc_Word16 tempin_ch1[FRAMESAMPLES/2];
+  WebRtc_Word16 tempin_ch2[FRAMESAMPLES/2];
+
+
+  /* High pass filter */
+  WebRtcIsacfix_HighpassFilterFixDec32(pin, FRAMESAMPLES, WebRtcIsacfix_kHpStCoeffInQ30, prefiltdata->HPstates_fix);
+
+
+  /* First Channel */
+  for (k=0;k<FRAMESAMPLES/2;k++) {
+    tempin_ch1[k] = pin[1+WEBRTC_SPL_MUL_16_16(2, k)];
+  }
+
+  /* Second Channel.  This is exactly like the first channel, except that the
+     even samples are now filtered instead (lower channel). */
+  for (k=0;k<FRAMESAMPLES/2;k++) {
+    tempin_ch2[k] = pin[WEBRTC_SPL_MUL_16_16(2, k)];
+  }
+
+
+  /*obtain polyphase components by forward all-pass filtering through each channel */
+  /* The all pass filtering automatically updates the filter states which are exported in the
+     prefiltdata structure */
+  AllpassFilter2FixDec16(tempin_ch1,WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT1_fix);
+  AllpassFilter2FixDec16(tempin_ch2,WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2 , NUMBEROFCHANNELAPSECTIONS, prefiltdata->INSTAT2_fix);
+
+
+  /* Now Construct low-pass and high-pass signals as combinations of polyphase components */
+  for (k=0; k<FRAMESAMPLES/2; k++) {
+    WebRtc_Word32 tmp1, tmp2, tmp3;
+    tmp1 = (WebRtc_Word32)tempin_ch1[k]; // Q0 -> Q0
+    tmp2 = (WebRtc_Word32)tempin_ch2[k]; // Q0 -> Q0
+    tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 + tmp2), 1);/* low pass signal*/
+    LP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*low pass */
+    tmp3 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W32((tmp1 - tmp2), 1);/* high pass signal*/
+    HP16[k] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp3); /*high pass */
+  }
+
+}/*end of WebRtcIsacfix_SplitAndFilter */
+
+#endif
+
+
+
+//////////////////////////////////////////////////////////
+////////// Combining
+/* Function WebRtcIsacfix_FilterAndCombine */
+/* This is a decoder function that takes the decimated
+   length FRAMESAMPLES/2 input low-pass and
+   high-pass signals and creates a reconstructed fullband
+   output signal of length FRAMESAMPLES. WebRtcIsacfix_FilterAndCombine
+   is the sibling function of WebRtcIsacfix_SplitAndFilter */
+/* INPUTS:
+   inLP: a length FRAMESAMPLES/2 array of input low-pass
+   samples.
+   inHP: a length FRAMESAMPLES/2 array of input high-pass
+   samples.
+   postfiltdata: input data structure containing the filterbank
+   states from the previous decoding iteration.
+   OUTPUTS:
+   Out: a length FRAMESAMPLES array of output reconstructed
+   samples (fullband) based on the input low-pass and
+   high-pass signals.
+   postfiltdata: the input data structure containing the filterbank
+   states is updated for the next decoding iteration */
+void WebRtcIsacfix_FilterAndCombine1(WebRtc_Word16 *tempin_ch1,
+                                     WebRtc_Word16 *tempin_ch2,
+                                     WebRtc_Word16 *out16,
+                                     PostFiltBankstr *postfiltdata)
+{
+  int k;
+  WebRtc_Word16 in[FRAMESAMPLES];
+
+  /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
+     that were used as a lower channel at the encoding side.  So at the decoder, the
+     corresponding all-pass filter factors for each channel are swapped.*/
+
+  AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix);
+
+  /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
+     at the decoder are swapped from the ones at the encoder, the 'upper' channel
+     all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */
+
+  AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, FRAMESAMPLES/2, NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix);
+
+  /* Merge outputs to form the full length output signal.*/
+  for (k=0;k<FRAMESAMPLES/2;k++) {
+    in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
+    in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
+  }
+
+  /* High pass filter */
+  WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
+  WebRtcIsacfix_HighpassFilterFixDec32(in, FRAMESAMPLES, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
+
+  for (k=0;k<FRAMESAMPLES;k++) {
+    out16[k] = in[k];
+  }
+}
+
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+/* Function WebRtcIsacfix_FilterAndCombine */
+/* This is a decoder function that takes the decimated
+   length len/2 input low-pass and
+   high-pass signals and creates a reconstructed fullband
+   output signal of length len. WebRtcIsacfix_FilterAndCombine
+   is the sibling function of WebRtcIsacfix_SplitAndFilter */
+/* INPUTS:
+   inLP: a length len/2 array of input low-pass
+   samples.
+   inHP: a length len/2 array of input high-pass
+   samples.
+   postfiltdata: input data structure containing the filterbank
+   states from the previous decoding iteration.
+   OUTPUTS:
+   Out: a length len array of output reconstructed
+   samples (fullband) based on the input low-pass and
+   high-pass signals.
+   postfiltdata: the input data structure containing the filterbank
+   states is updated for the next decoding iteration */
+void WebRtcIsacfix_FilterAndCombine2(WebRtc_Word16 *tempin_ch1,
+                                     WebRtc_Word16 *tempin_ch2,
+                                     WebRtc_Word16 *out16,
+                                     PostFiltBankstr *postfiltdata,
+                                     WebRtc_Word16 len)
+{
+  int k;
+  WebRtc_Word16 in[FRAMESAMPLES];
+
+  /* all-pass filter the new upper channel signal. HOWEVER, use the all-pass filter factors
+     that were used as a lower channel at the encoding side.  So at the decoder, the
+     corresponding all-pass filter factors for each channel are swapped.*/
+
+  AllpassFilter2FixDec16(tempin_ch1, WebRtcIsacfix_kLowerApFactorsQ15,(WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_UPPER_fix);
+
+  /* Now, all-pass filter the new lower channel signal. But since all-pass filter factors
+     at the decoder are swapped from the ones at the encoder, the 'upper' channel
+     all-pass filter factors (kUpperApFactors) are used to filter this new lower channel signal */
+
+  AllpassFilter2FixDec16(tempin_ch2, WebRtcIsacfix_kUpperApFactorsQ15, (WebRtc_Word16) (len/2), NUMBEROFCHANNELAPSECTIONS,postfiltdata->STATE_0_LOWER_fix);
+
+  /* Merge outputs to form the full length output signal.*/
+  for (k=0;k<len/2;k++) {
+    in[WEBRTC_SPL_MUL_16_16(2, k)]=tempin_ch2[k];
+    in[WEBRTC_SPL_MUL_16_16(2, k)+1]=tempin_ch1[k];
+  }
+
+  /* High pass filter */
+  WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut1Q30, postfiltdata->HPstates1_fix);
+  WebRtcIsacfix_HighpassFilterFixDec32(in, len, WebRtcIsacfix_kHPStCoeffOut2Q30, postfiltdata->HPstates2_fix);
+
+  for (k=0;k<len;k++) {
+    out16[k] = in[k];
+  }
+}
+
+#endif
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/filters.c b/src/modules/audio_coding/codecs/isac/fix/source/filters.c
new file mode 100644
index 0000000..6ee0477
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/filters.c
@@ -0,0 +1,122 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * filters.c
+ *
+ * This file contains function WebRtcIsacfix_AutocorrC,
+ * AllpassFilterForDec32, and WebRtcIsacfix_DecimateAllpass32
+ *
+ */
+
+#include <string.h>
+
+#include "pitch_estimator.h"
+#include "lpc_masking_model.h"
+#include "codec.h"
+
+// Autocorrelation function in fixed point.
+// NOTE! Different from SPLIB-version in how it scales the signal.
+int WebRtcIsacfix_AutocorrC(WebRtc_Word32* __restrict r,
+                            const WebRtc_Word16* __restrict x,
+                            WebRtc_Word16 N,
+                            WebRtc_Word16 order,
+                            WebRtc_Word16* __restrict scale) {
+  int i = 0;
+  int j = 0;
+  int16_t scaling = 0;
+  int32_t sum = 0;
+  uint32_t temp = 0;
+  int64_t prod = 0;
+
+  // Calculate r[0].
+  for (i = 0; i < N; i++) {
+    prod += WEBRTC_SPL_MUL_16_16(x[i], x[i]);
+  }
+
+  // Calculate scaling (the value of shifting).
+  temp = (uint32_t)(prod >> 31);
+  if(temp == 0) {
+    scaling = 0;
+  } else {
+    scaling = 32 - WebRtcSpl_NormU32(temp);
+  }
+  r[0] = (int32_t)(prod >> scaling);
+
+  // Perform the actual correlation calculation.
+  for (i = 1; i < order + 1; i++) {
+    prod = 0;
+    for (j = 0; j < N - i; j++) {
+      prod += WEBRTC_SPL_MUL_16_16(x[j], x[i + j]);
+    }
+    sum = (int32_t)(prod >> scaling);
+    r[i] = sum;
+  }
+
+  *scale = scaling;
+
+  return(order + 1);
+}
+
+static const WebRtc_Word32 kApUpperQ15[ALLPASSSECTIONS] = { 1137, 12537 };
+static const WebRtc_Word32 kApLowerQ15[ALLPASSSECTIONS] = { 5059, 24379 };
+
+
+static void AllpassFilterForDec32(WebRtc_Word16         *InOut16, //Q0
+                                  const WebRtc_Word32   *APSectionFactors, //Q15
+                                  WebRtc_Word16         lengthInOut,
+                                  WebRtc_Word32          *FilterState) //Q16
+{
+  int n, j;
+  WebRtc_Word32 a, b;
+
+  for (j=0; j<ALLPASSSECTIONS; j++) {
+    for (n=0;n<lengthInOut;n+=2){
+      a = WEBRTC_SPL_MUL_16_32_RSFT16(InOut16[n], APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
+      a = WEBRTC_SPL_LSHIFT_W32(a, 1); // Q15 -> Q16
+      b = WEBRTC_SPL_ADD_SAT_W32(a, FilterState[j]); //Q16+Q16=Q16
+      a = WEBRTC_SPL_MUL_16_32_RSFT16(
+          (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16),
+          -APSectionFactors[j]); //Q0*Q31=Q31 shifted 16 gives Q15
+      FilterState[j] = WEBRTC_SPL_ADD_SAT_W32(
+          WEBRTC_SPL_LSHIFT_W32(a,1),
+          WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)InOut16[n], 16)); // Q15<<1 + Q0<<16 = Q16 + Q16 = Q16
+      InOut16[n] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(b, 16); //Save as Q0
+    }
+  }
+}
+
+
+
+
+void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in,
+                                     WebRtc_Word32 *state_in,        /* array of size: 2*ALLPASSSECTIONS+1 */
+                                     WebRtc_Word16 N,                /* number of input samples */
+                                     WebRtc_Word16 *out)             /* array of size N/2 */
+{
+  int n;
+  WebRtc_Word16 data_vec[PITCH_FRAME_LEN];
+
+  /* copy input */
+  memcpy(data_vec+1, in, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (N-1)));
+
+
+  data_vec[0] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)],16);   //the z^(-1) state
+  state_in[WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)] = WEBRTC_SPL_LSHIFT_W32((WebRtc_UWord32)in[N-1],16);
+
+
+
+  AllpassFilterForDec32(data_vec+1, kApUpperQ15, N, state_in);
+  AllpassFilterForDec32(data_vec, kApLowerQ15, N, state_in+ALLPASSSECTIONS);
+
+  for (n=0;n<N/2;n++) {
+    out[n]=WEBRTC_SPL_ADD_SAT_W16(data_vec[WEBRTC_SPL_MUL_16_16(2, n)], data_vec[WEBRTC_SPL_MUL_16_16(2, n)+1]);
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/filters_neon.c b/src/modules/audio_coding/codecs/isac/fix/source/filters_neon.c
new file mode 100644
index 0000000..93143fe
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/filters_neon.c
@@ -0,0 +1,167 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * filters_neon.c
+ *
+ * This file contains function WebRtcIsacfix_AutocorrNeon, optimized for
+ * ARM Neon platform.
+ *
+ */
+
+#include <arm_neon.h>
+#include <assert.h>
+
+#include "codec.h"
+
+// Autocorrelation function in fixed point.
+// NOTE! Different from SPLIB-version in how it scales the signal.
+int WebRtcIsacfix_AutocorrNeon(
+    WebRtc_Word32* __restrict r,
+    const WebRtc_Word16* __restrict x,
+    WebRtc_Word16 N,
+    WebRtc_Word16 order,
+    WebRtc_Word16* __restrict scale) {
+
+  // The 1st for loop assumed N % 4 == 0.
+  assert(N % 4 == 0);
+
+  int i = 0;
+  int zeros_low = 0;
+  int zeros_high = 0;
+  int16_t scaling = 0;
+  int32_t sum = 0;
+
+  // Step 1, calculate r[0] and how much scaling is needed.
+
+  int16x4_t reg16x4;
+  int64x1_t reg64x1a;
+  int64x1_t reg64x1b;
+  int32x4_t reg32x4;
+  int64x2_t reg64x2 = vdupq_n_s64(0); // zeros
+
+  // Loop over the samples and do:
+  // sum += WEBRTC_SPL_MUL_16_16(x[i], x[i]);
+  for (i = 0; i < N; i += 4) {
+    reg16x4 = vld1_s16(&x[i]);
+    reg32x4 = vmull_s16(reg16x4, reg16x4);
+    reg64x2 = vpadalq_s32(reg64x2, reg32x4);
+  }
+  reg64x1a = vget_low_s64(reg64x2);
+  reg64x1b = vget_high_s64(reg64x2);
+  reg64x1a = vadd_s64(reg64x1a, reg64x1b);
+
+  // Calculate the value of shifting (scaling).
+  __asm__ __volatile__(
+    "vmov %[z_l], %[z_h], %P[reg]\n\t"
+    "clz %[z_l], %[z_l]\n\t"
+    "clz %[z_h], %[z_h]\n\t"
+    :[z_l]"+r"(zeros_low),
+     [z_h]"+r"(zeros_high)
+    :[reg]"w"(reg64x1a)
+  );
+  if (zeros_high != 32) {
+    scaling = (32 - zeros_high + 1);
+  } else if (zeros_low == 0) {
+    scaling = 1;
+  }
+  reg64x1b = -scaling;
+  reg64x1a = vshl_s64(reg64x1a, reg64x1b);
+
+  // Record the result.
+  r[0] = (int32_t)vget_lane_s64(reg64x1a, 0);
+
+
+  // Step 2, perform the actual correlation calculation.
+
+  /* Original C code (for the rest of the function):
+  for (i = 1; i < order + 1; i++)  {
+    prod = 0;
+    for (j = 0; j < N - i; j++) {
+      prod += WEBRTC_SPL_MUL_16_16(x[j], x[i + j]);
+    }
+    sum = (int32_t)(prod >> scaling);
+    r[i] = sum;
+  }
+  */
+
+  for (i = 1; i < order + 1; i++) {
+    int32_t prod_lower = 0;
+    int32_t prod_upper = 0;
+    const int16_t* ptr0 = &x[0];
+    const int16_t* ptr1 = &x[i];
+    int32_t tmp = 0;
+
+    // Initialize the sum (q9) to zero.
+    __asm__ __volatile__("vmov.i32 q9, #0\n\t":::"q9");
+
+    // Calculate the major block of the samples (a multiple of 8).
+    for (; ptr0 < &x[N - i - 7];) {
+      __asm__ __volatile__(
+        "vld1.16 {d20, d21}, [%[ptr0]]!\n\t"
+        "vld1.16 {d22, d23}, [%[ptr1]]!\n\t"
+        "vmull.s16 q12, d20, d22\n\t"
+        "vmull.s16 q13, d21, d23\n\t"
+        "vpadal.s32 q9, q12\n\t"
+        "vpadal.s32 q9, q13\n\t"
+
+        // Specify constraints.
+        :[ptr0]"+r"(ptr0),
+        [ptr1]"+r"(ptr1)
+        :
+        :"d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27"
+      );
+    }
+
+    // Calculate the rest of the samples.
+    for (; ptr0 < &x[N - i]; ptr0++, ptr1++) {
+      __asm__ __volatile__(
+        "smulbb %[tmp], %[ptr0], %[ptr1]\n\t"
+        "adds %[prod_lower], %[prod_lower], %[tmp]\n\t"
+        "adc %[prod_upper], %[prod_upper], %[tmp], asr #31\n\t"
+
+        // Specify constraints.
+        :[prod_lower]"+r"(prod_lower),
+        [prod_upper]"+r"(prod_upper),
+        [tmp]"+r"(tmp)
+        :[ptr0]"r"(*ptr0),
+        [ptr1]"r"(*ptr1)
+      );
+    }
+
+    // Sum the results up, and do shift.
+    __asm__ __volatile__(
+      "vadd.i64 d18, d19\n\t"
+      "vmov.32 d17[0], %[prod_lower]\n\t"
+      "vmov.32 d17[1], %[prod_upper]\n\t"
+      "vadd.i64 d17, d18\n\t"
+      "mov %[tmp], %[scaling], asr #31\n\t"
+      "vmov.32 d16, %[scaling], %[tmp]\n\t"
+      "vshl.s64 d17, d16\n\t"
+      "vmov.32 %[sum], d17[0]\n\t"
+
+      // Specify constraints.
+      :[sum]"=r"(sum),
+      [tmp]"+r"(tmp)
+      :[prod_upper]"r"(prod_upper),
+      [prod_lower]"r"(prod_lower),
+      [scaling]"r"(-scaling)
+      :"d16", "d17", "d18", "d19"
+    );
+
+    // Record the result.
+    r[i] = sum;
+  }
+
+  // Record the result.
+  *scale = scaling;
+
+  return(order + 1);
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/initialize.c b/src/modules/audio_coding/codecs/isac/fix/source/initialize.c
new file mode 100644
index 0000000..4d11af5
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/initialize.c
@@ -0,0 +1,175 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * initialize.c
+ *
+ * Internal initfunctions
+ *
+ */
+
+#include "codec.h"
+#include "structs.h"
+#include "pitch_estimator.h"
+
+
+void WebRtcIsacfix_InitMaskingEnc(MaskFiltstr_enc *maskdata) {
+
+  int k;
+
+  for (k = 0; k < WINLEN; k++) {
+    maskdata->DataBufferLoQ0[k] = (WebRtc_Word16) 0;
+    maskdata->DataBufferHiQ0[k] = (WebRtc_Word16) 0;
+  }
+  for (k = 0; k < ORDERLO+1; k++) {
+    maskdata->CorrBufLoQQ[k] = (WebRtc_Word32) 0;
+    maskdata->CorrBufLoQdom[k] = 0;
+
+    maskdata->PreStateLoGQ15[k] = 0;
+
+  }
+  for (k = 0; k < ORDERHI+1; k++) {
+    maskdata->CorrBufHiQQ[k] = (WebRtc_Word32) 0;
+    maskdata->CorrBufHiQdom[k] = 0;
+    maskdata->PreStateHiGQ15[k] = 0;
+  }
+
+  maskdata->OldEnergy = 10;
+
+  return;
+}
+
+void WebRtcIsacfix_InitMaskingDec(MaskFiltstr_dec *maskdata) {
+
+  int k;
+
+  for (k = 0; k < ORDERLO+1; k++)
+  {
+    maskdata->PostStateLoGQ0[k] = 0;
+  }
+  for (k = 0; k < ORDERHI+1; k++)
+  {
+    maskdata->PostStateHiGQ0[k] = 0;
+  }
+
+  maskdata->OldEnergy = 10;
+
+  return;
+}
+
+
+
+
+
+
+
+void WebRtcIsacfix_InitPreFilterbank(PreFiltBankstr *prefiltdata)
+{
+  int k;
+
+  for (k = 0; k < QLOOKAHEAD; k++) {
+    prefiltdata->INLABUF1_fix[k] = 0;
+    prefiltdata->INLABUF2_fix[k] = 0;
+  }
+  for (k = 0; k < WEBRTC_SPL_MUL_16_16(2,(QORDER-1)); k++) {
+
+    prefiltdata->INSTAT1_fix[k] = 0;
+    prefiltdata->INSTAT2_fix[k] = 0;
+  }
+
+  /* High pass filter states */
+  prefiltdata->HPstates_fix[0] = 0;
+  prefiltdata->HPstates_fix[1] = 0;
+
+  return;
+}
+
+void WebRtcIsacfix_InitPostFilterbank(PostFiltBankstr *postfiltdata)
+{
+  int k;
+
+  for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, POSTQORDER); k++) {
+
+    postfiltdata->STATE_0_LOWER_fix[k] = 0;
+    postfiltdata->STATE_0_UPPER_fix[k] = 0;
+  }
+
+  /* High pass filter states */
+
+  postfiltdata->HPstates1_fix[0] = 0;
+  postfiltdata->HPstates1_fix[1] = 0;
+
+  postfiltdata->HPstates2_fix[0] = 0;
+  postfiltdata->HPstates2_fix[1] = 0;
+
+  return;
+}
+
+
+void WebRtcIsacfix_InitPitchFilter(PitchFiltstr *pitchfiltdata)
+{
+  int k;
+
+  for (k = 0; k < PITCH_BUFFSIZE; k++)
+    pitchfiltdata->ubufQQ[k] = 0;
+  for (k = 0; k < (PITCH_DAMPORDER); k++)
+    pitchfiltdata->ystateQQ[k] = 0;
+
+  pitchfiltdata->oldlagQ7 = 6400; /* 50.0 in Q7 */
+  pitchfiltdata->oldgainQ12 = 0;
+}
+
+void WebRtcIsacfix_InitPitchAnalysis(PitchAnalysisStruct *State)
+{
+  int k;
+
+  for (k = 0; k < PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2; k++) {
+    State->dec_buffer16[k] = 0;
+  }
+  for (k = 0; k < WEBRTC_SPL_MUL_16_16(2, ALLPASSSECTIONS)+1; k++) {
+    State->decimator_state32[k] = 0;
+  }
+
+  for (k = 0; k < QLOOKAHEAD; k++)
+    State->inbuf[k] = 0;
+
+  WebRtcIsacfix_InitPitchFilter(&(State->PFstr_wght));
+
+  WebRtcIsacfix_InitPitchFilter(&(State->PFstr));
+}
+
+
+void WebRtcIsacfix_InitPlc( PLCstr *State )
+{
+  State->decayCoeffPriodic = WEBRTC_SPL_WORD16_MAX;
+  State->decayCoeffNoise = WEBRTC_SPL_WORD16_MAX;
+
+  State->used = PLC_WAS_USED;
+
+  WebRtcSpl_ZerosArrayW16(State->overlapLP, RECOVERY_OVERLAP);
+  WebRtcSpl_ZerosArrayW16(State->lofilt_coefQ15, ORDERLO);
+  WebRtcSpl_ZerosArrayW16(State->hifilt_coefQ15, ORDERHI );
+
+  State->AvgPitchGain_Q12 = 0;
+  State->lastPitchGain_Q12 = 0;
+  State->lastPitchLag_Q7 = 0;
+  State->gain_lo_hiQ17[0]=State->gain_lo_hiQ17[1] = 0;
+  WebRtcSpl_ZerosArrayW16(State->prevPitchInvIn, FRAMESAMPLES/2);
+  WebRtcSpl_ZerosArrayW16(State->prevPitchInvOut, PITCH_MAX_LAG + 10 );
+  WebRtcSpl_ZerosArrayW32(State->prevHP, PITCH_MAX_LAG + 10 );
+  State->pitchCycles = 0;
+  State->A = 0;
+  State->B = 0;
+  State->pitchIndex = 0;
+  State->stretchLag = 240;
+  State->seed = 4447;
+
+
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/src/modules/audio_coding/codecs/isac/fix/source/isacfix.c
new file mode 100644
index 0000000..8786b12
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/isacfix.c
@@ -0,0 +1,1551 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * isacfix.c
+ *
+ * This C file contains the functions for the ISAC API
+ *
+ */
+
+#include "modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
+
+#include <stdlib.h>
+
+#include "modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
+#include "modules/audio_coding/codecs/isac/fix/source/codec.h"
+#include "modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
+#include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
+#include "modules/audio_coding/codecs/isac/fix/source/structs.h"
+#include "system_wrappers/interface/cpu_features_wrapper.h"
+
+
+/**************************************************************************
+ * WebRtcIsacfix_AssignSize(...)
+ *
+ * Functions used when malloc is not allowed
+ * Returns number of bytes needed to allocate for iSAC struct.
+ *
+ */
+
+WebRtc_Word16 WebRtcIsacfix_AssignSize(int *sizeinbytes) {
+  *sizeinbytes=sizeof(ISACFIX_SubStruct)*2/sizeof(WebRtc_Word16);
+  return(0);
+}
+
+/***************************************************************************
+ * WebRtcIsacfix_Assign(...)
+ *
+ * Functions used when malloc is not allowed
+ * Place struct at given address
+ *
+ * If successful, Return 0, else Return -1
+ */
+
+WebRtc_Word16 WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst, void *ISACFIX_inst_Addr) {
+  if (ISACFIX_inst_Addr!=NULL) {
+    *inst = (ISACFIX_MainStruct*)ISACFIX_inst_Addr;
+    (*(ISACFIX_SubStruct**)inst)->errorcode = 0;
+    (*(ISACFIX_SubStruct**)inst)->initflag = 0;
+    (*(ISACFIX_SubStruct**)inst)->ISACenc_obj.SaveEnc_ptr = NULL;
+    return(0);
+  } else {
+    return(-1);
+  }
+}
+
+
+#ifndef ISACFIX_NO_DYNAMIC_MEM
+
+/****************************************************************************
+ * WebRtcIsacfix_Create(...)
+ *
+ * This function creates a ISAC instance, which will contain the state
+ * information for one coding/decoding channel.
+ *
+ * Input:
+ *      - *ISAC_main_inst   : a pointer to the coder instance.
+ *
+ * Return value             :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst)
+{
+  ISACFIX_SubStruct *tempo;
+  tempo = malloc(1 * sizeof(ISACFIX_SubStruct));
+  *ISAC_main_inst = (ISACFIX_MainStruct *)tempo;
+  if (*ISAC_main_inst!=NULL) {
+    (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0;
+    (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0;
+    (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL;
+    return(0);
+  } else {
+    return(-1);
+  }
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_CreateInternal(...)
+ *
+ * This function creates the memory that is used to store data in the encoder
+ *
+ * Input:
+ *      - *ISAC_main_inst   : a pointer to the coder instance.
+ *
+ * Return value             :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Allocate memory for storing encoder data */
+  ISAC_inst->ISACenc_obj.SaveEnc_ptr = malloc(1 * sizeof(ISAC_SaveEncData_t));
+
+  if (ISAC_inst->ISACenc_obj.SaveEnc_ptr!=NULL) {
+    return(0);
+  } else {
+    return(-1);
+  }
+}
+
+
+#endif
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_Free(...)
+ *
+ * This function frees the ISAC instance created at the beginning.
+ *
+ * Input:
+ *      - ISAC_main_inst    : a ISAC instance.
+ *
+ * Return value             :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  free(ISAC_main_inst);
+  return(0);
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_FreeInternal(...)
+ *
+ * This function frees the internal memory for storing encoder data.
+ *
+ * Input:
+ *       - ISAC_main_inst    : a ISAC instance.
+ *
+ * Return value              :  0 - Ok
+ *                             -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Release memory */
+  free(ISAC_inst->ISACenc_obj.SaveEnc_ptr);
+
+  return(0);
+}
+
+/****************************************************************************
+ * WebRtcAecm_InitNeon(...)
+ *
+ * This function initializes function pointers for ARM Neon platform.
+ */
+
+#if (defined WEBRTC_DETECT_ARM_NEON || defined WEBRTC_ARCH_ARM_NEON)
+static void WebRtcIsacfix_InitNeon(void) {
+  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon;
+  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon;
+  WebRtcIsacfix_CalculateResidualEnergy =
+      WebRtcIsacfix_CalculateResidualEnergyNeon;
+}
+#endif
+
+/****************************************************************************
+ * WebRtcIsacfix_EncoderInit(...)
+ *
+ * This function initializes a ISAC instance prior to the encoder calls.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - CodingMode        : 0 -> Bit rate and frame length are automatically
+ *                                 adjusted to available bandwidth on
+ *                                 transmission channel.
+ *                            1 -> User sets a frame length and a target bit
+ *                                 rate which is taken as the maximum short-term
+ *                                 average bit rate.
+ *
+ * Return value             :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
+                                        WebRtc_Word16  CodingMode)
+{
+  int k;
+  WebRtc_Word16 statusInit;
+  ISACFIX_SubStruct *ISAC_inst;
+
+  statusInit = 0;
+  /* typecast pointer to rela structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* flag encoder init */
+  ISAC_inst->initflag |= 2;
+
+  if (CodingMode == 0)
+    /* Adaptive mode */
+    ISAC_inst->ISACenc_obj.new_framelength  = INITIAL_FRAMESAMPLES;
+  else if (CodingMode == 1)
+    /* Instantaneous mode */
+    ISAC_inst->ISACenc_obj.new_framelength = 480;    /* default for I-mode */
+  else {
+    ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE;
+    statusInit = -1;
+  }
+
+  ISAC_inst->CodingMode = CodingMode;
+
+  WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj);
+  WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj);
+  WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj);
+  WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj);
+
+
+  WebRtcIsacfix_InitBandwidthEstimator(&ISAC_inst->bwestimator_obj);
+  WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj);
+
+
+  ISAC_inst->ISACenc_obj.buffer_index   = 0;
+  ISAC_inst->ISACenc_obj.frame_nb    = 0;
+  ISAC_inst->ISACenc_obj.BottleNeck      = 32000; /* default for I-mode */
+  ISAC_inst->ISACenc_obj.MaxDelay    = 10;    /* default for I-mode */
+  ISAC_inst->ISACenc_obj.current_framesamples = 0;
+  ISAC_inst->ISACenc_obj.s2nr     = 0;
+  ISAC_inst->ISACenc_obj.MaxBits    = 0;
+  ISAC_inst->ISACenc_obj.bitstr_seed   = 4447;
+  ISAC_inst->ISACenc_obj.payloadLimitBytes30  = STREAM_MAXW16_30MS << 1;
+  ISAC_inst->ISACenc_obj.payloadLimitBytes60  = STREAM_MAXW16_60MS << 1;
+  ISAC_inst->ISACenc_obj.maxPayloadBytes      = STREAM_MAXW16_60MS << 1;
+  ISAC_inst->ISACenc_obj.maxRateInBytes       = STREAM_MAXW16_30MS << 1;
+  ISAC_inst->ISACenc_obj.enforceFrameSize     = 0;
+
+  /* Init the bistream data area to zero */
+  for (k=0; k<STREAM_MAXW16_60MS; k++){
+    ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0;
+  }
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj);
+#endif
+
+  // Initiaze function pointers.
+  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
+  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
+  WebRtcIsacfix_CalculateResidualEnergy =
+      WebRtcIsacfix_CalculateResidualEnergyC;
+
+#ifdef WEBRTC_DETECT_ARM_NEON
+  if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
+    WebRtcIsacfix_InitNeon();
+  }
+#elif defined(WEBRTC_ARCH_ARM_NEON)
+  WebRtcIsacfix_InitNeon();
+#endif
+
+  return statusInit;
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_Encode(...)
+ *
+ * This function encodes 10ms frame(s) and inserts it into a package.
+ * Input speech length has to be 160 samples (10ms). The encoder buffers those
+ * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
+ * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - speechIn          : input speech vector.
+ *
+ * Output:
+ *      - encoded           : the encoded data vector
+ *
+ * Return value:
+ *                          : >0 - Length (in bytes) of coded data
+ *                          :  0 - The buffer didn't reach the chosen framesize
+ *                            so it keeps buffering speech samples.
+ *                          : -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
+                                   const WebRtc_Word16    *speechIn,
+                                   WebRtc_Word16          *encoded)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  WebRtc_Word16 stream_len;
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+
+  /* typecast pointer to rela structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+
+  /* check if encoder initiated */
+  if ((ISAC_inst->initflag & 2) != 2) {
+    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  stream_len = WebRtcIsacfix_EncodeImpl((WebRtc_Word16*)speechIn,
+                                    &ISAC_inst->ISACenc_obj,
+                                    &ISAC_inst->bwestimator_obj,
+                                    ISAC_inst->CodingMode);
+  if (stream_len<0) {
+    ISAC_inst->errorcode = - stream_len;
+    return -1;
+  }
+
+
+  /* convert from bytes to WebRtc_Word16 */
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0;k<(stream_len+1)>>1;k++) {
+    encoded[k] = (WebRtc_Word16)( ( (WebRtc_UWord16)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8 )
+                                  | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
+  }
+
+#else
+  WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
+#endif
+
+
+
+  return stream_len;
+
+}
+
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_EncodeNb(...)
+ *
+ * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
+ * it into a package. Input speech length has to be 80 samples (10ms). The encoder
+ * interpolates into wide-band (16 kHz sampling) buffers those
+ * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
+ * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
+ *
+ * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - speechIn          : input speech vector.
+ *
+ * Output:
+ *      - encoded           : the encoded data vector
+ *
+ * Return value:
+ *                          : >0 - Length (in bytes) of coded data
+ *                          :  0 - The buffer didn't reach the chosen framesize
+ *                            so it keeps buffering speech samples.
+ *                          : -1 - Error
+ */
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+WebRtc_Word16 WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
+                                      const WebRtc_Word16    *speechIn,
+                                      WebRtc_Word16          *encoded)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  WebRtc_Word16 stream_len;
+  WebRtc_Word16 speechInWB[FRAMESAMPLES_10ms];
+  WebRtc_Word16 Vector_Word16_1[FRAMESAMPLES_10ms/2];
+  WebRtc_Word16 Vector_Word16_2[FRAMESAMPLES_10ms/2];
+
+  int k;
+
+
+  /* typecast pointer to rela structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+
+  /* check if encoder initiated */
+  if ((ISAC_inst->initflag & 2) != 2) {
+    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
+    return (-1);
+  }
+
+
+  /* Oversample to WB */
+
+  /* Form polyphase signals, and compensate for DC offset */
+  for (k=0;k<FRAMESAMPLES_10ms/2;k++) {
+    Vector_Word16_1[k] = speechIn[k] + 1;
+    Vector_Word16_2[k] = speechIn[k];
+  }
+  WebRtcIsacfix_FilterAndCombine2(Vector_Word16_1, Vector_Word16_2, speechInWB, &ISAC_inst->ISACenc_obj.interpolatorstr_obj, FRAMESAMPLES_10ms);
+
+
+  /* Encode WB signal */
+  stream_len = WebRtcIsacfix_EncodeImpl((WebRtc_Word16*)speechInWB,
+                                    &ISAC_inst->ISACenc_obj,
+                                    &ISAC_inst->bwestimator_obj,
+                                    ISAC_inst->CodingMode);
+  if (stream_len<0) {
+    ISAC_inst->errorcode = - stream_len;
+    return -1;
+  }
+
+
+  /* convert from bytes to WebRtc_Word16 */
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0;k<(stream_len+1)>>1;k++) {
+    encoded[k] = (WebRtc_Word16)(((WebRtc_UWord16)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8)
+                                 | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
+  }
+
+#else
+  WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
+#endif
+
+
+
+  return stream_len;
+}
+#endif  /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
+
+
+/****************************************************************************
+ * WebRtcIsacfix_GetNewBitStream(...)
+ *
+ * This function returns encoded data, with the recieved bwe-index in the
+ * stream. It should always return a complete packet, i.e. only called once
+ * even for 60 msec frames
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - bweIndex          : index of bandwidth estimate to put in new bitstream
+ *
+ * Output:
+ *      - encoded           : the encoded data vector
+ *
+ * Return value:
+ *                          : >0 - Length (in bytes) of coded data
+ *                          : -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
+                                            WebRtc_Word16      bweIndex,
+                                            float              scale,
+                                            WebRtc_Word16        *encoded)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  WebRtc_Word16 stream_len;
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+
+  /* typecast pointer to rela structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+
+  /* check if encoder initiated */
+  if ((ISAC_inst->initflag & 2) != 2) {
+    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj,
+                                              bweIndex,
+                                              scale);
+  if (stream_len<0) {
+    ISAC_inst->errorcode = - stream_len;
+    return -1;
+  }
+
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0;k<(stream_len+1)>>1;k++) {
+    encoded[k] = (WebRtc_Word16)( ( (WebRtc_UWord16)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8 )
+                                  | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
+  }
+
+#else
+  WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
+#endif
+
+  return stream_len;
+
+}
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecoderInit(...)
+ *
+ * This function initializes a ISAC instance prior to the decoder calls.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *
+ * Return value
+ *                          :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* flag decoder init */
+  ISAC_inst->initflag |= 1;
+
+
+  WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj);
+  WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj);
+  WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj);
+
+  /* TS */
+  WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj );
+
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACdec_obj.decimatorstr_obj);
+#endif
+
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_UpdateBwEstimate1(...)
+ *
+ * This function updates the estimate of the bandwidth.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - encoded           : encoded ISAC frame(s).
+ *      - packet_size       : size of the packet.
+ *      - rtp_seq_number    : the RTP number of the packet.
+ *      - arr_ts            : the arrival time of the packet (from NetEq)
+ *                            in samples.
+ *
+ * Return value             :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
+                                     const WebRtc_UWord16   *encoded,
+                                     WebRtc_Word32          packet_size,
+                                     WebRtc_UWord16         rtp_seq_number,
+                                     WebRtc_UWord32         arr_ts)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  Bitstr_dec streamdata;
+  WebRtc_UWord16 partOfStream[5];
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+  WebRtc_Word16 err;
+
+  /* Set stream pointer to point at partOfStream */
+  streamdata.stream = (WebRtc_UWord16 *)partOfStream;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Sanity check of packet length */
+  if (packet_size <= 0) {
+    /* return error code if the packet length is null or less */
+    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
+    return -1;
+  } else if (packet_size > (STREAM_MAXW16<<1)) {
+    /* return error code if length of stream is too long */
+    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+    return -1;
+  }
+
+  /* check if decoder initiated */
+  if ((ISAC_inst->initflag & 1) != 1) {
+    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  streamdata.W_upper = 0xFFFFFFFF;
+  streamdata.streamval = 0;
+  streamdata.stream_index = 0;
+  streamdata.full = 1;
+
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0; k<5; k++) {
+    streamdata.stream[k] = (WebRtc_UWord16) (((WebRtc_UWord16)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
+  }
+#else
+  memcpy(streamdata.stream, encoded, 5);
+#endif
+
+  if (packet_size == 0)
+  {
+    /* return error code if the packet length is null */
+    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
+    return -1;
+  }
+
+  err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
+                                        &streamdata,
+                                        packet_size,
+                                        rtp_seq_number,
+                                        0,
+                                        arr_ts);
+
+
+  if (err < 0)
+  {
+    /* return error code if something went wrong */
+    ISAC_inst->errorcode = -err;
+    return -1;
+  }
+
+
+  return 0;
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_UpdateBwEstimate(...)
+ *
+ * This function updates the estimate of the bandwidth.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - encoded           : encoded ISAC frame(s).
+ *      - packet_size       : size of the packet.
+ *      - rtp_seq_number    : the RTP number of the packet.
+ *      - send_ts           : Send Time Stamp from RTP header
+ *      - arr_ts            : the arrival time of the packet (from NetEq)
+ *                            in samples.
+ *
+ * Return value             :  0 - Ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
+                                       const WebRtc_UWord16   *encoded,
+                                       WebRtc_Word32          packet_size,
+                                       WebRtc_UWord16         rtp_seq_number,
+                                       WebRtc_UWord32         send_ts,
+                                       WebRtc_UWord32         arr_ts)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  Bitstr_dec streamdata;
+  WebRtc_UWord16 partOfStream[5];
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+  WebRtc_Word16 err;
+
+  /* Set stream pointer to point at partOfStream */
+  streamdata.stream = (WebRtc_UWord16 *)partOfStream;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Sanity check of packet length */
+  if (packet_size <= 0) {
+    /* return error code if the packet length is null  or less */
+    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
+    return -1;
+  } else if (packet_size > (STREAM_MAXW16<<1)) {
+    /* return error code if length of stream is too long */
+    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+    return -1;
+  }
+
+  /* check if decoder initiated */
+  if ((ISAC_inst->initflag & 1) != 1) {
+    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  streamdata.W_upper = 0xFFFFFFFF;
+  streamdata.streamval = 0;
+  streamdata.stream_index = 0;
+  streamdata.full = 1;
+
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0; k<5; k++) {
+    streamdata.stream[k] = (WebRtc_UWord16) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
+  }
+#else
+  memcpy(streamdata.stream, encoded, 5);
+#endif
+
+  if (packet_size == 0)
+  {
+    /* return error code if the packet length is null */
+    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
+    return -1;
+  }
+
+  err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
+                                        &streamdata,
+                                        packet_size,
+                                        rtp_seq_number,
+                                        send_ts,
+                                        arr_ts);
+
+  if (err < 0)
+  {
+    /* return error code if something went wrong */
+    ISAC_inst->errorcode = -err;
+    return -1;
+  }
+
+
+  return 0;
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_Decode(...)
+ *
+ * This function decodes a ISAC frame. Output speech length
+ * will be a multiple of 480 samples: 480 or 960 samples,
+ * depending on the framesize (30 or 60 ms).
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - encoded           : encoded ISAC frame(s)
+ *      - len               : bytes in encoded vector
+ *
+ * Output:
+ *      - decoded           : The decoded vector
+ *
+ * Return value             : >0 - number of samples in decoded vector
+ *                            -1 - Error
+ */
+
+
+WebRtc_Word16 WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
+                                     const WebRtc_UWord16   *encoded,
+                                     WebRtc_Word16          len,
+                                     WebRtc_Word16          *decoded,
+                                     WebRtc_Word16     *speechType)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  /* number of samples (480 or 960), output from decoder */
+  /* that were actually used in the encoder/decoder (determined on the fly) */
+  WebRtc_Word16     number_of_samples;
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+  WebRtc_Word16 declen = 0;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* check if decoder initiated */
+  if ((ISAC_inst->initflag & 1) != 1) {
+    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  /* Sanity check of packet length */
+  if (len <= 0) {
+    /* return error code if the packet length is null  or less */
+    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
+    return -1;
+  } else if (len > (STREAM_MAXW16<<1)) {
+    /* return error code if length of stream is too long */
+    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+    return -1;
+  }
+
+  (ISAC_inst->ISACdec_obj.bitstr_obj).stream = (WebRtc_UWord16 *)encoded;
+
+  /* convert bitstream from WebRtc_Word16 to bytes */
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0; k<(len>>1); k++) {
+    (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
+  }
+  if (len & 0x0001)
+    (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] & 0xFF)<<8);
+#endif
+
+  /* added for NetEq purposes (VAD/DTX related) */
+  *speechType=1;
+
+  declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples);
+
+  if (declen < 0) {
+    /* Some error inside the decoder */
+    ISAC_inst->errorcode = -declen;
+    memset(decoded, 0, sizeof(WebRtc_Word16) * MAX_FRAMESAMPLES);
+    return -1;
+  }
+
+  /* error check */
+
+  if (declen & 0x0001) {
+    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) {
+      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+      memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples);
+      return -1;
+    }
+  } else {
+    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) {
+      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+      memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples);
+      return -1;
+    }
+  }
+
+  return number_of_samples;
+}
+
+
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecodeNb(...)
+ *
+ * This function decodes a ISAC frame in narrow-band (8 kHz sampling).
+ * Output speech length will be a multiple of 240 samples: 240 or 480 samples,
+ * depending on the framesize (30 or 60 ms).
+ *
+ * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - encoded           : encoded ISAC frame(s)
+ *      - len               : bytes in encoded vector
+ *
+ * Output:
+ *      - decoded           : The decoded vector
+ *
+ * Return value             : >0 - number of samples in decoded vector
+ *                            -1 - Error
+ */
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+WebRtc_Word16 WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
+                                        const WebRtc_UWord16   *encoded,
+                                        WebRtc_Word16          len,
+                                        WebRtc_Word16          *decoded,
+                                        WebRtc_Word16    *speechType)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  /* twice the number of samples (480 or 960), output from decoder */
+  /* that were actually used in the encoder/decoder (determined on the fly) */
+  WebRtc_Word16     number_of_samples;
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+  WebRtc_Word16 declen = 0;
+  WebRtc_Word16 dummy[FRAMESAMPLES/2];
+
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* check if decoder initiated */
+  if ((ISAC_inst->initflag & 1) != 1) {
+    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  if (len == 0)
+  {  /* return error code if the packet length is null */
+
+    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
+    return -1;
+  }
+
+  (ISAC_inst->ISACdec_obj.bitstr_obj).stream = (WebRtc_UWord16 *)encoded;
+
+  /* convert bitstream from WebRtc_Word16 to bytes */
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0; k<(len>>1); k++) {
+    (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
+  }
+  if (len & 0x0001)
+    (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (WebRtc_UWord16) ((encoded[k] & 0xFF)<<8);
+#endif
+
+  /* added for NetEq purposes (VAD/DTX related) */
+  *speechType=1;
+
+  declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples);
+
+  if (declen < 0) {
+    /* Some error inside the decoder */
+    ISAC_inst->errorcode = -declen;
+    memset(decoded, 0, sizeof(WebRtc_Word16) * FRAMESAMPLES);
+    return -1;
+  }
+
+  /* error check */
+
+  if (declen & 0x0001) {
+    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) {
+      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+      memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples);
+      return -1;
+    }
+  } else {
+    if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) {
+      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
+      memset(decoded, 0, sizeof(WebRtc_Word16) * number_of_samples);
+      return -1;
+    }
+  }
+
+  WebRtcIsacfix_SplitAndFilter2(decoded, decoded, dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
+
+  if (number_of_samples>FRAMESAMPLES) {
+    WebRtcIsacfix_SplitAndFilter2(decoded + FRAMESAMPLES, decoded + FRAMESAMPLES/2,
+                                  dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
+  }
+
+  return number_of_samples/2;
+}
+#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecodePlcNb(...)
+ *
+ * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
+ * Output speech length  will be "240*noOfLostFrames" samples
+ * that is equevalent of "30*noOfLostFrames" millisecond.
+ *
+ * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - noOfLostFrames    : Number of PLC frames (240 sample=30ms) to produce
+ *
+ * Output:
+ *      - decoded           : The decoded vector
+ *
+ * Return value             : >0 - number of samples in decoded PLC vector
+ *                            -1 - Error
+ */
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+WebRtc_Word16 WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst,
+                                         WebRtc_Word16          *decoded,
+                                         WebRtc_Word16 noOfLostFrames )
+{
+  WebRtc_Word16 no_of_samples, declen, k, ok;
+  WebRtc_Word16 outframeNB[FRAMESAMPLES];
+  WebRtc_Word16 outframeWB[FRAMESAMPLES];
+  WebRtc_Word16 dummy[FRAMESAMPLES/2];
+
+
+  ISACFIX_SubStruct *ISAC_inst;
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
+  if (noOfLostFrames > 2){
+    noOfLostFrames = 2;
+  }
+
+  k = 0;
+  declen = 0;
+  while( noOfLostFrames > 0 )
+  {
+    ok = WebRtcIsacfix_DecodePlcImpl( outframeWB, &ISAC_inst->ISACdec_obj, &no_of_samples );
+    if(ok)
+      return -1;
+
+    WebRtcIsacfix_SplitAndFilter2(outframeWB, &(outframeNB[k*240]), dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
+
+    declen += no_of_samples;
+    noOfLostFrames--;
+    k++;
+  }
+
+  declen>>=1;
+
+  for (k=0;k<declen;k++) {
+    decoded[k] = outframeNB[k];
+  }
+
+  return declen;
+}
+#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
+
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_DecodePlc(...)
+ *
+ * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
+ * Output speech length  will be "480*noOfLostFrames" samples
+ * that is equevalent of "30*noOfLostFrames" millisecond.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - noOfLostFrames    : Number of PLC frames (480sample = 30ms)
+ *                                to produce
+ *
+ * Output:
+ *      - decoded           : The decoded vector
+ *
+ * Return value             : >0 - number of samples in decoded PLC vector
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst,
+                                      WebRtc_Word16          *decoded,
+                                      WebRtc_Word16 noOfLostFrames)
+{
+
+  WebRtc_Word16 no_of_samples, declen, k, ok;
+  WebRtc_Word16 outframe16[MAX_FRAMESAMPLES];
+
+  ISACFIX_SubStruct *ISAC_inst;
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
+  if (noOfLostFrames > 2) {
+    noOfLostFrames = 2;
+  }
+  k = 0;
+  declen = 0;
+  while( noOfLostFrames > 0 )
+  {
+    ok = WebRtcIsacfix_DecodePlcImpl( &(outframe16[k*480]), &ISAC_inst->ISACdec_obj, &no_of_samples );
+    if(ok)
+      return -1;
+    declen += no_of_samples;
+    noOfLostFrames--;
+    k++;
+  }
+
+  for (k=0;k<declen;k++) {
+    decoded[k] = outframe16[k];
+  }
+
+  return declen;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_Control(...)
+ *
+ * This function sets the limit on the short-term average bit rate and the
+ * frame length. Should be used only in Instantaneous mode.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance.
+ *      - rate              : limit on the short-term average bit rate,
+ *                            in bits/second (between 10000 and 32000)
+ *      - framesize         : number of milliseconds per frame (30 or 60)
+ *
+ * Return value             : 0  - ok
+ *                            -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
+                                    WebRtc_Word16          rate,
+                                    WebRtc_Word16          framesize)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  if (ISAC_inst->CodingMode == 0)
+  {
+    /* in adaptive mode */
+    ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
+    return -1;
+  }
+
+
+  if (rate >= 10000 && rate <= 32000)
+    ISAC_inst->ISACenc_obj.BottleNeck = rate;
+  else {
+    ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
+    return -1;
+  }
+
+
+
+  if (framesize  == 30 || framesize == 60)
+    ISAC_inst->ISACenc_obj.new_framelength = (FS/1000) * framesize;
+  else {
+    ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
+    return -1;
+  }
+
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_ControlBwe(...)
+ *
+ * This function sets the initial values of bottleneck and frame-size if
+ * iSAC is used in channel-adaptive mode. Through this API, users can
+ * enforce a frame-size for all values of bottleneck. Then iSAC will not
+ * automatically change the frame-size.
+ *
+ *
+ * Input:
+ *  - ISAC_main_inst : ISAC instance.
+ *      - rateBPS           : initial value of bottleneck in bits/second
+ *                            10000 <= rateBPS <= 32000 is accepted
+ *                            For default bottleneck set rateBPS = 0
+ *      - frameSizeMs       : number of milliseconds per frame (30 or 60)
+ *      - enforceFrameSize  : 1 to enforce the given frame-size through out
+ *                            the adaptation process, 0 to let iSAC change
+ *                            the frame-size if required.
+ *
+ * Return value    : 0  - ok
+ *         -1 - Error
+ */
+
+WebRtc_Word16 WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
+                                        WebRtc_Word16 rateBPS,
+                                        WebRtc_Word16 frameSizeMs,
+                                        WebRtc_Word16 enforceFrameSize)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  /* Typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* check if encoder initiated */
+  if ((ISAC_inst->initflag & 2) != 2) {
+    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
+    return (-1);
+  }
+
+  /* Check that we are in channel-adaptive mode, otherwise, return -1 */
+  if (ISAC_inst->CodingMode != 0) {
+    ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
+    return (-1);
+  }
+
+  /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */
+  /* chosen frame size.                                                      */
+  ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0;
+
+  /* Set initial rate, if value between 10000 and 32000,                */
+  /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
+  if ((rateBPS >= 10000) && (rateBPS <= 32000)) {
+    ISAC_inst->bwestimator_obj.sendBwAvg = (((WebRtc_UWord32)rateBPS) << 7);
+  } else if (rateBPS != 0) {
+    ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
+    return -1;
+  }
+
+  /* Set initial framesize. If enforceFrameSize is set the frame size will not change */
+  if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
+    ISAC_inst->ISACenc_obj.new_framelength = (FS/1000) * frameSizeMs;
+  } else {
+    ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
+    return -1;
+  }
+
+  return 0;
+}
+
+
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_GetDownLinkBwIndex(...)
+ *
+ * This function returns index representing the Bandwidth estimate from
+ * other side to this side.
+ *
+ * Input:
+ *      - ISAC_main_inst: iSAC struct
+ *
+ * Output:
+ *      - rateIndex     : Bandwidth estimate to transmit to other side.
+ *
+ */
+
+WebRtc_Word16 WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
+                                       WebRtc_Word16*     rateIndex)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Call function to get Bandwidth Estimate */
+  *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj);
+
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_UpdateUplinkBw(...)
+ *
+ * This function takes an index representing the Bandwidth estimate from
+ * this side to other side and updates BWE.
+ *
+ * Input:
+ *      - ISAC_main_inst: iSAC struct
+ *      - rateIndex     : Bandwidth estimate from other side.
+ *
+ */
+
+WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
+                                   WebRtc_Word16     rateIndex)
+{
+  WebRtc_Word16 err = 0;
+  ISACFIX_SubStruct *ISAC_inst;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  /* Call function to update BWE with received Bandwidth Estimate */
+  err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex);
+  if (err < 0) {
+    ISAC_inst->errorcode = -err;
+    return (-1);
+  }
+
+  return 0;
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_ReadFrameLen(...)
+ *
+ * This function returns the length of the frame represented in the packet.
+ *
+ * Input:
+ *      - encoded       : Encoded bitstream
+ *
+ * Output:
+ *      - frameLength   : Length of frame in packet (in samples)
+ *
+ */
+
+WebRtc_Word16 WebRtcIsacfix_ReadFrameLen(const WebRtc_Word16* encoded,
+                                        WebRtc_Word16* frameLength)
+{
+  Bitstr_dec streamdata;
+  WebRtc_UWord16 partOfStream[5];
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+  WebRtc_Word16 err;
+
+  /* Set stream pointer to point at partOfStream */
+  streamdata.stream = (WebRtc_UWord16 *)partOfStream;
+
+  streamdata.W_upper = 0xFFFFFFFF;
+  streamdata.streamval = 0;
+  streamdata.stream_index = 0;
+  streamdata.full = 1;
+
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0; k<5; k++) {
+    streamdata.stream[k] = (WebRtc_UWord16) (((WebRtc_UWord16)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
+  }
+#else
+  memcpy(streamdata.stream, encoded, 5);
+#endif
+
+  /* decode frame length */
+  err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
+  if (err<0)  // error check
+    return err;
+
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_ReadBwIndex(...)
+ *
+ * This function returns the index of the Bandwidth estimate from the bitstream.
+ *
+ * Input:
+ *      - encoded       : Encoded bitstream
+ *
+ * Output:
+ *      - frameLength   : Length of frame in packet (in samples)
+ *      - rateIndex     : Bandwidth estimate in bitstream
+ *
+ */
+
+WebRtc_Word16 WebRtcIsacfix_ReadBwIndex(const WebRtc_Word16* encoded,
+                                   WebRtc_Word16* rateIndex)
+{
+  Bitstr_dec streamdata;
+  WebRtc_UWord16 partOfStream[5];
+#ifndef WEBRTC_BIG_ENDIAN
+  int k;
+#endif
+  WebRtc_Word16 err;
+
+  /* Set stream pointer to point at partOfStream */
+  streamdata.stream = (WebRtc_UWord16 *)partOfStream;
+
+  streamdata.W_upper = 0xFFFFFFFF;
+  streamdata.streamval = 0;
+  streamdata.stream_index = 0;
+  streamdata.full = 1;
+
+#ifndef WEBRTC_BIG_ENDIAN
+  for (k=0; k<5; k++) {
+    streamdata.stream[k] = (WebRtc_UWord16) (((WebRtc_UWord16)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
+  }
+#else
+  memcpy(streamdata.stream, encoded, 5);
+#endif
+
+  /* decode frame length, needed to get to the rateIndex in the bitstream */
+  err = WebRtcIsacfix_DecodeFrameLen(&streamdata, rateIndex);
+  if (err<0)  // error check
+    return err;
+
+  /* decode BW estimation */
+  err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex);
+  if (err<0)  // error check
+    return err;
+
+  return 0;
+}
+
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_GetErrorCode(...)
+ *
+ * This function can be used to check the error code of an iSAC instance. When
+ * a function returns -1 a error code will be set for that instance. The
+ * function below extract the code of the last error that occured in the
+ * specified instance.
+ *
+ * Input:
+ *      - ISAC_main_inst    : ISAC instance
+ *
+ * Return value             : Error code
+ */
+
+WebRtc_Word16 WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  return ISAC_inst->errorcode;
+}
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_GetUplinkBw(...)
+ *
+ * This function returns the inst quantized iSAC send bitrate
+ *
+ * Input:
+ *      - ISAC_main_inst    : iSAC instance
+ *
+ * Return value             : bitrate
+ */
+
+WebRtc_Word32 WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+  BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj);
+
+  return (WebRtc_Word32) WebRtcIsacfix_GetUplinkBandwidth(bw);
+}
+
+/****************************************************************************
+ * WebRtcIsacfix_GetNewFrameLen(...)
+ *
+ * This function return the next frame length (in samples) of iSAC.
+ *
+ * Input:
+ *      - ISAC_main_inst    : iSAC instance
+ *
+ * Return value             :  frame lenght in samples
+ */
+
+WebRtc_Word16 WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst)
+{
+  ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+  return ISAC_inst->ISACenc_obj.new_framelength;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_SetMaxPayloadSize(...)
+ *
+ * This function sets a limit for the maximum payload size of iSAC. The same
+ * value is used both for 30 and 60 msec packets.
+ * The absolute max will be valid until next time the function is called.
+ * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
+ *
+ * Input:
+ *      - ISAC_main_inst    : iSAC instance
+ *      - maxPayloadBytes   : maximum size of the payload in bytes
+ *                            valid values are between 100 and 400 bytes
+ *
+ *
+ * Return value             : 0 if sucessful
+ *                           -1 if error happens
+ */
+
+WebRtc_Word16 WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
+                                              WebRtc_Word16 maxPayloadBytes)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  if((maxPayloadBytes < 100) || (maxPayloadBytes > 400))
+  {
+    /* maxPayloadBytes is out of valid range */
+    return -1;
+  }
+  else
+  {
+    /* Set new absolute max, which will not change unless this function
+       is called again with a new value */
+    ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes;
+
+    /* Set new maximum values for 30 and 60 msec packets */
+    if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes;
+    } else {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes;
+    }
+
+    if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes;
+    } else {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1);
+    }
+  }
+  return 0;
+}
+
+
+/****************************************************************************
+ * WebRtcIsacfix_SetMaxRate(...)
+ *
+ * This function sets the maximum rate which the codec may not exceed for a
+ * singel packet. The maximum rate is set in bits per second.
+ * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
+ * per 30 msec).
+ * It is possible to set a maximum rate between 32000 and 53400 bits per second.
+ *
+ * The rate limit is valid until next time the function is called.
+ *
+ * NOTE! Packet size will never go above the value set if calling
+ * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
+ *
+ * Input:
+ *      - ISAC_main_inst    : iSAC instance
+ *      - maxRateInBytes    : maximum rate in bits per second,
+ *                            valid values are 32000 to 53400 bits
+ *
+ * Return value             : 0 if sucessful
+ *                           -1 if error happens
+ */
+
+WebRtc_Word16 WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
+                                       WebRtc_Word32 maxRate)
+{
+  ISACFIX_SubStruct *ISAC_inst;
+  WebRtc_Word16 maxRateInBytes;
+
+  /* typecast pointer to real structure */
+  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
+
+  if((maxRate < 32000) || (maxRate > 53400))
+  {
+    /* maxRate is out of valid range */
+    return -1;
+  }
+  else
+  {
+    /* Calculate maximum number of bytes per 30 msec packets for the given
+       maximum rate. Multiply with 30/1000 to get number of bits per 30 msec,
+       divide by 8 to get number of bytes per 30 msec:
+       maxRateInBytes = floor((maxRate * 30/1000) / 8); */
+    maxRateInBytes = (WebRtc_Word16)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) );
+
+    /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */
+    ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes;
+
+    /* For 30 msec packets: if the new limit is below the maximum
+       payload size, set a new limit */
+    if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes;
+    } else {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
+    }
+
+    /* For 60 msec packets: if the new limit (times 2) is below the
+       maximum payload size, set a new limit */
+    if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1);
+    } else {
+      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
+    }
+  }
+
+  return 0;
+}
+
+
+
+/****************************************************************************
+ * WebRtcIsacfix_version(...)
+ *
+ * This function returns the version number.
+ *
+ * Output:
+ *      - version  : Pointer to character string
+ *
+ */
+
+void WebRtcIsacfix_version(char *version)
+{
+  strcpy(version, "3.6.0");
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi b/src/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi
new file mode 100644
index 0000000..739b2e1
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/isacfix.gypi
@@ -0,0 +1,108 @@
+# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS.  All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+{
+  'targets': [
+    {
+      'target_name': 'iSACFix',
+      'type': '<(library)',
+      'dependencies': [
+        '<(webrtc_root)/common_audio/common_audio.gyp:signal_processing',
+        '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
+      ],
+      'include_dirs': [
+        '../interface',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '../interface',
+        ],
+      },
+      'sources': [
+        '../interface/isacfix.h',
+        'arith_routines.c',
+        'arith_routines_hist.c',
+        'arith_routines_logist.c',
+        'bandwidth_estimator.c',
+        'decode.c',
+        'decode_bwe.c',
+        'decode_plc.c',
+        'encode.c',
+        'entropy_coding.c',
+        'fft.c',
+        'filterbank_tables.c',
+        'filterbanks.c',
+        'filters.c',
+        'initialize.c',
+        'isacfix.c',
+        'lattice.c',
+        'lattice_c.c',
+        'lpc_masking_model.c',
+        'lpc_tables.c',
+        'pitch_estimator.c',
+        'pitch_filter.c',
+        'pitch_filter_c.c',
+        'pitch_gain_tables.c',
+        'pitch_lag_tables.c',
+        'spectrum_ar_model_tables.c',
+        'transform.c',
+        'arith_routins.h',
+        'bandwidth_estimator.h',
+        'codec.h',
+        'entropy_coding.h',
+        'fft.h',
+        'filterbank_tables.h',
+        'lpc_masking_model.h',
+        'lpc_tables.h',
+        'pitch_estimator.h',
+        'pitch_gain_tables.h',
+        'pitch_lag_tables.h',
+        'settings.h',
+        'spectrum_ar_model_tables.h',
+        'structs.h',
+      ],
+      'conditions': [
+        ['OS!="win"', {
+          'defines': [
+            'WEBRTC_LINUX',
+          ],
+        }],
+        ['target_arch=="arm" and armv7==1', {
+          'dependencies': [ 'isac_neon', ],
+          'sources': [
+            'lattice_armv7.S',
+            'pitch_filter_armv6.S',
+          ],
+          'sources!': [
+            'lattice_c.c',
+            'pitch_filter_c.c',
+          ],
+        }],
+      ],
+    },
+  ],
+  'conditions': [
+    ['target_arch=="arm" and armv7==1', {
+      'targets': [
+        {
+          'target_name': 'isac_neon',
+          'type': '<(library)',
+          'includes': ['../../../../../../build/arm_neon.gypi',],
+          'dependencies': [
+            '<(webrtc_root)/common_audio/common_audio.gyp:signal_processing',
+          ],
+          'sources': [
+            'filters_neon.c',
+            'lattice_neon.S',
+            'lpc_masking_model_neon.S',
+          ],
+        },
+      ],
+    }],
+  ],
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lattice.c b/src/modules/audio_coding/codecs/isac/fix/source/lattice.c
new file mode 100644
index 0000000..14588d0
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lattice.c
@@ -0,0 +1,314 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * lattice.c
+ *
+ * Contains the normalized lattice filter routines (MA and AR) for iSAC codec
+ *
+ */
+
+#include "codec.h"
+#include "settings.h"
+
+#define LATTICE_MUL_32_32_RSFT16(a32a, a32b, b32)                  \
+  ((WebRtc_Word32)(WEBRTC_SPL_MUL(a32a, b32) + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32))))
+/* This macro is FORBIDDEN to use elsewhere than in a function in this file and
+   its corresponding neon version. It might give unpredictable results, since a
+   general WebRtc_Word32*WebRtc_Word32 multiplication results in a 64 bit value.
+   The result is then shifted just 16 steps to the right, giving need for 48
+   bits, i.e. in the generel case, it will NOT fit in a WebRtc_Word32. In the
+   cases used in here, the WebRtc_Word32 will be enough, since (for a good
+   reason) the involved multiplicands aren't big enough to overflow a
+   WebRtc_Word32 after shifting right 16 bits. I have compared the result of a
+   multiplication between t32 and tmp32, done in two ways:
+   1) Using (WebRtc_Word32) (((float)(tmp32))*((float)(tmp32b))/65536.0);
+   2) Using LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
+   By running 25 files, I haven't found any bigger diff than 64 - this was in the
+   case when  method 1) gave 650235648 and 2) gave 650235712.
+*/
+
+/* Function prototype: filtering ar_g_Q0[] and ar_f_Q0[] through an AR filter
+   with coefficients cth_Q15[] and sth_Q15[].
+   Implemented for both generic and ARMv7 platforms.
+ */
+void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0,
+                                int16_t* ar_f_Q0,
+                                int16_t* cth_Q15,
+                                int16_t* sth_Q15,
+                                int16_t order_coef);
+
+/* Inner loop used for function WebRtcIsacfix_NormLatticeFilterMa(). It does:
+   for 0 <= n < HALF_SUBFRAMELEN - 1:
+     *ptr2 = input2 * (*ptr2) + input0 * (*ptr0));
+     *ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
+   Note, function WebRtcIsacfix_FilterMaLoopNeon and WebRtcIsacfix_FilterMaLoopC
+   are not bit-exact. The accuracy by the ARM Neon function is same or better.
+*/
+void WebRtcIsacfix_FilterMaLoopC(int16_t input0,  // Filter coefficient
+                                 int16_t input1,  // Filter coefficient
+                                 int32_t input2,  // Inverse coeff. (1/input1)
+                                 int32_t* ptr0,   // Sample buffer
+                                 int32_t* ptr1,   // Sample buffer
+                                 int32_t* ptr2) { // Sample buffer
+  int n = 0;
+
+  // Separate the 32-bit variable input2 into two 16-bit integers (high 16 and
+  // low 16 bits), for using LATTICE_MUL_32_32_RSFT16 in the loop.
+  int16_t t16a = (int16_t)(input2 >> 16);
+  int16_t t16b = (int16_t)input2;
+  if (t16b < 0) t16a++;
+
+  // The loop filtering the samples *ptr0, *ptr1, *ptr2 with filter coefficients
+  // input0, input1, and input2.
+  for(n = 0; n < HALF_SUBFRAMELEN - 1; n++, ptr0++, ptr1++, ptr2++) {
+    int32_t tmp32a = 0;
+    int32_t tmp32b = 0;
+
+    // Calculate *ptr2 = input2 * (*ptr2 + input0 * (*ptr0));
+    tmp32a = WEBRTC_SPL_MUL_16_32_RSFT15(input0, *ptr0); // Q15 * Q15 >> 15 = Q15
+    tmp32b = *ptr2 + tmp32a; // Q15 + Q15 = Q15
+    *ptr2 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
+
+    // Calculate *ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
+    tmp32a = WEBRTC_SPL_MUL_16_32_RSFT15(input1, *ptr0); // Q15*Q15>>15 = Q15
+    tmp32b = WEBRTC_SPL_MUL_16_32_RSFT15(input0, *ptr2); // Q15*Q15>>15 = Q15
+    *ptr1 = tmp32a + tmp32b; // Q15 + Q15 = Q15
+  }
+}
+
+// Declare a function pointer.
+FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
+
+/* filter the signal using normalized lattice filter */
+/* MA filter */
+void WebRtcIsacfix_NormLatticeFilterMa(WebRtc_Word16 orderCoef,
+                                       WebRtc_Word32 *stateGQ15,
+                                       WebRtc_Word16 *lat_inQ0,
+                                       WebRtc_Word16 *filt_coefQ15,
+                                       WebRtc_Word32 *gain_lo_hiQ17,
+                                       WebRtc_Word16 lo_hi,
+                                       WebRtc_Word16 *lat_outQ9)
+{
+  WebRtc_Word16 sthQ15[MAX_AR_MODEL_ORDER];
+  WebRtc_Word16 cthQ15[MAX_AR_MODEL_ORDER];
+
+  int u, i, k, n;
+  WebRtc_Word16 temp2,temp3;
+  WebRtc_Word16 ord_1 = orderCoef+1;
+  WebRtc_Word32 inv_cthQ16[MAX_AR_MODEL_ORDER];
+
+  WebRtc_Word32 gain32, fQtmp;
+  WebRtc_Word16 gain16;
+  WebRtc_Word16 gain_sh;
+
+  WebRtc_Word32 tmp32, tmp32b;
+  WebRtc_Word32 fQ15vec[HALF_SUBFRAMELEN];
+  WebRtc_Word32 gQ15[MAX_AR_MODEL_ORDER+1][HALF_SUBFRAMELEN];
+  WebRtc_Word16 sh;
+  WebRtc_Word16 t16a;
+  WebRtc_Word16 t16b;
+
+  for (u=0;u<SUBFRAMES;u++)
+  {
+    int32_t temp1 = WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN);
+
+    /* set the Direct Form coefficients */
+    temp2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(u, orderCoef);
+    temp3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, u)+lo_hi;
+
+    /* compute lattice filter coefficients */
+    memcpy(sthQ15, &filt_coefQ15[temp2], orderCoef * sizeof(WebRtc_Word16));
+
+    WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15);
+
+    /* compute the gain */
+    gain32 = gain_lo_hiQ17[temp3];
+    gain_sh = WebRtcSpl_NormW32(gain32);
+    gain32 = WEBRTC_SPL_LSHIFT_W32(gain32, gain_sh); //Q(17+gain_sh)
+
+    for (k=0;k<orderCoef;k++)
+    {
+      gain32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], gain32); //Q15*Q(17+gain_sh)>>15 = Q(17+gain_sh)
+      inv_cthQ16[k] = WebRtcSpl_DivW32W16((WebRtc_Word32)2147483647, cthQ15[k]); // 1/cth[k] in Q31/Q15 = Q16
+    }
+    gain16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(gain32, 16); //Q(1+gain_sh)
+
+    /* normalized lattice filter */
+    /*****************************/
+
+    /* initial conditions */
+    for (i=0;i<HALF_SUBFRAMELEN;i++)
+    {
+      fQ15vec[i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)lat_inQ0[i + temp1], 15); //Q15
+      gQ15[0][i] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)lat_inQ0[i + temp1], 15); //Q15
+    }
+
+
+    fQtmp = fQ15vec[0];
+
+    /* get the state of f&g for the first input, for all orders */
+    for (i=1;i<ord_1;i++)
+    {
+      // Calculate f[i][0] = inv_cth[i-1]*(f[i-1][0] + sth[i-1]*stateG[i-1]);
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], stateGQ15[i-1]);//Q15*Q15>>15 = Q15
+      tmp32b= fQtmp + tmp32; //Q15+Q15=Q15
+      tmp32 = inv_cthQ16[i-1]; //Q16
+      t16a = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32, 16);
+      t16b = (WebRtc_Word16) (tmp32-WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)t16a), 16));
+      if (t16b<0) t16a++;
+      tmp32 = LATTICE_MUL_32_32_RSFT16(t16a, t16b, tmp32b);
+      fQtmp = tmp32; // Q15
+
+      // Calculate g[i][0] = cth[i-1]*stateG[i-1] + sth[i-1]* f[i][0];
+      tmp32  = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[i-1], stateGQ15[i-1]); //Q15*Q15>>15 = Q15
+      tmp32b = WEBRTC_SPL_MUL_16_32_RSFT15(sthQ15[i-1], fQtmp); //Q15*Q15>>15 = Q15
+      tmp32  = tmp32 + tmp32b;//Q15+Q15 = Q15
+      gQ15[i][0] = tmp32; // Q15
+    }
+
+    /* filtering */
+    /* save the states */
+    for(k=0;k<orderCoef;k++)
+    {
+      // for 0 <= n < HALF_SUBFRAMELEN - 1:
+      //   f[k+1][n+1] = inv_cth[k]*(f[k][n+1] + sth[k]*g[k][n]);
+      //   g[k+1][n+1] = cth[k]*g[k][n] + sth[k]* f[k+1][n+1];
+      WebRtcIsacfix_FilterMaLoopFix(sthQ15[k], cthQ15[k], inv_cthQ16[k],
+                                    &gQ15[k][0], &gQ15[k+1][1], &fQ15vec[1]);
+    }
+
+    fQ15vec[0] = fQtmp;
+
+    for(n=0;n<HALF_SUBFRAMELEN;n++)
+    {
+      //gain32 = WEBRTC_SPL_RSHIFT_W32(gain32, gain_sh); // Q(17+gain_sh) -> Q17
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(gain16, fQ15vec[n]); //Q(1+gain_sh)*Q15>>16 = Q(gain_sh)
+      sh = 9-gain_sh; //number of needed shifts to reach Q9
+      t16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32, sh);
+      lat_outQ9[n + temp1] = t16a;
+    }
+
+    /* save the states */
+    for (i=0;i<ord_1;i++)
+    {
+      stateGQ15[i] = gQ15[i][HALF_SUBFRAMELEN-1];
+    }
+    //process next frame
+  }
+
+  return;
+}
+
+
+
+
+
+/* ----------------AR filter-------------------------*/
+/* filter the signal using normalized lattice filter */
+void WebRtcIsacfix_NormLatticeFilterAr(WebRtc_Word16 orderCoef,
+                                       WebRtc_Word16 *stateGQ0,
+                                       WebRtc_Word32 *lat_inQ25,
+                                       WebRtc_Word16 *filt_coefQ15,
+                                       WebRtc_Word32 *gain_lo_hiQ17,
+                                       WebRtc_Word16 lo_hi,
+                                       WebRtc_Word16 *lat_outQ0)
+{
+  int ii,n,k,i,u;
+  WebRtc_Word16 sthQ15[MAX_AR_MODEL_ORDER];
+  WebRtc_Word16 cthQ15[MAX_AR_MODEL_ORDER];
+  WebRtc_Word32 tmp32;
+
+
+  WebRtc_Word16 tmpAR;
+  WebRtc_Word16 ARfQ0vec[HALF_SUBFRAMELEN];
+  WebRtc_Word16 ARgQ0vec[MAX_AR_MODEL_ORDER+1];
+
+  WebRtc_Word32 inv_gain32;
+  WebRtc_Word16 inv_gain16;
+  WebRtc_Word16 den16;
+  WebRtc_Word16 sh;
+
+  WebRtc_Word16 temp2,temp3;
+  WebRtc_Word16 ord_1 = orderCoef+1;
+
+  for (u=0;u<SUBFRAMES;u++)
+  {
+    int32_t temp1 = WEBRTC_SPL_MUL_16_16(u, HALF_SUBFRAMELEN);
+
+    //set the denominator and numerator of the Direct Form
+    temp2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(u, orderCoef);
+    temp3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(2, u) + lo_hi;
+
+    for (ii=0; ii<orderCoef; ii++) {
+      sthQ15[ii] = filt_coefQ15[temp2+ii];
+    }
+
+    WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15);
+
+    /* Simulation of the 25 files shows that maximum value in
+       the vector gain_lo_hiQ17[] is 441344, which means that
+       it is log2((2^31)/441344) = 12.2 shifting bits from
+       saturation. Therefore, it should be safe to use Q27 instead
+       of Q17. */
+
+    tmp32 = WEBRTC_SPL_LSHIFT_W32(gain_lo_hiQ17[temp3], 10); // Q27
+
+    for (k=0;k<orderCoef;k++) {
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], tmp32); // Q15*Q27>>15 = Q27
+    }
+
+    sh = WebRtcSpl_NormW32(tmp32); // tmp32 is the gain
+    den16 = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32, sh-16); //Q(27+sh-16) = Q(sh+11) (all 16 bits are value bits)
+    inv_gain32 = WebRtcSpl_DivW32W16((WebRtc_Word32)2147483647, den16); // 1/gain in Q31/Q(sh+11) = Q(20-sh)
+
+    //initial conditions
+    inv_gain16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(inv_gain32, 2); // 1/gain in Q(20-sh-2) = Q(18-sh)
+
+    for (i=0;i<HALF_SUBFRAMELEN;i++)
+    {
+
+      tmp32 = WEBRTC_SPL_LSHIFT_W32(lat_inQ25[i + temp1], 1); //Q25->Q26
+      tmp32 = WEBRTC_SPL_MUL_16_32_RSFT16(inv_gain16, tmp32); //lat_in[]*inv_gain in (Q(18-sh)*Q26)>>16 = Q(28-sh)
+      tmp32 = WEBRTC_SPL_SHIFT_W32(tmp32, -(28-sh)); // lat_in[]*inv_gain in Q0
+
+      ARfQ0vec[i] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32); // Q0
+    }
+
+    for (i=orderCoef-1;i>=0;i--) //get the state of f&g for the first input, for all orders
+    {
+      tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cthQ15[i],ARfQ0vec[0])) - (WEBRTC_SPL_MUL_16_16(sthQ15[i],stateGQ0[i])) + 16384), 15);
+      tmpAR = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32); // Q0
+
+      tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sthQ15[i],ARfQ0vec[0])) + (WEBRTC_SPL_MUL_16_16(cthQ15[i], stateGQ0[i])) + 16384), 15);
+      ARgQ0vec[i+1] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32); // Q0
+      ARfQ0vec[0] = tmpAR;
+    }
+    ARgQ0vec[0] = ARfQ0vec[0];
+
+    // Filter ARgQ0vec[] and ARfQ0vec[] through coefficients cthQ15[] and sthQ15[].
+    WebRtcIsacfix_FilterArLoop(ARgQ0vec, ARfQ0vec, cthQ15, sthQ15, orderCoef);
+
+    for(n=0;n<HALF_SUBFRAMELEN;n++)
+    {
+      lat_outQ0[n + temp1] = ARfQ0vec[n];
+    }
+
+
+    /* cannot use memcpy in the following */
+
+    for (i=0;i<ord_1;i++)
+    {
+      stateGQ0[i] = ARgQ0vec[i];
+    }
+  }
+
+  return;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lattice_armv7.S b/src/modules/audio_coding/codecs/isac/fix/source/lattice_armv7.S
new file mode 100644
index 0000000..1cd3a76
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lattice_armv7.S
@@ -0,0 +1,82 @@
+@
+@ Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+@
+@ Use of this source code is governed by a BSD-style license
+@ that can be found in the LICENSE file in the root of the source
+@ tree. An additional intellectual property rights grant can be found
+@ in the file PATENTS.  All contributing project authors may
+@ be found in the AUTHORS file in the root of the source tree.
+@
+
+@ Contains a function for the core loop in the normalized lattice AR
+@ filter routine for iSAC codec, optimized for ARMv7 platforms.
+@
+@ Output is bit-exact with the reference C code in lattic_c.c
+@
+@ Register usage:
+@
+@ r0:  &ar_g_Q0
+@ r1:  &ar_f_Q0
+@ r2:  &cth_Q15
+@ r3:  &sth_Q15
+@ r4:  out loop counter
+@ r5:  tmpAR
+@ r9:  inner loop counter
+@ r12: constant #16384
+@ r6, r7, r8, r10, r11: scratch
+
+#include "settings.h"
+
+.arch armv7-a
+.global WebRtcIsacfix_FilterArLoop
+.align  2
+
+WebRtcIsacfix_FilterArLoop:
+.fnstart
+
+.save {r4-r11}
+  push    {r4-r11}
+
+  add     r1, #2                 @ &ar_f_Q0[1]
+  mov     r12, #16384
+  mov     r4, #HALF_SUBFRAMELEN
+  sub     r4, #1                 @ Outer loop counter = HALF_SUBFRAMELEN - 1
+
+HALF_SUBFRAME_LOOP:  @ for(n = 0; n < HALF_SUBFRAMELEN - 1; n++)
+
+  ldr     r9, [sp, #32]          @ Restore the inner loop counter to order_coef
+  ldrh    r5, [r1]               @ tmpAR = ar_f_Q0[n+1]
+  add     r0, r9, asl #1         @ Restore r0 to &ar_g_Q0[order_coef]
+  add     r2, r9, asl #1         @ Restore r2 to &cth_Q15[order_coef]
+  add     r3, r9, asl #1         @ Restore r3 to &sth_Q15[order_coef]
+
+ORDER_COEF_LOOP:  @ for(k = order_coef - 1 ; k >= 0; k--)
+
+  ldrh    r7, [r3, #-2]!         @ sth_Q15[k]
+  ldrh    r6, [r2, #-2]!         @ cth_Q15[k]
+
+  ldrh    r8, [r0, #-2]          @ ar_g_Q0[k]
+  smlabb  r11, r7, r5, r12       @ sth_Q15[k] * tmpAR + 16384
+  smlabb  r10, r6, r5, r12       @ cth_Q15[k] * tmpAR + 16384
+  smulbb  r7, r7, r8             @ sth_Q15[k] * ar_g_Q0[k]
+  smlabb  r11, r6, r8, r11       @ cth_Q15[k]*ar_g_Q0[k]+(sth_Q15[k]*tmpAR+16384)
+
+  sub     r10, r10, r7           @ cth_Q15[k]*tmpAR+16384-(sth_Q15[k]*ar_g_Q0[k])
+  ssat    r11, #16, r11, asr #15
+  ssat    r5, #16, r10, asr #15
+  strh    r11, [r0], #-2         @ Output: ar_g_Q0[k+1]
+
+  subs    r9, #1
+  bgt     ORDER_COEF_LOOP
+
+  strh    r5, [r0]               @ Output: ar_g_Q0[0] = tmpAR;
+  strh    r5, [r1], #2           @ Output: ar_f_Q0[n+1] = tmpAR;
+
+  subs    r4, #1
+  bne     HALF_SUBFRAME_LOOP
+
+  pop     {r4-r11}
+  bx      lr
+
+.fnend
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lattice_c.c b/src/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
new file mode 100644
index 0000000..80ccf39
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * Contains the core loop function for the lattice filter AR routine
+ * for iSAC codec.
+ *
+ */
+
+#include "settings.h"
+#include "signal_processing_library.h"
+#include "typedefs.h"
+
+/* Filter ar_g_Q0[] and ar_f_Q0[] through an AR filter with coefficients
+ * cth_Q15[] and sth_Q15[].
+ */
+void WebRtcIsacfix_FilterArLoop(int16_t* ar_g_Q0,     // Input samples
+                                int16_t* ar_f_Q0,     // Input samples
+                                int16_t* cth_Q15,     // Filter coefficients
+                                int16_t* sth_Q15,     // Filter coefficients
+                                int16_t order_coef) { // order of the filter
+  int n = 0;
+
+  for (n = 0; n < HALF_SUBFRAMELEN - 1; n++) {
+    int k = 0;
+    int16_t tmpAR = 0;
+    int32_t tmp32 = 0;
+    int32_t tmp32_2 = 0;
+
+    tmpAR = ar_f_Q0[n + 1];
+    for (k = order_coef - 1; k >= 0; k--) {
+      tmp32 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(cth_Q15[k], tmpAR))
+              - (WEBRTC_SPL_MUL_16_16(sth_Q15[k], ar_g_Q0[k])) + 16384), 15);
+      tmp32_2 = WEBRTC_SPL_RSHIFT_W32(((WEBRTC_SPL_MUL_16_16(sth_Q15[k], tmpAR))
+                + (WEBRTC_SPL_MUL_16_16(cth_Q15[k], ar_g_Q0[k])) + 16384), 15);
+      tmpAR   = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32);
+      ar_g_Q0[k + 1] = (WebRtc_Word16)WebRtcSpl_SatW32ToW16(tmp32_2);
+    }
+    ar_f_Q0[n + 1] = tmpAR;
+    ar_g_Q0[0] = tmpAR;
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lattice_neon.S b/src/modules/audio_coding/codecs/isac/fix/source/lattice_neon.S
new file mode 100644
index 0000000..a59b6e3
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lattice_neon.S
@@ -0,0 +1,155 @@
+@
+@ Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+@
+@ Use of this source code is governed by a BSD-style license
+@ that can be found in the LICENSE file in the root of the source
+@ tree. An additional intellectual property rights grant can be found
+@ in the file PATENTS.  All contributing project authors may
+@ be found in the AUTHORS file in the root of the source tree.
+@
+
+@ lattice_neon.s
+@
+@ Contains a function for the core loop in the normalized lattice MA 
+@ filter routine for iSAC codec, optimized for ARM Neon platform.
+@ void WebRtcIsacfix_FilterMaLoopNeon(int16_t input0,
+@                                     int16_t input1,
+@                                     int32_t input2,
+@                                     int32_t* ptr0,
+@                                     int32_t* ptr1,
+@                                     int32_t* __restrict ptr2);
+@ It calculates
+@   *ptr2 = input2 * (*ptr2) + input0 * (*ptr0));
+@   *ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
+@ in Q15 domain.
+@
+@ Reference code in lattice.c.
+@ Output is not bit-exact with the reference C code, due to the replacement
+@ of WEBRTC_SPL_MUL_16_32_RSFT15 and LATTICE_MUL_32_32_RSFT16 with Neon
+@ instructions, smulwb, and smull. Speech quality was not degraded by
+@ testing speech and tone vectors.
+
+.arch armv7-a
+.fpu neon
+
+#include "settings.h"
+
+.global WebRtcIsacfix_FilterMaLoopNeon
+
+.align  2
+
+WebRtcIsacfix_FilterMaLoopNeon:
+.fnstart
+
+.save {r4-r8}
+  push        {r4-r8}
+
+  vdup.32     d28, r0             @ Initialize Neon register with input0
+  vdup.32     d29, r1             @ Initialize Neon register with input1
+  vdup.32     d30, r2             @ Initialize Neon register with input2
+  ldr         r4, [sp, #20]       @ ptr1
+  ldr         r12, [sp, #24]      @ ptr2
+
+  @ Number of loop iterations after unrolling: r5 = (HALF_SUBFRAMELEN - 1) >> 2
+  @ Leftover samples after the loop, in r6:
+  @    r6 = (HALF_SUBFRAMELEN - 1) - (HALF_SUBFRAMELEN - 1) >> 2 << 2
+  mov         r6, #HALF_SUBFRAMELEN
+  sub         r6, #1
+  lsr         r5, r6, #2
+  sub         r6, r5, lsl #2
+
+  @ First r5 iterations in a loop.
+
+LOOP:
+  vld1.32     {d0, d1}, [r3]!     @ *ptr0
+
+  vmull.s32   q10, d0, d28        @ tmp32a = input0 * (*ptr0)
+  vmull.s32   q11, d1, d28        @ tmp32a = input0 * (*ptr0)
+  vmull.s32   q12, d0, d29        @ input1 * (*ptr0)
+  vmull.s32   q13, d1, d29        @ input1 * (*ptr0)
+                                  
+  vrshrn.i64  d4, q10, #15        
+  vrshrn.i64  d5, q11, #15        
+                                  
+  vld1.32     {d2, d3}, [r12]     @ *ptr2
+  vadd.i32    q3, q2, q1          @ tmp32b = *ptr2 + tmp32a
+                                  
+  vrshrn.i64  d0, q12, #15        
+                                  
+  vmull.s32   q10, d6, d30        @ input2 * (*ptr2 + tmp32b)
+  vmull.s32   q11, d7, d30        @ input2 * (*ptr2 + tmp32b)
+
+  vrshrn.i64  d16, q10, #16
+  vrshrn.i64  d17, q11, #16
+
+  vmull.s32   q10, d16, d28       @ input0 * (*ptr2)
+  vmull.s32   q11, d17, d28       @ input0 * (*ptr2)
+
+  vrshrn.i64  d1, q13, #15
+  vrshrn.i64  d18, q10, #15
+  vrshrn.i64  d19, q11, #15
+
+  vst1.32     {d16, d17}, [r12]!  @ *ptr2
+
+  vadd.i32    q9, q0, q9
+  subs        r5, #1
+  vst1.32     {d18, d19}, [r4]!   @ *ptr1
+
+  bgt         LOOP
+
+  @ Check how many samples still need to be processed.
+  subs        r6, #2
+  blt         LAST_SAMPLE
+
+  @ Process two more samples:
+  vld1.32     d0, [r3]!           @ *ptr0
+
+  vmull.s32   q11, d0, d28        @ tmp32a = input0 * (*ptr0)
+  vmull.s32   q13, d0, d29        @ input1 * (*ptr0)
+
+  vld1.32     d18, [r12]          @ *ptr2
+  vrshrn.i64  d4, q11, #15
+
+  vadd.i32    d7, d4, d18         @ tmp32b = *ptr2 + tmp32a
+  vmull.s32   q11, d7, d30        @ input2 * (*ptr2 + tmp32b)
+  vrshrn.i64  d16, q11, #16
+
+  vmull.s32   q11, d16, d28       @ input0 * (*ptr2)
+  vst1.32     d16, [r12]!         @ *ptr2
+
+  vrshrn.i64  d0, q13, #15
+  vrshrn.i64  d19, q11, #15
+  vadd.i32    d19, d0, d19
+
+  vst1.32     d19, [r4]!          @ *ptr1
+
+  @ If there's still one more sample, process it here.
+LAST_SAMPLE:
+  cmp         r6, #1
+  bne         END
+
+  @ *ptr2 = input2 * (*ptr2 + input0 * (*ptr0));
+  
+  ldr         r7, [r3]            @ *ptr0
+  ldr         r8, [r12]           @ *ptr2
+
+  smulwb      r5, r7, r0          @ tmp32a = *ptr0 * input0 >> 16
+  add         r8, r8, r5, lsl #1  @ tmp32b = *ptr2 + (tmp32a << 1)
+  smull       r5, r6, r8, r2      @ tmp32b * input2, in 64 bits
+  lsl         r6, #16
+  add         r6, r5, lsr #16     @ Only take the middle 32 bits
+  str         r6, [r12]           @ Output (*ptr2, as 32 bits)
+
+  @ *ptr1 = input1 * (*ptr0) + input0 * (*ptr2);
+
+  smulwb      r5, r7, r1          @ tmp32a = *ptr0 * input1 >> 16
+  smulwb      r6, r6, r0          @ tmp32b = *ptr2 * input0 >> 16
+  lsl         r5, r5, #1
+  add         r5, r6, lsl #1
+  str         r5, [r4]            @ Output (*ptr1)
+
+END:
+  pop         {r4-r8}
+  bx          lr
+
+.fnend
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c b/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c
new file mode 100644
index 0000000..4be438e
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.c
@@ -0,0 +1,957 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * lpc_masking_model.c
+ *
+ * LPC analysis and filtering functions
+ *
+ */
+
+#include "lpc_masking_model.h"
+
+#include <limits.h>  /* For LLONG_MAX and LLONG_MIN. */
+#include "codec.h"
+#include "entropy_coding.h"
+#include "settings.h"
+
+/* The conversion is implemented by the step-down algorithm */
+void WebRtcSpl_AToK_JSK(
+    WebRtc_Word16 *a16, /* Q11 */
+    WebRtc_Word16 useOrder,
+    WebRtc_Word16 *k16  /* Q15 */
+                        )
+{
+  int m, k;
+  WebRtc_Word32 tmp32[MAX_AR_MODEL_ORDER];
+  WebRtc_Word32 tmp32b;
+  WebRtc_Word32 tmp_inv_denum32;
+  WebRtc_Word16 tmp_inv_denum16;
+
+  k16[useOrder-1]= WEBRTC_SPL_LSHIFT_W16(a16[useOrder], 4); //Q11<<4 => Q15
+
+  for (m=useOrder-1; m>0; m--) {
+    tmp_inv_denum32 = ((WebRtc_Word32) 1073741823) - WEBRTC_SPL_MUL_16_16(k16[m], k16[m]); // (1 - k^2) in Q30
+    tmp_inv_denum16 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp_inv_denum32, 15); // (1 - k^2) in Q15
+
+    for (k=1; k<=m; k++) {
+      tmp32b = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)a16[k], 16) -
+          WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(k16[m], a16[m-k+1]), 1);
+
+      tmp32[k] = WebRtcSpl_DivW32W16(tmp32b, tmp_inv_denum16); //Q27/Q15 = Q12
+    }
+
+    for (k=1; k<m; k++) {
+      a16[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmp32[k], 1); //Q12>>1 => Q11
+    }
+
+    tmp32[m] = WEBRTC_SPL_SAT(4092, tmp32[m], -4092);
+    k16[m-1] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmp32[m], 3); //Q12<<3 => Q15
+  }
+
+  return;
+}
+
+
+
+
+
+WebRtc_Word16 WebRtcSpl_LevinsonW32_JSK(
+    WebRtc_Word32 *R,  /* (i) Autocorrelation of length >= order+1 */
+    WebRtc_Word16 *A,  /* (o) A[0..order] LPC coefficients (Q11) */
+    WebRtc_Word16 *K,  /* (o) K[0...order-1] Reflection coefficients (Q15) */
+    WebRtc_Word16 order /* (i) filter order */
+                                        ) {
+  WebRtc_Word16 i, j;
+  WebRtc_Word16 R_hi[LEVINSON_MAX_ORDER+1], R_low[LEVINSON_MAX_ORDER+1];
+  /* Aurocorr coefficients in high precision */
+  WebRtc_Word16 A_hi[LEVINSON_MAX_ORDER+1], A_low[LEVINSON_MAX_ORDER+1];
+  /* LPC coefficients in high precicion */
+  WebRtc_Word16 A_upd_hi[LEVINSON_MAX_ORDER+1], A_upd_low[LEVINSON_MAX_ORDER+1];
+  /* LPC coefficients for next iteration */
+  WebRtc_Word16 K_hi, K_low;      /* reflection coefficient in high precision */
+  WebRtc_Word16 Alpha_hi, Alpha_low, Alpha_exp; /* Prediction gain Alpha in high precision
+                                                   and with scale factor */
+  WebRtc_Word16 tmp_hi, tmp_low;
+  WebRtc_Word32 temp1W32, temp2W32, temp3W32;
+  WebRtc_Word16 norm;
+
+  /* Normalize the autocorrelation R[0]...R[order+1] */
+
+  norm = WebRtcSpl_NormW32(R[0]);
+
+  for (i=order;i>=0;i--) {
+    temp1W32 = WEBRTC_SPL_LSHIFT_W32(R[i], norm);
+    /* Put R in hi and low format */
+    R_hi[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+    R_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16)), 1);
+  }
+
+  /* K = A[1] = -R[1] / R[0] */
+
+  temp2W32  = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[1],16) +
+      WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[1],1);     /* R[1] in Q31      */
+  temp3W32  = WEBRTC_SPL_ABS_W32(temp2W32);      /* abs R[1]         */
+  temp1W32  = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); /* abs(R[1])/R[0] in Q31 */
+  /* Put back the sign on R[1] */
+  if (temp2W32 > 0) {
+    temp1W32 = -temp1W32;
+  }
+
+  /* Put K in hi and low format */
+  K_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+  K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);
+
+  /* Store first reflection coefficient */
+  K[0] = K_hi;
+
+  temp1W32 = WEBRTC_SPL_RSHIFT_W32(temp1W32, 4);    /* A[1] in Q27      */
+
+  /* Put A[1] in hi and low format */
+  A_hi[1] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+  A_low[1] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[1], 16)), 1);
+
+  /*  Alpha = R[0] * (1-K^2) */
+
+  temp1W32  = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, K_low), 14) +
+                                      WEBRTC_SPL_MUL_16_16(K_hi, K_hi)), 1); /* temp1W32 = k^2 in Q31 */
+
+  temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32);    /* Guard against <0 */
+  temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32;    /* temp1W32 = (1 - K[0]*K[0]) in Q31 */
+
+  /* Store temp1W32 = 1 - K[0]*K[0] on hi and low format */
+  tmp_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+  tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
+
+  /* Calculate Alpha in Q31 */
+  temp1W32 = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_hi) +
+                                     WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[0], tmp_low), 15) +
+                                     WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_low[0], tmp_hi), 15) ), 1);
+
+  /* Normalize Alpha and put it in hi and low format */
+
+  Alpha_exp = WebRtcSpl_NormW32(temp1W32);
+  temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp);
+  Alpha_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+  Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);
+
+  /* Perform the iterative calculations in the
+     Levinson Durbin algorithm */
+
+  for (i=2; i<=order; i++)
+  {
+
+    /*                    ----
+                          \
+                          temp1W32 =  R[i] + > R[j]*A[i-j]
+                          /
+                          ----
+                          j=1..i-1
+    */
+
+    temp1W32 = 0;
+
+    for(j=1; j<i; j++) {
+      /* temp1W32 is in Q31 */
+      temp1W32 += (WEBRTC_SPL_LSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[j], A_hi[i-j]), 1) +
+                   WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_hi[j], A_low[i-j]), 15) +
+                                            WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(R_low[j], A_hi[i-j]), 15) ), 1));
+    }
+
+    temp1W32  = WEBRTC_SPL_LSHIFT_W32(temp1W32, 4);
+    temp1W32 += (WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_hi[i], 16) +
+                 WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)R_low[i], 1));
+
+    /* K = -temp1W32 / Alpha */
+    temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32);      /* abs(temp1W32) */
+    temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); /* abs(temp1W32)/Alpha */
+
+    /* Put the sign of temp1W32 back again */
+    if (temp1W32 > 0) {
+      temp3W32 = -temp3W32;
+    }
+
+    /* Use the Alpha shifts from earlier to denormalize */
+    norm = WebRtcSpl_NormW32(temp3W32);
+    if ((Alpha_exp <= norm)||(temp3W32==0)) {
+      temp3W32 = WEBRTC_SPL_LSHIFT_W32(temp3W32, Alpha_exp);
+    } else {
+      if (temp3W32 > 0)
+      {
+        temp3W32 = (WebRtc_Word32)0x7fffffffL;
+      } else
+      {
+        temp3W32 = (WebRtc_Word32)0x80000000L;
+      }
+    }
+
+    /* Put K on hi and low format */
+    K_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
+    K_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)K_hi, 16)), 1);
+
+    /* Store Reflection coefficient in Q15 */
+    K[i-1] = K_hi;
+
+    /* Test for unstable filter. If unstable return 0 and let the
+       user decide what to do in that case
+    */
+
+    if ((WebRtc_Word32)WEBRTC_SPL_ABS_W16(K_hi) > (WebRtc_Word32)32740) {
+      return(-i); /* Unstable filter */
+    }
+
+    /*
+      Compute updated LPC coefficient: Anew[i]
+      Anew[j]= A[j] + K*A[i-j]   for j=1..i-1
+      Anew[i]= K
+    */
+
+    for(j=1; j<i; j++)
+    {
+      temp1W32  = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[j],16) +
+          WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[j],1);    /* temp1W32 = A[j] in Q27 */
+
+      temp1W32 += WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_MUL_16_16(K_hi, A_hi[i-j]) +
+                                           WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, A_low[i-j]), 15) +
+                                           WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_low, A_hi[i-j]), 15) ), 1); /* temp1W32 += K*A[i-j] in Q27 */
+
+      /* Put Anew in hi and low format */
+      A_upd_hi[j] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+      A_upd_low[j] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[j], 16)), 1);
+    }
+
+    temp3W32 = WEBRTC_SPL_RSHIFT_W32(temp3W32, 4);     /* temp3W32 = K in Q27 (Convert from Q31 to Q27) */
+
+    /* Store Anew in hi and low format */
+    A_upd_hi[i] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp3W32, 16);
+    A_upd_low[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp3W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_upd_hi[i], 16)), 1);
+
+    /*  Alpha = Alpha * (1-K^2) */
+
+    temp1W32  = WEBRTC_SPL_LSHIFT_W32((WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(K_hi, K_low), 14) +
+                                        WEBRTC_SPL_MUL_16_16(K_hi, K_hi)), 1);  /* K*K in Q31 */
+
+    temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32);      /* Guard against <0 */
+    temp1W32 = (WebRtc_Word32)0x7fffffffL - temp1W32;      /* 1 - K*K  in Q31 */
+
+    /* Convert 1- K^2 in hi and low format */
+    tmp_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+    tmp_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)tmp_hi, 16)), 1);
+
+    /* Calculate Alpha = Alpha * (1-K^2) in Q31 */
+    temp1W32 = WEBRTC_SPL_LSHIFT_W32(( WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_hi) +
+                                        WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(Alpha_hi, tmp_low), 15) +
+                                        WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(Alpha_low, tmp_hi), 15)), 1);
+
+    /* Normalize Alpha and store it on hi and low format */
+
+    norm = WebRtcSpl_NormW32(temp1W32);
+    temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm);
+
+    Alpha_hi = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(temp1W32, 16);
+    Alpha_low = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((temp1W32 - WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)Alpha_hi, 16)), 1);
+
+    /* Update the total nomalization of Alpha */
+    Alpha_exp = Alpha_exp + norm;
+
+    /* Update A[] */
+
+    for(j=1; j<=i; j++)
+    {
+      A_hi[j] =A_upd_hi[j];
+      A_low[j] =A_upd_low[j];
+    }
+  }
+
+  /*
+    Set A[0] to 1.0 and store the A[i] i=1...order in Q12
+    (Convert from Q27 and use rounding)
+  */
+
+  A[0] = 2048;
+
+  for(i=1; i<=order; i++) {
+    /* temp1W32 in Q27 */
+    temp1W32 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_hi[i], 16) +
+        WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)A_low[i], 1);
+    /* Round and store upper word */
+    A[i] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(temp1W32+(WebRtc_Word32)32768, 16);
+  }
+  return(1); /* Stable filters */
+}
+
+
+
+
+
+/* window */
+/* Matlab generation of floating point code:
+ *  t = (1:256)/257; r = 1-(1-t).^.45; w = sin(r*pi).^3; w = w/sum(w); plot((1:256)/8, w); grid;
+ *  for k=1:16, fprintf(1, '%.8f, ', w(k*16 + (-15:0))); fprintf(1, '\n'); end
+ * All values are multiplyed with 2^21 in fixed point code.
+ */
+static const WebRtc_Word16 kWindowAutocorr[WINLEN] = {
+  0,     0,     0,     0,     0,     1,     1,     2,     2,     3,     5,     6,
+  8,    10,    12,    14,    17,    20,    24,    28,    33,    38,    43,    49,
+  56,    63,    71,    79,    88,    98,   108,   119,   131,   143,   157,   171,
+  186,   202,   219,   237,   256,   275,   296,   318,   341,   365,   390,   416,
+  444,   472,   502,   533,   566,   600,   635,   671,   709,   748,   789,   831,
+  875,   920,   967,  1015,  1065,  1116,  1170,  1224,  1281,  1339,  1399,  1461,
+  1525,  1590,  1657,  1726,  1797,  1870,  1945,  2021,  2100,  2181,  2263,  2348,
+  2434,  2523,  2614,  2706,  2801,  2898,  2997,  3099,  3202,  3307,  3415,  3525,
+  3637,  3751,  3867,  3986,  4106,  4229,  4354,  4481,  4611,  4742,  4876,  5012,
+  5150,  5291,  5433,  5578,  5725,  5874,  6025,  6178,  6333,  6490,  6650,  6811,
+  6974,  7140,  7307,  7476,  7647,  7820,  7995,  8171,  8349,  8529,  8711,  8894,
+  9079,  9265,  9453,  9642,  9833, 10024, 10217, 10412, 10607, 10803, 11000, 11199,
+  11398, 11597, 11797, 11998, 12200, 12401, 12603, 12805, 13008, 13210, 13412, 13614,
+  13815, 14016, 14216, 14416, 14615, 14813, 15009, 15205, 15399, 15591, 15782, 15971,
+  16157, 16342, 16524, 16704, 16881, 17056, 17227, 17395, 17559, 17720, 17877, 18030,
+  18179, 18323, 18462, 18597, 18727, 18851, 18970, 19082, 19189, 19290, 19384, 19471,
+  19551, 19623, 19689, 19746, 19795, 19835, 19867, 19890, 19904, 19908, 19902, 19886,
+  19860, 19823, 19775, 19715, 19644, 19561, 19465, 19357, 19237, 19102, 18955, 18793,
+  18618, 18428, 18223, 18004, 17769, 17518, 17252, 16970, 16672, 16357, 16025, 15677,
+  15311, 14929, 14529, 14111, 13677, 13225, 12755, 12268, 11764, 11243, 10706, 10152,
+  9583,  8998,  8399,  7787,  7162,  6527,  5883,  5231,  4576,  3919,  3265,  2620,
+  1990,  1386,   825,   333
+};
+
+
+/* By using a hearing threshold level in dB of -28 dB (higher value gives more noise),
+   the H_T_H (in float) can be calculated as:
+   H_T_H = pow(10.0, 0.05 * (-28.0)) = 0.039810717055350
+   In Q19, H_T_H becomes round(0.039810717055350*2^19) ~= 20872, i.e.
+   H_T_H = 20872/524288.0, and H_T_HQ19 = 20872;
+*/
+
+
+/* The bandwidth expansion vectors are created from:
+   kPolyVecLo=[0.900000,0.810000,0.729000,0.656100,0.590490,0.531441,0.478297,0.430467,0.387420,0.348678,0.313811,0.282430];
+   kPolyVecHi=[0.800000,0.640000,0.512000,0.409600,0.327680,0.262144];
+   round(kPolyVecLo*32768)
+   round(kPolyVecHi*32768)
+*/
+static const WebRtc_Word16 kPolyVecLo[12] = {
+  29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425, 10283, 9255
+};
+static const WebRtc_Word16 kPolyVecHi[6] = {
+  26214, 20972, 16777, 13422, 10737, 8590
+};
+
+static __inline WebRtc_Word32 log2_Q8_LPC( WebRtc_UWord32 x ) {
+
+  WebRtc_Word32 zeros, lg2;
+  WebRtc_Word16 frac;
+
+  zeros=WebRtcSpl_NormU32(x);
+  frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)WEBRTC_SPL_LSHIFT_W32(x, zeros)&0x7FFFFFFF), 23);
+
+  /* log2(x) */
+
+  lg2= (WEBRTC_SPL_LSHIFT_W16((31-zeros), 8)+frac);
+  return lg2;
+
+}
+
+static const WebRtc_Word16 kMulPitchGain = -25; /* 200/256 in Q5 */
+static const WebRtc_Word16 kChngFactor = 3523; /* log10(2)*10/4*0.4/1.4=log10(2)/1.4= 0.2150 in Q14 */
+static const WebRtc_Word16 kExp2 = 11819; /* 1/log(2) */
+const int kShiftLowerBand = 11;  /* Shift value for lower band in Q domain. */
+const int kShiftHigherBand = 12;  /* Shift value for higher band in Q domain. */
+
+void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input, const WebRtc_Word16 *pitchGains_Q12,
+                           WebRtc_UWord32 *oldEnergy, WebRtc_Word16 *varscale)
+{
+  int k;
+  WebRtc_UWord32 nrgQ[4];
+  WebRtc_Word16 nrgQlog[4];
+  WebRtc_Word16 tmp16, chng1, chng2, chng3, chng4, tmp, chngQ, oldNrgQlog, pgQ, pg3;
+  WebRtc_Word32 expPg32;
+  WebRtc_Word16 expPg, divVal;
+  WebRtc_Word16 tmp16_1, tmp16_2;
+
+  /* Calculate energies of first and second frame halfs */
+  nrgQ[0]=0;
+  for (k = QLOOKAHEAD/2; k < (FRAMESAMPLES/4 + QLOOKAHEAD) / 2; k++) {
+    nrgQ[0] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
+  }
+  nrgQ[1]=0;
+  for ( ; k < (FRAMESAMPLES/2 + QLOOKAHEAD) / 2; k++) {
+    nrgQ[1] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
+  }
+  nrgQ[2]=0;
+  for ( ; k < (WEBRTC_SPL_MUL_16_16(FRAMESAMPLES, 3)/4 + QLOOKAHEAD) / 2; k++) {
+    nrgQ[2] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
+  }
+  nrgQ[3]=0;
+  for ( ; k < (FRAMESAMPLES + QLOOKAHEAD) / 2; k++) {
+    nrgQ[3] +=WEBRTC_SPL_MUL_16_16(input[k],input[k]);
+  }
+
+  for ( k=0; k<4; k++) {
+    nrgQlog[k] = (WebRtc_Word16)log2_Q8_LPC(nrgQ[k]); /* log2(nrgQ) */
+  }
+  oldNrgQlog = (WebRtc_Word16)log2_Q8_LPC(*oldEnergy);
+
+  /* Calculate average level change */
+  chng1 = WEBRTC_SPL_ABS_W16(nrgQlog[3]-nrgQlog[2]);
+  chng2 = WEBRTC_SPL_ABS_W16(nrgQlog[2]-nrgQlog[1]);
+  chng3 = WEBRTC_SPL_ABS_W16(nrgQlog[1]-nrgQlog[0]);
+  chng4 = WEBRTC_SPL_ABS_W16(nrgQlog[0]-oldNrgQlog);
+  tmp = chng1+chng2+chng3+chng4;
+  chngQ = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp, kChngFactor, 10); /* Q12 */
+  chngQ += 2926; /* + 1.0/1.4 in Q12 */
+
+  /* Find average pitch gain */
+  pgQ = 0;
+  for (k=0; k<4; k++)
+  {
+    pgQ += pitchGains_Q12[k];
+  }
+
+  pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pgQ, pgQ,11); /* pgQ in Q(12+2)=Q14. Q14*Q14>>11 => Q17 */
+  pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pgQ, pg3,13); /* Q17*Q14>>13 =>Q18  */
+  pg3 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(pg3, kMulPitchGain ,5); /* Q10  kMulPitchGain = -25 = -200 in Q-3. */
+
+  tmp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2,pg3,13);/* Q13*Q10>>13 => Q10*/
+  if (tmp16<0) {
+    tmp16_2 = (0x0400 | (tmp16 & 0x03FF));
+    tmp16_1 = (WEBRTC_SPL_RSHIFT_W16((WebRtc_UWord16)(tmp16 ^ 0xFFFF), 10)-3); /* Gives result in Q14 */
+    if (tmp16_1<0)
+      expPg=(WebRtc_Word16) -WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
+    else
+      expPg=(WebRtc_Word16) -WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
+  } else
+    expPg = (WebRtc_Word16) -16384; /* 1 in Q14, since 2^0=1 */
+
+  expPg32 = (WebRtc_Word32)WEBRTC_SPL_LSHIFT_W16((WebRtc_Word32)expPg, 8); /* Q22 */
+  divVal = WebRtcSpl_DivW32W16ResW16(expPg32, chngQ); /* Q22/Q12=Q10 */
+
+  tmp16=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(kExp2,divVal,13);/* Q13*Q10>>13 => Q10*/
+  if (tmp16<0) {
+    tmp16_2 = (0x0400 | (tmp16 & 0x03FF));
+    tmp16_1 = (WEBRTC_SPL_RSHIFT_W16((WebRtc_UWord16)(tmp16 ^ 0xFFFF), 10)-3); /* Gives result in Q14 */
+    if (tmp16_1<0)
+      expPg=(WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
+    else
+      expPg=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
+  } else
+    expPg = (WebRtc_Word16) 16384; /* 1 in Q14, since 2^0=1 */
+
+  *varscale = expPg-1;
+  *oldEnergy = nrgQ[3];
+}
+
+
+
+static __inline WebRtc_Word16  exp2_Q10_T(WebRtc_Word16 x) { // Both in and out in Q10
+
+  WebRtc_Word16 tmp16_1, tmp16_2;
+
+  tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF));
+  tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10);
+  if(tmp16_1>0)
+    return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
+  else
+    return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
+
+}
+
+
+// Declare function pointers.
+AutocorrFix WebRtcIsacfix_AutocorrFix;
+CalculateResidualEnergy WebRtcIsacfix_CalculateResidualEnergy;
+
+/* This routine calculates the residual energy for LPC.
+ * Formula as shown in comments inside.
+ */
+int32_t WebRtcIsacfix_CalculateResidualEnergyC(int lpc_order,
+                                               int32_t q_val_corr,
+                                               int q_val_polynomial,
+                                               int16_t* a_polynomial,
+                                               int32_t* corr_coeffs,
+                                               int* q_val_residual_energy) {
+  int i = 0, j = 0;
+  int shift_internal = 0, shift_norm = 0;
+  int32_t tmp32 = 0, word32_high = 0, word32_low = 0, residual_energy = 0;
+  int64_t sum64 = 0, sum64_tmp = 0;
+
+  for (i = 0; i <= lpc_order; i++) {
+    for (j = i; j <= lpc_order; j++) {
+      /* For the case of i == 0: residual_energy +=
+       *    a_polynomial[j] * corr_coeffs[i] * a_polynomial[j - i];
+       * For the case of i != 0: residual_energy +=
+       *    a_polynomial[j] * corr_coeffs[i] * a_polynomial[j - i] * 2;
+       */
+
+      tmp32 = WEBRTC_SPL_MUL_16_16(a_polynomial[j], a_polynomial[j - i]);
+                                   /* tmp32 in Q(q_val_polynomial * 2). */
+      if (i != 0) {
+        tmp32 <<= 1;
+      }
+      sum64_tmp = (int64_t)tmp32 * (int64_t)corr_coeffs[i];
+      sum64_tmp >>= shift_internal;
+
+      /* Test overflow and sum the result. */
+      if(((sum64_tmp > 0 && sum64 > 0) && (LLONG_MAX - sum64 < sum64_tmp)) ||
+         ((sum64_tmp < 0 && sum64 < 0) && (LLONG_MIN - sum64 > sum64_tmp))) {
+        /* Shift right for overflow. */
+        shift_internal += 1;
+        sum64 >>= 1;
+        sum64 += sum64_tmp >> 1;
+      } else {
+        sum64 += sum64_tmp;
+      }
+    }
+  }
+
+  word32_high = (int32_t)(sum64 >> 32);
+  word32_low = (int32_t)sum64;
+
+  // Calculate the value of shifting (shift_norm) for the 64-bit sum.
+  if(word32_high != 0) {
+    shift_norm = 32 - WebRtcSpl_NormW32(word32_high);
+    residual_energy = (int32_t)(sum64 >> shift_norm);
+  } else {
+    if((word32_low & 0x80000000) != 0) {
+      shift_norm = 1;
+      residual_energy = (uint32_t)word32_low >> 1;
+    } else {
+      shift_norm = WebRtcSpl_NormW32(word32_low);
+      residual_energy = word32_low << shift_norm;
+      shift_norm = -shift_norm;
+    }
+  }
+
+  /* Q(q_val_polynomial * 2) * Q(q_val_corr) >> shift_internal >> shift_norm
+   *   = Q(q_val_corr - shift_internal - shift_norm + q_val_polynomial * 2)
+   */
+  *q_val_residual_energy = q_val_corr - shift_internal - shift_norm
+                           + q_val_polynomial * 2;
+
+  return residual_energy;
+}
+
+void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0,
+                              WebRtc_Word16 *inHiQ0,
+                              MaskFiltstr_enc *maskdata,
+                              WebRtc_Word16 snrQ10,
+                              const WebRtc_Word16 *pitchGains_Q12,
+                              WebRtc_Word32 *gain_lo_hiQ17,
+                              WebRtc_Word16 *lo_coeffQ15,
+                              WebRtc_Word16 *hi_coeffQ15)
+{
+  int k, n, ii;
+  int pos1, pos2;
+  int sh_lo, sh_hi, sh, ssh, shMem;
+  WebRtc_Word16 varscaleQ14;
+
+  WebRtc_Word16 tmpQQlo, tmpQQhi;
+  WebRtc_Word32 tmp32;
+  WebRtc_Word16 tmp16,tmp16b;
+
+  WebRtc_Word16 polyHI[ORDERHI+1];
+  WebRtc_Word16 rcQ15_lo[ORDERLO], rcQ15_hi[ORDERHI];
+
+
+  WebRtc_Word16 DataLoQ6[WINLEN], DataHiQ6[WINLEN];
+  WebRtc_Word32 corrloQQ[ORDERLO+2];
+  WebRtc_Word32 corrhiQQ[ORDERHI+1];
+  WebRtc_Word32 corrlo2QQ[ORDERLO+1];
+  WebRtc_Word16 scale;
+  WebRtc_Word16 QdomLO, QdomHI, newQdomHI, newQdomLO;
+
+  WebRtc_Word32 res_nrgQQ;
+  WebRtc_Word32 sqrt_nrg;
+
+  /* less-noise-at-low-frequencies factor */
+  WebRtc_Word16 aaQ14;
+
+  /* Multiplication with 1/sqrt(12) ~= 0.28901734104046 can be done by convertion to
+     Q15, i.e. round(0.28901734104046*32768) = 9471, and use 9471/32768.0 ~= 0.289032
+  */
+  WebRtc_Word16 snrq;
+  int shft;
+
+  WebRtc_Word16 tmp16a;
+  WebRtc_Word32 tmp32a, tmp32b, tmp32c;
+
+  WebRtc_Word16 a_LOQ11[ORDERLO+1];
+  WebRtc_Word16 k_vecloQ15[ORDERLO];
+  WebRtc_Word16 a_HIQ12[ORDERHI+1];
+  WebRtc_Word16 k_vechiQ15[ORDERHI];
+
+  WebRtc_Word16 stab;
+
+  snrq=snrQ10;
+
+  /* SNR= C * 2 ^ (D * snrq) ; C=0.289, D=0.05*log2(10)=0.166 (~=172 in Q10)*/
+  tmp16 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(snrq, 172, 10); // Q10
+  tmp16b = exp2_Q10_T(tmp16); // Q10
+  snrq = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(tmp16b, 285, 10); // Q10
+
+  /* change quallevel depending on pitch gains and level fluctuations */
+  WebRtcIsacfix_GetVars(inLoQ0, pitchGains_Q12, &(maskdata->OldEnergy), &varscaleQ14);
+
+  /* less-noise-at-low-frequencies factor */
+  /* Calculation of 0.35 * (0.5 + 0.5 * varscale) in fixpoint:
+     With 0.35 in Q16 (0.35 ~= 22938/65536.0 = 0.3500061) and varscaleQ14 in Q14,
+     we get Q16*Q14>>16 = Q14
+  */
+  aaQ14 = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(
+      (WEBRTC_SPL_MUL_16_16(22938, (8192 + WEBRTC_SPL_RSHIFT_W32(varscaleQ14, 1)))
+       + ((WebRtc_Word32)32768)), 16);
+
+  /* Calculate tmp = (1.0 + aa*aa); in Q12 */
+  tmp16 = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(aaQ14, aaQ14, 15); //Q14*Q14>>15 = Q13
+  tmpQQlo = 4096 + WEBRTC_SPL_RSHIFT_W16(tmp16, 1); // Q12 + Q13>>1 = Q12
+
+  /* Calculate tmp = (1.0+aa) * (1.0+aa); */
+  tmp16 = 8192 + WEBRTC_SPL_RSHIFT_W16(aaQ14, 1); // 1+a in Q13
+  tmpQQhi = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 14); //Q13*Q13>>14 = Q12
+
+  /* replace data in buffer by new look-ahead data */
+  for (pos1 = 0; pos1 < QLOOKAHEAD; pos1++) {
+    maskdata->DataBufferLoQ0[pos1 + WINLEN - QLOOKAHEAD] = inLoQ0[pos1];
+  }
+
+  for (k = 0; k < SUBFRAMES; k++) {
+
+    /* Update input buffer and multiply signal with window */
+    for (pos1 = 0; pos1 < WINLEN - UPDATE/2; pos1++) {
+      maskdata->DataBufferLoQ0[pos1] = maskdata->DataBufferLoQ0[pos1 + UPDATE/2];
+      maskdata->DataBufferHiQ0[pos1] = maskdata->DataBufferHiQ0[pos1 + UPDATE/2];
+      DataLoQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(
+          maskdata->DataBufferLoQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6
+      DataHiQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(
+          maskdata->DataBufferHiQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6
+    }
+    pos2 = (WebRtc_Word16)(WEBRTC_SPL_MUL_16_16(k, UPDATE)/2);
+    for (n = 0; n < UPDATE/2; n++, pos1++) {
+      maskdata->DataBufferLoQ0[pos1] = inLoQ0[QLOOKAHEAD + pos2];
+      maskdata->DataBufferHiQ0[pos1] = inHiQ0[pos2++];
+      DataLoQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(
+          maskdata->DataBufferLoQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6
+      DataHiQ6[pos1] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT(
+          maskdata->DataBufferHiQ0[pos1], kWindowAutocorr[pos1], 15); // Q0*Q21>>15 = Q6
+    }
+
+    /* Get correlation coefficients */
+    /* The highest absolute value measured inside DataLo in the test set
+       For DataHi, corresponding value was 160.
+
+       This means that it should be possible to represent the input values
+       to WebRtcSpl_AutoCorrelation() as Q6 values (since 307*2^6 =
+       19648). Of course, Q0 will also work, but due to the low energy in
+       DataLo and DataHi, the outputted autocorrelation will be more accurate
+       and mimic the floating point code better, by being in an high as possible
+       Q-domain.
+    */
+
+    WebRtcIsacfix_AutocorrFix(corrloQQ,DataLoQ6,WINLEN, ORDERLO+1, &scale);
+    QdomLO = 12-scale; // QdomLO is the Q-domain of corrloQQ
+    sh_lo = WebRtcSpl_NormW32(corrloQQ[0]);
+    QdomLO += sh_lo;
+    for (ii=0; ii<ORDERLO+2; ii++) {
+      corrloQQ[ii] = WEBRTC_SPL_LSHIFT_W32(corrloQQ[ii], sh_lo);
+    }
+    /* It is investigated whether it was possible to use 16 bits for the
+       32-bit vector corrloQQ, but it didn't work. */
+
+    WebRtcIsacfix_AutocorrFix(corrhiQQ,DataHiQ6,WINLEN, ORDERHI, &scale);
+
+    QdomHI = 12-scale; // QdomHI is the Q-domain of corrhiQQ
+    sh_hi = WebRtcSpl_NormW32(corrhiQQ[0]);
+    QdomHI += sh_hi;
+    for (ii=0; ii<ORDERHI+1; ii++) {
+      corrhiQQ[ii] = WEBRTC_SPL_LSHIFT_W32(corrhiQQ[ii], sh_hi);
+    }
+
+    /* less noise for lower frequencies, by filtering/scaling autocorrelation sequences */
+
+    /* Calculate corrlo2[0] = tmpQQlo * corrlo[0] - 2.0*tmpQQlo * corrlo[1];*/
+    corrlo2QQ[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[0]), 1)- // Q(12+QdomLO-16)>>1 = Q(QdomLO-5)
+        WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, corrloQQ[1]), 2); // 2*Q(14+QdomLO-16)>>3 = Q(QdomLO-2)>>2 = Q(QdomLO-5)
+
+    /* Calculate corrlo2[n] = tmpQQlo * corrlo[n] - tmpQQlo * (corrlo[n-1] + corrlo[n+1]);*/
+    for (n = 1; n <= ORDERLO; n++) {
+
+      tmp32 = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n-1], 1) + WEBRTC_SPL_RSHIFT_W32(corrloQQ[n+1], 1); // Q(QdomLO-1)
+      corrlo2QQ[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQlo, corrloQQ[n]), 1)- // Q(12+QdomLO-16)>>1 = Q(QdomLO-5)
+          WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(aaQ14, tmp32), 2); // Q(14+QdomLO-1-16)>>2 = Q(QdomLO-3)>>2 = Q(QdomLO-5)
+
+    }
+    QdomLO -= 5;
+
+    /* Calculate corrhi[n] = tmpQQhi * corrhi[n]; */
+    for (n = 0; n <= ORDERHI; n++) {
+      corrhiQQ[n] = WEBRTC_SPL_MUL_16_32_RSFT16(tmpQQhi, corrhiQQ[n]); // Q(12+QdomHI-16) = Q(QdomHI-4)
+    }
+    QdomHI -= 4;
+
+    /* add white noise floor */
+    /* corrlo2QQ is in Q(QdomLO) and corrhiQQ is in Q(QdomHI) */
+    /* Calculate corrlo2[0] += 9.5367431640625e-7; and
+       corrhi[0]  += 9.5367431640625e-7, where the constant is 1/2^20 */
+
+    tmp32 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32) 1, QdomLO-20);
+    corrlo2QQ[0] += tmp32;
+    tmp32 = WEBRTC_SPL_SHIFT_W32((WebRtc_Word32) 1, QdomHI-20);
+    corrhiQQ[0]  += tmp32;
+
+    /* corrlo2QQ is in Q(QdomLO) and corrhiQQ is in Q(QdomHI) before the following
+       code segment, where we want to make sure we get a 1-bit margin */
+    for (n = 0; n <= ORDERLO; n++) {
+      corrlo2QQ[n] = WEBRTC_SPL_RSHIFT_W32(corrlo2QQ[n], 1); // Make sure we have a 1-bit margin
+    }
+    QdomLO -= 1; // Now, corrlo2QQ is in Q(QdomLO), with a 1-bit margin
+
+    for (n = 0; n <= ORDERHI; n++) {
+      corrhiQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], 1); // Make sure we have a 1-bit margin
+    }
+    QdomHI -= 1; // Now, corrhiQQ is in Q(QdomHI), with a 1-bit margin
+
+
+    newQdomLO = QdomLO;
+
+    for (n = 0; n <= ORDERLO; n++) {
+      WebRtc_Word32 tmp, tmpB, tmpCorr;
+      WebRtc_Word16 alpha=328; //0.01 in Q15
+      WebRtc_Word16 beta=324; //(1-0.01)*0.01=0.0099 in Q15
+      WebRtc_Word16 gamma=32440; //(1-0.01)=0.99 in Q15
+
+      if (maskdata->CorrBufLoQQ[n] != 0) {
+        shMem=WebRtcSpl_NormW32(maskdata->CorrBufLoQQ[n]);
+        sh = QdomLO - maskdata->CorrBufLoQdom[n];
+        if (sh<=shMem) {
+          tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufLoQQ[n], sh); // Get CorrBufLoQQ to same domain as corrlo2
+          tmp = WEBRTC_SPL_MUL_16_32_RSFT15(alpha, tmp);
+        } else if ((sh-shMem)<7){
+          tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufLoQQ[n], shMem); // Shift up CorrBufLoQQ as much as possible
+          tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, (sh-shMem)), tmp); // Shift alpha the number of times required to get tmp in QdomLO
+        } else {
+          tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufLoQQ[n], shMem); // Shift up CorrBufHiQQ as much as possible
+          tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, 6), tmp); // Shift alpha as much as possible without overflow the number of times required to get tmp in QdomHI
+          tmpCorr = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n], sh-shMem-6);
+          tmp = tmp + tmpCorr;
+          maskdata->CorrBufLoQQ[n] = tmp;
+          newQdomLO = QdomLO-(sh-shMem-6);
+          maskdata->CorrBufLoQdom[n] = newQdomLO;
+        }
+      } else
+        tmp = 0;
+
+      tmp = tmp + corrlo2QQ[n];
+
+      maskdata->CorrBufLoQQ[n] = tmp;
+      maskdata->CorrBufLoQdom[n] = QdomLO;
+
+      tmp=WEBRTC_SPL_MUL_16_32_RSFT15(beta, tmp);
+      tmpB=WEBRTC_SPL_MUL_16_32_RSFT15(gamma, corrlo2QQ[n]);
+      corrlo2QQ[n] = tmp + tmpB;
+    }
+    if( newQdomLO!=QdomLO) {
+      for (n = 0; n <= ORDERLO; n++) {
+        if (maskdata->CorrBufLoQdom[n] != newQdomLO)
+          corrloQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrloQQ[n], maskdata->CorrBufLoQdom[n]-newQdomLO);
+      }
+      QdomLO = newQdomLO;
+    }
+
+
+    newQdomHI = QdomHI;
+
+    for (n = 0; n <= ORDERHI; n++) {
+      WebRtc_Word32 tmp, tmpB, tmpCorr;
+      WebRtc_Word16 alpha=328; //0.01 in Q15
+      WebRtc_Word16 beta=324; //(1-0.01)*0.01=0.0099 in Q15
+      WebRtc_Word16 gamma=32440; //(1-0.01)=0.99 in Q1
+      if (maskdata->CorrBufHiQQ[n] != 0) {
+        shMem=WebRtcSpl_NormW32(maskdata->CorrBufHiQQ[n]);
+        sh = QdomHI - maskdata->CorrBufHiQdom[n];
+        if (sh<=shMem) {
+          tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufHiQQ[n], sh); // Get CorrBufHiQQ to same domain as corrhi
+          tmp = WEBRTC_SPL_MUL_16_32_RSFT15(alpha, tmp);
+          tmpCorr = corrhiQQ[n];
+          tmp = tmp + tmpCorr;
+          maskdata->CorrBufHiQQ[n] = tmp;
+          maskdata->CorrBufHiQdom[n] = QdomHI;
+        } else if ((sh-shMem)<7) {
+          tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufHiQQ[n], shMem); // Shift up CorrBufHiQQ as much as possible
+          tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, (sh-shMem)), tmp); // Shift alpha the number of times required to get tmp in QdomHI
+          tmpCorr = corrhiQQ[n];
+          tmp = tmp + tmpCorr;
+          maskdata->CorrBufHiQQ[n] = tmp;
+          maskdata->CorrBufHiQdom[n] = QdomHI;
+        } else {
+          tmp = WEBRTC_SPL_SHIFT_W32(maskdata->CorrBufHiQQ[n], shMem); // Shift up CorrBufHiQQ as much as possible
+          tmp = WEBRTC_SPL_MUL_16_32_RSFT15(WEBRTC_SPL_LSHIFT_W16(alpha, 6), tmp); // Shift alpha as much as possible without overflow the number of times required to get tmp in QdomHI
+          tmpCorr = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], sh-shMem-6);
+          tmp = tmp + tmpCorr;
+          maskdata->CorrBufHiQQ[n] = tmp;
+          newQdomHI = QdomHI-(sh-shMem-6);
+          maskdata->CorrBufHiQdom[n] = newQdomHI;
+        }
+      } else {
+        tmp = corrhiQQ[n];
+        tmpCorr = tmp;
+        maskdata->CorrBufHiQQ[n] = tmp;
+        maskdata->CorrBufHiQdom[n] = QdomHI;
+      }
+
+      tmp=WEBRTC_SPL_MUL_16_32_RSFT15(beta, tmp);
+      tmpB=WEBRTC_SPL_MUL_16_32_RSFT15(gamma, tmpCorr);
+      corrhiQQ[n] = tmp + tmpB;
+    }
+
+    if( newQdomHI!=QdomHI) {
+      for (n = 0; n <= ORDERHI; n++) {
+        if (maskdata->CorrBufHiQdom[n] != newQdomHI)
+          corrhiQQ[n] = WEBRTC_SPL_RSHIFT_W32(corrhiQQ[n], maskdata->CorrBufHiQdom[n]-newQdomHI);
+      }
+      QdomHI = newQdomHI;
+    }
+
+    stab=WebRtcSpl_LevinsonW32_JSK(corrlo2QQ, a_LOQ11, k_vecloQ15, ORDERLO);
+
+    if (stab<0) {  // If unstable use lower order
+      a_LOQ11[0]=2048;
+      for (n = 1; n <= ORDERLO; n++) {
+        a_LOQ11[n]=0;
+      }
+
+      stab=WebRtcSpl_LevinsonW32_JSK(corrlo2QQ, a_LOQ11, k_vecloQ15, 8);
+    }
+
+
+    WebRtcSpl_LevinsonDurbin(corrhiQQ,  a_HIQ12,  k_vechiQ15, ORDERHI);
+
+    /* bandwidth expansion */
+    for (n = 1; n <= ORDERLO; n++) {
+      a_LOQ11[n] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(kPolyVecLo[n-1], a_LOQ11[n]);
+    }
+
+
+    polyHI[0] = a_HIQ12[0];
+    for (n = 1; n <= ORDERHI; n++) {
+      a_HIQ12[n] = (WebRtc_Word16) WEBRTC_SPL_MUL_16_16_RSFT_WITH_FIXROUND(kPolyVecHi[n-1], a_HIQ12[n]);
+      polyHI[n] = a_HIQ12[n];
+    }
+
+    /* Normalize the corrlo2 vector */
+    sh = WebRtcSpl_NormW32(corrlo2QQ[0]);
+    for (n = 0; n <= ORDERLO; n++) {
+      corrlo2QQ[n] = WEBRTC_SPL_LSHIFT_W32(corrlo2QQ[n], sh);
+    }
+    QdomLO += sh; /* Now, corrlo2QQ is still in Q(QdomLO) */
+
+
+    /* residual energy */
+
+    sh_lo = 31;
+    res_nrgQQ = WebRtcIsacfix_CalculateResidualEnergy(ORDERLO, QdomLO,
+        kShiftLowerBand, a_LOQ11, corrlo2QQ, &sh_lo);
+
+    /* Convert to reflection coefficients */
+    WebRtcSpl_AToK_JSK(a_LOQ11, ORDERLO, rcQ15_lo);
+
+    if (sh_lo & 0x0001) {
+      res_nrgQQ=WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1);
+      sh_lo-=1;
+    }
+
+
+    if( res_nrgQQ > 0 )
+    {
+      sqrt_nrg=WebRtcSpl_Sqrt(res_nrgQQ);
+
+      /* add hearing threshold and compute the gain */
+      /* lo_coeff = varscale * S_N_R / (sqrt_nrg + varscale * H_T_H); */
+
+
+      //tmp32a=WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, H_T_HQ19, 17);  // Q14
+      tmp32a=WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) varscaleQ14,1);  // H_T_HQ19=65536 (16-17=-1)   ssh= WEBRTC_SPL_RSHIFT_W16(sh_lo, 1);  // sqrt_nrg is in Qssh
+      ssh= WEBRTC_SPL_RSHIFT_W16(sh_lo, 1);  // sqrt_nrg is in Qssh
+      sh = ssh - 14;
+      tmp32b = WEBRTC_SPL_SHIFT_W32(tmp32a, sh); // Q14->Qssh
+      tmp32c = sqrt_nrg + tmp32b;  // Qssh  (denominator)
+      tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, snrq, 0);  //Q24 (numerator)
+
+      sh = WebRtcSpl_NormW32(tmp32c);
+      shft = 16 - sh;
+      tmp16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32c, -shft); // Q(ssh-shft)  (denominator)
+
+      tmp32b = WebRtcSpl_DivW32W16(tmp32a, tmp16a); // Q(24-ssh+shft)
+      sh = ssh-shft-7;
+      *gain_lo_hiQ17 = WEBRTC_SPL_SHIFT_W32(tmp32b, sh);  // Gains in Q17
+    }
+    else
+    {
+      *gain_lo_hiQ17 = 100; //(WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 17);  // Gains in Q17
+    }
+    gain_lo_hiQ17++;
+
+    /* copy coefficients to output array */
+    for (n = 0; n < ORDERLO; n++) {
+      *lo_coeffQ15 = (WebRtc_Word16) (rcQ15_lo[n]);
+      lo_coeffQ15++;
+    }
+    /* residual energy */
+    sh_hi = 31;
+    res_nrgQQ = WebRtcIsacfix_CalculateResidualEnergy(ORDERHI, QdomHI,
+        kShiftHigherBand, a_HIQ12, corrhiQQ, &sh_hi);
+
+    /* Convert to reflection coefficients */
+    WebRtcSpl_LpcToReflCoef(polyHI, ORDERHI, rcQ15_hi);
+
+    if (sh_hi & 0x0001) {
+      res_nrgQQ=WEBRTC_SPL_RSHIFT_W32(res_nrgQQ, 1);
+      sh_hi-=1;
+    }
+
+
+    if( res_nrgQQ > 0 )
+    {
+      sqrt_nrg=WebRtcSpl_Sqrt(res_nrgQQ);
+
+
+      /* add hearing threshold and compute the gain */
+      /* hi_coeff = varscale * S_N_R / (sqrt_nrg + varscale * H_T_H); */
+
+      //tmp32a=WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, H_T_HQ19, 17);  // Q14
+      tmp32a=WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) varscaleQ14,1);  // H_T_HQ19=65536 (16-17=-1)
+
+      ssh= WEBRTC_SPL_RSHIFT_W32(sh_hi, 1);  // sqrt_nrg is in Qssh
+      sh = ssh - 14;
+      tmp32b = WEBRTC_SPL_SHIFT_W32(tmp32a, sh); // Q14->Qssh
+      tmp32c = sqrt_nrg + tmp32b;  // Qssh  (denominator)
+      tmp32a = WEBRTC_SPL_MUL_16_16_RSFT(varscaleQ14, snrq, 0);  //Q24 (numerator)
+
+      sh = WebRtcSpl_NormW32(tmp32c);
+      shft = 16 - sh;
+      tmp16a = (WebRtc_Word16) WEBRTC_SPL_SHIFT_W32(tmp32c, -shft); // Q(ssh-shft)  (denominator)
+
+      tmp32b = WebRtcSpl_DivW32W16(tmp32a, tmp16a); // Q(24-ssh+shft)
+      sh = ssh-shft-7;
+      *gain_lo_hiQ17 = WEBRTC_SPL_SHIFT_W32(tmp32b, sh);  // Gains in Q17
+    }
+    else
+    {
+      *gain_lo_hiQ17 = 100; //(WebRtc_Word32)WEBRTC_SPL_LSHIFT_W32( (WebRtc_Word32)1, 17);  // Gains in Q17
+    }
+    gain_lo_hiQ17++;
+
+
+    /* copy coefficients to output array */
+    for (n = 0; n < ORDERHI; n++) {
+      *hi_coeffQ15 = rcQ15_hi[n];
+      hi_coeffQ15++;
+    }
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h b/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h
new file mode 100644
index 0000000..e06a207
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * lpc_masking_model.h
+ *
+ * LPC functions
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "structs.h"
+
+void WebRtcIsacfix_GetVars(const WebRtc_Word16 *input,
+                           const WebRtc_Word16 *pitchGains_Q12,
+                           WebRtc_UWord32 *oldEnergy,
+                           WebRtc_Word16 *varscale);
+
+void WebRtcIsacfix_GetLpcCoef(WebRtc_Word16 *inLoQ0,
+                              WebRtc_Word16 *inHiQ0,
+                              MaskFiltstr_enc *maskdata,
+                              WebRtc_Word16 snrQ10,
+                              const WebRtc_Word16 *pitchGains_Q12,
+                              WebRtc_Word32 *gain_lo_hiQ17,
+                              WebRtc_Word16 *lo_coeffQ15,
+                              WebRtc_Word16 *hi_coeffQ15);
+
+typedef int32_t (*CalculateResidualEnergy)(int lpc_order,
+                                           int32_t q_val_corr,
+                                           int q_val_polynomial,
+                                           int16_t* a_polynomial,
+                                           int32_t* corr_coeffs,
+                                           int* q_val_residual_energy);
+extern CalculateResidualEnergy WebRtcIsacfix_CalculateResidualEnergy;
+
+int32_t WebRtcIsacfix_CalculateResidualEnergyC(int lpc_order,
+                                               int32_t q_val_corr,
+                                               int q_val_polynomial,
+                                               int16_t* a_polynomial,
+                                               int32_t* corr_coeffs,
+                                               int* q_val_residual_energy);
+
+#if (defined WEBRTC_DETECT_ARM_NEON) || (defined WEBRTC_ARCH_ARM_NEON)
+int32_t WebRtcIsacfix_CalculateResidualEnergyNeon(int lpc_order,
+                                                  int32_t q_val_corr,
+                                                  int q_val_polynomial,
+                                                  int16_t* a_polynomial,
+                                                  int32_t* corr_coeffs,
+                                                  int* q_val_residual_energy);
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_MASKING_MODEL_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_neon.S b/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_neon.S
new file mode 100644
index 0000000..20b60d0
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_neon.S
@@ -0,0 +1,177 @@
+@
+@ Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+@
+@ Use of this source code is governed by a BSD-style license
+@ that can be found in the LICENSE file in the root of the source
+@ tree. An additional intellectual property rights grant can be found
+@ in the file PATENTS.  All contributing project authors may
+@ be found in the AUTHORS file in the root of the source tree.
+@
+
+@ Contains a function for WebRtcIsacfix_CalculateResidualEnergyNeon() in
+@ iSAC codec, optimized for ARM Neon platform. Reference code in
+@ lpc_masking_model.c.
+
+.arch armv7-a
+.fpu neon
+.global WebRtcIsacfix_CalculateResidualEnergyNeon
+.align  2
+
+@ int32_t WebRtcIsacfix_CalculateResidualEnergyNeon(int lpc_order,
+@                                                   int32_t q_val_corr,
+@                                                   int q_val_polynomial,
+@                                                   int16_t* a_polynomial,
+@                                                   int32_t* corr_coeffs,
+@                                                   int* q_val_residual_energy);
+
+WebRtcIsacfix_CalculateResidualEnergyNeon:
+.fnstart
+.save {r4-r11}
+  push {r4-r11}
+
+  sub r13, r13, #16
+  str r1, [r13, #8]
+  str r2, [r13, #12]
+
+  mov r4, #1
+  vmov.s64 q11, #0            @ Initialize shift_internal.
+  vmov.s64 q13, #0            @ Initialize sum64.
+  vmov.s64 q10, #0
+  vmov.u8 d20[0], r4          @ Set q10 to 1.
+
+  cmp r0, #0
+  blt POST_LOOP_I
+
+  add r9, r3, r0, asl #1      @ &a_polynomial[lpc_order]
+  mov r6, #0                  @ Loop counter i.
+  ldr r11, [r13, #48]
+  sub r10, r0, #1
+  mov r7, r3                  @ &a_polynomial[0]
+  str r9, [r13, #4]
+
+LOOP_I:
+  ldr r2, [r11], #4            @ corr_coeffs[i]
+  vmov.s64 q15, #0            @ Initialize the sum64_tmp.
+  vdup.s32 d25, r2
+
+  cmp r0, r6                  @ Compare lpc_order to i.
+  movle r2, r6
+  ble POST_LOOP_J
+
+  mov r1, r6                  @ j = i;
+  mov r12, r7                  @ &a_polynomial[i]
+  mov r4, r3                  @ &a_polynomial[j - i]
+
+LOOP_J:
+  ldr r8, [r12], #4
+  ldr r5, [r4], #4
+  vmov.u32 d0[0], r8
+  vmov.u32 d1[0], r5
+  vmull.s16 q0, d0, d1
+  vmull.s32 q0, d0, d25
+  cmp r6, #0                  @ i == 0?
+  vshl.s64 q0, q11
+  beq SUM1
+  vshl.s64 q0, #1
+
+SUM1:
+  vqadd.s64 q14, q0, q15      @ Sum and test overflow.
+  add r1, r1, #2
+  bvc MOV1                    @ Skip the shift if there's no overflow.
+  vshr.s64 q0, #1
+  vshr.s64 q15, #1
+  vadd.s64 q14, q0, q15
+  vsub.s64 q11, q10
+
+MOV1:
+  cmp r0, r1                  @ Compare lpc_order to j.
+  vmov.s64 q15, q14
+  bgt LOOP_J
+
+  bic r1, r10, #1
+  add r2, r6, #2
+  add r2, r1, r2
+
+POST_LOOP_J:
+  vqadd.s64 q0, q13, q15      @ Sum and test overflow.
+  bvc MOV2                    @ Skip the shift if there's no overflow.
+  vshr.s64 q13, #1
+  vshr.s64 q15, #1
+  vadd.s64 q0, q13, q15
+  vsub.s64 q11, q10
+
+MOV2:
+  vmov.s64 q13, q0            @ update sum64.
+  cmp r2, r0
+  bne CHECK_LOOP_CONDITION
+
+  @ Last sample in the inner loop.
+  ldr r4, [r13, #4]
+  ldrsh r8, [r4]
+  ldrsh r12, [r9]
+  mul r8, r8, r12
+  vmov.s32 d0[0], r8
+  vmull.s32 q0, d0, d25
+  cmp r6, #0                  @ i == 0?
+  vshl.s64 q0, q11
+  beq SUM2
+  vshl.s64 q0, #1
+
+SUM2:
+  vqadd.s64 d1, d0, d26       @ Sum and test overflow.
+  bvc MOV3                    @ Skip the shift if there's no overflow.
+  vshr.s64 q13, #1
+  vshr.s64 d0, #1
+  vadd.s64 d1, d0, d26
+  vsub.s64 q11, q10
+
+MOV3:
+  vmov.s64 d26, d1            @ update sum64.
+
+CHECK_LOOP_CONDITION:
+  add r6, r6, #1
+  sub r9, r9, #2
+  cmp r0, r6                  @ Compare i to lpc_order.
+  sub r10, r10, #1
+  add r7, r7, #2
+  bge LOOP_I
+
+POST_LOOP_I:
+  mov r3, #0
+  vqadd.s64 d0, d26, d27      @ Sum and test overflow.
+  bvc GET_SHIFT_NORM          @ Skip the shift if there's no overflow.
+  vshr.s64 q13, #1
+  vadd.s64 d0, d26, d27
+  vsub.s64 q11, q10
+
+GET_SHIFT_NORM:
+  vcls.s32 d1, d0             @ Count leading extra sign bits.
+  vmov.32 r2, d1[1]           @ Store # of sign bits of only the 32 MSBs.
+  vmovl.s32 q1, d1
+  vshl.s64 d0, d3             @ d3 contains # of sign bits of the 32 MSBs.
+
+  vcls.s32 d1, d0             @ Count again the leading extra sign bits.
+  vmov.s32 r1, d1[1]          @ Store # of sign bits of only the 32 MSBs.
+  vmovl.s32 q1, d1
+  vshl.s64 d0, d3             @ d3 contains # of sign bits of the 32 MSBs.
+
+  vmov.s32 r0, d0[1]          @ residual_energy
+  vmov.s32 r3, d22[0]         @ shift_internal
+
+  @ Calculate the value for q_val_residual_energy.
+  ldr r4, [r13, #8]            @ q_val_corr
+  ldr r5, [r13, #12]           @ q_val_polynomial
+  sub r12, r4, #32
+  add r12, r12, r5, asl #1
+  add r1, r12, r1              @ add 1st part of shift_internal.
+  add r12, r1, r2              @ add 2nd part of shift_internal.
+  ldr r2, [r13, #52]
+  add r3, r12, r3              @ value for q_val_residual_energy.
+  str r3, [r2, #0]
+
+  add r13, r13, #16
+  pop {r4-r11}
+  bx  r14
+
+.fnend
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lpc_tables.c b/src/modules/audio_coding/codecs/isac/fix/source/lpc_tables.c
new file mode 100644
index 0000000..90cc9af
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lpc_tables.c
@@ -0,0 +1,1280 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * lpc_tables.c
+ *
+ * Coding tables for the KLT coefficients
+ *
+ */
+
+
+#include "settings.h"
+#include "lpc_tables.h"
+
+/* indices of KLT coefficients used */
+const WebRtc_UWord16 WebRtcIsacfix_kSelIndGain[12] = {
+  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+  10,  11};
+
+const WebRtc_UWord16 WebRtcIsacfix_kSelIndShape[108] = {
+  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
+  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
+  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
+  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
+  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
+  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
+  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
+  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
+  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
+  100,  101,  102,  103,  104,  105,  106,  107
+};
+
+/* cdf array for model indicator */
+const WebRtc_UWord16 WebRtcIsacfix_kModelCdf[4] = {
+  0,  15434,  37548,  65535
+};
+
+/* pointer to cdf array for model indicator */
+const WebRtc_UWord16 *WebRtcIsacfix_kModelCdfPtr[1] = {
+  WebRtcIsacfix_kModelCdf
+};
+
+/* initial cdf index for decoder of model indicator */
+const WebRtc_UWord16 WebRtcIsacfix_kModelInitIndex[1] = {
+  1
+};
+
+/* offset to go from rounded value to quantization index */
+const WebRtc_Word16 WebRtcIsacfix_kQuantMinGain[12] ={
+  3,  6,  4,  6,  6,  9,  5,  16,  11,  34,  32,  47
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kQuantMinShape[108] = {
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
+  1,  1,  1,  1,  2,  2,  2,  3,  0,  0,
+  0,  0,  1,  0,  0,  0,  0,  1,  1,  1,
+  1,  1,  1,  2,  2,  3,  0,  0,  0,  0,
+  1,  0,  1,  1,  1,  1,  1,  1,  1,  2,
+  2,  4,  3,  5,  0,  0,  0,  0,  1,  1,
+  1,  1,  1,  1,  2,  1,  2,  2,  3,  4,
+  4,  7,  0,  0,  1,  1,  1,  1,  1,  1,
+  1,  2,  3,  2,  3,  4,  4,  5,  7,  13,
+  0,  1,  1,  2,  3,  2,  2,  2,  4,  4,
+  5,  6,  7,  11, 9, 13, 12, 26
+};
+
+/* maximum quantization index */
+const WebRtc_UWord16 WebRtcIsacfix_kMaxIndGain[12] = {
+  6,  12,  8,  14,  10,  19,  12,  31,  22,  56,  52,  138
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kMaxIndShape[108] = {
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
+  2,  2,  2,  2,  4,  4,  5,  6,  0,  0,
+  0,  0,  1,  0,  0,  0,  0,  1,  2,  2,
+  2,  2,  3,  4,  5,  7,  0,  0,  0,  0,
+  2,  0,  2,  2,  2,  2,  3,  2,  2,  4,
+  4,  6,  6,  9,  0,  0,  0,  0,  2,  2,
+  2,  2,  2,  2,  3,  2,  4,  4,  7,  7,
+  9,  13, 0,  0,  2,  2,  2,  2,  2,  2,
+  3,  4,  5,  4,  6,  8,  8, 10, 16, 25,
+  0,  2,  2,  4,  5,  4,  4,  4,  7,  8,
+  9, 10, 13, 19, 17, 23, 25, 49
+};
+
+/* index offset */
+const WebRtc_UWord16 WebRtcIsacfix_kOffsetGain[3][12] = {
+  { 0,  7,  20,  29,  44,  55,  75,  88,  120,  143,  200,  253},
+  { 0,  7,  19,  27,  42,  53,  73,  86,  117,  140,  197,  249},
+  { 0,  7,  20,  28,  44,  55,  75,  89,  121,  145,  202,  257}
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kOffsetShape[3][108] = {
+  {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+    11,  14,  17,  20,  23,  28,  33,  39,  46,  47,
+    48,  49,  50,  52,  53,  54,  55,  56,  58,  61,
+    64,  67,  70,  74,  79,  85,  93,  94,  95,  96,
+    97,  100,  101,  104,  107,  110,  113,  117,  120,  123,
+    128,  133,  140,  147,  157,  158,  159,  160,  161,  164,
+    167,  170,  173,  176,  179,  183,  186,  191,  196,  204,
+    212,  222,  236,  237,  238,  241,  244,  247,  250,  253,
+    256,  260,  265,  271,  276,  283,  292,  301,  312,  329,
+    355,  356,  359,  362,  367,  373,  378,  383,  388,  396,
+    405,  415,  426,  440,  460,  478,  502,  528
+  },
+  {
+    0,  1,  2,  3,  4,  6,  7,  8,  9,  11,
+    13,  16,  19,  22,  26,  29,  34,  39,  45,  46,
+    47,  48,  49,  50,  51,  52,  53,  55,  57,  60,
+    63,  66,  70,  73,  78,  84,  91,  92,  93,  94,
+    95,  96,  97,  99,  102,  105,  108,  111,  114,  118,
+    123,  128,  134,  141,  151,  152,  153,  154,  156,  159,
+    162,  165,  168,  171,  174,  177,  181,  186,  194,  200,
+    208,  218,  233,  234,  235,  236,  239,  242,  245,  248,
+    251,  254,  258,  263,  270,  277,  288,  297,  308,  324,
+    349,  351,  354,  357,  361,  366,  372,  378,  383,  390,
+    398,  407,  420,  431,  450,  472,  496,  524
+  },
+  {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  11,
+    14,  17,  20,  23,  26,  29,  34,  40,  47,  48,
+    49,  50,  51,  52,  53,  54,  55,  58,  61,  64,
+    67,  70,  73,  77,  82,  88,  96,  97,  98,  99,
+    101,  102,  104,  107,  110,  113,  116,  119,  122,  125,
+    129,  134,  141,  150,  160,  161,  162,  163,  166,  168,
+    171,  174,  177,  180,  183,  186,  190,  195,  201,  208,
+    216,  226,  243,  244,  245,  248,  251,  254,  257,  260,
+    263,  268,  273,  278,  284,  291,  299,  310,  323,  340,
+    366,  368,  371,  374,  379,  383,  389,  394,  399,  406,
+    414,  422,  433,  445,  461,  480,  505,  533
+  }
+};
+
+/* initial cdf index for KLT coefficients */
+const WebRtc_UWord16 WebRtcIsacfix_kInitIndexGain[3][12] = {
+  { 3,  6,  4,  7,  5,  10,  6,  16,  11,  28,  26,  69},
+  { 3,  6,  4,  7,  5,  10,  6,  15,  11,  28,  26,  69},
+  { 3,  6,  4,  8,  5,  10,  7,  16,  12,  28,  27,  70}
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kInitIndexShape[3][108] = {
+  {
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
+    1,  1,  1,  1,  2,  2,  3,  3,  0,  0,
+    0,  0,  1,  0,  0,  0,  0,  1,  1,  1,
+    1,  1,  2,  2,  3,  4,  0,  0,  0,  0,
+    1,  0,  1,  1,  1,  1,  2,  1,  1,  2,
+    2,  3,  3,  5,  0,  0,  0,  0,  1,  1,
+    1,  1,  1,  1,  2,  1,  2,  2,  4,  4,
+    5,  7,  0,  0,  1,  1,  1,  1,  1,  1,
+    2,  2,  3,  2,  3,  4,  4,  5,  8,  13,
+    0,  1,  1,  2,  3,  2,  2,  2,  4,  4,
+    5,  5,  7,  10,  9,  12,  13,  25
+  },
+  {
+    0,  0,  0,  0,  1,  0,  0,  0,  1,  1,
+    1,  1,  1,  2,  1,  2,  2,  3,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
+    1,  2,  1,  2,  3,  3,  0,  0,  0,  0,
+    0,  0,  1,  1,  1,  1,  1,  1,  2,  2,
+    2,  3,  3,  5,  0,  0,  0,  1,  1,  1,
+    1,  1,  1,  1,  1,  2,  2,  4,  3,  4,
+    5,  7,  0,  0,  0,  1,  1,  1,  1,  1,
+    1,  2,  2,  3,  3,  5,  4,  5,  8,  12,
+    1,  1,  1,  2,  2,  3,  3,  2,  3,  4,
+    4,  6,  5,  9,  11,  12,  14,  25
+  },
+  {
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  1,
+    1,  1,  1,  1,  1,  2,  3,  3,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
+    1,  1,  2,  2,  3,  4,  0,  0,  0,  1,
+    0,  1,  1,  1,  1,  1,  1,  1,  1,  2,
+    2,  3,  4,  5,  0,  0,  0,  1,  1,  1,
+    1,  1,  1,  1,  1,  2,  2,  3,  3,  4,
+    5,  8,  0,  0,  1,  1,  1,  1,  1,  1,
+    2,  2,  2,  3,  3,  4,  5,  6,  8,  13,
+    1,  1,  1,  2,  2,  3,  2,  2,  3,  4,
+    4,  5,  6,  8,  9,  12,  14,  25
+  }
+};
+
+/* offsets for quantizer representation levels*/
+const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsGain[3] = {
+  0,  392,  779
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsShape[3] = {
+  0,  578,  1152
+};
+
+/* quantizer representation levels */
+
+
+
+const WebRtc_Word32 WebRtcIsacfix_kLevelsGainQ17[1176] = {
+  -364547,-231664,-102123,-573,104807,238257,368823,-758583,-640135,-510291
+  ,-377662,-252785,-113177,2627,112906,248601,389461,522691,644517,763974
+  ,-538963,-368179,-245823,-106095,-890,104299,241111,350730,493190,-800763
+  ,-646230,-510239,-382115,-248623,-111829,-2983,113852,251105,388114,519757
+  ,644048,774712,896334,1057931,-770009,-635310,-503690,-375087,-248106,-108525
+  ,-105,108259,243472,377948,519271,-1160885,-1032044,-914636,-777593,-647891
+  ,-518408,-388028,-254321,-115293,-598,117849,251296,385367,515510,652727
+  ,777432,920363,1038625,1153637,1316836,-632287,-505430,-379430,-248458,-118013
+  ,-888,118762,250266,381650,513327,652169,766471,932113,-2107480,-1971030
+  ,-1827020,-1698263,-1558670,-1436314,-1305377,-1172252,-1047355,-914202,-779651,-651001
+  ,-520999,-390394,-255761,-123490,-1893,126839,256703,385493,518607,651760
+  ,782750,908693,1044131,1163865,1311066,1424177,1582628,1709823,1831740,1955391
+  ,-1423044,-1288917,-1181281,-1043222,-911770,-780354,-646799,-522664,-386721,-258266
+  ,-128060,-1101,128233,259996,390336,519590,649290,778701,908010,1040796
+  ,1161235,1306889,1441882,-4446002,-4301031,-4194304,-4080591,-3947740,-3808975,-3686530
+  ,-3567839,-3383251,-3287089,-3136577,-3017405,-2869860,-2751321,-2619984,-2482932,-2354790
+  ,-2223147,-2090669,-1964135,-1831208,-1706697,-1570817,-1446008,-1305386,-1175773,-1046066
+  ,-915356,-785120,-653614,-524331,-393767,-260442,-130187,-799,128841,261466
+  ,393616,520542,652117,784613,914159,1045399,1181072,1308971,1442502,1570346
+  ,1693912,1843986,1966014,2090474,2224869,2364593,2475934,2628403,2752512,2856640
+  ,-4192441,-4063232,-3917821,-3799195,-3666233,-3519199,-3411021,-3269192,-3135684,-3008826
+  ,-2880875,-2747342,-2620981,-2494872,-2354979,-2229718,-2098939,-1964971,-1835399,-1703452
+  ,-1572806,-1440482,-1311794,-1179338,-1046521,-919823,-785914,-655335,-523416,-395507
+  ,-264833,-132184,-2546,131698,256217,391372,522688,651248,789964,909618
+  ,1035305,1179145,1313824,1436934,1552353,1693722,1815508,1972826,2096328,2228224
+  ,2359296,2490368,2598848,-6160384,-6029312,-5881382,-5767168,-5636096,-5505024,-5373952
+  ,-5228418,-5110384,-4954923,-4880576,-4710990,-4587364,-4471340,-4333905,-4211513,-4051293
+  ,-3907927,-3800105,-3675961,-3538640,-3413663,-3271148,-3152105,-3019103,-2869647,-2744015
+  ,-2620639,-2479385,-2364211,-2227611,-2095427,-1974497,-1834168,-1703561,-1568961,-1439826
+  ,-1309192,-1174050,-1050191,-917836,-786015,-656943,-518934,-394831,-257708,-128041
+  ,1610,128991,264442,393977,521383,653849,788164,918641,1049122,1181971
+  ,1308934,1439505,1571808,1706305,1836318,1966235,2097269,2228990,2357005,2490292
+  ,2617400,2749680,2881234,3014880,3145637,3276467,3409099,3536637,3671493,3802918
+  ,3929740,4065036,4194143,4325999,4456126,4586857,4717194,4843923,4978676,5110913
+  ,5245281,5371394,5499780,5633779,5762611,5897682,6028688,6167546,6296465,6421682
+  ,6548882,6682074,6809432,6941956,7078143,7204509,7334296,7475137,7609896,7732044
+  ,7861604,8002039,8131670,8259222,8390299,8522399,8650037,8782348,8908402,9037815
+  ,9164594,9300338,9434679,9574500,9699702,9833934,9948152,10083972,10244937,10332822
+  ,10485760,10600122,10760754,10892964,11010048,11111004,11272192,11403264,11525091,11624984
+  ,11796480,11915146,-393216,-262144,-101702,-740,100568,262144,393216,-786432
+  ,-655360,-524288,-383907,-243301,-94956,-156,95547,269629,416691,524288
+  ,655360,-393216,-262144,-88448,-37,87318,262144,393216,524288,-917504
+  ,-786432,-655360,-495894,-373308,-267503,-93211,4119,91308,250895,393216
+  ,526138,655360,786432,917504,-786432,-655360,-524288,-393216,-262144,-83497
+  ,222,86893,240922,393216,524288,-1048576,-917504,-790472,-655360,-508639
+  ,-383609,-262016,-95550,-3775,96692,256797,364847,534906,655360,786432
+  ,889679,1048576,1179648,1310720,1441792,-655360,-524288,-377684,-248408,-93690
+  ,1261,95441,227519,393216,524288,655360,786432,917504,-2097152,-1966080
+  ,-1809470,-1703936,-1572864,-1441792,-1314289,-1195149,-1056205,-917504,-809951,-657769
+  ,-521072,-383788,-248747,-106350,-2944,105550,243408,388548,521064,628732
+  ,786432,885456,1064548,1179648,1310720,1441792,1572864,1703936,1835008,-1441792
+  ,-1310720,-1179648,-1037570,-888492,-767774,-646634,-519935,-373458,-248029,-111915
+  ,760,111232,247735,379432,507672,672699,786432,917504,1048576,1179648
+  ,1310720,1441792,-4456448,-4325376,-4194304,-4063232,-3932160,-3801088,-3670016,-3538944
+  ,-3407872,-3276800,-3145728,-3014656,-2883584,-2752512,-2647002,-2490368,-2359296,-2228224
+  ,-2097152,-1951753,-1835008,-1703936,-1594177,-1462001,-1289150,-1160774,-1025917,-924928
+  ,-782509,-641294,-516191,-386630,-251910,-118886,5210,121226,253949,386008
+  ,517973,649374,780064,917783,1052462,1183856,1290593,1419389,1556641,1699884
+  ,1835008,1988314,2090470,2228224,2359296,2490368,2621440,2752512,2883584,-3801088
+  ,-3643514,-3539937,-3409931,-3263294,-3145658,-3012952,-2879230,-2752359,-2622556,-2483471
+  ,-2357556,-2226500,-2093112,-1965892,-1833664,-1701035,-1567767,-1440320,-1310556,-1178339
+  ,-1049625,-916812,-786477,-655277,-525050,-393773,-264828,-130696,-480,132126
+  ,260116,394197,527846,652294,785563,917183,1049511,1175958,1308161,1438759
+  ,1572253,1698835,1828535,1967072,2089391,2212798,2348901,2461547,2621440,2752512
+  ,2883584,-7309870,-7203780,-7062699,-6939106,-6790819,-6672036,-6553600,-6422317,-6288422
+  ,-6164694,-6026456,-5901410,-5754168,-5621459,-5502710,-5369686,-5240454,-5120712,-4976140
+  ,-4847970,-4723070,-4589083,-4450923,-4324680,-4189892,-4065551,-3931803,-3800209,-3668539
+  ,-3539395,-3404801,-3277470,-3141389,-3016710,-2885724,-2752612,-2618541,-2486762,-2354153
+  ,-2225059,-2094984,-1968194,-1830895,-1699508,-1575743,-1444516,-1308683,-1179714,-1053088
+  ,-917981,-783707,-653900,-524980,-395409,-260309,-131948,-3452,132113,263241
+  ,392185,522597,654134,788288,919810,1045795,1179210,1314201,1444235,1574447
+  ,1705193,1834009,1967332,2098102,2229019,2359147,2489859,2619878,2754966,2879671
+  ,3014438,3146143,3276733,3405958,3542196,3667493,3798815,3932961,4062458,4187125
+  ,4322346,4454875,4587752,4716809,4848274,4975027,5111957,5242215,5373085,5501158
+  ,5640140,5762918,5895358,6024008,6157906,6290628,6422713,6546339,6675888,6815606
+  ,6955288,7077501,7211630,7337893,7473635,7607175,7728310,7866475,7999658,8127888
+  ,8241758,8386483,8522550,8641582,8771915,8922139,9038632,9179385,9313426,9437184
+  ,9568256,9699328,9830400,9952933,10120004,10223616,10354688,10474645,10616832,-393216
+  ,-262144,-85425,-121,82533,262144,393216,-786432,-655360,-524288,-379928
+  ,-222821,-95200,287,95541,227093,393216,493567,655360,786432,-393216
+  ,-262144,-86805,510,86722,262144,393216,524288,-1048576,-917504,-786432
+  ,-624456,-529951,-395071,-241627,-101168,81,99975,241605,393216,524288
+  ,655360,786432,917504,-786432,-655360,-524288,-393216,-230359,-95619,-137
+  ,94425,226222,393216,524288,-1179648,-1048576,-917504,-773841,-655360,-492258
+  ,-379715,-244707,-103621,-434,104523,242680,381575,523659,650565,786432
+  ,917504,1048576,1179648,1310720,-786432,-629344,-524288,-376757,-242858,-101932
+  ,-2715,107155,239212,366480,514943,655360,786432,917504,-2228224,-2097152
+  ,-1966080,-1835008,-1703936,-1572864,-1441792,-1284584,-1179648,-1048819,-934658,-777181
+  ,-626371,-515660,-377493,-248975,-113036,436,113584,248354,379718,512475
+  ,653932,796494,917504,1048576,1179648,1310720,1441792,1572864,1703936,1835008
+  ,-1572864,-1441792,-1297608,-1161159,-1032316,-917092,-779770,-647384,-515529,-384269
+  ,-250003,-119252,1053,118111,249512,380545,512039,648101,770656,907003
+  ,1021725,1178082,1310720,1441792,-4587520,-4456448,-4325376,-4194304,-4063232,-3932160
+  ,-3801088,-3670016,-3538944,-3407872,-3276800,-3145728,-2999335,-2883584,-2752512,-2621440
+  ,-2490368,-2359296,-2228224,-2112691,-1966080,-1848781,-1709830,-1566109,-1438427,-1303530
+  ,-1176124,-1040936,-913876,-784585,-652025,-518361,-385267,-256342,-127297,-2733
+  ,125422,257792,389363,519911,651106,783805,909407,1044143,1174156,1309267
+  ,1436173,1553771,1708958,1814083,1967036,2095386,2255169,2359296,2478303,2621440
+  ,2752512,-4456448,-4325376,-4194304,-4063232,-3932160,-3797524,-3670016,-3560250,-3413217
+  ,-3257719,-3166416,-2986626,-2878000,-2781144,-2625383,-2495465,-2346792,-2230930,-2077063
+  ,-1949225,-1819274,-1697261,-1568664,-1443074,-1304302,-1175289,-1043794,-913423,-785561
+  ,-652104,-522835,-392667,-260517,-130088,-2,129509,260990,391931,522470
+  ,655770,784902,917093,1046445,1176951,1303121,1441362,1565401,1702022,1822856
+  ,1952852,2090384,2214607,2338436,2457483,2621440,-8781824,-8650752,-8519680,-8388608
+  ,-8260828,-8126464,-8003337,-7859030,-7750057,-7602176,-7471104,-7340032,-7193045,-7090588
+  ,-6946816,-6843344,-6676635,-6557575,-6447804,-6277614,-6159736,-6035729,-5884723,-5739567
+  ,-5634818,-5489867,-5372864,-5243300,-5098939,-4988639,-4856258,-4728494,-4591717,-4447428
+  ,-4322409,-4192918,-4062638,-3934141,-3797545,-3673373,-3531587,-3407391,-3277404,-3147797
+  ,-3013578,-2886548,-2749811,-2616428,-2490949,-2361301,-2228482,-2096883,-1964343,-1831754
+  ,-1702201,-1572495,-1442012,-1309242,-1182451,-1048996,-916905,-786510,-657079,-524730
+  ,-393672,-261313,-128743,166,130678,261334,393287,524155,655570,786839
+  ,917353,1052167,1179013,1309360,1442634,1571153,1703961,1832027,1965014,2097912
+  ,2224861,2355341,2490455,2623051,2753484,2877015,3015783,3144157,3273705,3405255
+  ,3542006,3669580,3802417,3935413,4065088,4190896,4333521,4456355,4579781,4713832
+  ,4845707,4978625,5113278,5243817,5382318,5500592,5638135,5761179,5900822,6029270
+  ,6186398,6297816,6436435,6559163,6666389,6806548,6950461,7086078,7195777,7350973
+  ,7480132,7614852,7743514,7847288,8014762,8126464,8257536,8388608,8519680,8650752
+  ,8781824,8912896,9043968,9175040,9306112,9437184
+};
+
+
+
+const WebRtc_Word16 WebRtcIsacfix_kLevelsShapeQ10[1735] = {
+  0,     0,    -1,     0,     0,     1,     0,     1,     0,  -821
+  ,     1,  -763,    -1,   656,  -620,     0,   633,  -636,     4,   615
+  ,  -630,     1,   649, -1773,  -670,     5,   678,  1810, -1876,  -676
+  ,     0,   691,  1843, -1806,  -743,    -1,   749,  1795,  2920, -2872
+  , -1761,  -772,    -3,   790,  1763,  2942,     0,     0,     0,     0
+  ,  -792,     2,     0,     0,     1,     0,  -854,     0,  -702,    -1
+  ,   662,  -624,    -5,   638,  -611,    -6,   638,  -647,     0,   651
+  ,  -685,    -4,   679,  2123, -1814,  -693,     0,   664,  1791, -1735
+  ,  -737,     0,   771,  1854,  2873, -2867, -1842,  -793,    -1,   821
+  ,  1826,  2805,  3922,     0,     0,     0,    -1,  -779,     1,   786
+  ,     1,  -708,     0,   789,  -799,     1,   797,  -663,     2,   646
+  ,  -600,     3,   609,  -600,     1,   658,  1807,  -627,    -3,   612
+  ,  -625,     3,   632, -1732,  -674,     1,   672,  2048, -1768,  -715
+  ,     0,   724,  1784, -3881, -3072, -1774,  -719,    -1,   730,  1811
+  , -2963, -1829,  -806,    -1,   816,  1795,  3050, -5389, -3784, -2942
+  , -1893,  -865,   -12,   867,  1885,  2945,  3928,    -2,     1,     4
+  ,     0,  -694,     2,   665,  -598,     5,   587,  -599,    -1,   661
+  ,  -656,    -7,   611,  -607,     5,   603,  -618,    -4,   620, -1794
+  ,  -645,    -2,   654,  -655,    -1,   658, -1801,  -700,     5,   707
+  ,  1927, -1752,  -745,    -8,   752,  1843, -2838, -1781,  -801,    11
+  ,   796,  1811,  2942,  3866, -3849, -3026, -1848,  -819,     2,   827
+  ,  1825,  2963, -3873, -2904, -1869,  -910,    -6,   903,  1902,  2885
+  ,  3978,  5286, -7168, -6081, -4989, -3968, -2963, -1970,  -943,    -2
+  ,   953,  1951,  2968,  3974,  5009,  6032,    -2,     3, -1024,     2
+  ,  1024,  -637,     1,   669,  -613,    -7,   630,  -603,     4,   612
+  ,  -612,     0,   590,  -645,   -11,   627,  -657,    -2,   671,  1849
+  , -1853,  -694,     2,   702,  1838, -3304, -1780,  -736,    -8,   732
+  ,  1772, -1709,  -755,    -6,   760,  1780, -2994, -1780,  -800,     8
+  ,   819,  1830,  2816, -4096, -2822, -1881,  -851,    -4,   855,  1872
+  ,  2840,  3899, -3908, -2904, -1878,  -887,     6,   897,  1872,  2942
+  ,  4008, -4992, -3881, -2933, -1915,  -928,     1,   937,  1919,  2900
+  ,  4009,  4881, -6848, -6157, -5065, -3981, -2983, -1972,  -978,    -1
+  ,   968,  1979,  2988,  4008,  5007,  6108,  7003,  8051,  9027,-13272
+  ,-12012,-11228,-10213, -9261, -8084, -7133, -6075, -5052, -4050, -3036
+  , -2014,  -996,    -4,  1007,  2031,  3038,  4049,  5074,  6134,  7069
+  ,  8094,  9069, 10212, 11049, 12104,    51, -1024,   -13,  1024,  -609
+  ,  -107,   613, -2048,  -687,   -95,   667,  2048, -3072, -1724,  -785
+  ,   -34,   732,  1819, -2048,  -703,   -26,   681,  2048, -2048,  -686
+  ,    -9,   665,  2048, -2048,  -702,    37,   748,  1723, -4096, -2786
+  , -1844,  -837,    37,   811,  1742,  3072, -4096, -2783, -1848,  -881
+  ,    39,   898,  1843,  2792,  3764, -5120, -4096, -2923, -1833,  -852
+  ,   -14,   862,  1824,  2834,  4096, -6144, -5120, -3914, -2842, -1870
+  ,  -886,   -27,   888,  1929,  2931,  4051, -7168, -6144, -5120, -3866
+  , -2933, -1915,  -927,    64,   933,  1902,  2929,  3912,  5063,  6144
+  ,-11264,-10240, -9216, -8192, -7086, -6144, -5039, -3972, -2943, -1929
+  ,  -941,     3,   938,  1942,  2959,  3933,  4905,  6088,  6983,  8192
+  , -9216, -8192, -7202, -6088, -4983, -4019, -2955, -1975,  -966,    17
+  ,   997,  1981,  2967,  3990,  4948,  6022,  6967,  8192,-13312,-12288
+  ,-11264,-10240, -9216, -8049, -6997, -6040, -5026, -4043, -3029, -2034
+  , -1015,   -23,   984,  1997,  3010,  4038,  5002,  6015,  6946,  8061
+  ,  9216, 10240,-12381,-11264,-10240, -9060, -8058, -7153, -6085, -5075
+  , -4051, -3042, -2037, -1017,    -5,  1007,  2028,  3035,  4050,  5088
+  ,  6111,  7160,  8156,  9215, 10095, 11229, 12202, 13016,-26624,-25600
+  ,-24582,-23671,-22674,-21400,-20355,-19508,-18315,-17269,-16361,-15299
+  ,-14363,-13294,-12262,-11237,-10203, -9227, -8165, -7156, -6116, -5122
+  , -4076, -3056, -2043, -1020,    -8,  1027,  2047,  3065,  4110,  5130
+  ,  6125,  7168,  8195,  9206, 10230, 11227, 12256, 13304, 14281, 15316
+  , 16374, 17382, 18428, 19388, 20361, 21468, 22448, 23781,     0,     0
+  ,    -1,     0,    -2,  1024,     0,     0,     0,    -1,  1024, -1024
+  ,     1, -1024,     4,  1024, -1024,     2,  1024, -1024,     2,  1024
+  , -2048, -1024,    -4,  1024, -1024,     2,  1024, -2048, -1024,    -3
+  ,  1024,  2048, -2048, -1024,     4,  1024,  2048, -3072, -2048, -1024
+  ,    -1,   662,  2048,     0,     1,     0,     0,     1,    -2,    -2
+  ,     0,     2,  1024,    -1,  1024, -1024,     4,  1024, -1024,     1
+  ,  1024, -1024,     1,  1024, -2048,  -781,    -4,   844,  -807,    -5
+  ,   866, -2048,  -726,   -13,   777,  2048, -2048,  -643,    -4,   617
+  ,  2048,  3072, -3072, -2048,  -629,     1,   630,  2048,  3072,     0
+  ,    -1,     1,    -2,     2,     1, -1024,     5, -1024,     6,  1024
+  , -1024,     4,  1024, -1024,     1,  1024, -1024,    -9,  1024,  -673
+  ,    -7,   655, -2048,  -665,   -15,   716, -2048,  -647,     4,   640
+  ,  2048, -2048,  -615,    -1,   635,  2048, -2048,  -613,    10,   637
+  ,  2048,  3072, -3072, -2048,  -647,    -3,   641,  2048,  3072, -5120
+  , -4096, -3072, -2048,  -681,     6,   685,  2048,  3072,  4096,     1
+  ,     1,     0,    -1,  1024, -1024,    -3,  1024, -1024,     6,  1024
+  , -1024,    -1,   769,  -733,     0,  1024,  -876,    -2,   653, -1024
+  ,    -4,   786,  -596,   -13,   595,  -634,    -2,   638,  2048, -2048
+  ,  -620,    -5,   620,  2048, -4096, -3072, -2048,  -639,    11,   655
+  ,  2048,  3072, -3072, -2048,  -659,     5,   663,  2048, -3072, -1823
+  ,  -687,    22,   695,  2048,  3072,  4096, -4096, -3072, -1848,  -715
+  ,    -3,   727,  1816,  3072,  4096,  5120, -8192, -7168, -6144, -5120
+  , -4096, -2884, -1771,  -756,   -14,   775,  1844,  3072,  4096,  5120
+  ,  6144,    -1,     1,     0, -1024,     2,   815,  -768,     2,   708
+  , -1024,    -3,   693,  -661,    -7,   607,  -643,    -5,   609,  -624
+  ,     3,   631,  -682,    -3,   691,  2048, -2048,  -640,     5,   650
+  ,  2048, -3072, -2048,  -701,     9,   704,  2048,  3072, -3072, -2048
+  ,  -670,    10,   674,  2048,  3072, -5120, -4096, -3072, -1749,  -738
+  ,     0,   733,  1811,  3072,  4096,  5120, -4096, -3072, -1873,  -753
+  ,     0,   756,  1874,  3072,  4096, -5120, -4096, -2900, -1838,  -793
+  ,    -6,   793,  1868,  2837,  4096,  5120, -7168, -6144, -5120, -4096
+  , -2832, -1891,  -828,     1,   828,  1901,  2823,  3912,  5120,  6144
+  ,  7168,  8192,-13312,-12288,-11264,-10240, -9216, -8192, -7168, -6144
+  , -5120, -3976, -3004, -1911,  -869,     7,   869,  1932,  3024,  3992
+  ,  5009,  6144,  7168,  8192,  9216, 10240, 11264,    -4,  1024,  -629
+  ,   -22,   609,  -623,     9,   640, -2048,  -768,     1,   682, -2048
+  ,  -741,    49,   722,  2048, -3072, -1706,  -808,   -20,   768,  1750
+  , -1684,  -727,   -29,   788,  1840,  3033, -1758,  -784,     0,   801
+  ,  1702, -3072, -1813,  -814,    38,   820,  1884,  2927, -4096, -3241
+  , -1839,  -922,    25,   882,  1886,  2812, -4096, -2982, -1923,  -894
+  ,    84,   912,  1869,  2778,  4096, -4928, -3965, -2902, -1920,  -883
+  ,     3,   917,  1953,  2921,  3957,  4922,  6144,  7168, -5120, -3916
+  , -2897, -1949,  -930,    31,   959,  1934,  2901,  3851,  5120, -9216
+  , -8192, -7046, -6029, -5030, -4034, -2980, -1969, -1013,   -76,   963
+  ,  1963,  2901,  3929,  4893,  6270,  7168,  8192,  9216,-12288,-11264
+  ,-10240, -9216, -8192, -6846, -6123, -5108, -4008, -3000, -1963,  -954
+  ,    -6,   958,  1992,  3009,  4020,  5085,  6097,  7168,  8192,  9216
+  ,-11264,-10139, -9194, -8127, -7156, -6102, -5053, -4049, -3036, -2025
+  , -1009,   -34,   974,  1984,  3034,  4028,  5138,  6000,  7057,  8166
+  ,  9070, 10033, 11360, 12288,-13312,-12288,-10932,-10190, -9120, -8123
+  , -7128, -6103, -5074, -4081, -3053, -2029,  -989,    -4,  1010,  2028
+  ,  3051,  4073,  5071,  6099,  7132,  8147,  9295, 10159, 11023, 12263
+  , 13312, 14336,-25600,-24576,-23552,-22529,-21504,-20480,-19456,-18637
+  ,-17425,-16165,-15316,-14327,-13606,-12135,-11182,-10107, -9153, -8144
+  , -7146, -6160, -5129, -4095, -3064, -2038, -1025,     1,  1031,  2072
+  ,  3074,  4088,  5123,  6149,  7157,  8173,  9198, 10244, 11250, 12268
+  , 13263, 14289, 15351, 16370, 17402, 18413, 19474, 20337, 21386, 22521
+  , 23367, 24350,     0,     0,     0,     0,     0,     0,     0,     0
+  , -1024,     0,  1024, -1024,     0,  1024, -1024,     0,  1024, -1024
+  ,     0,  1024, -1024,     0,  1024,  -773,     0,  1024,  -674,     0
+  ,   645, -2048,  -745,     0,   628,  2048, -2048,  -712,     0,   681
+  ,  2048,  3072, -3072, -2048,  -673,     0,   682,  1964,  3257,     0
+  ,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024
+  , -1024,     0,  1024, -1024,     0,  1024,  -705,     0,   623,  -771
+  ,     0,  1024,  -786,     0,   688,  -631,     0,   652,  2048, -2048
+  ,  -627,    -1,   666,  2048, -3072, -1756,  -694,     0,   674,  2048
+  , -3098, -1879,  -720,     5,   694,  1886,  2958,  4096,     0,     0
+  ,     0,     0,  1024,     0,     0,  1024,  -769,     0,  1024, -1024
+  ,     0,  1024, -1024,     0,  1024,  -817,     0,   734,  -786,     0
+  ,   651,  -638,     0,   637,  -623,     0,   671,  -652,     0,   619
+  ,  2048, -2048,  -670,    -1,   663,  2048, -1908,  -680,     1,   686
+  ,  2048,  3072,  4096, -4096, -3072, -1833,  -711,     0,   727,  1747
+  ,  3072,  4096, -4096, -2971, -1826,  -762,     2,   766,  1832,  2852
+  ,  3928,  5079,     0,     0,     0, -1024,     0,  1024, -1024,     0
+  ,  -656,     0,  1024,  -599,     0,   620, -1024,     0,  1024,  -603
+  ,     0,   622,  -643,     0,   660,  -599,     0,   611,  -641,    -1
+  ,   651,  2048, -2048,  -648,    -2,   647,  1798, -3072, -2048,  -672
+  ,     2,   670,  2048, -3072, -1780,  -694,    -1,   706,  1751,  3072
+  , -3072, -1862,  -757,     7,   739,  1798,  3072,  4096, -5120, -4096
+  , -3253, -1811,  -787,     3,   782,  1887,  3123,  4096, -7252, -6144
+  , -5354, -4060, -2864, -1863,  -820,   -11,   847,  1903,  2970,  3851
+  ,  4921,  5957,  7168,  8192,  9306,     0,     0, -1024,     0,  1024
+  ,  -726,     0,   706,  -692,     0,   593,  -598,     0,   616,  -624
+  ,     0,   616,  -605,     0,   613, -2048,  -652,     1,   635,  2048
+  , -2048,  -647,    -1,   660,  2048, -1811,  -668,    -2,   685,  2048
+  , -1796,  -731,    -2,   730,  1702,  3072, -3072, -1766,  -747,    -4
+  ,   756,  1770,  3072, -4096, -3024, -1762,  -783,     4,   771,  1781
+  ,  3072, -5120, -4057, -2807, -1832,  -822,     0,   816,  1804,  2851
+  ,  3949,  5120, -6144, -4899, -3927, -2920, -1893,  -874,    -2,   868
+  ,  1881,  2905,  3960,  4912,  6144, -9216, -8192, -7168, -6225, -4963
+  , -3943, -2956, -1890,  -902,     0,   897,  1914,  2916,  3984,  4990
+  ,  6050,  7168,-11264,-10217, -9114, -8132, -7035, -5988, -4984, -4000
+  , -2980, -1962,  -927,     7,   931,  1956,  2981,  4031,  4972,  6213
+  ,  7227,  8192,  9216, 10240, 11170, 12288, 13312, 14336,     0,  1024
+  ,  -557,     1,   571,  -606,    -4,   612, -1676,  -707,    10,   673
+  ,  2048, -2048,  -727,     5,   686, -3072, -1772,  -755,    12,   716
+  ,  1877, -1856,  -786,     2,   786,  1712, -1685,  -818,   -16,   863
+  ,  1729, -3072, -1762,  -857,     3,   866,  1838,  2841, -3862, -2816
+  , -1864,  -925,    -2,   923,  1897,  2779, -2782, -1838,  -920,   -28
+  ,   931,  1951,  2835,  3804, -4815, -4001, -2940, -1934,  -959,   -22
+  ,   975,  1957,  2904,  3971,  4835, -5148, -3892, -2944, -1953,  -986
+  ,   -11,   989,  1968,  2939,  3949,  4947,  5902, -9216, -8192, -6915
+  , -6004, -4965, -4013, -3009, -1977,  -987,    -1,   982,  1972,  3000
+  ,  3960,  4939,  5814, -8976, -7888, -7084, -5955, -5043, -4009, -2991
+  , -2002, -1000,    -8,   993,  2011,  3023,  4026,  5028,  6023,  7052
+  ,  8014,  9216,-11240,-10036, -9125, -8118, -7105, -6062, -5048, -4047
+  , -3044, -2025, -1009,    -1,  1011,  2023,  3042,  4074,  5085,  6108
+  ,  7119,  8142,  9152, 10114, 11141, 12250, 13307,-15360,-14099,-13284
+  ,-12291,-11223,-10221, -9152, -8147, -7128, -6104, -5077, -4072, -3062
+  , -2033, -1020,     7,  1018,  2038,  3059,  4081,  5084,  6109,  7102
+  ,  8128,  9134, 10125, 11239, 12080,-23552,-22528,-21504,-20480,-19456
+  ,-18159,-17240,-16291,-15364,-14285,-13305,-12271,-11233,-10217, -9198
+  , -8175, -7157, -6134, -5122, -4089, -3071, -2047, -1018,     3,  1026
+  ,  2041,  3077,  4090,  5108,  6131,  7150,  8172,  9175, 10196, 11272
+  , 12303, 13273, 14328, 15332, 16334, 17381, 18409, 19423, 20423, 21451
+  , 22679, 23391, 24568, 25600, 26589
+};
+
+/* cdf tables for quantizer indices */
+const WebRtc_UWord16 WebRtcIsacfix_kCdfGain[1212] = {
+  0,  13,  301,  3730,  61784,  65167,  65489,  65535,  0,  17,
+  142,  314,  929,  2466,  7678,  56450,  63463,  64740,  65204,  65426,
+  65527,  65535,  0,  8,  100,  724,  6301,  60105,  65125,  65510,
+  65531,  65535,  0,  13,  117,  368,  1068,  3010,  11928,  53603,
+  61177,  63404,  64505,  65108,  65422,  65502,  65531,  65535,  0,  4,
+  17,  96,  410,  1859,  12125,  54361,  64103,  65305,  65497,  65535,
+  0,  4,  88,  230,  469,  950,  1746,  3228,  6092,  16592,
+  44756,  56848,  61256,  63308,  64325,  64920,  65309,  65460,  65502,  65522,
+  65535,  0,  88,  352,  1675,  6339,  20749,  46686,  59284,  63525,
+  64949,  65359,  65502,  65527,  65535,  0,  13,  38,  63,  117,
+  234,  381,  641,  929,  1407,  2043,  2809,  4032,  5753,  8792,
+  14407,  24308,  38941,  48947,  55403,  59293,  61411,  62688,  63630,  64329,
+  64840,  65188,  65376,  65472,  65506,  65527,  65531,  65535,  0,  8,
+  29,  75,  222,  615,  1327,  2801,  5623,  9931,  16094,  24966,
+  34419,  43458,  50676,  56186,  60055,  62500,  63936,  64765,  65225,  65435,
+  65514,  65535,  0,  8,  13,  15,  17,  21,  33,  59,
+  71,  92,  151,  243,  360,  456,  674,  934,  1223,  1583,
+  1989,  2504,  3031,  3617,  4354,  5154,  6163,  7411,  8780,  10747,
+  12874,  15591,  18974,  23027,  27436,  32020,  36948,  41830,  46205,  49797,
+  53042,  56094,  58418,  60360,  61763,  62818,  63559,  64103,  64509,  64798,
+  65045,  65162,  65288,  65363,  65447,  65506,  65522,  65531,  65533,  65535,
+  0,  4,  6,  25,  38,  71,  138,  264,  519,  808,
+  1227,  1825,  2516,  3408,  4279,  5560,  7092,  9197,  11420,  14108,
+  16947,  20300,  23926,  27459,  31164,  34827,  38575,  42178,  45540,  48747,
+  51444,  54090,  56426,  58460,  60080,  61595,  62734,  63668,  64275,  64673,
+  64936,  65112,  65217,  65334,  65426,  65464,  65477,  65489,  65518,  65527,
+  65529,  65531,  65533,  65535,  0,  2,  4,  8,  10,  12,
+  14,  16,  21,  33,  50,  71,  84,  92,  105,  138,
+  180,  255,  318,  377,  435,  473,  511,  590,  682,  758,
+  913,  1097,  1256,  1449,  1671,  1884,  2169,  2445,  2772,  3157,
+  3563,  3944,  4375,  4848,  5334,  5820,  6448,  7101,  7716,  8378,
+  9102,  9956,  10752,  11648,  12707,  13670,  14758,  15910,  17187,  18472,
+  19627,  20649,  21951,  23169,  24283,  25552,  26862,  28227,  29391,  30764,
+  31882,  33213,  34432,  35600,  36910,  38116,  39464,  40729,  41872,  43144,
+  44371,  45514,  46762,  47813,  48968,  50069,  51032,  51974,  52908,  53737,
+  54603,  55445,  56282,  56990,  57572,  58191,  58840,  59410,  59887,  60264,
+  60607,  60946,  61269,  61516,  61771,  61960,  62198,  62408,  62558,  62776,
+  62985,  63207,  63408,  63546,  63739,  63906,  64070,  64237,  64371,  64551,
+  64677,  64836,  64999,  65095,  65213,  65284,  65338,  65380,  65426,  65447,
+  65472,  65485,  65487,  65489,  65502,  65510,  65512,  65514,  65516,  65518,
+  65522,  65531,  65533,  65535,  0,  2,  4,  6,  65528,  65531,
+  65533,  65535,  0,  2,  4,  6,  8,  10,  222,  65321,
+  65513,  65528,  65531,  65533,  65535,  0,  2,  4,  50,  65476,
+  65529,  65531,  65533,  65535,  0,  2,  4,  6,  8,  12,
+  38,  544,  64936,  65509,  65523,  65525,  65529,  65531,  65533,  65535,
+  0,  2,  4,  6,  8,  10,  1055,  64508,  65528,  65531,
+  65533,  65535,  0,  2,  4,  6,  8,  10,  12,  123,
+  3956,  62999,  65372,  65495,  65515,  65521,  65523,  65525,  65527,  65529,
+  65531,  65533,  65535,  0,  2,  4,  12,  53,  4707,  59445,
+  65467,  65525,  65527,  65529,  65531,  65533,  65535,  0,  2,  4,
+  6,  8,  10,  12,  14,  16,  38,  40,  50,  67,
+  96,  234,  929,  14345,  55750,  64866,  65389,  65462,  65514,  65517,
+  65519,  65521,  65523,  65525,  65527,  65529,  65531,  65533,  65535,  0,
+  2,  4,  6,  8,  10,  15,  35,  91,  377,  1946,
+  13618,  52565,  63714,  65184,  65465,  65520,  65523,  65525,  65527,  65529,
+  65531,  65533,  65535,  0,  2,  4,  6,  8,  10,  12,
+  14,  16,  18,  20,  22,  24,  26,  28,  30,  32,
+  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,
+  54,  82,  149,  362,  751,  1701,  4239,  12893,  38627,  55072,
+  60875,  63071,  64158,  64702,  65096,  65283,  65412,  65473,  65494,  65505,
+  65508,  65517,  65519,  65521,  65523,  65525,  65527,  65529,  65531,  65533,
+  65535,  0,  2,  15,  23,  53,  143,  260,  418,  698,
+  988,  1353,  1812,  2411,  3144,  4015,  5143,  6401,  7611,  8999,
+  10653,  12512,  14636,  16865,  19404,  22154,  24798,  27521,  30326,  33102,
+  35790,  38603,  41415,  43968,  46771,  49435,  52152,  54715,  57143,  59481,
+  61178,  62507,  63603,  64489,  64997,  65257,  65427,  65473,  65503,  65520,
+  65529,  65531,  65533,  65535,  0,  3,  6,  9,  26,  32,
+  44,  46,  64,  94,  111,  164,  205,  254,  327,  409,
+  506,  608,  733,  885,  1093,  1292,  1482,  1742,  1993,  2329,
+  2615,  3029,  3374,  3798,  4257,  4870,  5405,  5992,  6618,  7225,
+  7816,  8418,  9051,  9761,  10532,  11380,  12113,  13010,  13788,  14594,
+  15455,  16361,  17182,  18088,  18997,  20046,  20951,  21968,  22947,  24124,
+  25296,  26547,  27712,  28775,  29807,  30835,  31709,  32469,  33201,  34014,
+  34876,  35773,  36696,  37620,  38558,  39547,  40406,  41277,  42367,  43290,
+  44445,  45443,  46510,  47684,  48973,  50157,  51187,  52242,  53209,  54083,
+  55006,  55871,  56618,  57293,  57965,  58556,  59222,  59722,  60180,  60554,
+  60902,  61250,  61554,  61837,  62100,  62372,  62631,  62856,  63078,  63324,
+  63557,  63768,  63961,  64089,  64235,  64352,  64501,  64633,  64770,  64887,
+  65001,  65059,  65121,  65188,  65246,  65302,  65346,  65390,  65428,  65463,
+  65477,  65506,  65515,  65517,  65519,  65521,  65523,  65525,  65527,  65529,
+  65531,  65533,  65535,  0,  2,  4,  109,  65332,  65531,  65533,
+  65535,  0,  2,  4,  6,  8,  25,  1817,  63874,  65511,
+  65527,  65529,  65531,  65533,  65535,  0,  2,  4,  907,  65014,
+  65529,  65531,  65533,  65535,  0,  2,  4,  6,  8,  10,
+  12,  132,  2743,  62708,  65430,  65525,  65527,  65529,  65531,  65533,
+  65535,  0,  2,  4,  6,  8,  35,  3743,  61666,  65485,
+  65531,  65533,  65535,  0,  2,  4,  6,  8,  10,  23,
+  109,  683,  6905,  58417,  64911,  65398,  65497,  65518,  65525,  65527,
+  65529,  65531,  65533,  65535,  0,  2,  4,  6,  53,  510,
+  10209,  55212,  64573,  65441,  65522,  65529,  65531,  65533,  65535,  0,
+  2,  4,  6,  8,  10,  12,  14,  16,  18,  20,
+  22,  32,  90,  266,  1037,  3349,  14468,  50488,  62394,  64685,
+  65341,  65480,  65514,  65519,  65521,  65523,  65525,  65527,  65529,  65531,
+  65533,  65535,  0,  2,  4,  6,  9,  16,  37,  106,
+  296,  748,  1868,  5733,  18897,  45553,  60165,  63949,  64926,  65314,
+  65441,  65508,  65524,  65529,  65531,  65533,  65535,  0,  2,  4,
+  6,  8,  10,  12,  14,  16,  18,  20,  22,  24,
+  26,  28,  30,  32,  34,  36,  38,  40,  42,  44,
+  46,  48,  50,  83,  175,  344,  667,  1293,  2337,  4357,
+  8033,  14988,  28600,  43244,  52011,  57042,  59980,  61779,  63065,  63869,
+  64390,  64753,  64988,  65164,  65326,  65422,  65462,  65492,  65506,  65522,
+  65524,  65526,  65531,  65533,  65535,  0,  2,  4,  6,  8,
+  10,  12,  14,  16,  25,  39,  48,  55,  62,  65,
+  85,  106,  139,  169,  194,  252,  323,  485,  688,  1074,
+  1600,  2544,  3863,  5733,  8303,  11397,  15529,  20273,  25734,  31455,
+  36853,  41891,  46410,  50306,  53702,  56503,  58673,  60479,  61880,  62989,
+  63748,  64404,  64852,  65124,  65309,  65424,  65480,  65524,  65528,  65533,
+  65535,  0,  2,  4,  6,  8,  10,  12,  14,  21,
+  23,  25,  27,  29,  31,  39,  41,  43,  48,  60,
+  72,  79,  106,  136,  166,  187,  224,  252,  323,  381,
+  427,  478,  568,  660,  783,  912,  1046,  1175,  1365,  1567,
+  1768,  2024,  2347,  2659,  3049,  3529,  4033,  4623,  5281,  5925,
+  6726,  7526,  8417,  9468,  10783,  12141,  13571,  15222,  16916,  18659,
+  20350,  22020,  23725,  25497,  27201,  29026,  30867,  32632,  34323,  36062,
+  37829,  39466,  41144,  42654,  43981,  45343,  46579,  47759,  49013,  50171,
+  51249,  52283,  53245,  54148,  54938,  55669,  56421,  57109,  57791,  58464,
+  59092,  59674,  60105,  60653,  61083,  61407,  61757,  62095,  62388,  62649,
+  62873,  63157,  63358,  63540,  63725,  63884,  64046,  64155,  64278,  64426,
+  64548,  64654,  64806,  64906,  64994,  65077,  65137,  65215,  65277,  65324,
+  65354,  65409,  65437,  65455,  65462,  65490,  65495,  65499,  65508,  65511,
+  65513,  65515,  65517,  65519,  65521,  65523,  65525,  65527,  65529,  65531,
+  65533,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kCdfShape[2059] = {
+  0,  65535,  0,  65535,  0,  65535,  0,  65535,  0,  65535,
+  0,  65535,  0,  65535,  0,  65535,  0,  65535,  0,  4,
+  65535,  0,  8,  65514,  65535,  0,  29,  65481,  65535,  0,
+  121,  65439,  65535,  0,  239,  65284,  65535,  0,  8,  779,
+  64999,  65527,  65535,  0,  8,  888,  64693,  65522,  65535,  0,
+  29,  2604,  62843,  65497,  65531,  65535,  0,  25,  176,  4576,
+  61164,  65275,  65527,  65535,  0,  65535,  0,  65535,  0,  65535,
+  0,  65535,  0,  4,  65535,  0,  65535,  0,  65535,  0,
+  65535,  0,  65535,  0,  4,  65535,  0,  33,  65502,  65535,
+  0,  54,  65481,  65535,  0,  251,  65309,  65535,  0,  611,
+  65074,  65535,  0,  1273,  64292,  65527,  65535,  0,  4,  1809,
+  63940,  65518,  65535,  0,  88,  4392,  60603,  65426,  65531,  65535,
+  0,  25,  419,  7046,  57756,  64961,  65514,  65531,  65535,  0,
+  65535,  0,  65535,  0,  65535,  0,  65535,  0,  4,  65531,
+  65535,  0,  65535,  0,  8,  65531,  65535,  0,  4,  65527,
+  65535,  0,  17,  65510,  65535,  0,  42,  65481,  65535,  0,
+  197,  65342,  65531,  65535,  0,  385,  65154,  65535,  0,  1005,
+  64522,  65535,  0,  8,  1985,  63469,  65533,  65535,  0,  38,
+  3119,  61884,  65514,  65535,  0,  4,  6,  67,  4961,  60804,
+  65472,  65535,  0,  17,  565,  9182,  56538,  65087,  65514,  65535,
+  0,  8,  63,  327,  2118,  14490,  52774,  63839,  65376,  65522,
+  65535,  0,  65535,  0,  65535,  0,  65535,  0,  65535,  0,
+  17,  65522,  65535,  0,  59,  65489,  65535,  0,  50,  65522,
+  65535,  0,  54,  65489,  65535,  0,  310,  65179,  65535,  0,
+  615,  64836,  65535,  0,  4,  1503,  63965,  65535,  0,  2780,
+  63383,  65535,  0,  21,  3919,  61051,  65527,  65535,  0,  84,
+  6674,  59929,  65435,  65535,  0,  4,  255,  7976,  55784,  65150,
+  65518,  65531,  65535,  0,  4,  8,  582,  10726,  53465,  64949,
+  65518,  65535,  0,  29,  339,  3006,  17555,  49517,  62956,  65200,
+  65497,  65531,  65535,  0,  2,  33,  138,  565,  2324,  7670,
+  22089,  45966,  58949,  63479,  64966,  65380,  65518,  65535,  0,  65535,
+  0,  65535,  0,  2,  65533,  65535,  0,  46,  65514,  65535,
+  0,  414,  65091,  65535,  0,  540,  64911,  65535,  0,  419,
+  65162,  65535,  0,  976,  64790,  65535,  0,  2977,  62495,  65531,
+  65535,  0,  4,  3852,  61034,  65527,  65535,  0,  4,  29,
+  6021,  60243,  65468,  65535,  0,  84,  6711,  58066,  65418,  65535,
+  0,  13,  281,  9550,  54917,  65125,  65506,  65535,  0,  2,
+  63,  984,  12108,  52644,  64342,  65435,  65527,  65535,  0,  29,
+  251,  2014,  14871,  47553,  62881,  65229,  65518,  65535,  0,  13,
+  142,  749,  4220,  18497,  45200,  60913,  64823,  65426,  65527,  65535,
+  0,  13,  71,  264,  1176,  3789,  10500,  24480,  43488,  56324,
+  62315,  64493,  65242,  65464,  65514,  65522,  65531,  65535,  0,  4,
+  13,  38,  109,  205,  448,  850,  1708,  3429,  6276,  11371,
+  19221,  29734,  40955,  49391,  55411,  59460,  62102,  63793,  64656,  65150,
+  65401,  65485,  65522,  65531,  65535,  0,  65535,  0,  2,  65533,
+  65535,  0,  1160,  65476,  65535,  0,  2,  6640,  64763,  65533,
+  65535,  0,  2,  38,  9923,  61009,  65527,  65535,  0,  2,
+  4949,  63092,  65533,  65535,  0,  2,  3090,  63398,  65533,  65535,
+  0,  2,  2520,  58744,  65510,  65535,  0,  2,  13,  544,
+  8784,  51403,  65148,  65533,  65535,  0,  2,  25,  1017,  10412,
+  43550,  63651,  65489,  65527,  65535,  0,  2,  4,  29,  783,
+  13377,  52462,  64524,  65495,  65533,  65535,  0,  2,  4,  6,
+  100,  1817,  18451,  52590,  63559,  65376,  65531,  65535,  0,  2,
+  4,  6,  46,  385,  2562,  11225,  37416,  60488,  65026,  65487,
+  65529,  65533,  65535,  0,  2,  4,  6,  8,  10,  12,
+  42,  222,  971,  5221,  19811,  45048,  60312,  64486,  65294,  65474,
+  65525,  65529,  65533,  65535,  0,  2,  4,  8,  71,  167,
+  666,  2533,  7875,  19622,  38082,  54359,  62108,  64633,  65290,  65495,
+  65529,  65533,  65535,  0,  2,  4,  6,  8,  10,  13,
+  109,  586,  1930,  4949,  11600,  22641,  36125,  48312,  56899,  61495,
+  63927,  64932,  65389,  65489,  65518,  65531,  65533,  65535,  0,  4,
+  6,  8,  67,  209,  712,  1838,  4195,  8432,  14432,  22834,
+  31723,  40523,  48139,  53929,  57865,  60657,  62403,  63584,  64363,  64907,
+  65167,  65372,  65472,  65514,  65535,  0,  2,  4,  13,  25,
+  42,  46,  50,  75,  113,  147,  281,  448,  657,  909,
+  1185,  1591,  1976,  2600,  3676,  5317,  7398,  9914,  12941,  16169,
+  19477,  22885,  26464,  29851,  33360,  37228,  41139,  44802,  48654,  52058,
+  55181,  57676,  59581,  61022,  62190,  63107,  63676,  64199,  64547,  64924,
+  65158,  65313,  65430,  65481,  65518,  65535,  0,  65535,  0,  65535,
+  0,  65535,  0,  65535,  0,  65533,  65535,  0,  65535,  0,
+  65535,  0,  65535,  0,  65533,  65535,  0,  2,  65535,  0,
+  2,  65533,  65535,  0,  2,  65533,  65535,  0,  2,  65533,
+  65535,  0,  2,  4,  65533,  65535,  0,  2,  65533,  65535,
+  0,  2,  4,  65531,  65533,  65535,  0,  2,  4,  65531,
+  65533,  65535,  0,  2,  4,  6,  65524,  65533,  65535,  0,
+  65535,  0,  65535,  0,  65535,  0,  65535,  0,  65535,  0,
+  65535,  0,  65535,  0,  65535,  0,  65533,  65535,  0,  65533,
+  65535,  0,  2,  65533,  65535,  0,  2,  65533,  65535,  0,
+  2,  65533,  65535,  0,  2,  4,  65532,  65535,  0,  6,
+  65523,  65535,  0,  2,  15,  65530,  65533,  65535,  0,  2,
+  35,  65493,  65531,  65533,  65535,  0,  2,  4,  158,  65382,
+  65531,  65533,  65535,  0,  65535,  0,  65535,  0,  65535,  0,
+  65535,  0,  65535,  0,  65535,  0,  2,  65535,  0,  2,
+  65533,  65535,  0,  2,  65533,  65535,  0,  2,  65533,  65535,
+  0,  2,  65533,  65535,  0,  9,  65512,  65535,  0,  2,
+  12,  65529,  65535,  0,  2,  73,  65434,  65533,  65535,  0,
+  2,  240,  65343,  65533,  65535,  0,  2,  476,  65017,  65531,
+  65533,  65535,  0,  2,  4,  1046,  64686,  65531,  65533,  65535,
+  0,  2,  4,  6,  8,  1870,  63898,  65529,  65531,  65533,
+  65535,  0,  65535,  0,  65535,  0,  65535,  0,  65533,  65535,
+  0,  2,  65533,  65535,  0,  2,  65533,  65535,  0,  2,
+  65532,  65535,  0,  6,  65533,  65535,  0,  6,  65523,  65535,
+  0,  2,  65532,  65535,  0,  137,  65439,  65535,  0,  576,
+  64899,  65533,  65535,  0,  2,  289,  65299,  65533,  65535,  0,
+  2,  4,  6,  880,  64134,  65531,  65533,  65535,  0,  2,
+  4,  1853,  63347,  65533,  65535,  0,  2,  6,  2516,  61762,
+  65529,  65531,  65533,  65535,  0,  2,  4,  9,  3980,  61380,
+  65503,  65529,  65531,  65533,  65535,  0,  2,  4,  6,  8,
+  10,  12,  61,  6393,  59859,  65466,  65527,  65529,  65531,  65533,
+  65535,  0,  65535,  0,  65535,  0,  65535,  0,  2,  65532,
+  65535,  0,  3,  65529,  65535,  0,  2,  65529,  65535,  0,
+  61,  65453,  65535,  0,  234,  65313,  65535,  0,  503,  65138,
+  65535,  0,  155,  65402,  65533,  65535,  0,  2,  1058,  64554,
+  65533,  65535,  0,  2,  4,  3138,  62109,  65531,  65533,  65535,
+  0,  2,  4,  2031,  63339,  65531,  65533,  65535,  0,  2,
+  4,  6,  9,  4155,  60778,  65523,  65529,  65531,  65533,  65535,
+  0,  2,  4,  41,  6189,  59269,  65490,  65531,  65533,  65535,
+  0,  2,  4,  6,  210,  8789,  57043,  65400,  65528,  65531,
+  65533,  65535,  0,  2,  4,  6,  8,  26,  453,  10086,
+  55499,  64948,  65483,  65524,  65527,  65529,  65531,  65533,  65535,  0,
+  2,  4,  6,  8,  10,  12,  14,  16,  18,  20,
+  114,  1014,  11202,  52670,  64226,  65356,  65503,  65514,  65523,  65525,
+  65527,  65529,  65531,  65533,  65535,  0,  65533,  65535,  0,  15,
+  65301,  65535,  0,  152,  64807,  65535,  0,  2,  3328,  63308,
+  65535,  0,  2,  4050,  59730,  65533,  65535,  0,  2,  164,
+  10564,  61894,  65529,  65535,  0,  15,  6712,  59831,  65076,  65532,
+  65535,  0,  32,  7712,  57449,  65459,  65535,  0,  2,  210,
+  7849,  53110,  65021,  65523,  65535,  0,  2,  12,  1081,  13883,
+  48262,  62870,  65477,  65535,  0,  2,  88,  847,  6145,  37852,
+  62012,  65454,  65533,  65535,  0,  9,  47,  207,  1823,  14522,
+  45521,  61069,  64891,  65481,  65528,  65531,  65533,  65535,  0,  2,
+  9,  488,  2881,  12758,  38703,  58412,  64420,  65410,  65533,  65535,
+  0,  2,  4,  6,  61,  333,  1891,  6486,  19720,  43188,
+  57547,  62472,  64796,  65421,  65497,  65523,  65529,  65531,  65533,  65535,
+  0,  2,  4,  6,  8,  10,  12,  29,  117,  447,
+  1528,  6138,  21242,  43133,  56495,  62432,  64746,  65362,  65500,  65529,
+  65531,  65533,  65535,  0,  2,  18,  105,  301,  760,  1490,
+  3472,  7568,  15002,  26424,  40330,  53029,  60048,  62964,  64274,  64890,
+  65337,  65445,  65489,  65513,  65527,  65530,  65533,  65535,  0,  2,
+  4,  6,  41,  102,  409,  853,  2031,  4316,  7302,  11328,
+  16869,  24825,  34926,  43481,  50877,  56126,  59874,  62103,  63281,  63857,
+  64166,  64675,  65382,  65522,  65531,  65533,  65535,  0,  2,  4,
+  6,  8,  10,  12,  14,  16,  18,  29,  38,  53,
+  58,  96,  181,  503,  1183,  2849,  5590,  8600,  11379,  13942,
+  16478,  19453,  22638,  26039,  29411,  32921,  37596,  41433,  44998,  48560,
+  51979,  55106,  57666,  59892,  61485,  62616,  63484,  64018,  64375,  64685,
+  64924,  65076,  65278,  65395,  65471,  65509,  65529,  65535,  0,  65535,
+  0,  65535,  0,  65535,  0,  65535,  0,  65535,  0,  65535,
+  0,  65535,  0,  65535,  0,  2,  65533,  65535,  0,  2,
+  65533,  65535,  0,  2,  65533,  65535,  0,  2,  65533,  65535,
+  0,  2,  65533,  65535,  0,  2,  65533,  65535,  0,  7,
+  65519,  65535,  0,  2,  14,  65491,  65533,  65535,  0,  2,
+  81,  65427,  65531,  65533,  65535,  0,  2,  4,  312,  65293,
+  65528,  65533,  65535,  0,  65535,  0,  65535,  0,  65535,  0,
+  65535,  0,  65535,  0,  65535,  0,  65535,  0,  65535,  0,
+  2,  65533,  65535,  0,  2,  65533,  65535,  0,  2,  65533,
+  65535,  0,  5,  65523,  65535,  0,  2,  65533,  65535,  0,
+  7,  65526,  65535,  0,  46,  65464,  65533,  65535,  0,  2,
+  120,  65309,  65533,  65535,  0,  2,  5,  362,  65097,  65533,
+  65535,  0,  2,  18,  1164,  64785,  65528,  65531,  65533,  65535,
+  0,  65535,  0,  65535,  0,  65535,  0,  65533,  65535,  0,
+  65535,  0,  65533,  65535,  0,  2,  65533,  65535,  0,  2,
+  65533,  65535,  0,  2,  65533,  65535,  0,  2,  65530,  65535,
+  0,  2,  65523,  65535,  0,  69,  65477,  65535,  0,  141,
+  65459,  65535,  0,  194,  65325,  65533,  65535,  0,  2,  543,
+  64912,  65533,  65535,  0,  5,  1270,  64301,  65529,  65531,  65533,
+  65535,  0,  2,  4,  12,  2055,  63538,  65508,  65531,  65533,
+  65535,  0,  2,  7,  102,  3775,  61970,  65429,  65526,  65528,
+  65533,  65535,  0,  65535,  0,  65535,  0,  65535,  0,  2,
+  65533,  65535,  0,  2,  65535,  0,  9,  65533,  65535,  0,
+  25,  65512,  65535,  0,  2,  65533,  65535,  0,  44,  65480,
+  65535,  0,  48,  65475,  65535,  0,  162,  65373,  65535,  0,
+  637,  64806,  65533,  65535,  0,  2,  935,  64445,  65533,  65535,
+  0,  2,  4,  1662,  64083,  65533,  65535,  0,  2,  12,
+  3036,  62469,  65521,  65533,  65535,  0,  2,  120,  5405,  60468,
+  65469,  65531,  65533,  65535,  0,  2,  4,  18,  254,  6663,
+  58999,  65272,  65528,  65533,  65535,  0,  2,  4,  9,  12,
+  67,  591,  8981,  56781,  64564,  65365,  65508,  65524,  65526,  65529,
+  65531,  65533,  65535,  0,  65535,  0,  65535,  0,  2,  65533,
+  65535,  0,  9,  65526,  65535,  0,  14,  65503,  65535,  0,
+  127,  65390,  65535,  0,  517,  64990,  65535,  0,  178,  65330,
+  65535,  0,  2,  1055,  64533,  65533,  65535,  0,  2,  1558,
+  63942,  65533,  65535,  0,  2,  2205,  63173,  65533,  65535,  0,
+  25,  4493,  60862,  65505,  65533,  65535,  0,  2,  48,  5890,
+  59442,  65482,  65533,  65535,  0,  2,  4,  127,  7532,  58191,
+  65394,  65533,  65535,  0,  2,  5,  32,  550,  10388,  54924,
+  65046,  65510,  65531,  65533,  65535,  0,  2,  4,  30,  150,
+  1685,  14340,  51375,  63619,  65288,  65503,  65528,  65533,  65535,  0,
+  2,  4,  6,  8,  28,  97,  473,  2692,  15407,  50020,
+  62880,  65064,  65445,  65508,  65531,  65533,  65535,  0,  2,  4,
+  12,  32,  79,  150,  372,  907,  2184,  5868,  18207,  45431,
+  59856,  64031,  65096,  65401,  65481,  65507,  65521,  65523,  65525,  65527,
+  65529,  65531,  65533,  65535,  0,  65533,  65535,  0,  182,  65491,
+  65535,  0,  877,  64286,  65535,  0,  9,  2708,  63612,  65533,
+  65535,  0,  2,  6038,  59532,  65535,  0,  2,  92,  5500,
+  60539,  65533,  65535,  0,  268,  8908,  56512,  65385,  65535,  0,
+  129,  13110,  52742,  65036,  65535,  0,  2,  806,  14003,  51929,
+  64732,  65523,  65535,  0,  7,  92,  2667,  18159,  47678,  62610,
+  65355,  65535,  0,  32,  1836,  19676,  48237,  61677,  64960,  65526,
+  65535,  0,  21,  159,  967,  5668,  22782,  44709,  58317,  64020,
+  65406,  65528,  65535,  0,  7,  162,  1838,  8328,  23929,  43014,
+  56394,  63374,  65216,  65484,  65521,  65535,  0,  2,  4,  6,
+  28,  268,  1120,  3613,  10688,  24185,  40989,  54917,  61684,  64510,
+  65403,  65530,  65535,  0,  2,  16,  44,  139,  492,  1739,
+  5313,  13558,  26766,  41566,  52446,  58937,  62815,  64480,  65201,  65454,
+  65524,  65533,  65535,  0,  7,  25,  76,  263,  612,  1466,
+  3325,  6832,  12366,  20152,  29466,  39255,  47360,  53506,  57740,  60726,
+  62845,  64131,  64882,  65260,  65459,  65521,  65528,  65530,  65535,  0,
+  2,  4,  14,  48,  136,  312,  653,  1240,  2369,  4327,
+  7028,  10759,  15449,  21235,  28027,  35386,  42938,  49562,  54990,  59119,
+  62086,  63916,  64863,  65249,  65445,  65493,  65523,  65535,  0,  2,
+  4,  6,  8,  10,  12,  21,  83,  208,  409,  723,
+  1152,  1868,  2951,  4463,  6460,  8979,  11831,  15195,  18863,  22657,
+  26762,  30881,  34963,  39098,  43054,  47069,  50620,  53871,  56821,  59386,
+  61340,  62670,  63512,  64023,  64429,  64750,  64944,  65126,  65279,  65366,
+  65413,  65445,  65473,  65505,  65510,  65521,  65528,  65530,  65535
+};
+
+/* pointers to cdf tables for quantizer indices */
+const WebRtc_UWord16 *WebRtcIsacfix_kCdfGainPtr[3][12] = {
+  { WebRtcIsacfix_kCdfGain +0 +0,   WebRtcIsacfix_kCdfGain +0 +8,   WebRtcIsacfix_kCdfGain +0 +22,
+    WebRtcIsacfix_kCdfGain +0 +32,  WebRtcIsacfix_kCdfGain +0 +48,  WebRtcIsacfix_kCdfGain +0 +60,
+    WebRtcIsacfix_kCdfGain +0 +81,  WebRtcIsacfix_kCdfGain +0 +95,  WebRtcIsacfix_kCdfGain +0 +128,
+    WebRtcIsacfix_kCdfGain +0 +152, WebRtcIsacfix_kCdfGain +0 +210, WebRtcIsacfix_kCdfGain +0 +264
+  },
+  { WebRtcIsacfix_kCdfGain +404 +0,   WebRtcIsacfix_kCdfGain +404 +8,   WebRtcIsacfix_kCdfGain +404 +21,
+    WebRtcIsacfix_kCdfGain +404 +30,  WebRtcIsacfix_kCdfGain +404 +46,  WebRtcIsacfix_kCdfGain +404 +58,
+    WebRtcIsacfix_kCdfGain +404 +79,  WebRtcIsacfix_kCdfGain +404 +93,  WebRtcIsacfix_kCdfGain +404 +125,
+    WebRtcIsacfix_kCdfGain +404 +149, WebRtcIsacfix_kCdfGain +404 +207, WebRtcIsacfix_kCdfGain +404 +260
+  },
+  { WebRtcIsacfix_kCdfGain +803 +0,   WebRtcIsacfix_kCdfGain +803 +8,   WebRtcIsacfix_kCdfGain +803 +22,
+    WebRtcIsacfix_kCdfGain +803 +31,  WebRtcIsacfix_kCdfGain +803 +48,  WebRtcIsacfix_kCdfGain +803 +60,
+    WebRtcIsacfix_kCdfGain +803 +81,  WebRtcIsacfix_kCdfGain +803 +96,  WebRtcIsacfix_kCdfGain +803 +129,
+    WebRtcIsacfix_kCdfGain +803 +154, WebRtcIsacfix_kCdfGain +803 +212, WebRtcIsacfix_kCdfGain +803 +268
+  }
+};
+
+const WebRtc_UWord16 *WebRtcIsacfix_kCdfShapePtr[3][108] = {
+  { WebRtcIsacfix_kCdfShape +0 +0,   WebRtcIsacfix_kCdfShape +0 +2,   WebRtcIsacfix_kCdfShape +0 +4,
+    WebRtcIsacfix_kCdfShape +0 +6,   WebRtcIsacfix_kCdfShape +0 +8,   WebRtcIsacfix_kCdfShape +0 +10,
+    WebRtcIsacfix_kCdfShape +0 +12,  WebRtcIsacfix_kCdfShape +0 +14,  WebRtcIsacfix_kCdfShape +0 +16,
+    WebRtcIsacfix_kCdfShape +0 +18,  WebRtcIsacfix_kCdfShape +0 +21,  WebRtcIsacfix_kCdfShape +0 +25,
+    WebRtcIsacfix_kCdfShape +0 +29,  WebRtcIsacfix_kCdfShape +0 +33,  WebRtcIsacfix_kCdfShape +0 +37,
+    WebRtcIsacfix_kCdfShape +0 +43,  WebRtcIsacfix_kCdfShape +0 +49,  WebRtcIsacfix_kCdfShape +0 +56,
+    WebRtcIsacfix_kCdfShape +0 +64,  WebRtcIsacfix_kCdfShape +0 +66,  WebRtcIsacfix_kCdfShape +0 +68,
+    WebRtcIsacfix_kCdfShape +0 +70,  WebRtcIsacfix_kCdfShape +0 +72,  WebRtcIsacfix_kCdfShape +0 +75,
+    WebRtcIsacfix_kCdfShape +0 +77,  WebRtcIsacfix_kCdfShape +0 +79,  WebRtcIsacfix_kCdfShape +0 +81,
+    WebRtcIsacfix_kCdfShape +0 +83,  WebRtcIsacfix_kCdfShape +0 +86,  WebRtcIsacfix_kCdfShape +0 +90,
+    WebRtcIsacfix_kCdfShape +0 +94,  WebRtcIsacfix_kCdfShape +0 +98,  WebRtcIsacfix_kCdfShape +0 +102,
+    WebRtcIsacfix_kCdfShape +0 +107, WebRtcIsacfix_kCdfShape +0 +113, WebRtcIsacfix_kCdfShape +0 +120,
+    WebRtcIsacfix_kCdfShape +0 +129, WebRtcIsacfix_kCdfShape +0 +131, WebRtcIsacfix_kCdfShape +0 +133,
+    WebRtcIsacfix_kCdfShape +0 +135, WebRtcIsacfix_kCdfShape +0 +137, WebRtcIsacfix_kCdfShape +0 +141,
+    WebRtcIsacfix_kCdfShape +0 +143, WebRtcIsacfix_kCdfShape +0 +147, WebRtcIsacfix_kCdfShape +0 +151,
+    WebRtcIsacfix_kCdfShape +0 +155, WebRtcIsacfix_kCdfShape +0 +159, WebRtcIsacfix_kCdfShape +0 +164,
+    WebRtcIsacfix_kCdfShape +0 +168, WebRtcIsacfix_kCdfShape +0 +172, WebRtcIsacfix_kCdfShape +0 +178,
+    WebRtcIsacfix_kCdfShape +0 +184, WebRtcIsacfix_kCdfShape +0 +192, WebRtcIsacfix_kCdfShape +0 +200,
+    WebRtcIsacfix_kCdfShape +0 +211, WebRtcIsacfix_kCdfShape +0 +213, WebRtcIsacfix_kCdfShape +0 +215,
+    WebRtcIsacfix_kCdfShape +0 +217, WebRtcIsacfix_kCdfShape +0 +219, WebRtcIsacfix_kCdfShape +0 +223,
+    WebRtcIsacfix_kCdfShape +0 +227, WebRtcIsacfix_kCdfShape +0 +231, WebRtcIsacfix_kCdfShape +0 +235,
+    WebRtcIsacfix_kCdfShape +0 +239, WebRtcIsacfix_kCdfShape +0 +243, WebRtcIsacfix_kCdfShape +0 +248,
+    WebRtcIsacfix_kCdfShape +0 +252, WebRtcIsacfix_kCdfShape +0 +258, WebRtcIsacfix_kCdfShape +0 +264,
+    WebRtcIsacfix_kCdfShape +0 +273, WebRtcIsacfix_kCdfShape +0 +282, WebRtcIsacfix_kCdfShape +0 +293,
+    WebRtcIsacfix_kCdfShape +0 +308, WebRtcIsacfix_kCdfShape +0 +310, WebRtcIsacfix_kCdfShape +0 +312,
+    WebRtcIsacfix_kCdfShape +0 +316, WebRtcIsacfix_kCdfShape +0 +320, WebRtcIsacfix_kCdfShape +0 +324,
+    WebRtcIsacfix_kCdfShape +0 +328, WebRtcIsacfix_kCdfShape +0 +332, WebRtcIsacfix_kCdfShape +0 +336,
+    WebRtcIsacfix_kCdfShape +0 +341, WebRtcIsacfix_kCdfShape +0 +347, WebRtcIsacfix_kCdfShape +0 +354,
+    WebRtcIsacfix_kCdfShape +0 +360, WebRtcIsacfix_kCdfShape +0 +368, WebRtcIsacfix_kCdfShape +0 +378,
+    WebRtcIsacfix_kCdfShape +0 +388, WebRtcIsacfix_kCdfShape +0 +400, WebRtcIsacfix_kCdfShape +0 +418,
+    WebRtcIsacfix_kCdfShape +0 +445, WebRtcIsacfix_kCdfShape +0 +447, WebRtcIsacfix_kCdfShape +0 +451,
+    WebRtcIsacfix_kCdfShape +0 +455, WebRtcIsacfix_kCdfShape +0 +461, WebRtcIsacfix_kCdfShape +0 +468,
+    WebRtcIsacfix_kCdfShape +0 +474, WebRtcIsacfix_kCdfShape +0 +480, WebRtcIsacfix_kCdfShape +0 +486,
+    WebRtcIsacfix_kCdfShape +0 +495, WebRtcIsacfix_kCdfShape +0 +505, WebRtcIsacfix_kCdfShape +0 +516,
+    WebRtcIsacfix_kCdfShape +0 +528, WebRtcIsacfix_kCdfShape +0 +543, WebRtcIsacfix_kCdfShape +0 +564,
+    WebRtcIsacfix_kCdfShape +0 +583, WebRtcIsacfix_kCdfShape +0 +608, WebRtcIsacfix_kCdfShape +0 +635
+  },
+  { WebRtcIsacfix_kCdfShape +686 +0,   WebRtcIsacfix_kCdfShape +686 +2,   WebRtcIsacfix_kCdfShape +686 +4,
+    WebRtcIsacfix_kCdfShape +686 +6,   WebRtcIsacfix_kCdfShape +686 +8,   WebRtcIsacfix_kCdfShape +686 +11,
+    WebRtcIsacfix_kCdfShape +686 +13,  WebRtcIsacfix_kCdfShape +686 +15,  WebRtcIsacfix_kCdfShape +686 +17,
+    WebRtcIsacfix_kCdfShape +686 +20,  WebRtcIsacfix_kCdfShape +686 +23,  WebRtcIsacfix_kCdfShape +686 +27,
+    WebRtcIsacfix_kCdfShape +686 +31,  WebRtcIsacfix_kCdfShape +686 +35,  WebRtcIsacfix_kCdfShape +686 +40,
+    WebRtcIsacfix_kCdfShape +686 +44,  WebRtcIsacfix_kCdfShape +686 +50,  WebRtcIsacfix_kCdfShape +686 +56,
+    WebRtcIsacfix_kCdfShape +686 +63,  WebRtcIsacfix_kCdfShape +686 +65,  WebRtcIsacfix_kCdfShape +686 +67,
+    WebRtcIsacfix_kCdfShape +686 +69,  WebRtcIsacfix_kCdfShape +686 +71,  WebRtcIsacfix_kCdfShape +686 +73,
+    WebRtcIsacfix_kCdfShape +686 +75,  WebRtcIsacfix_kCdfShape +686 +77,  WebRtcIsacfix_kCdfShape +686 +79,
+    WebRtcIsacfix_kCdfShape +686 +82,  WebRtcIsacfix_kCdfShape +686 +85,  WebRtcIsacfix_kCdfShape +686 +89,
+    WebRtcIsacfix_kCdfShape +686 +93,  WebRtcIsacfix_kCdfShape +686 +97,  WebRtcIsacfix_kCdfShape +686 +102,
+    WebRtcIsacfix_kCdfShape +686 +106, WebRtcIsacfix_kCdfShape +686 +112, WebRtcIsacfix_kCdfShape +686 +119,
+    WebRtcIsacfix_kCdfShape +686 +127, WebRtcIsacfix_kCdfShape +686 +129, WebRtcIsacfix_kCdfShape +686 +131,
+    WebRtcIsacfix_kCdfShape +686 +133, WebRtcIsacfix_kCdfShape +686 +135, WebRtcIsacfix_kCdfShape +686 +137,
+    WebRtcIsacfix_kCdfShape +686 +139, WebRtcIsacfix_kCdfShape +686 +142, WebRtcIsacfix_kCdfShape +686 +146,
+    WebRtcIsacfix_kCdfShape +686 +150, WebRtcIsacfix_kCdfShape +686 +154, WebRtcIsacfix_kCdfShape +686 +158,
+    WebRtcIsacfix_kCdfShape +686 +162, WebRtcIsacfix_kCdfShape +686 +167, WebRtcIsacfix_kCdfShape +686 +173,
+    WebRtcIsacfix_kCdfShape +686 +179, WebRtcIsacfix_kCdfShape +686 +186, WebRtcIsacfix_kCdfShape +686 +194,
+    WebRtcIsacfix_kCdfShape +686 +205, WebRtcIsacfix_kCdfShape +686 +207, WebRtcIsacfix_kCdfShape +686 +209,
+    WebRtcIsacfix_kCdfShape +686 +211, WebRtcIsacfix_kCdfShape +686 +214, WebRtcIsacfix_kCdfShape +686 +218,
+    WebRtcIsacfix_kCdfShape +686 +222, WebRtcIsacfix_kCdfShape +686 +226, WebRtcIsacfix_kCdfShape +686 +230,
+    WebRtcIsacfix_kCdfShape +686 +234, WebRtcIsacfix_kCdfShape +686 +238, WebRtcIsacfix_kCdfShape +686 +242,
+    WebRtcIsacfix_kCdfShape +686 +247, WebRtcIsacfix_kCdfShape +686 +253, WebRtcIsacfix_kCdfShape +686 +262,
+    WebRtcIsacfix_kCdfShape +686 +269, WebRtcIsacfix_kCdfShape +686 +278, WebRtcIsacfix_kCdfShape +686 +289,
+    WebRtcIsacfix_kCdfShape +686 +305, WebRtcIsacfix_kCdfShape +686 +307, WebRtcIsacfix_kCdfShape +686 +309,
+    WebRtcIsacfix_kCdfShape +686 +311, WebRtcIsacfix_kCdfShape +686 +315, WebRtcIsacfix_kCdfShape +686 +319,
+    WebRtcIsacfix_kCdfShape +686 +323, WebRtcIsacfix_kCdfShape +686 +327, WebRtcIsacfix_kCdfShape +686 +331,
+    WebRtcIsacfix_kCdfShape +686 +335, WebRtcIsacfix_kCdfShape +686 +340, WebRtcIsacfix_kCdfShape +686 +346,
+    WebRtcIsacfix_kCdfShape +686 +354, WebRtcIsacfix_kCdfShape +686 +362, WebRtcIsacfix_kCdfShape +686 +374,
+    WebRtcIsacfix_kCdfShape +686 +384, WebRtcIsacfix_kCdfShape +686 +396, WebRtcIsacfix_kCdfShape +686 +413,
+    WebRtcIsacfix_kCdfShape +686 +439, WebRtcIsacfix_kCdfShape +686 +442, WebRtcIsacfix_kCdfShape +686 +446,
+    WebRtcIsacfix_kCdfShape +686 +450, WebRtcIsacfix_kCdfShape +686 +455, WebRtcIsacfix_kCdfShape +686 +461,
+    WebRtcIsacfix_kCdfShape +686 +468, WebRtcIsacfix_kCdfShape +686 +475, WebRtcIsacfix_kCdfShape +686 +481,
+    WebRtcIsacfix_kCdfShape +686 +489, WebRtcIsacfix_kCdfShape +686 +498, WebRtcIsacfix_kCdfShape +686 +508,
+    WebRtcIsacfix_kCdfShape +686 +522, WebRtcIsacfix_kCdfShape +686 +534, WebRtcIsacfix_kCdfShape +686 +554,
+    WebRtcIsacfix_kCdfShape +686 +577, WebRtcIsacfix_kCdfShape +686 +602, WebRtcIsacfix_kCdfShape +686 +631
+  },
+  { WebRtcIsacfix_kCdfShape +1368 +0,   WebRtcIsacfix_kCdfShape +1368 +2,   WebRtcIsacfix_kCdfShape +1368 +4,
+    WebRtcIsacfix_kCdfShape +1368 +6,   WebRtcIsacfix_kCdfShape +1368 +8,   WebRtcIsacfix_kCdfShape +1368 +10,
+    WebRtcIsacfix_kCdfShape +1368 +12,  WebRtcIsacfix_kCdfShape +1368 +14,  WebRtcIsacfix_kCdfShape +1368 +16,
+    WebRtcIsacfix_kCdfShape +1368 +20,  WebRtcIsacfix_kCdfShape +1368 +24,  WebRtcIsacfix_kCdfShape +1368 +28,
+    WebRtcIsacfix_kCdfShape +1368 +32,  WebRtcIsacfix_kCdfShape +1368 +36,  WebRtcIsacfix_kCdfShape +1368 +40,
+    WebRtcIsacfix_kCdfShape +1368 +44,  WebRtcIsacfix_kCdfShape +1368 +50,  WebRtcIsacfix_kCdfShape +1368 +57,
+    WebRtcIsacfix_kCdfShape +1368 +65,  WebRtcIsacfix_kCdfShape +1368 +67,  WebRtcIsacfix_kCdfShape +1368 +69,
+    WebRtcIsacfix_kCdfShape +1368 +71,  WebRtcIsacfix_kCdfShape +1368 +73,  WebRtcIsacfix_kCdfShape +1368 +75,
+    WebRtcIsacfix_kCdfShape +1368 +77,  WebRtcIsacfix_kCdfShape +1368 +79,  WebRtcIsacfix_kCdfShape +1368 +81,
+    WebRtcIsacfix_kCdfShape +1368 +85,  WebRtcIsacfix_kCdfShape +1368 +89,  WebRtcIsacfix_kCdfShape +1368 +93,
+    WebRtcIsacfix_kCdfShape +1368 +97,  WebRtcIsacfix_kCdfShape +1368 +101, WebRtcIsacfix_kCdfShape +1368 +105,
+    WebRtcIsacfix_kCdfShape +1368 +110, WebRtcIsacfix_kCdfShape +1368 +116, WebRtcIsacfix_kCdfShape +1368 +123,
+    WebRtcIsacfix_kCdfShape +1368 +132, WebRtcIsacfix_kCdfShape +1368 +134, WebRtcIsacfix_kCdfShape +1368 +136,
+    WebRtcIsacfix_kCdfShape +1368 +138, WebRtcIsacfix_kCdfShape +1368 +141, WebRtcIsacfix_kCdfShape +1368 +143,
+    WebRtcIsacfix_kCdfShape +1368 +146, WebRtcIsacfix_kCdfShape +1368 +150, WebRtcIsacfix_kCdfShape +1368 +154,
+    WebRtcIsacfix_kCdfShape +1368 +158, WebRtcIsacfix_kCdfShape +1368 +162, WebRtcIsacfix_kCdfShape +1368 +166,
+    WebRtcIsacfix_kCdfShape +1368 +170, WebRtcIsacfix_kCdfShape +1368 +174, WebRtcIsacfix_kCdfShape +1368 +179,
+    WebRtcIsacfix_kCdfShape +1368 +185, WebRtcIsacfix_kCdfShape +1368 +193, WebRtcIsacfix_kCdfShape +1368 +203,
+    WebRtcIsacfix_kCdfShape +1368 +214, WebRtcIsacfix_kCdfShape +1368 +216, WebRtcIsacfix_kCdfShape +1368 +218,
+    WebRtcIsacfix_kCdfShape +1368 +220, WebRtcIsacfix_kCdfShape +1368 +224, WebRtcIsacfix_kCdfShape +1368 +227,
+    WebRtcIsacfix_kCdfShape +1368 +231, WebRtcIsacfix_kCdfShape +1368 +235, WebRtcIsacfix_kCdfShape +1368 +239,
+    WebRtcIsacfix_kCdfShape +1368 +243, WebRtcIsacfix_kCdfShape +1368 +247, WebRtcIsacfix_kCdfShape +1368 +251,
+    WebRtcIsacfix_kCdfShape +1368 +256, WebRtcIsacfix_kCdfShape +1368 +262, WebRtcIsacfix_kCdfShape +1368 +269,
+    WebRtcIsacfix_kCdfShape +1368 +277, WebRtcIsacfix_kCdfShape +1368 +286, WebRtcIsacfix_kCdfShape +1368 +297,
+    WebRtcIsacfix_kCdfShape +1368 +315, WebRtcIsacfix_kCdfShape +1368 +317, WebRtcIsacfix_kCdfShape +1368 +319,
+    WebRtcIsacfix_kCdfShape +1368 +323, WebRtcIsacfix_kCdfShape +1368 +327, WebRtcIsacfix_kCdfShape +1368 +331,
+    WebRtcIsacfix_kCdfShape +1368 +335, WebRtcIsacfix_kCdfShape +1368 +339, WebRtcIsacfix_kCdfShape +1368 +343,
+    WebRtcIsacfix_kCdfShape +1368 +349, WebRtcIsacfix_kCdfShape +1368 +355, WebRtcIsacfix_kCdfShape +1368 +361,
+    WebRtcIsacfix_kCdfShape +1368 +368, WebRtcIsacfix_kCdfShape +1368 +376, WebRtcIsacfix_kCdfShape +1368 +385,
+    WebRtcIsacfix_kCdfShape +1368 +397, WebRtcIsacfix_kCdfShape +1368 +411, WebRtcIsacfix_kCdfShape +1368 +429,
+    WebRtcIsacfix_kCdfShape +1368 +456, WebRtcIsacfix_kCdfShape +1368 +459, WebRtcIsacfix_kCdfShape +1368 +463,
+    WebRtcIsacfix_kCdfShape +1368 +467, WebRtcIsacfix_kCdfShape +1368 +473, WebRtcIsacfix_kCdfShape +1368 +478,
+    WebRtcIsacfix_kCdfShape +1368 +485, WebRtcIsacfix_kCdfShape +1368 +491, WebRtcIsacfix_kCdfShape +1368 +497,
+    WebRtcIsacfix_kCdfShape +1368 +505, WebRtcIsacfix_kCdfShape +1368 +514, WebRtcIsacfix_kCdfShape +1368 +523,
+    WebRtcIsacfix_kCdfShape +1368 +535, WebRtcIsacfix_kCdfShape +1368 +548, WebRtcIsacfix_kCdfShape +1368 +565,
+    WebRtcIsacfix_kCdfShape +1368 +585, WebRtcIsacfix_kCdfShape +1368 +611, WebRtcIsacfix_kCdfShape +1368 +640
+  }
+};
+
+/* code length for all coefficients using different models */
+
+const WebRtc_Word16 WebRtcIsacfix_kCodeLenGainQ11[392] = {
+  25189, 16036,  8717,   358,  8757, 15706, 21456, 24397, 18502, 17559
+  , 13794, 11088,  7480,   873,  6603, 11636, 14627, 16805, 19132, 26624
+  , 26624, 19408, 13751,  7280,   583,  7591, 15178, 23773, 28672, 25189
+  , 19045, 16442, 13412, 10397,  5893,  1338,  6376,  9992, 12074, 13853
+  , 15781, 19821, 22819, 28672, 28672, 25189, 19858, 15781, 11262,  5477
+  ,  1298,  5632, 11814, 17234, 22020, 28672, 19677, 18125, 16587, 14521
+  , 13032, 11196,  9249,  5411,  2495,  4994,  7975, 10234, 12308, 13892
+  , 15148, 17944, 21725, 23917, 25189, 19539, 16293, 11531,  7808,  4475
+  ,  2739,  4872,  8089, 11314, 14992, 18105, 23257, 26624, 25189, 23257
+  , 23257, 20982, 18697, 18023, 16338, 16036, 14539, 13695, 13146, 11763
+  , 10754,  9074,  7260,  5584,  4430,  5553,  6848,  8344, 10141, 11636
+  , 12535, 13416, 14342, 15477, 17296, 19282, 22349, 23773, 28672, 28672
+  , 26624, 23773, 21456, 18023, 15118, 13362, 11212,  9293,  8043,  6985
+  ,  5908,  5721,  5853,  6518,  7316,  8360,  9716, 11289, 12912, 14652
+  , 16969, 19858, 23773, 26624, 28013, 30720, 30720, 28672, 25426, 23141
+  , 25426, 23773, 20720, 19408, 18697, 19282, 16859, 16338, 16026, 15377
+  , 15021, 14319, 14251, 13937, 13260, 13017, 12332, 11703, 11430, 10359
+  , 10128,  9405,  8757,  8223,  7974,  7859,  7646,  7673,  7997,  8580
+  ,  8880,  9061,  9866, 10397, 11358, 12200, 13244, 14157, 15021, 16026
+  , 16490, 18697, 18479, 20011, 19677, 20720, 24576, 26276, 30720, 30720
+  , 28672, 30720, 24068, 25189, 22437, 20345, 18479, 16396, 16026, 14928
+  , 13877, 13450, 12696, 12766, 11626, 11098, 10159,  9998,  9437,  9275
+  ,  8783,  8552,  8629,  8488,  8522,  8454,  8571,  8775,  8915,  9427
+  ,  9483,  9851, 10260, 10933, 11131, 11974, 12560, 13833, 15080, 16304
+  , 17491, 19017, 18697, 19408, 22020, 25189, 25426, 22819, 26276, 30720
+  , 30720, 30720, 30720, 30720, 30720, 28672, 30720, 30720, 30720, 30720
+  , 28013, 25426, 24397, 23773, 25189, 26624, 25189, 22437, 21725, 20011
+  , 20527, 20720, 20771, 22020, 22020, 19858, 19408, 19972, 17866, 17360
+  , 17791, 17219, 16805, 16927, 16067, 16162, 15661, 15178, 15021, 15209
+  , 14845, 14570, 14490, 14490, 13733, 13617, 13794, 13577, 13312, 12824
+  , 13032, 12683, 12189, 12469, 12109, 11940, 11636, 11617, 11932, 12294
+  , 11578, 11775, 12039, 11654, 11560, 11439, 11909, 11421, 12029, 11513
+  , 11773, 11899, 11560, 11805, 11476, 11664, 11963, 11647, 11754, 11963
+  , 11703, 12211, 11932, 12074, 12469, 12535, 12560, 12912, 12783, 12866
+  , 12884, 13378, 13957, 13775, 13635, 14019, 14545, 15240, 15520, 15554
+  , 15697, 16490, 16396, 17281, 16599, 16969, 17963, 16859, 16983, 16805
+  , 17099, 18210, 17219, 17646, 17700, 17646, 18297, 17425, 18479, 17791
+  , 17718, 19282, 18672, 20173, 20982, 21725, 21456, 23773, 23257, 25189
+  , 30720, 30720, 25189, 26624, 30720, 30720, 30720, 30720, 28672, 26276
+  , 30720, 30720
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kCodeLenShapeQ11[577] = {
+  0,     0,     0,     0,     0,     0,     0,     0,     0, 28672
+  ,     0, 26624,     1, 23773, 22819,     4, 20982, 18598,    10, 19282
+  , 16587,    22, 16442, 26624, 13126,    60, 14245, 26624, 26624, 12736
+  ,    79, 12912, 25189, 22819,  9563,   249,  9474, 22349, 28672, 23257
+  , 17944,  7980,   434,  8181, 16431, 26624,     0,     0,     0,     0
+  , 28672,     0,     0,     0,     0,     0, 28672,     0, 22437,     3
+  , 22437, 20982,     5, 20982, 16442,    22, 16752, 13814,    49, 14646
+  , 11645,   116, 11734, 26624, 28672, 10613,   158, 11010, 24397, 19539
+  ,  8046,   453,  7709, 19017, 28672, 23257, 15110,  6770,   758,  6523
+  , 14108, 24397, 28672,     0,     0,     0,     0, 28672,     0, 28672
+  ,     0, 26624,     1, 28672, 28672,     1, 26624, 24397,     2, 23257
+  , 21725,     4, 20982, 17158,    18, 17281, 28672, 15178,    35, 15209
+  , 12343,    92, 12320, 26624, 10344,   189, 10217, 30720, 22020,  9033
+  ,   322,  8549, 23773, 28672, 30720, 20622,  7666,   473,  7806, 20527
+  , 24397, 14135,  5995,   960,  6018, 14872, 23773, 26624, 20928, 16293
+  , 10636,  4926,  1588,  5256, 11088, 18043, 25189,     0,     0,     0
+  ,     0, 24397,     1, 25189, 20720,     5, 21456, 21209,     3, 25189
+  , 20982,     5, 21456, 15818,    30, 15410, 13794,    60, 13416, 28672
+  , 11162,   142, 11025,  9337,   231, 10094, 23773,  8338,   405,  7930
+  , 26624, 19677,  6787,   613,  7318, 19161, 28672, 16442,  6319,   932
+  ,  5748, 15312, 25189, 28672, 28672, 28672, 13998,  5513,  1263,  5146
+  , 14024, 24397, 22819, 15818,  9460,  4447,  2122,  4681,  9970, 15945
+  , 22349, 28672, 30720, 22622, 19017, 14872, 10689,  7405,  4473,  2983
+  ,  4783,  7894, 11186, 14964, 18210, 24397,     0,     0, 30720,     0
+  , 30720, 21456,     3, 23773, 14964,    39, 14757, 14179,    53, 13751
+  , 14928,    36, 15272, 12430,    79, 13228,  9135,   285,  9077, 28672
+  , 28672,  8377,   403,  7919, 26624, 28672, 23257,  7068,   560,  7473
+  , 20345, 19677,  6770,   720,  6464, 18697, 25189, 16249,  5779,  1087
+  ,  5494, 15209, 22819, 30720, 20622, 12601,  5240,  1419,  5091, 12095
+  , 19408, 26624, 22819, 16805, 10683,  4812,  2056,  4293,  9836, 16026
+  , 24397, 25189, 18409, 13833,  8681,  4503,  2653,  4220,  8329, 13853
+  , 19132, 26624, 25189, 20771, 17219, 12630,  9520,  6733,  4565,  3657
+  ,  4817,  7069, 10058, 13212, 16805, 21209, 26624, 26276, 28672, 28672
+  , 26276, 23257, 20173, 19282, 16538, 15051, 12811, 10754,  9267,  7547
+  ,  6270,  5407,  5214,  6057,  7054,  8226,  9488, 10806, 12793, 14442
+  , 16442, 19677, 22099, 26276, 28672,     0, 30720,     0, 30720, 11920
+  ,    56, 20720, 30720,  6766,   355, 13130, 30720, 30720, 22180,  5589
+  ,   736,  7902, 26624, 30720,  7634,   354,  9721, 30720, 30720,  9027
+  ,   246, 10117, 30720, 30720,  9630,   453,  6709, 23257, 30720, 25683
+  , 14228,  6127,  1271,  4615, 15178, 30720, 30720, 23504, 12382,  5739
+  ,  2015,  3492, 10560, 22020, 26624, 30720, 30720, 23257, 13192,  4873
+  ,  1527,  5001, 12445, 22020, 30720, 30720, 30720, 30720, 19344, 10761
+  ,  4051,  1927,  5281, 10594, 17866, 28672, 30720, 30720, 30720, 21869
+  , 15554, 10060,  5979,  2710,  3085,  7889, 14646, 21725, 28672, 30720
+  , 30720, 30720, 30720, 30720, 30720, 30720, 22719, 17425, 13212,  8083
+  ,  4439,  2820,  4305,  8136, 12988, 17425, 21151, 28672, 28672, 30720
+  , 30720, 30720, 28672, 20527, 19282, 14412, 10513,  7407,  5079,  3744
+  ,  4115,  6308,  9621, 13599, 17040, 22349, 28672, 30720, 30720, 30720
+  , 30720, 30720, 30720, 29522, 19282, 14545, 11485,  9093,  6760,  5262
+  ,  4672,  4970,  6005,  7852,  9732, 12343, 14672, 19161, 22819, 25189
+  , 30720, 30720, 28672, 30720, 30720, 20720, 18125, 14388, 12007,  9825
+  ,  8092,  7064,  6069,  5903,  5932,  6359,  7169,  8310,  9324, 10711
+  , 11867, 13096, 14157, 16338, 17040, 19161, 21725, 23773, 30720, 30720
+  , 26276, 25426, 24397, 28672, 28672, 23257, 22020, 22349, 18297, 17646
+  , 16983, 16431, 16162, 15021, 15178, 13751, 12142, 10895, 10193,  9632
+  ,  9086,  8896,  8823,  8735,  8591,  8754,  8649,  8361,  8329,  8522
+  ,  8373,  8739,  8993,  9657, 10454, 11279, 11899, 12614, 14024, 14273
+  , 15477, 15240, 16649, 17866, 18697, 21151, 22099
+};
+
+/* left KLT transforms */
+const WebRtc_Word16 WebRtcIsacfix_kT1GainQ15[3][4] = {
+  { -26130, 19773, 19773, 26130 },
+  { -26664, 19046, 19046, 26664 },
+  { -23538, 22797, 22797, 23538 }
+};
+
+
+
+const WebRtc_Word16 WebRtcIsacfix_kT1ShapeQ15[3][324] = {
+  { 52,16,168,7,439,-138,-89,306,671,882,
+    157,1301,291,1598,-3571,-1943,-1119,32404,96,-12,
+    379,-64,-307,345,-836,539,1045,2541,-2865,-992,
+    1683,-4717,5808,7427,30599,2319,183,-73,451,481,
+    933,-198,781,-397,1244,-777,3690,-2414,149,-1356,
+    -2593,-31140,8289,-1737,-202,-14,-214,360,501,450,
+    -245,-7,797,3638,-2804,3042,-337,22137,-22103,2264,
+    6838,-3381,305,172,263,-195,-355,351,179,513,
+    2234,3343,5509,7531,19075,-17740,-16836,2244,-629,-1505,
+    -153,108,124,-324,2694,-124,1492,-850,5347,4285,
+    7439,-10229,-22822,-12467,-12891,3645,822,-232,131,13,
+    374,565,536,4681,1294,-1935,1926,-5734,-10643,26462,
+    -12480,-5589,-1038,-2468,964,-704,-247,-106,186,-558,
+    -4050,3760,2972,2141,-7393,6294,26740,11991,-3251,5461,
+    5341,1574,2208,-51,-552,-297,-753,-154,2068,-5371,
+    3578,4106,28043,-10533,8041,2353,2389,4609,3410,1906,
+    351,-249,18,-15,1117,539,2870,9084,17585,-24528,
+    -366,-6490,2009,-3170,2942,1116,-232,1672,1065,606,
+    -399,-388,-518,38,3728,28948,-11936,4543,4104,-4441,
+    1545,-4044,1485,622,-68,186,-473,135,-280,125,
+    -546,-1813,6989,6606,23711,19376,-2636,2870,-4553,-1687,
+    878,-375,205,-208,-409,-108,-200,-45,-1670,-337,
+    8213,-5524,-2334,5240,-12939,-26205,5937,-1582,-592,-959,
+    -5374,2449,3400,559,349,-492,668,12379,-27684,3419,
+    5117,4415,-297,-8270,-1252,-3490,-1272,-1199,-3159,191,
+    630,488,-797,-3071,12912,-27783,-10249,1047,647,619,
+    111,-3722,-915,-1055,-502,5,-1384,-306,221,68,
+    5219,13173,-26474,-11663,-5626,927,806,-1127,236,-589,
+    -522,-230,-312,-315,-428,-573,426,192,-11830,-26883,
+    -14121,-2785,-1429,-109,410,-832,-302,539,-459,104,
+    1,-530,-202,-289,153,116,30082,-12944,-671,20,
+    649,98,103,215,234,0,280,-51,-169,298,
+    31,230,-73,-51
+  },
+  { -154,-7,-192,61,-739,-389,-947,-162,-60,94,
+    511,-716,1520,-1428,4168,-2214,1816,32270,-123,-77,
+    -199,-99,-42,-588,203,-240,-930,-35,1580,234,
+    3206,-5507,-1495,-10946,30000,-2667,-136,-176,-240,-175,
+    -204,-661,-1796,-1039,-1271,498,3143,734,2663,2699,
+    -8127,29333,10495,2356,-72,113,-91,118,-2840,-723,
+    -1733,-1158,-389,-2116,-3054,-3,-5179,8071,29546,6308,
+    5657,-3178,-186,-294,-473,-635,1213,-983,-1437,-1715,
+    -1094,1280,-92,-9573,948,29576,-7060,-5921,2954,1349,
+    -337,-108,-1099,962,418,-413,-1149,-334,1241,3975,
+    -6825,26725,-14377,7051,-4772,-1707,2335,2008,-150,570,
+    1371,42,-1649,-619,2039,3369,-1225,1583,-2755,-15207,
+    -27504,-4855,-4304,1495,2733,1324,15,-448,403,353,
+    3016,-1242,2338,2673,2064,-7496,-30447,-3686,5833,-1301,
+    -2455,2122,1519,608,43,-653,773,-3072,912,-1537,
+    4505,10284,30237,1549,3200,-691,205,1702,658,1014,
+    1499,148,79,-322,-1162,-4639,-813,7536,3204,29109,
+    -10747,-26,1611,2286,2114,2561,1022,372,348,207,
+    1062,-1088,-443,-9849,2381,5671,29097,-7612,-2927,3853,
+    194,1155,275,1438,1438,1312,581,888,-784,906,
+    112,-11103,25104,14438,-9311,-3068,1210,368,370,-940,
+    -2434,-1148,1925,392,657,258,-526,1475,-2281,-4265,
+    -1880,1534,2185,-1472,959,-30934,6306,3114,-4109,1768,
+    -2612,-703,45,644,2185,2033,5670,7211,19114,-22427,
+    6432,5150,-4090,-2694,3860,1245,-596,293,1829,369,
+    -319,229,-3256,2170,-6374,-26216,-4570,-16053,-5766,-262,
+    -2006,2873,-1477,147,378,-1544,-344,-544,-985,-481,
+    4210,4542,30757,-7291,-4863,1529,-2079,-628,-603,-783,
+    -408,1646,697,808,-620,-292,181,158,-13313,-29173,
+    5984,-1262,859,-1776,-558,-24,-883,-1421,739,210,
+    -531,-285,131,-160,-246,-56,29345,-13706,-2859,-2966,
+    -300,-970,-2382,-268,-103,-636,-12,-62,-691,-253,
+    -147,-127,27,66
+  },
+  { 55,-212,-198,489,-274,81,682,399,328,-934,
+    -389,-37,1357,-3632,5276,6581,-9493,-29921,29,-45,
+    2,190,172,-15,311,-130,-1085,-25,324,-684,
+    3223,-6580,4485,-5280,-29521,9933,82,-320,-530,229,
+    -705,-533,-414,848,-1842,-4473,1390,-857,6717,-6692,
+    4648,29397,576,8339,-68,-85,238,-330,264,-1012,
+    -381,-203,-3384,-3329,3906,6810,3790,-6250,28312,-8078,
+    8089,1565,160,-569,-612,-613,-1063,-1928,-1125,3421,
+    -7481,-7484,4942,-6984,4330,-25591,-10574,-6982,5682,-1781,
+    -308,89,178,-1715,-420,-3530,-5776,1219,-8617,-7137,
+    7015,4981,24875,12657,-5408,-3356,-785,-1972,326,-858,
+    -506,-3382,-986,-6258,-2259,4015,-8374,-10482,3127,23826,
+    -14126,-514,-5417,2178,-2912,-17,-587,80,67,-5881,
+    -1702,-5351,-4481,398,-10156,-225,20727,-15460,-11603,7752,
+    3660,1714,-2001,-359,499,-527,-1225,-7820,-1297,-6326,
+    -8526,7900,-18328,13311,-17488,-2926,-196,-17,2281,873,
+    480,-160,-624,471,780,-8729,1707,-14262,-20647,1721,
+    18590,-2206,-1214,-1066,312,-2602,783,-412,-113,49,
+    -119,1305,-2371,-15132,-1833,-18252,20295,-8316,2227,341,
+    -2074,-702,3082,-262,-465,-198,430,30,-70,-788,
+    2342,-25132,-4863,19783,-484,2137,2811,-1906,799,1586,
+    962,-734,-191,-30,-129,-93,-1126,1729,5860,-2030,
+    8953,603,-3338,-10869,-1144,22070,12130,10513,3191,-6881,
+    -3514,2090,711,-666,1843,-5997,-5681,2921,-17641,-2801,
+    4969,18590,7169,12214,8587,4405,3008,-1074,-371,-77,
+    253,331,-5611,5014,13152,-1985,18483,-1696,8043,20463,
+    2381,-393,1688,-1205,618,1220,457,248,-83,176,
+    7920,-13676,-22139,-3038,17402,2036,844,3258,994,719,
+    2087,-44,426,494,12,-91,46,5,-14204,22912,
+    -18156,-361,442,2298,-829,2229,386,1433,1335,1323,
+    55,-592,-139,49,-12,-57,27783,17134,350,-282,
+    552,158,142,2488,465,329,1087,118,143,10,
+    56,65,-15,-31
+  }
+};
+
+/* right KLT transforms */
+const WebRtc_Word16 WebRtcIsacfix_kT2GainQ15[3][36] = {
+  {   4775, -14892,  20313, -17104,  10533,  -3613,  -6782,  16044,  -8889,
+      -11019,  21330, -10720,  13193, -15678, -11101,  14461,  12250, -13096,
+      -16951,   2167,  16066,  15569,   -702, -16754, -19195, -12823,  -4321,
+      5128,    13348,  17825,  13232,  13404,  13494,  13490,  13383,  13261
+  },
+  {  -3725,  11408, -18493,  20031, -13097,   3865,   9344, -19294,  10740,
+     8856, -18432,   8982,  13975, -14444, -11930,  11774,  14285, -13594,
+     -16323,     -4,  16340,  15609,    359, -17220, -18401, -13471,  -4643,
+     5225,  13375,  18053,  13124,  13463,  13621,  13583,  13393,  13072
+  },
+  {  -3513,  11402, -17883,  19504, -14399,   4885,   8702, -19513,  12046,
+     8533, -18110,   8447,  12778, -14838, -12444,  13177,  14107, -12759,
+     -17268,    914,  15822,  15661,    838, -16686, -18907, -12936,  -4820,
+     4175,  12398,  18830,  12913,  13215,  13433,  13572,  13601,  13518
+  }
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kT2ShapeQ15[3][36] = {
+  {   4400, -11512,  17205, -19470,  14770,  -5345,   9784, -19222,  11228,
+      6842, -18371,   9909,  14191, -13496, -11563,  14015,  11827, -14839,
+      -15439,    948,  17802,  14827,  -2053, -17132,  18723,  14516,   4135,
+      -6822, -13869, -16016,  12975,  13341,  13563,  13603,  13478,  13296
+  },
+  {   5420, -14215,  19060, -18073,  11709,  -3911,   9645, -18335,   7717,
+      10842, -19283,   9777,  14898, -12555, -13661,  11668,  13520, -13733,
+      -15936,  -1358,  15671,  16728,    328, -17100,  17527,  13973,   5587,
+      -5194, -14165, -17677,  12970,  13446,  13693,  13660,  13462,  13015
+  },
+  {   4386, -12426,  18019, -18895,  13894,  -5034,   9713, -19270,  10283,
+      8692, -18439,   9317,  13992, -13454, -13241,  12850,  13366, -13336,
+      -16334,   -498,  15976,  16213,   -114, -16987,  18191,  13659,   4958,
+      -5116, -13444, -18021,  12911,  13424,  13718,  13674,  13464,  13054
+  }
+};
+
+/* means of log gains and LAR coefficients*/
+const WebRtc_Word16 WebRtcIsacfix_kMeansGainQ8[3][12] = {
+  { -1758, -1370, -1758, -1373, -1757, -1375,
+    -1758, -1374, -1758, -1373, -1755, -1370
+  },
+  { -1569, -1224, -1569, -1225, -1569, -1227,
+    -1569, -1226, -1567, -1225, -1565, -1224
+  },
+  { -1452,  -957, -1447,  -951, -1438,  -944,
+    -1431,  -938, -1419,  -931, -1406,  -926
+  }
+};
+
+
+const WebRtc_Word32 WebRtcIsacfix_kMeansShapeQ17[3][108] = {
+  { -119581, 34418, -44193, 11112, -4428, 18906, 9222, 8068, 1953, 5425,
+    1871, 1689, 109933, 33751, 10471, -2566, 1090, 2320, -119219, 33728,
+    -43759, 11450, -4870, 19117, 9174, 8037, 1972, 5331, 1872, 1843,
+    109899, 34301, 10629, -2316, 1272, 2562, -118608, 32318, -44012, 11591,
+    -4914, 18932, 9456, 8088, 1900, 5419, 1723, 1853, 109963, 35059,
+    10745, -2335, 1161, 2520, -119174, 32107, -44462, 11635, -4694, 18611,
+    9757, 8108, 1969, 5486, 1673, 1777, 109636, 34907, 10643, -2406,
+    1034, 2420, -118597, 32320, -44590, 10854, -4569, 18821, 9701, 7866,
+    2003, 5577, 1732, 1626, 109913, 34448, 10714, -2752, 990, 2228,
+    -118138, 32996, -44352, 10334, -3772, 18488, 9464, 7865, 2208, 5540,
+    1745, 1664, 109880, 33381, 10640, -2779, 980, 2054
+  },
+  { -146328, 46370, 1047, 26431, 10035, 13933, 6415, 14359, -2368, 6661,
+    2269, 1764, 96623, 7802, 4163, 10742, 1643, 2954, -146871, 46561, 1127,
+    26225, 10113, 14096, 6771, 14323, -2037, 6788, 2297, 1761, 96324, 8382,
+    4309, 10450, 1695, 3016, -146502, 46475, 1580, 26118, 10487, 14179, 6622,
+    14439, -2034, 6757, 2342, 1761, 95869, 8966, 4347, 10358, 1999, 2855,
+    -146958, 47717, 826, 25952, 10263, 14061, 5266, 13681, -2417, 6582, 2047,
+    1608, 96257, 9107, 4452, 10301, 1792, 2676, -146992, 47123, 446, 25822,
+    10405, 14292, 5140, 13804, -2403, 6496, 1834, 1735, 97489, 9253, 4414,
+    10684, 1549, 2721, -145811, 46182, 901, 26482, 10241, 14524, 6075, 14514,
+    -2147, 6691, 2196, 1899, 97011, 8178, 4102, 10758, 1638, 2869
+  },
+  { -166617, 46969, -43908, 17726, 6330, 25615, 6913, 5450, -2301, 1984,
+    507, 2883, 149998, 28709, 19333, 16703, 11093, 8965, -168254, 46604,
+    -44315, 17862, 6474, 25746, 7018, 5373, -2343, 1930, 513, 2819, 150391,
+    28627, 19194, 16678, 10998, 8929, -169093, 46084, -44767, 17427, 6401,
+    25674, 7147, 5472, -2336, 1820, 491, 2802, 149860, 28430, 19064, 16524,
+    10898, 8875, -170205, 46189, -44877, 17403, 6190, 25209, 7035, 5673, -2173,
+    1894, 574, 2756, 148830, 28230, 18819, 16418, 10789, 8811, -171263, 45045,
+    -44834, 16858, 6103, 24726, 7014, 5713, -2103, 1877, 518, 2729, 147073,
+    27744, 18629, 16277, 10690, 8703, -171720, 44153, -45062, 15951, 5872,
+    24429, 7044, 5585, -2082, 1807, 519, 2769, 144791, 27402, 18490, 16126,
+    10548, 8635
+  }
+};
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h b/src/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h
new file mode 100644
index 0000000..4f2e0e7
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * lpc_tables.h
+ *
+ * header file for coding tables for the LPC coefficients
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_
+
+#include "typedefs.h"
+
+
+/* indices of KLT coefficients used */
+extern const WebRtc_UWord16 WebRtcIsacfix_kSelIndGain[12];
+
+extern const WebRtc_UWord16 WebRtcIsacfix_kSelIndShape[108];
+
+/* cdf array for model indicator */
+extern const WebRtc_UWord16 WebRtcIsacfix_kModelCdf[KLT_NUM_MODELS+1];
+
+/* pointer to cdf array for model indicator */
+extern const WebRtc_UWord16 *WebRtcIsacfix_kModelCdfPtr[1];
+
+/* initial cdf index for decoder of model indicator */
+extern const WebRtc_UWord16 WebRtcIsacfix_kModelInitIndex[1];
+
+/* offset to go from rounded value to quantization index */
+extern const WebRtc_Word16 WebRtcIsacfix_kQuantMinGain[12];
+
+extern const WebRtc_Word16 WebRtcIsacfix_kQuantMinShape[108];
+
+/* maximum quantization index */
+extern const WebRtc_UWord16 WebRtcIsacfix_kMaxIndGain[12];
+
+extern const WebRtc_UWord16 WebRtcIsacfix_kMaxIndShape[108];
+
+/* index offset */
+extern const WebRtc_UWord16 WebRtcIsacfix_kOffsetGain[KLT_NUM_MODELS][12];
+
+extern const WebRtc_UWord16 WebRtcIsacfix_kOffsetShape[KLT_NUM_MODELS][108];
+
+/* initial cdf index for KLT coefficients */
+extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndexGain[KLT_NUM_MODELS][12];
+
+extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndexShape[KLT_NUM_MODELS][108];
+
+/* offsets for quantizer representation levels */
+extern const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsGain[3];
+
+extern const WebRtc_UWord16 WebRtcIsacfix_kOfLevelsShape[3];
+
+/* quantizer representation levels */
+extern const WebRtc_Word32 WebRtcIsacfix_kLevelsGainQ17[1176];
+
+extern const WebRtc_Word16 WebRtcIsacfix_kLevelsShapeQ10[1735];
+
+/* cdf tables for quantizer indices */
+extern const WebRtc_UWord16 WebRtcIsacfix_kCdfGain[1212];
+
+extern const WebRtc_UWord16 WebRtcIsacfix_kCdfShape[2059];
+
+/* pointers to cdf tables for quantizer indices */
+extern const WebRtc_UWord16 *WebRtcIsacfix_kCdfGainPtr[KLT_NUM_MODELS][12];
+
+extern const WebRtc_UWord16 *WebRtcIsacfix_kCdfShapePtr[KLT_NUM_MODELS][108];
+
+/* code length for all coefficients using different models */
+extern const WebRtc_Word16 WebRtcIsacfix_kCodeLenGainQ11[392];
+
+extern const WebRtc_Word16 WebRtcIsacfix_kCodeLenShapeQ11[577];
+
+/* left KLT transforms */
+extern const WebRtc_Word16 WebRtcIsacfix_kT1GainQ15[KLT_NUM_MODELS][4];
+
+extern const WebRtc_Word16 WebRtcIsacfix_kT1ShapeQ15[KLT_NUM_MODELS][324];
+
+/* right KLT transforms */
+extern const WebRtc_Word16 WebRtcIsacfix_kT2GainQ15[KLT_NUM_MODELS][36];
+
+extern const WebRtc_Word16 WebRtcIsacfix_kT2ShapeQ15[KLT_NUM_MODELS][36];
+
+/* means of log gains and LAR coefficients */
+extern const WebRtc_Word16 WebRtcIsacfix_kMeansGainQ8[KLT_NUM_MODELS][12];
+
+extern const WebRtc_Word32 WebRtcIsacfix_kMeansShapeQ17[3][108];
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c b/src/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
new file mode 100644
index 0000000..6af02d8
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
@@ -0,0 +1,551 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_estimator.c
+ *
+ * Pitch filter functions
+ *
+ */
+
+#ifdef WEBRTC_ARCH_ARM_NEON
+#include <arm_neon.h>
+#endif
+
+#include "pitch_estimator.h"
+#include "signal_processing_library.h"
+#include "system_wrappers/interface/compile_assert.h"
+
+/* log2[0.2, 0.5, 0.98] in Q8 */
+static const WebRtc_Word16 kLogLagWinQ8[3] = {
+  -594, -256, -7
+};
+
+/* [1 -0.75 0.25] in Q12 */
+static const WebRtc_Word16 kACoefQ12[3] = {
+  4096, -3072, 1024
+};
+
+
+
+static __inline WebRtc_Word32 Log2Q8( WebRtc_UWord32 x ) {
+
+  WebRtc_Word32 zeros, lg2;
+  WebRtc_Word16 frac;
+
+  zeros=WebRtcSpl_NormU32(x);
+  frac=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(((WebRtc_UWord32)(WEBRTC_SPL_LSHIFT_W32(x, zeros))&0x7FFFFFFF), 23);
+  /* log2(magn(i)) */
+
+  lg2= (WEBRTC_SPL_LSHIFT_W32((31-zeros), 8)+frac);
+  return lg2;
+
+}
+
+static __inline WebRtc_Word16 Exp2Q10(WebRtc_Word16 x) { // Both in and out in Q10
+
+  WebRtc_Word16 tmp16_1, tmp16_2;
+
+  tmp16_2=(WebRtc_Word16)(0x0400|(x&0x03FF));
+  tmp16_1=-(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(x,10);
+  if(tmp16_1>0)
+    return (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W16(tmp16_2, tmp16_1);
+  else
+    return (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W16(tmp16_2, -tmp16_1);
+
+}
+
+
+
+/* 1D parabolic interpolation . All input and output values are in Q8 */
+static __inline void Intrp1DQ8(WebRtc_Word32 *x, WebRtc_Word32 *fx, WebRtc_Word32 *y, WebRtc_Word32 *fy) {
+
+  WebRtc_Word16 sign1=1, sign2=1;
+  WebRtc_Word32 r32, q32, t32, nom32, den32;
+  WebRtc_Word16 t16, tmp16, tmp16_1;
+
+  if ((fx[0]>0) && (fx[2]>0)) {
+    r32=fx[1]-fx[2];
+    q32=fx[0]-fx[1];
+    nom32=q32+r32;
+    den32=WEBRTC_SPL_MUL_32_16((q32-r32), 2);
+    if (nom32<0)
+      sign1=-1;
+    if (den32<0)
+      sign2=-1;
+
+    /* t = (q32+r32)/(2*(q32-r32)) = (fx[0]-fx[1] + fx[1]-fx[2])/(2 * fx[0]-fx[1] - (fx[1]-fx[2]))*/
+    /* (Signs are removed because WebRtcSpl_DivResultInQ31 can't handle negative numbers) */
+    t32=WebRtcSpl_DivResultInQ31(WEBRTC_SPL_MUL_32_16(nom32, sign1),WEBRTC_SPL_MUL_32_16(den32, sign2)); /* t in Q31, without signs */
+
+    t16=(WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(t32, 23);  /* Q8 */
+    t16=t16*sign1*sign2;        /* t in Q8 with signs */
+
+    *y = x[0]+t16;          /* Q8 */
+    // *y = x[1]+t16;          /* Q8 */
+
+    /* The following code calculates fy in three steps */
+    /* fy = 0.5 * t * (t-1) * fx[0] + (1-t*t) * fx[1] + 0.5 * t * (t+1) * fx[2]; */
+
+    /* Part I: 0.5 * t * (t-1) * fx[0] */
+    tmp16_1=(WebRtc_Word16)WEBRTC_SPL_MUL_16_16(t16,t16); /* Q8*Q8=Q16 */
+    tmp16_1 = WEBRTC_SPL_RSHIFT_W16(tmp16_1,2);  /* Q16>>2 = Q14 */
+    t16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(t16, 64);           /* Q8<<6 = Q14  */
+    tmp16 = tmp16_1-t16;
+    *fy = WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[0]); /* (Q14 * Q8 >>15)/2 = Q8 */
+
+    /* Part II: (1-t*t) * fx[1] */
+    tmp16 = 16384-tmp16_1;        /* 1 in Q14 - Q14 */
+    *fy += WEBRTC_SPL_MUL_16_32_RSFT14(tmp16, fx[1]);/* Q14 * Q8 >> 14 = Q8 */
+
+    /* Part III: 0.5 * t * (t+1) * fx[2] */
+    tmp16 = tmp16_1+t16;
+    *fy += WEBRTC_SPL_MUL_16_32_RSFT15(tmp16, fx[2]);/* (Q14 * Q8 >>15)/2 = Q8 */
+  } else {
+    *y = x[0];
+    *fy= fx[1];
+  }
+}
+
+
+static void FindFour32(WebRtc_Word32 *in, WebRtc_Word16 length, WebRtc_Word16 *bestind)
+{
+  WebRtc_Word32 best[4]= {-100, -100, -100, -100};
+  WebRtc_Word16 k;
+
+  for (k=0; k<length; k++) {
+    if (in[k] > best[3]) {
+      if (in[k] > best[2]) {
+        if (in[k] > best[1]) {
+          if (in[k] > best[0]) { // The Best
+            best[3] = best[2];
+            bestind[3] = bestind[2];
+            best[2] = best[1];
+            bestind[2] = bestind[1];
+            best[1] = best[0];
+            bestind[1] = bestind[0];
+            best[0] = in[k];
+            bestind[0] = k;
+          } else { // 2nd best
+            best[3] = best[2];
+            bestind[3] = bestind[2];
+            best[2] = best[1];
+            bestind[2] = bestind[1];
+            best[1] = in[k];
+            bestind[1] = k;
+          }
+        } else { // 3rd best
+          best[3] = best[2];
+          bestind[3] = bestind[2];
+          best[2] = in[k];
+          bestind[2] = k;
+        }
+      } else {  // 4th best
+        best[3] = in[k];
+        bestind[3] = k;
+      }
+    }
+  }
+}
+
+
+
+
+
+static void PCorr2Q32(const WebRtc_Word16 *in, WebRtc_Word32 *logcorQ8)
+{
+  WebRtc_Word16 scaling,n,k;
+  WebRtc_Word32 ysum32,csum32, lys, lcs;
+  WebRtc_Word32 oneQ8;
+
+
+  const WebRtc_Word16 *x, *inptr;
+
+  oneQ8 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, 8);  // 1.00 in Q8
+
+  x = in + PITCH_MAX_LAG/2 + 2;
+  scaling = WebRtcSpl_GetScalingSquare ((WebRtc_Word16 *) in, PITCH_CORR_LEN2, PITCH_CORR_LEN2);
+  ysum32 = 1;
+  csum32 = 0;
+  x = in + PITCH_MAX_LAG/2 + 2;
+  for (n = 0; n < PITCH_CORR_LEN2; n++) {
+    ysum32 += WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[n],(WebRtc_Word16) in[n], scaling);  // Q0
+    csum32 += WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) x[n],(WebRtc_Word16) in[n], scaling); // Q0
+  }
+
+  logcorQ8 += PITCH_LAG_SPAN2 - 1;
+
+  lys=Log2Q8((WebRtc_UWord32) ysum32); // Q8
+  lys=WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
+
+  if (csum32>0) {
+
+    lcs=Log2Q8((WebRtc_UWord32) csum32);   // 2log(csum) in Q8
+
+    if (lcs>(lys + oneQ8) ){ // csum/sqrt(ysum) > 2 in Q8
+      *logcorQ8 = lcs - lys;  // log2(csum/sqrt(ysum))
+    } else {
+      *logcorQ8 = oneQ8;  // 1.00
+    }
+
+  } else {
+    *logcorQ8 = 0;
+  }
+
+
+  for (k = 1; k < PITCH_LAG_SPAN2; k++) {
+    inptr = &in[k];
+    ysum32 -= WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[k-1],(WebRtc_Word16) in[k-1], scaling);
+    ysum32 += WEBRTC_SPL_MUL_16_16_RSFT( (WebRtc_Word16) in[PITCH_CORR_LEN2 + k - 1],(WebRtc_Word16) in[PITCH_CORR_LEN2 + k - 1], scaling);
+
+#ifdef WEBRTC_ARCH_ARM_NEON
+    {
+      int32_t vbuff[4];
+      int32x4_t int_32x4_sum = vmovq_n_s32(0);
+      // Can't shift a Neon register to right with a non-constant shift value.
+      int32x4_t int_32x4_scale = vdupq_n_s32(-scaling);
+      // Assert a codition used in loop unrolling at compile-time.
+      COMPILE_ASSERT(PITCH_CORR_LEN2 %4 == 0);
+
+      for (n = 0; n < PITCH_CORR_LEN2; n += 4) {
+        int16x4_t int_16x4_x = vld1_s16(&x[n]);
+        int16x4_t int_16x4_in = vld1_s16(&inptr[n]);
+        int32x4_t int_32x4 = vmull_s16(int_16x4_x, int_16x4_in);
+        int_32x4 = vshlq_s32(int_32x4, int_32x4_scale);
+        int_32x4_sum = vaddq_s32(int_32x4_sum, int_32x4);
+      }
+
+      // Use vector store to avoid long stall from data trasferring
+      // from vector to general register.
+      vst1q_s32(vbuff, int_32x4_sum);
+      csum32 = vbuff[0] + vbuff[1];
+      csum32 += vbuff[2];
+      csum32 += vbuff[3];
+    }
+#else
+    csum32 = 0;
+    if(scaling == 0) {
+      for (n = 0; n < PITCH_CORR_LEN2; n++) {
+        csum32 += x[n] * inptr[n];
+      }
+    } else {
+      for (n = 0; n < PITCH_CORR_LEN2; n++) {
+        csum32 += (x[n] * inptr[n]) >> scaling;
+      }
+    }
+#endif
+
+    logcorQ8--;
+
+    lys=Log2Q8((WebRtc_UWord32)ysum32); // Q8
+    lys=WEBRTC_SPL_RSHIFT_W32(lys, 1); //sqrt(ysum);
+
+    if (csum32>0) {
+
+      lcs=Log2Q8((WebRtc_UWord32) csum32);   // 2log(csum) in Q8
+
+      if (lcs>(lys + oneQ8) ){ // csum/sqrt(ysum) > 2
+        *logcorQ8 = lcs - lys;  // log2(csum/sqrt(ysum))
+      } else {
+        *logcorQ8 = oneQ8;  // 1.00
+      }
+
+    } else {
+      *logcorQ8 = 0;
+    }
+  }
+}
+
+
+
+void WebRtcIsacfix_InitialPitch(const WebRtc_Word16 *in, /* Q0 */
+                                PitchAnalysisStruct *State,
+                                WebRtc_Word16 *lagsQ7                   /* Q7 */
+                                )
+{
+  WebRtc_Word16 buf_dec16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2+2];
+  WebRtc_Word32 *crrvecQ8_1,*crrvecQ8_2;
+  WebRtc_Word32 cv1q[PITCH_LAG_SPAN2+2],cv2q[PITCH_LAG_SPAN2+2], peakvq[PITCH_LAG_SPAN2+2];
+  int k;
+  WebRtc_Word16 peaks_indq;
+  WebRtc_Word16 peakiq[PITCH_LAG_SPAN2];
+  WebRtc_Word32 corr;
+  WebRtc_Word32 corr32, corr_max32, corr_max_o32;
+  WebRtc_Word16 npkq;
+  WebRtc_Word16 best4q[4]={0,0,0,0};
+  WebRtc_Word32 xq[3],yq[1],fyq[1];
+  WebRtc_Word32 *fxq;
+  WebRtc_Word32 best_lag1q, best_lag2q;
+  WebRtc_Word32 tmp32a,tmp32b,lag32,ratq;
+  WebRtc_Word16 start;
+  WebRtc_Word16 oldgQ12, tmp16a, tmp16b, gain_bias16,tmp16c, tmp16d, bias16;
+  WebRtc_Word32 tmp32c,tmp32d, tmp32e;
+  WebRtc_Word16 old_lagQ;
+  WebRtc_Word32 old_lagQ8;
+  WebRtc_Word32 lagsQ8[4];
+
+  old_lagQ = State->PFstr_wght.oldlagQ7; // Q7
+  old_lagQ8= WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)old_lagQ,1); //Q8
+
+  oldgQ12= State->PFstr_wght.oldgainQ12;
+
+  crrvecQ8_1=&cv1q[1];
+  crrvecQ8_2=&cv2q[1];
+
+
+  /* copy old values from state buffer */
+  memcpy(buf_dec16, State->dec_buffer16, WEBRTC_SPL_MUL_16_16(sizeof(WebRtc_Word16), (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2)));
+
+  /* decimation; put result after the old values */
+  WebRtcIsacfix_DecimateAllpass32(in, State->decimator_state32, PITCH_FRAME_LEN,
+                                  &buf_dec16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2]);
+
+  /* low-pass filtering */
+  start= PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2;
+  WebRtcSpl_FilterARFastQ12(&buf_dec16[start],&buf_dec16[start],(WebRtc_Word16*)kACoefQ12,3, PITCH_FRAME_LEN/2);
+
+  /* copy end part back into state buffer */
+  for (k = 0; k < (PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2); k++)
+    State->dec_buffer16[k] = buf_dec16[k+PITCH_FRAME_LEN/2];
+
+
+  /* compute correlation for first and second half of the frame */
+  PCorr2Q32(buf_dec16, crrvecQ8_1);
+  PCorr2Q32(buf_dec16 + PITCH_CORR_STEP2, crrvecQ8_2);
+
+
+  /* bias towards pitch lag of previous frame */
+  tmp32a = Log2Q8((WebRtc_UWord32) old_lagQ8) - 2304; // log2(0.5*oldlag) in Q8
+  tmp32b = WEBRTC_SPL_MUL_16_16_RSFT(oldgQ12,oldgQ12, 10); //Q12 & * 4.0;
+  gain_bias16 = (WebRtc_Word16) tmp32b;  //Q12
+  if (gain_bias16 > 3276) gain_bias16 = 3276; // 0.8 in Q12
+
+
+  for (k = 0; k < PITCH_LAG_SPAN2; k++)
+  {
+    if (crrvecQ8_1[k]>0) {
+      tmp32b = Log2Q8((WebRtc_UWord32) (k + (PITCH_MIN_LAG/2-2)));
+      tmp16a = (WebRtc_Word16) (tmp32b - tmp32a); // Q8 & fabs(ratio)<4
+      tmp32c = WEBRTC_SPL_MUL_16_16_RSFT(tmp16a,tmp16a, 6); //Q10
+      tmp16b = (WebRtc_Word16) tmp32c; // Q10 & <8
+      tmp32d = WEBRTC_SPL_MUL_16_16_RSFT(tmp16b, 177 , 8); // mult with ln2 in Q8
+      tmp16c = (WebRtc_Word16) tmp32d; // Q10 & <4
+      tmp16d = Exp2Q10((WebRtc_Word16) -tmp16c); //Q10
+      tmp32c = WEBRTC_SPL_MUL_16_16_RSFT(gain_bias16,tmp16d,13); // Q10  & * 0.5
+      bias16 = (WebRtc_Word16) (1024 + tmp32c); // Q10
+      tmp32b = Log2Q8((WebRtc_UWord32) bias16) - 2560; // Q10 in -> Q8 out with 10*2^8 offset
+      crrvecQ8_1[k] += tmp32b ; // -10*2^8 offset
+    }
+  }
+
+  /* taper correlation functions */
+  for (k = 0; k < 3; k++) {
+    crrvecQ8_1[k] += kLogLagWinQ8[k];
+    crrvecQ8_2[k] += kLogLagWinQ8[k];
+
+    crrvecQ8_1[PITCH_LAG_SPAN2-1-k] += kLogLagWinQ8[k];
+    crrvecQ8_2[PITCH_LAG_SPAN2-1-k] += kLogLagWinQ8[k];
+  }
+
+
+  /* Make zeropadded corr vectors */
+  cv1q[0]=0;
+  cv2q[0]=0;
+  cv1q[PITCH_LAG_SPAN2+1]=0;
+  cv2q[PITCH_LAG_SPAN2+1]=0;
+  corr_max32 = 0;
+
+  for (k = 1; k <= PITCH_LAG_SPAN2; k++)
+  {
+
+
+    corr32=crrvecQ8_1[k-1];
+    if (corr32 > corr_max32)
+      corr_max32 = corr32;
+
+    corr32=crrvecQ8_2[k-1];
+    corr32 += -4; // Compensate for later (log2(0.99))
+
+    if (corr32 > corr_max32)
+      corr_max32 = corr32;
+
+  }
+
+  /* threshold value to qualify as a peak */
+  // corr_max32 += -726; // log(0.14)/log(2.0) in Q8
+  corr_max32 += -1000; // log(0.14)/log(2.0) in Q8
+  corr_max_o32 = corr_max32;
+
+
+  /* find peaks in corr1 */
+  peaks_indq = 0;
+  for (k = 1; k <= PITCH_LAG_SPAN2; k++)
+  {
+    corr32=cv1q[k];
+    if (corr32>corr_max32) { // Disregard small peaks
+      if ((corr32>=cv1q[k-1]) && (corr32>cv1q[k+1])) { // Peak?
+        peakvq[peaks_indq] = corr32;
+        peakiq[peaks_indq++] = k;
+      }
+    }
+  }
+
+
+  /* find highest interpolated peak */
+  corr_max32=0;
+  best_lag1q =0;
+  if (peaks_indq > 0) {
+    FindFour32(peakvq, (WebRtc_Word16) peaks_indq, best4q);
+    npkq = WEBRTC_SPL_MIN(peaks_indq, 4);
+
+    for (k=0;k<npkq;k++) {
+
+      lag32 =  peakiq[best4q[k]];
+      fxq = &cv1q[peakiq[best4q[k]]-1];
+      xq[0]= lag32;
+      xq[0] = WEBRTC_SPL_LSHIFT_W32(xq[0], 8);
+      Intrp1DQ8(xq, fxq, yq, fyq);
+
+      tmp32a= Log2Q8((WebRtc_UWord32) *yq) - 2048; // offset 8*2^8
+      /* Bias towards short lags */
+      /* log(pow(0.8, log(2.0 * *y )))/log(2.0) */
+      tmp32b= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32a, -42, 8);
+      tmp32c= tmp32b + 256;
+      *fyq += tmp32c;
+      if (*fyq > corr_max32) {
+        corr_max32 = *fyq;
+        best_lag1q = *yq;
+      }
+    }
+    tmp32a = best_lag1q - OFFSET_Q8;
+    tmp32b = WEBRTC_SPL_LSHIFT_W32(tmp32a, 1);
+    lagsQ8[0] = tmp32b + PITCH_MIN_LAG_Q8;
+    lagsQ8[1] = lagsQ8[0];
+  } else {
+    lagsQ8[0] = old_lagQ8;
+    lagsQ8[1] = lagsQ8[0];
+  }
+
+  /* Bias towards constant pitch */
+  tmp32a = lagsQ8[0] - PITCH_MIN_LAG_Q8;
+  ratq = WEBRTC_SPL_RSHIFT_W32(tmp32a, 1) + OFFSET_Q8;
+
+  for (k = 1; k <= PITCH_LAG_SPAN2; k++)
+  {
+    tmp32a = WEBRTC_SPL_LSHIFT_W32(k, 7); // 0.5*k Q8
+    tmp32b = (WebRtc_Word32) (WEBRTC_SPL_LSHIFT_W32(tmp32a, 1)) - ratq; // Q8
+    tmp32c = WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32b, (WebRtc_Word16) tmp32b, 8); // Q8
+
+    tmp32b = (WebRtc_Word32) tmp32c + (WebRtc_Word32)  WEBRTC_SPL_RSHIFT_W32(ratq, 1); // (k-r)^2 + 0.5 * r  Q8
+    tmp32c = Log2Q8((WebRtc_UWord32) tmp32a) - 2048; // offset 8*2^8 , log2(0.5*k) Q8
+    tmp32d = Log2Q8((WebRtc_UWord32) tmp32b) - 2048; // offset 8*2^8 , log2(0.5*k) Q8
+    tmp32e =  tmp32c -tmp32d;
+
+    cv2q[k] += WEBRTC_SPL_RSHIFT_W32(tmp32e, 1);
+
+  }
+
+  /* find peaks in corr2 */
+  corr_max32 = corr_max_o32;
+  peaks_indq = 0;
+
+  for (k = 1; k <= PITCH_LAG_SPAN2; k++)
+  {
+    corr=cv2q[k];
+    if (corr>corr_max32) { // Disregard small peaks
+      if ((corr>=cv2q[k-1]) && (corr>cv2q[k+1])) { // Peak?
+        peakvq[peaks_indq] = corr;
+        peakiq[peaks_indq++] = k;
+      }
+    }
+  }
+
+
+
+  /* find highest interpolated peak */
+  corr_max32 = 0;
+  best_lag2q =0;
+  if (peaks_indq > 0) {
+
+    FindFour32(peakvq, (WebRtc_Word16) peaks_indq, best4q);
+    npkq = WEBRTC_SPL_MIN(peaks_indq, 4);
+    for (k=0;k<npkq;k++) {
+
+      lag32 =  peakiq[best4q[k]];
+      fxq = &cv2q[peakiq[best4q[k]]-1];
+
+      xq[0]= lag32;
+      xq[0] = WEBRTC_SPL_LSHIFT_W32(xq[0], 8);
+      Intrp1DQ8(xq, fxq, yq, fyq);
+
+      /* Bias towards short lags */
+      /* log(pow(0.8, log(2.0f * *y )))/log(2.0f) */
+      tmp32a= Log2Q8((WebRtc_UWord32) *yq) - 2048; // offset 8*2^8
+      tmp32b= WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16) tmp32a, -82, 8);
+      tmp32c= tmp32b + 256;
+      *fyq += tmp32c;
+      if (*fyq > corr_max32) {
+        corr_max32 = *fyq;
+        best_lag2q = *yq;
+      }
+    }
+
+    tmp32a = best_lag2q - OFFSET_Q8;
+    tmp32b = WEBRTC_SPL_LSHIFT_W32(tmp32a, 1);
+    lagsQ8[2] = tmp32b + PITCH_MIN_LAG_Q8;
+    lagsQ8[3] = lagsQ8[2];
+  } else {
+    lagsQ8[2] = lagsQ8[0];
+    lagsQ8[3] = lagsQ8[0];
+  }
+
+  lagsQ7[0]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[0], 1);
+  lagsQ7[1]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[1], 1);
+  lagsQ7[2]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[2], 1);
+  lagsQ7[3]=(WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(lagsQ8[3], 1);
+
+
+}
+
+
+
+void WebRtcIsacfix_PitchAnalysis(const WebRtc_Word16 *inn,               /* PITCH_FRAME_LEN samples */
+                                 WebRtc_Word16 *outQ0,                  /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
+                                 PitchAnalysisStruct *State,
+                                 WebRtc_Word16 *PitchLags_Q7,
+                                 WebRtc_Word16 *PitchGains_Q12)
+{
+  WebRtc_Word16 inbufQ0[PITCH_FRAME_LEN + QLOOKAHEAD];
+  WebRtc_Word16 k;
+
+  /* inital pitch estimate */
+  WebRtcIsacfix_InitialPitch(inn, State,  PitchLags_Q7);
+
+
+  /* Calculate gain */
+  WebRtcIsacfix_PitchFilterGains(inn, &(State->PFstr_wght), PitchLags_Q7, PitchGains_Q12);
+
+  /* concatenate previous input's end and current input */
+  for (k = 0; k < QLOOKAHEAD; k++) {
+    inbufQ0[k] = State->inbuf[k];
+  }
+  for (k = 0; k < PITCH_FRAME_LEN; k++) {
+    inbufQ0[k+QLOOKAHEAD] = (WebRtc_Word16) inn[k];
+  }
+
+  /* lookahead pitch filtering for masking analysis */
+  WebRtcIsacfix_PitchFilter(inbufQ0, outQ0, &(State->PFstr), PitchLags_Q7,PitchGains_Q12, 2);
+
+
+  /* store last part of input */
+  for (k = 0; k < QLOOKAHEAD; k++) {
+    State->inbuf[k] = inbufQ0[k + PITCH_FRAME_LEN];
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h b/src/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h
new file mode 100644
index 0000000..6225256
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_estimator.h
+ *
+ * Pitch functions
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_
+
+#include "structs.h"
+
+void WebRtcIsacfix_PitchAnalysis(const WebRtc_Word16 *in,               /* PITCH_FRAME_LEN samples */
+                                 WebRtc_Word16 *outQ0,                  /* PITCH_FRAME_LEN+QLOOKAHEAD samples */
+                                 PitchAnalysisStruct *State,
+                                 WebRtc_Word16 *lagsQ7,
+                                 WebRtc_Word16 *PitchGains_Q12);
+
+void WebRtcIsacfix_InitialPitch(const WebRtc_Word16 *in,
+                                PitchAnalysisStruct *State,
+                                WebRtc_Word16 *qlags);
+
+void WebRtcIsacfix_PitchFilter(WebRtc_Word16 *indatFix,
+                               WebRtc_Word16 *outdatQQ,
+                               PitchFiltstr *pfp,
+                               WebRtc_Word16 *lagsQ7,
+                               WebRtc_Word16 *gainsQ12,
+                               WebRtc_Word16 type);
+
+void WebRtcIsacfix_PitchFilterCore(int loopNumber,
+                                   WebRtc_Word16 gain,
+                                   int index,
+                                   WebRtc_Word16 sign,
+                                   WebRtc_Word16* inputState,
+                                   WebRtc_Word16* outputBuff2,
+                                   const WebRtc_Word16* coefficient,
+                                   WebRtc_Word16* inputBuf,
+                                   WebRtc_Word16* outputBuf,
+                                   int* index2);
+
+void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16 *indatQ0,
+                                    PitchFiltstr *pfp,
+                                    WebRtc_Word16 *lagsQ7,
+                                    WebRtc_Word16 *gainsQ12);
+
+void WebRtcIsacfix_DecimateAllpass32(const WebRtc_Word16 *in,
+                                     WebRtc_Word32 *state_in,        /* array of size: 2*ALLPASSSECTIONS+1 */
+                                     WebRtc_Word16 N,                   /* number of input samples */
+                                     WebRtc_Word16 *out);             /* array of size N/2 */
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_ESTIMATOR_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c b/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
new file mode 100644
index 0000000..f30293e
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
@@ -0,0 +1,280 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_filter.c
+ *
+ * Pitch filter functions
+ *
+ */
+
+#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
+#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
+#include "modules/audio_coding/codecs/isac/fix/source/structs.h"
+#include "system_wrappers/interface/compile_assert.h"
+
+// Number of segments in a pitch subframe.
+static const int kSegments = 5;
+
+// A division factor of 1/5 in Q15.
+static const WebRtc_Word16 kDivFactor = 6553;
+
+// Filter coefficicients in Q15.
+static const WebRtc_Word16 kDampFilter[PITCH_DAMPORDER] = {
+  -2294, 8192, 20972, 8192, -2294
+};
+
+// Interpolation coefficients; generated by design_pitch_filter.m.
+// Coefficients are stored in Q14.
+static const WebRtc_Word16 kIntrpCoef[PITCH_FRACS][PITCH_FRACORDER] = {
+  {-367, 1090, -2706,  9945, 10596, -3318,  1626, -781,  287},
+  {-325,  953, -2292,  7301, 12963, -3320,  1570, -743,  271},
+  {-240,  693, -1622,  4634, 14809, -2782,  1262, -587,  212},
+  {-125,  358,  -817,  2144, 15982, -1668,   721, -329,  118},
+  {   0,    0,    -1,     1, 16380,     1,    -1,    0,    0},
+  { 118, -329,   721, -1668, 15982,  2144,  -817,  358, -125},
+  { 212, -587,  1262, -2782, 14809,  4634, -1622,  693, -240},
+  { 271, -743,  1570, -3320, 12963,  7301, -2292,  953, -325}
+};
+
+// Function prototype for pitch filtering.
+// TODO(Turaj): Add descriptions of input and output parameters.
+void WebRtcIsacfix_PitchFilterCore(int loopNumber,
+                                   WebRtc_Word16 gain,
+                                   int index,
+                                   WebRtc_Word16 sign,
+                                   WebRtc_Word16* inputState,
+                                   WebRtc_Word16* outputBuf2,
+                                   const WebRtc_Word16* coefficient,
+                                   WebRtc_Word16* inputBuf,
+                                   WebRtc_Word16* outputBuf,
+                                   int* index2);
+
+static __inline WebRtc_Word32 CalcLrIntQ(WebRtc_Word32 fixVal,
+                                         WebRtc_Word16 qDomain) {
+  WebRtc_Word32 intgr;
+  WebRtc_Word32 roundVal;
+
+  roundVal = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1,  qDomain - 1);
+  intgr = WEBRTC_SPL_RSHIFT_W32(fixVal + roundVal, qDomain);
+
+  return intgr;
+}
+
+void WebRtcIsacfix_PitchFilter(WebRtc_Word16* indatQQ, // Q10 if type is 1 or 4,
+                                                       // Q0 if type is 2.
+                               WebRtc_Word16* outdatQQ,
+                               PitchFiltstr* pfp,
+                               WebRtc_Word16* lagsQ7,
+                               WebRtc_Word16* gainsQ12,
+                               WebRtc_Word16 type) {
+  int    k, ind, cnt;
+  WebRtc_Word16 sign = 1;
+  WebRtc_Word16 inystateQQ[PITCH_DAMPORDER];
+  WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE + QLOOKAHEAD];
+  const WebRtc_Word16 Gain = 21299;     // 1.3 in Q14
+  WebRtc_Word16 oldLagQ7;
+  WebRtc_Word16 oldGainQ12, lagdeltaQ7, curLagQ7, gaindeltaQ12, curGainQ12;
+  int indW32 = 0, frcQQ = 0;
+  WebRtc_Word32 tmpW32;
+  const WebRtc_Word16* fracoeffQQ = NULL;
+
+  // Assumptions in ARM assembly for WebRtcIsacfix_PitchFilterCoreARM().
+  COMPILE_ASSERT(PITCH_FRACORDER == 9);
+  COMPILE_ASSERT(PITCH_DAMPORDER == 5);
+
+  // Set up buffer and states.
+  memcpy(ubufQQ, pfp->ubufQQ, sizeof(pfp->ubufQQ));
+  memcpy(inystateQQ, pfp->ystateQQ, sizeof(inystateQQ));
+
+  // Get old lag and gain value from memory.
+  oldLagQ7 = pfp->oldlagQ7;
+  oldGainQ12 = pfp->oldgainQ12;
+
+  if (type == 4) {
+    sign = -1;
+
+    // Make output more periodic.
+    for (k = 0; k < PITCH_SUBFRAMES; k++) {
+      gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+          gainsQ12[k], Gain, 14);
+    }
+  }
+
+  // No interpolation if pitch lag step is big.
+  if ((WEBRTC_SPL_MUL_16_16_RSFT(lagsQ7[0], 3, 1) < oldLagQ7) ||
+      (lagsQ7[0] > WEBRTC_SPL_MUL_16_16_RSFT(oldLagQ7, 3, 1))) {
+    oldLagQ7 = lagsQ7[0];
+    oldGainQ12 = gainsQ12[0];
+  }
+
+  ind = 0;
+
+  for (k = 0; k < PITCH_SUBFRAMES; k++) {
+    // Calculate interpolation steps.
+    lagdeltaQ7 = lagsQ7[k] - oldLagQ7;
+    lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
+                  lagdeltaQ7, kDivFactor, 15);
+    curLagQ7 = oldLagQ7;
+    gaindeltaQ12 = gainsQ12[k] - oldGainQ12;
+    gaindeltaQ12 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(
+                    gaindeltaQ12, kDivFactor, 15);
+
+    curGainQ12 = oldGainQ12;
+    oldLagQ7 = lagsQ7[k];
+    oldGainQ12 = gainsQ12[k];
+
+    // Each frame has 4 60-sample pitch subframes, and each subframe has 5
+    // 12-sample segments. Each segment need to be processed with
+    // newly-updated parameters, so we break the pitch filtering into
+    // two for-loops (5 x 12) below. It's also why kDivFactor = 0.2 (in Q15).
+    for (cnt = 0; cnt < kSegments; cnt++) {
+      // Update parameters for each segment.
+      curGainQ12 += gaindeltaQ12;
+      curLagQ7 += lagdeltaQ7;
+      indW32 = CalcLrIntQ(curLagQ7, 7);
+      tmpW32 = WEBRTC_SPL_LSHIFT_W32(indW32, 7);
+      tmpW32 -= curLagQ7;
+      frcQQ = WEBRTC_SPL_RSHIFT_W32(tmpW32, 4);
+      frcQQ += 4;
+
+      if (frcQQ == PITCH_FRACS) {
+        frcQQ = 0;
+      }
+      fracoeffQQ = kIntrpCoef[frcQQ];
+
+      // Pitch filtering.
+      WebRtcIsacfix_PitchFilterCore(PITCH_SUBFRAME_LEN / kSegments, curGainQ12,
+        indW32, sign, inystateQQ, ubufQQ, fracoeffQQ, indatQQ, outdatQQ, &ind);
+    }
+  }
+
+  // Export buffer and states.
+  memcpy(pfp->ubufQQ, ubufQQ + PITCH_FRAME_LEN, sizeof(pfp->ubufQQ));
+  memcpy(pfp->ystateQQ, inystateQQ, sizeof(pfp->ystateQQ));
+
+  pfp->oldlagQ7 = oldLagQ7;
+  pfp->oldgainQ12 = oldGainQ12;
+
+  if (type == 2) {
+    // Filter look-ahead segment.
+    WebRtcIsacfix_PitchFilterCore(QLOOKAHEAD, curGainQ12, indW32, 1, inystateQQ,
+                ubufQQ, fracoeffQQ, indatQQ, outdatQQ, &ind);
+  }
+}
+
+
+void WebRtcIsacfix_PitchFilterGains(const WebRtc_Word16* indatQ0,
+                                    PitchFiltstr* pfp,
+                                    WebRtc_Word16* lagsQ7,
+                                    WebRtc_Word16* gainsQ12) {
+  int  k, n, m, ind, pos, pos3QQ;
+
+  WebRtc_Word16 ubufQQ[PITCH_INTBUFFSIZE];
+  WebRtc_Word16 oldLagQ7, lagdeltaQ7, curLagQ7;
+  const WebRtc_Word16* fracoeffQQ = NULL;
+  WebRtc_Word16 scale;
+  WebRtc_Word16 cnt = 0, frcQQ, indW16 = 0, tmpW16;
+  WebRtc_Word32 tmpW32, tmp2W32, csum1QQ, esumxQQ;
+
+  // Set up buffer and states.
+  memcpy(ubufQQ, pfp->ubufQQ, sizeof(pfp->ubufQQ));
+  oldLagQ7 = pfp->oldlagQ7;
+
+  // No interpolation if pitch lag step is big.
+  if ((WEBRTC_SPL_MUL_16_16_RSFT(lagsQ7[0], 3, 1) < oldLagQ7) ||
+      (lagsQ7[0] > WEBRTC_SPL_MUL_16_16_RSFT(oldLagQ7, 3, 1))) {
+    oldLagQ7 = lagsQ7[0];
+  }
+
+  ind = 0;
+  pos = ind + PITCH_BUFFSIZE;
+  scale = 0;
+  for (k = 0; k < PITCH_SUBFRAMES; k++) {
+
+    // Calculate interpolation steps.
+    lagdeltaQ7 = lagsQ7[k] - oldLagQ7;
+    lagdeltaQ7 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
+                   lagdeltaQ7, kDivFactor, 15);
+    curLagQ7 = oldLagQ7;
+    oldLagQ7 = lagsQ7[k];
+
+    csum1QQ = 1;
+    esumxQQ = 1;
+
+    // Same as function WebRtcIsacfix_PitchFilter(), we break the pitch
+    // filtering into two for-loops (5 x 12) below.
+    for (cnt = 0; cnt < kSegments; cnt++) {
+      // Update parameters for each segment.
+      curLagQ7 += lagdeltaQ7;
+      indW16 = (WebRtc_Word16)CalcLrIntQ(curLagQ7, 7);
+      tmpW16 = WEBRTC_SPL_LSHIFT_W16(indW16, 7);
+      tmpW16 -= curLagQ7;
+      frcQQ = WEBRTC_SPL_RSHIFT_W16(tmpW16, 4);
+      frcQQ += 4;
+
+      if (frcQQ == PITCH_FRACS) {
+        frcQQ = 0;
+      }
+      fracoeffQQ = kIntrpCoef[frcQQ];
+
+      pos3QQ = pos - (indW16 + 4);
+
+      for (n = 0; n < PITCH_SUBFRAME_LEN / kSegments; n++) {
+        // Filter to get fractional pitch.
+
+        tmpW32 = 0;
+        for (m = 0; m < PITCH_FRACORDER; m++) {
+          tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQ[pos3QQ + m], fracoeffQQ[m]);
+        }
+
+        // Subtract from input and update buffer.
+        ubufQQ[pos] = indatQ0[ind];
+
+        tmp2W32 = WEBRTC_SPL_MUL_16_32_RSFT14(indatQ0[ind], tmpW32);
+        tmpW32 += 8192;
+        tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
+        tmpW32 = WEBRTC_SPL_MUL_16_16(tmpW16, tmpW16);
+
+        if ((tmp2W32 > 1073700000) || (csum1QQ > 1073700000) ||
+            (tmpW32 > 1073700000) || (esumxQQ > 1073700000)) {  // 2^30
+          scale++;
+          csum1QQ = WEBRTC_SPL_RSHIFT_W32(csum1QQ, 1);
+          esumxQQ = WEBRTC_SPL_RSHIFT_W32(esumxQQ, 1);
+        }
+        tmp2W32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, scale);
+        csum1QQ += tmp2W32;
+        tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmpW32, scale);
+        esumxQQ += tmpW32;
+
+        ind++;
+        pos++;
+        pos3QQ++;
+      }
+    }
+
+    if (csum1QQ < esumxQQ) {
+      tmp2W32 = WebRtcSpl_DivResultInQ31(csum1QQ, esumxQQ);
+
+      // Gain should be half the correlation.
+      tmpW32 = WEBRTC_SPL_RSHIFT_W32(tmp2W32, 20);
+    } else {
+      tmpW32 = 4096;
+    }
+    gainsQ12[k] = (WebRtc_Word16)WEBRTC_SPL_SAT(PITCH_MAX_GAIN_Q12, tmpW32, 0);
+  }
+
+  // Export buffer and states.
+  memcpy(pfp->ubufQQ, ubufQQ + PITCH_FRAME_LEN, sizeof(pfp->ubufQQ));
+  pfp->oldlagQ7 = lagsQ7[PITCH_SUBFRAMES - 1];
+  pfp->oldgainQ12 = gainsQ12[PITCH_SUBFRAMES - 1];
+
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter_armv6.S b/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter_armv6.S
new file mode 100644
index 0000000..7ce3b6f
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter_armv6.S
@@ -0,0 +1,147 @@
+@
+@ Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+@
+@ Use of this source code is governed by a BSD-style license
+@ that can be found in the LICENSE file in the root of the source
+@ tree. An additional intellectual property rights grant can be found
+@ in the file PATENTS.  All contributing project authors may
+@ be found in the AUTHORS file in the root of the source tree.
+@
+
+@ Contains the core loop routine for the pitch filter function in iSAC,
+@ optimized for ARMv7 platforms.
+@
+@ Output is bit-exact with the reference C code in pitch_filter.c.
+
+#include "settings.h"
+
+.arch armv6
+.align  2
+.global WebRtcIsacfix_PitchFilterCore
+
+
+@ void WebRtcIsacfix_PitchFilterCore(int loopNumber,
+@                                    WebRtc_Word16 gain,
+@                                    int index,
+@                                    WebRtc_Word16 sign,
+@                                    WebRtc_Word16* inputState,
+@                                    WebRtc_Word16* outputBuf2,
+@                                    const WebRtc_Word16* coefficient,
+@                                    WebRtc_Word16* inputBuf,
+@                                    WebRtc_Word16* outputBuf,
+@                                    int* index2) {
+
+WebRtcIsacfix_PitchFilterCore:
+.fnstart
+  push {r4-r11}
+  sub sp, #8
+
+  str r0, [sp]                @ loopNumber
+  str r3, [sp, #4]            @ sign
+  ldr r3, [sp, #44]           @ outputBuf2
+  ldr r6, [sp, #60]           @ index2
+  ldr r7, [r6]                @ *index2
+  ldr r8, [sp, #52]           @ inputBuf
+  ldr r12, [sp, #56]          @ outputBuf
+
+  add r4, r7, r0
+  str r4, [r6]                @ Store return value to index2.
+
+  mov r10, r7, asl #1
+  add r12, r10                @ &outputBuf[*index2]
+  add r8, r10                 @ &inputBuf[*index2]
+
+  add r4, r7, #PITCH_BUFFSIZE @ *index2 + PITCH_BUFFSIZE
+  add r6, r3, r4, lsl #1      @ &outputBuf2[*index2 + PITCH_BUFFSIZE]
+  sub r4, r2                  @ r2: index
+  sub r4, #2                  @ *index2 + PITCH_BUFFSIZE - index - 2
+  add r3, r4, lsl #1          @ &ubufQQpos2[*index2]
+  ldr r9, [sp, #48]           @ coefficient
+
+LOOP:
+@ Usage of registers in the loop:
+@  r0: loop counter
+@  r1: gain
+@  r2: tmpW32
+@  r3: &ubufQQpos2[]
+@  r6: &outputBuf2[]
+@  r8: &inputBuf[]
+@  r9: &coefficient[]
+@  r12: &outputBuf[]
+@  r4, r5, r7, r10, r11: scratch
+
+  @ Filter to get fractional pitch.
+  @ The pitch filter loop here is unrolled with 9 multipications.
+  pld [r3]
+  ldr r10, [r3], #4           @ ubufQQpos2[*index2 + 0, *index2 + 1]
+  ldr r4, [r9], #4            @ coefficient[0, 1]
+  ldr r11, [r3], #4
+  ldr r5, [r9], #4
+  smuad r2, r10, r4
+  smlad r2, r11, r5, r2
+
+  ldr r10, [r3], #4
+  ldr r4, [r9], #4
+  ldr r11, [r3], #4
+  ldr r5, [r9], #4
+  smlad r2, r10, r4, r2
+  ldrh r10, [r3], #-14        @ r3 back to &ubufQQpos2[*index2].
+  ldrh  r4, [r9], #-16        @ r9 back to &coefficient[0].
+  smlad r2, r11, r5, r2
+  smlabb r2, r10, r4, r2
+
+  @ Saturate to avoid overflow in tmpW16.
+  asr r2, #1
+  add r4, r2, #0x1000
+  ssat r7, #16, r4, asr #13
+
+  @ Shift low pass filter state, and excute the low pass filter.
+  @ The memmove() and the low pass filter loop are unrolled and mixed.
+  smulbb r5, r1, r7
+  add r7, r5, #0x800
+  asr r7, #12                 @ Get the value for inputState[0].
+  ldr r11, [sp, #40]          @ inputState
+  pld [r11]
+  adr r10, kDampFilter
+  ldrsh r4, [r10], #2         @ kDampFilter[0]
+  mul r2, r7, r4
+  ldr r4, [r11]               @ inputState[0, 1], before shift.
+  strh r7, [r11]              @ inputState[0], after shift.
+  ldr r5, [r11, #4]           @ inputState[2, 3], before shift.
+  ldr r7, [r10], #4           @ kDampFilter[1, 2]
+  ldr r10, [r10]              @ kDampFilter[3, 4]
+  str r4, [r11, #2]           @ inputState[1, 2], after shift.
+  str r5, [r11, #6]           @ inputState[3, 4], after shift.
+  smlad r2, r4, r7, r2
+  smlad r2, r5, r10, r2
+
+  @ Saturate to avoid overflow.
+  @ First shift the sample to the range of [0xC0000000, 0x3FFFFFFF],
+  @ to avoid overflow in the next saturation step.
+  asr r2, #1
+  add r10, r2, #0x2000
+  ssat r10, #16, r10, asr #14
+
+  @ Subtract from input and update buffer.
+  ldr r11, [sp, #4]           @ sign
+  ldrsh r4, [r8]
+  ldrsh r7, [r8], #2          @ inputBuf[*index2]
+  smulbb r5, r11, r10
+  subs r0, #1
+  sub r4, r5
+  ssat r2, #16, r4
+  strh  r2, [r12], #2         @ outputBuf[*index2]
+
+  add r2, r7
+  ssat r2, #16, r2
+  strh  r2, [r6], #2          @ outputBuff2[*index2 + PITCH_BUFFSIZE]
+  bgt LOOP
+
+  add sp, #8
+  pop {r4-r11}
+  bx  lr
+.fnend
+
+.align  2
+kDampFilter:
+  .short  -2294, 8192, 20972, 8192, -2294
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c b/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c
new file mode 100644
index 0000000..29b4b6a
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_filter_c.c
@@ -0,0 +1,74 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
+
+/* Filter coefficicients in Q15. */
+static const WebRtc_Word16 kDampFilter[PITCH_DAMPORDER] = {
+  -2294, 8192, 20972, 8192, -2294
+};
+
+void WebRtcIsacfix_PitchFilterCore(int loopNumber,
+                                   WebRtc_Word16 gain,
+                                   int index,
+                                   WebRtc_Word16 sign,
+                                   WebRtc_Word16* inputState,
+                                   WebRtc_Word16* outputBuf2,
+                                   const WebRtc_Word16* coefficient,
+                                   WebRtc_Word16* inputBuf,
+                                   WebRtc_Word16* outputBuf,
+                                   int* index2) {
+  int i = 0, j = 0;  /* Loop counters. */
+  WebRtc_Word16* ubufQQpos2 = &outputBuf2[PITCH_BUFFSIZE - (index + 2)];
+  WebRtc_Word16 tmpW16 = 0;
+
+  for (i = 0; i < loopNumber; i++) {
+    WebRtc_Word32 tmpW32 = 0;
+
+    /* Filter to get fractional pitch. */
+    for (j = 0; j < PITCH_FRACORDER; j++) {
+      tmpW32 += WEBRTC_SPL_MUL_16_16(ubufQQpos2[*index2 + j], coefficient[j]);
+    }
+
+    /* Saturate to avoid overflow in tmpW16. */
+    tmpW32 = WEBRTC_SPL_SAT(536862719, tmpW32, -536879104);
+    tmpW32 += 8192;
+    tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 14);
+
+    /* Shift low pass filter state. */
+    memmove(&inputState[1], &inputState[0],
+            (PITCH_DAMPORDER - 1) * sizeof(WebRtc_Word16));
+    inputState[0] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(
+                      gain, tmpW16, 12);
+
+    /* Low pass filter. */
+    tmpW32 = 0;
+    /* TODO(kma): Define a static inline function WebRtcSpl_DotProduct()
+       in spl_inl.h to replace this and other similar loops. */
+    for (j = 0; j < PITCH_DAMPORDER; j++) {
+      tmpW32 += WEBRTC_SPL_MUL_16_16(inputState[j], kDampFilter[j]);
+    }
+
+    /* Saturate to avoid overflow in tmpW16. */
+    tmpW32 = WEBRTC_SPL_SAT(1073725439, tmpW32, -1073758208);
+    tmpW32 += 16384;
+    tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(tmpW32, 15);
+
+    /* Subtract from input and update buffer. */
+    tmpW32 = inputBuf[*index2] - WEBRTC_SPL_MUL_16_16(sign, tmpW16);
+    outputBuf[*index2] = WebRtcSpl_SatW32ToW16(tmpW32);
+    tmpW32 = inputBuf[*index2] + outputBuf[*index2];
+    outputBuf2[*index2 + PITCH_BUFFSIZE] = WebRtcSpl_SatW32ToW16(tmpW32);
+
+    (*index2)++;
+  }
+}
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.c b/src/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.c
new file mode 100644
index 0000000..50ea658
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.c
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_gain_tables.c
+ *
+ * This file contains tables for the pitch filter side-info in the entropy coder.
+ *
+ */
+
+#include "pitch_gain_tables.h"
+
+
+/********************* Pitch Filter Gain Coefficient Tables ************************/
+
+/* cdf for quantized pitch filter gains */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchGainCdf[255] = {
+  0,  2,  4,  6,  64,  901,  903,  905,  16954,  16956,
+  16961,  17360,  17362,  17364,  17366,  17368,  17370,  17372,  17374,  17411,
+  17514,  17516,  17583,  18790,  18796,  18802,  20760,  20777,  20782,  21722,
+  21724,  21728,  21738,  21740,  21742,  21744,  21746,  21748,  22224,  22227,
+  22230,  23214,  23229,  23239,  25086,  25108,  25120,  26088,  26094,  26098,
+  26175,  26177,  26179,  26181,  26183,  26185,  26484,  26507,  26522,  27705,
+  27731,  27750,  29767,  29799,  29817,  30866,  30883,  30885,  31025,  31029,
+  31031,  31033,  31035,  31037,  31114,  31126,  31134,  32687,  32722,  32767,
+  35718,  35742,  35757,  36943,  36952,  36954,  37115,  37128,  37130,  37132,
+  37134,  37136,  37143,  37145,  37152,  38843,  38863,  38897,  47458,  47467,
+  47474,  49040,  49061,  49063,  49145,  49157,  49159,  49161,  49163,  49165,
+  49167,  49169,  49171,  49757,  49770,  49782,  61333,  61344,  61346,  62860,
+  62883,  62885,  62887,  62889,  62891,  62893,  62895,  62897,  62899,  62901,
+  62903,  62905,  62907,  62909,  65496,  65498,  65500,  65521,  65523,  65525,
+  65527,  65529,  65531,  65533,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535
+};
+
+/* index limits and ranges */
+const WebRtc_Word16 WebRtcIsacfix_kLowerlimiGain[3] = {
+  -7, -2, -1
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kUpperlimitGain[3] = {
+  0,  3,  1
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kMultsGain[2] = {
+  18,  3
+};
+
+/* size of cdf table */
+const WebRtc_UWord16 WebRtcIsacfix_kCdfTableSizeGain[1] = {
+  256
+};
+
+/* mean values of pitch filter gains in FIXED point Q12 */
+const WebRtc_Word16 WebRtcIsacfix_kPitchGain1[144] = {
+  843, 1092, 1336, 1222, 1405, 1656, 1500, 1815, 1843, 1838, 1839,
+  1843, 1843, 1843, 1843, 1843,   1843, 1843, 814, 846, 1092, 1013,
+  1174, 1383, 1391, 1511, 1584, 1734, 1753, 1843, 1843, 1843,   1843,
+  1843, 1843, 1843, 524, 689, 777, 845, 947, 1069, 1090, 1263,
+  1380, 1447, 1559, 1676,   1645, 1749, 1843, 1843, 1843, 1843, 81,
+  477, 563, 611, 706, 806, 849, 1012, 1192, 1128,   1330, 1489,
+  1425, 1576, 1826, 1741, 1843, 1843, 0,     290, 305, 356, 488,
+  575, 602, 741,    890, 835, 1079, 1196, 1182, 1376, 1519, 1506,
+  1680, 1843, 0,     47,  97,  69,  289, 381,    385, 474, 617,
+  664, 803, 1079, 935, 1160, 1269, 1265, 1506, 1741, 0,      0,
+  0,      0,      112, 120, 190, 283, 442, 343, 526, 809, 684,
+  935, 1134, 1020, 1265, 1506, 0,      0,      0,      0,      0,      0,
+  0,      111,    256, 87,  373, 597, 430, 684, 935, 770, 1020,
+  1265
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kPitchGain2[144] = {
+  1760, 1525, 1285, 1747, 1671, 1393, 1843, 1826, 1555, 1843, 1784,
+  1606, 1843, 1843, 1711, 1843,   1843, 1814, 1389, 1275, 1040, 1564,
+  1414, 1252, 1610, 1495, 1343, 1753, 1592, 1405, 1804, 1720,   1475,
+  1843, 1814, 1581, 1208, 1061, 856, 1349, 1148, 994, 1390, 1253,
+  1111, 1495, 1343, 1178,   1770, 1465, 1234, 1814, 1581, 1342, 1040,
+  793, 713, 1053, 895, 737, 1128, 1003, 861, 1277,   1094, 981,
+  1475, 1192, 1019, 1581, 1342, 1098, 855, 570, 483, 833, 648,
+  540, 948, 744,    572, 1009, 844, 636, 1234, 934, 685, 1342,
+  1217, 984, 537, 318, 124, 603, 423, 350,    687, 479, 322,
+  791, 581, 430, 987, 671, 488, 1098, 849, 597, 283, 27,
+  0,     397,    222, 38,  513, 271, 124, 624, 325, 157, 737,
+  484, 233, 849, 597, 343, 27,  0,      0,   141, 0,     0,
+  256, 69,  0,     370, 87,  0,     484, 229, 0,     597, 343,
+  87
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kPitchGain3[144] = {
+  1843, 1843, 1711, 1843, 1818, 1606, 1843, 1827, 1511, 1814, 1639,
+  1393, 1760, 1525, 1285, 1656,   1419, 1176, 1835, 1718, 1475, 1841,
+  1650, 1387, 1648, 1498, 1287, 1600, 1411, 1176, 1522, 1299,   1040,
+  1419, 1176, 928, 1773, 1461, 1128, 1532, 1355, 1202, 1429, 1260,
+  1115, 1398, 1151, 1025,   1172, 1080, 790, 1176, 928, 677, 1475,
+  1147, 1019, 1276, 1096, 922, 1214, 1010, 901, 1057,   893, 800,
+  1040, 796, 734, 928, 677, 424, 1137, 897, 753, 1120, 830,
+  710, 875, 751,    601, 795, 642, 583, 790, 544, 475, 677,
+  474, 140, 987, 750, 482, 697, 573, 450,    691, 487, 303,
+  661, 394, 332, 537, 303, 220, 424, 168, 0,     737, 484,
+  229, 624,    348, 153, 441, 261, 136, 397, 166, 51,  283,
+  27,  0,     168, 0,     0,     484, 229,    0,   370, 57,  0,
+  256, 43,  0,     141, 0,  0,   27,  0,   0,   0,   0,
+  0
+};
+
+
+const WebRtc_Word16 WebRtcIsacfix_kPitchGain4[144] = {
+  1843, 1843, 1843, 1843, 1841, 1843, 1500, 1821, 1843, 1222, 1434,
+  1656, 843, 1092, 1336, 504,    757, 1007, 1843, 1843, 1843, 1838,
+  1791, 1843, 1265, 1505, 1599, 965, 1219, 1425, 730, 821,    1092,
+  249, 504, 757, 1783, 1819, 1843, 1351, 1567, 1727, 1096, 1268,
+  1409, 805, 961, 1131,   444, 670, 843, 0,  249, 504, 1425,
+  1655, 1743, 1096, 1324, 1448, 822, 1019, 1199, 490,    704, 867,
+  81,  450, 555, 0,     0,  249, 1247, 1428, 1530, 881, 1073,
+  1283, 610, 759,    939, 278, 464, 645, 0,     200, 270, 0,
+  0,   0,  935, 1163, 1410, 528, 790, 1068,   377, 499, 717,
+  173, 240, 274, 0,   43,  62,  0,   0,   0,   684, 935,
+  1182, 343,    551, 735, 161, 262, 423, 0,      55,  27,  0,
+  0,   0,   0,   0,   0,   430, 684,    935, 87,  377, 597,
+  0,   46,  256, 0,   0,   0,   0,   0,   0,   0,   0,
+  0
+};
+
+
+
+/* transform matrix in Q12*/
+const WebRtc_Word16 WebRtcIsacfix_kTransform[4][4] = {
+  { -2048, -2048, -2048, -2048 },
+  {  2748,   916,  -916, -2748 },
+  {  2048, -2048, -2048,  2048 },
+  {   916, -2748,  2748,  -916 }
+};
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h b/src/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h
new file mode 100644
index 0000000..788e553
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_gain_tables.h
+ *
+ * This file contains tables for the pitch filter side-info in the entropy coder.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_
+
+#include "typedefs.h"
+
+
+/********************* Pitch Filter Gain Coefficient Tables ************************/
+/* cdf for quantized pitch filter gains */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchGainCdf[255];
+
+/* index limits and ranges */
+extern const WebRtc_Word16 WebRtcIsacfix_kLowerlimiGain[3];
+extern const WebRtc_Word16 WebRtcIsacfix_kUpperlimitGain[3];
+extern const WebRtc_UWord16 WebRtcIsacfix_kMultsGain[2];
+
+/* mean values of pitch filter gains in Q12*/
+extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain1[144];
+extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain2[144];
+extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain3[144];
+extern const WebRtc_Word16 WebRtcIsacfix_kPitchGain4[144];
+
+/* size of cdf table */
+extern const WebRtc_UWord16 WebRtcIsacfix_kCdfTableSizeGain[1];
+
+/* transform matrix */
+extern const WebRtc_Word16 WebRtcIsacfix_kTransform[4][4];
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.c b/src/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.c
new file mode 100644
index 0000000..81700e4
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.c
@@ -0,0 +1,306 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_lag_tables.c
+ *
+ * This file contains tables for the pitch filter side-info in the entropy coder.
+ *
+ */
+
+#include "settings.h"
+#include "pitch_lag_tables.h"
+
+
+/********************* Pitch Filter Gain Coefficient Tables ************************/
+
+/* tables for use with small pitch gain */
+
+/* cdf for quantized pitch filter lags */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Lo[127] = {
+  0,  134,  336,  549,  778,  998,  1264,  1512,  1777,  2070,
+  2423,  2794,  3051,  3361,  3708,  3979,  4315,  4610,  4933,  5269,
+  5575,  5896,  6155,  6480,  6816,  7129,  7477,  7764,  8061,  8358,
+  8718,  9020,  9390,  9783,  10177,  10543,  10885,  11342,  11795,  12213,
+  12680,  13096,  13524,  13919,  14436,  14903,  15349,  15795,  16267,  16734,
+  17266,  17697,  18130,  18632,  19080,  19447,  19884,  20315,  20735,  21288,
+  21764,  22264,  22723,  23193,  23680,  24111,  24557,  25022,  25537,  26082,
+  26543,  27090,  27620,  28139,  28652,  29149,  29634,  30175,  30692,  31273,
+  31866,  32506,  33059,  33650,  34296,  34955,  35629,  36295,  36967,  37726,
+  38559,  39458,  40364,  41293,  42256,  43215,  44231,  45253,  46274,  47359,
+  48482,  49678,  50810,  51853,  53016,  54148,  55235,  56263,  57282,  58363,
+  59288,  60179,  61076,  61806,  62474,  63129,  63656,  64160,  64533,  64856,
+  65152,  65535,  65535,  65535,  65535,  65535,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Lo[20] = {
+  0,  429,  3558,  5861,  8558,  11639,  15210,  19502,  24773,  31983,
+  42602,  48567,  52601,  55676,  58160,  60172,  61889,  63235,  65383,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Lo[2] = {
+  0,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Lo[10] = {
+  0,  2966,  6368,  11182,  19431,  37793,  48532,  55353,  60626,  65535
+};
+
+const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrLo[4] = {
+  WebRtcIsacfix_kPitchLagCdf1Lo,
+  WebRtcIsacfix_kPitchLagCdf2Lo,
+  WebRtcIsacfix_kPitchLagCdf3Lo,
+  WebRtcIsacfix_kPitchLagCdf4Lo
+};
+
+/* size of first cdf table */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeLo[1] = {
+  128
+};
+
+/* index limits and ranges */
+const WebRtc_Word16 WebRtcIsacfix_kLowerLimitLo[4] = {
+  -140, -9,  0, -4
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kUpperLimitLo[4] = {
+  -20,  9,  0,  4
+};
+
+/* initial index for arithmetic decoder */
+const WebRtc_UWord16 WebRtcIsacfix_kInitIndLo[3] = {
+  10,  1,  5
+};
+
+/* mean values of pitch filter lags in Q10 */
+
+const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Lo[19] = {
+  -17627, -16207, -14409, -12319, -10253, -8200, -6054, -3986, -1948, -19,
+  1937, 3974, 6064, 8155, 10229, 12270, 14296, 16127, 17520
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Lo[9] = {
+  -7949, -6063, -4036, -1941, 38, 1977, 4060, 6059
+};
+
+
+
+/* tables for use with medium pitch gain */
+
+/* cdf for quantized pitch filter lags */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Mid[255] = {
+  0,  28,  61,  88,  121,  149,  233,  331,  475,  559,
+  624,  661,  689,  712,  745,  791,  815,  843,  866,  922,
+  959,  1024,  1061,  1117,  1178,  1238,  1280,  1350,  1453,  1513,
+  1564,  1625,  1671,  1741,  1788,  1904,  2072,  2421,  2626,  2770,
+  2840,  2900,  2942,  3012,  3068,  3115,  3147,  3194,  3254,  3319,
+  3366,  3520,  3678,  3780,  3850,  3911,  3957,  4032,  4106,  4185,
+  4292,  4474,  4683,  4842,  5019,  5191,  5321,  5428,  5540,  5675,
+  5763,  5847,  5959,  6127,  6304,  6564,  6839,  7090,  7263,  7421,
+  7556,  7728,  7872,  7984,  8142,  8361,  8580,  8743,  8938,  9227,
+  9409,  9539,  9674,  9795,  9930,  10060,  10177,  10382,  10614,  10861,
+  11038,  11271,  11415,  11629,  11792,  12044,  12193,  12416,  12574,  12821,
+  13007,  13235,  13445,  13654,  13901,  14134,  14488,  15000,  15703,  16285,
+  16504,  16797,  17086,  17328,  17579,  17807,  17998,  18268,  18538,  18836,
+  19087,  19274,  19474,  19716,  19935,  20270,  20833,  21303,  21532,  21741,
+  21978,  22207,  22523,  22770,  23054,  23613,  23943,  24204,  24399,  24651,
+  24832,  25074,  25270,  25549,  25759,  26015,  26150,  26424,  26713,  27048,
+  27342,  27504,  27681,  27854,  28021,  28207,  28412,  28664,  28859,  29064,
+  29278,  29548,  29748,  30107,  30377,  30656,  30856,  31164,  31452,  31755,
+  32011,  32328,  32626,  32919,  33319,  33789,  34329,  34925,  35396,  35973,
+  36443,  36964,  37551,  38156,  38724,  39357,  40023,  40908,  41587,  42602,
+  43924,  45037,  45810,  46597,  47421,  48291,  49092,  50051,  51448,  52719,
+  53440,  54241,  54944,  55977,  56676,  57299,  57872,  58389,  59059,  59688,
+  60237,  60782,  61094,  61573,  61890,  62290,  62658,  63030,  63217,  63454,
+  63622,  63882,  64003,  64273,  64427,  64529,  64581,  64697,  64758,  64902,
+  65414,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Mid[36] = {
+  0,  71,  335,  581,  836,  1039,  1323,  1795,  2258,  2608,
+  3005,  3591,  4243,  5344,  7163,  10583,  16848,  28078,  49448,  57007,
+  60357,  61850,  62837,  63437,  63872,  64188,  64377,  64614,  64774,  64949,
+  65039,  65115,  65223,  65360,  65474,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Mid[2] = {
+  0,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Mid[20] = {
+  0,  28,  246,  459,  667,  1045,  1523,  2337,  4337,  11347,
+  44231,  56709,  60781,  62243,  63161,  63969,  64608,  65062,  65502,  65535
+};
+
+const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrMid[4] = {
+  WebRtcIsacfix_kPitchLagCdf1Mid,
+  WebRtcIsacfix_kPitchLagCdf2Mid,
+  WebRtcIsacfix_kPitchLagCdf3Mid,
+  WebRtcIsacfix_kPitchLagCdf4Mid
+};
+
+/* size of first cdf table */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeMid[1] = {
+  256
+};
+
+/* index limits and ranges */
+const WebRtc_Word16 WebRtcIsacfix_kLowerLimitMid[4] = {
+  -280, -17,  0, -9
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kUpperLimitMid[4] = {
+  -40,  17,  0,  9
+};
+
+/* initial index for arithmetic decoder */
+const WebRtc_UWord16 WebRtcIsacfix_kInitIndMid[3] = {
+  18,  1,  10
+};
+
+/* mean values of pitch filter lags in Q10 */
+
+const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Mid[35] = {
+  -17297, -16250, -15416, -14343, -13341, -12363, -11270,
+  -10355, -9122, -8217, -7172, -6083, -5102, -4004, -3060,
+  -1982, -952, -18, 935, 1976, 3040, 4032,
+  5082, 6065, 7257, 8202, 9264, 10225, 11242,
+  12234, 13337, 14336, 15374, 16187, 17347
+};
+
+
+const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Mid[19] = {
+  -8811, -8081, -7203, -6003, -5057, -4025, -2983, -1964,
+  -891, 29, 921, 1920, 2988, 4064, 5187, 6079, 7173, 8074, 8849
+};
+
+
+/* tables for use with large pitch gain */
+
+/* cdf for quantized pitch filter lags */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Hi[511] = {
+  0,  7,  18,  33,  69,  105,  156,  228,  315,  612,
+  680,  691,  709,  724,  735,  738,  742,  746,  749,  753,
+  756,  760,  764,  774,  782,  785,  789,  796,  800,  803,
+  807,  814,  818,  822,  829,  832,  847,  854,  858,  869,
+  876,  883,  898,  908,  934,  977,  1010,  1050,  1060,  1064,
+  1075,  1078,  1086,  1089,  1093,  1104,  1111,  1122,  1133,  1136,
+  1151,  1162,  1183,  1209,  1252,  1281,  1339,  1364,  1386,  1401,
+  1411,  1415,  1426,  1430,  1433,  1440,  1448,  1455,  1462,  1477,
+  1487,  1495,  1502,  1506,  1509,  1516,  1524,  1531,  1535,  1542,
+  1553,  1556,  1578,  1589,  1611,  1625,  1639,  1643,  1654,  1665,
+  1672,  1687,  1694,  1705,  1708,  1719,  1730,  1744,  1752,  1759,
+  1791,  1795,  1820,  1867,  1886,  1915,  1936,  1943,  1965,  1987,
+  2041,  2099,  2161,  2175,  2200,  2211,  2226,  2233,  2244,  2251,
+  2266,  2280,  2287,  2298,  2309,  2316,  2331,  2342,  2356,  2378,
+  2403,  2418,  2447,  2497,  2544,  2602,  2863,  2895,  2903,  2935,
+  2950,  2971,  3004,  3011,  3018,  3029,  3040,  3062,  3087,  3127,
+  3152,  3170,  3199,  3243,  3293,  3322,  3340,  3377,  3402,  3427,
+  3474,  3518,  3543,  3579,  3601,  3637,  3659,  3706,  3731,  3760,
+  3818,  3847,  3869,  3901,  3920,  3952,  4068,  4169,  4220,  4271,
+  4524,  4571,  4604,  4632,  4672,  4730,  4777,  4806,  4857,  4904,
+  4951,  5002,  5031,  5060,  5107,  5150,  5212,  5266,  5331,  5382,
+  5432,  5490,  5544,  5610,  5700,  5762,  5812,  5874,  5972,  6022,
+  6091,  6163,  6232,  6305,  6402,  6540,  6685,  6880,  7090,  7271,
+  7379,  7452,  7542,  7625,  7687,  7770,  7843,  7911,  7966,  8024,
+  8096,  8190,  8252,  8320,  8411,  8501,  8585,  8639,  8751,  8842,
+  8918,  8986,  9066,  9127,  9203,  9269,  9345,  9406,  9464,  9536,
+  9612,  9667,  9735,  9844,  9931,  10036,  10119,  10199,  10260,  10358,
+  10441,  10514,  10666,  10734,  10872,  10951,  11053,  11125,  11223,  11324,
+  11516,  11664,  11737,  11816,  11892,  12008,  12120,  12200,  12280,  12392,
+  12490,  12576,  12685,  12812,  12917,  13003,  13108,  13210,  13300,  13384,
+  13470,  13579,  13673,  13771,  13879,  13999,  14136,  14201,  14368,  14614,
+  14759,  14867,  14958,  15030,  15121,  15189,  15280,  15385,  15461,  15555,
+  15653,  15768,  15884,  15971,  16069,  16145,  16210,  16279,  16380,  16463,
+  16539,  16615,  16688,  16818,  16919,  17017,  18041,  18338,  18523,  18649,
+  18790,  18917,  19047,  19167,  19315,  19460,  19601,  19731,  19858,  20068,
+  20173,  20318,  20466,  20625,  20741,  20911,  21045,  21201,  21396,  21588,
+  21816,  22022,  22305,  22547,  22786,  23072,  23322,  23600,  23879,  24168,
+  24433,  24769,  25120,  25511,  25895,  26289,  26792,  27219,  27683,  28077,
+  28566,  29094,  29546,  29977,  30491,  30991,  31573,  32105,  32594,  33173,
+  33788,  34497,  35181,  35833,  36488,  37255,  37921,  38645,  39275,  39894,
+  40505,  41167,  41790,  42431,  43096,  43723,  44385,  45134,  45858,  46607,
+  47349,  48091,  48768,  49405,  49955,  50555,  51167,  51985,  52611,  53078,
+  53494,  53965,  54435,  54996,  55601,  56125,  56563,  56838,  57244,  57566,
+  57967,  58297,  58771,  59093,  59419,  59647,  59886,  60143,  60461,  60693,
+  60917,  61170,  61416,  61634,  61891,  62122,  62310,  62455,  62632,  62839,
+  63103,  63436,  63639,  63805,  63906,  64015,  64192,  64355,  64475,  64558,
+  64663,  64742,  64811,  64865,  64916,  64956,  64981,  65025,  65068,  65115,
+  65195,  65314,  65419,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,  65535,
+  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Hi[68] = {
+  0,  7,  11,  22,  37,  52,  56,  59,  81,  85,
+  89,  96,  115,  130,  137,  152,  170,  181,  193,  200,
+  207,  233,  237,  259,  289,  318,  363,  433,  592,  992,
+  1607,  3062,  6149,  12206,  25522,  48368,  58223,  61918,  63640,  64584,
+  64943,  65098,  65206,  65268,  65294,  65335,  65350,  65372,  65387,  65402,
+  65413,  65420,  65428,  65435,  65439,  65450,  65454,  65468,  65472,  65476,
+  65483,  65491,  65498,  65505,  65516,  65520,  65528,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Hi[2] = {
+  0,  65535
+};
+
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Hi[35] = {
+  0,  7,  19,  30,  41,  48,  63,  74,  82,  96,
+  122,  152,  215,  330,  701,  2611,  10931,  48106,  61177,  64341,
+  65112,  65238,  65309,  65338,  65364,  65379,  65401,  65427,  65453,
+  65465,  65476,  65490,  65509,  65528,  65535
+};
+
+const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrHi[4] = {
+  WebRtcIsacfix_kPitchLagCdf1Hi,
+  WebRtcIsacfix_kPitchLagCdf2Hi,
+  WebRtcIsacfix_kPitchLagCdf3Hi,
+  WebRtcIsacfix_kPitchLagCdf4Hi
+};
+
+/* size of first cdf table */
+const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeHi[1] = {
+  512
+};
+
+/* index limits and ranges */
+const WebRtc_Word16 WebRtcIsacfix_kLowerLimitHi[4] = {
+  -552, -34,  0, -16
+};
+
+const WebRtc_Word16 WebRtcIsacfix_kUpperLimitHi[4] = {
+  -80,  32,  0,  17
+};
+
+/* initial index for arithmetic decoder */
+const WebRtc_UWord16 WebRtcIsacfix_kInitIndHi[3] = {
+  34,  1,  18
+};
+
+/* mean values of pitch filter lags */
+
+const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Hi[67] = {
+  -17482, -16896, -16220, -15929, -15329, -14848, -14336, -13807, -13312, -12800, -12218, -11720,
+  -11307, -10649, -10396, -9742, -9148, -8668, -8297, -7718, -7155, -6656, -6231, -5600, -5129,
+  -4610, -4110, -3521, -3040, -2525, -2016, -1506, -995, -477, -5, 469, 991, 1510, 2025, 2526, 3079,
+  3555, 4124, 4601, 5131, 5613, 6194, 6671, 7140, 7645, 8207, 8601, 9132, 9728, 10359, 10752, 11302,
+  11776, 12288, 12687, 13204, 13759, 14295, 14810, 15360, 15764, 16350
+};
+
+
+const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Hi[34] = {
+  -8175, -7659, -7205, -6684, -6215, -5651, -5180, -4566, -4087, -3536, -3096,
+  -2532, -1990, -1482, -959, -440, 11, 451, 954, 1492, 2020, 2562, 3059,
+  3577, 4113, 4618, 5134, 5724, 6060, 6758, 7015, 7716, 8066, 8741
+};
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h b/src/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h
new file mode 100644
index 0000000..9517c29
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h
@@ -0,0 +1,103 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * pitch_lag_tables.h
+ *
+ * This file contains tables for the pitch filter side-info in the entropy coder.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_
+
+
+#include "typedefs.h"
+
+
+/********************* Pitch Filter Lag Coefficient Tables ************************/
+
+/* tables for use with small pitch gain */
+
+/* cdfs for quantized pitch lags */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Lo[127];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Lo[20];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Lo[2];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Lo[10];
+
+extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrLo[4];
+
+/* size of first cdf table */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeLo[1];
+
+/* index limits and ranges */
+extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitLo[4];
+extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitLo[4];
+
+/* initial index for arithmetic decoder */
+extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndLo[3];
+
+/* mean values of pitch filter lags */
+extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Lo[19];
+extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Lo[9];
+
+
+
+/* tables for use with medium pitch gain */
+
+/* cdfs for quantized pitch lags */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Mid[255];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Mid[36];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Mid[2];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Mid[20];
+
+extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrMid[4];
+
+/* size of first cdf table */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeMid[1];
+
+/* index limits and ranges */
+extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitMid[4];
+extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitMid[4];
+
+/* initial index for arithmetic decoder */
+extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndMid[3];
+
+/* mean values of pitch filter lags */
+extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Mid[35];
+extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Mid[19];
+
+
+/* tables for use with large pitch gain */
+
+/* cdfs for quantized pitch lags */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf1Hi[511];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf2Hi[68];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf3Hi[2];
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagCdf4Hi[35];
+
+extern const WebRtc_UWord16 *WebRtcIsacfix_kPitchLagPtrHi[4];
+
+/* size of first cdf table */
+extern const WebRtc_UWord16 WebRtcIsacfix_kPitchLagSizeHi[1];
+
+/* index limits and ranges */
+extern const WebRtc_Word16 WebRtcIsacfix_kLowerLimitHi[4];
+extern const WebRtc_Word16 WebRtcIsacfix_kUpperLimitHi[4];
+
+/* initial index for arithmetic decoder */
+extern const WebRtc_UWord16 WebRtcIsacfix_kInitIndHi[3];
+
+/* mean values of pitch filter lags */
+extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag2Hi[67];
+extern const WebRtc_Word16 WebRtcIsacfix_kMeanLag4Hi[34];
+
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/settings.h b/src/modules/audio_coding/codecs/isac/fix/source/settings.h
new file mode 100644
index 0000000..da88ba2
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/settings.h
@@ -0,0 +1,205 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * settings.h
+ *
+ * Declaration of #defines used in the iSAC codec
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_
+
+
+/* sampling frequency (Hz) */
+#define FS                                      16000
+/* 1.5 times Sampling frequency */
+#define FS_1_HALF        (WebRtc_UWord32) 24000
+/* Three times Sampling frequency */
+#define FS3          (WebRtc_UWord32) 48000
+/* Eight times Sampling frequency */
+#define FS8          (WebRtc_UWord32) 128000
+
+/* number of samples per frame (either 480 (30ms) or 960 (60ms)) */
+#define INITIAL_FRAMESAMPLES     960
+
+/* miliseconds */
+#define FRAMESIZE                               30
+/* number of samples per frame processed in the encoder (30ms) */
+#define FRAMESAMPLES                            480     /* ((FRAMESIZE*FS)/1000) */
+#define FRAMESAMPLES_HALF       240
+/* max number of samples per frame (= 60 ms frame) */
+#define MAX_FRAMESAMPLES      960
+/* number of samples per 10ms frame */
+#define FRAMESAMPLES_10ms                       160      /* ((10*FS)/1000) */
+/* Number of samples per 1 ms */
+#define SAMPLES_PER_MSEC      16
+/* number of subframes */
+#define SUBFRAMES                               6
+/* length of a subframe */
+#define UPDATE                                  80
+/* length of half a subframe (low/high band) */
+#define HALF_SUBFRAMELEN                        40    /* (UPDATE/2) */
+/* samples of look ahead (in a half-band, so actually half the samples of look ahead @ FS) */
+#define QLOOKAHEAD                              24    /* 3 ms */
+
+/* order of AR model in spectral entropy coder */
+#define AR_ORDER                                6
+#define MAX_ORDER                               13
+#define LEVINSON_MAX_ORDER                  12
+
+/* window length (masking analysis) */
+#define WINLEN                                  256
+/* order of low-band pole filter used to approximate masking curve */
+#define ORDERLO                                 12
+/* order of hi-band pole filter used to approximate masking curve */
+#define ORDERHI                                 6
+
+#define KLT_NUM_AVG_GAIN                        0
+#define KLT_NUM_AVG_SHAPE                       0
+#define KLT_NUM_MODELS                          3
+#define LPC_SHAPE_ORDER                         18    /* (ORDERLO + ORDERHI) */
+
+#define KLT_ORDER_GAIN                          12    /* (2 * SUBFRAMES) */
+#define KLT_ORDER_SHAPE                         108   /*  (LPC_SHAPE_ORDER * SUBFRAMES) */
+
+
+
+/* order for post_filter_bank */
+#define POSTQORDER                              3
+/* order for pre-filterbank */
+#define QORDER                                  3
+/* for decimator */
+#define ALLPASSSECTIONS                         2
+/* The number of composite all-pass filter factors */
+#define NUMBEROFCOMPOSITEAPSECTIONS             4
+
+/* The number of all-pass filter factors in an upper or lower channel*/
+#define NUMBEROFCHANNELAPSECTIONS               2
+
+
+
+#define DPMIN_Q10                            -10240   /* -10.00 in Q10 */
+#define DPMAX_Q10                             10240   /* 10.00 in Q10 */
+#define MINBITS_Q10                           10240   /* 10.0 in Q10 */
+
+
+/* array size for byte stream in number of Word16. */
+#define STREAM_MAXW16       300 /* The old maximum size still needed for the decoding */
+#define STREAM_MAXW16_30MS  100 /* 100 Word16 = 200 bytes = 53.4 kbit/s @ 30 ms.framelength */
+#define STREAM_MAXW16_60MS  200 /* 200 Word16 = 400 bytes = 53.4 kbit/s @ 60 ms.framelength */
+
+
+/* storage size for bit counts */
+//#define BIT_COUNTER_SIZE                        30
+/* maximum order of any AR model or filter */
+#define MAX_AR_MODEL_ORDER                      12
+
+/* Maximum number of iterations allowed to limit payload size */
+#define MAX_PAYLOAD_LIMIT_ITERATION           1
+
+/* Bandwidth estimator */
+
+#define MIN_ISAC_BW                           10000     /* Minimum bandwidth in bits per sec */
+#define MAX_ISAC_BW                           32000     /* Maxmum bandwidth in bits per sec */
+#define MIN_ISAC_MD                           5         /* Minimum Max Delay in ?? */
+#define MAX_ISAC_MD                           25        /* Maxmum Max Delay in ?? */
+#define DELAY_CORRECTION_MAX      717
+#define DELAY_CORRECTION_MED      819
+#define Thld_30_60         18000
+#define Thld_60_30         27000
+
+/* assumed header size; we don't know the exact number (header compression may be used) */
+#define HEADER_SIZE                           35       /* bytes */
+#define INIT_FRAME_LEN                        60
+#define INIT_BN_EST                           20000
+#define INIT_BN_EST_Q7                        2560000  /* 20 kbps in Q7 */
+#define INIT_REC_BN_EST_Q5                    789312   /* INIT_BN_EST + INIT_HDR_RATE in Q5 */
+
+/* 8738 in Q18 is ~ 1/30 */
+/* #define INIT_HDR_RATE (((HEADER_SIZE * 8 * 1000) * 8738) >> NUM_BITS_TO_SHIFT (INIT_FRAME_LEN)) */
+#define INIT_HDR_RATE                    4666
+/* number of packets in a row for a high rate burst */
+#define BURST_LEN                             3
+/* ms, max time between two full bursts */
+#define BURST_INTERVAL                        800
+/* number of packets in a row for initial high rate burst */
+#define INIT_BURST_LEN                        5
+/* bits/s, rate for the first BURST_LEN packets */
+#define INIT_RATE                             10240000 /* INIT_BN_EST in Q9 */
+
+
+/* For pitch analysis */
+#define PITCH_FRAME_LEN                         240  /* (FRAMESAMPLES/2) 30 ms  */
+#define PITCH_MAX_LAG                           140       /* 57 Hz  */
+#define PITCH_MIN_LAG                           20                /* 400 Hz */
+#define PITCH_MIN_LAG_Q8                        5120 /* 256 * PITCH_MIN_LAG */
+#define OFFSET_Q8                               768  /* 256 * 3 */
+
+#define PITCH_MAX_GAIN_Q12      1843                  /* 0.45 */
+#define PITCH_LAG_SPAN2                         65   /* (PITCH_MAX_LAG/2-PITCH_MIN_LAG/2+5) */
+#define PITCH_CORR_LEN2                         60     /* 15 ms  */
+#define PITCH_CORR_STEP2                        60   /* (PITCH_FRAME_LEN/4) */
+#define PITCH_SUBFRAMES                         4
+#define PITCH_SUBFRAME_LEN                      60   /* (PITCH_FRAME_LEN/PITCH_SUBFRAMES) */
+
+/* For pitch filter */
+#define PITCH_BUFFSIZE                   190  /* (PITCH_MAX_LAG + 50) Extra 50 for fraction and LP filters */
+#define PITCH_INTBUFFSIZE               430  /* (PITCH_FRAME_LEN+PITCH_BUFFSIZE) */
+#define PITCH_FRACS                             8
+#define PITCH_FRACORDER                         9
+#define PITCH_DAMPORDER                         5
+
+
+/* Order of high pass filter */
+#define HPORDER                                 2
+
+
+/* PLC */
+#define DECAY_RATE               10               /* Q15, 20% of decay every lost frame apllied linearly sample by sample*/
+#define PLC_WAS_USED              1
+#define PLC_NOT_USED              3
+#define RECOVERY_OVERLAP         80
+#define RESAMP_RES              256
+#define RESAMP_RES_BIT            8
+
+
+
+/* Define Error codes */
+/* 6000 General */
+#define ISAC_MEMORY_ALLOCATION_FAILED    6010
+#define ISAC_MODE_MISMATCH       6020
+#define ISAC_DISALLOWED_BOTTLENECK     6030
+#define ISAC_DISALLOWED_FRAME_LENGTH    6040
+/* 6200 Bandwidth estimator */
+#define ISAC_RANGE_ERROR_BW_ESTIMATOR    6240
+/* 6400 Encoder */
+#define ISAC_ENCODER_NOT_INITIATED     6410
+#define ISAC_DISALLOWED_CODING_MODE     6420
+#define ISAC_DISALLOWED_FRAME_MODE_ENCODER   6430
+#define ISAC_DISALLOWED_BITSTREAM_LENGTH            6440
+#define ISAC_PAYLOAD_LARGER_THAN_LIMIT              6450
+/* 6600 Decoder */
+#define ISAC_DECODER_NOT_INITIATED     6610
+#define ISAC_EMPTY_PACKET       6620
+#define ISAC_DISALLOWED_FRAME_MODE_DECODER   6630
+#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH  6640
+#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH   6650
+#define ISAC_RANGE_ERROR_DECODE_PITCH_GAIN   6660
+#define ISAC_RANGE_ERROR_DECODE_PITCH_LAG   6670
+#define ISAC_RANGE_ERROR_DECODE_LPC     6680
+#define ISAC_RANGE_ERROR_DECODE_SPECTRUM   6690
+#define ISAC_LENGTH_MISMATCH      6730
+/* 6800 Call setup formats */
+#define ISAC_INCOMPATIBLE_FORMATS     6810
+
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SETTINGS_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.c b/src/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.c
new file mode 100644
index 0000000..81b932f
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.c
@@ -0,0 +1,193 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * spectrum_ar_model_tables.c
+ *
+ * This file contains tables with AR coefficients, Gain coefficients
+ * and cosine tables.
+ *
+ */
+
+#include "spectrum_ar_model_tables.h"
+#include "settings.h"
+
+/********************* AR Coefficient Tables ************************/
+
+/* cdf for quantized reflection coefficient 1 */
+const WebRtc_UWord16 WebRtcIsacfix_kRc1Cdf[12] = {
+  0,  2,  4,  129,  7707,  57485,  65495,  65527,  65529,  65531,
+  65533,  65535
+};
+
+/* cdf for quantized reflection coefficient 2 */
+const WebRtc_UWord16 WebRtcIsacfix_kRc2Cdf[12] = {
+  0,  2,  4,  7,  531,  25298,  64525,  65526,  65529,  65531,
+  65533,  65535
+};
+
+/* cdf for quantized reflection coefficient 3 */
+const WebRtc_UWord16 WebRtcIsacfix_kRc3Cdf[12] = {
+  0,  2,  4,  6,  620,  22898,  64843,  65527,  65529,  65531,
+  65533,  65535
+};
+
+/* cdf for quantized reflection coefficient 4 */
+const WebRtc_UWord16 WebRtcIsacfix_kRc4Cdf[12] = {
+  0,  2,  4,  6,  35,  10034,  60733,  65506,  65529,  65531,
+  65533,  65535
+};
+
+/* cdf for quantized reflection coefficient 5 */
+const WebRtc_UWord16 WebRtcIsacfix_kRc5Cdf[12] = {
+  0,  2,  4,  6,  36,  7567,  56727,  65385,  65529,  65531,
+  65533,  65535
+};
+
+/* cdf for quantized reflection coefficient 6 */
+const WebRtc_UWord16 WebRtcIsacfix_kRc6Cdf[12] = {
+  0,  2,  4,  6,  14,  6579,  57360,  65409,  65529,  65531,
+  65533,  65535
+};
+
+/* representation levels for quantized reflection coefficient 1 */
+const WebRtc_Word16 WebRtcIsacfix_kRc1Levels[11] = {
+  -32104, -29007, -23202, -15496, -9279, -2577, 5934, 17535, 24512, 29503, 32104
+};
+
+/* representation levels for quantized reflection coefficient 2 */
+const WebRtc_Word16 WebRtcIsacfix_kRc2Levels[11] = {
+  -32104, -29503, -23494, -15261, -7309, -1399, 6158, 16381, 24512, 29503, 32104
+};
+
+/* representation levels for quantized reflection coefficient 3 */
+const WebRtc_Word16 WebRtcIsacfix_kRc3Levels[11] = {
+  -32104, -29503, -23157, -15186, -7347, -1359, 5829, 17535, 24512, 29503, 32104
+};
+
+/* representation levels for quantized reflection coefficient 4 */
+const WebRtc_Word16 WebRtcIsacfix_kRc4Levels[11] = {
+  -32104, -29503, -24512, -15362, -6665, -342, 6596, 14585, 24512, 29503, 32104
+};
+
+/* representation levels for quantized reflection coefficient 5 */
+const WebRtc_Word16 WebRtcIsacfix_kRc5Levels[11] = {
+  -32104, -29503, -24512, -15005, -6564, -106, 7123, 14920, 24512, 29503, 32104
+};
+
+/* representation levels for quantized reflection coefficient 6 */
+const WebRtc_Word16 WebRtcIsacfix_kRc6Levels[11] = {
+  -32104, -29503, -24512, -15096, -6656, -37, 7036, 14847, 24512, 29503, 32104
+};
+
+/* quantization boundary levels for reflection coefficients */
+const WebRtc_Word16 WebRtcIsacfix_kRcBound[12] = {
+  -32768, -31441, -27566, -21458, -13612, -4663,
+  4663, 13612, 21458, 27566, 31441, 32767
+};
+
+/* initial index for AR reflection coefficient quantizer and cdf table search */
+const WebRtc_UWord16 WebRtcIsacfix_kRcInitInd[6] = {
+  5,  5,  5,  5,  5,  5
+};
+
+/* pointers to AR cdf tables */
+const WebRtc_UWord16 *WebRtcIsacfix_kRcCdfPtr[AR_ORDER] = {
+  WebRtcIsacfix_kRc1Cdf,
+  WebRtcIsacfix_kRc2Cdf,
+  WebRtcIsacfix_kRc3Cdf,
+  WebRtcIsacfix_kRc4Cdf,
+  WebRtcIsacfix_kRc5Cdf,
+  WebRtcIsacfix_kRc6Cdf
+};
+
+/* pointers to AR representation levels tables */
+const WebRtc_Word16 *WebRtcIsacfix_kRcLevPtr[AR_ORDER] = {
+  WebRtcIsacfix_kRc1Levels,
+  WebRtcIsacfix_kRc2Levels,
+  WebRtcIsacfix_kRc3Levels,
+  WebRtcIsacfix_kRc4Levels,
+  WebRtcIsacfix_kRc5Levels,
+  WebRtcIsacfix_kRc6Levels
+};
+
+
+/******************** GAIN Coefficient Tables ***********************/
+
+/* cdf for Gain coefficient */
+const WebRtc_UWord16 WebRtcIsacfix_kGainCdf[19] = {
+  0,  2,  4,  6,  8,  10,  12,  14,  16,  1172,
+  11119,  29411,  51699,  64445,  65527,  65529,  65531,  65533,  65535
+};
+
+/* representation levels for quantized squared Gain coefficient */
+const WebRtc_Word32 WebRtcIsacfix_kGain2Lev[18] = {
+  128, 128, 128, 128, 128, 215, 364, 709, 1268,
+  1960, 3405, 6078, 11286, 17827, 51918, 134498, 487432, 2048000
+};
+
+/* quantization boundary levels for squared Gain coefficient */
+const WebRtc_Word32 WebRtcIsacfix_kGain2Bound[19] = {
+  0, 21, 35, 59, 99, 166, 280, 475, 815, 1414,
+  2495, 4505, 8397, 16405, 34431, 81359, 240497, 921600, 0x7FFFFFFF
+};
+
+/* pointers to Gain cdf table */
+const WebRtc_UWord16 *WebRtcIsacfix_kGainPtr[1] = {
+  WebRtcIsacfix_kGainCdf
+};
+
+/* gain initial index for gain quantizer and cdf table search */
+const WebRtc_UWord16 WebRtcIsacfix_kGainInitInd[1] = {
+  11
+};
+
+
+/************************* Cosine Tables ****************************/
+
+/* cosine table */
+const WebRtc_Word16 WebRtcIsacfix_kCos[6][60] = {
+  { 512,   512,   511,   510,   508,   507,   505,   502,   499,   496,
+        493,   489,   485,   480,   476,   470,   465,   459,   453,   447,
+ 440,   433,   426,   418,   410,   402,   394,   385,   376,   367,
+        357,   348,   338,   327,   317,   306,   295,   284,   273,   262,
+ 250,   238,   226,   214,   202,   190,   177,   165,   152,   139,
+        126,   113,   100,   87,   73,   60,   47,   33,   20,   7       },
+  { 512,   510,   508,   503,   498,   491,   483,   473,   462,   450,
+        437,   422,   406,   389,   371,   352,   333,   312,   290,   268,
+ 244,   220,   196,   171,   145,   120,   93,   67,   40,   13,
+        -13,   -40,   -67,   -93,   -120,   -145,   -171,   -196,   -220,   -244,
+ -268,   -290,   -312,   -333,   -352,   -371,   -389,   -406,   -422,   -437,
+        -450,   -462,   -473,   -483,   -491,   -498,   -503,   -508,   -510,   -512    },
+  { 512,   508,   502,   493,   480,   465,   447,   426,   402,   376,
+        348,   317,   284,   250,   214,   177,   139,   100,   60,   20,
+ -20,   -60,   -100,   -139,   -177,   -214,   -250,   -284,   -317,   -348,
+        -376,   -402,   -426,   -447,   -465,   -480,   -493,   -502,   -508,   -512,
+ -512,   -508,   -502,   -493,   -480,   -465,   -447,   -426,   -402,   -376,
+        -348,   -317,   -284,   -250,   -214,   -177,   -139,   -100,   -60,   -20     },
+  { 511,   506,   495,   478,   456,   429,   398,   362,   322,   279,
+        232,   183,   133,   80,   27,   -27,   -80,   -133,   -183,   -232,
+ -279,   -322,   -362,   -398,   -429,   -456,   -478,   -495,   -506,   -511,
+        -511,   -506,   -495,   -478,   -456,   -429,   -398,   -362,   -322,   -279,
+ -232,   -183,   -133,   -80,   -27,   27,   80,   133,   183,   232,
+        279,   322,   362,   398,   429,   456,   478,   495,   506,   511     },
+  { 511,   502,   485,   459,   426,   385,   338,   284,   226,   165,
+        100,   33,   -33,   -100,   -165,   -226,   -284,   -338,   -385,   -426,
+ -459,   -485,   -502,   -511,   -511,   -502,   -485,   -459,   -426,   -385,
+        -338,   -284,   -226,   -165,   -100,   -33,   33,   100,   165,   226,
+ 284,   338,   385,   426,   459,   485,   502,   511,   511,   502,
+        485,   459,   426,   385,   338,   284,   226,   165,   100,   33      },
+  { 510,   498,   473,   437,   389,   333,   268,   196,   120,   40,
+        -40,   -120,   -196,   -268,   -333,   -389,   -437,   -473,   -498,   -510,
+ -510,   -498,   -473,   -437,   -389,   -333,   -268,   -196,   -120,   -40,
+        40,   120,   196,   268,   333,   389,   437,   473,   498,   510,
+ 510,   498,   473,   437,   389,   333,   268,   196,   120,   40,
+        -40,   -120,   -196,   -268,   -333,   -389,   -437,   -473,   -498,   -510    }
+};
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h b/src/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h
new file mode 100644
index 0000000..b506d0e
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * spectrum_ar_model_tables.h
+ *
+ * This file contains definitions of tables with AR coefficients,
+ * Gain coefficients and cosine tables.
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
+
+#include "typedefs.h"
+#include "settings.h"
+
+
+/********************* AR Coefficient Tables ************************/
+/* cdf for quantized reflection coefficient 1 */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRc1Cdf[12];
+
+/* cdf for quantized reflection coefficient 2 */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRc2Cdf[12];
+
+/* cdf for quantized reflection coefficient 3 */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRc3Cdf[12];
+
+/* cdf for quantized reflection coefficient 4 */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRc4Cdf[12];
+
+/* cdf for quantized reflection coefficient 5 */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRc5Cdf[12];
+
+/* cdf for quantized reflection coefficient 6 */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRc6Cdf[12];
+
+/* representation levels for quantized reflection coefficient 1 */
+extern const WebRtc_Word16 WebRtcIsacfix_kRc1Levels[11];
+
+/* representation levels for quantized reflection coefficient 2 */
+extern const WebRtc_Word16 WebRtcIsacfix_kRc2Levels[11];
+
+/* representation levels for quantized reflection coefficient 3 */
+extern const WebRtc_Word16 WebRtcIsacfix_kRc3Levels[11];
+
+/* representation levels for quantized reflection coefficient 4 */
+extern const WebRtc_Word16 WebRtcIsacfix_kRc4Levels[11];
+
+/* representation levels for quantized reflection coefficient 5 */
+extern const WebRtc_Word16 WebRtcIsacfix_kRc5Levels[11];
+
+/* representation levels for quantized reflection coefficient 6 */
+extern const WebRtc_Word16 WebRtcIsacfix_kRc6Levels[11];
+
+/* quantization boundary levels for reflection coefficients */
+extern const WebRtc_Word16 WebRtcIsacfix_kRcBound[12];
+
+/* initial indices for AR reflection coefficient quantizer and cdf table search */
+extern const WebRtc_UWord16 WebRtcIsacfix_kRcInitInd[AR_ORDER];
+
+/* pointers to AR cdf tables */
+extern const WebRtc_UWord16 *WebRtcIsacfix_kRcCdfPtr[AR_ORDER];
+
+/* pointers to AR representation levels tables */
+extern const WebRtc_Word16 *WebRtcIsacfix_kRcLevPtr[AR_ORDER];
+
+
+/******************** GAIN Coefficient Tables ***********************/
+/* cdf for Gain coefficient */
+extern const WebRtc_UWord16 WebRtcIsacfix_kGainCdf[19];
+
+/* representation levels for quantized Gain coefficient */
+extern const WebRtc_Word32 WebRtcIsacfix_kGain2Lev[18];
+
+/* squared quantization boundary levels for Gain coefficient */
+extern const WebRtc_Word32 WebRtcIsacfix_kGain2Bound[19];
+
+/* pointer to Gain cdf table */
+extern const WebRtc_UWord16 *WebRtcIsacfix_kGainPtr[1];
+
+/* Gain initial index for gain quantizer and cdf table search */
+extern const WebRtc_UWord16 WebRtcIsacfix_kGainInitInd[1];
+
+/************************* Cosine Tables ****************************/
+/* Cosine table */
+extern const WebRtc_Word16 WebRtcIsacfix_kCos[6][60];
+
+#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/structs.h b/src/modules/audio_coding/codecs/isac/fix/source/structs.h
new file mode 100644
index 0000000..c038a43
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/structs.h
@@ -0,0 +1,382 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * structs.h
+ *
+ * This header file contains all the structs used in the ISAC codec
+ *
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_
+#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_
+
+
+#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
+#include "typedefs.h"
+
+/* Bitstream struct for decoder */
+typedef struct Bitstreamstruct_dec {
+
+  WebRtc_UWord16  *stream;          /* Pointer to bytestream to decode */
+  WebRtc_UWord32  W_upper;          /* Upper boundary of interval W */
+  WebRtc_UWord32  streamval;
+  WebRtc_UWord16  stream_index;     /* Index to the current position in bytestream */
+  WebRtc_Word16   full;             /* 0 - first byte in memory filled, second empty*/
+  /* 1 - both bytes are empty (we just filled the previous memory */
+
+} Bitstr_dec;
+
+/* Bitstream struct for encoder */
+typedef struct Bitstreamstruct_enc {
+
+  WebRtc_UWord16  stream[STREAM_MAXW16_60MS];   /* Vector for adding encoded bytestream */
+  WebRtc_UWord32  W_upper;          /* Upper boundary of interval W */
+  WebRtc_UWord32  streamval;
+  WebRtc_UWord16  stream_index;     /* Index to the current position in bytestream */
+  WebRtc_Word16   full;             /* 0 - first byte in memory filled, second empty*/
+  /* 1 - both bytes are empty (we just filled the previous memory */
+
+} Bitstr_enc;
+
+
+typedef struct {
+
+  WebRtc_Word16 DataBufferLoQ0[WINLEN];
+  WebRtc_Word16 DataBufferHiQ0[WINLEN];
+
+  WebRtc_Word32 CorrBufLoQQ[ORDERLO+1];
+  WebRtc_Word32 CorrBufHiQQ[ORDERHI+1];
+
+  WebRtc_Word16 CorrBufLoQdom[ORDERLO+1];
+  WebRtc_Word16 CorrBufHiQdom[ORDERHI+1];
+
+  WebRtc_Word32 PreStateLoGQ15[ORDERLO+1];
+  WebRtc_Word32 PreStateHiGQ15[ORDERHI+1];
+
+  WebRtc_UWord32 OldEnergy;
+
+} MaskFiltstr_enc;
+
+
+
+typedef struct {
+
+  WebRtc_Word16 PostStateLoGQ0[ORDERLO+1];
+  WebRtc_Word16 PostStateHiGQ0[ORDERHI+1];
+
+  WebRtc_UWord32 OldEnergy;
+
+} MaskFiltstr_dec;
+
+
+
+
+
+
+
+
+typedef struct {
+
+  //state vectors for each of the two analysis filters
+
+  WebRtc_Word32 INSTAT1_fix[2*(QORDER-1)];
+  WebRtc_Word32 INSTAT2_fix[2*(QORDER-1)];
+  WebRtc_Word16 INLABUF1_fix[QLOOKAHEAD];
+  WebRtc_Word16 INLABUF2_fix[QLOOKAHEAD];
+
+  /* High pass filter */
+  WebRtc_Word32 HPstates_fix[HPORDER];
+
+} PreFiltBankstr;
+
+
+typedef struct {
+
+  //state vectors for each of the two analysis filters
+  WebRtc_Word32 STATE_0_LOWER_fix[2*POSTQORDER];
+  WebRtc_Word32 STATE_0_UPPER_fix[2*POSTQORDER];
+
+  /* High pass filter */
+
+  WebRtc_Word32 HPstates1_fix[HPORDER];
+  WebRtc_Word32 HPstates2_fix[HPORDER];
+
+} PostFiltBankstr;
+
+typedef struct {
+
+
+  /* data buffer for pitch filter */
+  WebRtc_Word16 ubufQQ[PITCH_BUFFSIZE];
+
+  /* low pass state vector */
+  WebRtc_Word16 ystateQQ[PITCH_DAMPORDER];
+
+  /* old lag and gain */
+  WebRtc_Word16 oldlagQ7;
+  WebRtc_Word16 oldgainQ12;
+
+} PitchFiltstr;
+
+
+
+typedef struct {
+
+  //for inital estimator
+  WebRtc_Word16   dec_buffer16[PITCH_CORR_LEN2+PITCH_CORR_STEP2+PITCH_MAX_LAG/2-PITCH_FRAME_LEN/2+2];
+  WebRtc_Word32   decimator_state32[2*ALLPASSSECTIONS+1];
+  WebRtc_Word16   inbuf[QLOOKAHEAD];
+
+  PitchFiltstr  PFstr_wght;
+  PitchFiltstr  PFstr;
+
+
+} PitchAnalysisStruct;
+
+
+typedef struct {
+  /* Parameters used in PLC to avoid re-computation       */
+
+  /* --- residual signals --- */
+  WebRtc_Word16 prevPitchInvIn[FRAMESAMPLES/2];
+  WebRtc_Word16 prevPitchInvOut[PITCH_MAX_LAG + 10];            // [FRAMESAMPLES/2]; save 90
+  WebRtc_Word32 prevHP[PITCH_MAX_LAG + 10];                     // [FRAMESAMPLES/2]; save 90
+
+
+  WebRtc_Word16 decayCoeffPriodic; /* how much to supress a sample */
+  WebRtc_Word16 decayCoeffNoise;
+  WebRtc_Word16 used;       /* if PLC is used */
+
+
+  WebRtc_Word16 *lastPitchLP;                                  // [FRAMESAMPLES/2]; saved 240;
+
+
+  /* --- LPC side info --- */
+  WebRtc_Word16 lofilt_coefQ15[ ORDERLO ];
+  WebRtc_Word16 hifilt_coefQ15[ ORDERHI ];
+  WebRtc_Word32 gain_lo_hiQ17[2];
+
+  /* --- LTP side info --- */
+  WebRtc_Word16 AvgPitchGain_Q12;
+  WebRtc_Word16 lastPitchGain_Q12;
+  WebRtc_Word16 lastPitchLag_Q7;
+
+  /* --- Add-overlap in recovery packet --- */
+  WebRtc_Word16 overlapLP[ RECOVERY_OVERLAP ];                 // [FRAMESAMPLES/2]; saved 160
+
+  WebRtc_Word16 pitchCycles;
+  WebRtc_Word16 A;
+  WebRtc_Word16 B;
+  WebRtc_Word16 pitchIndex;
+  WebRtc_Word16 stretchLag;
+  WebRtc_Word16 *prevPitchLP;                                  // [ FRAMESAMPLES/2 ]; saved 240
+  WebRtc_Word16 seed;
+
+  WebRtc_Word16 std;
+} PLCstr;
+
+
+
+/* Have instance of struct together with other iSAC structs */
+typedef struct {
+
+  WebRtc_Word16   prevFrameSizeMs;      /* Previous frame size (in ms) */
+  WebRtc_UWord16  prevRtpNumber;      /* Previous RTP timestamp from received packet */
+  /* (in samples relative beginning)  */
+  WebRtc_UWord32  prevSendTime;   /* Send time for previous packet, from RTP header */
+  WebRtc_UWord32  prevArrivalTime;      /* Arrival time for previous packet (in ms using timeGetTime()) */
+  WebRtc_UWord16  prevRtpRate;          /* rate of previous packet, derived from RTP timestamps (in bits/s) */
+  WebRtc_UWord32  lastUpdate;           /* Time since the last update of the Bottle Neck estimate (in samples) */
+  WebRtc_UWord32  lastReduction;        /* Time sinse the last reduction (in samples) */
+  WebRtc_Word32   countUpdates;         /* How many times the estimate was update in the beginning */
+
+  /* The estimated bottle neck rate from there to here (in bits/s)                */
+  WebRtc_UWord32  recBw;
+  WebRtc_UWord32  recBwInv;
+  WebRtc_UWord32  recBwAvg;
+  WebRtc_UWord32  recBwAvgQ;
+
+  WebRtc_UWord32  minBwInv;
+  WebRtc_UWord32  maxBwInv;
+
+  /* The estimated mean absolute jitter value, as seen on this side (in ms)       */
+  WebRtc_Word32   recJitter;
+  WebRtc_Word32   recJitterShortTerm;
+  WebRtc_Word32   recJitterShortTermAbs;
+  WebRtc_Word32   recMaxDelay;
+  WebRtc_Word32   recMaxDelayAvgQ;
+
+
+  WebRtc_Word16   recHeaderRate;         /* (assumed) bitrate for headers (bps) */
+
+  WebRtc_UWord32  sendBwAvg;           /* The estimated bottle neck rate from here to there (in bits/s) */
+  WebRtc_Word32   sendMaxDelayAvg;    /* The estimated mean absolute jitter value, as seen on the other siee (in ms)  */
+
+
+  WebRtc_Word16   countRecPkts;          /* number of packets received since last update */
+  WebRtc_Word16   highSpeedRec;        /* flag for marking that a high speed network has been detected downstream */
+
+  /* number of consecutive pkts sent during which the bwe estimate has
+     remained at a value greater than the downstream threshold for determining highspeed network */
+  WebRtc_Word16   countHighSpeedRec;
+
+  /* flag indicating bwe should not adjust down immediately for very late pckts */
+  WebRtc_Word16   inWaitPeriod;
+
+  /* variable holding the time of the start of a window of time when
+     bwe should not adjust down immediately for very late pckts */
+  WebRtc_UWord32  startWaitPeriod;
+
+  /* number of consecutive pkts sent during which the bwe estimate has
+     remained at a value greater than the upstream threshold for determining highspeed network */
+  WebRtc_Word16   countHighSpeedSent;
+
+  /* flag indicated the desired number of packets over threshold rate have been sent and
+     bwe will assume the connection is over broadband network */
+  WebRtc_Word16   highSpeedSend;
+
+
+
+
+} BwEstimatorstr;
+
+
+typedef struct {
+
+  /* boolean, flags if previous packet exceeded B.N. */
+  WebRtc_Word16    PrevExceed;
+  /* ms */
+  WebRtc_Word16    ExceedAgo;
+  /* packets left to send in current burst */
+  WebRtc_Word16    BurstCounter;
+  /* packets */
+  WebRtc_Word16    InitCounter;
+  /* ms remaining in buffer when next packet will be sent */
+  WebRtc_Word16    StillBuffered;
+
+} RateModel;
+
+/* The following strutc is used to store data from encoding, to make it
+   fast and easy to construct a new bitstream with a different Bandwidth
+   estimate. All values (except framelength and minBytes) is double size to
+   handle 60 ms of data.
+*/
+typedef struct {
+
+  /* Used to keep track of if it is first or second part of 60 msec packet */
+  int     startIdx;
+
+  /* Frame length in samples */
+  WebRtc_Word16         framelength;
+
+  /* Pitch Gain */
+  WebRtc_Word16   pitchGain_index[2];
+
+  /* Pitch Lag */
+  WebRtc_Word32   meanGain[2];
+  WebRtc_Word16   pitchIndex[PITCH_SUBFRAMES*2];
+
+  /* LPC */
+  WebRtc_Word32         LPCcoeffs_g[12*2]; /* KLT_ORDER_GAIN = 12 */
+  WebRtc_Word16   LPCindex_s[108*2]; /* KLT_ORDER_SHAPE = 108 */
+  WebRtc_Word16   LPCindex_g[12*2];  /* KLT_ORDER_GAIN = 12 */
+
+  /* Encode Spec */
+  WebRtc_Word16   fre[FRAMESAMPLES];
+  WebRtc_Word16   fim[FRAMESAMPLES];
+  WebRtc_Word16   AvgPitchGain[2];
+
+  /* Used in adaptive mode only */
+  int     minBytes;
+
+} ISAC_SaveEncData_t;
+
+typedef struct {
+
+  Bitstr_enc          bitstr_obj;
+  MaskFiltstr_enc     maskfiltstr_obj;
+  PreFiltBankstr      prefiltbankstr_obj;
+  PitchFiltstr        pitchfiltstr_obj;
+  PitchAnalysisStruct pitchanalysisstr_obj;
+  RateModel           rate_data_obj;
+
+  WebRtc_Word16         buffer_index;
+  WebRtc_Word16         current_framesamples;
+
+  WebRtc_Word16      data_buffer_fix[FRAMESAMPLES]; // the size was MAX_FRAMESAMPLES
+
+  WebRtc_Word16         frame_nb;
+  WebRtc_Word16         BottleNeck;
+  WebRtc_Word16         MaxDelay;
+  WebRtc_Word16         new_framelength;
+  WebRtc_Word16         s2nr;
+  WebRtc_UWord16        MaxBits;
+
+  WebRtc_Word16         bitstr_seed;
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  PostFiltBankstr     interpolatorstr_obj;
+#endif
+
+  ISAC_SaveEncData_t *SaveEnc_ptr;
+  WebRtc_Word16         payloadLimitBytes30; /* Maximum allowed number of bits for a 30 msec packet */
+  WebRtc_Word16         payloadLimitBytes60; /* Maximum allowed number of bits for a 30 msec packet */
+  WebRtc_Word16         maxPayloadBytes;     /* Maximum allowed number of bits for both 30 and 60 msec packet */
+  WebRtc_Word16         maxRateInBytes;      /* Maximum allowed rate in bytes per 30 msec packet */
+  WebRtc_Word16         enforceFrameSize;    /* If set iSAC will never change packet size */
+
+} ISACFIX_EncInst_t;
+
+
+typedef struct {
+
+  Bitstr_dec          bitstr_obj;
+  MaskFiltstr_dec     maskfiltstr_obj;
+  PostFiltBankstr     postfiltbankstr_obj;
+  PitchFiltstr        pitchfiltstr_obj;
+  PLCstr              plcstr_obj;               /* TS; for packet loss concealment */
+
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+  PreFiltBankstr      decimatorstr_obj;
+#endif
+
+} ISACFIX_DecInst_t;
+
+
+
+typedef struct {
+
+  ISACFIX_EncInst_t ISACenc_obj;
+  ISACFIX_DecInst_t ISACdec_obj;
+  BwEstimatorstr     bwestimator_obj;
+  WebRtc_Word16         CodingMode;       /* 0 = adaptive; 1 = instantaneous */
+  WebRtc_Word16   errorcode;
+  WebRtc_Word16   initflag;  /* 0 = nothing initiated; 1 = encoder or decoder */
+  /* not initiated; 2 = all initiated */
+} ISACFIX_SubStruct;
+
+
+typedef struct {
+  WebRtc_Word32   lpcGains[12];     /* 6 lower-band & 6 upper-band we may need to double it for 60*/
+  /* */
+  WebRtc_UWord32  W_upper;          /* Upper boundary of interval W */
+  WebRtc_UWord32  streamval;
+  WebRtc_UWord16  stream_index;     /* Index to the current position in bytestream */
+  WebRtc_Word16   full;             /* 0 - first byte in memory filled, second empty*/
+  /* 1 - both bytes are empty (we just filled the previous memory */
+  WebRtc_UWord16  beforeLastWord;
+  WebRtc_UWord16  lastWord;
+} transcode_obj;
+
+
+//Bitstr_enc myBitStr;
+
+#endif  /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_STRUCTS_H_ */
diff --git a/src/modules/audio_coding/codecs/isac/fix/source/transform.c b/src/modules/audio_coding/codecs/isac/fix/source/transform.c
new file mode 100644
index 0000000..56ef9f2
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/source/transform.c
@@ -0,0 +1,296 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * WebRtcIsacfix_kTransform.c
+ *
+ * Transform functions
+ *
+ */
+
+#include "fft.h"
+#include "codec.h"
+#include "settings.h"
+
+
+/* Cosine table 1 in Q14 */
+static const WebRtc_Word16 kCosTab1[FRAMESAMPLES/2] = {
+  16384,  16383,  16378,  16371,  16362,  16349,  16333,  16315,  16294,  16270,
+  16244,  16214,  16182,  16147,  16110,  16069,  16026,  15980,  15931,  15880,
+  15826,  15769,  15709,  15647,  15582,  15515,  15444,  15371,  15296,  15218,
+  15137,  15053,  14968,  14879,  14788,  14694,  14598,  14500,  14399,  14295,
+  14189,  14081,  13970,  13856,  13741,  13623,  13502,  13380,  13255,  13128,
+  12998,  12867,  12733,  12597,  12458,  12318,  12176,  12031,  11885,  11736,
+  11585,  11433,  11278,  11121,  10963,  10803,  10641,  10477,  10311,  10143,
+  9974,   9803,   9630,   9456,   9280,   9102,   8923,   8743,   8561,   8377,
+  8192,   8006,   7818,   7629,   7438,   7246,   7053,   6859,   6664,   6467,
+  6270,   6071,   5872,   5671,   5469,   5266,   5063,   4859,   4653,   4447,
+  4240,   4033,   3825,   3616,   3406,   3196,   2986,   2775,   2563,   2351,
+  2139,   1926,   1713,   1499,   1285,   1072,    857,    643,    429,    214,
+  0,   -214,   -429,   -643,   -857,  -1072,  -1285,  -1499,  -1713,  -1926,
+  -2139,  -2351,  -2563,  -2775,  -2986,  -3196,  -3406,  -3616,  -3825,  -4033,
+  -4240,  -4447,  -4653,  -4859,  -5063,  -5266,  -5469,  -5671,  -5872,  -6071,
+  -6270,  -6467,  -6664,  -6859,  -7053,  -7246,  -7438,  -7629,  -7818,  -8006,
+  -8192,  -8377,  -8561,  -8743,  -8923,  -9102,  -9280,  -9456,  -9630,  -9803,
+  -9974, -10143, -10311, -10477, -10641, -10803, -10963, -11121, -11278, -11433,
+  -11585, -11736, -11885, -12031, -12176, -12318, -12458, -12597, -12733, -12867,
+  -12998, -13128, -13255, -13380, -13502, -13623, -13741, -13856, -13970, -14081,
+  -14189, -14295, -14399, -14500, -14598, -14694, -14788, -14879, -14968, -15053,
+  -15137, -15218, -15296, -15371, -15444, -15515, -15582, -15647, -15709, -15769,
+  -15826, -15880, -15931, -15980, -16026, -16069, -16110, -16147, -16182, -16214,
+  -16244, -16270, -16294, -16315, -16333, -16349, -16362, -16371, -16378, -16383
+};
+
+
+/* Sine table 1 in Q14 */
+static const WebRtc_Word16 kSinTab1[FRAMESAMPLES/2] = {
+  0,   214,   429,   643,   857,  1072,  1285,  1499,  1713,  1926,
+  2139,  2351,  2563,  2775,  2986,  3196,  3406,  3616,  3825,  4033,
+  4240,  4447,  4653,  4859,  5063,  5266,  5469,  5671,  5872,  6071,
+  6270,  6467,  6664,  6859,  7053,  7246,  7438,  7629,  7818,  8006,
+  8192,  8377,  8561,  8743,  8923,  9102,  9280,  9456,  9630,  9803,
+  9974, 10143, 10311, 10477, 10641, 10803, 10963, 11121, 11278, 11433,
+  11585, 11736, 11885, 12031, 12176, 12318, 12458, 12597, 12733, 12867,
+  12998, 13128, 13255, 13380, 13502, 13623, 13741, 13856, 13970, 14081,
+  14189, 14295, 14399, 14500, 14598, 14694, 14788, 14879, 14968, 15053,
+  15137, 15218, 15296, 15371, 15444, 15515, 15582, 15647, 15709, 15769,
+  15826, 15880, 15931, 15980, 16026, 16069, 16110, 16147, 16182, 16214,
+  16244, 16270, 16294, 16315, 16333, 16349, 16362, 16371, 16378, 16383,
+  16384, 16383, 16378, 16371, 16362, 16349, 16333, 16315, 16294, 16270,
+  16244, 16214, 16182, 16147, 16110, 16069, 16026, 15980, 15931, 15880,
+  15826, 15769, 15709, 15647, 15582, 15515, 15444, 15371, 15296, 15218,
+  15137, 15053, 14968, 14879, 14788, 14694, 14598, 14500, 14399, 14295,
+  14189, 14081, 13970, 13856, 13741, 13623, 13502, 13380, 13255, 13128,
+  12998, 12867, 12733, 12597, 12458, 12318, 12176, 12031, 11885, 11736,
+  11585, 11433, 11278, 11121, 10963, 10803, 10641, 10477, 10311, 10143,
+  9974,  9803,  9630,  9456,  9280,  9102,  8923,  8743,  8561,  8377,
+  8192,  8006,  7818,  7629,  7438,  7246,  7053,  6859,  6664,  6467,
+  6270,  6071,  5872,  5671,  5469,  5266,  5063,  4859,  4653,  4447,
+  4240,  4033,  3825,  3616,  3406,  3196,  2986,  2775,  2563,  2351,
+  2139,  1926,  1713,  1499,  1285,  1072,   857,   643,   429,   214
+};
+
+
+/* Cosine table 2 in Q14 */
+static const WebRtc_Word16 kCosTab2[FRAMESAMPLES/4] = {
+  107,   -322,   536,   -750,   965,  -1179,  1392,  -1606,  1819,  -2032,
+  2245,  -2457,  2669,  -2880,  3091,  -3301,  3511,  -3720,  3929,  -4137,
+  4344,  -4550,  4756,  -4961,  5165,  -5368,  5570,  -5771,  5971,  -6171,
+  6369,  -6566,  6762,  -6957,  7150,  -7342,  7534,  -7723,  7912,  -8099,
+  8285,  -8469,  8652,  -8833,  9013,  -9191,  9368,  -9543,  9717,  -9889,
+  10059, -10227, 10394, -10559, 10722, -10883, 11042, -11200, 11356, -11509,
+  11661, -11810, 11958, -12104, 12247, -12389, 12528, -12665, 12800, -12933,
+  13063, -13192, 13318, -13441, 13563, -13682, 13799, -13913, 14025, -14135,
+  14242, -14347, 14449, -14549, 14647, -14741, 14834, -14924, 15011, -15095,
+  15178, -15257, 15334, -15408, 15480, -15549, 15615, -15679, 15739, -15798,
+  15853, -15906, 15956, -16003, 16048, -16090, 16129, -16165, 16199, -16229,
+  16257, -16283, 16305, -16325, 16342, -16356, 16367, -16375, 16381, -16384
+};
+
+
+/* Sine table 2 in Q14 */
+static const WebRtc_Word16 kSinTab2[FRAMESAMPLES/4] = {
+  16384, -16381, 16375, -16367, 16356, -16342, 16325, -16305, 16283, -16257,
+  16229, -16199, 16165, -16129, 16090, -16048, 16003, -15956, 15906, -15853,
+  15798, -15739, 15679, -15615, 15549, -15480, 15408, -15334, 15257, -15178,
+  15095, -15011, 14924, -14834, 14741, -14647, 14549, -14449, 14347, -14242,
+  14135, -14025, 13913, -13799, 13682, -13563, 13441, -13318, 13192, -13063,
+  12933, -12800, 12665, -12528, 12389, -12247, 12104, -11958, 11810, -11661,
+  11509, -11356, 11200, -11042, 10883, -10722, 10559, -10394, 10227, -10059,
+  9889,  -9717,  9543,  -9368,  9191,  -9013,  8833,  -8652,  8469,  -8285,
+  8099,  -7912,  7723,  -7534,  7342,  -7150,  6957,  -6762,  6566,  -6369,
+  6171,  -5971,  5771,  -5570,  5368,  -5165,  4961,  -4756,  4550,  -4344,
+  4137,  -3929,  3720,  -3511,  3301,  -3091,  2880,  -2669,  2457,  -2245,
+  2032,  -1819,  1606,  -1392,  1179,   -965,   750,   -536,   322,   -107
+};
+
+
+
+void WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9,
+                             WebRtc_Word16 *inre2Q9,
+                             WebRtc_Word16 *outreQ7,
+                             WebRtc_Word16 *outimQ7)
+{
+
+  int k;
+  WebRtc_Word32 tmpreQ16[FRAMESAMPLES/2], tmpimQ16[FRAMESAMPLES/2];
+  WebRtc_Word16 tmp1rQ14, tmp1iQ14;
+  WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16;
+  WebRtc_Word32 v1Q16, v2Q16;
+  WebRtc_Word16 factQ19, sh;
+
+  /* Multiply with complex exponentials and combine into one complex vector */
+  factQ19 = 16921; // 0.5/sqrt(240) in Q19 is round(.5/sqrt(240)*(2^19)) = 16921
+  for (k = 0; k < FRAMESAMPLES/2; k++) {
+    tmp1rQ14 = kCosTab1[k];
+    tmp1iQ14 = kSinTab1[k];
+    xrQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre1Q9[k]) + WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre2Q9[k]), 7);
+    xiQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre2Q9[k]) - WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre1Q9[k]), 7);
+    tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
+    tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
+  }
+
+
+  xrQ16  = WebRtcSpl_MaxAbsValueW32(tmpreQ16, FRAMESAMPLES/2);
+  yrQ16 = WebRtcSpl_MaxAbsValueW32(tmpimQ16, FRAMESAMPLES/2);
+  if (yrQ16>xrQ16) {
+    xrQ16 = yrQ16;
+  }
+
+  sh = WebRtcSpl_NormW32(xrQ16);
+  sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
+  //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)
+
+  //"Fastest" vectors
+  if (sh>=0) {
+    for (k=0; k<FRAMESAMPLES/2; k++) {
+      inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpreQ16[k], sh); //Q(16+sh)
+      inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpimQ16[k], sh); //Q(16+sh)
+    }
+  } else {
+    WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1);
+    for (k=0; k<FRAMESAMPLES/2; k++) {
+      inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpreQ16[k]+round, -sh); //Q(16+sh)
+      inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpimQ16[k]+round, -sh); //Q(16+sh)
+    }
+  }
+
+  /* Get DFT */
+  WebRtcIsacfix_FftRadix16Fastest(inre1Q9, inre2Q9, -1); // real call
+
+  //"Fastest" vectors
+  if (sh>=0) {
+    for (k=0; k<FRAMESAMPLES/2; k++) {
+      tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre1Q9[k], sh); //Q(16+sh) -> Q16
+      tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre2Q9[k], sh); //Q(16+sh) -> Q16
+    }
+  } else {
+    for (k=0; k<FRAMESAMPLES/2; k++) {
+      tmpreQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre1Q9[k], -sh); //Q(16+sh) -> Q16
+      tmpimQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre2Q9[k], -sh); //Q(16+sh) -> Q16
+    }
+  }
+
+
+  /* Use symmetry to separate into two complex vectors and center frames in time around zero */
+  for (k = 0; k < FRAMESAMPLES/4; k++) {
+    xrQ16 = tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
+    yiQ16 = -tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
+    xiQ16 = tmpimQ16[k] - tmpimQ16[FRAMESAMPLES/2 - 1 - k];
+    yrQ16 = tmpimQ16[k] + tmpimQ16[FRAMESAMPLES/2 - 1 - k];
+    tmp1rQ14 = kCosTab2[k];
+    tmp1iQ14 = kSinTab2[k];
+    v1Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xiQ16);
+    v2Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xiQ16);
+    outreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v1Q16, 9);
+    outimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v2Q16, 9);
+    v1Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yiQ16);
+    v2Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yiQ16);
+    outreQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); //CalcLrIntQ(v1Q16, 9);
+    outimQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); //CalcLrIntQ(v2Q16, 9);
+
+  }
+}
+
+
+void WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7, WebRtc_Word16 *inimQ7, WebRtc_Word32 *outre1Q16, WebRtc_Word32 *outre2Q16)
+{
+
+  int k;
+  WebRtc_Word16 tmp1rQ14, tmp1iQ14;
+  WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16;
+  WebRtc_Word32 tmpInRe, tmpInIm, tmpInRe2, tmpInIm2;
+  WebRtc_Word16 factQ11;
+  WebRtc_Word16 sh;
+
+  for (k = 0; k < FRAMESAMPLES/4; k++) {
+    /* Move zero in time to beginning of frames */
+    tmp1rQ14 = kCosTab2[k];
+    tmp1iQ14 = kSinTab2[k];
+
+    tmpInRe = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[k], 9);  // Q7 -> Q16
+    tmpInIm = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[k], 9);  // Q7 -> Q16
+    tmpInRe2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[FRAMESAMPLES/2 - 1 - k], 9);  // Q7 -> Q16
+    tmpInIm2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[FRAMESAMPLES/2 - 1 - k], 9);  // Q7 -> Q16
+
+    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm);
+    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe);
+    yrQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm2) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe2);
+    yiQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe2) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm2);
+
+    /* Combine into one vector,  z = x + j * y */
+    outre1Q16[k] = xrQ16 - yiQ16;
+    outre1Q16[FRAMESAMPLES/2 - 1 - k] = xrQ16 + yiQ16;
+    outre2Q16[k] = xiQ16 + yrQ16;
+    outre2Q16[FRAMESAMPLES/2 - 1 - k] = -xiQ16 + yrQ16;
+  }
+
+  /* Get IDFT */
+  tmpInRe  = WebRtcSpl_MaxAbsValueW32(outre1Q16, 240);
+  tmpInIm = WebRtcSpl_MaxAbsValueW32(outre2Q16, 240);
+  if (tmpInIm>tmpInRe) {
+    tmpInRe = tmpInIm;
+  }
+
+  sh = WebRtcSpl_NormW32(tmpInRe);
+  sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
+  //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)
+
+  //"Fastest" vectors
+  if (sh>=0) {
+    for (k=0; k<240; k++) {
+      inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre1Q16[k], sh); //Q(16+sh)
+      inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre2Q16[k], sh); //Q(16+sh)
+    }
+  } else {
+    WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1);
+    for (k=0; k<240; k++) {
+      inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre1Q16[k]+round, -sh); //Q(16+sh)
+      inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre2Q16[k]+round, -sh); //Q(16+sh)
+    }
+  }
+
+  WebRtcIsacfix_FftRadix16Fastest(inreQ7, inimQ7, 1); // real call
+
+  //"Fastest" vectors
+  if (sh>=0) {
+    for (k=0; k<240; k++) {
+      outre1Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inreQ7[k], sh); //Q(16+sh) -> Q16
+      outre2Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inimQ7[k], sh); //Q(16+sh) -> Q16
+    }
+  } else {
+    for (k=0; k<240; k++) {
+      outre1Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inreQ7[k], -sh); //Q(16+sh) -> Q16
+      outre2Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inimQ7[k], -sh); //Q(16+sh) -> Q16
+    }
+  }
+
+  /* Divide through by the normalizing constant: */
+  /* scale all values with 1/240, i.e. with 273 in Q16 */
+  /* 273/65536 ~= 0.0041656                            */
+  /*     1/240 ~= 0.0041666                            */
+  for (k=0; k<240; k++) {
+    outre1Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre1Q16[k]);
+    outre2Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k]);
+  }
+
+  /* Demodulate and separate */
+  factQ11 = 31727; // sqrt(240) in Q11 is round(15.49193338482967*2048) = 31727
+  for (k = 0; k < FRAMESAMPLES/2; k++) {
+    tmp1rQ14 = kCosTab1[k];
+    tmp1iQ14 = kSinTab1[k];
+    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre1Q16[k]) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre2Q16[k]);
+    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre2Q16[k]) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre1Q16[k]);
+    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16);
+    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16);
+    outre2Q16[k] = xiQ16;
+    outre1Q16[k] = xrQ16;
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/ISACHist.cc b/src/modules/audio_coding/codecs/isac/fix/test/ISACHist.cc
new file mode 100644
index 0000000..753acd7
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/ISACHist.cc
@@ -0,0 +1,173 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+//#include "isac_codec.h"
+//#include "isac_structs.h"
+#include "isacfix.h"
+
+
+#define NUM_CODECS 1
+
+int main(int argc, char* argv[])
+{
+    FILE *inFileList;
+    FILE *audioFile;
+    FILE *outFile;
+    char audioFileName[501];
+    short audioBuff[960];
+    short encoded[600];
+    short startAudio;
+    short encodedLen;
+    ISACFIX_MainStruct *isac_struct;
+    unsigned long int hist[601];
+
+    // reset the histogram
+    for(short n=0; n < 601; n++)
+    {
+        hist[n] = 0;
+    }
+    
+    
+    inFileList = fopen(argv[1], "r");
+    if(inFileList == NULL)
+    {
+        printf("Could not open the input file.\n");
+        getchar();
+        exit(-1);
+    }
+    outFile = fopen(argv[2], "w");
+    if(outFile == NULL)
+    {
+        printf("Could not open the histogram file.\n");
+        getchar();
+        exit(-1);
+    }
+
+    short frameSizeMsec = 30;
+    if(argc > 3)
+    {
+        frameSizeMsec = atoi(argv[3]);
+    }
+    
+    short audioOffset = 0;
+    if(argc > 4)
+    {
+        audioOffset = atoi(argv[4]);
+    }
+    int ok;
+    ok = WebRtcIsacfix_Create(&isac_struct);
+    // instantaneous mode
+    ok |= WebRtcIsacfix_EncoderInit(isac_struct, 1);
+    // is not used but initialize
+    ok |= WebRtcIsacfix_DecoderInit(isac_struct);    
+    ok |= WebRtcIsacfix_Control(isac_struct, 32000, frameSizeMsec);
+
+    if(ok != 0)
+    {
+        printf("\nProblem in seting up iSAC\n");
+        exit(-1);
+    } 
+
+    while( fgets(audioFileName, 500, inFileList) != NULL )
+    {
+        // remove trailing white-spaces and any Cntrl character
+        if(strlen(audioFileName) == 0)
+        {
+            continue;
+        }
+        short n = strlen(audioFileName) - 1;
+        while(isspace(audioFileName[n]) || iscntrl(audioFileName[n]))
+        {
+            audioFileName[n] = '\0';
+            n--;
+            if(n < 0)
+            {
+                break;
+            }
+        }
+
+        // remove leading spaces
+        if(strlen(audioFileName) == 0)
+        {
+            continue;
+        }
+        n = 0;
+        while((isspace(audioFileName[n]) || iscntrl(audioFileName[n])) && 
+            (audioFileName[n] != '\0'))
+        {
+            n++;
+        }
+        memmove(audioFileName, &audioFileName[n], 500 - n);
+        if(strlen(audioFileName) == 0)
+        {
+            continue;
+        }
+        audioFile = fopen(audioFileName, "rb");
+        if(audioFile == NULL)
+        {
+            printf("\nCannot open %s!!!!!\n", audioFileName);
+            exit(0);
+        }
+
+        if(audioOffset > 0)
+        {
+            fseek(audioFile, (audioOffset<<1), SEEK_SET);
+        }
+        
+        while(fread(audioBuff, sizeof(short), (480*frameSizeMsec/30), audioFile) >= (480*frameSizeMsec/30))
+        {            
+            startAudio = 0;
+            do
+            {
+                encodedLen = WebRtcIsacfix_Encode(isac_struct, 
+                                                  &audioBuff[startAudio], encoded);
+                startAudio += 160;            
+            } while(encodedLen == 0);
+
+            if(encodedLen < 0)
+            {
+                printf("\nEncoding Error!!!\n");
+                exit(0);
+            }
+            hist[encodedLen]++;
+        }
+        fclose(audioFile);
+    }
+    fclose(inFileList);
+    unsigned long totalFrames = 0;
+    for(short n=0; n < 601; n++)
+    {
+        totalFrames += hist[n];
+        fprintf(outFile, "%10lu\n", hist[n]);
+    }
+    fclose(outFile);
+    
+    short topTenCntr = 0;
+    printf("\nTotal number of Frames %lu\n\n", totalFrames);
+    printf("Payload Len    # occurences\n");
+    printf("===========    ============\n");
+
+    for(short n = 600; (n >= 0) && (topTenCntr < 10); n--)
+    {
+        if(hist[n] > 0)
+        {
+            topTenCntr++;
+            printf("    %3d            %3d\n", n, hist[n]);
+        }
+    }
+    WebRtcIsacfix_Free(isac_struct);    
+    return 0;
+}
+    
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/Isac_test.cc b/src/modules/audio_coding/codecs/isac/fix/test/Isac_test.cc
new file mode 100644
index 0000000..2791db4
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/Isac_test.cc
@@ -0,0 +1,260 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/******************************************************************
+	Stand Alone test application for ISACFIX and ISAC LC
+
+******************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "typedefs.h"
+
+#include "isacfix.h"
+ISACFIX_MainStruct *ISACfix_inst;
+
+#define FS								16000
+
+
+typedef struct {
+	WebRtc_UWord32 arrival_time;            /* samples */
+	WebRtc_UWord32 sample_count;            /* samples */
+	WebRtc_UWord16 rtp_number;
+} BottleNeckModel;
+
+void get_arrival_time(int current_framesamples,   /* samples */
+					  int packet_size,            /* bytes */
+					  int bottleneck,             /* excluding headers; bits/s */
+					  BottleNeckModel *BN_data)
+{
+	const int HeaderSize = 35; 
+	int HeaderRate;
+
+	HeaderRate = HeaderSize * 8 * FS / current_framesamples;     /* bits/s */
+
+	/* everything in samples */
+	BN_data->sample_count = BN_data->sample_count + current_framesamples;
+
+	BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate);
+
+	if (BN_data->arrival_time < BN_data->sample_count)
+		BN_data->arrival_time = BN_data->sample_count;
+
+	BN_data->rtp_number++;
+}
+
+/*
+#ifdef __cplusplus
+extern "C" {
+#endif
+*/
+int main(int argc, char* argv[]){ 
+
+	/* Parameters */
+	FILE *pInFile, *pOutFile, *pChcFile; 
+	WebRtc_Word8 inFile[40];
+	WebRtc_Word8 outFile[40];
+	WebRtc_Word8 chcFile[40];
+	WebRtc_Word8 codec[10];
+	WebRtc_Word16 bitrt, spType, size;
+	WebRtc_UWord16 frameLen;
+	WebRtc_Word16 sigOut[1000], sigIn[1000]; 
+	WebRtc_UWord16 bitStream[500]; /* double to 32 kbps for 60 ms */
+
+	WebRtc_Word16 chc, ok;
+	int noOfCalls, cdlen;
+	WebRtc_Word16 noOfLostFrames;
+	int err, errtype;
+
+	BottleNeckModel       BN_data;
+
+	int totalbits =0;
+	int totalsmpls =0;
+
+	/*End Parameters*/
+
+	
+	if ((argc==6)||(argc==7) ){
+
+		strcpy(codec,argv[5]);
+
+		if(argc==7){
+			if (!_stricmp("isac",codec)){
+				bitrt = atoi(argv[6]);
+				if ( (bitrt<10000)&&(bitrt>32000)){
+					printf("Error: Supported bit rate in the range 10000-32000 bps!\n");
+					exit(-1);
+				}
+
+			}else{
+	      printf("Error: Codec not recognized. Check spelling!\n");
+	      exit(-1);
+			}
+
+		} else { 
+				printf("Error: Codec not recognized. Check spelling!\n");
+				exit(-1);
+		}
+	} else {
+		printf("Error: Wrong number of input parameter!\n\n");
+		exit(-1);
+	}
+	
+	frameLen = atoi(argv[4]);
+	strcpy(chcFile,argv[3]);
+	strcpy(outFile,argv[2]);
+	strcpy(inFile,argv[1]);
+
+	/*  Open file streams */
+	if( (pInFile = fopen(inFile,"rb")) == NULL ) {
+		printf( "Error: Did not find input file!\n" );
+		exit(-1);
+	}
+	strcat(outFile,"_");
+	strcat(outFile, argv[4]);
+	strcat(outFile,"_");
+	strcat(outFile, codec);
+	
+	if (argc==7){
+		strcat(outFile,"_");
+		strcat(outFile, argv[6]);
+	}
+	if (_stricmp("none", chcFile)){
+		strcat(outFile,"_");
+		strcat(outFile, "plc");
+	}
+	
+	strcat(outFile, ".otp");
+	
+	if (_stricmp("none", chcFile)){
+		if( (pChcFile = fopen(chcFile,"rb")) == NULL ) {
+			printf( "Error: Did not find channel file!\n" );
+			exit(-1);
+		}
+	}
+    /******************************************************************/
+	if (!_stricmp("isac", codec)){    /*    ISAC   */
+		if ((frameLen!=480)&&(frameLen!=960)) {
+			printf("Error: ISAC only supports 480 and 960 samples per frame (not %d)\n", frameLen);
+			exit(-1);
+		}
+		if( (pOutFile = fopen(outFile,"wb")) == NULL ) {
+			printf( "Could not open output file!\n" );
+			exit(-1);
+		}
+		ok=WebRtcIsacfix_Create(&ISACfix_inst);
+		if (ok!=0) {
+			printf("Couldn't allocate memory for iSAC fix instance\n");
+			exit(-1);
+		}
+
+		BN_data.arrival_time  = 0;
+		BN_data.sample_count  = 0;
+		BN_data.rtp_number    = 0;
+
+		WebRtcIsacfix_EncoderInit(ISACfix_inst,1);
+		WebRtcIsacfix_DecoderInit(ISACfix_inst);
+		err = WebRtcIsacfix_Control(ISACfix_inst, bitrt, (frameLen>>4));
+		if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+				exit(EXIT_FAILURE);
+			}
+		/* loop over frame */
+		while (fread(sigIn,sizeof(WebRtc_Word16),frameLen,pInFile) == frameLen) {
+			
+			noOfCalls=0;
+			cdlen=0;
+			while (cdlen<=0) {
+				cdlen=WebRtcIsacfix_Encode(ISACfix_inst,&sigIn[noOfCalls*160],(WebRtc_Word16*)bitStream);
+				if(cdlen==-1){
+					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
+					printf("\n\nError in encoder: %d.\n\n", errtype);
+					exit(-1);
+				}
+				noOfCalls++;
+			}
+	
+	
+			if(_stricmp("none", chcFile)){
+				if (fread(&chc,sizeof(WebRtc_Word16),1,pChcFile)!=1) /* packet may be lost */
+					break;
+			} else {
+				chc = 1; /* packets never lost */
+			}
+					
+			/* simulate packet handling through NetEq and the modem */
+			get_arrival_time(frameLen, cdlen, bitrt, &BN_data);
+			
+			if (chc){ /* decode */
+
+				err = WebRtcIsacfix_UpdateBwEstimate1(ISACfix_inst,
+								  bitStream,
+								  cdlen,
+								  BN_data.rtp_number,
+								  BN_data.arrival_time);
+
+				if (err < 0) {
+					/* exit if returned with error */
+					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
+					printf("\n\nError in decoder: %d.\n\n", errtype);
+					exit(EXIT_FAILURE);
+				}
+				size = WebRtcIsacfix_Decode(ISACfix_inst, bitStream, cdlen, sigOut, &spType);
+				if(size<=0){
+					/* exit if returned with error */
+					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
+					printf("\n\nError in decoder: %d.\n\n", errtype);
+					exit(-1);
+				}
+			} else { /* PLC */
+				if (frameLen == 480){
+					noOfLostFrames = 1;
+				} else{
+					noOfLostFrames = 2;
+				}
+				size = WebRtcIsacfix_DecodePlc(ISACfix_inst, sigOut, noOfLostFrames );
+				if(size<=0){
+					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
+					printf("\n\nError in decoder: %d.\n\n", errtype);
+					exit(-1);
+				}
+			}
+				
+			/* Write decoded speech to file */
+			fwrite(sigOut,sizeof(short),size,pOutFile);
+
+		totalbits += 8 * cdlen;
+		totalsmpls += size;
+
+		}
+	/******************************************************************/
+	}
+
+//	printf("\n\ntotal bits				= %d bits", totalbits);
+	printf("\nmeasured average bitrate		= %0.3f kbits/s", (double)totalbits * 16 / totalsmpls);
+	printf("\n");
+
+
+	fclose(pInFile);
+	fclose(pOutFile);
+	if (_stricmp("none", chcFile)){
+		fclose(pChcFile);
+	}
+
+	if (!_stricmp("isac", codec)){
+		WebRtcIsacfix_Free(ISACfix_inst);
+	}
+									 			
+	return 0;
+
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/ChannelFiles.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/ChannelFiles.txt
new file mode 100644
index 0000000..05f7410
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/ChannelFiles.txt
@@ -0,0 +1,3 @@
+bottlenecks.txt
+lowrates.txt
+tworates.txt
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/InputFiles.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/InputFiles.txt
new file mode 100644
index 0000000..f26b7af
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/InputFiles.txt
@@ -0,0 +1,31 @@
+DTMF_16kHz_long.pcm
+DTMF_16kHz_short.pcm
+F00.INP
+F01.INP
+F02.INP
+F03.INP
+F04.INP
+F05.INP
+F06.INP
+longtest.pcm
+ltest_speech_clean.pcm
+ltest_music.pcm
+ltest_speech_noisy.pcm
+misc2.pcm
+purenb.pcm
+sawsweep_380_60.pcm
+sinesweep.pcm
+sinesweep_half.pcm
+speechmusic.pcm
+speechmusic_nb.pcm
+speechoffice0dB.pcm
+speech_and_misc_NB.pcm
+speech_and_misc_WB.pcm
+testM4.pcm
+testM4D_rev.pcm  
+testM4D.pcm  
+testfile.pcm
+tone_cisco.pcm
+tone_cisco_long.pcm
+wb_contspeech.pcm
+wb_speech_office25db.pcm
\ No newline at end of file
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/InputFilesFew.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/InputFilesFew.txt
new file mode 100644
index 0000000..08bbde3
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/InputFilesFew.txt
@@ -0,0 +1,6 @@
+DTMF_16kHz_short.pcm
+ltest_speech_noisy.pcm
+misc2.pcm
+sinesweep.pcm
+speechmusic.pcm
+tone_cisco.pcm
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/ListOfTestCases.xls b/src/modules/audio_coding/codecs/isac/fix/test/QA/ListOfTestCases.xls
new file mode 100644
index 0000000..f0889ef
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/ListOfTestCases.xls
Binary files differ
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/diffiSAC.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/diffiSAC.txt
new file mode 100644
index 0000000..96b87c0
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/diffiSAC.txt
@@ -0,0 +1,481 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+diff ../dataqa350/i30_1DTMF_16kHz_long.pcm ../dataqa351/i30_1DTMF_16kHz_long.pcm
+diff ../dataqa350/i60_1DTMF_16kHz_long.pcm ../dataqa351/i60_1DTMF_16kHz_long.pcm
+diff ../dataqa350/i30_2DTMF_16kHz_long.pcm ../dataqa351/i30_2DTMF_16kHz_long.pcm
+diff ../dataqa350/i60_2DTMF_16kHz_long.pcm ../dataqa351/i60_2DTMF_16kHz_long.pcm
+diff ../dataqa350/i30_3DTMF_16kHz_long.pcm ../dataqa351/i30_3DTMF_16kHz_long.pcm
+diff ../dataqa350/i60_3DTMF_16kHz_long.pcm ../dataqa351/i60_3DTMF_16kHz_long.pcm
+diff ../dataqa350/i30_4DTMF_16kHz_long.pcm ../dataqa351/i30_4DTMF_16kHz_long.pcm
+diff ../dataqa350/i60_4DTMF_16kHz_long.pcm ../dataqa351/i60_4DTMF_16kHz_long.pcm
+diff ../dataqa350/i30_5DTMF_16kHz_long.pcm ../dataqa351/i30_5DTMF_16kHz_long.pcm
+diff ../dataqa350/i60_5DTMF_16kHz_long.pcm ../dataqa351/i60_5DTMF_16kHz_long.pcm
+diff ../dataqa350/i30_6DTMF_16kHz_long.pcm ../dataqa351/i30_6DTMF_16kHz_long.pcm
+diff ../dataqa350/i60_6DTMF_16kHz_long.pcm ../dataqa351/i60_6DTMF_16kHz_long.pcm
+diff ../dataqa350/a1DTMF_16kHz_long.pcm ../dataqa351/a1DTMF_16kHz_long.pcm
+diff ../dataqa350/a2DTMF_16kHz_long.pcm ../dataqa351/a2DTMF_16kHz_long.pcm
+diff ../dataqa350/a3DTMF_16kHz_long.pcm ../dataqa351/a3DTMF_16kHz_long.pcm
+diff ../dataqa350/i30_7DTMF_16kHz_short.pcm ../dataqa351/i30_7DTMF_16kHz_short.pcm
+diff ../dataqa350/i60_7DTMF_16kHz_short.pcm ../dataqa351/i60_7DTMF_16kHz_short.pcm
+diff ../dataqa350/i30_8DTMF_16kHz_short.pcm ../dataqa351/i30_8DTMF_16kHz_short.pcm
+diff ../dataqa350/i60_8DTMF_16kHz_short.pcm ../dataqa351/i60_8DTMF_16kHz_short.pcm
+diff ../dataqa350/i30_9DTMF_16kHz_short.pcm ../dataqa351/i30_9DTMF_16kHz_short.pcm
+diff ../dataqa350/i60_9DTMF_16kHz_short.pcm ../dataqa351/i60_9DTMF_16kHz_short.pcm
+diff ../dataqa350/i30_10DTMF_16kHz_short.pcm ../dataqa351/i30_10DTMF_16kHz_short.pcm
+diff ../dataqa350/i60_10DTMF_16kHz_short.pcm ../dataqa351/i60_10DTMF_16kHz_short.pcm
+diff ../dataqa350/i30_11DTMF_16kHz_short.pcm ../dataqa351/i30_11DTMF_16kHz_short.pcm
+diff ../dataqa350/i60_11DTMF_16kHz_short.pcm ../dataqa351/i60_11DTMF_16kHz_short.pcm
+diff ../dataqa350/i30_12DTMF_16kHz_short.pcm ../dataqa351/i30_12DTMF_16kHz_short.pcm
+diff ../dataqa350/i60_12DTMF_16kHz_short.pcm ../dataqa351/i60_12DTMF_16kHz_short.pcm
+diff ../dataqa350/a4DTMF_16kHz_short.pcm ../dataqa351/a4DTMF_16kHz_short.pcm
+diff ../dataqa350/a5DTMF_16kHz_short.pcm ../dataqa351/a5DTMF_16kHz_short.pcm
+diff ../dataqa350/a6DTMF_16kHz_short.pcm ../dataqa351/a6DTMF_16kHz_short.pcm
+diff ../dataqa350/i30_13F00.INP ../dataqa350/i30_13F00.INP
+diff ../dataqa350/i60_13F00.INP ../dataqa350/i60_13F00.INP
+diff ../dataqa350/i30_14F00.INP ../dataqa350/i30_14F00.INP
+diff ../dataqa350/i60_14F00.INP ../dataqa350/i60_14F00.INP
+diff ../dataqa350/i30_15F00.INP ../dataqa350/i30_15F00.INP
+diff ../dataqa350/i60_15F00.INP ../dataqa350/i60_15F00.INP
+diff ../dataqa350/i30_16F00.INP ../dataqa350/i30_16F00.INP
+diff ../dataqa350/i60_16F00.INP ../dataqa350/i60_16F00.INP
+diff ../dataqa350/i30_17F00.INP ../dataqa350/i30_17F00.INP
+diff ../dataqa350/i60_17F00.INP ../dataqa350/i60_17F00.INP
+diff ../dataqa350/i30_18F00.INP ../dataqa350/i30_18F00.INP
+diff ../dataqa350/i60_18F00.INP ../dataqa350/i60_18F00.INP
+diff ../dataqa350/a7F00.INP ../dataqa350/a7F00.INP
+diff ../dataqa350/a8F00.INP ../dataqa350/a8F00.INP
+diff ../dataqa350/a9F00.INP ../dataqa350/a9F00.INP
+diff ../dataqa350/i30_19F01.INP ../dataqa350/i30_19F01.INP
+diff ../dataqa350/i60_19F01.INP ../dataqa350/i60_19F01.INP
+diff ../dataqa350/i30_20F01.INP ../dataqa350/i30_20F01.INP
+diff ../dataqa350/i60_20F01.INP ../dataqa350/i60_20F01.INP
+diff ../dataqa350/i30_21F01.INP ../dataqa350/i30_21F01.INP
+diff ../dataqa350/i60_21F01.INP ../dataqa350/i60_21F01.INP
+diff ../dataqa350/i30_22F01.INP ../dataqa350/i30_22F01.INP
+diff ../dataqa350/i60_22F01.INP ../dataqa350/i60_22F01.INP
+diff ../dataqa350/i30_23F01.INP ../dataqa350/i30_23F01.INP
+diff ../dataqa350/i60_23F01.INP ../dataqa350/i60_23F01.INP
+diff ../dataqa350/i30_24F01.INP ../dataqa350/i30_24F01.INP
+diff ../dataqa350/i60_24F01.INP ../dataqa350/i60_24F01.INP
+diff ../dataqa350/a10F01.INP ../dataqa350/a10F01.INP
+diff ../dataqa350/a11F01.INP ../dataqa350/a11F01.INP
+diff ../dataqa350/a12F01.INP ../dataqa350/a12F01.INP
+diff ../dataqa350/i30_25F02.INP ../dataqa350/i30_25F02.INP
+diff ../dataqa350/i60_25F02.INP ../dataqa350/i60_25F02.INP
+diff ../dataqa350/i30_26F02.INP ../dataqa350/i30_26F02.INP
+diff ../dataqa350/i60_26F02.INP ../dataqa350/i60_26F02.INP
+diff ../dataqa350/i30_27F02.INP ../dataqa350/i30_27F02.INP
+diff ../dataqa350/i60_27F02.INP ../dataqa350/i60_27F02.INP
+diff ../dataqa350/i30_28F02.INP ../dataqa350/i30_28F02.INP
+diff ../dataqa350/i60_28F02.INP ../dataqa350/i60_28F02.INP
+diff ../dataqa350/i30_29F02.INP ../dataqa350/i30_29F02.INP
+diff ../dataqa350/i60_29F02.INP ../dataqa350/i60_29F02.INP
+diff ../dataqa350/i30_30F02.INP ../dataqa350/i30_30F02.INP
+diff ../dataqa350/i60_30F02.INP ../dataqa350/i60_30F02.INP
+diff ../dataqa350/a13F02.INP ../dataqa350/a13F02.INP
+diff ../dataqa350/a14F02.INP ../dataqa350/a14F02.INP
+diff ../dataqa350/a15F02.INP ../dataqa350/a15F02.INP
+diff ../dataqa350/i30_31F03.INP ../dataqa350/i30_31F03.INP
+diff ../dataqa350/i60_31F03.INP ../dataqa350/i60_31F03.INP
+diff ../dataqa350/i30_32F03.INP ../dataqa350/i30_32F03.INP
+diff ../dataqa350/i60_32F03.INP ../dataqa350/i60_32F03.INP
+diff ../dataqa350/i30_33F03.INP ../dataqa350/i30_33F03.INP
+diff ../dataqa350/i60_33F03.INP ../dataqa350/i60_33F03.INP
+diff ../dataqa350/i30_34F03.INP ../dataqa350/i30_34F03.INP
+diff ../dataqa350/i60_34F03.INP ../dataqa350/i60_34F03.INP
+diff ../dataqa350/i30_35F03.INP ../dataqa350/i30_35F03.INP
+diff ../dataqa350/i60_35F03.INP ../dataqa350/i60_35F03.INP
+diff ../dataqa350/i30_36F03.INP ../dataqa350/i30_36F03.INP
+diff ../dataqa350/i60_36F03.INP ../dataqa350/i60_36F03.INP
+diff ../dataqa350/a16F03.INP ../dataqa350/a16F03.INP
+diff ../dataqa350/a17F03.INP ../dataqa350/a17F03.INP
+diff ../dataqa350/a18F03.INP ../dataqa350/a18F03.INP
+diff ../dataqa350/i30_37F04.INP ../dataqa350/i30_37F04.INP
+diff ../dataqa350/i60_37F04.INP ../dataqa350/i60_37F04.INP
+diff ../dataqa350/i30_38F04.INP ../dataqa350/i30_38F04.INP
+diff ../dataqa350/i60_38F04.INP ../dataqa350/i60_38F04.INP
+diff ../dataqa350/i30_39F04.INP ../dataqa350/i30_39F04.INP
+diff ../dataqa350/i60_39F04.INP ../dataqa350/i60_39F04.INP
+diff ../dataqa350/i30_40F04.INP ../dataqa350/i30_40F04.INP
+diff ../dataqa350/i60_40F04.INP ../dataqa350/i60_40F04.INP
+diff ../dataqa350/i30_41F04.INP ../dataqa350/i30_41F04.INP
+diff ../dataqa350/i60_41F04.INP ../dataqa350/i60_41F04.INP
+diff ../dataqa350/i30_42F04.INP ../dataqa350/i30_42F04.INP
+diff ../dataqa350/i60_42F04.INP ../dataqa350/i60_42F04.INP
+diff ../dataqa350/a19F04.INP ../dataqa350/a19F04.INP
+diff ../dataqa350/a20F04.INP ../dataqa350/a20F04.INP
+diff ../dataqa350/a21F04.INP ../dataqa350/a21F04.INP
+diff ../dataqa350/i30_43F05.INP ../dataqa350/i30_43F05.INP
+diff ../dataqa350/i60_43F05.INP ../dataqa350/i60_43F05.INP
+diff ../dataqa350/i30_44F05.INP ../dataqa350/i30_44F05.INP
+diff ../dataqa350/i60_44F05.INP ../dataqa350/i60_44F05.INP
+diff ../dataqa350/i30_45F05.INP ../dataqa350/i30_45F05.INP
+diff ../dataqa350/i60_45F05.INP ../dataqa350/i60_45F05.INP
+diff ../dataqa350/i30_46F05.INP ../dataqa350/i30_46F05.INP
+diff ../dataqa350/i60_46F05.INP ../dataqa350/i60_46F05.INP
+diff ../dataqa350/i30_47F05.INP ../dataqa350/i30_47F05.INP
+diff ../dataqa350/i60_47F05.INP ../dataqa350/i60_47F05.INP
+diff ../dataqa350/i30_48F05.INP ../dataqa350/i30_48F05.INP
+diff ../dataqa350/i60_48F05.INP ../dataqa350/i60_48F05.INP
+diff ../dataqa350/a22F05.INP ../dataqa350/a22F05.INP
+diff ../dataqa350/a23F05.INP ../dataqa350/a23F05.INP
+diff ../dataqa350/a24F05.INP ../dataqa350/a24F05.INP
+diff ../dataqa350/i30_49F06.INP ../dataqa350/i30_49F06.INP
+diff ../dataqa350/i60_49F06.INP ../dataqa350/i60_49F06.INP
+diff ../dataqa350/i30_50F06.INP ../dataqa350/i30_50F06.INP
+diff ../dataqa350/i60_50F06.INP ../dataqa350/i60_50F06.INP
+diff ../dataqa350/i30_51F06.INP ../dataqa350/i30_51F06.INP
+diff ../dataqa350/i60_51F06.INP ../dataqa350/i60_51F06.INP
+diff ../dataqa350/i30_52F06.INP ../dataqa350/i30_52F06.INP
+diff ../dataqa350/i60_52F06.INP ../dataqa350/i60_52F06.INP
+diff ../dataqa350/i30_53F06.INP ../dataqa350/i30_53F06.INP
+diff ../dataqa350/i60_53F06.INP ../dataqa350/i60_53F06.INP
+diff ../dataqa350/i30_54F06.INP ../dataqa350/i30_54F06.INP
+diff ../dataqa350/i60_54F06.INP ../dataqa350/i60_54F06.INP
+diff ../dataqa350/a25F06.INP ../dataqa350/a25F06.INP
+diff ../dataqa350/a26F06.INP ../dataqa350/a26F06.INP
+diff ../dataqa350/a27F06.INP ../dataqa350/a27F06.INP
+diff ../dataqa350/i30_55longtest.pcm ../dataqa351/i30_55longtest.pcm
+diff ../dataqa350/i60_55longtest.pcm ../dataqa351/i60_55longtest.pcm
+diff ../dataqa350/i30_56longtest.pcm ../dataqa351/i30_56longtest.pcm
+diff ../dataqa350/i60_56longtest.pcm ../dataqa351/i60_56longtest.pcm
+diff ../dataqa350/i30_57longtest.pcm ../dataqa351/i30_57longtest.pcm
+diff ../dataqa350/i60_57longtest.pcm ../dataqa351/i60_57longtest.pcm
+diff ../dataqa350/i30_58longtest.pcm ../dataqa351/i30_58longtest.pcm
+diff ../dataqa350/i60_58longtest.pcm ../dataqa351/i60_58longtest.pcm
+diff ../dataqa350/i30_59longtest.pcm ../dataqa351/i30_59longtest.pcm
+diff ../dataqa350/i60_59longtest.pcm ../dataqa351/i60_59longtest.pcm
+diff ../dataqa350/i30_60longtest.pcm ../dataqa351/i30_60longtest.pcm
+diff ../dataqa350/i60_60longtest.pcm ../dataqa351/i60_60longtest.pcm
+diff ../dataqa350/a28longtest.pcm ../dataqa351/a28longtest.pcm
+diff ../dataqa350/a29longtest.pcm ../dataqa351/a29longtest.pcm
+diff ../dataqa350/a30longtest.pcm ../dataqa351/a30longtest.pcm
+diff ../dataqa350/i30_61ltest_speech_clean.pcm ../dataqa351/i30_61ltest_speech_clean.pcm
+diff ../dataqa350/i60_61ltest_speech_clean.pcm ../dataqa351/i60_61ltest_speech_clean.pcm
+diff ../dataqa350/i30_62ltest_speech_clean.pcm ../dataqa351/i30_62ltest_speech_clean.pcm
+diff ../dataqa350/i60_62ltest_speech_clean.pcm ../dataqa351/i60_62ltest_speech_clean.pcm
+diff ../dataqa350/i30_63ltest_speech_clean.pcm ../dataqa351/i30_63ltest_speech_clean.pcm
+diff ../dataqa350/i60_63ltest_speech_clean.pcm ../dataqa351/i60_63ltest_speech_clean.pcm
+diff ../dataqa350/i30_64ltest_speech_clean.pcm ../dataqa351/i30_64ltest_speech_clean.pcm
+diff ../dataqa350/i60_64ltest_speech_clean.pcm ../dataqa351/i60_64ltest_speech_clean.pcm
+diff ../dataqa350/i30_65ltest_speech_clean.pcm ../dataqa351/i30_65ltest_speech_clean.pcm
+diff ../dataqa350/i60_65ltest_speech_clean.pcm ../dataqa351/i60_65ltest_speech_clean.pcm
+diff ../dataqa350/i30_66ltest_speech_clean.pcm ../dataqa351/i30_66ltest_speech_clean.pcm
+diff ../dataqa350/i60_66ltest_speech_clean.pcm ../dataqa351/i60_66ltest_speech_clean.pcm
+diff ../dataqa350/a31ltest_speech_clean.pcm ../dataqa351/a31ltest_speech_clean.pcm
+diff ../dataqa350/a32ltest_speech_clean.pcm ../dataqa351/a32ltest_speech_clean.pcm
+diff ../dataqa350/a33ltest_speech_clean.pcm ../dataqa351/a33ltest_speech_clean.pcm
+diff ../dataqa350/i30_67ltest_music.pcm ../dataqa351/i30_67ltest_music.pcm
+diff ../dataqa350/i60_67ltest_music.pcm ../dataqa351/i60_67ltest_music.pcm
+diff ../dataqa350/i30_68ltest_music.pcm ../dataqa351/i30_68ltest_music.pcm
+diff ../dataqa350/i60_68ltest_music.pcm ../dataqa351/i60_68ltest_music.pcm
+diff ../dataqa350/i30_69ltest_music.pcm ../dataqa351/i30_69ltest_music.pcm
+diff ../dataqa350/i60_69ltest_music.pcm ../dataqa351/i60_69ltest_music.pcm
+diff ../dataqa350/i30_70ltest_music.pcm ../dataqa351/i30_70ltest_music.pcm
+diff ../dataqa350/i60_70ltest_music.pcm ../dataqa351/i60_70ltest_music.pcm
+diff ../dataqa350/i30_71ltest_music.pcm ../dataqa351/i30_71ltest_music.pcm
+diff ../dataqa350/i60_71ltest_music.pcm ../dataqa351/i60_71ltest_music.pcm
+diff ../dataqa350/i30_72ltest_music.pcm ../dataqa351/i30_72ltest_music.pcm
+diff ../dataqa350/i60_72ltest_music.pcm ../dataqa351/i60_72ltest_music.pcm
+diff ../dataqa350/a34ltest_music.pcm ../dataqa351/a34ltest_music.pcm
+diff ../dataqa350/a35ltest_music.pcm ../dataqa351/a35ltest_music.pcm
+diff ../dataqa350/a36ltest_music.pcm ../dataqa351/a36ltest_music.pcm
+diff ../dataqa350/i30_73ltest_speech_noisy.pcm ../dataqa351/i30_73ltest_speech_noisy.pcm
+diff ../dataqa350/i60_73ltest_speech_noisy.pcm ../dataqa351/i60_73ltest_speech_noisy.pcm
+diff ../dataqa350/i30_74ltest_speech_noisy.pcm ../dataqa351/i30_74ltest_speech_noisy.pcm
+diff ../dataqa350/i60_74ltest_speech_noisy.pcm ../dataqa351/i60_74ltest_speech_noisy.pcm
+diff ../dataqa350/i30_75ltest_speech_noisy.pcm ../dataqa351/i30_75ltest_speech_noisy.pcm
+diff ../dataqa350/i60_75ltest_speech_noisy.pcm ../dataqa351/i60_75ltest_speech_noisy.pcm
+diff ../dataqa350/i30_76ltest_speech_noisy.pcm ../dataqa351/i30_76ltest_speech_noisy.pcm
+diff ../dataqa350/i60_76ltest_speech_noisy.pcm ../dataqa351/i60_76ltest_speech_noisy.pcm
+diff ../dataqa350/i30_77ltest_speech_noisy.pcm ../dataqa351/i30_77ltest_speech_noisy.pcm
+diff ../dataqa350/i60_77ltest_speech_noisy.pcm ../dataqa351/i60_77ltest_speech_noisy.pcm
+diff ../dataqa350/i30_78ltest_speech_noisy.pcm ../dataqa351/i30_78ltest_speech_noisy.pcm
+diff ../dataqa350/i60_78ltest_speech_noisy.pcm ../dataqa351/i60_78ltest_speech_noisy.pcm
+diff ../dataqa350/a37ltest_speech_noisy.pcm ../dataqa351/a37ltest_speech_noisy.pcm
+diff ../dataqa350/a38ltest_speech_noisy.pcm ../dataqa351/a38ltest_speech_noisy.pcm
+diff ../dataqa350/a39ltest_speech_noisy.pcm ../dataqa351/a39ltest_speech_noisy.pcm
+diff ../dataqa350/i30_79misc2.pcm ../dataqa351/i30_79misc2.pcm
+diff ../dataqa350/i60_79misc2.pcm ../dataqa351/i60_79misc2.pcm
+diff ../dataqa350/i30_80misc2.pcm ../dataqa351/i30_80misc2.pcm
+diff ../dataqa350/i60_80misc2.pcm ../dataqa351/i60_80misc2.pcm
+diff ../dataqa350/i30_81misc2.pcm ../dataqa351/i30_81misc2.pcm
+diff ../dataqa350/i60_81misc2.pcm ../dataqa351/i60_81misc2.pcm
+diff ../dataqa350/i30_82misc2.pcm ../dataqa351/i30_82misc2.pcm
+diff ../dataqa350/i60_82misc2.pcm ../dataqa351/i60_82misc2.pcm
+diff ../dataqa350/i30_83misc2.pcm ../dataqa351/i30_83misc2.pcm
+diff ../dataqa350/i60_83misc2.pcm ../dataqa351/i60_83misc2.pcm
+diff ../dataqa350/i30_84misc2.pcm ../dataqa351/i30_84misc2.pcm
+diff ../dataqa350/i60_84misc2.pcm ../dataqa351/i60_84misc2.pcm
+diff ../dataqa350/a40misc2.pcm ../dataqa351/a40misc2.pcm
+diff ../dataqa350/a41misc2.pcm ../dataqa351/a41misc2.pcm
+diff ../dataqa350/a42misc2.pcm ../dataqa351/a42misc2.pcm
+diff ../dataqa350/i30_85purenb.pcm ../dataqa351/i30_85purenb.pcm
+diff ../dataqa350/i60_85purenb.pcm ../dataqa351/i60_85purenb.pcm
+diff ../dataqa350/i30_86purenb.pcm ../dataqa351/i30_86purenb.pcm
+diff ../dataqa350/i60_86purenb.pcm ../dataqa351/i60_86purenb.pcm
+diff ../dataqa350/i30_87purenb.pcm ../dataqa351/i30_87purenb.pcm
+diff ../dataqa350/i60_87purenb.pcm ../dataqa351/i60_87purenb.pcm
+diff ../dataqa350/i30_88purenb.pcm ../dataqa351/i30_88purenb.pcm
+diff ../dataqa350/i60_88purenb.pcm ../dataqa351/i60_88purenb.pcm
+diff ../dataqa350/i30_89purenb.pcm ../dataqa351/i30_89purenb.pcm
+diff ../dataqa350/i60_89purenb.pcm ../dataqa351/i60_89purenb.pcm
+diff ../dataqa350/i30_90purenb.pcm ../dataqa351/i30_90purenb.pcm
+diff ../dataqa350/i60_90purenb.pcm ../dataqa351/i60_90purenb.pcm
+diff ../dataqa350/a43purenb.pcm ../dataqa351/a43purenb.pcm
+diff ../dataqa350/a44purenb.pcm ../dataqa351/a44purenb.pcm
+diff ../dataqa350/a45purenb.pcm ../dataqa351/a45purenb.pcm
+diff ../dataqa350/i30_91sawsweep_380_60.pcm ../dataqa351/i30_91sawsweep_380_60.pcm
+diff ../dataqa350/i60_91sawsweep_380_60.pcm ../dataqa351/i60_91sawsweep_380_60.pcm
+diff ../dataqa350/i30_92sawsweep_380_60.pcm ../dataqa351/i30_92sawsweep_380_60.pcm
+diff ../dataqa350/i60_92sawsweep_380_60.pcm ../dataqa351/i60_92sawsweep_380_60.pcm
+diff ../dataqa350/i30_93sawsweep_380_60.pcm ../dataqa351/i30_93sawsweep_380_60.pcm
+diff ../dataqa350/i60_93sawsweep_380_60.pcm ../dataqa351/i60_93sawsweep_380_60.pcm
+diff ../dataqa350/i30_94sawsweep_380_60.pcm ../dataqa351/i30_94sawsweep_380_60.pcm
+diff ../dataqa350/i60_94sawsweep_380_60.pcm ../dataqa351/i60_94sawsweep_380_60.pcm
+diff ../dataqa350/i30_95sawsweep_380_60.pcm ../dataqa351/i30_95sawsweep_380_60.pcm
+diff ../dataqa350/i60_95sawsweep_380_60.pcm ../dataqa351/i60_95sawsweep_380_60.pcm
+diff ../dataqa350/i30_96sawsweep_380_60.pcm ../dataqa351/i30_96sawsweep_380_60.pcm
+diff ../dataqa350/i60_96sawsweep_380_60.pcm ../dataqa351/i60_96sawsweep_380_60.pcm
+diff ../dataqa350/a46sawsweep_380_60.pcm ../dataqa351/a46sawsweep_380_60.pcm
+diff ../dataqa350/a47sawsweep_380_60.pcm ../dataqa351/a47sawsweep_380_60.pcm
+diff ../dataqa350/a48sawsweep_380_60.pcm ../dataqa351/a48sawsweep_380_60.pcm
+diff ../dataqa350/i30_97sinesweep.pcm ../dataqa351/i30_97sinesweep.pcm
+diff ../dataqa350/i60_97sinesweep.pcm ../dataqa351/i60_97sinesweep.pcm
+diff ../dataqa350/i30_98sinesweep.pcm ../dataqa351/i30_98sinesweep.pcm
+diff ../dataqa350/i60_98sinesweep.pcm ../dataqa351/i60_98sinesweep.pcm
+diff ../dataqa350/i30_99sinesweep.pcm ../dataqa351/i30_99sinesweep.pcm
+diff ../dataqa350/i60_99sinesweep.pcm ../dataqa351/i60_99sinesweep.pcm
+diff ../dataqa350/i30_100sinesweep.pcm ../dataqa351/i30_100sinesweep.pcm
+diff ../dataqa350/i60_100sinesweep.pcm ../dataqa351/i60_100sinesweep.pcm
+diff ../dataqa350/i30_101sinesweep.pcm ../dataqa351/i30_101sinesweep.pcm
+diff ../dataqa350/i60_101sinesweep.pcm ../dataqa351/i60_101sinesweep.pcm
+diff ../dataqa350/i30_102sinesweep.pcm ../dataqa351/i30_102sinesweep.pcm
+diff ../dataqa350/i60_102sinesweep.pcm ../dataqa351/i60_102sinesweep.pcm
+diff ../dataqa350/a49sinesweep.pcm ../dataqa351/a49sinesweep.pcm
+diff ../dataqa350/a50sinesweep.pcm ../dataqa351/a50sinesweep.pcm
+diff ../dataqa350/a51sinesweep.pcm ../dataqa351/a51sinesweep.pcm
+diff ../dataqa350/i30_103sinesweep_half.pcm ../dataqa351/i30_103sinesweep_half.pcm
+diff ../dataqa350/i60_103sinesweep_half.pcm ../dataqa351/i60_103sinesweep_half.pcm
+diff ../dataqa350/i30_104sinesweep_half.pcm ../dataqa351/i30_104sinesweep_half.pcm
+diff ../dataqa350/i60_104sinesweep_half.pcm ../dataqa351/i60_104sinesweep_half.pcm
+diff ../dataqa350/i30_105sinesweep_half.pcm ../dataqa351/i30_105sinesweep_half.pcm
+diff ../dataqa350/i60_105sinesweep_half.pcm ../dataqa351/i60_105sinesweep_half.pcm
+diff ../dataqa350/i30_106sinesweep_half.pcm ../dataqa351/i30_106sinesweep_half.pcm
+diff ../dataqa350/i60_106sinesweep_half.pcm ../dataqa351/i60_106sinesweep_half.pcm
+diff ../dataqa350/i30_107sinesweep_half.pcm ../dataqa351/i30_107sinesweep_half.pcm
+diff ../dataqa350/i60_107sinesweep_half.pcm ../dataqa351/i60_107sinesweep_half.pcm
+diff ../dataqa350/i30_108sinesweep_half.pcm ../dataqa351/i30_108sinesweep_half.pcm
+diff ../dataqa350/i60_108sinesweep_half.pcm ../dataqa351/i60_108sinesweep_half.pcm
+diff ../dataqa350/a52sinesweep_half.pcm ../dataqa351/a52sinesweep_half.pcm
+diff ../dataqa350/a53sinesweep_half.pcm ../dataqa351/a53sinesweep_half.pcm
+diff ../dataqa350/a54sinesweep_half.pcm ../dataqa351/a54sinesweep_half.pcm
+diff ../dataqa350/i30_109speechmusic.pcm ../dataqa351/i30_109speechmusic.pcm
+diff ../dataqa350/i60_109speechmusic.pcm ../dataqa351/i60_109speechmusic.pcm
+diff ../dataqa350/i30_110speechmusic.pcm ../dataqa351/i30_110speechmusic.pcm
+diff ../dataqa350/i60_110speechmusic.pcm ../dataqa351/i60_110speechmusic.pcm
+diff ../dataqa350/i30_111speechmusic.pcm ../dataqa351/i30_111speechmusic.pcm
+diff ../dataqa350/i60_111speechmusic.pcm ../dataqa351/i60_111speechmusic.pcm
+diff ../dataqa350/i30_112speechmusic.pcm ../dataqa351/i30_112speechmusic.pcm
+diff ../dataqa350/i60_112speechmusic.pcm ../dataqa351/i60_112speechmusic.pcm
+diff ../dataqa350/i30_113speechmusic.pcm ../dataqa351/i30_113speechmusic.pcm
+diff ../dataqa350/i60_113speechmusic.pcm ../dataqa351/i60_113speechmusic.pcm
+diff ../dataqa350/i30_114speechmusic.pcm ../dataqa351/i30_114speechmusic.pcm
+diff ../dataqa350/i60_114speechmusic.pcm ../dataqa351/i60_114speechmusic.pcm
+diff ../dataqa350/a55speechmusic.pcm ../dataqa351/a55speechmusic.pcm
+diff ../dataqa350/a56speechmusic.pcm ../dataqa351/a56speechmusic.pcm
+diff ../dataqa350/a57speechmusic.pcm ../dataqa351/a57speechmusic.pcm
+diff ../dataqa350/i30_115speechmusic_nb.pcm ../dataqa351/i30_115speechmusic_nb.pcm
+diff ../dataqa350/i60_115speechmusic_nb.pcm ../dataqa351/i60_115speechmusic_nb.pcm
+diff ../dataqa350/i30_116speechmusic_nb.pcm ../dataqa351/i30_116speechmusic_nb.pcm
+diff ../dataqa350/i60_116speechmusic_nb.pcm ../dataqa351/i60_116speechmusic_nb.pcm
+diff ../dataqa350/i30_117speechmusic_nb.pcm ../dataqa351/i30_117speechmusic_nb.pcm
+diff ../dataqa350/i60_117speechmusic_nb.pcm ../dataqa351/i60_117speechmusic_nb.pcm
+diff ../dataqa350/i30_118speechmusic_nb.pcm ../dataqa351/i30_118speechmusic_nb.pcm
+diff ../dataqa350/i60_118speechmusic_nb.pcm ../dataqa351/i60_118speechmusic_nb.pcm
+diff ../dataqa350/i30_119speechmusic_nb.pcm ../dataqa351/i30_119speechmusic_nb.pcm
+diff ../dataqa350/i60_119speechmusic_nb.pcm ../dataqa351/i60_119speechmusic_nb.pcm
+diff ../dataqa350/i30_120speechmusic_nb.pcm ../dataqa351/i30_120speechmusic_nb.pcm
+diff ../dataqa350/i60_120speechmusic_nb.pcm ../dataqa351/i60_120speechmusic_nb.pcm
+diff ../dataqa350/a58speechmusic_nb.pcm ../dataqa351/a58speechmusic_nb.pcm
+diff ../dataqa350/a59speechmusic_nb.pcm ../dataqa351/a59speechmusic_nb.pcm
+diff ../dataqa350/a60speechmusic_nb.pcm ../dataqa351/a60speechmusic_nb.pcm
+diff ../dataqa350/i30_121speechoffice0dB.pcm ../dataqa351/i30_121speechoffice0dB.pcm
+diff ../dataqa350/i60_121speechoffice0dB.pcm ../dataqa351/i60_121speechoffice0dB.pcm
+diff ../dataqa350/i30_122speechoffice0dB.pcm ../dataqa351/i30_122speechoffice0dB.pcm
+diff ../dataqa350/i60_122speechoffice0dB.pcm ../dataqa351/i60_122speechoffice0dB.pcm
+diff ../dataqa350/i30_123speechoffice0dB.pcm ../dataqa351/i30_123speechoffice0dB.pcm
+diff ../dataqa350/i60_123speechoffice0dB.pcm ../dataqa351/i60_123speechoffice0dB.pcm
+diff ../dataqa350/i30_124speechoffice0dB.pcm ../dataqa351/i30_124speechoffice0dB.pcm
+diff ../dataqa350/i60_124speechoffice0dB.pcm ../dataqa351/i60_124speechoffice0dB.pcm
+diff ../dataqa350/i30_125speechoffice0dB.pcm ../dataqa351/i30_125speechoffice0dB.pcm
+diff ../dataqa350/i60_125speechoffice0dB.pcm ../dataqa351/i60_125speechoffice0dB.pcm
+diff ../dataqa350/i30_126speechoffice0dB.pcm ../dataqa351/i30_126speechoffice0dB.pcm
+diff ../dataqa350/i60_126speechoffice0dB.pcm ../dataqa351/i60_126speechoffice0dB.pcm
+diff ../dataqa350/a61speechoffice0dB.pcm ../dataqa351/a61speechoffice0dB.pcm
+diff ../dataqa350/a62speechoffice0dB.pcm ../dataqa351/a62speechoffice0dB.pcm
+diff ../dataqa350/a63speechoffice0dB.pcm ../dataqa351/a63speechoffice0dB.pcm
+diff ../dataqa350/i30_127speech_and_misc_NB.pcm ../dataqa351/i30_127speech_and_misc_NB.pcm
+diff ../dataqa350/i60_127speech_and_misc_NB.pcm ../dataqa351/i60_127speech_and_misc_NB.pcm
+diff ../dataqa350/i30_128speech_and_misc_NB.pcm ../dataqa351/i30_128speech_and_misc_NB.pcm
+diff ../dataqa350/i60_128speech_and_misc_NB.pcm ../dataqa351/i60_128speech_and_misc_NB.pcm
+diff ../dataqa350/i30_129speech_and_misc_NB.pcm ../dataqa351/i30_129speech_and_misc_NB.pcm
+diff ../dataqa350/i60_129speech_and_misc_NB.pcm ../dataqa351/i60_129speech_and_misc_NB.pcm
+diff ../dataqa350/i30_130speech_and_misc_NB.pcm ../dataqa351/i30_130speech_and_misc_NB.pcm
+diff ../dataqa350/i60_130speech_and_misc_NB.pcm ../dataqa351/i60_130speech_and_misc_NB.pcm
+diff ../dataqa350/i30_131speech_and_misc_NB.pcm ../dataqa351/i30_131speech_and_misc_NB.pcm
+diff ../dataqa350/i60_131speech_and_misc_NB.pcm ../dataqa351/i60_131speech_and_misc_NB.pcm
+diff ../dataqa350/i30_132speech_and_misc_NB.pcm ../dataqa351/i30_132speech_and_misc_NB.pcm
+diff ../dataqa350/i60_132speech_and_misc_NB.pcm ../dataqa351/i60_132speech_and_misc_NB.pcm
+diff ../dataqa350/a64speech_and_misc_NB.pcm ../dataqa351/a64speech_and_misc_NB.pcm
+diff ../dataqa350/a65speech_and_misc_NB.pcm ../dataqa351/a65speech_and_misc_NB.pcm
+diff ../dataqa350/a66speech_and_misc_NB.pcm ../dataqa351/a66speech_and_misc_NB.pcm
+diff ../dataqa350/i30_133speech_and_misc_WB.pcm ../dataqa351/i30_133speech_and_misc_WB.pcm
+diff ../dataqa350/i60_133speech_and_misc_WB.pcm ../dataqa351/i60_133speech_and_misc_WB.pcm
+diff ../dataqa350/i30_134speech_and_misc_WB.pcm ../dataqa351/i30_134speech_and_misc_WB.pcm
+diff ../dataqa350/i60_134speech_and_misc_WB.pcm ../dataqa351/i60_134speech_and_misc_WB.pcm
+diff ../dataqa350/i30_135speech_and_misc_WB.pcm ../dataqa351/i30_135speech_and_misc_WB.pcm
+diff ../dataqa350/i60_135speech_and_misc_WB.pcm ../dataqa351/i60_135speech_and_misc_WB.pcm
+diff ../dataqa350/i30_136speech_and_misc_WB.pcm ../dataqa351/i30_136speech_and_misc_WB.pcm
+diff ../dataqa350/i60_136speech_and_misc_WB.pcm ../dataqa351/i60_136speech_and_misc_WB.pcm
+diff ../dataqa350/i30_137speech_and_misc_WB.pcm ../dataqa351/i30_137speech_and_misc_WB.pcm
+diff ../dataqa350/i60_137speech_and_misc_WB.pcm ../dataqa351/i60_137speech_and_misc_WB.pcm
+diff ../dataqa350/i30_138speech_and_misc_WB.pcm ../dataqa351/i30_138speech_and_misc_WB.pcm
+diff ../dataqa350/i60_138speech_and_misc_WB.pcm ../dataqa351/i60_138speech_and_misc_WB.pcm
+diff ../dataqa350/a67speech_and_misc_WB.pcm ../dataqa351/a67speech_and_misc_WB.pcm
+diff ../dataqa350/a68speech_and_misc_WB.pcm ../dataqa351/a68speech_and_misc_WB.pcm
+diff ../dataqa350/a69speech_and_misc_WB.pcm ../dataqa351/a69speech_and_misc_WB.pcm
+diff ../dataqa350/i30_139testM4.pcm ../dataqa351/i30_139testM4.pcm
+diff ../dataqa350/i60_139testM4.pcm ../dataqa351/i60_139testM4.pcm
+diff ../dataqa350/i30_140testM4.pcm ../dataqa351/i30_140testM4.pcm
+diff ../dataqa350/i60_140testM4.pcm ../dataqa351/i60_140testM4.pcm
+diff ../dataqa350/i30_141testM4.pcm ../dataqa351/i30_141testM4.pcm
+diff ../dataqa350/i60_141testM4.pcm ../dataqa351/i60_141testM4.pcm
+diff ../dataqa350/i30_142testM4.pcm ../dataqa351/i30_142testM4.pcm
+diff ../dataqa350/i60_142testM4.pcm ../dataqa351/i60_142testM4.pcm
+diff ../dataqa350/i30_143testM4.pcm ../dataqa351/i30_143testM4.pcm
+diff ../dataqa350/i60_143testM4.pcm ../dataqa351/i60_143testM4.pcm
+diff ../dataqa350/i30_144testM4.pcm ../dataqa351/i30_144testM4.pcm
+diff ../dataqa350/i60_144testM4.pcm ../dataqa351/i60_144testM4.pcm
+diff ../dataqa350/a70testM4.pcm ../dataqa351/a70testM4.pcm
+diff ../dataqa350/a71testM4.pcm ../dataqa351/a71testM4.pcm
+diff ../dataqa350/a72testM4.pcm ../dataqa351/a72testM4.pcm
+diff ../dataqa350/i30_145testM4D_rev.pcm ../dataqa351/i30_145testM4D_rev.pcm
+diff ../dataqa350/i60_145testM4D_rev.pcm ../dataqa351/i60_145testM4D_rev.pcm
+diff ../dataqa350/i30_146testM4D_rev.pcm ../dataqa351/i30_146testM4D_rev.pcm
+diff ../dataqa350/i60_146testM4D_rev.pcm ../dataqa351/i60_146testM4D_rev.pcm
+diff ../dataqa350/i30_147testM4D_rev.pcm ../dataqa351/i30_147testM4D_rev.pcm
+diff ../dataqa350/i60_147testM4D_rev.pcm ../dataqa351/i60_147testM4D_rev.pcm
+diff ../dataqa350/i30_148testM4D_rev.pcm ../dataqa351/i30_148testM4D_rev.pcm
+diff ../dataqa350/i60_148testM4D_rev.pcm ../dataqa351/i60_148testM4D_rev.pcm
+diff ../dataqa350/i30_149testM4D_rev.pcm ../dataqa351/i30_149testM4D_rev.pcm
+diff ../dataqa350/i60_149testM4D_rev.pcm ../dataqa351/i60_149testM4D_rev.pcm
+diff ../dataqa350/i30_150testM4D_rev.pcm ../dataqa351/i30_150testM4D_rev.pcm
+diff ../dataqa350/i60_150testM4D_rev.pcm ../dataqa351/i60_150testM4D_rev.pcm
+diff ../dataqa350/a73testM4D_rev.pcm ../dataqa351/a73testM4D_rev.pcm
+diff ../dataqa350/a74testM4D_rev.pcm ../dataqa351/a74testM4D_rev.pcm
+diff ../dataqa350/a75testM4D_rev.pcm ../dataqa351/a75testM4D_rev.pcm
+diff ../dataqa350/i30_151testM4D.pcm ../dataqa351/i30_151testM4D.pcm
+diff ../dataqa350/i60_151testM4D.pcm ../dataqa351/i60_151testM4D.pcm
+diff ../dataqa350/i30_152testM4D.pcm ../dataqa351/i30_152testM4D.pcm
+diff ../dataqa350/i60_152testM4D.pcm ../dataqa351/i60_152testM4D.pcm
+diff ../dataqa350/i30_153testM4D.pcm ../dataqa351/i30_153testM4D.pcm
+diff ../dataqa350/i60_153testM4D.pcm ../dataqa351/i60_153testM4D.pcm
+diff ../dataqa350/i30_154testM4D.pcm ../dataqa351/i30_154testM4D.pcm
+diff ../dataqa350/i60_154testM4D.pcm ../dataqa351/i60_154testM4D.pcm
+diff ../dataqa350/i30_155testM4D.pcm ../dataqa351/i30_155testM4D.pcm
+diff ../dataqa350/i60_155testM4D.pcm ../dataqa351/i60_155testM4D.pcm
+diff ../dataqa350/i30_156testM4D.pcm ../dataqa351/i30_156testM4D.pcm
+diff ../dataqa350/i60_156testM4D.pcm ../dataqa351/i60_156testM4D.pcm
+diff ../dataqa350/a76testM4D.pcm ../dataqa351/a76testM4D.pcm
+diff ../dataqa350/a77testM4D.pcm ../dataqa351/a77testM4D.pcm
+diff ../dataqa350/a78testM4D.pcm ../dataqa351/a78testM4D.pcm
+diff ../dataqa350/i30_157testfile.pcm ../dataqa351/i30_157testfile.pcm
+diff ../dataqa350/i60_157testfile.pcm ../dataqa351/i60_157testfile.pcm
+diff ../dataqa350/i30_158testfile.pcm ../dataqa351/i30_158testfile.pcm
+diff ../dataqa350/i60_158testfile.pcm ../dataqa351/i60_158testfile.pcm
+diff ../dataqa350/i30_159testfile.pcm ../dataqa351/i30_159testfile.pcm
+diff ../dataqa350/i60_159testfile.pcm ../dataqa351/i60_159testfile.pcm
+diff ../dataqa350/i30_160testfile.pcm ../dataqa351/i30_160testfile.pcm
+diff ../dataqa350/i60_160testfile.pcm ../dataqa351/i60_160testfile.pcm
+diff ../dataqa350/i30_161testfile.pcm ../dataqa351/i30_161testfile.pcm
+diff ../dataqa350/i60_161testfile.pcm ../dataqa351/i60_161testfile.pcm
+diff ../dataqa350/i30_162testfile.pcm ../dataqa351/i30_162testfile.pcm
+diff ../dataqa350/i60_162testfile.pcm ../dataqa351/i60_162testfile.pcm
+diff ../dataqa350/a79testfile.pcm ../dataqa351/a79testfile.pcm
+diff ../dataqa350/a80testfile.pcm ../dataqa351/a80testfile.pcm
+diff ../dataqa350/a81testfile.pcm ../dataqa351/a81testfile.pcm
+diff ../dataqa350/i30_163tone_cisco.pcm ../dataqa351/i30_163tone_cisco.pcm
+diff ../dataqa350/i60_163tone_cisco.pcm ../dataqa351/i60_163tone_cisco.pcm
+diff ../dataqa350/i30_164tone_cisco.pcm ../dataqa351/i30_164tone_cisco.pcm
+diff ../dataqa350/i60_164tone_cisco.pcm ../dataqa351/i60_164tone_cisco.pcm
+diff ../dataqa350/i30_165tone_cisco.pcm ../dataqa351/i30_165tone_cisco.pcm
+diff ../dataqa350/i60_165tone_cisco.pcm ../dataqa351/i60_165tone_cisco.pcm
+diff ../dataqa350/i30_166tone_cisco.pcm ../dataqa351/i30_166tone_cisco.pcm
+diff ../dataqa350/i60_166tone_cisco.pcm ../dataqa351/i60_166tone_cisco.pcm
+diff ../dataqa350/i30_167tone_cisco.pcm ../dataqa351/i30_167tone_cisco.pcm
+diff ../dataqa350/i60_167tone_cisco.pcm ../dataqa351/i60_167tone_cisco.pcm
+diff ../dataqa350/i30_168tone_cisco.pcm ../dataqa351/i30_168tone_cisco.pcm
+diff ../dataqa350/i60_168tone_cisco.pcm ../dataqa351/i60_168tone_cisco.pcm
+diff ../dataqa350/a82tone_cisco.pcm ../dataqa351/a82tone_cisco.pcm
+diff ../dataqa350/a83tone_cisco.pcm ../dataqa351/a83tone_cisco.pcm
+diff ../dataqa350/a84tone_cisco.pcm ../dataqa351/a84tone_cisco.pcm
+diff ../dataqa350/i30_169tone_cisco_long.pcm ../dataqa351/i30_169tone_cisco_long.pcm
+diff ../dataqa350/i60_169tone_cisco_long.pcm ../dataqa351/i60_169tone_cisco_long.pcm
+diff ../dataqa350/i30_170tone_cisco_long.pcm ../dataqa351/i30_170tone_cisco_long.pcm
+diff ../dataqa350/i60_170tone_cisco_long.pcm ../dataqa351/i60_170tone_cisco_long.pcm
+diff ../dataqa350/i30_171tone_cisco_long.pcm ../dataqa351/i30_171tone_cisco_long.pcm
+diff ../dataqa350/i60_171tone_cisco_long.pcm ../dataqa351/i60_171tone_cisco_long.pcm
+diff ../dataqa350/i30_172tone_cisco_long.pcm ../dataqa351/i30_172tone_cisco_long.pcm
+diff ../dataqa350/i60_172tone_cisco_long.pcm ../dataqa351/i60_172tone_cisco_long.pcm
+diff ../dataqa350/i30_173tone_cisco_long.pcm ../dataqa351/i30_173tone_cisco_long.pcm
+diff ../dataqa350/i60_173tone_cisco_long.pcm ../dataqa351/i60_173tone_cisco_long.pcm
+diff ../dataqa350/i30_174tone_cisco_long.pcm ../dataqa351/i30_174tone_cisco_long.pcm
+diff ../dataqa350/i60_174tone_cisco_long.pcm ../dataqa351/i60_174tone_cisco_long.pcm
+diff ../dataqa350/a85tone_cisco_long.pcm ../dataqa351/a85tone_cisco_long.pcm
+diff ../dataqa350/a86tone_cisco_long.pcm ../dataqa351/a86tone_cisco_long.pcm
+diff ../dataqa350/a87tone_cisco_long.pcm ../dataqa351/a87tone_cisco_long.pcm
+diff ../dataqa350/i30_175wb_contspeech.pcm ../dataqa351/i30_175wb_contspeech.pcm
+diff ../dataqa350/i60_175wb_contspeech.pcm ../dataqa351/i60_175wb_contspeech.pcm
+diff ../dataqa350/i30_176wb_contspeech.pcm ../dataqa351/i30_176wb_contspeech.pcm
+diff ../dataqa350/i60_176wb_contspeech.pcm ../dataqa351/i60_176wb_contspeech.pcm
+diff ../dataqa350/i30_177wb_contspeech.pcm ../dataqa351/i30_177wb_contspeech.pcm
+diff ../dataqa350/i60_177wb_contspeech.pcm ../dataqa351/i60_177wb_contspeech.pcm
+diff ../dataqa350/i30_178wb_contspeech.pcm ../dataqa351/i30_178wb_contspeech.pcm
+diff ../dataqa350/i60_178wb_contspeech.pcm ../dataqa351/i60_178wb_contspeech.pcm
+diff ../dataqa350/i30_179wb_contspeech.pcm ../dataqa351/i30_179wb_contspeech.pcm
+diff ../dataqa350/i60_179wb_contspeech.pcm ../dataqa351/i60_179wb_contspeech.pcm
+diff ../dataqa350/i30_180wb_contspeech.pcm ../dataqa351/i30_180wb_contspeech.pcm
+diff ../dataqa350/i60_180wb_contspeech.pcm ../dataqa351/i60_180wb_contspeech.pcm
+diff ../dataqa350/a88wb_contspeech.pcm ../dataqa351/a88wb_contspeech.pcm
+diff ../dataqa350/a89wb_contspeech.pcm ../dataqa351/a89wb_contspeech.pcm
+diff ../dataqa350/a90wb_contspeech.pcm ../dataqa351/a90wb_contspeech.pcm
+diff ../dataqa350/i30_181wb_speech_office25db.pcm ../dataqa351/i30_181wb_speech_office25db.pcm
+diff ../dataqa350/i60_181wb_speech_office25db.pcm ../dataqa351/i60_181wb_speech_office25db.pcm
+diff ../dataqa350/i30_182wb_speech_office25db.pcm ../dataqa351/i30_182wb_speech_office25db.pcm
+diff ../dataqa350/i60_182wb_speech_office25db.pcm ../dataqa351/i60_182wb_speech_office25db.pcm
+diff ../dataqa350/i30_183wb_speech_office25db.pcm ../dataqa351/i30_183wb_speech_office25db.pcm
+diff ../dataqa350/i60_183wb_speech_office25db.pcm ../dataqa351/i60_183wb_speech_office25db.pcm
+diff ../dataqa350/i30_184wb_speech_office25db.pcm ../dataqa351/i30_184wb_speech_office25db.pcm
+diff ../dataqa350/i60_184wb_speech_office25db.pcm ../dataqa351/i60_184wb_speech_office25db.pcm
+diff ../dataqa350/i30_185wb_speech_office25db.pcm ../dataqa351/i30_185wb_speech_office25db.pcm
+diff ../dataqa350/i60_185wb_speech_office25db.pcm ../dataqa351/i60_185wb_speech_office25db.pcm
+diff ../dataqa350/i30_186wb_speech_office25db.pcm ../dataqa351/i30_186wb_speech_office25db.pcm
+diff ../dataqa350/i60_186wb_speech_office25db.pcm ../dataqa351/i60_186wb_speech_office25db.pcm
+diff ../dataqa350/a91wb_speech_office25db.pcm ../dataqa351/a91wb_speech_office25db.pcm
+diff ../dataqa350/a92wb_speech_office25db.pcm ../dataqa351/a92wb_speech_office25db.pcm
+diff ../dataqa350/a93wb_speech_office25db.pcm ../dataqa351/a93wb_speech_office25db.pcm
+diff ../dataqa350/a30_1DTMF_16kHz_short.pcm ../dataqa351/a30_1DTMF_16kHz_short.pcm
+diff ../dataqa350/a60_1DTMF_16kHz_short.pcm ../dataqa351/a60_1DTMF_16kHz_short.pcm
+diff ../dataqa350/a30_2ltest_speech_noisy.pcm ../dataqa351/a30_2ltest_speech_noisy.pcm
+diff ../dataqa350/a60_2ltest_speech_noisy.pcm ../dataqa351/a60_2ltest_speech_noisy.pcm
+diff ../dataqa350/a30_3misc2.pcm ../dataqa351/a30_3misc2.pcm
+diff ../dataqa350/a60_3misc2.pcm ../dataqa351/a60_3misc2.pcm
+diff ../dataqa350/a30_4sinesweep.pcm ../dataqa351/a30_4sinesweep.pcm
+diff ../dataqa350/a60_4sinesweep.pcm ../dataqa351/a60_4sinesweep.pcm
+diff ../dataqa350/a30_5speechmusic.pcm ../dataqa351/a30_5speechmusic.pcm
+diff ../dataqa350/a60_5speechmusic.pcm ../dataqa351/a60_5speechmusic.pcm
+diff ../dataqa350/a30_6tone_cisco.pcm ../dataqa351/a30_6tone_cisco.pcm
+diff ../dataqa350/a60_6tone_cisco.pcm ../dataqa351/a60_6tone_cisco.pcm
+diff ../dataqa350/a60_7tone_cisco.pcm ../dataqa351/a60_7tone_cisco.pcm
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/diffiSACPLC.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/diffiSACPLC.txt
new file mode 100644
index 0000000..9e3629b
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/diffiSACPLC.txt
@@ -0,0 +1,20 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGFILE=logplc.txt
+echo "START PLC TEST" > $LOGFILE
+
+OUTDIR1=../dataqaplc_0
+OUTDIR2=../dataqaplc_1
+
+diff $OUTDIR1/outplc1.pcm $OUTDIR2/outplc1.pcm 
+diff $OUTDIR1/outplc2.pcm $OUTDIR2/outplc2.pcm 
+diff $OUTDIR1/outplc3.pcm $OUTDIR2/outplc3.pcm 
+diff $OUTDIR1/outplc4.pcm $OUTDIR2/outplc4.pcm 
+diff $OUTDIR1/outplc5.pcm $OUTDIR2/outplc5.pcm 
+diff $OUTDIR1/outplc6.pcm $OUTDIR2/outplc6.pcm 
+
+echo DONE!
+
+
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACLongtest.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACLongtest.txt
new file mode 100644
index 0000000..eeffc0c
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACLongtest.txt
@@ -0,0 +1,61 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGFILE=logNormal.txt
+echo "START ISAC TEST" > $LOGFILE
+echo >> $LOGFILE
+
+ISAC=../Release/kenny.exe
+ISACFIXFLOAT=../Release/testFixFloat.exe
+
+INFILES=$(cat InputFiles.txt)
+SUBSET=$(cat InputFilesFew.txt)
+CHANNELFILES=$(cat ChannelFiles.txt)
+CHANNELLIST=($(cat ChannelFiles.txt))
+INDIR=../data/orig
+OUTDIR=../dataqa
+mkdir -p $OUTDIR
+
+TARGETRATE=(10000 15000 20000 25000 30000 32000)
+#echo ${CHANNELFILES[1]}
+
+index1=0
+index2=0
+
+for file in $INFILES # loop over all input files
+  do
+  
+  for rate in ${TARGETRATE[*]}
+	do
+	let "index1=index1+1"
+	$ISAC -I $rate -FL 30 $INDIR/"$file" $OUTDIR/i30_$index1"$file" >> $LOGFILE
+	$ISAC -I $rate -FL 60 $INDIR/"$file" $OUTDIR/i60_$index1"$file" >> $LOGFILE
+  done
+  for channel in $CHANNELFILES
+	do
+	let "index2=index2+1"
+	$ISAC $INDIR/$channel $INDIR/"$file" $OUTDIR/a$index2"$file" >> $LOGFILE
+  done
+
+done
+
+index1=0
+
+for file in $SUBSET # loop over the subset of input files
+  do
+	let "index1=index1+1"
+	$ISAC $INDIR/${CHANNELLIST[0]} -FL 30 -FIXED_FL $INDIR/"$file" $OUTDIR/a30_$index1"$file" >> $LOGFILE
+	$ISAC $INDIR/${CHANNELLIST[0]} -FL 60 -FIXED_FL $INDIR/"$file" $OUTDIR/a60_$index1"$file" >> $LOGFILE
+done
+
+let "index1=index1+1"	
+ $ISAC $INDIR/${CHANNELLIST[0]} -INITRATE 25000 -FL 30 $INDIR/"$file" $OUTDIR/a60_$index1"$file" >> $LOGFILE
+
+# Run fault test
+
+#./runiSACfault.txt
+
+echo DONE!
+
+
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACNB.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACNB.txt
new file mode 100644
index 0000000..605595c
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACNB.txt
@@ -0,0 +1,45 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGFILE=logNB.txt
+echo "START NARROWBAND TEST" > $LOGFILE
+echo >> $LOGFILE
+
+ISAC=../Release/kenny.exe
+ISACFIXFLOAT=../Release/testFixFloat.exe
+
+INFILES=$(cat InputFiles.txt)
+SUBSET=$(cat InputFilesFew.txt)
+CHANNELFILES=$(cat ChannelFiles.txt)
+CHANNELLIST=($(cat ChannelFiles.txt))
+INDIR=../data/orig
+OUTDIR=../dataqaNB
+mkdir -p $OUTDIR
+
+TARGETRATE=(10000 15000 20000 25000 30000 32000)
+#echo ${CHANNELFILES[1]}
+
+index1=0
+index2=0
+
+# Narrowband Interfaces
+
+for file in $SUBSET # loop over all input files
+  do
+  for rate in ${TARGETRATE[*]}
+	do
+	let "index1=index1+1"
+ 	$ISAC $rate -FL 30 -NB 1 $INDIR/"$file" $OUTDIR/nb130_$index1"$file" >> $LOGFILE
+	$ISAC $rate -FL 60 -NB 1 $INDIR/"$file" $OUTDIR/nb160_$index1"$file" >> $LOGFILE
+	$ISAC $rate -FL 30 -NB 2 $INDIR/"$file" $OUTDIR/nb230_$index1"$file" >> $LOGFILE
+	$ISAC $rate -FL 60 -NB 2 $INDIR/"$file" $OUTDIR/nb260_$index1"$file" >> $LOGFILE
+	$ISAC $rate -FL 30 -NB 2 -PL 10 $INDIR/"$file" $OUTDIR/nb2plc30_$index1"$file" >> $LOGFILE
+	$ISAC $rate -FL 60 -NB 2 -PL 10 $INDIR/"$file" $OUTDIR/nb2plc60_$index1"$file" >> $LOGFILE
+  done
+
+done
+
+echo DONE!
+
+
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACPLC.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACPLC.txt
new file mode 100644
index 0000000..6bee6f7
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACPLC.txt
@@ -0,0 +1,23 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGFILE=logplc.txt
+echo "START PLC TEST" > $LOGFILE
+
+ISAC=../Release/kenny.exe
+
+INDIR=../data/orig
+OUTDIR=../dataqaplc_0
+mkdir -p $OUTDIR
+
+$ISAC 12000 -PL 15 $INDIR/speechmusic.pcm $OUTDIR/outplc1.pcm 
+$ISAC 20000 -PL 15 $INDIR/speechmusic.pcm $OUTDIR/outplc2.pcm 
+$ISAC 32000 -PL 15 $INDIR/speechmusic.pcm $OUTDIR/outplc3.pcm 
+$ISAC 12000 -PL 15 $INDIR/tone_cisco.pcm $OUTDIR/outplc4.pcm 
+$ISAC 20000 -PL 15 $INDIR/tone_cisco.pcm $OUTDIR/outplc5.pcm 
+$ISAC 32000 -PL 15 $INDIR/tone_cisco.pcm $OUTDIR/outplc6.pcm 
+
+echo DONE!
+
+
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACRate.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACRate.txt
new file mode 100644
index 0000000..d8403e0
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACRate.txt
@@ -0,0 +1,23 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGG=loggRate.txt
+OUTDIR=../dataqaRate
+mkdir -p $OUTDIR
+
+../Release/kenny.exe 13000 -FIXED_FL -FL 30 -MAX 100 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_1.pcm > $LOGG
+../Release/kenny.exe ../data/orig/bottlenecks.txt -FIXED_FL -FL 30 -MAXRATE 32000 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_2.pcm >> $LOGG
+../Release/kenny.exe 13000 -FIXED_FL -FL 30 -MAX 100 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_3.pcm >> $LOGG
+../Release/kenny.exe ../data/orig/bottlenecks.txt -FIXED_FL -FL 30 -MAXRATE 32000 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_4.pcm >> $LOGG
+../Release/kenny.exe 13000 -FIXED_FL -FL 60 -MAX 100 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_5.pcm >> $LOGG
+../Release/kenny.exe ../data/orig/bottlenecks.txt -FIXED_FL -FL 60 -MAXRATE 32000 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_6.pcm >> $LOGG
+../Release/kenny.exe 13000 -INIT_RATE 32000 -FIXED_FL -FL 60 -MAX 100 ../data/orig/sawsweep_380_60.pcm $OUTDIR/out_napi_7.pcm >> $LOGG
+
+../Release/kenny.exe 13000 -FIXED_FL -FL 30 -MAX 100 ../data/orig/longspeech.pcm $OUTDIR/out_napi_11.pcm >> $LOGG
+../Release/kenny.exe ../data/orig/bottlenecks.txt -FIXED_FL -FL 30 -MAXRATE 32000 ../data/orig/longspeech.pcm $OUTDIR/out_napi_12.pcm >> $LOGG
+../Release/kenny.exe 13000 -FIXED_FL -FL 30 -MAX 100 ../data/orig/longspeech.pcm $OUTDIR/out_napi_13.pcm >> $LOGG
+../Release/kenny.exe ../data/orig/bottlenecks.txt -FIXED_FL -FL 30 -MAXRATE 32000 ../data/orig/longspeech.pcm $OUTDIR/out_napi_14.pcm >> $LOGG
+../Release/kenny.exe 13000 -FIXED_FL -FL 60 -MAX 100 ../data/orig/longspeech.pcm $OUTDIR/out_napi_15.pcm >> $LOGG
+../Release/kenny.exe ../data/orig/bottlenecks.txt -FIXED_FL -FL 60 -MAXRATE 32000 ../data/orig/longspeech.pcm $OUTDIR/out_napi_16.pcm >> $LOGG
+../Release/kenny.exe 13000 -INIT_RATE 32000 -FIXED_FL -FL 60 -MAX 100 ../data/orig/longspeech.pcm $OUTDIR/out_napi_17.pcm >> $LOGG
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACfault.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACfault.txt
new file mode 100644
index 0000000..f4d9478
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACfault.txt
@@ -0,0 +1,40 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGFILE=logfault.txt
+echo "START FAULT TEST" > $LOGFILE
+
+ISAC=../Release/kenny.exe
+ISACFIXFLOAT=../Release/testFixFloat.exe
+
+INFILES=$(cat InputFiles.txt)
+SUBSET=$(cat InputFilesFew.txt)
+CHANNELFILES=$(cat ChannelFiles.txt)
+CHANNELLIST=($(cat ChannelFiles.txt))
+INDIR=../data/orig
+OUTDIR=../dataqaft
+mkdir -p $OUTDIR
+
+TARGETRATE=(10000 15000 20000 25000 30000 32000)
+FAULTTEST=(1 2 3 4 5 6 7 9)
+
+index1=0
+
+file=wb_contspeech.pcm
+
+# Fault test
+for testnr in ${FAULTTEST[*]}
+   do
+	$ISAC 32000 -F $testnr $INDIR/"$file" $OUTDIR/ft$testnr"$file" >> $LOGFILE
+done
+
+# Fault test number 10, error in bitstream
+ $ISAC 32000 -F 10 $INDIR/"$file" $OUTDIR/ft10_"$file" >> $LOGFILE
+ $ISAC 32000 -F 10 -PL 10 $INDIR/"$file" $OUTDIR/ft10plc_"$file" >> $LOGFILE
+ $ISAC 32000 -F 10 -NB 1 $INDIR/"$file" $OUTDIR/ft10nb1_"$file" >> $LOGFILE
+ $ISAC 32000 -F 10 -NB 2 -PL 10 $INDIR/"$file" $OUTDIR/ft10nb2_"$file" >> $LOGFILE
+
+echo DONE!
+
+
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACfixfloat.txt b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACfixfloat.txt
new file mode 100644
index 0000000..c9e02df
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/QA/runiSACfixfloat.txt
@@ -0,0 +1,47 @@
+#!/bin/bash
+(set -o igncr) 2>/dev/null && set -o igncr; # force bash to ignore \r character
+
+LOGFILE=logfxfl.txt
+echo "START FIX-FLOAT TEST" > $LOGFILE
+
+
+ISACFIXFLOAT=../testFixFloat.exe
+
+INFILES=$(cat InputFiles.txt)
+SUBSET=$(cat InputFilesFew.txt)
+CHANNELFILES=$(cat ChannelFiles.txt)
+CHANNELLIST=($(cat ChannelFiles.txt))
+INDIR=../data/orig
+OUTDIR=../dataqafxfl
+mkdir -p $OUTDIR
+
+index1=0
+
+for file in $INFILES # loop over all input files
+  do
+  
+  for channel in $CHANNELFILES
+	do
+	let "index1=index1+1"
+
+	$ISACFIXFLOAT $INDIR/$channel -m 1 -PLC $INDIR/"$file" $OUTDIR/flfx$index1"$file" >> $LOGFILE
+	$ISACFIXFLOAT $INDIR/$channel -m 2 -PLC $INDIR/"$file" $OUTDIR/fxfl$index1"$file" >> $LOGFILE
+  done
+
+done
+
+index1=0
+
+for file in $SUBSET # loop over the subset of input files
+  do
+	let "index1=index1+1"
+	$ISACFIXFLOAT $INDIR/$channel -m 1 -NB 1 $INDIR/"$file" $OUTDIR/flfxnb1_$index1"$file" >> $LOGFILE
+	$ISACFIXFLOAT $INDIR/$channel -m 2 -NB 1 $INDIR/"$file" $OUTDIR/fxflnb1_$index1"$file" >> $LOGFILE
+	$ISACFIXFLOAT $INDIR/$channel -m 1 -NB 2 -PLC $INDIR/"$file" $OUTDIR/flfxnb2_$index1"$file" >> $LOGFILE
+	$ISACFIXFLOAT $INDIR/$channel -m 2 -NB 2 -PLC $INDIR/"$file" $OUTDIR/fxflnb2_$index1"$file" >> $LOGFILE
+done
+
+echo DONE!
+
+
+
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/isacfix_unittest.cc b/src/modules/audio_coding/codecs/isac/fix/test/isacfix_unittest.cc
new file mode 100644
index 0000000..bef71e9
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/isacfix_unittest.cc
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#include <typedefs.h>
+
+#include "gtest/gtest.h"
+#include "modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
+#include "modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h"
+#include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
+#include "system_wrappers/interface/cpu_features_wrapper.h"
+
+class IsacUnitTest : public testing::Test {
+ protected:
+  // Pass a function pointer to the Tester function.
+  void CalculateResidualEnergyTester(CalculateResidualEnergy
+                                     CalculateResidualEnergyFunction) {
+    const int kIntOrder = 10;
+    const int32_t kInt32QDomain = 5;
+    const int kIntShift = 11;
+    int16_t a[kIntOrder + 1] = {32760, 122, 7, 0, -32760, -3958,
+        -48, 18745, 498, 9, 23456};
+    int32_t corr[kIntOrder + 1] = {11443647, -27495, 0,
+        98745, -11443600, 1, 1, 498, 9, 888, 23456};
+    int q_shift_residual = 0;
+    int32_t residual_energy = 0;
+
+    // Test the code path where (residual_energy >= 0x10000).
+    residual_energy = CalculateResidualEnergyFunction(kIntOrder,
+        kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
+    EXPECT_EQ(1789023310, residual_energy);
+    EXPECT_EQ(2, q_shift_residual);
+
+    // Test the code path where (residual_energy < 0x10000)
+    // and ((energy & 0x8000) != 0).
+    for(int i = 0; i < kIntOrder + 1; i++) {
+      a[i] = 24575 >> i;
+      corr[i] = i;
+    }
+    residual_energy = CalculateResidualEnergyFunction(kIntOrder,
+        kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
+    EXPECT_EQ(1595279092, residual_energy);
+    EXPECT_EQ(26, q_shift_residual);
+
+    // Test the code path where (residual_energy <= 0x7fff).
+    for(int i = 0; i < kIntOrder + 1; i++) {
+      a[i] = 2457 >> i;
+    }
+    residual_energy = CalculateResidualEnergyFunction(kIntOrder,
+        kInt32QDomain, kIntShift, a, corr, &q_shift_residual);
+    EXPECT_EQ(2029266944, residual_energy);
+    EXPECT_EQ(33, q_shift_residual);
+  }
+};
+
+TEST_F(IsacUnitTest, CalculateResidualEnergyTest) {
+  CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyC);
+#ifdef WEBRTC_DETECT_ARM_NEON
+  if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
+    CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyNeon);
+  }
+#elif defined(WEBRTC_ARCH_ARM_NEON)
+  CalculateResidualEnergyTester(WebRtcIsacfix_CalculateResidualEnergyNeon);
+#endif
+}
+
+TEST_F(IsacUnitTest, HighpassFilterFixDec32Test) {
+  const int kSamples = 20;
+  int16_t in[kSamples];
+  int32_t state[2] = {12345, 987654};
+#ifdef WEBRTC_ARCH_ARM_V7
+  int32_t out[kSamples] = {-1040, -1035, -22875, -1397, -27604, 20018, 7917,
+    -1279, -8552, -14494, -7558, -23537, -27258, -30554, -32768, -3432, -32768,
+    25215, -27536, 22436};
+#else
+  int32_t out[kSamples] = {-1040, -1035, -22875, -1397, -27604, 20017, 7915,
+    -1280, -8554, -14496, -7561, -23541, -27263, -30560, -32768, -3441, -32768,
+    25203, -27550, 22419};
+#endif
+
+  for(int i = 0; i < kSamples; i++) {
+    in[i] = WEBRTC_SPL_WORD32_MAX / (i + 1);
+  }
+
+  WebRtcIsacfix_HighpassFilterFixDec32(in, kSamples,
+      WebRtcIsacfix_kHPStCoeffOut1Q30, state);
+
+  for(int i = 0; i < kSamples; i++) {
+    EXPECT_EQ(out[i], in[i]);
+  }
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/kenny.c b/src/modules/audio_coding/codecs/isac/fix/test/kenny.c
new file mode 100644
index 0000000..8b04c98
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/kenny.c
@@ -0,0 +1,853 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/* kenny.c  - Main function for the iSAC coder */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "isacfix.h"
+
+
+/* Defines */
+#define SEED_FILE "randseed.txt"  /* Used when running decoder on garbage data */
+#define MAX_FRAMESAMPLES    960   /* max number of samples per frame (= 60 ms frame) */
+#define FRAMESAMPLES_10ms 160   /* number of samples per 10ms frame */
+#define FS           16000 /* sampling frequency (Hz) */
+
+/* Function for reading audio data from PCM file */
+int readframe(WebRtc_Word16 *data, FILE *inp, int length) {
+
+  short k, rlen, status = 0;
+
+  rlen = fread(data, sizeof(WebRtc_Word16), length, inp);
+  if (rlen < length) {
+    for (k = rlen; k < length; k++)
+      data[k] = 0;
+    status = 1;
+  }
+
+  return status;
+}
+
+/* Struct for bottleneck model */
+typedef struct {
+  WebRtc_UWord32 send_time;            /* samples */
+  WebRtc_UWord32 arrival_time;         /* samples */
+  WebRtc_UWord32 sample_count;         /* samples */
+  WebRtc_UWord16 rtp_number;
+} BottleNeckModel;
+
+void get_arrival_time(int current_framesamples,   /* samples */
+                      int packet_size,            /* bytes */
+                      int bottleneck,             /* excluding headers; bits/s */
+                      BottleNeckModel *BN_data)
+{
+  const int HeaderSize = 35;
+  int HeaderRate;
+
+  HeaderRate = HeaderSize * 8 * FS / current_framesamples;     /* bits/s */
+
+  /* everything in samples */
+  BN_data->sample_count = BN_data->sample_count + current_framesamples;
+
+  BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate);
+  BN_data->send_time += current_framesamples;
+
+  if (BN_data->arrival_time < BN_data->sample_count)
+    BN_data->arrival_time = BN_data->sample_count;
+
+  BN_data->rtp_number++;
+}
+
+void get_arrival_time2(int current_framesamples,
+                       int current_delay,
+                       BottleNeckModel *BN_data)
+{
+  if (current_delay == -1)
+    //dropped packet
+  {
+    BN_data->arrival_time += current_framesamples;
+  }
+  else if (current_delay != -2)
+  {
+    //
+    BN_data->arrival_time += (current_framesamples + ((FS/1000) * current_delay));
+  }
+  //else
+  //current packet has same timestamp as previous packet
+
+  BN_data->rtp_number++;
+}
+
+int main(int argc, char* argv[])
+{
+
+  char inname[100], outname[100],  outbitsname[100], bottleneck_file[100];
+  FILE *inp, *outp, *f_bn, *outbits;
+  int endfile;
+
+  int i, errtype, h = 0, k, packetLossPercent = 0;
+  WebRtc_Word16 CodingMode;
+  WebRtc_Word16 bottleneck;
+  WebRtc_Word16 framesize = 30;           /* ms */
+  int cur_framesmpls, err = 0, lostPackets = 0;
+
+  /* Runtime statistics */
+  double starttime, runtime, length_file;
+
+  WebRtc_Word16 stream_len = 0;
+  WebRtc_Word16 framecnt, declen = 0;
+  WebRtc_Word16 shortdata[FRAMESAMPLES_10ms];
+  WebRtc_Word16 decoded[MAX_FRAMESAMPLES];
+  WebRtc_UWord16 streamdata[500];
+  WebRtc_Word16 speechType[1];
+  WebRtc_Word16 prevFrameSize = 1;
+  WebRtc_Word16 rateBPS = 0;
+  WebRtc_Word16 fixedFL = 0;
+  WebRtc_Word16 payloadSize = 0;
+  WebRtc_Word32 payloadRate = 0;
+  int setControlBWE = 0;
+  int readLoss;
+  FILE  *plFile = NULL;
+
+  char version_number[20];
+  char tmpBit[5] = ".bit";
+
+  double kbps;
+  int totalbits =0;
+  int totalsmpls =0;
+#ifdef _DEBUG
+  FILE *fy;
+#endif
+  WebRtc_Word16 testNum, testCE;
+
+  FILE *fp_gns = NULL;
+  int gns = 0;
+  int cur_delay = 0;
+  char gns_file[100];
+
+  int nbTest = 0;
+  WebRtc_Word16 lostFrame;
+  float scale = (float)0.7;
+  /* only one structure used for ISAC encoder */
+  ISACFIX_MainStruct *ISAC_main_inst;
+
+  /* For fault test 10, garbage data */
+  FILE *seedfile;
+  unsigned int random_seed = (unsigned int) time(NULL);//1196764538
+
+  BottleNeckModel       BN_data;
+  f_bn  = NULL;
+
+#ifdef _DEBUG
+  fy = fopen("bit_rate.dat", "w");
+  fclose(fy);
+  fy = fopen("bytes_frames.dat", "w");
+  fclose(fy);
+#endif
+
+  readLoss = 0;
+  packetLossPercent = 0;
+
+  /* Handling wrong input arguments in the command line */
+  if ((argc<3) || (argc>21))  {
+    printf("\n\nWrong number of arguments or flag values.\n\n");
+
+    printf("\n");
+    WebRtcIsacfix_version(version_number);
+    printf("iSAC version %s \n\n", version_number);
+
+    printf("Usage:\n\n");
+    printf("./kenny.exe [-F num][-I] bottleneck_value infile outfile \n\n");
+    printf("with:\n");
+    printf("[-I]             :if -I option is specified, the coder will use\n");
+    printf("                  an instantaneous Bottleneck value. If not, it\n");
+    printf("                  will be an adaptive Bottleneck value.\n\n");
+    printf("bottleneck_value :the value of the bottleneck provided either\n");
+    printf("                  as a fixed value (e.g. 25000) or\n");
+    printf("                  read from a file (e.g. bottleneck.txt)\n\n");
+    printf("[-INITRATE num]  :Set a new value for initial rate. Note! Only used"
+           " in adaptive mode.\n\n");
+    printf("[-FL num]        :Set (initial) frame length in msec. Valid length"
+           " are 30 and 60 msec.\n\n");
+    printf("[-FIXED_FL]      :Frame length will be fixed to initial value.\n\n");
+    printf("[-MAX num]       :Set the limit for the payload size of iSAC"
+           " in bytes. \n");
+    printf("                  Minimum 100, maximum 400.\n\n");
+    printf("[-MAXRATE num]   :Set the maxrate for iSAC in bits per second. \n");
+    printf("                  Minimum 32000, maximum 53400.\n\n");
+    printf("[-F num]         :if -F option is specified, the test function\n");
+    printf("                  will run the iSAC API fault scenario specified"
+           " by the\n");
+    printf("                  supplied number.\n");
+    printf("                  F 1 - Call encoder prior to init encoder call\n");
+    printf("                  F 2 - Call decoder prior to init decoder call\n");
+    printf("                  F 3 - Call decoder prior to encoder call\n");
+    printf("                  F 4 - Call decoder with a too short coded"
+           " sequence\n");
+    printf("                  F 5 - Call decoder with a too long coded"
+           " sequence\n");
+    printf("                  F 6 - Call decoder with random bit stream\n");
+    printf("                  F 7 - Call init encoder/decoder at random"
+           " during a call\n");
+    printf("                  F 8 - Call encoder/decoder without having"
+           " allocated memory for \n");
+    printf("                        encoder/decoder instance\n");
+    printf("                  F 9 - Call decodeB without calling decodeA\n");
+    printf("                  F 10 - Call decodeB with garbage data\n");
+    printf("[-PL num]       : if -PL option is specified 0<num<100 will "
+           "specify the\n");
+    printf("                  percentage of packet loss\n\n");
+    printf("[-G file]       : if -G option is specified the file given is"
+           " a .gns file\n");
+    printf("                  that represents a network profile\n\n");
+    printf("[-NB num]       : if -NB option, use the narrowband interfaces\n");
+    printf("                  num=1 => encode with narrowband encoder"
+           " (infile is narrowband)\n");
+    printf("                  num=2 => decode with narrowband decoder"
+           " (outfile is narrowband)\n\n");
+    printf("[-CE num]       : Test of APIs used by Conference Engine.\n");
+    printf("                  CE 1 - createInternal, freeInternal,"
+           " getNewBitstream \n");
+    printf("                  CE 2 - transcode, getBWE \n");
+    printf("                  CE 3 - getSendBWE, setSendBWE.  \n\n");
+    printf("[-RTP_INIT num] : if -RTP_INIT option is specified num will be"
+           " the initial\n");
+    printf("                  value of the rtp sequence number.\n\n");
+    printf("infile          : Normal speech input file\n\n");
+    printf("outfile         : Speech output file\n\n");
+    printf("Example usage   : \n\n");
+    printf("./kenny.exe -I bottleneck.txt speechIn.pcm speechOut.pcm\n\n");
+    exit(0);
+
+  }
+
+  /* Print version number */
+  WebRtcIsacfix_version(version_number);
+  printf("iSAC version %s \n\n", version_number);
+
+  /* Loop over all command line arguments */
+  CodingMode = 0;
+  testNum = 0;
+  testCE = 0;
+  for (i = 1; i < argc-2;i++) {
+    /* Instantaneous mode */
+    if (!strcmp ("-I", argv[i])) {
+      printf("\nInstantaneous BottleNeck\n");
+      CodingMode = 1;
+      i++;
+    }
+
+    /* Set (initial) bottleneck value */
+    if (!strcmp ("-INITRATE", argv[i])) {
+      rateBPS = atoi(argv[i + 1]);
+      setControlBWE = 1;
+      if ((rateBPS < 10000) || (rateBPS > 32000)) {
+        printf("\n%d is not a initial rate. "
+               "Valid values are in the range 10000 to 32000.\n", rateBPS);
+        exit(0);
+      }
+      printf("\nNew initial rate: %d\n", rateBPS);
+      i++;
+    }
+
+    /* Set (initial) framelength */
+    if (!strcmp ("-FL", argv[i])) {
+      framesize = atoi(argv[i + 1]);
+      if ((framesize != 30) && (framesize != 60)) {
+        printf("\n%d is not a valid frame length. "
+               "Valid length are 30 and 60 msec.\n", framesize);
+        exit(0);
+      }
+      printf("\nFrame Length: %d\n", framesize);
+      i++;
+    }
+
+    /* Fixed frame length */
+    if (!strcmp ("-FIXED_FL", argv[i])) {
+      fixedFL = 1;
+      setControlBWE = 1;
+    }
+
+    /* Set maximum allowed payload size in bytes */
+    if (!strcmp ("-MAX", argv[i])) {
+      payloadSize = atoi(argv[i + 1]);
+      printf("Maximum Payload Size: %d\n", payloadSize);
+      i++;
+    }
+
+    /* Set maximum rate in bytes */
+    if (!strcmp ("-MAXRATE", argv[i])) {
+      payloadRate = atoi(argv[i + 1]);
+      printf("Maximum Rate in kbps: %d\n", payloadRate);
+      i++;
+    }
+
+    /* Test of fault scenarious */
+    if (!strcmp ("-F", argv[i])) {
+      testNum = atoi(argv[i + 1]);
+      printf("\nFault test: %d\n", testNum);
+      if (testNum < 1 || testNum > 10) {
+        printf("\n%d is not a valid Fault Scenario number."
+               " Valid Fault Scenarios are numbered 1-10.\n", testNum);
+        exit(0);
+      }
+      i++;
+    }
+
+    /* Packet loss test */
+    if (!strcmp ("-PL", argv[i])) {
+      if( isdigit( *argv[i+1] ) ) {
+        packetLossPercent = atoi( argv[i+1] );
+        if( (packetLossPercent < 0) | (packetLossPercent > 100) ) {
+          printf( "\nInvalid packet loss perentage \n" );
+          exit( 0 );
+        }
+        if( packetLossPercent > 0 ) {
+          printf( "\nSimulating %d %% of independent packet loss\n",
+                  packetLossPercent );
+        } else {
+          printf( "\nNo Packet Loss Is Simulated \n" );
+        }
+        readLoss = 0;
+      } else {
+        readLoss = 1;
+        plFile = fopen( argv[i+1], "rb" );
+        if( plFile == NULL ) {
+          printf( "\n couldn't open the frameloss file: %s\n", argv[i+1] );
+          exit( 0 );
+        }
+        printf( "\nSimulating packet loss through the given "
+                "channel file: %s\n", argv[i+1] );
+      }
+      i++;
+    }
+
+    /* Random packetlosses */
+    if (!strcmp ("-rnd", argv[i])) {
+      srand(time(NULL) );
+      printf( "\n Random pattern in lossed packets \n" );
+    }
+
+    /* Use gns file */
+    if (!strcmp ("-G", argv[i])) {
+      sscanf(argv[i + 1], "%s", gns_file);
+      fp_gns = fopen(gns_file, "rb");
+      if (fp_gns  == NULL) {
+        printf("Cannot read file %s.\n", gns_file);
+        exit(0);
+      }
+      gns = 1;
+      i++;
+    }
+
+    /* Run Narrowband interfaces (either encoder or decoder) */
+    if (!strcmp ("-NB", argv[i])) {
+      nbTest = atoi(argv[i + 1]);
+      i++;
+    }
+
+    /* Run Conference Engine APIs */
+    if (!strcmp ("-CE", argv[i])) {
+      testCE = atoi(argv[i + 1]);
+      if (testCE==1 || testCE==2) {
+        i++;
+        scale = (float)atof( argv[i+1] );
+      } else if (testCE < 1 || testCE > 3) {
+        printf("\n%d is not a valid CE-test number, valid Fault "
+               "Scenarios are numbered 1-3\n", testCE);
+        exit(0);
+      }
+      i++;
+    }
+
+    /* Set initial RTP number */
+    if (!strcmp ("-RTP_INIT", argv[i])) {
+      i++;
+    }
+  }
+
+  /* Get Bottleneck value                                                   */
+  /* Gns files and bottleneck should not and can not be used simultaneously */
+  bottleneck = atoi(argv[CodingMode+1]);
+  if (bottleneck == 0 && gns == 0) {
+    sscanf(argv[CodingMode+1], "%s", bottleneck_file);
+    f_bn = fopen(bottleneck_file, "rb");
+    if (f_bn  == NULL) {
+      printf("No value provided for BottleNeck and cannot read file %s\n", bottleneck_file);
+      exit(0);
+    } else {
+      int aux_var;
+      printf("reading bottleneck rates from file %s\n\n",bottleneck_file);
+      if (fscanf(f_bn, "%d", &aux_var) == EOF) {
+        /* Set pointer to beginning of file */
+        fseek(f_bn, 0L, SEEK_SET);
+        if (fscanf(f_bn, "%d", &aux_var) == EOF) {
+          exit(0);
+        }
+      }
+      bottleneck = (WebRtc_Word16)aux_var;
+      /* Bottleneck is a cosine function
+       * Matlab code for writing the bottleneck file:
+       * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
+       * fid = fopen('bottleneck.txt', 'wb');
+       * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
+       */
+    }
+  } else {
+    f_bn = NULL;
+    printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
+  }
+
+  if (CodingMode == 0) {
+    printf("\nAdaptive BottleNeck\n");
+  }
+
+  /* Get Input and Output files */
+  sscanf(argv[argc-2], "%s", inname);
+  sscanf(argv[argc-1], "%s", outname);
+
+  /* Add '.bit' to output bitstream file */
+  while ((int)outname[h] != 0) {
+    outbitsname[h] = outname[h];
+    h++;
+  }
+  for (k=0; k<5; k++) {
+    outbitsname[h] = tmpBit[k];
+    h++;
+  }
+  if ((inp = fopen(inname,"rb")) == NULL) {
+    printf("  iSAC: Cannot read file %s\n", inname);
+    exit(1);
+  }
+  if ((outp = fopen(outname,"wb")) == NULL) {
+    printf("  iSAC: Cannot write file %s\n", outname);
+    exit(1);
+  }
+
+  if ((outbits = fopen(outbitsname,"wb")) == NULL) {
+    printf("  iSAC: Cannot write file %s\n", outbitsname);
+    exit(1);
+  }
+  printf("\nInput:%s\nOutput:%s\n\n", inname, outname);
+
+  /* Error test number 10, garbage data */
+  if (testNum == 10) {
+    /* Test to run decoder with garbage data */
+    srand(random_seed);
+
+    if ( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) {
+      printf("Error: Could not open file %s\n", SEED_FILE);
+    }
+    else {
+      fprintf(seedfile, "%u\n", random_seed);
+      fclose(seedfile);
+    }
+  }
+
+  /* Runtime statistics */
+  starttime = clock()/(double)CLOCKS_PER_SEC;
+
+  /* Initialize the ISAC and BN structs */
+  if (testNum != 8)
+  {
+    if(1){
+      err =WebRtcIsacfix_Create(&ISAC_main_inst);
+    }else{
+      /* Test the Assign functions */
+      int sss;
+      void *ppp;
+      err =WebRtcIsacfix_AssignSize(&sss);
+      ppp=malloc(sss);
+      err =WebRtcIsacfix_Assign(&ISAC_main_inst,ppp);
+    }
+    /* Error check */
+    if (err < 0) {
+      printf("\n\n Error in create.\n\n");
+    }
+    if (testCE == 1) {
+      err = WebRtcIsacfix_CreateInternal(ISAC_main_inst);
+      /* Error check */
+      if (err < 0) {
+        printf("\n\n Error in createInternal.\n\n");
+      }
+    }
+  }
+
+  /* Init of bandwidth data */
+  BN_data.send_time     = 0;
+  BN_data.arrival_time  = 0;
+  BN_data.sample_count  = 0;
+  BN_data.rtp_number    = 0;
+
+  /* Initialize encoder and decoder */
+  framecnt= 0;
+  endfile = 0;
+  if (testNum != 1) {
+    WebRtcIsacfix_EncoderInit(ISAC_main_inst, CodingMode);
+  }
+  if (testNum != 2) {
+    WebRtcIsacfix_DecoderInit(ISAC_main_inst);
+  }
+
+  if (CodingMode == 1) {
+    err = WebRtcIsacfix_Control(ISAC_main_inst, bottleneck, framesize);
+    if (err < 0) {
+      /* exit if returned with error */
+      errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+      printf("\n\n Error in control: %d.\n\n", errtype);
+    }
+  } else if(setControlBWE == 1) {
+    err = WebRtcIsacfix_ControlBwe(ISAC_main_inst, rateBPS, framesize, fixedFL);
+  }
+
+  if (payloadSize != 0) {
+    err = WebRtcIsacfix_SetMaxPayloadSize(ISAC_main_inst, payloadSize);
+    if (err < 0) {
+      /* exit if returned with error */
+      errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+      printf("\n\n Error in SetMaxPayloadSize: %d.\n\n", errtype);
+      exit(EXIT_FAILURE);
+    }
+  }
+  if (payloadRate != 0) {
+    err = WebRtcIsacfix_SetMaxRate(ISAC_main_inst, payloadRate);
+    if (err < 0) {
+      /* exit if returned with error */
+      errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+      printf("\n\n Error in SetMaxRateInBytes: %d.\n\n", errtype);
+      exit(EXIT_FAILURE);
+    }
+  }
+
+  *speechType = 1;
+
+
+  while (endfile == 0) {
+
+    if(testNum == 7 && (rand()%2 == 0)) {
+      err = WebRtcIsacfix_EncoderInit(ISAC_main_inst, CodingMode);
+      /* Error check */
+      if (err < 0) {
+        errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+        printf("\n\n Error in encoderinit: %d.\n\n", errtype);
+      }
+
+      err = WebRtcIsacfix_DecoderInit(ISAC_main_inst);
+      /* Error check */
+      if (err < 0) {
+        errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+        printf("\n\n Error in decoderinit: %d.\n\n", errtype);
+      }
+    }
+
+
+    cur_framesmpls = 0;
+    while (1) {
+      /* Read 10 ms speech block */
+      if (nbTest != 1) {
+        endfile = readframe(shortdata, inp, FRAMESAMPLES_10ms);
+      } else {
+        endfile = readframe(shortdata, inp, (FRAMESAMPLES_10ms/2));
+      }
+
+      if (testNum == 7) {
+        srand(time(NULL));
+      }
+
+      /* iSAC encoding */
+      if (!(testNum == 3 && framecnt == 0)) {
+        if (nbTest != 1) {
+          short bwe;
+
+          /* Encode */
+          stream_len = WebRtcIsacfix_Encode(ISAC_main_inst,
+                                            shortdata,
+                                            (WebRtc_Word16*)streamdata);
+
+          /* If packet is ready, and CE testing, call the different API functions
+             from the internal API.                       */
+          if (stream_len>0) {
+            if (testCE == 1) {
+              err = WebRtcIsacfix_ReadBwIndex((WebRtc_Word16*)streamdata, &bwe);
+              stream_len = WebRtcIsacfix_GetNewBitStream(
+                  ISAC_main_inst,
+                  bwe,
+                  scale,
+                  (WebRtc_Word16*)streamdata);
+            } else if (testCE == 2) {
+              /* transcode function not supported */
+            } else if (testCE == 3) {
+              /* Only for Function testing. The functions should normally
+                 not be used in this way                                      */
+
+              err = WebRtcIsacfix_GetDownLinkBwIndex(ISAC_main_inst, &bwe);
+              /* Error Check */
+              if (err < 0) {
+                errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+                printf("\nError in getSendBWE: %d.\n", errtype);
+              }
+
+              err = WebRtcIsacfix_UpdateUplinkBw(ISAC_main_inst, bwe);
+              /* Error Check */
+              if (err < 0) {
+                errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+                printf("\nError in setBWE: %d.\n", errtype);
+              }
+
+            }
+          }
+        } else {
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+          stream_len = WebRtcIsacfix_EncodeNb(ISAC_main_inst,
+                                              shortdata,
+                                              streamdata);
+#else
+          stream_len = -1;
+#endif
+        }
+      }
+      else
+      {
+        break;
+      }
+
+      if (stream_len < 0 || err < 0) {
+        /* exit if returned with error */
+        errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+        printf("\nError in encoder: %d.\n", errtype);
+      } else {
+        if (fwrite(streamdata, sizeof(char),
+                   stream_len, outbits) != (size_t)stream_len) {
+          return -1;
+        }
+      }
+
+      cur_framesmpls += FRAMESAMPLES_10ms;
+
+      /* read next bottleneck rate */
+      if (f_bn != NULL) {
+        int aux_var;
+        if (fscanf(f_bn, "%d", &aux_var) == EOF) {
+          /* Set pointer to beginning of file */
+          fseek(f_bn, 0L, SEEK_SET);
+          if (fscanf(f_bn, "%d", &aux_var) == EOF) {
+            exit(0);
+          }
+        }
+        bottleneck = (WebRtc_Word16)aux_var;
+        if (CodingMode == 1) {
+          WebRtcIsacfix_Control(ISAC_main_inst, bottleneck, framesize);
+        }
+      }
+
+      /* exit encoder loop if the encoder returned a bitstream */
+      if (stream_len != 0) break;
+    }
+
+    /* make coded sequence to short be inreasing */
+    /* the length the decoder expects */
+    if (testNum == 4) {
+      stream_len += 10;
+    }
+
+    /* make coded sequence to long be decreasing */
+    /* the length the decoder expects */
+    if (testNum == 5) {
+      stream_len -= 10;
+    }
+
+    if (testNum == 6) {
+      srand(time(NULL));
+      for (i = 0; i < stream_len; i++ ) {
+        streamdata[i] = rand();
+      }
+    }
+
+    /* set pointer to beginning of file */
+    if (fp_gns != NULL) {
+      if (fscanf(fp_gns, "%d", &cur_delay) == EOF) {
+        fseek(fp_gns, 0L, SEEK_SET);
+        if (fscanf(fp_gns, "%d", &cur_delay) == EOF) {
+          exit(0);
+        }
+      }
+    }
+
+    /* simulate packet handling through NetEq and the modem */
+    if (!(testNum == 3 && framecnt == 0)) {
+      if (gns == 0) {
+        get_arrival_time(cur_framesmpls, stream_len, bottleneck,
+                         &BN_data);
+      } else {
+        get_arrival_time2(cur_framesmpls, cur_delay, &BN_data);
+      }
+    }
+
+    /* packet not dropped */
+    if (cur_delay != -1) {
+
+      /* Error test number 10, garbage data */
+      if (testNum == 10) {
+        for ( i = 0; i < stream_len; i++) {
+          streamdata[i] = (short) (streamdata[i] + (short) rand());
+        }
+      }
+
+      if (testNum != 9) {
+        err = WebRtcIsacfix_UpdateBwEstimate(ISAC_main_inst,
+                                             streamdata,
+                                             stream_len,
+                                             BN_data.rtp_number,
+                                             BN_data.send_time,
+                                             BN_data.arrival_time);
+
+        if (err < 0) {
+          /* exit if returned with error */
+          errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+          printf("\nError in decoder: %d.\n", errtype);
+        }
+      }
+#ifdef _DEBUG
+      fprintf(stderr,"  \rframe = %7d", framecnt);
+#endif
+
+      if( readLoss == 1 ) {
+        if( fread( &lostFrame, sizeof(WebRtc_Word16), 1, plFile ) != 1 ) {
+          rewind( plFile );
+        }
+        lostFrame = !lostFrame;
+      } else {
+        lostFrame = (rand()%100 < packetLossPercent);
+      }
+
+
+
+      /* iSAC decoding */
+      if( lostFrame && framecnt >  0) {
+        if (nbTest !=2) {
+          declen = WebRtcIsacfix_DecodePlc(ISAC_main_inst,
+                                           decoded, prevFrameSize );
+        } else {
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+          declen = WebRtcIsacfix_DecodePlcNb(ISAC_main_inst, decoded,
+                                             prevFrameSize );
+#else
+          declen = -1;
+#endif
+        }
+        lostPackets++;
+      } else {
+        if (nbTest !=2 ) {
+          short FL;
+          /* Call getFramelen, only used here for function test */
+          err = WebRtcIsacfix_ReadFrameLen((WebRtc_Word16*)streamdata, &FL);
+          declen = WebRtcIsacfix_Decode( ISAC_main_inst, streamdata, stream_len,
+                                         decoded, speechType );
+          /* Error check */
+          if (err<0 || declen<0 || FL!=declen) {
+            errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+            printf("\nError in decode_B/or getFrameLen: %d.\n", errtype);
+          }
+          prevFrameSize = declen/480;
+
+        } else {
+#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
+          declen = WebRtcIsacfix_DecodeNb( ISAC_main_inst, streamdata,
+                                           stream_len, decoded, speechType );
+#else
+          declen = -1;
+#endif
+          prevFrameSize = declen/240;
+        }
+      }
+
+      if (declen <= 0) {
+        /* exit if returned with error */
+        errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
+        printf("\nError in decoder: %d.\n", errtype);
+      }
+
+      /* Write decoded speech frame to file */
+      if (fwrite(decoded, sizeof(WebRtc_Word16),
+                 declen, outp) != (size_t)declen) {
+        return -1;
+      }
+      //   fprintf( ratefile, "%f \n", stream_len / ( ((double)declen)/
+      // ((double)FS) ) * 8 );
+    } else {
+      lostPackets++;
+    }
+    framecnt++;
+
+    totalsmpls += declen;
+    totalbits += 8 * stream_len;
+    kbps = ((double) FS) / ((double) cur_framesmpls) * 8.0 *
+        stream_len / 1000.0;// kbits/s
+
+    /* Error test number 10, garbage data */
+    if (testNum == 10) {
+      if ( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) {
+        printf( "Error: Could not open file %s\n", SEED_FILE);
+      }
+      else {
+        fprintf(seedfile, "ok\n\n");
+        fclose(seedfile);
+      }
+    }
+
+#ifdef _DEBUG
+
+    fy = fopen("bit_rate.dat", "a");
+    fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
+    fclose(fy);
+
+#endif /* _DEBUG */
+
+  }
+  printf("\nLost Frames %d ~ %4.1f%%\n", lostPackets,
+         (double)lostPackets/(double)framecnt*100.0 );
+  printf("\n\ntotal bits                          = %d bits", totalbits);
+  printf("\nmeasured average bitrate              = %0.3f kbits/s",
+         (double)totalbits *(FS/1000) / totalsmpls);
+  printf("\n");
+
+#ifdef _DEBUG
+  /* fprintf(stderr,"\n\ntotal bits    = %d bits", totalbits);
+     fprintf(stderr,"\nmeasured average bitrate  = %0.3f kbits/s",
+     (double)totalbits *(FS/1000) / totalsmpls);
+     fprintf(stderr,"\n");
+  */
+#endif /* _DEBUG */
+
+  /* Runtime statistics */
+
+
+  runtime = (double)(((double)clock()/(double)CLOCKS_PER_SEC)-starttime);
+  length_file = ((double)framecnt*(double)declen/FS);
+  printf("\n\nLength of speech file: %.1f s\n", length_file);
+  printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n",
+         runtime, (100*runtime/length_file));
+  printf("\n\n_______________________________________________\n");
+
+  fclose(inp);
+  fclose(outp);
+  fclose(outbits);
+
+  if ( testCE == 1) {
+    WebRtcIsacfix_FreeInternal(ISAC_main_inst);
+  }
+  WebRtcIsacfix_Free(ISAC_main_inst);
+  return 0;
+}
diff --git a/src/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c b/src/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c
new file mode 100644
index 0000000..57c30ca
--- /dev/null
+++ b/src/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c
@@ -0,0 +1,693 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * test_iSACfixfloat.c
+ *
+ * Test compatibility and quality between floating- and fixed-point code
+ * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* include API */
+#include "isac.h"
+#include "isacfix.h"
+
+
+/* max number of samples per frame (= 60 ms frame) */
+#define MAX_FRAMESAMPLES				960
+/* number of samples per 10ms frame */
+#define FRAMESAMPLES_10ms				160
+/* sampling frequency (Hz) */
+#define FS								16000
+
+
+
+/* Runtime statistics */
+#include <time.h>
+#define CLOCKS_PER_SEC  1000
+
+
+
+//	FILE *histfile, *ratefile;
+
+
+/* function for reading audio data from PCM file */
+int readframe(WebRtc_Word16 *data, FILE *inp, int length) {
+	
+	short k, rlen, status = 0;
+		
+	rlen = fread(data, sizeof(WebRtc_Word16), length, inp);
+	if (rlen < length) {
+		for (k = rlen; k < length; k++)
+			data[k] = 0;
+		status = 1;
+	}
+	
+	return status;
+}
+
+typedef struct {
+	WebRtc_UWord32 send_time;            /* samples */
+	WebRtc_UWord32 arrival_time;            /* samples */
+	WebRtc_UWord32 sample_count;            /* samples */
+	WebRtc_UWord16 rtp_number;
+} BottleNeckModel;
+
+void get_arrival_time(int current_framesamples,   /* samples */
+					  int packet_size,            /* bytes */
+					  int bottleneck,             /* excluding headers; bits/s */
+					  BottleNeckModel *BN_data)
+{
+	const int HeaderSize = 35; 
+	int HeaderRate;
+
+	HeaderRate = HeaderSize * 8 * FS / current_framesamples;     /* bits/s */
+
+	/* everything in samples */
+	BN_data->sample_count = BN_data->sample_count + current_framesamples;
+
+	BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate);
+	BN_data->send_time += current_framesamples;
+
+	if (BN_data->arrival_time < BN_data->sample_count)
+		BN_data->arrival_time = BN_data->sample_count;
+
+	BN_data->rtp_number++;
+}
+
+
+
+int main(int argc, char* argv[])
+{
+
+	char inname[50], outname[50], bottleneck_file[50], bitfilename[60], bitending[10]="_bits.pcm";	
+	FILE *inp, *outp, *f_bn, *bitsp;
+	int framecnt, endfile;
+
+
+	int i,j,errtype, plc=0;
+	WebRtc_Word16 CodingMode;
+	WebRtc_Word16 bottleneck;
+
+	WebRtc_Word16 framesize = 30;           /* ms */
+    //WebRtc_Word16 framesize = 60; /* To invoke cisco complexity case at frame 2252 */
+	
+	int cur_framesmpls, err;
+	
+	/* Runtime statistics */
+	double starttime;
+	double runtime;
+	double length_file;
+	
+	WebRtc_Word16 stream_len = 0;
+	WebRtc_Word16 declen;
+	
+	WebRtc_Word16 shortdata[FRAMESAMPLES_10ms];
+	WebRtc_Word16 decoded[MAX_FRAMESAMPLES];
+	WebRtc_UWord16 streamdata[600];
+	WebRtc_Word16	speechType[1];
+	
+//	WebRtc_Word16	*iSACstruct;
+
+	char version_number[20];
+	int mode=-1, tmp, nbTest=0; /*,sss;*/
+
+#ifdef _DEBUG
+	FILE *fy;
+	double kbps;
+	int totalbits =0;
+	int totalsmpls =0;
+#endif /* _DEBUG */
+
+
+
+
+	/* only one structure used for ISAC encoder */
+	ISAC_MainStruct *ISAC_main_inst;
+	ISACFIX_MainStruct *ISACFIX_main_inst;
+
+	BottleNeckModel       BN_data;
+	f_bn  = NULL;
+
+#ifdef _DEBUG
+	fy = fopen("bit_rate.dat", "w");
+	fclose(fy);
+	fy = fopen("bytes_frames.dat", "w");
+	fclose(fy);
+#endif /* _DEBUG */
+
+
+//histfile = fopen("histo.dat", "ab");
+//ratefile = fopen("rates.dat", "ab");
+
+	/* handling wrong input arguments in the command line */
+	if ((argc<6) || (argc>10))  {
+		printf("\n\nWrong number of arguments or flag values.\n\n");
+
+		printf("\n");
+		WebRtcIsacfix_version(version_number);
+		printf("iSAC version %s \n\n", version_number);
+
+		printf("Usage:\n\n");
+		printf("./kenny.exe [-I] bottleneck_value infile outfile \n\n");
+		printf("with:\n");
+
+		printf("[-I]			:	if -I option is specified, the coder will use\n");
+		printf("				an instantaneous Bottleneck value. If not, it\n");
+		printf("				will be an adaptive Bottleneck value.\n\n");
+		printf("bottleneck_value	:	the value of the bottleneck provided either\n");
+		printf("				as a fixed value (e.g. 25000) or\n");
+		printf("				read from a file (e.g. bottleneck.txt)\n\n");
+		printf("[-m] mode		: Mode (encoder - decoder):\n");
+		printf("				:		0 - float - float \n");
+		printf("				:		1 - float - fix \n");
+		printf("				:		2 - fix - float \n");
+		printf("				:		3 - fix - fix \n");
+		printf("[-PLC]	 		:	Test PLC packetlosses\n");
+		printf("[-NB] num		:	Test NB interfaces, num=1 encNB, num=2 decNB\n");
+		printf("infile			:	Normal speech input file\n\n");
+		printf("outfile			:	Speech output file\n\n");
+		printf("Example usage:\n\n");
+		printf("./kenny.exe -I bottleneck.txt -m 1 speechIn.pcm speechOut.pcm\n\n");
+		exit(0);
+
+	} 
+	
+	
+	printf("--------------------START---------------------\n\n");
+	WebRtcIsac_version(version_number);
+	printf("iSAC FLOAT version %s \n", version_number);
+	WebRtcIsacfix_version(version_number);
+	printf("iSAC FIX version   %s \n\n", version_number);
+
+	CodingMode = 0;
+	tmp=1;
+	for (i = 1; i < argc;i++)
+	{
+		if (!strcmp ("-I", argv[i]))
+		{
+			printf("\nInstantaneous BottleNeck\n");
+			CodingMode = 1;
+			i++;
+			tmp=0;
+		} 
+
+		if (!strcmp ("-m", argv[i])) {
+			mode=atoi(argv[i+1]);
+			i++;
+		}		
+
+		if (!strcmp ("-PLC", argv[i]))
+		{
+			plc=1;
+		}
+		
+		if (!strcmp ("-NB", argv[i]))
+		{
+			nbTest = atoi(argv[i + 1]);
+			i++;
+		}
+			  
+	}
+	
+	if(mode<0) {
+		printf("\nError! Mode must be set: -m 0 \n");
+		exit(0);
+	}
+	
+	if (CodingMode == 0)
+	{
+		printf("\nAdaptive BottleNeck\n");
+	}
+
+
+
+	/* Get Bottleneck value */
+	bottleneck = atoi(argv[2-tmp]);
+	if (bottleneck == 0)
+	{
+		sscanf(argv[2-tmp], "%s", bottleneck_file);
+		f_bn = fopen(bottleneck_file, "rb");
+		if (f_bn  == NULL)
+		{
+			printf("No value provided for BottleNeck and cannot read file %s.\n", bottleneck_file);
+			exit(0);
+		}
+		else {
+			printf("reading bottleneck rates from file %s\n\n",bottleneck_file);
+			if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
+					/* Set pointer to beginning of file */
+					fseek(f_bn, 0L, SEEK_SET);
+					fscanf(f_bn, "%d", &bottleneck);
+			}		
+
+			/*	Bottleneck is a cosine function 
+			*	Matlab code for writing the bottleneck file:
+			*	BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
+			*	fid = fopen('bottleneck.txt', 'wb');
+			*	fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
+			*/
+		}
+	}
+	else 
+	{
+		printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
+	}
+
+
+
+	/* Get Input and Output files */
+	sscanf(argv[argc-2], "%s", inname);
+	sscanf(argv[argc-1], "%s", outname);
+	
+	if ((inp = fopen(inname,"rb")) == NULL) {
+		printf("  iSAC: Cannot read file %s.\n", inname);
+		exit(1);
+	}
+	if ((outp = fopen(outname,"wb")) == NULL) {
+		printf("  iSAC: Cannot write file %s.\n", outname);
+		exit(1);
+	}
+	printf("\nInput:%s\nOutput:%s\n", inname, outname);
+
+	i=0;
+	while (outname[i]!='\0') {
+		bitfilename[i]=outname[i];
+		i++;
+	}
+	i-=4;
+	for (j=0;j<9;j++, i++)
+		bitfilename[i]=bitending[j];
+	bitfilename[i]='\0';
+	if ((bitsp = fopen(bitfilename,"wb")) == NULL) {
+		printf("  iSAC: Cannot read file %s.\n", bitfilename);
+		exit(1);
+	}
+	printf("Bitstream:%s\n\n", bitfilename);
+
+
+	
+	starttime = clock()/(double)CLOCKS_PER_SEC; /* Runtime statistics */
+
+
+	/* Initialize the ISAC and BN structs */
+	WebRtcIsac_create(&ISAC_main_inst);
+/*	WebRtcIsacfix_AssignSize(&sss);
+	iSACstruct=malloc(sss);
+	WebRtcIsacfix_Assign(&ISACFIX_main_inst,iSACstruct);*/
+	WebRtcIsacfix_Create(&ISACFIX_main_inst);
+	
+	BN_data.send_time	  = 0;
+	BN_data.arrival_time  = 0;
+	BN_data.sample_count  = 0;
+	BN_data.rtp_number    = 0;
+	
+	/* Initialize encoder and decoder */
+    framecnt= 0;
+    endfile	= 0;
+
+	if (mode==0) { /* Encode using FLOAT, decode using FLOAT */
+
+		printf("Coding mode: Encode using FLOAT, decode using FLOAT \n\n");
+
+		/* Init iSAC FLOAT */
+		WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
+		WebRtcIsac_DecoderInit(ISAC_main_inst);
+		if (CodingMode == 1) {
+			err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+			//	exit(EXIT_FAILURE);
+			}
+		}
+	
+	} else if (mode==1) { /* Encode using FLOAT, decode using FIX */
+
+		printf("Coding mode: Encode using FLOAT, decode using FIX \n\n");
+
+		/* Init iSAC FLOAT */
+		WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
+		WebRtcIsac_DecoderInit(ISAC_main_inst);
+		if (CodingMode == 1) {
+			err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+			//	exit(EXIT_FAILURE);
+			}
+		}
+
+		/* Init iSAC FIX */
+		WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
+		WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
+		if (CodingMode == 1) {
+			err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		}
+	} else if (mode==2) { /* Encode using FIX, decode using FLOAT */
+
+		printf("Coding mode: Encode using FIX, decode using FLOAT \n\n");
+
+		/* Init iSAC FLOAT */
+		WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
+		WebRtcIsac_DecoderInit(ISAC_main_inst);
+		if (CodingMode == 1) {
+			err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		}
+		
+		/* Init iSAC FIX */
+		WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
+		WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
+		if (CodingMode == 1) {
+			err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		}
+	} else if (mode==3) {
+
+		printf("Coding mode: Encode using FIX, decode using FIX \n\n");
+
+		WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
+		WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
+		if (CodingMode == 1) {
+			err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\n Error in initialization: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		}
+
+	} else
+		printf("Mode must be value between 0 and 3\n");
+	*speechType = 1;
+
+//#define BI_TEST 1
+#ifdef BI_TEST
+    err = WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_main_inst, 300);
+    if (err < 0) {
+            /* exit if returned with error */
+            errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+            printf("\n\n Error in setMaxPayloadSize: %d.\n\n", errtype);
+            fclose(inp);
+            fclose(outp);
+            fclose(bitsp);
+            return(EXIT_FAILURE);
+    }
+#endif
+
+
+    while (endfile == 0) {	
+
+		cur_framesmpls = 0;
+		while (1) {
+			/* Read 10 ms speech block */
+			if (nbTest != 1)
+				endfile = readframe(shortdata, inp, FRAMESAMPLES_10ms);
+			else
+				endfile = readframe(shortdata, inp, (FRAMESAMPLES_10ms/2));
+
+			/* iSAC encoding */
+
+			if (mode==0 || mode ==1) {
+				stream_len = WebRtcIsac_Encode(ISAC_main_inst, shortdata,	streamdata);
+				if (stream_len < 0) {
+					/* exit if returned with error */
+					errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+					printf("\n\nError in encoder: %d.\n\n", errtype);
+				//	exit(EXIT_FAILURE);
+				}
+			} else if (mode==2 || mode==3) {
+				/* iSAC encoding */
+				if (nbTest != 1)
+					stream_len = WebRtcIsacfix_Encode(ISACFIX_main_inst, shortdata,	streamdata);
+				else
+					stream_len = WebRtcIsacfix_EncodeNb(ISACFIX_main_inst, shortdata, streamdata);
+		
+				if (stream_len < 0) {
+					/* exit if returned with error */
+					errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+					printf("\n\nError in encoder: %d.\n\n", errtype);
+				//	exit(EXIT_FAILURE);
+				}
+			}			
+
+			cur_framesmpls += FRAMESAMPLES_10ms;
+
+			/* read next bottleneck rate */
+			if (f_bn != NULL) {
+				if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
+					/* Set pointer to beginning of file */
+					fseek(f_bn, 0L, SEEK_SET);
+					fscanf(f_bn, "%d", &bottleneck);
+				}
+				if (CodingMode == 1) {
+					if (mode==0 || mode==1)
+					  WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
+					else if	(mode==2 || mode==3)
+						WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
+				}
+			}
+
+			/* exit encoder loop if the encoder returned a bitstream */
+			if (stream_len != 0) break;
+		}
+		
+		fwrite(streamdata, 1, stream_len, bitsp); /* NOTE! Writes bytes to file */
+
+		/* simulate packet handling through NetEq and the modem */
+		get_arrival_time(cur_framesmpls, stream_len, bottleneck,
+						 &BN_data);
+//*****************************
+		if (1){
+		if (mode==0) {
+			err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst,
+									  streamdata,
+									  stream_len,
+									  BN_data.rtp_number,
+									  BN_data.arrival_time);
+
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+			/* iSAC decoding */
+			declen = WebRtcIsac_Decode(ISAC_main_inst,
+										  streamdata,
+									  	  stream_len,
+										  decoded,
+										  speechType);
+			if (declen <= 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		} else if (mode==1) {
+
+			err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst,
+									  streamdata,
+									  stream_len,
+									  BN_data.rtp_number,
+									  BN_data.arrival_time);
+			err = WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_main_inst,
+									  streamdata,
+									  stream_len,
+									  BN_data.rtp_number,
+									  BN_data.arrival_time);
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+
+			declen = WebRtcIsac_Decode(ISAC_main_inst,
+										  streamdata,
+									  	  stream_len,
+										  decoded,
+										  speechType);
+
+			/* iSAC decoding */
+			if (plc && (framecnt+1)%10 == 0) {
+				if (nbTest !=2 )
+					declen = WebRtcIsacfix_DecodePlc( ISACFIX_main_inst, decoded, 1 );
+				else
+					declen = WebRtcIsacfix_DecodePlcNb( ISACFIX_main_inst, decoded, 1 );
+			} else {
+				if (nbTest !=2 )
+					declen = WebRtcIsacfix_Decode(ISACFIX_main_inst,
+												  streamdata,
+											  	  stream_len,
+												  decoded,
+												  speechType);
+				else
+					declen = WebRtcIsacfix_DecodeNb(ISACFIX_main_inst,
+												  streamdata,
+											  	  stream_len,
+												  decoded,
+												  speechType);
+			}
+			
+			if (declen <= 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		} else if (mode==2) {
+			err = WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_main_inst,
+									  streamdata,
+									  stream_len,
+									  BN_data.rtp_number,
+									  BN_data.arrival_time);
+
+			err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst,
+									  streamdata,
+									  stream_len,
+									  BN_data.rtp_number,
+									  BN_data.arrival_time);
+
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+			/* iSAC decoding */
+			declen = WebRtcIsac_Decode(ISAC_main_inst,
+										  streamdata,
+									  	  stream_len,
+										  decoded,
+										  speechType);
+			if (declen <= 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsac_GetErrorCode(ISAC_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		}  else if (mode==3) {
+			err = WebRtcIsacfix_UpdateBwEstimate(ISACFIX_main_inst,
+									  streamdata,
+									  stream_len,
+									  BN_data.rtp_number,
+									  BN_data.send_time,
+									  BN_data.arrival_time);
+
+			if (err < 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+			/* iSAC decoding */
+						
+			if (plc && (framecnt+1)%10 == 0) {
+				if (nbTest !=2 )
+					declen = WebRtcIsacfix_DecodePlc( ISACFIX_main_inst, decoded, 1 );
+				else
+					declen = WebRtcIsacfix_DecodePlcNb( ISACFIX_main_inst, decoded, 1 );
+			} else {
+				if (nbTest !=2 )
+					declen = WebRtcIsacfix_Decode(ISACFIX_main_inst,
+												  streamdata,
+											  	  stream_len,
+												  decoded,
+												  speechType);
+				else
+					declen = WebRtcIsacfix_DecodeNb(ISACFIX_main_inst,
+												  streamdata,
+											  	  stream_len,
+												  decoded,
+												  speechType);
+			}
+			if (declen <= 0) {
+				/* exit if returned with error */
+				errtype=WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
+				printf("\n\nError in decoder: %d.\n\n", errtype);
+				//exit(EXIT_FAILURE);
+			}
+		}
+
+		/* Write decoded speech frame to file */
+		fwrite(decoded, sizeof(WebRtc_Word16), declen, outp);
+		}
+
+		fprintf(stderr,"  \rframe = %d", framecnt);
+		framecnt++;
+
+
+
+#ifdef _DEBUG
+		
+		totalsmpls += declen;
+		totalbits += 8 * stream_len;
+		kbps = ((double) FS) / ((double) cur_framesmpls) * 8.0 * stream_len / 1000.0;// kbits/s
+		fy = fopen("bit_rate.dat", "a");
+		fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
+		fclose(fy);
+		
+#endif /* _DEBUG */
+	
+	}
+	
+#ifdef _DEBUG
+	printf("\n\ntotal bits				= %d bits", totalbits);
+	printf("\nmeasured average bitrate		= %0.3f kbits/s", (double)totalbits *(FS/1000) / totalsmpls);
+	printf("\n");
+#endif /* _DEBUG */
+	
+	/* Runtime statistics */
+	runtime = (double)(clock()/(double)CLOCKS_PER_SEC-starttime);
+	length_file = ((double)framecnt*(double)declen/FS);
+	printf("\n\nLength of speech file: %.1f s\n", length_file);
+	printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime, (100*runtime/length_file));
+	printf("---------------------END----------------------\n");
+	
+	fclose(inp);
+	fclose(outp);
+	
+	WebRtcIsac_Free(ISAC_main_inst);
+	WebRtcIsacfix_Free(ISACFIX_main_inst);
+
+	
+
+//	fclose(histfile);
+//	fclose(ratefile);
+	
+	return 0;
+
+}	
+
+
diff --git a/src/system_wrappers/interface/atomic32.h b/src/system_wrappers/interface/atomic32.h
new file mode 100644
index 0000000..e2b1258
--- /dev/null
+++ b/src/system_wrappers/interface/atomic32.h
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+// Atomic, system independent 32-bit integer.  Unless you know what you're
+// doing, use locks instead! :-)
+//
+// Note: uses full memory barriers.
+// Note: assumes 32-bit (or higher) system
+#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_H_
+#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_H_
+
+#include <cstddef>
+
+#include "common_types.h"
+#include "constructor_magic.h"
+
+namespace webrtc {
+
+// 32 bit atomic variable.  Note that this class relies on the compiler to
+// align the 32 bit value correctly (on a 32 bit boundary), so as long as you're
+// not doing things like reinterpret_cast over some custom allocated memory
+// without being careful with alignment, you should be fine.
+class Atomic32
+{
+public:
+    Atomic32(WebRtc_Word32 initialValue = 0);
+    ~Atomic32();
+
+    // Prefix operator!
+    WebRtc_Word32 operator++();
+    WebRtc_Word32 operator--();
+
+    WebRtc_Word32 operator+=(WebRtc_Word32 value);
+    WebRtc_Word32 operator-=(WebRtc_Word32 value);
+
+    // Sets the value atomically to newValue if the value equals compare value.
+    // The function returns true if the exchange happened.
+    bool CompareExchange(WebRtc_Word32 newValue, WebRtc_Word32 compareValue);
+    WebRtc_Word32 Value() const;
+
+private:
+    // Disable the + and - operator since it's unclear what these operations
+    // should do.
+    Atomic32 operator+(const Atomic32& other);
+    Atomic32 operator-(const Atomic32& other);
+
+    // Checks if |_value| is 32bit aligned.
+    inline bool Is32bitAligned() const {
+      return (reinterpret_cast<ptrdiff_t>(&_value) & 3) == 0;
+    }
+
+    DISALLOW_COPY_AND_ASSIGN(Atomic32);
+
+    WebRtc_Word32 _value;
+};
+}  // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_H_
diff --git a/src/system_wrappers/interface/atomic32_wrapper.h b/src/system_wrappers/interface/atomic32_wrapper.h
deleted file mode 100644
index 40862fb..0000000
--- a/src/system_wrappers/interface/atomic32_wrapper.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// Atomic system independant 32-bit integer.
-// Note: uses full memory barriers.
-// Note: assumes 32-bit (or higher) system
-#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_
-#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_
-
-#include "common_types.h"
-
-namespace webrtc {
-class Atomic32Impl;
-class Atomic32Wrapper
-{
-public:
-    Atomic32Wrapper(WebRtc_Word32 initialValue = 0);
-    ~Atomic32Wrapper();
-
-    // Prefix operator!
-    WebRtc_Word32 operator++();
-    WebRtc_Word32 operator--();
-
-    Atomic32Wrapper& operator=(const Atomic32Wrapper& rhs);
-    Atomic32Wrapper& operator=(WebRtc_Word32 rhs);
-
-    WebRtc_Word32 operator+=(WebRtc_Word32 rhs);
-    WebRtc_Word32 operator-=(WebRtc_Word32 rhs);
-
-    // Sets the value atomically to newValue if the value equals compare value.
-    // The function returns true if the exchange happened.
-    bool CompareExchange(WebRtc_Word32 newValue, WebRtc_Word32 compareValue);
-    WebRtc_Word32 Value() const;
-private:
-    // Disable the + and - operator since it's unclear what these operations
-    // should do.
-    Atomic32Wrapper operator+(const Atomic32Wrapper& rhs);
-    Atomic32Wrapper operator-(const Atomic32Wrapper& rhs);
-
-    WebRtc_Word32& operator++(int);
-    WebRtc_Word32& operator--(int);
-
-    // Cheshire cat to hide the implementation (faster than
-    // using virtual functions)
-    Atomic32Impl& _impl;
-};
-} // namespace webrtc
-#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ATOMIC32_WRAPPER_H_
diff --git a/src/system_wrappers/interface/compile_assert.h b/src/system_wrappers/interface/compile_assert.h
new file mode 100644
index 0000000..4feda86
--- /dev/null
+++ b/src/system_wrappers/interface/compile_assert.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
+#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
+
+/* Use this macro to verify at compile time that certain restrictions are met.
+ * The argument is the boolean expression to evaluate.
+ * Example:
+ *   COMPILE_ASSERT(sizeof(foo) < 128);
+*/
+#define COMPILE_ASSERT(expression) switch(0){case 0: case expression:;}
+
+#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
diff --git a/src/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h b/src/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h
new file mode 100644
index 0000000..d85c724
--- /dev/null
+++ b/src/system_wrappers/interface/fix_interlocked_exchange_pointer_win.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file under third_party_mods/chromium directory of
+// source tree or at
+// http://src.chromium.org/viewvc/chrome/trunk/src/LICENSE
+
+// Various inline functions and macros to fix compilation of 32 bit target
+// on MSVC with /Wp64 flag enabled.
+
+// The original code can be found here:
+// http://src.chromium.org/svn/trunk/src/base/fix_wp64.h
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_
+
+#include <windows.h>
+
+// Platform SDK fixes when building with /Wp64 for a 32 bits target.
+#if !defined(_WIN64) && defined(_Wp64)
+
+#ifdef InterlockedExchangePointer
+#undef InterlockedExchangePointer
+// The problem is that the macro provided for InterlockedExchangePointer() is
+// doing a (LONG) C-style cast that triggers invariably the warning C4312 when
+// building on 32 bits.
+inline void* InterlockedExchangePointer(void* volatile* target, void* value) {
+  return reinterpret_cast<void*>(static_cast<LONG_PTR>(InterlockedExchange(
+      reinterpret_cast<volatile LONG*>(target),
+      static_cast<LONG>(reinterpret_cast<LONG_PTR>(value)))));
+}
+#endif  // #ifdef InterlockedExchangePointer
+
+#endif // #if !defined(_WIN64) && defined(_Wp64)
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_FIX_INTERLOCKED_EXCHANGE_POINTER_WINDOWS_H_
diff --git a/src/system_wrappers/interface/ref_count.h b/src/system_wrappers/interface/ref_count.h
index f90b0b3..5112bd9 100644
--- a/src/system_wrappers/interface/ref_count.h
+++ b/src/system_wrappers/interface/ref_count.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -11,7 +11,7 @@
 #ifndef SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_
 #define SYSTEM_WRAPPERS_INTERFACE_REF_COUNT_H_
 
-#include "system_wrappers/interface/atomic32_wrapper.h"
+#include "system_wrappers/interface/atomic32.h"
 
 namespace webrtc {
 
@@ -74,7 +74,7 @@
   }
 
  protected:
-  Atomic32Wrapper ref_count_;
+  Atomic32 ref_count_;
 };
 
 }  // namespace webrtc
diff --git a/src/system_wrappers/interface/sleep.h b/src/system_wrappers/interface/sleep.h
new file mode 100644
index 0000000..c0205bf
--- /dev/null
+++ b/src/system_wrappers/interface/sleep.h
@@ -0,0 +1,24 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+// An OS-independent sleep function.
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SLEEP_H_
+#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SLEEP_H_
+
+namespace webrtc {
+
+// This function sleeps for the specified number of milliseconds.
+// It may return early if the thread is woken by some other event,
+// such as the delivery of a signal on Unix.
+void SleepMs(int msecs);
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SLEEP_H_
diff --git a/src/system_wrappers/interface/static_instance.h b/src/system_wrappers/interface/static_instance.h
index 8fe91cc..b670f96 100644
--- a/src/system_wrappers/interface/static_instance.h
+++ b/src/system_wrappers/interface/static_instance.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -128,10 +128,8 @@
     // local copy.
     T* new_instance = T::CreateInstance();
     if (1 == InterlockedIncrement(&instance_count)) {
-      T* old_value = static_cast<T*> (InterlockedExchangePointer(
-          reinterpret_cast<void* volatile*>(&instance), new_instance));
-      assert(old_value == NULL);
-      assert(instance);
+      InterlockedExchangePointer(reinterpret_cast<void* volatile*>(&instance),
+                                 new_instance);
     } else {
       InterlockedDecrement(&instance_count);
       if (new_instance) {
diff --git a/src/system_wrappers/interface/thread_wrapper.h b/src/system_wrappers/interface/thread_wrapper.h
index 72a06e8..030ac8a 100644
--- a/src/system_wrappers/interface/thread_wrapper.h
+++ b/src/system_wrappers/interface/thread_wrapper.h
@@ -16,6 +16,9 @@
 #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_THREAD_WRAPPER_H_
 
+#include "common_types.h"
+#include "typedefs.h"
+
 namespace webrtc {
 // Object that will be passed by the spawned thread when it enters the callback
 // function.
@@ -51,9 +54,12 @@
     // threadName  NULL terminated thread name, will be visable in the Windows
     //             debugger.
     static ThreadWrapper* CreateThread(ThreadRunFunction func = 0,
-                                    ThreadObj obj= 0,
-                                    ThreadPriority prio = kNormalPriority,
-                                    const char* threadName = 0);
+                                       ThreadObj obj= 0,
+                                       ThreadPriority prio = kNormalPriority,
+                                       const char* threadName = 0);
+
+    // Get the current thread's kernel thread ID.
+    static uint32_t GetThreadId();
 
     // Non blocking termination of the spawned thread. Note that it is not safe
     // to delete this class until the spawned thread has been reclaimed.
@@ -69,8 +75,9 @@
     // should be lower than (number of CPUs - 1). amountOfProcessors should be
     // equal to the number of processors listed in processorNumbers
     virtual bool SetAffinity(const int* /*processorNumbers*/,
-                             const unsigned int /*amountOfProcessors*/)
-                            {return false;}
+                             const unsigned int /*amountOfProcessors*/) {
+      return false;
+    }
 
     // Stops the spawned thread and waits for it to be reclaimed with a timeout
     // of two seconds. Will return false if the thread was not reclaimed.
diff --git a/src/system_wrappers/interface/tick_util.h b/src/system_wrappers/interface/tick_util.h
index e78e53d..0cd85d0 100644
--- a/src/system_wrappers/interface/tick_util.h
+++ b/src/system_wrappers/interface/tick_util.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -19,6 +19,9 @@
 #include <mmsystem.h>
 #elif WEBRTC_LINUX
 #include <ctime>
+#elif WEBRTC_MAC
+#include <mach/mach_time.h>
+#include <string.h>
 #else
 #include <sys/time.h>
 #include <time.h>
@@ -133,6 +136,7 @@
 {
     TickTime result;
 #if _WIN32
+    // TODO(wu): Remove QueryPerformanceCounter implementation.
     #ifdef USE_QUERY_PERFORMANCE_COUNTER
         // QueryPerformanceCounter returns the value from the TSC which is
         // incremented at the CPU frequency. The algorithm used requires
@@ -164,12 +168,27 @@
     #endif
 #elif defined(WEBRTC_LINUX)
     struct timespec ts;
+    // TODO(wu): Remove CLOCK_REALTIME implementation.
     #ifdef WEBRTC_CLOCK_TYPE_REALTIME
         clock_gettime(CLOCK_REALTIME, &ts);
     #else
         clock_gettime(CLOCK_MONOTONIC, &ts);
     #endif
     result._ticks = 1000000000LL * static_cast<WebRtc_Word64>(ts.tv_sec) + static_cast<WebRtc_Word64>(ts.tv_nsec);
+#elif defined(WEBRTC_MAC)
+    static mach_timebase_info_data_t timebase;
+    if (timebase.denom == 0) {
+      // Get the timebase if this is the first time we run.
+      // Recommended by Apple's QA1398.
+      kern_return_t retval = mach_timebase_info(&timebase);
+      if (retval != KERN_SUCCESS) {
+        // TODO(wu): Implement CHECK similar to chrome for all the platforms.
+        // Then replace this with a CHECK(retval == KERN_SUCCESS);
+        asm("int3");
+      }
+    }
+    // Use timebase to convert absolute time tick units into nanoseconds.
+    result._ticks = mach_absolute_time() * timebase.numer / timebase.denom;
 #else
     struct timeval tv;
     gettimeofday(&tv, NULL);
@@ -189,7 +208,7 @@
     #else
         return now._ticks;
     #endif
-#elif WEBRTC_LINUX
+#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
     return now._ticks / 1000000LL;
 #else
     return now._ticks / 1000LL;
@@ -208,7 +227,7 @@
     #else
         return now._ticks *1000LL;
     #endif
-#elif WEBRTC_LINUX
+#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
     return now._ticks / 1000LL;
 #else
     return now._ticks;
@@ -230,7 +249,7 @@
     #else
         return ms;
     #endif
-#elif WEBRTC_LINUX
+#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
     return ms * 1000000LL;
 #else
     return ms * 1000LL;
@@ -247,7 +266,7 @@
     #else
         return ticks;
     #endif
-#elif WEBRTC_LINUX
+#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
     return ticks / 1000000LL;
 #else
     return ticks / 1000LL;
@@ -280,7 +299,7 @@
 	// _interval is in ms
         return _interval;
     #endif
-#elif WEBRTC_LINUX
+#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
     // _interval is in ns
     return _interval / 1000000;
 #else
@@ -300,7 +319,7 @@
 	// _interval is in ms
         return _interval *1000LL;
     #endif
-#elif WEBRTC_LINUX
+#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
     // _interval is in ns
     return _interval / 1000;
 #else
diff --git a/src/system_wrappers/interface/trace.h b/src/system_wrappers/interface/trace.h
index 8330f7c..f88d23f 100644
--- a/src/system_wrappers/interface/trace.h
+++ b/src/system_wrappers/interface/trace.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -45,11 +45,11 @@
     // Sets the file name. If addFileCounter is false the same file will be
     // reused when it fills up. If it's true a new file with incremented name
     // will be used.
-    static WebRtc_Word32 SetTraceFile(const WebRtc_Word8* fileName,
+    static WebRtc_Word32 SetTraceFile(const char* fileName,
                                       const bool addFileCounter = false);
 
     // Returns the name of the file that the trace is currently writing to.
-    static WebRtc_Word32 TraceFile(WebRtc_Word8 fileName[1024]);
+    static WebRtc_Word32 TraceFile(char fileName[1024]);
 
     // Registers callback to receive trace messages. TODO (hellner)
     // why not use OutStream instead? Why is TraceCallback not defined in this
@@ -70,7 +70,6 @@
                     const TraceModule module,
                     const WebRtc_Word32 id,
                     const char* msg, ...);
-
 };
 } // namespace webrtc
 #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TRACE_H_
diff --git a/src/system_wrappers/source/Android.mk b/src/system_wrappers/source/Android.mk
index 575580a..dee84ca 100644
--- a/src/system_wrappers/source/Android.mk
+++ b/src/system_wrappers/source/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 #
 # Use of this source code is governed by a BSD-style license
 # that can be found in the LICENSE file in the root of the source
@@ -17,15 +17,15 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_SRC_FILES := \
+    android/cpu-features.c \
+    cpu_features_android.c \
     map.cc \
-    rw_lock_generic.cc \
     sort.cc \
     aligned_malloc.cc \
-    atomic32.cc \
+    atomic32_posix.cc \
     condition_variable.cc \
     cpu_no_op.cc \
     cpu_features.cc \
-    cpu_features_arm.c \
     cpu_info.cc \
     critical_section.cc \
     event.cc \
@@ -38,6 +38,7 @@
     cpu_linux.cc \
     critical_section_posix.cc \
     event_posix.cc \
+    sleep.cc \
     thread_posix.cc \
     trace_posix.cc \
     rw_lock_posix.cc 
diff --git a/src/system_wrappers/source/android/cpu-features.c b/src/system_wrappers/source/android/cpu-features.c
new file mode 100644
index 0000000..6a5cd8f
--- /dev/null
+++ b/src/system_wrappers/source/android/cpu-features.c
@@ -0,0 +1,396 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <sys/system_properties.h>
+#ifdef __arm__
+#include <machine/cpu-features.h>
+#endif
+#include <pthread.h>
+#include "cpu-features.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static  pthread_once_t     g_once;
+static  AndroidCpuFamily   g_cpuFamily;
+static  uint64_t           g_cpuFeatures;
+static  int                g_cpuCount;
+
+static const int  android_cpufeatures_debug = 0;
+
+#ifdef __arm__
+#  define DEFAULT_CPU_FAMILY  ANDROID_CPU_FAMILY_ARM
+#elif defined __i386__
+#  define DEFAULT_CPU_FAMILY  ANDROID_CPU_FAMILY_X86
+#else
+#  define DEFAULT_CPU_FAMILY  ANDROID_CPU_FAMILY_UNKNOWN
+#endif
+
+#define  D(...) \
+    do { \
+        if (android_cpufeatures_debug) { \
+            printf(__VA_ARGS__); fflush(stdout); \
+        } \
+    } while (0)
+
+#ifdef __i386__
+static __inline__ void x86_cpuid(int func, int values[4])
+{
+    int a, b, c, d;
+    /* We need to preserve ebx since we're compiling PIC code */
+    /* this means we can't use "=b" for the second output register */
+    __asm__ __volatile__ ( \
+      "push %%ebx\n"
+      "cpuid\n" \
+      "mov %1, %%ebx\n"
+      "pop %%ebx\n"
+      : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+      : "a" (func) \
+    );
+    values[0] = a;
+    values[1] = b;
+    values[2] = c;
+    values[3] = d;
+}
+#endif
+
+/* Read the content of /proc/cpuinfo into a user-provided buffer.
+ * Return the length of the data, or -1 on error. Does *not*
+ * zero-terminate the content. Will not read more
+ * than 'buffsize' bytes.
+ */
+static int
+read_file(const char*  pathname, char*  buffer, size_t  buffsize)
+{
+    int  fd, len;
+
+    fd = open(pathname, O_RDONLY);
+    if (fd < 0)
+        return -1;
+
+    do {
+        len = read(fd, buffer, buffsize);
+    } while (len < 0 && errno == EINTR);
+
+    close(fd);
+
+    return len;
+}
+
+/* Extract the content of a the first occurence of a given field in
+ * the content of /proc/cpuinfo and return it as a heap-allocated
+ * string that must be freed by the caller.
+ *
+ * Return NULL if not found
+ */
+static char*
+extract_cpuinfo_field(char* buffer, int buflen, const char* field)
+{
+    int  fieldlen = strlen(field);
+    char* bufend = buffer + buflen;
+    char* result = NULL;
+    int len, ignore;
+    const char *p, *q;
+
+    /* Look for first field occurence, and ensures it starts the line.
+     */
+    p = buffer;
+    bufend = buffer + buflen;
+    for (;;) {
+        p = memmem(p, bufend-p, field, fieldlen);
+        if (p == NULL)
+            goto EXIT;
+
+        if (p == buffer || p[-1] == '\n')
+            break;
+
+        p += fieldlen;
+    }
+
+    /* Skip to the first column followed by a space */
+    p += fieldlen;
+    p  = memchr(p, ':', bufend-p);
+    if (p == NULL || p[1] != ' ')
+        goto EXIT;
+
+    /* Find the end of the line */
+    p += 2;
+    q = memchr(p, '\n', bufend-p);
+    if (q == NULL)
+        q = bufend;
+
+    /* Copy the line into a heap-allocated buffer */
+    len = q-p;
+    result = malloc(len+1);
+    if (result == NULL)
+        goto EXIT;
+
+    memcpy(result, p, len);
+    result[len] = '\0';
+
+EXIT:
+    return result;
+}
+
+/* Count the number of occurences of a given field prefix in /proc/cpuinfo.
+ */
+static int
+count_cpuinfo_field(char* buffer, int buflen, const char* field)
+{
+    int fieldlen = strlen(field);
+    const char* p = buffer;
+    const char* bufend = buffer + buflen;
+    const char* q;
+    int count = 0;
+
+    for (;;) {
+        const char* q;
+
+        p = memmem(p, bufend-p, field, fieldlen);
+        if (p == NULL)
+            break;
+
+        /* Ensure that the field is at the start of a line */
+        if (p > buffer && p[-1] != '\n') {
+            p += fieldlen;
+            continue;
+        }
+
+
+        /* skip any whitespace */
+        q = p + fieldlen;
+        while (q < bufend && (*q == ' ' || *q == '\t'))
+            q++;
+
+        /* we must have a colon now */
+        if (q < bufend && *q == ':') {
+            count += 1;
+            q ++;
+        }
+        p = q;
+    }
+
+    return count;
+}
+
+/* Like strlen(), but for constant string literals */
+#define STRLEN_CONST(x)  ((sizeof(x)-1)
+
+
+/* Checks that a space-separated list of items contains one given 'item'.
+ * Returns 1 if found, 0 otherwise.
+ */
+static int
+has_list_item(const char* list, const char* item)
+{
+    const char*  p = list;
+    int itemlen = strlen(item);
+
+    if (list == NULL)
+        return 0;
+
+    while (*p) {
+        const char*  q;
+
+        /* skip spaces */
+        while (*p == ' ' || *p == '\t')
+            p++;
+
+        /* find end of current list item */
+        q = p;
+        while (*q && *q != ' ' && *q != '\t')
+            q++;
+
+        if (itemlen == q-p && !memcmp(p, item, itemlen))
+            return 1;
+
+        /* skip to next item */
+        p = q;
+    }
+    return 0;
+}
+
+
+static void
+android_cpuInit(void)
+{
+    char cpuinfo[4096];
+    int  cpuinfo_len;
+
+    g_cpuFamily   = DEFAULT_CPU_FAMILY;
+    g_cpuFeatures = 0;
+    g_cpuCount    = 1;
+
+    cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo);
+    D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
+      cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);
+
+    if (cpuinfo_len < 0)  /* should not happen */ {
+        return;
+    }
+
+    /* Count the CPU cores, the value may be 0 for single-core CPUs */
+    g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "processor");
+    if (g_cpuCount == 0) {
+        g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "Processor");
+        if (g_cpuCount == 0) {
+            g_cpuCount = 1;
+        }
+    }
+
+    D("found cpuCount = %d\n", g_cpuCount);
+
+#ifdef __ARM_ARCH__
+    {
+        char*  features = NULL;
+        char*  architecture = NULL;
+
+        /* Extract architecture from the "CPU Architecture" field.
+         * The list is well-known, unlike the the output of
+         * the 'Processor' field which can vary greatly.
+         *
+         * See the definition of the 'proc_arch' array in
+         * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
+         * same file.
+         */
+        char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
+
+        if (cpuArch != NULL) {
+            char*  end;
+            long   archNumber;
+            int    hasARMv7 = 0;
+
+            D("found cpuArch = '%s'\n", cpuArch);
+
+            /* read the initial decimal number, ignore the rest */
+            archNumber = strtol(cpuArch, &end, 10);
+
+            /* Here we assume that ARMv8 will be upwards compatible with v7
+                * in the future. Unfortunately, there is no 'Features' field to
+                * indicate that Thumb-2 is supported.
+                */
+            if (end > cpuArch && archNumber >= 7) {
+                hasARMv7 = 1;
+            }
+
+            /* Unfortunately, it seems that certain ARMv6-based CPUs
+             * report an incorrect architecture number of 7!
+             *
+             * See http://code.google.com/p/android/issues/detail?id=10812
+             *
+             * We try to correct this by looking at the 'elf_format'
+             * field reported by the 'Processor' field, which is of the
+             * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
+             * an ARMv6-one.
+             */
+            if (hasARMv7) {
+                char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
+                                                      "Processor");
+                if (cpuProc != NULL) {
+                    D("found cpuProc = '%s'\n", cpuProc);
+                    if (has_list_item(cpuProc, "(v6l)")) {
+                        D("CPU processor and architecture mismatch!!\n");
+                        hasARMv7 = 0;
+                    }
+                    free(cpuProc);
+                }
+            }
+
+            if (hasARMv7) {
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7;
+            }
+
+            /* The LDREX / STREX instructions are available from ARMv6 */
+            if (archNumber >= 6) {
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX;
+            }
+
+            free(cpuArch);
+        }
+
+        /* Extract the list of CPU features from 'Features' field */
+        char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
+
+        if (cpuFeatures != NULL) {
+
+            D("found cpuFeatures = '%s'\n", cpuFeatures);
+
+            if (has_list_item(cpuFeatures, "vfpv3"))
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
+
+            else if (has_list_item(cpuFeatures, "vfpv3d16"))
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
+
+            if (has_list_item(cpuFeatures, "neon")) {
+                /* Note: Certain kernels only report neon but not vfpv3
+                    *       in their features list. However, ARM mandates
+                    *       that if Neon is implemented, so must be VFPv3
+                    *       so always set the flag.
+                    */
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON |
+                                 ANDROID_CPU_ARM_FEATURE_VFPv3;
+            }
+            free(cpuFeatures);
+        }
+    }
+#endif /* __ARM_ARCH__ */
+
+#ifdef __i386__
+    g_cpuFamily = ANDROID_CPU_FAMILY_X86;
+
+    int regs[4];
+
+/* According to http://en.wikipedia.org/wiki/CPUID */
+#define VENDOR_INTEL_b  0x756e6547
+#define VENDOR_INTEL_c  0x6c65746e
+#define VENDOR_INTEL_d  0x49656e69
+
+    x86_cpuid(0, regs);
+    int vendorIsIntel = (regs[1] == VENDOR_INTEL_b &&
+                         regs[2] == VENDOR_INTEL_c &&
+                         regs[3] == VENDOR_INTEL_d);
+
+    x86_cpuid(1, regs);
+    if ((regs[2] & (1 << 9)) != 0) {
+        g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3;
+    }
+    if ((regs[2] & (1 << 23)) != 0) {
+        g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT;
+    }
+    if (vendorIsIntel && (regs[2] & (1 << 22)) != 0) {
+        g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE;
+    }
+#endif
+}
+
+
+AndroidCpuFamily
+android_getCpuFamily(void)
+{
+    pthread_once(&g_once, android_cpuInit);
+    return g_cpuFamily;
+}
+
+
+uint64_t
+android_getCpuFeatures(void)
+{
+    pthread_once(&g_once, android_cpuInit);
+    return g_cpuFeatures;
+}
+
+
+int
+android_getCpuCount(void)
+{
+    pthread_once(&g_once, android_cpuInit);
+    return g_cpuCount;
+}
diff --git a/src/system_wrappers/source/android/cpu-features.h b/src/system_wrappers/source/android/cpu-features.h
new file mode 100644
index 0000000..f20c0bc
--- /dev/null
+++ b/src/system_wrappers/source/android/cpu-features.h
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+// You can download Android source at
+// http://source.android.com/source/downloading.html
+// Original files are in ndk/sources/android/cpufeatures
+// Revision is Change-Id: I9a0629efba36a6023f05e5f092e7addcc1b7d2a9
+
+#ifndef CPU_FEATURES_H
+#define CPU_FEATURES_H
+
+#include <sys/cdefs.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+typedef enum {
+    ANDROID_CPU_FAMILY_UNKNOWN = 0,
+    ANDROID_CPU_FAMILY_ARM,
+    ANDROID_CPU_FAMILY_X86,
+
+    ANDROID_CPU_FAMILY_MAX  /* do not remove */
+
+} AndroidCpuFamily;
+
+/* Return family of the device's CPU */
+extern AndroidCpuFamily   android_getCpuFamily(void);
+
+enum {
+    ANDROID_CPU_ARM_FEATURE_ARMv7       = (1 << 0),
+    ANDROID_CPU_ARM_FEATURE_VFPv3       = (1 << 1),
+    ANDROID_CPU_ARM_FEATURE_NEON        = (1 << 2),
+    ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3),
+};
+
+enum {
+    ANDROID_CPU_X86_FEATURE_SSSE3  = (1 << 0),
+    ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1),
+    ANDROID_CPU_X86_FEATURE_MOVBE  = (1 << 2),
+};
+
+extern uint64_t    android_getCpuFeatures(void);
+
+/* Return the number of CPU cores detected on this device. */
+extern int         android_getCpuCount(void);
+
+__END_DECLS
+
+#endif /* CPU_FEATURES_H */
diff --git a/src/system_wrappers/source/atomic32.cc b/src/system_wrappers/source/atomic32.cc
deleted file mode 100644
index 588dd3e..0000000
--- a/src/system_wrappers/source/atomic32.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "atomic32_wrapper.h"
-
-#if defined(_WIN32)
-    #include "atomic32_win.h"
-#elif defined(WEBRTC_LINUX)
-    #include "atomic32_linux.h"
-#elif defined(WEBRTC_MAC)
-    #include "atomic32_mac.h"
-#else
-    #error unsupported os!
-#endif
-
-namespace webrtc {
-Atomic32Wrapper::Atomic32Wrapper(WebRtc_Word32 initialValue)
-    : _impl(*new Atomic32Impl(initialValue))
-{
-}
-
-Atomic32Wrapper::~Atomic32Wrapper()
-{
-    delete &_impl;
-}
-
-WebRtc_Word32 Atomic32Wrapper::operator++()
-{
-    return ++_impl;
-}
-
-WebRtc_Word32 Atomic32Wrapper::operator--()
-{
-    return --_impl;
-}
-
-// Read and write to properly aligned variables are atomic operations.
-// Ex reference (for Windows): http://msdn.microsoft.com/en-us/library/ms684122(v=VS.85).aspx
-// TODO (hellner) operator= and Atomic32Wrapper::Value() can be fully
-// implemented here.
-Atomic32Wrapper& Atomic32Wrapper::operator=(const Atomic32Wrapper& rhs)
-{
-    if(this == &rhs)
-    {
-        return *this;
-    }
-    _impl = rhs._impl;
-    return *this;
-}
-
-Atomic32Wrapper& Atomic32Wrapper::operator=(WebRtc_Word32 rhs)
-{
-    _impl = rhs;
-    return *this;
-}
-
-WebRtc_Word32 Atomic32Wrapper::operator+=(WebRtc_Word32 rhs)
-{
-    return _impl += rhs;
-}
-
-WebRtc_Word32 Atomic32Wrapper::operator-=(WebRtc_Word32 rhs)
-{
-    return _impl -= rhs;
-}
-
-bool Atomic32Wrapper::CompareExchange(WebRtc_Word32 newValue,
-                                      WebRtc_Word32 compareValue)
-{
-    return _impl.CompareExchange(newValue,compareValue);
-}
-
-WebRtc_Word32 Atomic32Wrapper::Value() const
-{
-    return _impl.Value();
-}
-} // namespace webrtc
diff --git a/src/system_wrappers/source/atomic32_linux.h b/src/system_wrappers/source/atomic32_linux.h
deleted file mode 100644
index f9f5650..0000000
--- a/src/system_wrappers/source/atomic32_linux.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// Atomic system independant 32-bit signed integer.
-// Linux implementation.
-// Note: Requires gcc 4.1.2 or later.
-#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_
-#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_
-
-#include <inttypes.h>
-#include <malloc.h>
-
-#include "common_types.h"
-
-namespace webrtc {
-class Atomic32Impl
-{
-public:
-    inline Atomic32Impl(WebRtc_Word32 initialValue);
-    inline ~Atomic32Impl();
-
-    inline WebRtc_Word32 operator++();
-    inline WebRtc_Word32 operator--();
-
-    inline Atomic32Impl& operator=(const Atomic32Impl& rhs);
-    inline Atomic32Impl& operator=(WebRtc_Word32 rhs);
-    inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs);
-    inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs);
-
-    inline bool CompareExchange(WebRtc_Word32 newValue,
-                                WebRtc_Word32 compareValue);
-
-    inline WebRtc_Word32 Value() const;
-private:
-    void*        _ptrMemory;
-    // Volatile ensures full memory barriers.
-    volatile WebRtc_Word32* _value;
-};
-
-// TODO (hellner) use aligned_malloc instead of doing it manually.
-inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue)
-    : _ptrMemory(NULL),
-      _value(NULL)
-{   // Align the memory associated with _value on a 32-bit boundary. This is a
-    // requirement for the used Linux APIs to be atomic.
-    // Keep _ptrMemory to be able to reclaim memory.
-    _ptrMemory = malloc(sizeof(WebRtc_Word32)*2);
-    _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3));
-    *_value = initialValue;
-}
-
-inline Atomic32Impl::~Atomic32Impl()
-{
-    if(_ptrMemory != NULL)
-    {
-        free(_ptrMemory);
-    }
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator++()
-{
-    WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,1);
-    returnValue++;
-    return returnValue;
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator--()
-{
-    WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,1);
-    returnValue--;
-    return returnValue;
-}
-
-inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs)
-{
-    *_value = *rhs._value;
-    return *this;
-}
-
-inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs)
-{
-    *_value = rhs;
-    return *this;
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs)
-{
-    WebRtc_Word32 returnValue = __sync_fetch_and_add(_value,rhs);
-    returnValue += rhs;
-    return returnValue;
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs)
-{
-    WebRtc_Word32 returnValue = __sync_fetch_and_sub(_value,rhs);
-    returnValue -= rhs;
-    return returnValue;
-}
-
-inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue,
-                                          WebRtc_Word32 compareValue)
-{
-    return __sync_bool_compare_and_swap(_value,compareValue,newValue);
-}
-
-inline WebRtc_Word32 Atomic32Impl::Value() const
-{
-    return *_value;
-}
-} // namespace webrtc
-
-#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_LINUX_H_
diff --git a/src/system_wrappers/source/atomic32_mac.cc b/src/system_wrappers/source/atomic32_mac.cc
new file mode 100644
index 0000000..9a493b5
--- /dev/null
+++ b/src/system_wrappers/source/atomic32_mac.cc
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "atomic32.h"
+
+#include <assert.h>
+#include <libkern/OSAtomic.h>
+#include <stdlib.h>
+
+#include "common_types.h"
+
+namespace webrtc {
+
+Atomic32::Atomic32(WebRtc_Word32 initialValue) : _value(initialValue)
+{
+    assert(Is32bitAligned());
+}
+
+Atomic32::~Atomic32()
+{
+}
+
+WebRtc_Word32 Atomic32::operator++()
+{
+    return OSAtomicIncrement32Barrier(&_value);
+}
+
+WebRtc_Word32 Atomic32::operator--()
+{
+    return OSAtomicDecrement32Barrier(&_value);
+}
+
+WebRtc_Word32 Atomic32::operator+=(WebRtc_Word32 value)
+{
+    return OSAtomicAdd32Barrier(value, &_value);
+}
+
+WebRtc_Word32 Atomic32::operator-=(WebRtc_Word32 value)
+{
+    return OSAtomicAdd32Barrier(-value, &_value);
+}
+
+bool Atomic32::CompareExchange(WebRtc_Word32 newValue,
+                               WebRtc_Word32 compareValue)
+{
+    return OSAtomicCompareAndSwap32Barrier(compareValue, newValue, &_value);
+}
+
+WebRtc_Word32 Atomic32::Value() const
+{
+    return _value;
+}
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/atomic32_mac.h b/src/system_wrappers/source/atomic32_mac.h
deleted file mode 100644
index bf8febc..0000000
--- a/src/system_wrappers/source/atomic32_mac.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// Atomic system independant 32-bit signed integer.
-// Mac implementation.
-#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_
-#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_
-
-#include <stdlib.h>
-#include <libkern/OSAtomic.h>
-
-#include "common_types.h"
-
-namespace webrtc {
-class Atomic32Impl
-{
-public:
-    inline Atomic32Impl(WebRtc_Word32 initialValue);
-    inline ~Atomic32Impl();
-
-    inline WebRtc_Word32 operator++();
-    inline WebRtc_Word32 operator--();
-
-    inline Atomic32Impl& operator=(const Atomic32Impl& rhs);
-    inline Atomic32Impl& operator=(WebRtc_Word32 rhs);
-    inline WebRtc_Word32 operator+=(WebRtc_Word32 rhs);
-    inline WebRtc_Word32 operator-=(WebRtc_Word32 rhs);
-
-    inline bool CompareExchange(WebRtc_Word32 newValue,
-                                WebRtc_Word32 compareValue);
-
-    inline WebRtc_Word32 Value() const;
-private:
-    void*        _ptrMemory;
-    // Volatile ensures full memory barriers.
-    volatile WebRtc_Word32* _value;
-};
-
-// TODO (hellner) use aligned_malloc instead of doing it manually.
-inline Atomic32Impl::Atomic32Impl(WebRtc_Word32 initialValue)
-    :
-    _ptrMemory(NULL),
-    _value(NULL)
-{   // Align the memory associated with _value on a 32-bit boundary. This is a
-    // requirement for the used Mac APIs to be atomic.
-    // Keep _ptrMemory to be able to reclaim memory.
-    _ptrMemory = malloc(sizeof(WebRtc_Word32)*2);
-    _value = (WebRtc_Word32*) (((uintptr_t)_ptrMemory+3)&(~0x3));
-    *_value = initialValue;
-}
-
-inline Atomic32Impl::~Atomic32Impl()
-{
-    if(_ptrMemory != NULL)
-    {
-        free(_ptrMemory);
-    }
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator++()
-{
-    return OSAtomicIncrement32Barrier(
-               reinterpret_cast<volatile int32_t*>(_value));
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator--()
-{
-    return OSAtomicDecrement32Barrier(
-               reinterpret_cast<volatile int32_t*>(_value));
-}
-
-inline Atomic32Impl& Atomic32Impl::operator=(const Atomic32Impl& rhs)
-{
-    *_value = *rhs._value;
-    return *this;
-}
-
-inline Atomic32Impl& Atomic32Impl::operator=(WebRtc_Word32 rhs)
-{
-    *_value = rhs;
-    return *this;
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator+=(WebRtc_Word32 rhs)
-{
-    return OSAtomicAdd32Barrier(rhs,
-                                reinterpret_cast<volatile int32_t*>(_value));
-}
-
-inline WebRtc_Word32 Atomic32Impl::operator-=(WebRtc_Word32 rhs)
-{
-    return OSAtomicAdd32Barrier(-rhs,
-                                reinterpret_cast<volatile int32_t*>(_value));
-}
-
-inline bool Atomic32Impl::CompareExchange(WebRtc_Word32 newValue,
-                                          WebRtc_Word32 compareValue)
-{
-    return OSAtomicCompareAndSwap32Barrier(
-               compareValue,
-               newValue,
-               reinterpret_cast<volatile int32_t*>(_value));
-}
-
-inline WebRtc_Word32 Atomic32Impl::Value() const
-{
-    return *_value;
-}
-} // namespace webrtc
-#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_ATOMIC32_MAC_H_
diff --git a/src/system_wrappers/source/atomic32_posix.cc b/src/system_wrappers/source/atomic32_posix.cc
new file mode 100644
index 0000000..05b0e57
--- /dev/null
+++ b/src/system_wrappers/source/atomic32_posix.cc
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "atomic32.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <malloc.h>
+
+#include "common_types.h"
+
+namespace webrtc {
+
+Atomic32::Atomic32(WebRtc_Word32 initialValue) : _value(initialValue)
+{
+    assert(Is32bitAligned());
+}
+
+Atomic32::~Atomic32()
+{
+}
+
+WebRtc_Word32 Atomic32::operator++()
+{
+    return __sync_fetch_and_add(&_value, 1) + 1;
+}
+
+WebRtc_Word32 Atomic32::operator--()
+{
+    return __sync_fetch_and_sub(&_value, 1) - 1;
+}
+
+WebRtc_Word32 Atomic32::operator+=(WebRtc_Word32 value)
+{
+    WebRtc_Word32 returnValue = __sync_fetch_and_add(&_value, value);
+    returnValue += value;
+    return returnValue;
+}
+
+WebRtc_Word32 Atomic32::operator-=(WebRtc_Word32 value)
+{
+    WebRtc_Word32 returnValue = __sync_fetch_and_sub(&_value, value);
+    returnValue -= value;
+    return returnValue;
+}
+
+bool Atomic32::CompareExchange(WebRtc_Word32 newValue,
+                               WebRtc_Word32 compareValue)
+{
+    return __sync_bool_compare_and_swap(&_value, compareValue, newValue);
+}
+
+WebRtc_Word32 Atomic32::Value() const
+{
+    return _value;
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/atomic32_win.cc b/src/system_wrappers/source/atomic32_win.cc
new file mode 100644
index 0000000..2fa9d3d
--- /dev/null
+++ b/src/system_wrappers/source/atomic32_win.cc
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "atomic32.h"
+
+#include <assert.h>
+#include <windows.h>
+
+#include "common_types.h"
+#include "compile_assert.h"
+
+namespace webrtc {
+
+Atomic32::Atomic32(WebRtc_Word32 initialValue) : _value(initialValue)
+{
+    // Make sure that the counter variable we're using is of the same size
+    // as what the API expects.
+    COMPILE_ASSERT(sizeof(_value) == sizeof(LONG));
+    assert(Is32bitAligned());
+}
+
+Atomic32::~Atomic32()
+{
+}
+
+WebRtc_Word32 Atomic32::operator++()
+{
+    return static_cast<WebRtc_Word32>(InterlockedIncrement(
+        reinterpret_cast<volatile LONG*>(&_value)));
+}
+
+WebRtc_Word32 Atomic32::operator--()
+{
+    return static_cast<WebRtc_Word32>(InterlockedDecrement(
+        reinterpret_cast<volatile LONG*>(&_value)));
+}
+
+WebRtc_Word32 Atomic32::operator+=(WebRtc_Word32 value)
+{
+    return InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(&_value),
+                                  value);
+}
+
+WebRtc_Word32 Atomic32::operator-=(WebRtc_Word32 value)
+{
+    return InterlockedExchangeAdd(reinterpret_cast<volatile LONG*>(&_value),
+                                  -value);
+}
+
+bool Atomic32::CompareExchange(WebRtc_Word32 newValue,
+                               WebRtc_Word32 compareValue)
+{
+    const LONG oldValue = InterlockedCompareExchange(
+          reinterpret_cast<volatile LONG*>(&_value),
+          newValue,
+          compareValue);
+    // If the old value and the compare value is the same an exchange happened.
+    return (oldValue == compareValue);
+}
+
+WebRtc_Word32 Atomic32::Value() const
+{
+    return _value;
+}
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/condition_variable_unittest.cc b/src/system_wrappers/source/condition_variable_unittest.cc
new file mode 100644
index 0000000..a9fdd0d
--- /dev/null
+++ b/src/system_wrappers/source/condition_variable_unittest.cc
@@ -0,0 +1,208 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "system_wrappers/interface/condition_variable_wrapper.h"
+
+#include "gtest/gtest.h"
+#include "system_wrappers/interface/critical_section_wrapper.h"
+#include "system_wrappers/interface/thread_wrapper.h"
+#include "system_wrappers/interface/trace.h"
+#include "system_wrappers/source/unittest_utilities.h"
+
+namespace webrtc {
+
+namespace {
+
+const int kLogTrace = false;  // Set to true to enable debug logging to stdout.
+const int kLongWaitMs = 100*1000;  // A long time in testing terms
+const int kShortWaitMs = 2*1000;  // Long enough for process switches to happen
+
+#define LOG(...) WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, __VA_ARGS__);
+
+// A Baton is one possible control structure one can build using
+// conditional variables.
+// A Baton is always held by one and only one active thread - unlike
+// a lock, it can never be free.
+// One can pass it or grab it - both calls have timeouts.
+// Note - a production tool would guard against passing it without
+// grabbing it first. This one is for testing, so it doesn't.
+class Baton {
+ public:
+  Baton()
+    : giver_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+      crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+      cond_var_(ConditionVariableWrapper::CreateConditionVariable()),
+      being_passed_(false),
+      pass_count_(0) {
+  }
+
+  ~Baton() {
+    delete giver_sect_;
+    delete crit_sect_;
+    delete cond_var_;
+  }
+
+  // Pass the baton. Returns false if baton is not picked up in |max_msecs|.
+  // Only one process can pass at the same time; this property is
+  // ensured by the |giver_sect_| lock.
+  bool Pass(WebRtc_UWord32 max_msecs) {
+    LOG("Locking giver_sect");
+    CriticalSectionScoped cs_giver(giver_sect_);
+    LOG("Locked giver_sect, locking crit_sect");
+    CriticalSectionScoped cs(crit_sect_);
+    SignalBatonAvailable();
+    const bool result = TakeBatonIfStillFree(max_msecs);
+    if (result) {
+      ++pass_count_;
+      LOG("Pass count is %d", pass_count_);
+    }
+    return result;
+  }
+
+  // Grab the baton. Returns false if baton is not passed.
+  bool Grab(WebRtc_UWord32 max_msecs) {
+    CriticalSectionScoped cs(crit_sect_);
+    return WaitUntilBatonOffered(max_msecs);
+  }
+
+  int PassCount() {
+    // We don't allow polling PassCount() during a Pass()-call since there is
+    // no guarantee that |pass_count_| is incremented until the Pass()-call
+    // finishes. I.e. the Grab()-call may finish before |pass_count_| has been
+    // incremented.
+    // Thus, this function waits on giver_sect_.
+    CriticalSectionScoped cs(giver_sect_);
+    return pass_count_;
+  }
+
+ private:
+  // Wait/Signal forms a classical semaphore on |being_passed_|.
+  // These functions must be called with crit_sect_ held.
+  bool WaitUntilBatonOffered(int timeout_ms) {
+    while (!being_passed_) {
+      LOG("Wait waiting");
+      if (!cond_var_->SleepCS(*crit_sect_, timeout_ms)) {
+        LOG("Wait timeout");
+        return false;
+      }
+    }
+    being_passed_ = false;
+    cond_var_->Wake();
+    return true;
+  }
+
+  void SignalBatonAvailable() {
+    assert(!being_passed_);
+    being_passed_ = true;
+    LOG("Signal waking");
+    cond_var_->Wake();
+  }
+
+  // Timeout extension: Wait for a limited time for someone else to
+  // take it, and take it if it's not taken.
+  // Returns true if resource is taken by someone else, false
+  // if it is taken back by the caller.
+  // This function must be called with both |giver_sect_| and
+  // |crit_sect_| held.
+  bool TakeBatonIfStillFree(int timeout_ms) {
+    bool not_timeout = true;
+    while (being_passed_ && not_timeout) {
+      LOG("Takeback waiting");
+      not_timeout = cond_var_->SleepCS(*crit_sect_, timeout_ms);
+      // If we're woken up while variable is still held, we may have
+      // gotten a wakeup destined for a grabber thread.
+      // This situation is not treated specially here.
+    }
+    if (!being_passed_) {
+      return true;
+    } else {
+      LOG("Takeback grab");
+      assert(!not_timeout);
+      being_passed_ = false;
+      return false;
+    }
+  }
+
+  // Lock that ensures that there is only one thread in the active
+  // part of Pass() at a time.
+  // |giver_sect_| must always be acquired before |cond_var_|.
+  CriticalSectionWrapper* giver_sect_;
+  // Lock that protects |being_passed_|.
+  CriticalSectionWrapper* crit_sect_;
+  ConditionVariableWrapper* cond_var_;
+  bool being_passed_;
+  // Statistics information: Number of successfull passes.
+  int pass_count_;
+};
+
+// Function that waits on a Baton, and passes it right back.
+// We expect these calls never to time out.
+bool WaitingRunFunction(void* obj) {
+  Baton* the_baton = static_cast<Baton*> (obj);
+  LOG("Thread waiting");
+  EXPECT_TRUE(the_baton->Grab(kLongWaitMs));
+  LOG("Thread waking parent");
+  EXPECT_TRUE(the_baton->Pass(kLongWaitMs));
+  return true;
+}
+
+class CondVarTest : public ::testing::Test {
+ public:
+  CondVarTest()
+    : trace_(kLogTrace) {
+  }
+
+  virtual void SetUp() {
+    thread_ = ThreadWrapper::CreateThread(&WaitingRunFunction,
+                                          &baton_);
+    unsigned int id = 42;
+    ASSERT_TRUE(thread_->Start(id));
+  }
+
+  virtual void TearDown() {
+    // We have to wake the thread in order to make it obey the stop order.
+    // But we don't know if the thread has completed the run function, so
+    // we don't know if it will exit before or after the Pass.
+    // Thus, we need to pin it down inside its Run function (between Grab
+    // and Pass).
+    ASSERT_TRUE(baton_.Pass(kShortWaitMs));
+    thread_->SetNotAlive();
+    ASSERT_TRUE(baton_.Grab(kShortWaitMs));
+    ASSERT_TRUE(thread_->Stop());
+    delete thread_;
+  }
+
+ protected:
+  Baton baton_;
+
+ private:
+  ScopedTracing trace_;
+  ThreadWrapper* thread_;
+};
+
+// The SetUp and TearDown functions use condition variables.
+// This test verifies those pieces in isolation.
+TEST_F(CondVarTest, InitFunctionsWork) {
+  // All relevant asserts are in the SetUp and TearDown functions.
+}
+
+// This test verifies that one can use the baton multiple times.
+TEST_F(CondVarTest, PassBatonMultipleTimes) {
+  const int kNumberOfRounds = 2;
+  for (int i = 0; i < kNumberOfRounds; ++i) {
+    ASSERT_TRUE(baton_.Pass(kShortWaitMs));
+    ASSERT_TRUE(baton_.Grab(kShortWaitMs));
+  }
+  EXPECT_EQ(2*kNumberOfRounds, baton_.PassCount());
+}
+
+}  // anonymous namespace
+
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/condition_variable_win.cc b/src/system_wrappers/source/condition_variable_win.cc
new file mode 100644
index 0000000..f4fae0b
--- /dev/null
+++ b/src/system_wrappers/source/condition_variable_win.cc
@@ -0,0 +1,224 @@
+/*
+ *  Use of this source code is governed by the ACE copyright license which
+ *  can be found in the LICENSE file in the third_party_mods/ace directory of
+ *  the source tree or at http://www1.cse.wustl.edu/~schmidt/ACE-copying.html.
+ */
+/*
+ *  This source code contain modifications to the original source code
+ *  which can be found here:
+ *  http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (section 3.2).
+ *  Modifications:
+ *  1) Dynamic detection of native support for condition variables.
+ *  2) Use of WebRTC defined types and classes. Renaming of some functions.
+ *  3) Introduction of a second event for wake all functionality. This prevents
+ *     a thread from spinning on the same condition variable, preventing other
+ *     threads from waking up.
+ */
+
+// TODO (hellner): probably nicer to split up native and generic
+// implementation into two different files
+
+#include "condition_variable_win.h"
+
+#include "critical_section_win.h"
+#include "trace.h"
+
+namespace webrtc {
+bool ConditionVariableWindows::_winSupportConditionVariablesPrimitive = false;
+static HMODULE library = NULL;
+
+PInitializeConditionVariable  _PInitializeConditionVariable;
+PSleepConditionVariableCS     _PSleepConditionVariableCS;
+PWakeConditionVariable        _PWakeConditionVariable;
+PWakeAllConditionVariable     _PWakeAllConditionVariable;
+
+typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);
+typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,
+                                                 PCRITICAL_SECTION, DWORD);
+typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);
+typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);
+
+ConditionVariableWindows::ConditionVariableWindows()
+    : _eventID(WAKEALL_0)
+{
+    if (!library)
+    {
+        // Use native implementation if supported (i.e Vista+)
+        library = LoadLibrary(TEXT("Kernel32.dll"));
+        if (library)
+        {
+            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
+                         "Loaded Kernel.dll");
+
+            _PInitializeConditionVariable =
+                (PInitializeConditionVariable) GetProcAddress(
+                    library,
+                    "InitializeConditionVariable");
+            _PSleepConditionVariableCS =
+                (PSleepConditionVariableCS)GetProcAddress(
+                    library,
+                    "SleepConditionVariableCS");
+            _PWakeConditionVariable =
+                (PWakeConditionVariable)GetProcAddress(
+                    library,
+                     "WakeConditionVariable");
+            _PWakeAllConditionVariable =
+                (PWakeAllConditionVariable)GetProcAddress(
+                    library,
+                    "WakeAllConditionVariable");
+
+            if(_PInitializeConditionVariable &&
+               _PSleepConditionVariableCS &&
+               _PWakeConditionVariable &&
+               _PWakeAllConditionVariable)
+            {
+                WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
+                             "Loaded native condition variables");
+                _winSupportConditionVariablesPrimitive = true;
+            }
+        }
+    }
+
+    if (_winSupportConditionVariablesPrimitive)
+    {
+        _PInitializeConditionVariable(&_conditionVariable);
+
+        _events[WAKEALL_0] = NULL;
+        _events[WAKEALL_1] = NULL;
+        _events[WAKE] = NULL;
+
+    } else {
+        memset(&_numWaiters[0],0,sizeof(_numWaiters));
+
+        InitializeCriticalSection(&_numWaitersCritSect);
+
+        _events[WAKEALL_0] = CreateEvent(NULL,  // no security attributes
+                                         TRUE,  // manual-reset, sticky event
+                                         FALSE, // initial state non-signaled
+                                         NULL); // no name for event
+
+        _events[WAKEALL_1] = CreateEvent(NULL,  // no security attributes
+                                         TRUE,  // manual-reset, sticky event
+                                         FALSE, // initial state non-signaled
+                                         NULL); // no name for event
+
+        _events[WAKE] = CreateEvent(NULL,  // no security attributes
+                                    FALSE, // auto-reset, sticky event
+                                    FALSE, // initial state non-signaled
+                                    NULL); // no name for event
+    }
+}
+
+ConditionVariableWindows::~ConditionVariableWindows()
+{
+    if(!_winSupportConditionVariablesPrimitive)
+    {
+        CloseHandle(_events[WAKE]);
+        CloseHandle(_events[WAKEALL_1]);
+        CloseHandle(_events[WAKEALL_0]);
+
+        DeleteCriticalSection(&_numWaitersCritSect);
+    }
+}
+
+void ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect)
+{
+    SleepCS(critSect, INFINITE);
+}
+
+bool ConditionVariableWindows::SleepCS(CriticalSectionWrapper& critSect,
+                                       unsigned long maxTimeInMS)
+{
+    CriticalSectionWindows* cs = reinterpret_cast<CriticalSectionWindows*>(
+                                     &critSect);
+
+    if(_winSupportConditionVariablesPrimitive)
+    {
+        BOOL retVal = _PSleepConditionVariableCS(&_conditionVariable,
+                                                 &(cs->crit),maxTimeInMS);
+        return (retVal == 0) ? false : true;
+
+    }else
+    {
+        EnterCriticalSection(&_numWaitersCritSect);
+        // Get the eventID for the event that will be triggered by next
+        // WakeAll() call and start waiting for it.
+        const EventWakeUpType eventID = (WAKEALL_0 == _eventID) ?
+                                            WAKEALL_1 : WAKEALL_0;
+        ++(_numWaiters[eventID]);
+        LeaveCriticalSection(&_numWaitersCritSect);
+
+        LeaveCriticalSection(&cs->crit);
+        HANDLE events[2];
+        events[0] = _events[WAKE];
+        events[1] = _events[eventID];
+        const DWORD result = WaitForMultipleObjects(2, // Wait on 2 events.
+                                                    events,
+                                                    FALSE, // Wait for either.
+                                                    maxTimeInMS);
+
+        const bool retVal = (result != WAIT_TIMEOUT);
+
+        EnterCriticalSection(&_numWaitersCritSect);
+        --(_numWaiters[eventID]);
+        // Last waiter should only be true for WakeAll(). WakeAll() correspond
+        // to position 1 in events[] -> (result == WAIT_OBJECT_0 + 1)
+        const bool lastWaiter = (result == WAIT_OBJECT_0 + 1) &&
+                                (_numWaiters[eventID] == 0);
+        LeaveCriticalSection(&_numWaitersCritSect);
+
+        if (lastWaiter)
+        {
+            // Reset/unset the WakeAll() event since all threads have been
+            // released.
+            ResetEvent(_events[eventID]);
+        }
+
+        EnterCriticalSection(&cs->crit);
+        return retVal;
+    }
+}
+
+void
+ConditionVariableWindows::Wake()
+{
+    if(_winSupportConditionVariablesPrimitive)
+    {
+        _PWakeConditionVariable(&_conditionVariable);
+    }else
+    {
+        EnterCriticalSection(&_numWaitersCritSect);
+        const bool haveWaiters = (_numWaiters[WAKEALL_0] > 0) ||
+                                 (_numWaiters[WAKEALL_1] > 0);
+        LeaveCriticalSection(&_numWaitersCritSect);
+
+        if (haveWaiters)
+        {
+            SetEvent(_events[WAKE]);
+        }
+    }
+}
+
+void
+ConditionVariableWindows::WakeAll()
+{
+    if(_winSupportConditionVariablesPrimitive)
+    {
+        _PWakeAllConditionVariable(&_conditionVariable);
+    }else
+    {
+        EnterCriticalSection(&_numWaitersCritSect);
+        // Update current WakeAll() event
+        _eventID = (WAKEALL_0 == _eventID) ? WAKEALL_1 : WAKEALL_0;
+        // Trigger current event
+        const EventWakeUpType eventID = _eventID;
+        const bool haveWaiters = _numWaiters[eventID] > 0;
+        LeaveCriticalSection(&_numWaitersCritSect);
+
+        if (haveWaiters)
+        {
+            SetEvent(_events[eventID]);
+        }
+    }
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/condition_variable_win.h b/src/system_wrappers/source/condition_variable_win.h
new file mode 100644
index 0000000..aab2564
--- /dev/null
+++ b/src/system_wrappers/source/condition_variable_win.h
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_
+
+#include "condition_variable_wrapper.h"
+
+#include <windows.h>
+
+namespace webrtc {
+#if !defined CONDITION_VARIABLE_INIT
+    typedef struct _RTL_CONDITION_VARIABLE
+    {
+        void* Ptr;
+    } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
+
+    typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+#endif
+
+typedef void (WINAPI *PInitializeConditionVariable)(PCONDITION_VARIABLE);
+typedef BOOL (WINAPI *PSleepConditionVariableCS)(PCONDITION_VARIABLE,
+                                                 PCRITICAL_SECTION, DWORD);
+typedef void (WINAPI *PWakeConditionVariable)(PCONDITION_VARIABLE);
+typedef void (WINAPI *PWakeAllConditionVariable)(PCONDITION_VARIABLE);
+
+
+class ConditionVariableWindows : public ConditionVariableWrapper
+{
+public:
+    ConditionVariableWindows();
+    ~ConditionVariableWindows();
+
+    void SleepCS(CriticalSectionWrapper& critSect);
+    bool SleepCS(CriticalSectionWrapper& critSect, unsigned long maxTimeInMS);
+    void Wake();
+    void WakeAll();
+
+private:
+    enum EventWakeUpType
+    {
+        WAKEALL_0   = 0,
+        WAKEALL_1   = 1,
+        WAKE        = 2,
+        EVENT_COUNT = 3
+    };
+
+private:
+    // Native support for Windows Vista+
+    static bool              _winSupportConditionVariablesPrimitive;
+    CONDITION_VARIABLE       _conditionVariable;
+
+    unsigned int     _numWaiters[2];
+    EventWakeUpType  _eventID;
+    CRITICAL_SECTION _numWaitersCritSect;
+    HANDLE           _events[EVENT_COUNT];
+};
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CONDITION_VARIABLE_WINDOWS_H_
diff --git a/src/system_wrappers/source/cpu_features_android.c b/src/system_wrappers/source/cpu_features_android.c
new file mode 100644
index 0000000..7a4fa6e
--- /dev/null
+++ b/src/system_wrappers/source/cpu_features_android.c
@@ -0,0 +1,15 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "android/cpu-features.h"
+
+uint64_t WebRtc_GetCPUFeaturesARM(void) {
+  return android_getCpuFeatures();
+}
diff --git a/src/system_wrappers/source/cpu_features_arm.c b/src/system_wrappers/source/cpu_features_arm.c
deleted file mode 100644
index 1065118..0000000
--- a/src/system_wrappers/source/cpu_features_arm.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// This file is derived from Android's NDK package r7, located at
-// <ndk>/sources/android/cpufeatures/ (downloadable from
-// http://developer.android.com/sdk/ndk/index.html).
-
-#include "cpu_features_wrapper.h"
-
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-// Define CPU family.
-typedef enum {
-  CPU_FAMILY_UNKNOWN = 0,
-  CPU_FAMILY_ARM,
-  CPU_FAMILY_X86,
-  CPU_FAMILY_MAX  // Do not remove.
-} CpuFamily;
-
-static pthread_once_t g_once;
-static CpuFamily g_cpuFamily;
-static uint64_t g_cpuFeatures;
-static int g_cpuCount;
-
-static const int cpufeatures_debug = 0;
-
-#ifdef __arm__
-#  define DEFAULT_CPU_FAMILY  CPU_FAMILY_ARM
-#elif defined __i386__
-#  define DEFAULT_CPU_FAMILY  CPU_FAMILY_X86
-#else
-#  define DEFAULT_CPU_FAMILY  CPU_FAMILY_UNKNOWN
-#endif
-
-#define  D(...) \
-  do { \
-    if (cpufeatures_debug) { \
-      printf(__VA_ARGS__); fflush(stdout); \
-    } \
-  } while (0)
-
-/* Read the content of /proc/cpuinfo into a user-provided buffer.
- * Return the length of the data, or -1 on error. Does *not*
- * zero-terminate the content. Will not read more
- * than 'buffsize' bytes.
- */
-static int read_file(const char*  pathname, char*  buffer, size_t  buffsize) {
-  int  fd, len;
-
-  fd = open(pathname, O_RDONLY);
-  if (fd < 0)
-    return -1;
-
-  do {
-    len = read(fd, buffer, buffsize);
-  } while (len < 0 && errno == EINTR);
-
-  close(fd);
-
-  return len;
-}
-
-/* Extract the content of a the first occurence of a given field in
- * the content of /proc/cpuinfo and return it as a heap-allocated
- * string that must be freed by the caller.
- *
- * Return NULL if not found
- */
-static char* extract_cpuinfo_field(char* buffer, int buflen, const char* field) {
-  int  fieldlen = strlen(field);
-  char* bufend = buffer + buflen;
-  char* result = NULL;
-  int len, ignore;
-  const char* p, *q;
-
-  /* Look for first field occurence, and ensures it starts the line.
-   */
-  p = buffer;
-  bufend = buffer + buflen;
-  for (;;) {
-    p = memmem(p, bufend - p, field, fieldlen);
-    if (p == NULL)
-      goto EXIT;
-
-    if (p == buffer || p[-1] == '\n')
-      break;
-
-    p += fieldlen;
-  }
-
-  /* Skip to the first column followed by a space */
-  p += fieldlen;
-  p  = memchr(p, ':', bufend - p);
-  if (p == NULL || p[1] != ' ')
-    goto EXIT;
-
-  /* Find the end of the line */
-  p += 2;
-  q = memchr(p, '\n', bufend - p);
-  if (q == NULL)
-    q = bufend;
-
-  /* Copy the line into a heap-allocated buffer */
-  len = q - p;
-  result = malloc(len + 1);
-  if (result == NULL)
-    goto EXIT;
-
-  memcpy(result, p, len);
-  result[len] = '\0';
-
-EXIT:
-  return result;
-}
-
-/* Count the number of occurences of a given field prefix in /proc/cpuinfo.
- */
-static int count_cpuinfo_field(char* buffer, int buflen, const char* field) {
-  int fieldlen = strlen(field);
-  const char* p = buffer;
-  const char* bufend = buffer + buflen;
-  const char* q;
-  int count = 0;
-
-  for (;;) {
-    const char* q;
-
-    p = memmem(p, bufend - p, field, fieldlen);
-    if (p == NULL)
-      break;
-
-    /* Ensure that the field is at the start of a line */
-    if (p > buffer && p[-1] != '\n') {
-      p += fieldlen;
-      continue;
-    }
-
-
-    /* skip any whitespace */
-    q = p + fieldlen;
-    while (q < bufend && (*q == ' ' || *q == '\t'))
-      q++;
-
-    /* we must have a colon now */
-    if (q < bufend && *q == ':') {
-      count += 1;
-      q ++;
-    }
-    p = q;
-  }
-
-  return count;
-}
-
-/* Like strlen(), but for constant string literals */
-#define STRLEN_CONST(x)  ((sizeof(x)-1)
-
-
-/* Checks that a space-separated list of items contains one given 'item'.
- * Returns 1 if found, 0 otherwise.
- */
-static int has_list_item(const char* list, const char* item) {
-  const char*  p = list;
-  int itemlen = strlen(item);
-
-  if (list == NULL)
-    return 0;
-
-  while (*p) {
-    const char*  q;
-
-    /* skip spaces */
-    while (*p == ' ' || *p == '\t')
-      p++;
-
-    /* find end of current list item */
-    q = p;
-    while (*q && *q != ' ' && *q != '\t')
-      q++;
-
-    if (itemlen == q - p && !memcmp(p, item, itemlen))
-      return 1;
-
-    /* skip to next item */
-    p = q;
-  }
-  return 0;
-}
-
-
-static void cpuInit(void) {
-  char cpuinfo[4096];
-  int  cpuinfo_len;
-
-  g_cpuFamily   = DEFAULT_CPU_FAMILY;
-  g_cpuFeatures = 0;
-  g_cpuCount    = 1;
-
-  cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo);
-  D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
-    cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);
-
-  if (cpuinfo_len < 0) { /* should not happen */
-    return;
-  }
-
-  /* Count the CPU cores, the value may be 0 for single-core CPUs */
-  g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "processor");
-  if (g_cpuCount == 0) {
-    g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "Processor");
-    if (g_cpuCount == 0) {
-      g_cpuCount = 1;
-    }
-  }
-
-  D("found cpuCount = %d\n", g_cpuCount);
-
-#ifdef __arm__
-  {
-    char*  features = NULL;
-    char*  architecture = NULL;
-
-    /* Extract architecture from the "CPU Architecture" field.
-     * The list is well-known, unlike the the output of
-     * the 'Processor' field which can vary greatly.
-     *
-     * See the definition of the 'proc_arch' array in
-     * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
-     * same file.
-     */
-    char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
-                                          "CPU architecture");
-
-    if (cpuArch != NULL) {
-      char*  end;
-      long   archNumber;
-      int    hasARMv7 = 0;
-
-      D("found cpuArch = '%s'\n", cpuArch);
-
-      /* read the initial decimal number, ignore the rest */
-      archNumber = strtol(cpuArch, &end, 10);
-
-      /* Here we assume that ARMv8 will be upwards compatible with v7
-          * in the future. Unfortunately, there is no 'Features' field to
-          * indicate that Thumb-2 is supported.
-          */
-      if (end > cpuArch && archNumber >= 7) {
-        hasARMv7 = 1;
-      }
-
-      /* Unfortunately, it seems that certain ARMv6-based CPUs
-       * report an incorrect architecture number of 7!
-       *
-       * We try to correct this by looking at the 'elf_format'
-       * field reported by the 'Processor' field, which is of the
-       * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
-       * an ARMv6-one.
-       */
-      if (hasARMv7) {
-        char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
-                                              "Processor");
-        if (cpuProc != NULL) {
-          D("found cpuProc = '%s'\n", cpuProc);
-          if (has_list_item(cpuProc, "(v6l)")) {
-            D("CPU processor and architecture mismatch!!\n");
-            hasARMv7 = 0;
-          }
-          free(cpuProc);
-        }
-      }
-
-      if (hasARMv7) {
-        g_cpuFeatures |= kCPUFeatureARMv7;
-      }
-
-      /* The LDREX / STREX instructions are available from ARMv6 */
-      if (archNumber >= 6) {
-        g_cpuFeatures |= kCPUFeatureLDREXSTREX;
-      }
-
-      free(cpuArch);
-    }
-
-    /* Extract the list of CPU features from 'Features' field */
-    char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
-                                              "Features");
-
-    if (cpuFeatures != NULL) {
-
-      D("found cpuFeatures = '%s'\n", cpuFeatures);
-
-      if (has_list_item(cpuFeatures, "vfpv3"))
-        g_cpuFeatures |= kCPUFeatureVFPv3;
-
-      else if (has_list_item(cpuFeatures, "vfpv3d16"))
-        g_cpuFeatures |= kCPUFeatureVFPv3;
-
-      if (has_list_item(cpuFeatures, "neon")) {
-        /* Note: Certain kernels only report neon but not vfpv3
-            *       in their features list. However, ARM mandates
-            *       that if Neon is implemented, so must be VFPv3
-            *       so always set the flag.
-            */
-        g_cpuFeatures |= kCPUFeatureNEON |
-                         kCPUFeatureVFPv3;
-      }
-      free(cpuFeatures);
-    }
-  }
-#endif  // __arm__
-
-#ifdef __i386__
-  g_cpuFamily = CPU_FAMILY_X86;
-#endif
-}
-
-
-uint64_t WebRtc_GetCPUFeaturesARM(void) {
-  pthread_once(&g_once, cpuInit);
-  return g_cpuFeatures;
-}
diff --git a/src/system_wrappers/source/cpu_linux.cc b/src/system_wrappers/source/cpu_linux.cc
index 9d7d89d..8e8ecda 100644
--- a/src/system_wrappers/source/cpu_linux.cc
+++ b/src/system_wrappers/source/cpu_linux.cc
@@ -179,6 +179,7 @@
     char line[100];
     if (!fgets(line, 100, fp))
     {
+        fclose(fp);
         return -1;
     }
     int numCores = -1;
diff --git a/src/system_wrappers/source/cpu_measurement_harness.cc b/src/system_wrappers/source/cpu_measurement_harness.cc
new file mode 100644
index 0000000..237e776
--- /dev/null
+++ b/src/system_wrappers/source/cpu_measurement_harness.cc
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "system_wrappers/interface/cpu_wrapper.h"
+#include "system_wrappers/interface/event_wrapper.h"
+#include "system_wrappers/interface/scoped_ptr.h"
+#include "system_wrappers/source/cpu_measurement_harness.h"
+
+const int kCpuCheckPeriodMs = 100;
+
+namespace webrtc {
+
+CpuMeasurementHarness* CpuMeasurementHarness::Create(
+    CpuTarget* target,
+    int work_period_ms,
+    int work_iterations_per_period,
+    int duration_ms) {
+  if (target == NULL) {
+    return NULL;
+  }
+  if (work_period_ms > duration_ms) {
+    return NULL;
+  }
+  if (work_period_ms < 0) {
+    return NULL;
+  }
+  if (duration_ms < 0) {
+    return NULL;
+  }
+  if (work_iterations_per_period < 1) {
+    return NULL;
+  }
+  return new CpuMeasurementHarness(target, work_period_ms,
+                                   work_iterations_per_period, duration_ms);
+}
+
+CpuMeasurementHarness::CpuMeasurementHarness(CpuTarget* target,
+                                             int work_period_ms,
+                                             int work_iterations_per_period,
+                                             int duration_ms)
+    : cpu_target_(target),
+      work_period_ms_(work_period_ms),
+      work_iterations_per_period_(work_iterations_per_period),
+      duration_ms_(duration_ms),
+      cpu_sum_(0),
+      cpu_iterations_(0),
+      cpu_(CpuWrapper::CreateCpu()),
+      event_(EventWrapper::Create()) {
+}
+
+CpuMeasurementHarness::~CpuMeasurementHarness() {
+}
+
+bool CpuMeasurementHarness::Run() {
+  if (!WaitForCpuInit()) {
+    return false;
+  }
+  // No need for precision. Run for approximately the asked for duration.
+  // TODO(hellner): very low prio if at all, the actual duration of the test
+  // will be longer if calling DoWork() is not negligable and/or called many
+  // times. It may make sense to compensate for drift here. This will,
+  // however, only add complexity with minimal gains. Perhaps renaming the
+  // duration_ms_ to something more fuzzy is a better idea. However, the name
+  // would be very convoluted if it is to be self documenting.
+  int elapsed_time_ms = 0;
+  int last_measured_time = 0;
+  while (elapsed_time_ms < duration_ms_) {
+    if (((elapsed_time_ms - last_measured_time) / kCpuCheckPeriodMs) >= 1) {
+      last_measured_time = elapsed_time_ms;
+      Measure();
+    }
+    if (!DoWork()) {
+      return false;
+    }
+    event_->Wait(work_period_ms_);
+    elapsed_time_ms += work_period_ms_;
+  }
+  return true;
+}
+
+int CpuMeasurementHarness::AverageCpu() {
+  if (cpu_iterations_ == 0) {
+    return 0;
+  }
+  assert(cpu_sum_ >= 0);
+  assert(cpu_iterations_ >= 0);
+  return cpu_sum_ / cpu_iterations_;
+}
+
+bool CpuMeasurementHarness::WaitForCpuInit() {
+  bool cpu_usage_available = false;
+  int num_iterations = 0;
+  // Initializing the CPU measurements may take a couple of seconds on Windows.
+  // Since the initialization is lazy we need to wait until it is completed.
+  // Should not take more than 10000 ms.
+  while (!cpu_usage_available && (++num_iterations < 10000)) {
+    event_->Wait(1);
+    cpu_usage_available = cpu_->CpuUsage() != -1;
+  }
+  return cpu_usage_available;
+}
+
+void CpuMeasurementHarness::Measure() {
+  WebRtc_UWord32 num_cores = 0;
+  WebRtc_UWord32* cores = NULL;
+  // Return the average CPU for now.
+  cpu_sum_ = cpu_->CpuUsageMultiCore(num_cores, cores);
+  ++cpu_iterations_;
+}
+
+bool CpuMeasurementHarness::DoWork() {
+  for (int i = 0; i < work_iterations_per_period_; ++i) {
+    if (!cpu_target_->DoWork()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/cpu_measurement_harness.h b/src/system_wrappers/source/cpu_measurement_harness.h
new file mode 100644
index 0000000..3b87f27
--- /dev/null
+++ b/src/system_wrappers/source/cpu_measurement_harness.h
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef SRC_SYSTEM_WRAPPERS_SOURCE_CPU_MEASUREMENT_HARNESS_H_
+#define SRC_SYSTEM_WRAPPERS_SOURCE_CPU_MEASUREMENT_HARNESS_H_
+
+#include "system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+class CpuWrapper;
+class EventWrapper;
+class ThreadWrapper;
+
+// This abstract class provides an interface that should be passed to
+// CpuMeasurementHarness. CpuMeasurementHarness will call it with the
+// frequency requested and measure the CPU usage for all calls.
+class CpuTarget {
+ public:
+  // Callback function for which the CPU usage should be calculated.
+  virtual bool DoWork() = 0;
+
+ protected:
+  CpuTarget() {}
+  virtual ~CpuTarget() {}
+};
+
+class CpuMeasurementHarness {
+ public:
+  static CpuMeasurementHarness* Create(CpuTarget* target,
+                                       int work_period_ms,
+                                       int work_iterations_per_period,
+                                       int duration_ms);
+  ~CpuMeasurementHarness();
+  bool Run();
+  int AverageCpu();
+
+ protected:
+  CpuMeasurementHarness(CpuTarget* target, int work_period_ms,
+                        int work_iterations_per_period, int duration_ms);
+
+ private:
+  bool WaitForCpuInit();
+  void Measure();
+  bool DoWork();
+
+  CpuTarget* cpu_target_;
+  const int work_period_ms_;
+  const int work_iterations_per_period_;
+  const int duration_ms_;
+  int cpu_sum_;
+  int cpu_iterations_;
+  scoped_ptr<CpuWrapper> cpu_;
+  scoped_ptr<EventWrapper> event_;
+};
+
+}  // namespace webrtc
+
+#endif  // SRC_SYSTEM_WRAPPERS_SOURCE_CPU_MEASUREMENT_HARNESS_H_
diff --git a/src/system_wrappers/source/cpu_win.cc b/src/system_wrappers/source/cpu_win.cc
new file mode 100644
index 0000000..86a6a6a
--- /dev/null
+++ b/src/system_wrappers/source/cpu_win.cc
@@ -0,0 +1,530 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "cpu_win.h"
+
+#define _WIN32_DCOM
+
+#include <assert.h>
+#include <iostream>
+#include <Wbemidl.h>
+
+#pragma comment(lib, "wbemuuid.lib")
+
+#include "condition_variable_wrapper.h"
+#include "critical_section_wrapper.h"
+#include "event_wrapper.h"
+#include "thread_wrapper.h"
+
+namespace webrtc {
+WebRtc_Word32 CpuWindows::CpuUsage()
+{
+    if (!has_initialized_)
+    {
+        return -1;
+    }
+    // Last element is the average
+    return cpu_usage_[number_of_objects_ - 1];
+}
+
+WebRtc_Word32 CpuWindows::CpuUsageMultiCore(WebRtc_UWord32& num_cores,
+                                            WebRtc_UWord32*& cpu_usage)
+{
+    if (has_terminated_) {
+        num_cores = 0;
+        cpu_usage = NULL;
+        return -1;
+    }
+    if (!has_initialized_)
+    {
+        num_cores = 0;
+        cpu_usage = NULL;
+        return -1;
+    }
+    num_cores = number_of_objects_ - 1;
+    cpu_usage = cpu_usage_;
+    return cpu_usage_[number_of_objects_-1];
+}
+
+CpuWindows::CpuWindows()
+    : cpu_polling_thread(NULL),
+      initialize_(true),
+      has_initialized_(false),
+      terminate_(false),
+      has_terminated_(false),
+      cpu_usage_(NULL),
+      wbem_enum_access_(NULL),
+      number_of_objects_(0),
+      cpu_usage_handle_(0),
+      previous_processor_timestamp_(NULL),
+      timestamp_sys_100_ns_handle_(0),
+      previous_100ns_timestamp_(NULL),
+      wbem_service_(NULL),
+      wbem_service_proxy_(NULL),
+      wbem_refresher_(NULL),
+      wbem_enum_(NULL)
+{
+    // All resources are allocated in PollingCpu().
+    if (AllocateComplexDataTypes())
+    {
+        StartPollingCpu();
+    }
+    else
+    {
+        assert(false);
+    }
+}
+
+CpuWindows::~CpuWindows()
+{
+    // All resources are reclaimed in StopPollingCpu().
+    StopPollingCpu();
+    DeAllocateComplexDataTypes();
+}
+
+bool CpuWindows::AllocateComplexDataTypes()
+{
+    cpu_polling_thread = ThreadWrapper::CreateThread(
+        CpuWindows::Process,
+        reinterpret_cast<void*>(this),
+        kNormalPriority,
+        "CpuWindows");
+    init_crit_ = CriticalSectionWrapper::CreateCriticalSection();
+    init_cond_ = ConditionVariableWrapper::CreateConditionVariable();
+    terminate_crit_ = CriticalSectionWrapper::CreateCriticalSection();
+    terminate_cond_ = ConditionVariableWrapper::CreateConditionVariable();
+    sleep_event = EventWrapper::Create();
+    return (cpu_polling_thread != NULL) && (init_crit_ != NULL) &&
+           (init_cond_ != NULL) && (terminate_crit_ != NULL) &&
+           (terminate_cond_ != NULL) && (sleep_event != NULL);
+}
+
+void CpuWindows::DeAllocateComplexDataTypes()
+{
+    if (sleep_event != NULL)
+    {
+        delete sleep_event;
+        sleep_event = NULL;
+    }
+    if (terminate_cond_ != NULL)
+    {
+        delete terminate_cond_;
+        terminate_cond_ = NULL;
+    }
+    if (terminate_crit_ != NULL)
+    {
+        delete terminate_crit_;
+        terminate_crit_ = NULL;
+    }
+    if (init_cond_ != NULL)
+    {
+        delete init_cond_;
+        init_cond_ = NULL;
+    }
+    if (init_crit_ != NULL)
+    {
+        delete init_crit_;
+        init_crit_ = NULL;
+    }
+    if (cpu_polling_thread != NULL)
+    {
+        delete cpu_polling_thread;
+        cpu_polling_thread = NULL;
+    }
+}
+
+void CpuWindows::StartPollingCpu()
+{
+    unsigned int dummy_id = 0;
+    if (!cpu_polling_thread->Start(dummy_id))
+    {
+        initialize_ = false;
+        has_terminated_ = true;
+        assert(false);
+    }
+}
+
+bool CpuWindows::StopPollingCpu()
+{
+    {
+        // If StopPollingCpu is called immediately after StartPollingCpu() it is
+        // possible that cpu_polling_thread is in the process of initializing.
+        // Let initialization finish to avoid getting into a bad state.
+        CriticalSectionScoped cs(init_crit_);
+        while(initialize_)
+        {
+            init_cond_->SleepCS(*init_crit_);
+        }
+    }
+
+    CriticalSectionScoped cs(terminate_crit_);
+    terminate_ = true;
+    sleep_event->Set();
+    while (!has_terminated_)
+    {
+        terminate_cond_->SleepCS(*terminate_crit_);
+    }
+    cpu_polling_thread->Stop();
+    delete cpu_polling_thread;
+    cpu_polling_thread = NULL;
+    return true;
+}
+
+bool CpuWindows::Process(void* thread_object)
+{
+    return reinterpret_cast<CpuWindows*>(thread_object)->ProcessImpl();
+}
+
+bool CpuWindows::ProcessImpl()
+{
+    {
+        CriticalSectionScoped cs(terminate_crit_);
+        if (terminate_)
+        {
+            Terminate();
+            terminate_cond_->WakeAll();
+            return false;
+        }
+    }
+    // Initialize on first iteration
+    if (initialize_)
+    {
+        CriticalSectionScoped cs(init_crit_);
+        initialize_ = false;
+        const bool success = Initialize();
+        init_cond_->WakeAll();
+        if (!success || !has_initialized_)
+        {
+            has_initialized_ = false;
+            terminate_ = true;
+            return true;
+        }
+    }
+    // Approximately one seconds sleep for each CPU measurement. Precision is
+    // not important. 1 second refresh rate is also used by Performance Monitor
+    // (perfmon).
+    if(kEventTimeout != sleep_event->Wait(1000))
+    {
+        // Terminating. No need to update CPU usage.
+        assert(terminate_);
+        return true;
+    }
+
+    // UpdateCpuUsage() returns false if a single (or more) CPU read(s) failed.
+    // Not a major problem if it happens.
+    UpdateCpuUsage();
+    return true;
+}
+
+bool CpuWindows::CreateWmiConnection()
+{
+    IWbemLocator* service_locator = NULL;
+    HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL,
+                                  CLSCTX_INPROC_SERVER, IID_IWbemLocator,
+                                  reinterpret_cast<void**> (&service_locator));
+    if (FAILED(hr))
+    {
+        return false;
+    }
+    // To get the WMI service specify the WMI namespace.
+    BSTR wmi_namespace = SysAllocString(L"\\\\.\\root\\cimv2");
+    if (wmi_namespace == NULL)
+    {
+        // This type of failure signifies running out of memory.
+        service_locator->Release();
+        return false;
+    }
+    hr = service_locator->ConnectServer(wmi_namespace, NULL, NULL, NULL, 0L,
+                                        NULL, NULL, &wbem_service_);
+    SysFreeString(wmi_namespace);
+    service_locator->Release();
+    return !FAILED(hr);
+}
+
+// Sets up WMI refresher and enum
+bool CpuWindows::CreatePerfOsRefresher()
+{
+    // Create refresher.
+    HRESULT hr = CoCreateInstance(CLSID_WbemRefresher, NULL,
+                                  CLSCTX_INPROC_SERVER, IID_IWbemRefresher,
+                                  reinterpret_cast<void**> (&wbem_refresher_));
+    if (FAILED(hr))
+    {
+        return false;
+    }
+    // Create PerfOS_Processor enum.
+    IWbemConfigureRefresher* wbem_refresher_config = NULL;
+    hr = wbem_refresher_->QueryInterface(
+        IID_IWbemConfigureRefresher,
+        reinterpret_cast<void**> (&wbem_refresher_config));
+    if (FAILED(hr))
+    {
+        return false;
+    }
+
+    // Create a proxy to the IWbemServices so that a local authentication
+    // can be set up (this is needed to be able to successfully call 
+    // IWbemConfigureRefresher::AddEnum). Setting authentication with
+    // CoInitializeSecurity is process-wide (which is too intrusive).
+    hr = CoCopyProxy(static_cast<IUnknown*> (wbem_service_),
+                     reinterpret_cast<IUnknown**> (&wbem_service_proxy_));
+    if(FAILED(hr))
+    {
+        return false;
+    }
+    // Set local authentication.
+    // RPC_C_AUTHN_WINNT means using NTLM instead of Kerberos which is default.
+    hr = CoSetProxyBlanket(static_cast<IUnknown*> (wbem_service_proxy_),
+                           RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
+                           RPC_C_AUTHN_LEVEL_DEFAULT,
+                           RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
+    if(FAILED(hr))
+    {
+        return false;
+    }
+
+    // Don't care about the particular id for the enum.
+    long enum_id = 0;
+    hr = wbem_refresher_config->AddEnum(wbem_service_proxy_,
+                                        L"Win32_PerfRawData_PerfOS_Processor",
+                                        0, NULL, &wbem_enum_, &enum_id);
+    wbem_refresher_config->Release();
+    wbem_refresher_config = NULL;
+    return !FAILED(hr);
+}
+
+// Have to pull the first round of data to be able set the handles.
+bool CpuWindows::CreatePerfOsCpuHandles()
+{
+    // Update the refresher so that there is data available in wbem_enum_.
+    wbem_refresher_->Refresh(0L);
+
+    // The number of enumerators is the number of processor + 1 (the total).
+    // This is unknown at this point.
+    DWORD number_returned = 0;
+    HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_,
+                                        wbem_enum_access_, &number_returned);
+    // number_returned indicates the number of enumerators that are needed.
+    if (hr == WBEM_E_BUFFER_TOO_SMALL &&
+        number_returned > number_of_objects_)
+    {
+        // Allocate the number IWbemObjectAccess asked for by the
+        // GetObjects(..) function.
+        wbem_enum_access_ = new IWbemObjectAccess*[number_returned];
+        cpu_usage_ = new WebRtc_UWord32[number_returned];
+        previous_processor_timestamp_ = new unsigned __int64[number_returned];
+        previous_100ns_timestamp_ = new unsigned __int64[number_returned];
+        if ((wbem_enum_access_ == NULL) || (cpu_usage_ == NULL) ||
+            (previous_processor_timestamp_ == NULL) ||
+            (previous_100ns_timestamp_ == NULL))
+        {
+            // Out of memory.
+            return false;
+        }
+
+        SecureZeroMemory(wbem_enum_access_, number_returned *
+                         sizeof(IWbemObjectAccess*));
+        memset(cpu_usage_, 0, sizeof(int) * number_returned);
+        memset(previous_processor_timestamp_, 0, sizeof(unsigned __int64) *
+               number_returned);
+        memset(previous_100ns_timestamp_, 0, sizeof(unsigned __int64) *
+               number_returned);
+
+        number_of_objects_ = number_returned;
+        // Read should be successfull now that memory has been allocated.
+        hr = wbem_enum_->GetObjects(0L, number_of_objects_, wbem_enum_access_,
+                                    &number_returned);
+        if (FAILED(hr))
+        {
+            return false;
+        }
+    }
+    else
+    {
+        // 0 enumerators should not be enough. Something has gone wrong here.
+        return false;
+    }
+
+    // Get the enumerator handles that are needed for calculating CPU usage.
+    CIMTYPE cpu_usage_type;
+    hr = wbem_enum_access_[0]->GetPropertyHandle(L"PercentProcessorTime",
+                                                 &cpu_usage_type,
+                                                 &cpu_usage_handle_);
+    if (FAILED(hr))
+    {
+        return false;
+    }
+    CIMTYPE timestamp_sys_100_ns_type;
+    hr = wbem_enum_access_[0]->GetPropertyHandle(L"TimeStamp_Sys100NS",
+                                                 &timestamp_sys_100_ns_type,
+                                                 &timestamp_sys_100_ns_handle_);
+    return !FAILED(hr);
+}
+
+bool CpuWindows::Initialize()
+{
+    if (terminate_)
+    {
+        return false;
+    }
+    // Initialize COM library.
+    HRESULT hr = CoInitializeEx(NULL,COINIT_MULTITHREADED);
+    if (FAILED(hr))
+    {
+        return false;
+    }
+    if (FAILED(hr))
+    {
+        return false;
+    }
+
+    if (!CreateWmiConnection())
+    {
+        return false;
+    }
+    if (!CreatePerfOsRefresher())
+    {
+        return false;
+    }
+    if (!CreatePerfOsCpuHandles())
+    {
+        return false;
+    }
+    has_initialized_ = true;
+    return true;
+}
+
+bool CpuWindows::Terminate()
+{
+    if (has_terminated_)
+    {
+        return false;
+    }
+    // Reverse order of Initialize().
+    // Some compilers complain about deleting NULL though it's well defined
+    if (previous_100ns_timestamp_ != NULL)
+    {
+        delete[] previous_100ns_timestamp_;
+        previous_100ns_timestamp_ = NULL;
+    }
+    if (previous_processor_timestamp_ != NULL)
+    {
+        delete[] previous_processor_timestamp_;
+        previous_processor_timestamp_ = NULL;
+    }
+    if (cpu_usage_ != NULL)
+    {
+        delete[] cpu_usage_;
+        cpu_usage_ = NULL;
+    }
+    if (wbem_enum_access_ != NULL)
+    {
+        for (DWORD i = 0; i < number_of_objects_; i++)
+        {
+            if(wbem_enum_access_[i] != NULL)
+            {
+                wbem_enum_access_[i]->Release();
+            }
+        }
+        delete[] wbem_enum_access_;
+        wbem_enum_access_ = NULL;
+    }
+    if (wbem_enum_ != NULL)
+    {
+        wbem_enum_->Release();
+        wbem_enum_ = NULL;
+    }    
+    if (wbem_refresher_ != NULL)
+    {
+        wbem_refresher_->Release();
+        wbem_refresher_ = NULL;
+    }
+    if (wbem_service_proxy_ != NULL)
+    {
+        wbem_service_proxy_->Release();
+        wbem_service_proxy_ = NULL;
+    }
+    if (wbem_service_ != NULL)
+    {
+        wbem_service_->Release();
+        wbem_service_ = NULL;
+    }
+    // CoUninitialized should be called once for every CoInitializeEx.
+    // Regardless if it failed or not.
+    CoUninitialize();
+    has_terminated_ = true;
+    return true;
+}
+
+bool CpuWindows::UpdateCpuUsage()
+{
+    wbem_refresher_->Refresh(0L);
+    DWORD number_returned = 0;
+    HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_,
+                                        wbem_enum_access_,&number_returned);
+    if (FAILED(hr))
+    {
+        // wbem_enum_access_ has already been allocated. Unless the number of
+        // CPUs change runtime this should not happen.
+        return false;
+    }
+    unsigned __int64 cpu_usage = 0;
+    unsigned __int64 timestamp_100ns = 0;
+    bool returnValue = true;
+    for (DWORD i = 0; i < number_returned; i++)
+    {
+        hr = wbem_enum_access_[i]->ReadQWORD(cpu_usage_handle_,&cpu_usage);
+        if (FAILED(hr))
+        {
+            returnValue = false;
+        }
+        hr = wbem_enum_access_[i]->ReadQWORD(timestamp_sys_100_ns_handle_,
+                                             &timestamp_100ns);
+        if (FAILED(hr))
+        {
+            returnValue = false;
+        }
+        wbem_enum_access_[i]->Release();
+        wbem_enum_access_[i] = NULL;
+
+        const bool wrapparound =
+            (previous_processor_timestamp_[i] > cpu_usage) ||
+            (previous_100ns_timestamp_[i] > timestamp_100ns);
+        const bool first_time = (previous_processor_timestamp_[i] == 0) ||
+                                (previous_100ns_timestamp_[i] == 0);
+        if (wrapparound || first_time)
+        {
+            previous_processor_timestamp_[i] = cpu_usage;
+            previous_100ns_timestamp_[i] = timestamp_100ns;
+            continue;
+        }
+        const unsigned __int64 processor_timestamp_delta =
+            cpu_usage - previous_processor_timestamp_[i];
+        const unsigned __int64 timestamp_100ns_delta =
+            timestamp_100ns - previous_100ns_timestamp_[i];
+
+        if (processor_timestamp_delta >= timestamp_100ns_delta)
+        {
+            cpu_usage_[i] = 0;
+        } else {
+            // Quotient must be float since the division is guaranteed to yield
+            // a value between 0 and 1 which is 0 in integer division.
+            const float delta_quotient =
+                static_cast<float>(processor_timestamp_delta) /
+                static_cast<float>(timestamp_100ns_delta);
+            cpu_usage_[i] = 100 - static_cast<WebRtc_UWord32>(delta_quotient *
+                                                              100);
+        }
+        previous_processor_timestamp_[i] = cpu_usage;
+        previous_100ns_timestamp_[i] = timestamp_100ns;
+    }
+    return returnValue;
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/cpu_win.h b/src/system_wrappers/source/cpu_win.h
new file mode 100644
index 0000000..d15073c
--- /dev/null
+++ b/src/system_wrappers/source/cpu_win.h
@@ -0,0 +1,103 @@
+// This file contains a Windows implementation of CpuWrapper.
+// Note: Windows XP, Windows Server 2003 are the minimum requirements.
+//       The requirements are due to the implementation being based on
+//       WMI.
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_
+
+#include "cpu_wrapper.h"
+
+#include <Wbemidl.h>
+
+namespace webrtc {
+class ConditionVariableWrapper;
+class CriticalSectionWrapper;
+class EventWrapper;
+class ThreadWrapper;
+
+class CpuWindows : public CpuWrapper
+{
+public:
+    virtual WebRtc_Word32 CpuUsage();
+    virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/,
+                                   WebRtc_UWord32 /*length*/) {return -1;}
+    virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32  /*dwProcessID*/) {return -1;}
+
+    virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores,
+                                            WebRtc_UWord32*& cpu_usage);
+
+    virtual void Reset() {}
+    virtual void Stop() {}
+
+    CpuWindows();
+    virtual ~CpuWindows();
+private:
+    bool AllocateComplexDataTypes();
+    void DeAllocateComplexDataTypes();
+
+    void StartPollingCpu();
+    bool StopPollingCpu();
+
+    static bool Process(void* thread_object);
+    bool ProcessImpl();
+
+    bool CreateWmiConnection();
+    bool CreatePerfOsRefresher();
+    bool CreatePerfOsCpuHandles();
+    bool Initialize();
+    bool Terminate();
+
+    bool UpdateCpuUsage();
+
+    ThreadWrapper* cpu_polling_thread;
+
+    bool initialize_;
+    bool has_initialized_;
+    CriticalSectionWrapper* init_crit_;
+    ConditionVariableWrapper* init_cond_;
+
+    bool terminate_;
+    bool has_terminated_;
+    CriticalSectionWrapper* terminate_crit_;
+    ConditionVariableWrapper* terminate_cond_;
+
+    // For sleep with wake-up functionality.
+    EventWrapper* sleep_event;
+
+    // Will be an array. Just care about CPU 0 for now.
+    WebRtc_UWord32* cpu_usage_;
+
+    // One IWbemObjectAccess for each processor and one for the total.
+    // 0-n-1 is the individual processors.
+    // n is the total.
+    IWbemObjectAccess** wbem_enum_access_;
+    DWORD number_of_objects_;
+
+    // Cpu timestamp
+    long cpu_usage_handle_;
+    unsigned __int64* previous_processor_timestamp_;
+
+    // Timestamp
+    long timestamp_sys_100_ns_handle_;
+    unsigned __int64* previous_100ns_timestamp_;
+
+    IWbemServices* wbem_service_;
+    IWbemServices* wbem_service_proxy_;
+
+    IWbemRefresher* wbem_refresher_;
+
+    IWbemHiPerfEnum* wbem_enum_;
+
+};
+} // namespace webrtc
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_WINDOWS_NO_CPOL_H_
diff --git a/src/system_wrappers/source/cpu_wrapper_unittest.cc b/src/system_wrappers/source/cpu_wrapper_unittest.cc
index dd49c3a..cd149dc 100644
--- a/src/system_wrappers/source/cpu_wrapper_unittest.cc
+++ b/src/system_wrappers/source/cpu_wrapper_unittest.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -23,7 +23,14 @@
 using webrtc::scoped_ptr;
 using webrtc::Trace;
 
-TEST(CpuWrapperTest, Usage) {
+// This test is flaky on Windows/Release.
+// http://code.google.com/p/webrtc/issues/detail?id=290
+#ifdef _WIN32
+#define MAYBE_Usage DISABLED_Usage
+#else
+#define MAYBE_Usage Usage
+#endif
+TEST(CpuWrapperTest, MAYBE_Usage) {
   Trace::CreateTrace();
   std::string trace_file = webrtc::test::OutputPath() +
       "cpu_wrapper_unittest.txt";
@@ -42,7 +49,7 @@
   // Initializing the CPU measurements may take a couple of seconds on Windows.
   // Since the initialization is lazy we need to wait until it is completed.
   // Should not take more than 10000 ms.
-  while (cpu_usage_available && (++num_iterations < 10000)) {
+  while (!cpu_usage_available && (++num_iterations < 10000)) {
     if (cores != NULL) {
       ASSERT_GT(num_cores, 0u);
       break;
diff --git a/src/system_wrappers/source/critical_section_posix.cc b/src/system_wrappers/source/critical_section_posix.cc
index b499b9f..70f85f9 100644
--- a/src/system_wrappers/source/critical_section_posix.cc
+++ b/src/system_wrappers/source/critical_section_posix.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -8,31 +8,39 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+// General note: return values for the various pthread synchronization APIs
+// are explicitly ignored here. In Chromium, the same thing is done for release.
+// However, in debugging, failure in these APIs are logged. There is currently
+// no equivalent to DCHECK_EQ in WebRTC code so this is the best we can do here.
+// TODO(henrike): add logging when pthread synchronization APIs are failing.
+
 #include "critical_section_posix.h"
 
 namespace webrtc {
+
 CriticalSectionPosix::CriticalSectionPosix()
 {
     pthread_mutexattr_t attr;
-    pthread_mutexattr_init(&attr);
-    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&_mutex, &attr);
+    (void) pthread_mutexattr_init(&attr);
+    (void) pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    (void) pthread_mutex_init(&_mutex, &attr);
 }
 
 CriticalSectionPosix::~CriticalSectionPosix()
 {
-    pthread_mutex_destroy(&_mutex);
+    (void) pthread_mutex_destroy(&_mutex);
 }
 
 void
 CriticalSectionPosix::Enter()
 {
-    pthread_mutex_lock(&_mutex);
+    (void) pthread_mutex_lock(&_mutex);
 }
 
 void
 CriticalSectionPosix::Leave()
 {
-    pthread_mutex_unlock(&_mutex);
+    (void) pthread_mutex_unlock(&_mutex);
 }
+
 } // namespace webrtc
diff --git a/src/system_wrappers/source/critical_section_unittest.cc b/src/system_wrappers/source/critical_section_unittest.cc
new file mode 100644
index 0000000..c48b9f7
--- /dev/null
+++ b/src/system_wrappers/source/critical_section_unittest.cc
@@ -0,0 +1,167 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifdef _WIN32
+// For Sleep()
+#include <windows.h>
+#else
+// For nanosleep()
+#include <time.h>
+#endif
+
+#include "system_wrappers/interface/critical_section_wrapper.h"
+
+#include "gtest/gtest.h"
+#include "system_wrappers/interface/sleep.h"
+#include "system_wrappers/interface/thread_wrapper.h"
+#include "system_wrappers/interface/trace.h"
+#include "system_wrappers/source/unittest_utilities.h"
+
+namespace webrtc {
+
+namespace {
+
+const bool kLogTrace = false;  // Set to true to enable debug logging to stdout.
+
+#define LOG(...) WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, __VA_ARGS__);
+
+// Cause a process switch. Needed to avoid depending on
+// busy-wait in tests.
+static void SwitchProcess() {
+  // Note - sched_yield has been tried as process switch. This does
+  // not cause a process switch enough of the time for reliability.
+  SleepMs(1);
+}
+
+class ProtectedCount {
+ public:
+  explicit ProtectedCount(CriticalSectionWrapper* crit_sect)
+    : crit_sect_(crit_sect),
+      count_(0) {
+  }
+
+  void Increment() {
+    CriticalSectionScoped cs(crit_sect_);
+    ++count_;
+    LOG("Inc to %d", count_);
+  }
+
+  int Count() const {
+    CriticalSectionScoped cs(crit_sect_);
+    return count_;
+  }
+
+ private:
+  CriticalSectionWrapper* crit_sect_;
+  int count_;
+};
+
+class CritSectTest : public ::testing::Test {
+ public:
+  CritSectTest() : trace_(kLogTrace) {
+  }
+
+  // Waits a number of cycles for the count to reach a given value.
+  // Returns true if the target is reached or passed.
+  bool WaitForCount(int target, ProtectedCount* count) {
+    int loop_counter = 0;
+    // On Posix, this SwitchProcess() needs to be in a loop to make the
+    // test both fast and non-flaky.
+    // With 1 us wait as the switch, up to 7 rounds have been observed.
+    while (count->Count() < target && loop_counter < 100*target) {
+      ++loop_counter;
+      SwitchProcess();
+    }
+    LOG("Test looped %d times\n", loop_counter);
+    return (count->Count() >= target);
+  }
+
+ private:
+  ScopedTracing trace_;
+};
+
+bool LockUnlockThenStopRunFunction(void* obj) {
+  LOG("Wait starting");
+  ProtectedCount* the_count = static_cast<ProtectedCount*> (obj);
+  LOG("Wait incrementing");
+  the_count->Increment();
+  LOG("Wait returning");
+  return false;
+}
+
+TEST_F(CritSectTest, ThreadWakesOnce) {
+  CriticalSectionWrapper* crit_sect
+      = CriticalSectionWrapper::CreateCriticalSection();
+  ProtectedCount count(crit_sect);
+  ThreadWrapper* thread = ThreadWrapper::CreateThread(
+      &LockUnlockThenStopRunFunction, &count);
+  unsigned int id = 42;
+  crit_sect->Enter();
+  ASSERT_TRUE(thread->Start(id));
+  SwitchProcess();
+  // The critical section is of reentrant mode, so this should not release
+  // the lock, even though count.Count() locks and unlocks the critical section
+  // again.
+  // Thus, the thread should not be able to increment the count
+  ASSERT_EQ(0, count.Count());
+  crit_sect->Leave();  // This frees the thread to act.
+  EXPECT_TRUE(WaitForCount(1, &count));
+  EXPECT_TRUE(thread->Stop());
+  delete thread;
+  delete crit_sect;
+}
+
+bool LockUnlockRunFunction(void* obj) {
+  LOG("Wait starting");
+  ProtectedCount* the_count = static_cast<ProtectedCount*> (obj);
+  LOG("Wait incrementing");
+  the_count->Increment();
+  SwitchProcess();
+  LOG("Wait returning");
+  return true;
+}
+
+TEST_F(CritSectTest, ThreadWakesTwice) {
+  CriticalSectionWrapper* crit_sect
+      = CriticalSectionWrapper::CreateCriticalSection();
+  ProtectedCount count(crit_sect);
+  ThreadWrapper* thread = ThreadWrapper::CreateThread(&LockUnlockRunFunction,
+                                                      &count);
+  unsigned int id = 42;
+  crit_sect->Enter();  // Make sure counter stays 0 until we wait for it.
+  ASSERT_TRUE(thread->Start(id));
+  crit_sect->Leave();
+
+  // The thread is capable of grabbing the lock multiple times,
+  // incrementing counter once each time.
+  // It's possible for the count to be incremented by more than 2.
+  EXPECT_TRUE(WaitForCount(2, &count));
+  EXPECT_LE(2, count.Count());
+
+  // The thread does not increment while lock is held.
+  crit_sect->Enter();
+  int count_before = count.Count();
+  for (int i = 0; i < 10; i++) {
+    SwitchProcess();
+  }
+  EXPECT_EQ(count_before, count.Count());
+  crit_sect->Leave();
+
+  thread->SetNotAlive();  // Tell thread to exit once run function finishes.
+  SwitchProcess();
+  EXPECT_LT(count_before, count.Count());
+  EXPECT_TRUE(thread->Stop());
+  delete thread;
+  delete crit_sect;
+}
+
+}  // anonymous namespace
+
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/critical_section_win.cc b/src/system_wrappers/source/critical_section_win.cc
new file mode 100644
index 0000000..bbc66e5
--- /dev/null
+++ b/src/system_wrappers/source/critical_section_win.cc
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "critical_section_win.h"
+
+namespace webrtc {
+CriticalSectionWindows::CriticalSectionWindows()
+{
+    InitializeCriticalSection(&crit);
+}
+
+CriticalSectionWindows::~CriticalSectionWindows()
+{
+    DeleteCriticalSection(&crit);
+}
+
+void
+CriticalSectionWindows::Enter()
+{
+    EnterCriticalSection(&crit);
+}
+
+void
+CriticalSectionWindows::Leave()
+{
+    LeaveCriticalSection(&crit);
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/critical_section_win.h b/src/system_wrappers/source/critical_section_win.h
new file mode 100644
index 0000000..9556fa9
--- /dev/null
+++ b/src/system_wrappers/source/critical_section_win.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_
+
+#include "typedefs.h"
+#include "critical_section_wrapper.h"
+#include <windows.h>
+
+namespace webrtc {
+class CriticalSectionWindows : public CriticalSectionWrapper
+{
+public:
+    CriticalSectionWindows();
+
+    virtual ~CriticalSectionWindows();
+
+    virtual void Enter();
+    virtual void Leave();
+
+private:
+    CRITICAL_SECTION crit;
+
+    friend class ConditionVariableWindows;
+};
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_
diff --git a/src/system_wrappers/source/event_win.cc b/src/system_wrappers/source/event_win.cc
new file mode 100644
index 0000000..efcb5af
--- /dev/null
+++ b/src/system_wrappers/source/event_win.cc
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "event_win.h"
+
+#include "Mmsystem.h"
+
+namespace webrtc {
+EventWindows::EventWindows()
+    : _event(::CreateEvent(NULL  /* security attributes */,
+                           FALSE /* manual reset */,
+                           FALSE /* initial state */,
+                           NULL  /* name of event */)),
+      _timerID(NULL)
+{
+}
+
+EventWindows::~EventWindows()
+{
+    CloseHandle(_event);
+}
+
+bool EventWindows::Set()
+{
+    // Note: setting an event that is already set has no effect.
+    return SetEvent(_event) == 1 ? true : false;
+}
+
+bool EventWindows::Reset()
+{
+    return ResetEvent(_event) == 1 ? true : false;
+}
+
+EventTypeWrapper EventWindows::Wait(unsigned long maxTime)
+{
+    unsigned long res = WaitForSingleObject(_event, maxTime);
+    switch(res)
+    {
+    case WAIT_OBJECT_0:
+        return kEventSignaled;
+    case WAIT_TIMEOUT:
+        return kEventTimeout;
+    default:
+        return kEventError;
+    }
+}
+
+bool EventWindows::StartTimer(bool periodic, unsigned long time)
+{
+    if (_timerID != NULL)
+    {
+        timeKillEvent(_timerID);
+        _timerID=NULL;
+    }
+    if (periodic)
+    {
+        _timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0,
+                              TIME_PERIODIC|TIME_CALLBACK_EVENT_PULSE);
+    } else {
+        _timerID=timeSetEvent(time, 0,(LPTIMECALLBACK)HANDLE(_event),0,
+                              TIME_ONESHOT|TIME_CALLBACK_EVENT_SET);
+    }
+
+    if (_timerID == NULL)
+    {
+        return false;
+    }
+    return true;
+}
+
+bool EventWindows::StopTimer()
+{
+    timeKillEvent(_timerID);
+    _timerID = NULL;
+    return true;
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/event_win.h b/src/system_wrappers/source/event_win.h
new file mode 100644
index 0000000..8ca1360
--- /dev/null
+++ b/src/system_wrappers/source/event_win.h
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_
+
+#include <windows.h>
+
+#include "event_wrapper.h"
+
+#include "typedefs.h"
+
+namespace webrtc {
+class EventWindows : public EventWrapper
+{
+public:
+    EventWindows();
+    virtual ~EventWindows();
+
+    virtual EventTypeWrapper Wait(unsigned long maxTime);
+    virtual bool Set();
+    virtual bool Reset();
+
+    virtual bool StartTimer(bool periodic, unsigned long time);
+    virtual bool StopTimer();
+
+private:
+    HANDLE  _event;
+    WebRtc_UWord32 _timerID;
+};
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_EVENT_WINDOWS_H_
diff --git a/src/system_wrappers/source/file_impl.cc b/src/system_wrappers/source/file_impl.cc
index d163bf6..4d06c54 100644
--- a/src/system_wrappers/source/file_impl.cc
+++ b/src/system_wrappers/source/file_impl.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -118,7 +118,7 @@
                               bool loop, bool text)
 {
     size_t length = strlen(fileNameUTF8);
-    if (length > kMaxFileNameSize)
+    if (length > kMaxFileNameSize - 1)
     {
         return -1;
     }
diff --git a/src/system_wrappers/source/rw_lock.cc b/src/system_wrappers/source/rw_lock.cc
index b308358..16da0e3 100644
--- a/src/system_wrappers/source/rw_lock.cc
+++ b/src/system_wrappers/source/rw_lock.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -14,9 +14,6 @@
 
 #if defined(_WIN32)
     #include "rw_lock_win.h"
-#elif defined(WEBRTC_ANDROID)
-    #include <stdlib.h>
-    #include "rw_lock_generic.h"
 #else
     #include "rw_lock_posix.h"
 #endif
@@ -26,8 +23,6 @@
 {
 #ifdef _WIN32
     RWLockWrapper* lock =  new RWLockWindows();
-#elif defined(WEBRTC_ANDROID)
-    RWLockWrapper* lock =  new RWLockWrapperGeneric();
 #else
     RWLockWrapper* lock =  new RWLockPosix();
 #endif
diff --git a/src/system_wrappers/source/rw_lock_win.cc b/src/system_wrappers/source/rw_lock_win.cc
new file mode 100644
index 0000000..82cd0ac
--- /dev/null
+++ b/src/system_wrappers/source/rw_lock_win.cc
@@ -0,0 +1,186 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "rw_lock_win.h"
+
+#include "critical_section_wrapper.h"
+#include "condition_variable_wrapper.h"
+#include "trace.h"
+
+// TODO (hellner) why not just use the rw_lock_generic.cc solution if
+//                           native is not supported? Unnecessary redundancy!
+
+namespace webrtc {
+bool RWLockWindows::_winSupportRWLockPrimitive = false;
+static HMODULE library = NULL;
+
+PInitializeSRWLock       _PInitializeSRWLock;
+PAcquireSRWLockExclusive _PAcquireSRWLockExclusive;
+PAcquireSRWLockShared    _PAcquireSRWLockShared;
+PReleaseSRWLockShared    _PReleaseSRWLockShared;
+PReleaseSRWLockExclusive _PReleaseSRWLockExclusive;
+
+RWLockWindows::RWLockWindows()
+    : _critSectPtr(NULL),
+      _readCondPtr(NULL),
+      _writeCondPtr(NULL),
+      _readersActive(0),
+      _writerActive(false),
+      _readersWaiting(0),
+      _writersWaiting(0)
+{
+}
+
+RWLockWindows::~RWLockWindows()
+{
+    delete _writeCondPtr;
+    delete _readCondPtr;
+    delete _critSectPtr;
+}
+
+int RWLockWindows::Init()
+{
+    if(!library)
+    {
+        // Use native implementation if supported (i.e Vista+)
+        library = LoadLibrary(TEXT("Kernel32.dll"));
+        if(library)
+        {
+            WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
+                         "Loaded Kernel.dll");
+
+            _PInitializeSRWLock =
+                (PInitializeSRWLock)GetProcAddress(
+                    library,
+                    "InitializeSRWLock");
+
+            _PAcquireSRWLockExclusive =
+               (PAcquireSRWLockExclusive)GetProcAddress(
+                   library,
+                   "AcquireSRWLockExclusive");
+            _PReleaseSRWLockExclusive =
+                (PReleaseSRWLockExclusive)GetProcAddress(
+                    library,
+                    "ReleaseSRWLockExclusive");
+            _PAcquireSRWLockShared =
+                (PAcquireSRWLockShared)GetProcAddress(
+                    library,
+                    "AcquireSRWLockShared");
+            _PReleaseSRWLockShared =
+                (PReleaseSRWLockShared)GetProcAddress(
+                    library,
+                    "ReleaseSRWLockShared");
+
+            if( _PInitializeSRWLock &&
+                _PAcquireSRWLockExclusive &&
+                _PReleaseSRWLockExclusive &&
+                _PAcquireSRWLockShared &&
+                _PReleaseSRWLockShared )
+            {
+                WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
+                            "Loaded Simple RW Lock");
+                _winSupportRWLockPrimitive = true;
+            }
+        }
+    }
+    if(_winSupportRWLockPrimitive)
+    {
+        _PInitializeSRWLock(&_lock);
+    } else {
+        _critSectPtr  = CriticalSectionWrapper::CreateCriticalSection();
+        _readCondPtr  = ConditionVariableWrapper::CreateConditionVariable();
+        _writeCondPtr = ConditionVariableWrapper::CreateConditionVariable();
+    }
+    return 0;
+}
+
+void RWLockWindows::AcquireLockExclusive()
+{
+    if (_winSupportRWLockPrimitive)
+    {
+        _PAcquireSRWLockExclusive(&_lock);
+    } else {
+        _critSectPtr->Enter();
+
+        if (_writerActive || _readersActive > 0)
+        {
+            ++_writersWaiting;
+            while (_writerActive || _readersActive > 0)
+            {
+                _writeCondPtr->SleepCS(*_critSectPtr);
+            }
+            --_writersWaiting;
+        }
+        _writerActive = true;
+        _critSectPtr->Leave();
+    }
+}
+
+void RWLockWindows::ReleaseLockExclusive()
+{
+    if(_winSupportRWLockPrimitive)
+    {
+        _PReleaseSRWLockExclusive(&_lock);
+    } else {
+        _critSectPtr->Enter();
+        _writerActive = false;
+        if (_writersWaiting > 0)
+        {
+            _writeCondPtr->Wake();
+
+        }else if (_readersWaiting > 0) {
+            _readCondPtr->WakeAll();
+        }
+        _critSectPtr->Leave();
+    }
+}
+
+void RWLockWindows::AcquireLockShared()
+{
+    if(_winSupportRWLockPrimitive)
+    {
+        _PAcquireSRWLockShared(&_lock);
+    } else
+    {
+        _critSectPtr->Enter();
+        if (_writerActive || _writersWaiting > 0)
+        {
+            ++_readersWaiting;
+
+            while (_writerActive || _writersWaiting > 0)
+            {
+                _readCondPtr->SleepCS(*_critSectPtr);
+            }
+            --_readersWaiting;
+        }
+        ++_readersActive;
+        _critSectPtr->Leave();
+    }
+}
+
+void RWLockWindows::ReleaseLockShared()
+{
+    if(_winSupportRWLockPrimitive)
+    {
+        _PReleaseSRWLockShared(&_lock);
+    } else
+    {
+        _critSectPtr->Enter();
+
+        --_readersActive;
+
+        if (_readersActive == 0 && _writersWaiting > 0)
+        {
+            _writeCondPtr->Wake();
+        }
+        _critSectPtr->Leave();
+    }
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/rw_lock_win.h b/src/system_wrappers/source/rw_lock_win.h
new file mode 100644
index 0000000..dc5355e
--- /dev/null
+++ b/src/system_wrappers/source/rw_lock_win.h
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_
+
+#include "rw_lock_wrapper.h"
+
+#include <Windows.h>
+
+#if !defined(RTL_SRWLOCK_INIT)
+    typedef struct _RTL_SRWLOCK
+    {
+        void* Ptr;
+    } RTL_SRWLOCK, *PRTL_SRWLOCK;
+    typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+#endif
+
+namespace webrtc {
+class CriticalSectionWrapper;
+class ConditionVariableWrapper;
+
+typedef void (WINAPI *PInitializeSRWLock)(PSRWLOCK);
+
+typedef void (WINAPI *PAcquireSRWLockExclusive)(PSRWLOCK);
+typedef void (WINAPI *PReleaseSRWLockExclusive)(PSRWLOCK);
+
+typedef void (WINAPI *PAcquireSRWLockShared)(PSRWLOCK);
+typedef void (WINAPI *PReleaseSRWLockShared)(PSRWLOCK);
+
+
+class RWLockWindows :public RWLockWrapper
+{
+public:
+    RWLockWindows();
+    virtual ~RWLockWindows();
+
+    virtual void AcquireLockExclusive();
+    virtual void ReleaseLockExclusive();
+
+    virtual void AcquireLockShared();
+    virtual void ReleaseLockShared();
+
+protected:
+    virtual int Init();
+
+private:
+    // For native implementation.
+    static bool _winSupportRWLockPrimitive;
+    SRWLOCK     _lock;
+
+    // Genric implementation, fallback if native is not supported.
+    CriticalSectionWrapper*   _critSectPtr;
+    ConditionVariableWrapper* _readCondPtr;
+    ConditionVariableWrapper* _writeCondPtr;
+
+    int  _readersActive;
+    bool _writerActive;
+    int  _readersWaiting;
+    int  _writersWaiting;
+};
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_RW_LOCK_WINDOWS_H_
diff --git a/src/system_wrappers/source/set_thread_name_win.h b/src/system_wrappers/source/set_thread_name_win.h
new file mode 100644
index 0000000..a46f4d6
--- /dev/null
+++ b/src/system_wrappers/source/set_thread_name_win.h
@@ -0,0 +1,43 @@
+/*
+ *  Use of this source code is governed by the MICROSOFT LIMITED PUBLIC LICENSE
+ *  copyright license which can be found in the LICENSE file in the
+ *  third_party_mods/mslpl directory of the source tree or at
+ *  http://msdn.microsoft.com/en-us/cc300389.aspx#P.
+ */
+/*
+ *  The original code can be found here:
+ *  http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.71).aspx
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_
+
+namespace webrtc {
+
+struct THREADNAME_INFO
+{
+   DWORD dwType;     // must be 0x1000
+   LPCSTR szName;    // pointer to name (in user addr space)
+   DWORD dwThreadID; // thread ID (-1 = caller thread)
+   DWORD dwFlags;    // reserved for future use, must be zero
+};
+
+void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
+{
+    THREADNAME_INFO info;
+    info.dwType = 0x1000;
+    info.szName = szThreadName;
+    info.dwThreadID = dwThreadID;
+    info.dwFlags = 0;
+
+    __try
+    {
+        RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD),
+                       (ULONG_PTR*)&info);
+    }
+    __except (EXCEPTION_CONTINUE_EXECUTION)
+    {
+    }
+}
+} // namespace webrtc
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_SET_NAME_H_
diff --git a/src/system_wrappers/source/sleep.cc b/src/system_wrappers/source/sleep.cc
new file mode 100644
index 0000000..be85238
--- /dev/null
+++ b/src/system_wrappers/source/sleep.cc
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+// An OS-independent sleep function.
+
+#include "system_wrappers/interface/sleep.h"
+
+#ifdef _WIN32
+// For Sleep()
+#include <windows.h>
+#else
+// For nanosleep()
+#include <time.h>
+#endif
+
+namespace webrtc {
+
+void SleepMs(int msecs) {
+#ifdef _WIN32
+  Sleep(msecs);
+#else
+  struct timespec short_wait;
+  struct timespec remainder;
+  short_wait.tv_sec = msecs / 1000;
+  short_wait.tv_nsec = (msecs % 1000) * 1000 * 1000;
+  nanosleep(&short_wait, &remainder);
+#endif
+}
+
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/sort.cc b/src/system_wrappers/source/sort.cc
index f44b644..34aa437 100644
--- a/src/system_wrappers/source/sort.cc
+++ b/src/system_wrappers/source/sort.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -412,8 +412,6 @@
         case TYPE_Float64:
             StdSort<double>(data, numOfElements);
             break;
-        default:
-            return -1;
         }
 #endif
         return 0;
@@ -543,9 +541,9 @@
             return StdKeySort<float>(data, key, numOfElements, sizeOfElement);
         case TYPE_Float64:
             return StdKeySort<double>(data, key, numOfElements, sizeOfElement);
-        default:
-            return -1;
         }
+        assert(false);
+        return -1;
 #endif
     }
 } // namespace webrtc
diff --git a/src/system_wrappers/source/system_wrappers.gyp b/src/system_wrappers/source/system_wrappers.gyp
index ce2438f..b530d6f 100644
--- a/src/system_wrappers/source/system_wrappers.gyp
+++ b/src/system_wrappers/source/system_wrappers.gyp
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 #
 # Use of this source code is governed by a BSD-style license
 # that can be found in the LICENSE file in the root of the source
@@ -23,7 +23,8 @@
       },
       'sources': [
         '../interface/aligned_malloc.h',
-        '../interface/atomic32_wrapper.h',
+        '../interface/atomic32.h',
+        '../interface/compile_assert.h',
         '../interface/condition_variable_wrapper.h',
         '../interface/cpu_info.h',
         '../interface/cpu_wrapper.h',
@@ -41,16 +42,16 @@
         '../interface/rw_lock_wrapper.h',
         '../interface/scoped_ptr.h',
         '../interface/scoped_refptr.h',
+        '../interface/sleep.h',
         '../interface/sort.h',
         '../interface/static_instance.h',
         '../interface/thread_wrapper.h',
         '../interface/tick_util.h',
         '../interface/trace.h',
         'aligned_malloc.cc',
-        'atomic32.cc',
-        'atomic32_linux.h',
-        'atomic32_mac.h',
-        'atomic32_win.h',
+        'atomic32_mac.cc',
+        'atomic32_posix.cc',
+        'atomic32_win.cc',
         'condition_variable.cc',
         'condition_variable_posix.cc',
         'condition_variable_posix.h',
@@ -88,6 +89,7 @@
         'rw_lock_posix.h',
         'rw_lock_win.cc',
         'rw_lock_win.h',
+        'sleep.cc',
         'sort.cc',
         'thread.cc',
         'thread_posix.cc',
@@ -109,6 +111,9 @@
         },{
           'sources!': [ 'data_log.cc', ],
         },],
+        ['OS=="android"', {
+          'dependencies': [ 'cpu_features_android', ],
+        }],
         ['OS=="linux"', {
           'link_settings': {
             'libraries': [ '-lrt', ],
@@ -118,6 +123,9 @@
           'link_settings': {
             'libraries': [ '$(SDKROOT)/System/Library/Frameworks/ApplicationServices.framework', ],
           },
+          'sources!': [
+            'atomic32_posix.cc',
+          ],
         }],
         ['OS=="win"', {
           'link_settings': {
@@ -147,18 +155,41 @@
     },
   ], # targets
   'conditions': [
-    ['build_with_chromium==0', {
+    ['OS=="android"', {
+      'targets': [
+        {
+          'variables': {
+            # Treat this as third-party code.
+            'chromium_code': 0,
+          },
+          'target_name': 'cpu_features_android',
+          'type': '<(library)',
+          'sources': [
+            'android/cpu-features.c',
+            'android/cpu-features.h',
+            # TODO(leozwang): Ideally we want to audomatically exclude .c files
+            # as with .cc files, gyp currently only excludes .cc files.
+            'cpu_features_android.c',
+          ],
+        },
+      ],
+    }],
+    ['include_tests==1', {
       'targets': [
         {
           'target_name': 'system_wrappers_unittests',
           'type': 'executable',
           'dependencies': [
             'system_wrappers',
-            '<(webrtc_root)/../testing/gtest.gyp:gtest',
-            '<(webrtc_root)/../test/test.gyp:test_support_main',
+            '<(DEPTH)/testing/gtest.gyp:gtest',
+            '<(webrtc_root)/test/test.gyp:test_support_main',
           ],
           'sources': [
+            'condition_variable_unittest.cc',
             'cpu_wrapper_unittest.cc',
+            'cpu_measurement_harness.h',
+            'cpu_measurement_harness.cc',
+            'critical_section_unittest.cc',
             'list_unittest.cc',
             'map_unittest.cc',
             'data_log_unittest.cc',
@@ -166,6 +197,9 @@
             'data_log_helpers_unittest.cc',
             'data_log_c_helpers_unittest.c',
             'data_log_c_helpers_unittest.h',
+            'thread_unittest.cc',
+            'trace_unittest.cc',
+            'unittest_utilities_unittest.cc',
           ],
           'conditions': [
             ['enable_data_logging==1', {
@@ -176,7 +210,7 @@
           ],
         },
       ], # targets
-    }], # build_with_chromium
+    }], # include_tests
   ], # conditions
 }
 
diff --git a/src/system_wrappers/source/thread_posix.cc b/src/system_wrappers/source/thread_posix.cc
index eb0e8f4..6334490 100644
--- a/src/system_wrappers/source/thread_posix.cc
+++ b/src/system_wrappers/source/thread_posix.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -8,6 +8,40 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+// The state of a thread is controlled by the two member variables
+// _alive and _dead.
+// _alive represents the state the thread has been ordered to achieve.
+// It is set to true by the thread at startup, and is set to false by
+// other threads, using SetNotAlive() and Stop().
+// _dead represents the state the thread has achieved.
+// It is written by the thread encapsulated by this class only
+// (except at init). It is read only by the Stop() method.
+// The Run() method fires _event when it's started; this ensures that the
+// Start() method does not continue until after _dead is false.
+// This protects against premature Stop() calls from the creator thread, but
+// not from other threads.
+
+// Their transitions and states:
+// _alive    _dead  Set by
+// false     true   Constructor
+// true      false  Run() method entry
+// false     any    Run() method runFunction failure
+// any       false  Run() method exit (happens only with _alive false)
+// false     any    SetNotAlive
+// false     any    Stop         Stop waits for _dead to become true.
+//
+// Summarized a different way:
+// Variable   Writer               Reader
+// _alive     Constructor(false)   Run.loop
+//            Run.start(true)
+//            Run.fail(false)
+//            SetNotAlive(false)
+//            Stop(false)
+//
+// _dead      Constructor(true)    Stop.loop
+//            Run.start(false)
+//            Run.exit(true)
+
 #include "thread_posix.h"
 
 #include <errno.h>
@@ -22,8 +56,13 @@
 #include <sys/prctl.h>
 #endif
 
-#include "event_wrapper.h"
-#include "trace.h"
+#if defined(WEBRTC_MAC)
+#include <mach/mach.h>
+#endif
+
+#include "system_wrappers/interface/critical_section_wrapper.h"
+#include "system_wrappers/interface/event_wrapper.h"
+#include "system_wrappers/interface/trace.h"
 
 namespace webrtc {
 extern "C"
@@ -35,17 +74,6 @@
     }
 }
 
-#if (defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID))
-static pid_t gettid()
-{
-#if defined(__NR_gettid)
-    return  syscall(__NR_gettid);
-#else
-    return -1;
-#endif
-}
-#endif
-
 ThreadWrapper* ThreadPosix::Create(ThreadRunFunction func, ThreadObj obj,
                                    ThreadPriority prio, const char* threadName)
 {
@@ -67,22 +95,37 @@
                          ThreadPriority prio, const char* threadName)
     : _runFunction(func),
       _obj(obj),
+      _crit_state(CriticalSectionWrapper::CreateCriticalSection()),
       _alive(false),
       _dead(true),
       _prio(prio),
       _event(EventWrapper::Create()),
-      _setThreadName(false)
-{
-#ifdef WEBRTC_LINUX
-    _linuxPid = -1;
+      _name(),
+      _setThreadName(false),
+#if (defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID))
+      _pid(-1),
 #endif
+      _attr(),
+      _thread(0)
+{
     if (threadName != NULL)
     {
         _setThreadName = true;
         strncpy(_name, threadName, kThreadMaxNameLength);
+        _name[kThreadMaxNameLength - 1] = '\0';
     }
 }
 
+uint32_t ThreadWrapper::GetThreadId() {
+#if defined(WEBRTC_ANDROID) || defined(WEBRTC_LINUX)
+  return static_cast<uint32_t>(syscall(__NR_gettid));
+#elif defined(WEBRTC_MAC)
+  return static_cast<uint32_t>(mach_thread_self());
+#else
+  return reinterpret_cast<uint32_t>(pthread_self());
+#endif
+}
+
 int ThreadPosix::Construct()
 {
     int result = 0;
@@ -104,7 +147,6 @@
     {
         return -1;
     }
-
     return 0;
 }
 
@@ -112,6 +154,7 @@
 {
     pthread_attr_destroy(&_attr);
     delete _event;
+    delete _crit_state;
 }
 
 #define HAS_THREAD_ID !defined(MAC_IPHONE) && !defined(MAC_IPHONE_SIM)  &&  \
@@ -180,8 +223,6 @@
     case kRealtimePriority:
         param.sched_priority = maxPrio - 1;
         break;
-    default:
-        return false;
     }
     result = pthread_setschedparam(_thread, policy, &param);
     if (result == EINVAL)
@@ -191,33 +232,40 @@
     return true;
 }
 
-#if (defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID))
+// CPU_ZERO and CPU_SET are not available in NDK r7, so disable
+// SetAffinity on Android for now.
+#if (defined(WEBRTC_LINUX) && (!defined(WEBRTC_ANDROID)))
 bool ThreadPosix::SetAffinity(const int* processorNumbers,
-                              const unsigned int amountOfProcessors)
-{
-    if (!processorNumbers || (amountOfProcessors == 0))
-    {
-        return false;
-    }
+                              const unsigned int amountOfProcessors) {
+  if (!processorNumbers || (amountOfProcessors == 0)) {
+    return false;
+  }
+  cpu_set_t mask;
+  CPU_ZERO(&mask);
 
-    cpu_set_t mask;
-    CPU_ZERO(&mask);
-
-    for(unsigned int processor = 0;
-        processor < amountOfProcessors;
-        processor++)
-    {
-        CPU_SET(processorNumbers[processor], &mask);
-    }
-    const int result = sched_setaffinity(_linuxPid, (unsigned int)sizeof(mask),
-                                         &mask);
-    if (result != 0)
-    {
-        return false;
-
-    }
-    return true;
+  for (unsigned int processor = 0;
+      processor < amountOfProcessors;
+      processor++) {
+    CPU_SET(processorNumbers[processor], &mask);
+  }
+#if defined(WEBRTC_ANDROID)
+  // Android.
+  const int result = syscall(__NR_sched_setaffinity,
+                             _pid,
+                             sizeof(mask),
+                             &mask);
+#else
+  // "Normal" Linux.
+  const int result = sched_setaffinity(_pid,
+                                       sizeof(mask),
+                                       &mask);
+#endif
+  if (result != 0) {
+    return false;
+  }
+  return true;
 }
+
 #else
 // NOTE: On Mac OS X, use the Thread affinity API in
 // /usr/include/mach/thread_policy.h: thread_policy_set and mach_thread_self()
@@ -230,6 +278,7 @@
 
 void ThreadPosix::SetNotAlive()
 {
+    CriticalSectionScoped cs(_crit_state);
     _alive = false;
 }
 
@@ -249,18 +298,27 @@
 
 bool ThreadPosix::Stop()
 {
-    _alive = false;
+    bool dead = false;
+    {
+        CriticalSectionScoped cs(_crit_state);
+        _alive = false;
+        dead = _dead;
+    }
 
     // TODO (hellner) why not use an event here?
     // Wait up to 10 seconds for the thread to terminate
-    for (int i = 0; i < 1000 && !_dead; i++)
+    for (int i = 0; i < 1000 && !dead; i++)
     {
         timespec t;
         t.tv_sec = 0;
         t.tv_nsec = 10*1000*1000;
         nanosleep(&t, NULL);
+        {
+            CriticalSectionScoped cs(_crit_state);
+            dead = _dead;
+        }
     }
-    if (_dead)
+    if (dead)
     {
         return true;
     }
@@ -272,13 +330,13 @@
 
 void ThreadPosix::Run()
 {
-    _alive = true;
-    _dead  = false;
-#ifdef WEBRTC_LINUX
-    if(_linuxPid == -1)
     {
-        _linuxPid = gettid();
+        CriticalSectionScoped cs(_crit_state);
+        _alive = true;
+        _dead  = false;
     }
+#if (defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID))
+    _pid = GetThreadId();
 #endif
     // The event the Start() is waiting for.
     _event->Set();
@@ -286,38 +344,38 @@
     if (_setThreadName)
     {
 #ifdef WEBRTC_LINUX
-        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,
-                     "Thread with id:%d name:%s started ", _linuxPid, _name);
         prctl(PR_SET_NAME, (unsigned long)_name, 0, 0, 0);
-#else
+#endif
         WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,
                      "Thread with name:%s started ", _name);
-#endif
-    }else
+    } else
     {
-#ifdef WEBRTC_LINUX
-        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
-                     "Thread with id:%d without name started", _linuxPid);
-#else
         WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                      "Thread without name started");
-#endif
     }
+    bool alive = true;
     do
     {
         if (_runFunction)
         {
             if (!_runFunction(_obj))
             {
-                _alive = false;
+                alive = false;
             }
         }
         else
         {
-            _alive = false;
+            alive = false;
+        }
+        {
+            CriticalSectionScoped cs(_crit_state);
+            if (!alive) {
+              _alive = false;
+            }
+            alive = _alive;
         }
     }
-    while (_alive);
+    while (alive);
 
     if (_setThreadName)
     {
@@ -335,6 +393,9 @@
         WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,-1,
                      "Thread without name stopped");
     }
-    _dead = true;
+    {
+        CriticalSectionScoped cs(_crit_state);
+        _dead = true;
+    }
 }
 } // namespace webrtc
diff --git a/src/system_wrappers/source/thread_posix.h b/src/system_wrappers/source/thread_posix.h
index f664a52..45489a8 100644
--- a/src/system_wrappers/source/thread_posix.h
+++ b/src/system_wrappers/source/thread_posix.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -15,6 +15,8 @@
 #include <pthread.h>
 
 namespace webrtc {
+
+class CriticalSectionWrapper;
 class EventWrapper;
 
 class ThreadPosix : public ThreadWrapper
@@ -47,6 +49,7 @@
     ThreadObj           _obj;
 
     // internal state
+    CriticalSectionWrapper* _crit_state;  // Protects _alive and _dead
     bool                    _alive;
     bool                    _dead;
     ThreadPriority          _prio;
@@ -57,12 +60,11 @@
     bool                    _setThreadName;
 
     // handle to thread
+#if (defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID))
+    pid_t                   _pid;
+#endif
     pthread_attr_t          _attr;
     pthread_t               _thread;
-#ifdef WEBRTC_LINUX
-    pid_t                   _linuxPid;
-#endif
-
 };
 } // namespace webrtc
 
diff --git a/src/system_wrappers/source/thread_unittest.cc b/src/system_wrappers/source/thread_unittest.cc
new file mode 100644
index 0000000..361424a
--- /dev/null
+++ b/src/system_wrappers/source/thread_unittest.cc
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "system_wrappers/interface/thread_wrapper.h"
+
+#include "gtest/gtest.h"
+#include "system_wrappers/interface/trace.h"
+
+namespace webrtc {
+
+const int kLogTrace = 0;
+
+class TestTraceCallback : public TraceCallback {
+ public:
+  virtual void Print(const TraceLevel level,
+                     const char* traceString,
+                     const int length) {
+    if (traceString) {
+      char* cmd_print = new char[length+1];
+      memcpy(cmd_print, traceString, length);
+      cmd_print[length] = '\0';
+      printf("%s\n", cmd_print);
+      fflush(stdout);
+      delete[] cmd_print;
+    }
+  }
+};
+
+class ThreadTest : public ::testing::Test {
+ public:
+  ThreadTest() {
+    StartTrace();
+  }
+  ~ThreadTest() {
+    StopTrace();
+  }
+
+ private:
+  void StartTrace() {
+    if (kLogTrace) {
+      Trace::CreateTrace();
+      Trace::SetLevelFilter(webrtc::kTraceAll);
+      Trace::SetTraceCallback(&trace_);
+    }
+  }
+
+  void StopTrace() {
+    if (kLogTrace) {
+      Trace::ReturnTrace();
+    }
+  }
+
+  TestTraceCallback trace_;
+};
+
+// Function that does nothing, and reports success.
+bool NullRunFunction(void* /* obj */) {
+  return true;
+}
+
+TEST_F(ThreadTest, StartStop) {
+  ThreadWrapper* thread = ThreadWrapper::CreateThread(&NullRunFunction);
+  unsigned int id = 42;
+  ASSERT_TRUE(thread->Start(id));
+  EXPECT_TRUE(thread->Stop());
+  delete thread;
+}
+
+// Function that sets a boolean.
+bool SetFlagRunFunction(void* obj) {
+  bool* obj_as_bool = static_cast<bool*> (obj);
+  *obj_as_bool = true;
+  return true;
+}
+
+TEST_F(ThreadTest, RunFunctionIsCalled) {
+  bool flag = false;
+  ThreadWrapper* thread = ThreadWrapper::CreateThread(&SetFlagRunFunction,
+                                                      &flag);
+  unsigned int id = 42;
+  ASSERT_TRUE(thread->Start(id));
+  // At this point, the flag may be either true or false.
+  EXPECT_TRUE(thread->Stop());
+  // We expect the thread to have run at least once.
+  EXPECT_TRUE(flag);
+  delete thread;
+}
+
+}  // namespace webrtc
diff --git a/src/system_wrappers/source/thread_win.cc b/src/system_wrappers/source/thread_win.cc
new file mode 100644
index 0000000..07c586a
--- /dev/null
+++ b/src/system_wrappers/source/thread_win.cc
@@ -0,0 +1,233 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "thread_win.h"
+
+#include <assert.h>
+#include <process.h>
+#include <stdio.h>
+#include <windows.h>
+
+#include "set_thread_name_win.h"
+#include "trace.h"
+
+namespace webrtc {
+ThreadWindows::ThreadWindows(ThreadRunFunction func, ThreadObj obj,
+                             ThreadPriority prio, const char* threadName)
+    : ThreadWrapper(),
+      _runFunction(func),
+      _obj(obj),
+      _alive(false),
+      _dead(true),
+      _doNotCloseHandle(false),
+      _prio(prio),
+      _event(NULL),
+      _thread(NULL),
+      _id(0),
+      _name(),
+      _setThreadName(false)
+{
+    _event = EventWrapper::Create();
+    _critsectStop = CriticalSectionWrapper::CreateCriticalSection();
+    if (threadName != NULL)
+    {
+        // Set the thread name to appear in the VS debugger.
+        _setThreadName = true;
+        strncpy(_name, threadName, kThreadMaxNameLength);
+    }
+}
+
+ThreadWindows::~ThreadWindows()
+{
+#ifdef _DEBUG
+    assert(!_alive);
+#endif
+    if (_thread)
+    {
+        CloseHandle(_thread);
+    }
+    if(_event)
+    {
+        delete _event;
+    }
+    if(_critsectStop)
+    {
+        delete _critsectStop;
+    }
+}
+
+uint32_t ThreadWrapper::GetThreadId() {
+  return GetCurrentThreadId();
+}
+
+unsigned int WINAPI ThreadWindows::StartThread(LPVOID lpParameter)
+{
+    static_cast<ThreadWindows*>(lpParameter)->Run();
+    return 0;
+}
+
+bool ThreadWindows::Start(unsigned int& threadID)
+{
+    _doNotCloseHandle = false;
+
+    // Set stack size to 1M
+    _thread=(HANDLE)_beginthreadex(NULL, 1024*1024, StartThread, (void*)this, 0,
+                                   &threadID);
+    if(_thread == NULL)
+    {
+        return false;
+    }
+    _id = threadID;
+    _event->Wait(INFINITE);
+
+    switch(_prio)
+    {
+    case kLowPriority:
+        SetThreadPriority(_thread, THREAD_PRIORITY_BELOW_NORMAL);
+        break;
+    case kNormalPriority:
+        SetThreadPriority(_thread, THREAD_PRIORITY_NORMAL);
+        break;
+    case kHighPriority:
+        SetThreadPriority(_thread, THREAD_PRIORITY_ABOVE_NORMAL);
+        break;
+    case kHighestPriority:
+        SetThreadPriority(_thread, THREAD_PRIORITY_HIGHEST);
+        break;
+    case kRealtimePriority:
+        SetThreadPriority(_thread, THREAD_PRIORITY_TIME_CRITICAL);
+        break;
+    };
+    return true;
+}
+
+bool ThreadWindows::SetAffinity(const int* processorNumbers,
+                                const unsigned int amountOfProcessors)
+{
+    DWORD_PTR processorBitMask = 0;
+    for(unsigned int processorIndex = 0;
+        processorIndex < amountOfProcessors;
+        processorIndex++)
+    {
+        // Convert from an array with processor numbers to a bitmask
+        // Processor numbers start at zero.
+        // TODO (hellner): this looks like a bug. Shouldn't the '=' be a '+='?
+        // Or even better |=
+        processorBitMask = 1 << processorNumbers[processorIndex];
+    }
+    return SetThreadAffinityMask(_thread,processorBitMask) != 0;
+}
+
+void ThreadWindows::SetNotAlive()
+{
+    _alive = false;
+}
+
+bool ThreadWindows::Shutdown()
+{
+    DWORD exitCode = 0;
+    BOOL ret = TRUE;
+    if (_thread)
+    {
+        ret = TerminateThread(_thread, exitCode);
+        _alive = false;
+        _dead = true;
+        _thread = NULL;
+    }
+    return ret == TRUE;
+}
+
+bool ThreadWindows::Stop()
+{
+    _critsectStop->Enter();
+    // Prevents the handle from being closed in ThreadWindows::Run()
+    _doNotCloseHandle = true;
+    _alive = false;
+    bool signaled = false;
+    if (_thread && !_dead)
+    {
+        _critsectStop->Leave();
+        // Wait up to 2 seconds for the thread to complete.
+        if( WAIT_OBJECT_0 == WaitForSingleObject(_thread, 2000))
+        {
+            signaled = true;
+        }
+        _critsectStop->Enter();
+    }
+    if (_thread)
+    {
+        CloseHandle(_thread);
+        _thread = NULL;
+    }
+    _critsectStop->Leave();
+
+    if (_dead || signaled)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+void ThreadWindows::Run()
+{
+    _alive = true;
+    _dead = false;
+    _event->Set();
+
+    // All tracing must be after _event->Set to avoid deadlock in Trace.
+    if (_setThreadName)
+    {
+        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,
+                     "Thread with name:%s started ", _name);
+        SetThreadName(-1, _name); // -1, set thread name for the calling thread.
+    }else
+    {
+        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,
+                     "Thread without name started");
+    }
+
+    do
+    {
+        if (_runFunction)
+        {
+            if (!_runFunction(_obj))
+            {
+                _alive = false;
+            }
+        } else {
+            _alive = false;
+        }
+    } while(_alive);
+
+    if (_setThreadName)
+    {
+        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, _id,
+                     "Thread with name:%s stopped", _name);
+    } else {
+        WEBRTC_TRACE(kTraceStateInfo, kTraceUtility,_id,
+                     "Thread without name stopped");
+    }
+
+    _critsectStop->Enter();
+
+    if (_thread && !_doNotCloseHandle)
+    {
+        HANDLE thread = _thread;
+        _thread = NULL;
+        CloseHandle(thread);
+    }
+    _dead = true;
+
+    _critsectStop->Leave();
+};
+} // namespace webrtc
diff --git a/src/system_wrappers/source/thread_win.h b/src/system_wrappers/source/thread_win.h
new file mode 100644
index 0000000..4fd7523
--- /dev/null
+++ b/src/system_wrappers/source/thread_win.h
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_
+
+#include "thread_wrapper.h"
+#include "event_wrapper.h"
+#include "critical_section_wrapper.h"
+
+#include <windows.h>
+
+namespace webrtc {
+
+class ThreadWindows : public ThreadWrapper
+{
+public:
+    ThreadWindows(ThreadRunFunction func, ThreadObj obj, ThreadPriority prio,
+                  const char* threadName);
+    virtual ~ThreadWindows();
+
+    virtual bool Start(unsigned int& id);
+    bool SetAffinity(const int* processorNumbers,
+                     const unsigned int amountOfProcessors);
+    virtual bool Stop();
+    virtual void SetNotAlive();
+
+    static unsigned int WINAPI StartThread(LPVOID lpParameter);
+
+    virtual bool Shutdown();
+
+protected:
+    virtual void Run();
+
+private:
+    ThreadRunFunction    _runFunction;
+    ThreadObj            _obj;
+
+    bool                    _alive;
+    bool                    _dead;
+
+    // TODO (hellner)
+    // _doNotCloseHandle member seem pretty redundant. Should be able to remove
+    // it. Basically it should be fine to reclaim the handle when calling stop
+    // and in the destructor.
+    bool                    _doNotCloseHandle;
+    ThreadPriority          _prio;
+    EventWrapper*           _event;
+    CriticalSectionWrapper* _critsectStop;
+
+    HANDLE                  _thread;
+    unsigned int            _id;
+    char                    _name[kThreadMaxNameLength];
+    bool                    _setThreadName;
+
+};
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_THREAD_WINDOWS_H_
diff --git a/src/system_wrappers/source/trace_impl.cc b/src/system_wrappers/source/trace_impl.cc
index 1156519..c6d9296 100644
--- a/src/system_wrappers/source/trace_impl.cc
+++ b/src/system_wrappers/source/trace_impl.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -17,17 +17,16 @@
 #include "trace_win.h"
 #else
 #include <stdio.h>
-#include <time.h>
 #include <stdarg.h>
 #include "trace_posix.h"
 #endif // _WIN32
 
+#include "system_wrappers/interface/sleep.h"
+
 #define KEY_LEN_CHARS 31
 
 #ifdef _WIN32
-    #pragma warning(disable:4355)
-// VS 2005: Disable warnings for default initialized arrays.
-    #pragma warning(disable:4351)
+#pragma warning(disable:4355)
 #endif // _WIN32
 
 namespace webrtc {
@@ -94,7 +93,7 @@
         for(int n = 0; n < WEBRTC_TRACE_MAX_QUEUE; n++)
         {
             _messageQueue[m][n] = new
-                WebRtc_Word8[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
+                char[WEBRTC_TRACE_MAX_MESSAGE_SIZE];
         }
     }
 }
@@ -108,14 +107,7 @@
     // TODO (hellner): why not use condition variables to do this? Or let the
     //                 worker thread die and let this thread flush remaining
     //                 messages?
-#ifdef _WIN32
-    Sleep(10);
-#else
-    timespec t;
-    t.tv_sec = 0;
-    t.tv_nsec = 10*1000000;
-    nanosleep(&t,NULL);
-#endif
+    SleepMs(10);
 
     _thread.SetNotAlive();
     // Make sure the thread finishes as quickly as possible (instead of having
@@ -147,6 +139,12 @@
     }
 }
 
+WebRtc_Word32 TraceImpl::AddThreadId(char* traceMessage) const {
+  WebRtc_UWord32 threadId = ThreadWrapper::GetThreadId();
+  // Messages is 12 characters.
+  return sprintf(traceMessage, "%10u; ", threadId);
+}
+
 WebRtc_Word32 TraceImpl::AddLevel(char* szMessage, const TraceLevel level) const
 {
     switch (level)
@@ -277,9 +275,6 @@
                 sprintf(traceMessage, "  VIDEO PROC:%5ld %5ld;", idEngine,
                         idChannel);
                 break;
-            default:
-                assert(false);
-                return 0;
         }
     } else {
         switch (module)
@@ -335,16 +330,13 @@
             case kTraceVideoPreocessing:
                 sprintf (traceMessage, "  VIDEO PROC:%11ld;", idl);
                 break;
-            default:
-                assert(false);
-                return 0;
         }
     }
     // All messages are 25 characters.
     return 25;
 }
 
-WebRtc_Word32 TraceImpl::SetTraceFileImpl(const WebRtc_Word8* fileNameUTF8,
+WebRtc_Word32 TraceImpl::SetTraceFileImpl(const char* fileNameUTF8,
                                           const bool addFileCounter)
 {
     CriticalSectionScoped lock(_critsectInterface);
@@ -358,7 +350,7 @@
         {
             _fileCountText = 1;
 
-            WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize];
+            char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize];
             CreateFileName(fileNameUTF8, fileNameWithCounterUTF8,
                            _fileCountText);
             if(_traceFile.OpenFile(fileNameWithCounterUTF8, false, false,
@@ -379,7 +371,7 @@
 }
 
 WebRtc_Word32 TraceImpl::TraceFileImpl(
-    WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize])
+    char fileNameUTF8[FileWrapper::kMaxFileNameSize])
 {
     CriticalSectionScoped lock(_critsectInterface);
     return _traceFile.FileName(fileNameUTF8, FileWrapper::kMaxFileNameSize);
@@ -429,8 +421,14 @@
 void TraceImpl::AddMessageToList(
     const char traceMessage[WEBRTC_TRACE_MAX_MESSAGE_SIZE],
     const WebRtc_UWord16 length,
-    const TraceLevel level)
-{
+    const TraceLevel level) {
+#ifdef WEBRTC_DIRECT_TRACE
+    if (_callback) {
+      _callback->Print(level, traceMessage, length);
+    }
+    return;
+#endif
+
     CriticalSectionScoped lock(_critsectArray);
 
     if(_nextFreeIdx[_activeQueue] >= WEBRTC_TRACE_MAX_QUEUE)
@@ -550,8 +548,8 @@
                     _traceFile.Rewind();
                 } else
                 {
-                    WebRtc_Word8 oldFileName[FileWrapper::kMaxFileNameSize];
-                    WebRtc_Word8 newFileName[FileWrapper::kMaxFileNameSize];
+                    char oldFileName[FileWrapper::kMaxFileNameSize];
+                    char newFileName[FileWrapper::kMaxFileNameSize];
 
                     // get current name
                     _traceFile.FileName(oldFileName,
@@ -571,7 +569,7 @@
             }
             if(_rowCountText ==  0)
             {
-                WebRtc_Word8 message[WEBRTC_TRACE_MAX_MESSAGE_SIZE + 1];
+                char message[WEBRTC_TRACE_MAX_MESSAGE_SIZE + 1];
                 WebRtc_Word32 length = AddDateTimeInfo(message);
                 if(length != -1)
                 {
@@ -637,7 +635,7 @@
         ackLen += len;
 
         len = AddThreadId(meassagePtr);
-        if(len == -1)
+        if(len < 0)
         {
             return;
         }
@@ -663,8 +661,8 @@
 }
 
 bool TraceImpl::UpdateFileName(
-    const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],
-    WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
+    const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
+    char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
     const WebRtc_UWord32 newCount) const
 {
     WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
@@ -706,8 +704,8 @@
 }
 
 bool TraceImpl::CreateFileName(
-    const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],
-    WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
+    const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
+    char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
     const WebRtc_UWord32 newCount) const
 {
     WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
@@ -760,7 +758,7 @@
     return 0;
 }
 
-WebRtc_Word32 Trace::TraceFile(WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize])
+WebRtc_Word32 Trace::TraceFile(char fileName[FileWrapper::kMaxFileNameSize])
 {
     TraceImpl* trace = TraceImpl::GetTrace();
     if(trace)
@@ -772,7 +770,7 @@
     return -1;
 }
 
-WebRtc_Word32 Trace::SetTraceFile(const WebRtc_Word8* fileName,
+WebRtc_Word32 Trace::SetTraceFile(const char* fileName,
                                   const bool addFileCounter)
 {
     TraceImpl* trace = TraceImpl::GetTrace();
diff --git a/src/system_wrappers/source/trace_impl.h b/src/system_wrappers/source/trace_impl.h
index 455a3d5..2b85813 100644
--- a/src/system_wrappers/source/trace_impl.h
+++ b/src/system_wrappers/source/trace_impl.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -49,10 +49,10 @@
     static TraceImpl* CreateInstance();
     static TraceImpl* GetTrace(const TraceLevel level = kTraceAll);
 
-    WebRtc_Word32 SetTraceFileImpl(const WebRtc_Word8* fileName,
+    WebRtc_Word32 SetTraceFileImpl(const char* fileName,
                                    const bool addFileCounter);
     WebRtc_Word32 TraceFileImpl(
-        WebRtc_Word8 fileName[FileWrapper::kMaxFileNameSize]);
+        char fileName[FileWrapper::kMaxFileNameSize]);
 
     WebRtc_Word32 SetTraceCallbackImpl(TraceCallback* callback);
 
@@ -69,8 +69,9 @@
     static TraceImpl* StaticInstance(CountOperation count_operation,
         const TraceLevel level = kTraceAll);
 
+    WebRtc_Word32 AddThreadId(char* traceMessage) const;
+
     // OS specific implementations
-    virtual WebRtc_Word32 AddThreadId(char* traceMessage) const = 0;
     virtual WebRtc_Word32 AddTime(char* traceMessage,
                                   const TraceLevel level) const = 0;
 
@@ -98,13 +99,13 @@
         const TraceLevel level);
 
     bool UpdateFileName(
-        const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],
-        WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
+        const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
+        char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
         const WebRtc_UWord32 newCount) const;
 
     bool CreateFileName(
-        const WebRtc_Word8 fileNameUTF8[FileWrapper::kMaxFileNameSize],
-        WebRtc_Word8 fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
+        const char fileNameUTF8[FileWrapper::kMaxFileNameSize],
+        char fileNameWithCounterUTF8[FileWrapper::kMaxFileNameSize],
         const WebRtc_UWord32 newCount) const;
 
     void WriteToFile();
@@ -123,7 +124,7 @@
     WebRtc_UWord16 _nextFreeIdx[WEBRTC_TRACE_NUM_ARRAY];
     TraceLevel _level[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];
     WebRtc_UWord16 _length[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];
-    WebRtc_Word8* _messageQueue[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];
+    char* _messageQueue[WEBRTC_TRACE_NUM_ARRAY][WEBRTC_TRACE_MAX_QUEUE];
     WebRtc_UWord8 _activeQueue;
 };
 } // namespace webrtc
diff --git a/src/system_wrappers/source/trace_impl_no_op.cc b/src/system_wrappers/source/trace_impl_no_op.cc
index 1752871..e74d901 100644
--- a/src/system_wrappers/source/trace_impl_no_op.cc
+++ b/src/system_wrappers/source/trace_impl_no_op.cc
@@ -31,12 +31,12 @@
 }
 
 WebRtc_Word32 Trace::TraceFile(
-    WebRtc_Word8 /*fileName*/[1024])
+    char/*fileName*/[1024])
 {
     return -1;
 }
 
-WebRtc_Word32 Trace::SetTraceFile(const WebRtc_Word8* /*fileName*/,
+WebRtc_Word32 Trace::SetTraceFile(const char* /*fileName*/,
                                   const bool /*addFileCounter*/)
 {
     return -1;
diff --git a/src/system_wrappers/source/trace_posix.cc b/src/system_wrappers/source/trace_posix.cc
index 198c434..1b8dd93 100644
--- a/src/system_wrappers/source/trace_posix.cc
+++ b/src/system_wrappers/source/trace_posix.cc
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -14,10 +14,8 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/time.h>
 #include <time.h>
-#ifdef __linux__
-    #include <sys/syscall.h>
-#endif
 #ifdef WEBRTC_ANDROID
     #include <pthread.h>
 #else
@@ -41,8 +39,9 @@
 namespace webrtc {
 TracePosix::TracePosix()
 {
-    _prevAPITickCount = time(NULL);
-    _prevTickCount = _prevAPITickCount;
+    struct timeval systemTimeHighRes;
+    gettimeofday(&systemTimeHighRes, 0);
+    _prevAPITickCount = _prevTickCount = systemTimeHighRes.tv_sec;
 }
 
 TracePosix::~TracePosix()
@@ -50,69 +49,47 @@
     StopThread();
 }
 
-WebRtc_Word32 TracePosix::AddThreadId(char* traceMessage) const {
-#ifdef __linux__
-  pid_t threadId = (pid_t) syscall(__NR_gettid);
-  sprintf(traceMessage, "%10d; ", threadId);
-#else
-  WebRtc_UWord64 threadId = (WebRtc_UWord64)pthread_self();
-  sprintf(traceMessage, "%10llu; ",
-          static_cast<long long unsigned int>(threadId));
-#endif
-  // 12 bytes are written.
-  return 12;
-}
-
 WebRtc_Word32 TracePosix::AddTime(char* traceMessage,
                                   const TraceLevel level) const
 {
-    time_t dwCurrentTimeInSeconds = time(NULL);
-    struct tm systemTime;
-    gmtime_r(&dwCurrentTimeInSeconds, &systemTime);
-
-    if(level == kTraceApiCall)
+    struct timeval systemTimeHighRes;
+    if (gettimeofday(&systemTimeHighRes, 0) == -1)
     {
-        WebRtc_UWord32 dwDeltaTime = dwCurrentTimeInSeconds - _prevTickCount;
-        _prevTickCount = dwCurrentTimeInSeconds;
-
-        if(_prevTickCount == 0)
-        {
-            dwDeltaTime = 0;
-        }
-        if(dwDeltaTime > 0x0fffffff)
-        {
-            // Either wraparound or data race.
-            dwDeltaTime = 0;
-        }
-        if(dwDeltaTime > 99999)
-        {
-            dwDeltaTime = 99999;
-        }
-
-        sprintf(traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.tm_hour,
-                systemTime.tm_min, systemTime.tm_sec, 0,
-                static_cast<unsigned long>(dwDeltaTime));
-    } else {
-        WebRtc_UWord32 dwDeltaTime = dwCurrentTimeInSeconds - _prevAPITickCount;
-        _prevAPITickCount = dwCurrentTimeInSeconds;
-        if(_prevAPITickCount == 0)
-        {
-            dwDeltaTime = 0;
-        }
-        if(dwDeltaTime > 0x0fffffff)
-        {
-            // Either wraparound or data race.
-            dwDeltaTime = 0;
-        }
-        if(dwDeltaTime > 99999)
-        {
-            dwDeltaTime = 99999;
-        }
-        sprintf(traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.tm_hour,
-                systemTime.tm_min, systemTime.tm_sec, 0,
-                static_cast<unsigned long>(dwDeltaTime));
+        return -1;
     }
-    // Messages is 22 characters.
+    struct tm buffer;
+    const struct tm* systemTime =
+        localtime_r(&systemTimeHighRes.tv_sec, &buffer);
+
+    const WebRtc_UWord32 ms_time = systemTimeHighRes.tv_usec / 1000;
+    WebRtc_UWord32 prevTickCount = 0;
+    if (level == kTraceApiCall)
+    {
+        prevTickCount = _prevTickCount;
+        _prevTickCount = ms_time;
+    } else {
+        prevTickCount = _prevAPITickCount;
+        _prevAPITickCount = ms_time;
+    }
+    WebRtc_UWord32 dwDeltaTime = ms_time - prevTickCount;
+    if (prevTickCount == 0)
+    {
+        dwDeltaTime = 0;
+    }
+    if (dwDeltaTime > 0x0fffffff)
+    {
+        // Either wraparound or data race.
+        dwDeltaTime = 0;
+    }
+    if(dwDeltaTime > 99999)
+    {
+        dwDeltaTime = 99999;
+    }
+
+    sprintf(traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime->tm_hour,
+            systemTime->tm_min, systemTime->tm_sec, ms_time,
+            static_cast<unsigned long>(dwDeltaTime));
+    // Messages are 22 characters.
     return 22;
 }
 
@@ -127,7 +104,8 @@
 {
     time_t t;
     time(&t);
-    sprintf(traceMessage, "Local Date: %s", ctime(&t));
+    char buffer[26];  // man ctime says buffer should have room for >=26 bytes.
+    sprintf(traceMessage, "Local Date: %s", ctime_r(&t, buffer));
     WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(traceMessage));
 
     if ('\n' == traceMessage[len - 1])
diff --git a/src/system_wrappers/source/trace_posix.h b/src/system_wrappers/source/trace_posix.h
index 099bcc8..8c37cd2 100644
--- a/src/system_wrappers/source/trace_posix.h
+++ b/src/system_wrappers/source/trace_posix.h
@@ -21,7 +21,6 @@
     TracePosix();
     virtual ~TracePosix();
 
-    virtual WebRtc_Word32 AddThreadId(char *traceMessage) const;
     virtual WebRtc_Word32 AddTime(char* traceMessage,
                                   const TraceLevel level) const;
 
diff --git a/src/system_wrappers/source/trace_unittest.cc b/src/system_wrappers/source/trace_unittest.cc
new file mode 100644
index 0000000..982e715
--- /dev/null
+++ b/src/system_wrappers/source/trace_unittest.cc
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "system_wrappers/interface/trace.h"
+
+#include "gtest/gtest.h"
+#include "system_wrappers/source/cpu_measurement_harness.h"
+#include "testsupport/fileutils.h"
+
+using webrtc::CpuMeasurementHarness;
+using webrtc::Trace;
+using webrtc::kTraceWarning;
+using webrtc::kTraceUtility;
+
+class Logger : public webrtc::CpuTarget {
+ public:
+  Logger() {
+    Trace::CreateTrace();
+    std::string trace_file = webrtc::test::OutputPath() +
+        "trace_unittest.txt";
+    Trace::SetTraceFile(trace_file.c_str());
+    Trace::SetLevelFilter(webrtc::kTraceAll);
+  }
+  virtual ~Logger() {
+    Trace::ReturnTrace();
+  }
+
+  virtual bool DoWork() {
+    // Use input paremeters to WEBRTC_TRACE that are not likely to be removed
+    // in future code. E.g. warnings will likely be kept and this file is in
+    // utility so it should use kTraceUtility.
+    WEBRTC_TRACE(kTraceWarning, kTraceUtility, 0, "Log line");
+    return true;
+  }
+};
+
+// This test is disabled because it measures CPU usage. This is flaky because
+// the CPU usage for a machine may spike due to OS or other application.
+TEST(TraceTest, DISABLED_CpuUsage) {
+  Logger logger;
+  const int periodicity_ms = 1;
+  const int iterations_per_period = 10;
+  const int duration_ms = 1000;
+  CpuMeasurementHarness* cpu_harness =
+      CpuMeasurementHarness::Create(&logger, periodicity_ms,
+                                    iterations_per_period, duration_ms);
+  cpu_harness->Run();
+  const int average_cpu = cpu_harness->AverageCpu();
+  EXPECT_GE(5, average_cpu);
+}
diff --git a/src/system_wrappers/source/trace_win.cc b/src/system_wrappers/source/trace_win.cc
new file mode 100644
index 0000000..f81ed8b
--- /dev/null
+++ b/src/system_wrappers/source/trace_win.cc
@@ -0,0 +1,131 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "trace_win.h"
+
+#include <cassert>
+#include <stdarg.h>
+
+#include "Mmsystem.h"
+
+#if defined(_DEBUG)
+    #define BUILDMODE "d"
+#elif defined(DEBUG)
+    #define BUILDMODE "d"
+#elif defined(NDEBUG)
+    #define BUILDMODE "r"
+#else
+    #define BUILDMODE "?"
+#endif
+#define BUILDTIME __TIME__
+#define BUILDDATE __DATE__
+// Example: "Oct 10 2002 12:05:30 r"
+#define BUILDINFO BUILDDATE " " BUILDTIME " " BUILDMODE
+
+namespace webrtc {
+TraceWindows::TraceWindows()
+    : _prevAPITickCount(0),
+      _prevTickCount(0)
+{
+}
+
+TraceWindows::~TraceWindows()
+{
+    StopThread();
+}
+
+WebRtc_Word32 TraceWindows::AddTime(char* traceMessage,
+                                    const TraceLevel level) const
+{
+    WebRtc_UWord32 dwCurrentTime = timeGetTime();
+    SYSTEMTIME systemTime;
+    GetSystemTime(&systemTime);
+
+    if(level == kTraceApiCall)
+    {
+        WebRtc_UWord32 dwDeltaTime = dwCurrentTime- _prevTickCount;
+        _prevTickCount = dwCurrentTime;
+
+        if(_prevTickCount == 0)
+        {
+            dwDeltaTime = 0;
+        }
+        if(dwDeltaTime > 0x0fffffff)
+        {
+            // Either wraparound or data race.
+            dwDeltaTime = 0;
+        }
+        if(dwDeltaTime > 99999)
+        {
+            dwDeltaTime = 99999;
+        }
+
+        sprintf (traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.wHour,
+                 systemTime.wMinute, systemTime.wSecond,
+                 systemTime.wMilliseconds, dwDeltaTime);
+    } else {
+        WebRtc_UWord32 dwDeltaTime = dwCurrentTime - _prevAPITickCount;
+        _prevAPITickCount = dwCurrentTime;
+
+        if(_prevAPITickCount == 0)
+        {
+            dwDeltaTime = 0;
+        }
+        if(dwDeltaTime > 0x0fffffff)
+        {
+            // Either wraparound or data race.
+            dwDeltaTime = 0;
+        }
+        if(dwDeltaTime > 99999)
+        {
+            dwDeltaTime = 99999;
+        }
+        sprintf (traceMessage, "(%2u:%2u:%2u:%3u |%5lu) ", systemTime.wHour,
+                 systemTime.wMinute, systemTime.wSecond,
+                 systemTime.wMilliseconds, dwDeltaTime);
+    }
+    // Messages is 12 characters.
+    return 22;
+}
+
+WebRtc_Word32 TraceWindows::AddBuildInfo(char* traceMessage) const
+{
+    // write data and time to text file
+    sprintf(traceMessage, "Build info: %s", BUILDINFO);
+    // Include NULL termination (hence + 1).
+    return static_cast<WebRtc_Word32>(strlen(traceMessage)+1);
+}
+
+WebRtc_Word32 TraceWindows::AddDateTimeInfo(char* traceMessage) const
+{
+    _prevAPITickCount = timeGetTime();
+    _prevTickCount = _prevAPITickCount;
+
+    SYSTEMTIME sysTime;
+    GetLocalTime (&sysTime);
+
+    TCHAR szDateStr[20];
+    TCHAR szTimeStr[20];
+
+    // Create date string (e.g. Apr 04 2002)
+    GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, TEXT("MMM dd yyyy"),
+                  szDateStr, 20);
+
+    // Create time string (e.g. 15:32:08)
+    GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, TEXT("HH':'mm':'ss"),
+                  szTimeStr, 20);
+
+    sprintf(traceMessage, "Local Date: %s Local Time: %s", szDateStr,
+            szTimeStr);
+
+    // Include NULL termination (hence + 1).
+    return static_cast<WebRtc_Word32>(strlen(traceMessage)+ 1);
+}
+} // namespace webrtc
diff --git a/src/system_wrappers/source/trace_win.h b/src/system_wrappers/source/trace_win.h
new file mode 100644
index 0000000..803198e
--- /dev/null
+++ b/src/system_wrappers/source/trace_win.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_
+
+#include "trace_impl.h"
+#include <stdio.h>
+#include <windows.h>
+
+namespace webrtc {
+class TraceWindows : public TraceImpl
+{
+public:
+    TraceWindows();
+    virtual ~TraceWindows();
+
+    virtual WebRtc_Word32 AddTime(char* traceMessage,
+                                  const TraceLevel level) const;
+
+    virtual WebRtc_Word32 AddBuildInfo(char* traceMessage) const;
+    virtual WebRtc_Word32 AddDateTimeInfo(char* traceMessage) const;
+private:
+    volatile mutable WebRtc_UWord32    _prevAPITickCount;
+    volatile mutable WebRtc_UWord32   _prevTickCount;
+};
+} // namespace webrtc
+
+#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_TRACE_WINDOWS_H_
diff --git a/src/system_wrappers/source/unittest_utilities.h b/src/system_wrappers/source/unittest_utilities.h
new file mode 100644
index 0000000..771d798
--- /dev/null
+++ b/src/system_wrappers/source/unittest_utilities.h
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_UNITTEST_UTILITIES_H_
+#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_UNITTEST_UTILITIES_H_
+
+// This file contains utilities that make it simpler to write unittests
+// that are appropriate for the system_wrappers classes.
+
+#include <stdio.h>
+#include <string.h>
+
+#include "system_wrappers/interface/trace.h"
+
+namespace webrtc {
+
+class TestTraceCallback : public TraceCallback {
+ public:
+  virtual void Print(const TraceLevel level,
+                     const char* traceString,
+                     const int length) {
+    if (traceString) {
+      char* cmd_print = new char[length+1];
+      memcpy(cmd_print, traceString, length);
+      cmd_print[length] = '\0';
+      printf("%s\n", cmd_print);
+      fflush(stdout);
+      delete[] cmd_print;
+    }
+  }
+};
+
+// A class that turns on tracing to stdout at the beginning of the test,
+// and turns it off once the test is finished.
+// Intended usage:
+// class SomeTest : public ::testing::Test {
+//  protected:
+//   SomeTest()
+//     : trace_(false) {}  // Change to true to turn on tracing.
+//  private:
+//   ScopedTracing trace_;
+// }
+class ScopedTracing {
+ public:
+  explicit ScopedTracing(bool logOn) {
+    logging_ = logOn;
+    StartTrace();
+  }
+
+  ~ScopedTracing() {
+    StopTrace();
+  }
+
+ private:
+  void StartTrace() {
+    if (logging_) {
+      Trace::CreateTrace();
+      Trace::SetLevelFilter(webrtc::kTraceAll);
+      Trace::SetTraceCallback(&trace_);
+    }
+  }
+
+  void StopTrace() {
+    if (logging_) {
+      Trace::ReturnTrace();
+    }
+  }
+
+ private:
+  bool logging_;
+  TestTraceCallback trace_;
+};
+
+}  // namespace webrtc
+
+#endif  // WEBRTC_SYSTEM_WRAPPERS_SOURCE_UNITTEST_UTILITIES_H_
diff --git a/src/system_wrappers/source/unittest_utilities_unittest.cc b/src/system_wrappers/source/unittest_utilities_unittest.cc
new file mode 100644
index 0000000..6e9a0c6
--- /dev/null
+++ b/src/system_wrappers/source/unittest_utilities_unittest.cc
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "system_wrappers/source/unittest_utilities.h"
+
+#include "gtest/gtest.h"
+#include "system_wrappers/interface/trace.h"
+
+namespace webrtc {
+
+// These tests merely check that the code compiles and that no
+// fatal accidents happen when logging.
+TEST(UnittestUtilities, TraceOn) {
+  ScopedTracing trace(true);
+  WEBRTC_TRACE(kTraceInfo, kTraceUtility, 0, "Log line that should appear");
+  // TODO(hta): Verify that output appears.
+  // Note - output is written on another thread, so can take time to appear.
+}
+
+TEST(UnittestUtilities, TraceOff) {
+  ScopedTracing trace(false);
+  WEBRTC_TRACE(kTraceInfo, kTraceUtility, 0,
+               "Log line that should not appear");
+  // TODO(hta): Verify that no output appears.
+}
+
+}  // namespace webrtc