git-svn-id: http://webrtc.googlecode.com/svn/trunk@156 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/modules/audio_coding/main/test/ACMTest.cpp b/src/modules/audio_coding/main/test/ACMTest.cpp
new file mode 100644
index 0000000..1bbac0e
--- /dev/null
+++ b/src/modules/audio_coding/main/test/ACMTest.cpp
@@ -0,0 +1,16 @@
+/*
+ *  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 "ACMTest.h"
+
+ACMTest::~ACMTest()
+{
+}
+
diff --git a/src/modules/audio_coding/main/test/ACMTest.h b/src/modules/audio_coding/main/test/ACMTest.h
new file mode 100644
index 0000000..e965671
--- /dev/null
+++ b/src/modules/audio_coding/main/test/ACMTest.h
@@ -0,0 +1,21 @@
+/*
+ *  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 ACMTEST_H
+#define ACMTEST_H
+
+class ACMTest
+{
+public:
+    virtual ~ACMTest() =0;
+    virtual void Perform() =0;
+};
+
+#endif
diff --git a/src/modules/audio_coding/main/test/APITest.cpp b/src/modules/audio_coding/main/test/APITest.cpp
new file mode 100644
index 0000000..98c3905
--- /dev/null
+++ b/src/modules/audio_coding/main/test/APITest.cpp
@@ -0,0 +1,1602 @@
+/*
+ *  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 <cctype>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+#include <ostream>
+
+#include "APITest.h"
+#include "thread_wrapper.h"
+#include "event_wrapper.h"
+#include "tick_util.h"
+#include "trace.h"
+#include "utility.h"
+#include "common_types.h"
+#include "engine_configurations.h"
+
+#define TEST_DURATION_SEC 600
+
+#define NUMBER_OF_SENDER_TESTS 6
+
+#define MAX_FILE_NAME_LENGTH_BYTE 500
+#define CHECK_THREAD_NULLITY(myThread, S) if(myThread != NULL){unsigned int i; (myThread)->Start(i);}else{throw S; exit(1);}
+
+using namespace webrtc;
+
+void
+APITest::Wait(WebRtc_UWord32 waitLengthMs)
+{
+    if(_randomTest)
+    {
+        return;
+    }
+    else
+    {
+        EventWrapper* myEvent = EventWrapper::Create();
+        myEvent->Wait(waitLengthMs);
+        delete myEvent;
+        return;
+    }
+}
+
+
+
+APITest::APITest():
+_acmA(NULL),
+_acmB(NULL),
+_channel_A2B(NULL),
+_channel_B2A(NULL),
+_writeToFile(true),
+_pullEventA(NULL),
+_pushEventA(NULL),
+_processEventA(NULL),
+_apiEventA(NULL),
+_pullEventB(NULL),
+_pushEventB(NULL),
+_processEventB(NULL),
+_apiEventB(NULL),
+_codecCntrA(0),
+_codecCntrB(0),
+_testCntrA(1),
+_testCntrB(1),
+_thereIsEncoderA(false),
+_thereIsEncoderB(false),
+_thereIsDecoderA(false),
+_thereIsDecoderB(false),
+_sendVADA(false),
+_sendDTXA(false),
+_sendVADModeA(VADNormal),
+_sendVADB(false),
+_sendDTXB(false),
+_sendVADModeB(VADNormal),
+_minDelayA(0),
+_minDelayB(0),
+_dotPositionA(0),
+_dotMoveDirectionA(1),
+_dotPositionB(39),
+_dotMoveDirectionB(-1),
+_dtmfCallback(NULL),
+_vadCallbackA(NULL),
+_vadCallbackB(NULL),
+_apiTestRWLock(*RWLockWrapper::CreateRWLock()),
+_randomTest(false),
+_testNumA(0),
+_testNumB(1)
+{
+    int n;
+    for( n = 0; n < 32; n++)
+    {
+        _payloadUsed[n] = false;
+    }
+
+    for(n = 0; n < 3; n++)
+    {
+        _receiveVADActivityA[n] = 0;
+        _receiveVADActivityB[n] = 0;
+    }
+    
+    _movingDot[40] = '\0';
+
+    for(int n = 0; n <40; n++)
+    {
+        _movingDot[n]  = ' ';
+    }
+}
+
+APITest::~APITest()
+{
+    DESTROY_ACM(_acmA);
+    DESTROY_ACM(_acmB);
+
+    DELETE_POINTER(_channel_A2B);
+    DELETE_POINTER(_channel_B2A);
+
+    DELETE_POINTER(_pushEventA);
+    DELETE_POINTER(_pullEventA);
+    DELETE_POINTER(_processEventA);
+    DELETE_POINTER(_apiEventA);
+
+    DELETE_POINTER(_pushEventB);
+    DELETE_POINTER(_pullEventB);
+    DELETE_POINTER(_processEventB);
+    DELETE_POINTER(_apiEventB);
+
+    _inFileA.Close();
+    _outFileA.Close();
+
+    _inFileB.Close();
+    _outFileB.Close();
+
+    DELETE_POINTER(_dtmfCallback);
+    DELETE_POINTER(_vadCallbackA);
+    DELETE_POINTER(_vadCallbackB);
+
+    delete &_apiTestRWLock;
+}
+
+
+
+//WebRtc_Word16
+//APITest::SetInFile(char* fileName, WebRtc_UWord16 frequencyHz)
+//{
+//    return _inFile.Open(fileName, frequencyHz, "rb");
+//}
+//
+//WebRtc_Word16
+//APITest::SetOutFile(char* fileName, WebRtc_UWord16 frequencyHz)
+//{
+//    return _outFile.Open(fileName, frequencyHz, "wb");
+//}
+
+WebRtc_Word16 
+APITest::SetUp()
+{
+    _acmA = AudioCodingModule::Create(1);
+    _acmB = AudioCodingModule::Create(2);
+
+    CodecInst dummyCodec;
+    int lastPayloadType = 0;
+
+    WebRtc_Word16 numCodecs = _acmA->NumberOfCodecs();
+    for(WebRtc_UWord8 n = 0; n < numCodecs; n++)
+    {
+        AudioCodingModule::Codec(n, dummyCodec);
+        if((STR_CASE_CMP(dummyCodec.plname, "CN") == 0) &&
+            (dummyCodec.plfreq == 32000))
+        {
+            continue;
+        }
+
+        printf("Register Receive Codec %s  ", dummyCodec.plname);
+
+        if((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname))
+        {
+            // Check registration with an already occupied payload type
+            int currentPayloadType = dummyCodec.pltype;
+            dummyCodec.pltype = 97; //lastPayloadType;
+            CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec));
+            dummyCodec.pltype = currentPayloadType;
+        }
+
+        if((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname))
+        {
+            // test if re-registration works;
+            CodecInst nextCodec;
+            int currentPayloadType = dummyCodec.pltype;
+            AudioCodingModule::Codec(n + 1, nextCodec);
+            dummyCodec.pltype = nextCodec.pltype;
+            if(!FixedPayloadTypeCodec(nextCodec.plname))
+            {
+                _acmB->RegisterReceiveCodec(dummyCodec);
+            }
+            dummyCodec.pltype = currentPayloadType;
+        }
+
+        if((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname))
+        {
+            // test if un-registration works;
+            CodecInst nextCodec;
+            int currentPayloadType = dummyCodec.pltype;
+            AudioCodingModule::Codec(n + 1, nextCodec);
+            nextCodec.pltype = dummyCodec.pltype;
+            if(!FixedPayloadTypeCodec(nextCodec.plname))
+            {
+                CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec));
+                CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype));
+            }
+        }
+
+
+        CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec));
+        printf("   side A done!");
+        CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec));
+        printf("   side B done!\n");
+
+        if(!strcmp(dummyCodec.plname, "CN"))
+        {
+            CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
+            CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
+        }
+        lastPayloadType = dummyCodec.pltype;
+        if((lastPayloadType >= 96) && (lastPayloadType <= 127))
+        {
+            _payloadUsed[lastPayloadType - 96] = true;
+        }
+    }
+    _thereIsDecoderA = true;
+    _thereIsDecoderB = true;
+
+    // Register Send Codec
+    AudioCodingModule::Codec((WebRtc_UWord8)_codecCntrA, dummyCodec);
+    CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec));
+    _thereIsEncoderA = true;
+    //
+    AudioCodingModule::Codec((WebRtc_UWord8)_codecCntrB, dummyCodec);
+    CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec));
+    _thereIsEncoderB = true;
+
+    char fileName[500];
+    WebRtc_UWord16 frequencyHz;
+    
+    printf("\n\nAPI Test\n");
+    printf("========\n");
+    printf("Hit enter to accept the default values indicated in []\n\n");
+
+    //--- Input A
+    strcpy(fileName, "./modules/audio_coding/main/test/testfile32kHz.pcm");
+    frequencyHz = 32000;
+    printf("Enter input file at side A [%s]: ", fileName);
+    PCMFile::ChooseFile(fileName, 499, &frequencyHz);
+    _inFileA.Open(fileName, frequencyHz, "rb", true);
+
+    //--- Output A
+    strcpy(fileName, "./modules/audio_coding/main/test/outA.pcm");
+    printf("Enter output file at side A [%s]: ", fileName);
+    PCMFile::ChooseFile(fileName, 499, &frequencyHz);
+    _outFileA.Open(fileName, frequencyHz, "wb");
+
+    //--- Input B
+    strcpy(fileName, "./modules/audio_coding/main/test/testfile32kHz.pcm");
+    printf("\n\nEnter input file at side B [%s]: ", fileName);
+    PCMFile::ChooseFile(fileName, 499, &frequencyHz);
+    _inFileB.Open(fileName, frequencyHz, "rb", true);
+
+    //--- Output B
+    strcpy(fileName, "./modules/audio_coding/main/test/outB.pcm");
+    printf("Enter output file at side B [%s]: ", fileName);
+    PCMFile::ChooseFile(fileName, 499, &frequencyHz);
+    _outFileB.Open(fileName, frequencyHz, "wb");
+
+    //--- Set A-to-B channel
+    _channel_A2B = new Channel(2);
+    CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B));
+    _channel_A2B->RegisterReceiverACM(_acmB);
+
+    //--- Set B-to-A channel
+    _channel_B2A = new Channel(1);
+    CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A));
+    _channel_B2A->RegisterReceiverACM(_acmA);
+    
+    //--- EVENT TIMERS
+    // A
+    _pullEventA    = EventWrapper::Create();
+    _pushEventA    = EventWrapper::Create();
+    _processEventA = EventWrapper::Create();
+    _apiEventA     = EventWrapper::Create();
+    // B
+    _pullEventB    = EventWrapper::Create();
+    _pushEventB    = EventWrapper::Create();
+    _processEventB = EventWrapper::Create();
+    _apiEventB     = EventWrapper::Create();
+
+    //--- I/O params
+    // A
+    _outFreqHzA = _outFileA.SamplingFrequency();
+    // B
+    _outFreqHzB = _outFileB.SamplingFrequency();
+
+
+    //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt");    
+
+    char print[11];
+
+    printf("\nRandom Test (y/n)?");
+    fgets(print, 10, stdin); 
+    print[10] = '\0';
+    if(strstr(print, "y") != NULL)
+    {
+        _randomTest = true;
+        _verbose = false;
+        _writeToFile = false;
+        Trace::CreateTrace();
+        Trace::SetTraceFile("ACMAPITest.txt");
+        //freopen("APITest_log.txt", "w", stdout);
+    }
+    else
+    {
+        Trace::CreateTrace();
+        Trace::SetTraceFile("ACMAPITest.txt", true);
+        _randomTest = false;
+        printf("\nPrint Tests (y/n)? ");
+        fgets(print, 10, stdin); 
+        print[10] = '\0';
+        if(strstr(print, "y") == NULL)
+        {
+            freopen("APITest_log.txt", "w", stdout);
+            _verbose = false;
+        }
+    }
+
+#ifdef WEBRTC_DTMF_DETECTION
+    _dtmfCallback = new DTMFDetector;
+#endif
+    _vadCallbackA = new VADCallback;
+    _vadCallbackB = new VADCallback;
+    
+    return 0;
+}
+
+bool 
+APITest::PushAudioThreadA(void* obj)
+{
+    return static_cast<APITest*>(obj)->PushAudioRunA();
+}
+
+bool 
+APITest::PushAudioThreadB(void* obj)
+{
+    return static_cast<APITest*>(obj)->PushAudioRunB();
+}
+
+bool 
+APITest::PullAudioThreadA(void* obj)
+{
+    return static_cast<APITest*>(obj)->PullAudioRunA();
+}
+
+bool 
+APITest::PullAudioThreadB(void* obj)
+{
+    return static_cast<APITest*>(obj)->PullAudioRunB();
+}
+
+bool
+APITest::ProcessThreadA(void* obj)
+{
+    return static_cast<APITest*>(obj)->ProcessRunA();
+}
+
+bool
+APITest::ProcessThreadB(void* obj)
+{
+    return static_cast<APITest*>(obj)->ProcessRunB();
+}
+
+bool
+APITest::APIThreadA(void* obj)
+{
+    return static_cast<APITest*>(obj)->APIRunA();
+}
+
+bool
+APITest::APIThreadB(void* obj)
+{
+    return static_cast<APITest*>(obj)->APIRunB();
+}
+
+bool 
+APITest::PullAudioRunA()
+{
+    _pullEventA->Wait(100);
+    AudioFrame audioFrame;
+    if(_acmA->PlayoutData10Ms(_outFreqHzA, audioFrame) < 0)
+    {
+        bool thereIsDecoder;
+        {
+            ReadLockScoped rl(_apiTestRWLock);
+            thereIsDecoder = _thereIsDecoderA;
+        }
+        if(thereIsDecoder)
+        {
+            fprintf(stderr, "\n>>>>>>    cannot pull audio A       <<<<<<<< \n");
+        }
+    }
+    else
+    {
+        if(_writeToFile)
+        {
+            _outFileA.Write10MsData(audioFrame);
+        }
+        _receiveVADActivityA[(int)audioFrame._vadActivity]++;
+    }
+    return true;
+}
+
+bool 
+APITest::PullAudioRunB()
+{
+    _pullEventB->Wait(100);
+    AudioFrame audioFrame;
+    if(_acmB->PlayoutData10Ms(_outFreqHzB, audioFrame) < 0)
+    {
+        bool thereIsDecoder;
+        {
+            ReadLockScoped rl(_apiTestRWLock);
+            thereIsDecoder = _thereIsDecoderB;
+        }
+        if(thereIsDecoder)
+        {
+            fprintf(stderr, "\n>>>>>>    cannot pull audio B       <<<<<<<< \n");
+            fprintf(stderr, "%d %d\n", _testNumA, _testNumB);
+        }
+    }
+    else
+    {
+        if(_writeToFile)
+        {
+            _outFileB.Write10MsData(audioFrame);
+        }
+        _receiveVADActivityB[(int)audioFrame._vadActivity]++;
+    }     
+    return true;
+}
+
+bool 
+APITest::PushAudioRunA()
+{
+    _pushEventA->Wait(100);
+    AudioFrame audioFrame;
+    _inFileA.Read10MsData(audioFrame);
+    if(_acmA->Add10MsData(audioFrame) < 0)
+    {
+        bool thereIsEncoder;
+        {
+            ReadLockScoped rl(_apiTestRWLock);
+            thereIsEncoder = _thereIsEncoderA;
+        }
+        if(thereIsEncoder)
+        {
+            fprintf(stderr, "\n>>>>        add10MsData at A failed       <<<<\n");
+        }
+    }
+    return true;
+}
+
+bool 
+APITest::PushAudioRunB()
+{
+    _pushEventB->Wait(100);
+    AudioFrame audioFrame;
+    _inFileB.Read10MsData(audioFrame);
+    if(_acmB->Add10MsData(audioFrame) < 0)
+    {
+        bool thereIsEncoder;
+        {
+            ReadLockScoped rl(_apiTestRWLock);
+            thereIsEncoder = _thereIsEncoderB;
+        }
+
+        if(thereIsEncoder)
+        {
+            fprintf(stderr, "\n>>>>   cannot add audio to B    <<<<");
+        }
+    }
+
+    return true;
+}
+
+bool
+APITest::ProcessRunA()
+{
+    _processEventA->Wait(100);
+    if(_acmA->Process() < 0)
+    {
+        // do not print error message if there is no encoder
+        bool thereIsEncoder;
+        {
+            ReadLockScoped rl(_apiTestRWLock);
+            thereIsEncoder = _thereIsEncoderA;
+        }
+
+        if(thereIsEncoder)
+        {
+            fprintf(stderr, "\n>>>>>      Process Failed at A     <<<<<\n");
+        }
+    }
+    return true;
+}
+
+bool
+APITest::ProcessRunB()
+{
+    _processEventB->Wait(100);
+    if(_acmB->Process() < 0)
+    {
+        bool thereIsEncoder;
+        {
+            ReadLockScoped rl(_apiTestRWLock);
+            thereIsEncoder = _thereIsEncoderB;
+        }
+        if(thereIsEncoder)
+        {
+            fprintf(stderr, "\n>>>>>      Process Failed at B     <<<<<\n");
+        }
+    }
+    return true;
+}
+
+/*/
+ *
+ * In side A we test the APIs which are related to sender Side.
+ *
+/*/
+
+
+void
+APITest::RunTest(char thread)
+{
+    int testNum;
+    {
+        WriteLockScoped cs(_apiTestRWLock);
+        if(thread == 'A')
+        {
+            _testNumA = (_testNumB + 1 + (rand() % 6)) % 7;
+            testNum = _testNumA;
+            
+            _movingDot[_dotPositionA] = ' ';
+            if(_dotPositionA == 0)
+            {
+                _dotMoveDirectionA = 1;
+            }
+            if(_dotPositionA == 19)
+            {
+                _dotMoveDirectionA = -1;
+            }
+            _dotPositionA += _dotMoveDirectionA;            
+            _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0)? '>':'<';
+        }
+        else
+        {
+            _testNumB = (_testNumA + 1 + (rand() % 6)) % 7;
+            testNum = _testNumB;
+
+            _movingDot[_dotPositionB] = ' ';
+            if(_dotPositionB == 20)
+            {
+                _dotMoveDirectionB = 1;
+            }
+            if(_dotPositionB == 39)
+            {
+                _dotMoveDirectionB = -1;
+            }
+            _dotPositionB += _dotMoveDirectionB;            
+            _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0)? '>':'<';
+        }
+        //fprintf(stderr, "%c: %d \n", thread, testNum);
+        //fflush(stderr);
+    }
+    switch(testNum)
+    {
+    case 0:
+        CurrentCodec('A');
+        ChangeCodec('A');
+        break;
+    case 1:
+        TestPlayout('B');
+        break;
+    case 2:
+        if(!_randomTest)
+        {
+            fprintf(stdout, "\nTesting Delay ...\n");
+        }
+        TestDelay('A');
+        break;
+    case 3:
+        TestSendVAD('A');    
+        break;
+    case 4:
+        TestRegisteration('A');
+        break;
+    case 5:
+        TestReceiverVAD('A');
+        break;
+    case 6:
+#ifdef WEBRTC_DTMF_DETECTION
+        LookForDTMF('A');
+#endif
+        break;
+    default:
+        fprintf(stderr, "Wrong Test Number\n");
+        getchar();
+        exit(1);
+    }
+}
+
+
+
+bool
+APITest::APIRunA()
+{   
+    _apiEventA->Wait(50);
+
+    bool randomTest;
+    {
+        ReadLockScoped rl(_apiTestRWLock);
+        randomTest = _randomTest;
+    }
+    if(randomTest)
+    {
+        RunTest('A');
+    }
+    else
+    {
+        CurrentCodec('A');
+        ChangeCodec('A');
+        TestPlayout('B');
+        if(_codecCntrA == 0)
+        {
+            fprintf(stdout, "\nTesting Delay ...\n");
+            TestDelay('A');
+        }
+        // VAD TEST
+        TestSendVAD('A');    
+        TestRegisteration('A');
+        TestReceiverVAD('A');
+#ifdef WEBRTC_DTMF_DETECTION
+        LookForDTMF('A');
+#endif
+    }
+    return true;
+}
+
+bool
+APITest::APIRunB()
+{   
+    _apiEventB->Wait(50);
+    bool randomTest;
+    {
+        ReadLockScoped rl(_apiTestRWLock);
+        randomTest = _randomTest;
+    }
+    //_apiEventB->Wait(2000);
+    if(randomTest)
+    {
+        RunTest('B');
+    }
+ 
+    return true;
+}
+
+void
+APITest::Perform()
+{
+    SetUp();
+
+    //--- THREADS
+    // A
+    // PUSH
+    ThreadWrapper* myPushAudioThreadA = ThreadWrapper::CreateThread(PushAudioThreadA, 
+        this, kNormalPriority, "PushAudioThreadA");
+    CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread");
+    // PULL
+    ThreadWrapper* myPullAudioThreadA = ThreadWrapper::CreateThread(PullAudioThreadA, 
+        this, kNormalPriority, "PullAudioThreadA");
+    CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread");
+    // Process
+    ThreadWrapper* myProcessThreadA = ThreadWrapper::CreateThread(ProcessThreadA, 
+        this, kNormalPriority, "ProcessThreadA");
+    CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread");
+    // API 
+    ThreadWrapper* myAPIThreadA = ThreadWrapper::CreateThread(APIThreadA, 
+        this, kNormalPriority, "APIThreadA");
+    CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread");
+    // B
+    // PUSH
+    ThreadWrapper* myPushAudioThreadB = ThreadWrapper::CreateThread(PushAudioThreadB, 
+        this, kNormalPriority, "PushAudioThreadB");
+    CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread");
+    // PULL
+    ThreadWrapper* myPullAudioThreadB = ThreadWrapper::CreateThread(PullAudioThreadB, 
+        this, kNormalPriority, "PullAudioThreadB");
+    CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread");
+    // Process
+    ThreadWrapper* myProcessThreadB = ThreadWrapper::CreateThread(ProcessThreadB, 
+        this, kNormalPriority, "ProcessThreadB");
+    CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread");
+    // API
+    ThreadWrapper* myAPIThreadB = ThreadWrapper::CreateThread(APIThreadB, 
+        this, kNormalPriority, "APIThreadB");
+    CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread");
+ 
+
+    //_apiEventA->StartTimer(true, 5000);
+    //_apiEventB->StartTimer(true, 5000);
+
+    _processEventA->StartTimer(true, 10);
+    _processEventB->StartTimer(true, 10);
+    
+    _pullEventA->StartTimer(true, 10);
+    _pullEventB->StartTimer(true, 10);
+
+    _pushEventA->StartTimer(true, 10);
+    _pushEventB->StartTimer(true, 10);
+
+    // Keep main thread waiting for sender/receiver
+    // threads to complete
+    EventWrapper* completeEvent = EventWrapper::Create();
+    WebRtc_UWord64 startTime = TickTime::MillisecondTimestamp();
+    WebRtc_UWord64 currentTime;
+    do
+    {
+        {
+            //ReadLockScoped rl(_apiTestRWLock);
+            //fprintf(stderr, "\r%s", _movingDot);
+        }
+        //fflush(stderr);
+        completeEvent->Wait(50);
+        currentTime = TickTime::MillisecondTimestamp();
+    } while((currentTime - startTime) < 120000); // Run test in 2 minutes (120000 ms)
+
+    //completeEvent->Wait(0xFFFFFFFF);//(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000));
+    delete completeEvent;
+    
+    myPushAudioThreadA->Stop();
+    myPullAudioThreadA->Stop();
+    myProcessThreadA->Stop();
+    myAPIThreadA->Stop();
+
+    delete myPushAudioThreadA;
+    delete myPullAudioThreadA;
+    delete myProcessThreadA;
+    delete myAPIThreadA;
+
+
+    myPushAudioThreadB->Stop();
+    myPullAudioThreadB->Stop();
+    myProcessThreadB->Stop();
+    myAPIThreadB->Stop();
+
+    delete myPushAudioThreadB;
+    delete myPullAudioThreadB;
+    delete myProcessThreadB;
+    delete myAPIThreadB;
+}
+
+
+void
+APITest::CheckVADStatus(char side)
+{
+
+    bool dtxEnabled;
+    bool vadEnabled;
+    ACMVADMode vadMode;
+    EventWrapper* myEvent = EventWrapper::Create();
+    if(side == 'A')
+    {
+        _acmA->VAD(dtxEnabled, vadEnabled, vadMode);
+        _acmA->RegisterVADCallback(NULL);
+        _vadCallbackA->Reset();
+        _acmA->RegisterVADCallback(_vadCallbackA);
+        
+        if(!_randomTest)
+        {
+            if(_verbose)
+            {
+                fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", 
+                    dtxEnabled? "ON":"OFF",
+                    vadEnabled? "ON":"OFF",
+                    (int)vadMode);
+                Wait(5000);
+                fprintf(stdout, " => bit-rate %3.0f kbps\n",
+                    _channel_A2B->BitRate());
+            }
+            else
+            {
+                Wait(5000);
+                fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n", 
+                    dtxEnabled? "ON":"OFF",
+                    vadEnabled? "ON":"OFF",
+                    (int)vadMode,
+                    _channel_A2B->BitRate());
+            }
+            _vadCallbackA->PrintFrameTypes();
+        }
+
+        if(dtxEnabled != _sendDTXA)
+        {
+            fprintf(stderr, ">>>   Error Enabling DTX    <<<\n");
+        }
+        if((vadEnabled != _sendVADA) && (!dtxEnabled))
+        {
+            fprintf(stderr, ">>>   Error Enabling VAD    <<<\n");
+        }
+        if((vadMode != _sendVADModeA) && vadEnabled)
+        {
+            fprintf(stderr, ">>>   Error setting VAD-mode    <<<\n");
+        }
+    }
+    else
+    {
+        _acmB->VAD(dtxEnabled, vadEnabled, vadMode);
+
+        _acmB->RegisterVADCallback(NULL);
+        _vadCallbackB->Reset();
+        _acmB->RegisterVADCallback(_vadCallbackB);
+        
+        if(!_randomTest)
+        {
+            if(_verbose)
+            {
+                fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", 
+                    dtxEnabled? "ON":"OFF",
+                    vadEnabled? "ON":"OFF",
+                    (int)vadMode);
+                Wait(5000);
+                fprintf(stdout, " => bit-rate %3.0f kbps\n",
+                    _channel_B2A->BitRate());
+            }
+            else
+            {
+                Wait(5000);
+                fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n", 
+                    dtxEnabled? "ON":"OFF",
+                    vadEnabled? "ON":"OFF",
+                    (int)vadMode,
+                    _channel_B2A->BitRate());
+            }
+            _vadCallbackB->PrintFrameTypes();
+        }
+
+        if(dtxEnabled != _sendDTXB)
+        {
+            fprintf(stderr, ">>>   Error Enabling DTX    <<<\n");
+        }
+        if((vadEnabled != _sendVADB) && (!dtxEnabled))
+        {
+            fprintf(stderr, ">>>   Error Enabling VAD    <<<\n");
+        }
+        if((vadMode != _sendVADModeB) && vadEnabled)
+        {
+            fprintf(stderr, ">>>   Error setting VAD-mode    <<<\n");
+        }
+    }
+}
+
+// Set Min delay, get delay, playout timestamp
+void
+APITest::TestDelay(char side)
+{
+    AudioCodingModule* myACM;
+    Channel* myChannel;
+    WebRtc_Word32* myMinDelay;
+    EventWrapper* myEvent = EventWrapper::Create();
+
+    WebRtc_UWord32 inTimestamp = 0;
+    WebRtc_UWord32 outTimestamp = 0;
+    double estimDelay = 0;    
+    WebRtc_UWord16 delay = 0;
+
+    double averageEstimDelay = 0;
+    double averageDelay = 0;
+
+    CircularBuffer estimDelayCB(100);
+    CircularBuffer delayCB(100);
+    estimDelayCB.SetArithMean(true);
+    delayCB.SetArithMean(true);
+
+
+    if(side == 'A')
+    {
+        myACM = _acmA;
+        myChannel = _channel_B2A;
+        myMinDelay = &_minDelayA;
+    }
+    else
+    {
+        myACM = _acmB;
+        myChannel = _channel_A2B;
+        myMinDelay = &_minDelayB;
+    }
+
+
+    CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
+
+
+    inTimestamp = myChannel->LastInTimestamp();        
+    CHECK_ERROR_MT(myACM->PlayoutTimestamp(outTimestamp));
+    CHECK_ERROR_MT(myACM->Delay(delay));
+
+    if(!_randomTest)
+    {
+        myEvent->StartTimer(true, 30);
+        int n = 0;
+        int settlePoint = 5000;
+        while(n < settlePoint + 400)
+        {
+            myEvent->Wait(1000);
+
+            inTimestamp = myChannel->LastInTimestamp();        
+            CHECK_ERROR_MT(myACM->PlayoutTimestamp(outTimestamp));
+
+            //std::cout << outTimestamp << std::endl << std::flush;
+            estimDelay = (double)((WebRtc_UWord32)(inTimestamp - outTimestamp)) / 
+                ((double)myACM->ReceiveFrequency() / 1000.0);
+
+            estimDelayCB.Update(estimDelay);
+
+            estimDelayCB.ArithMean(averageEstimDelay);
+            //printf("\n %6.1f \n", estimDelay);
+            //std::cout << " " << std::flush;
+
+            CHECK_ERROR_MT(myACM->Delay(delay));
+            delayCB.Update(delay);
+            delayCB.ArithMean(averageDelay);
+
+            if(_verbose)
+            {
+                fprintf(stdout, "\rExpected: %4d,    retreived: %6.1f,   measured: %6.1f",
+                    *myMinDelay, averageDelay, averageEstimDelay);
+                std::cout << " " << std::flush;
+            }
+            if((averageDelay > *myMinDelay) && (n < settlePoint))
+            {
+                settlePoint = n;
+            }
+            n++;
+        }
+        myEvent->StopTimer();
+    }
+
+    if((!_verbose) && (!_randomTest))
+    {
+        fprintf(stdout, "\nExpected: %4d,    retreived: %6.1f,   measured: %6.1f",
+            *myMinDelay, averageDelay, averageEstimDelay);
+    }
+
+    *myMinDelay = (rand() % 1000) + 1;
+  
+    ACMJitterStatistics jitterStat;
+    ACMNetworkStatistics networkStat;
+    CHECK_ERROR_MT(myACM->JitterStatistics(jitterStat));
+    CHECK_ERROR_MT(myACM->NetworkStatistics(networkStat));
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side);
+        fprintf(stdout, "--------------------------------------\n");
+        fprintf(stdout, "buffer-size............. %d\n", networkStat.currentBufferSize);    
+        fprintf(stdout, "Preferred buffer-size... %d\n", networkStat.preferredBufferSize);  
+        fprintf(stdout, "packet-size rate........ %d\n", networkStat.currentPacketLossRate);
+        fprintf(stdout, "discard rate............ %d\n", networkStat.currentDiscardRate);   
+        fprintf(stdout, "expand rate............. %d\n", networkStat.currentExpandRate);    
+        fprintf(stdout, "Preemptive rate......... %d\n", networkStat.currentPreemptiveRate);
+        fprintf(stdout, "Accelerate rate......... %d\n", networkStat.currentAccelerateRate);
+
+        fprintf(stdout, "\n\nJitter Statistics at side %c\n", side);
+        fprintf(stdout, "--------------------------------------\n");
+        fprintf(stdout, "Jitter buffer min size....... %d\n",   jitterStat.jbMinSize);              
+        fprintf(stdout, "Jitter buffer Max size....... %d\n",    jitterStat.jbMaxSize);              
+        fprintf(stdout, "Jitter buffer Average size... %d\n",    jitterStat.jbAvgSize);              
+        fprintf(stdout, "Change Count................. %d ms\n", jitterStat.jbChangeCount);          
+        fprintf(stdout, "Late Loss.................... %d ms\n", jitterStat.lateLossMs);             
+        fprintf(stdout, "Accelerate................... %d ms\n", jitterStat.accelerateMs);           
+        fprintf(stdout, "Flushed...................... %d ms\n", jitterStat.flushedMs);              
+        fprintf(stdout, "Generated Silence............ %d ms\n", jitterStat.generatedSilentMs);      
+        fprintf(stdout, "Interpolated Voice........... %d ms\n", jitterStat.interpolatedVoiceMs);    
+        fprintf(stdout, "Interpolated Silence......... %d ms\n", jitterStat.interpolatedSilentMs);   
+        fprintf(stdout, "No tiny expand............... %d\n",    jitterStat.numExpandTiny);          
+        fprintf(stdout, "No small expand.............. %d\n",    jitterStat.numExpandSmall);         
+        fprintf(stdout, "No Medium expand............. %d\n",    jitterStat.numExpandMedium);        
+        fprintf(stdout, "No long expand............... %d\n",    jitterStat.numExpandLong);          
+        fprintf(stdout, "longest expand............... %d ms\n", jitterStat.longestExpandDurationMs);
+        fprintf(stdout, "No IAT 500................... %d ms\n", jitterStat.countIAT500ms);          
+        fprintf(stdout, "No IAT 1000.................. %d ms\n", jitterStat.countIAT1000ms);         
+        fprintf(stdout, "No IAT 2000.................. %d ms\n", jitterStat.countIAT2000ms);         
+        fprintf(stdout, "longest IAT.................. %d ms\n", jitterStat.longestIATms);           
+        fprintf(stdout, "Min packet delay............. %d ms\n", jitterStat.minPacketDelayMs);       
+        fprintf(stdout, "Max packet delay............. %d ms\n", jitterStat.maxPacketDelayMs);       
+        fprintf(stdout, "Average packet delay......... %d ms\n", jitterStat.avgPacketDelayMs);       
+    }
+
+    CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay));
+
+    if(!_randomTest)
+    {
+        myEvent->Wait(500);
+        fprintf(stdout, "\n");
+        fprintf(stdout, "\n");
+    }
+    delete myEvent;
+}
+
+// Unregister a codec & register again.
+void
+APITest::TestRegisteration(char sendSide)
+{
+    AudioCodingModule* sendACM;
+    AudioCodingModule* receiveACM;
+    bool* thereIsDecoder;
+    EventWrapper* myEvent = EventWrapper::Create();
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\n");
+        fprintf(stdout, "---------------------------------------------------------\n");
+        fprintf(stdout, "           Unregister/register Receive Codec\n");
+        fprintf(stdout, "---------------------------------------------------------\n");
+    }
+    
+    switch(sendSide)
+    {
+    case 'A':
+        {
+            sendACM = _acmA;
+            receiveACM = _acmB;
+            thereIsDecoder = &_thereIsDecoderB;
+            break;
+        }
+    case 'B':
+        {
+            sendACM = _acmB;
+            receiveACM = _acmA;
+            thereIsDecoder = &_thereIsDecoderA;
+            break;
+        }
+    default:
+        fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n", sendSide);
+        exit(-1);
+    }
+
+    CodecInst myCodec;
+    if(sendACM->SendCodec(myCodec) < 0)
+    {
+        AudioCodingModule::Codec(_codecCntrA, myCodec);
+    }
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
+        fflush(stdout);
+    }
+    {
+        WriteLockScoped wl(_apiTestRWLock);
+        *thereIsDecoder = false;
+    }
+    //myEvent->Wait(20);
+    CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
+    Wait(1000);
+
+    int currentPayload = myCodec.pltype;
+
+    if(!FixedPayloadTypeCodec(myCodec.plname))
+    {
+        WebRtc_Word32 i;
+        for(i = 0; i < 32; i++)
+        {
+            if(!_payloadUsed[i])
+            {
+                if(!_randomTest)
+                {
+                    fprintf(stdout, "Register receive codec with new Payload, AUDIO BACK.\n");
+                }
+                //myCodec.pltype = i + 96;
+                //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
+                //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
+                //myEvent->Wait(20);
+                //{
+                //    WriteLockScoped wl(_apiTestRWLock);
+                //    *thereIsDecoder = true;
+                //}
+                Wait(1000);
+
+                if(!_randomTest)
+                {
+                    fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n");
+                }
+                //{
+                //    WriteLockScoped wl(_apiTestRWLock);
+                //    *thereIsDecoder = false;
+                //}
+                //myEvent->Wait(20);
+                //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
+                Wait(1000);
+
+                myCodec.pltype = currentPayload;
+                if(!_randomTest)
+                {
+                    fprintf(stdout, "Register receive codec with default Payload, AUDIO BACK.\n");
+                    fflush(stdout);
+                }
+                CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
+                //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec));
+                myEvent->Wait(20);
+                {
+                    WriteLockScoped wl(_apiTestRWLock);
+                    *thereIsDecoder = true;
+                }
+                Wait(1000);
+
+                break;
+            }
+        }
+        if(i == 32)
+        {
+            CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
+            {
+                WriteLockScoped wl(_apiTestRWLock);
+                *thereIsDecoder = true;
+            }
+        }
+    }
+    else
+    {
+        if(!_randomTest)
+        {
+            fprintf(stdout, "Register receive codec with fixed Payload, AUDIO BACK.\n");
+            fflush(stdout);
+        }
+        CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
+        //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype));
+        //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec));
+        myEvent->Wait(20);
+        {
+            WriteLockScoped wl(_apiTestRWLock);
+            *thereIsDecoder = true;
+        }
+    }
+    delete myEvent;
+    if(!_randomTest)
+    {
+        fprintf(stdout, "---------------------------------------------------------\n");
+    }
+}
+
+// Playout Mode, background noise mode.
+// Receiver Frequency, playout frequency.
+void
+APITest::TestPlayout(char receiveSide)
+{
+    AudioCodingModule* receiveACM;
+    AudioPlayoutMode* playoutMode;
+    ACMBackgroundNoiseMode* bgnMode;
+    switch(receiveSide)
+    {
+        case 'A':
+            {
+                receiveACM = _acmA;
+                playoutMode = &_playoutModeA;
+                bgnMode = &_bgnModeA;
+                break;
+            }
+        case 'B':
+            {
+                receiveACM = _acmB;
+                playoutMode = &_playoutModeB;
+                bgnMode = &_bgnModeB;
+                break;
+            }
+        default:
+            receiveACM = _acmA;
+    }
+
+    WebRtc_Word32 receiveFreqHz = receiveACM->ReceiveFrequency();
+    WebRtc_Word32 playoutFreqHz = receiveACM->PlayoutFrequency();
+
+    CHECK_ERROR_MT(receiveFreqHz);
+    CHECK_ERROR_MT(playoutFreqHz);
+    
+    char bgnString[25];
+    switch(*bgnMode)
+    {
+    case On:
+        {
+            *bgnMode = Fade;
+            strncpy(bgnString, "Fade", 25);
+            break;
+        }
+    case Fade:
+        {
+            *bgnMode = Off;
+            strncpy(bgnString, "OFF", 25);
+            break;
+        }
+    case Off:
+        {
+            *bgnMode = On;
+            strncpy(bgnString, "ON", 25);
+            break;
+        }
+    default:
+        *bgnMode = On;
+        strncpy(bgnString, "ON", 25);
+    }
+    CHECK_ERROR_MT(receiveACM->SetBackgroundNoiseMode(*bgnMode));
+    bgnString[24] = '\0';
+
+    char playoutString[25];
+    switch(*playoutMode)
+    {
+    case voice:
+        {
+            *playoutMode = fax;
+            strncpy(playoutString, "FAX", 25);
+            break;
+        }
+    case fax:
+        {
+            *playoutMode = streaming;
+            strncpy(playoutString, "Streaming", 25);
+            break;
+        }
+    case streaming:
+        {
+            *playoutMode = voice;
+            strncpy(playoutString, "Voice", 25);
+            break;
+        }
+    default:
+        *playoutMode = voice;
+        strncpy(playoutString, "Voice", 25);
+    }
+    CHECK_ERROR_MT(receiveACM->SetPlayoutMode(*playoutMode));
+    playoutString[24] = '\0';
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n");
+        fprintf(stdout, "In Side %c\n", receiveSide);
+        fprintf(stdout, "---------------------------------\n");
+        fprintf(stdout, "Receive Frequency....... %d Hz\n", receiveFreqHz);
+        fprintf(stdout, "Playout Frequency....... %d Hz\n", playoutFreqHz);
+        fprintf(stdout, "Audio Playout Mode...... %s\n", playoutString);
+        fprintf(stdout, "Background Noise Mode... %s\n", bgnString);
+    }
+}
+
+// set/get receiver VAD status & mode.
+void
+APITest::TestReceiverVAD(char side)
+{
+    AudioCodingModule* myACM;
+    EventWrapper* myEvent = EventWrapper::Create();
+    WebRtc_UWord64* myReceiveVADActivity;
+
+    if(side == 'A')
+    {
+        myACM = _acmA;
+        myReceiveVADActivity = _receiveVADActivityA;
+    }
+    else
+    {
+        myACM = _acmB;
+        myReceiveVADActivity = _receiveVADActivityB;
+    }
+
+    bool vadStatus = myACM->ReceiveVADStatus();
+    ACMVADMode mode = myACM->ReceiveVADMode();
+
+    CHECK_ERROR_MT(mode);
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\nCurrent Receive VAD at side %c\n", side);
+        fprintf(stdout, "----------------------------------\n");
+        fprintf(stdout, "Status........ %s\n", vadStatus? "ON":"OFF");
+        fprintf(stdout, "mode.......... %d\n", (int)mode);
+        fprintf(stdout, "VAD Active.... %llu\n", myReceiveVADActivity[0]);
+        fprintf(stdout, "VAD Passive... %llu\n", myReceiveVADActivity[1]);
+        fprintf(stdout, "VAD Unknown... %llu\n", myReceiveVADActivity[2]);
+    }
+
+    if(vadStatus)
+    {
+        if(!_randomTest)
+        {
+            fprintf(stdout, "\nChange Receive VAD at side %c\n\n", side);
+        }
+
+        switch(mode)
+        {
+        case VADNormal:
+            mode = VADAggr;
+            break;
+        case VADLowBitrate:
+            mode = VADVeryAggr;
+            break;
+        case VADAggr:
+            mode = VADLowBitrate;
+            break;
+        case VADVeryAggr:
+            vadStatus = false;
+            mode = VADNormal;
+            break;
+        default:
+            mode = VADNormal;
+        }
+       
+        CHECK_ERROR_MT(myACM->SetReceiveVADMode(mode));
+        CHECK_ERROR_MT(myACM->SetReceiveVADStatus(vadStatus));
+    }
+    else
+    {
+        if(!_randomTest)
+        {
+            fprintf(stdout, "\nTurn on Receive VAD at side %c\n\n", side);
+        }
+        CHECK_ERROR_MT(myACM->SetReceiveVADStatus(true));
+        CHECK_ERROR_MT(myACM->SetReceiveVADMode(VADNormal));
+    }
+    for(int n = 0; n < 3; n++)
+    {
+        myReceiveVADActivity[n] = 0;
+    }
+}
+
+
+void
+APITest::TestSendVAD(char side)
+{
+    if(_randomTest)
+    {
+        return;
+    }
+
+    bool* vad;
+    bool* dtx;
+    ACMVADMode* mode;
+    Channel* myChannel;
+    AudioCodingModule* myACM;
+
+    CodecInst myCodec;
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\n");
+        fprintf(stdout, "-----------------------------------------------\n");
+        fprintf(stdout, "                Test VAD API\n");
+        fprintf(stdout, "-----------------------------------------------\n");
+    }
+
+    if(side == 'A')
+    {
+        AudioCodingModule::Codec(_codecCntrA, myCodec);
+        vad = &_sendVADA;
+        dtx = &_sendDTXA;
+        mode = &_sendVADModeA;
+        myChannel = _channel_A2B;
+        myACM = _acmA;
+    }
+    else
+    {
+        AudioCodingModule::Codec(_codecCntrB, myCodec);
+        vad = &_sendVADB;
+        dtx = &_sendDTXB;
+        mode = &_sendVADModeB;
+        myChannel = _channel_B2A;
+        myACM = _acmB;
+    }
+
+    CheckVADStatus(side);
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\n");
+    }
+
+    switch(*mode)
+    {
+    case VADNormal:
+        *vad = true;
+        *dtx = true;
+        *mode = VADAggr;
+        break;
+    case VADLowBitrate:
+        *vad = true;
+        *dtx = true;
+        *mode = VADVeryAggr;
+        break;
+    case VADAggr:
+        *vad = true;
+        *dtx = true;
+        *mode = VADLowBitrate;
+        break;
+    case VADVeryAggr:
+        *vad = false;
+        *dtx = false;
+        *mode = VADNormal;
+        break;
+    default:
+        *mode = VADNormal;
+    }
+
+    *dtx = (myCodec.plfreq == 32000)? false:*dtx;
+
+    CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
+    myChannel->ResetStats();
+
+    CheckVADStatus(side);
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n");
+        fprintf(stdout, "-----------------------------------------------\n");
+    }
+
+    // Fault Test
+    CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode)-1));
+    CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode)4));
+    
+
+
+}
+
+
+void
+APITest::CurrentCodec(char side)
+{
+    CodecInst myCodec;
+    EventWrapper* myEvent = EventWrapper::Create();
+    if(side == 'A')
+    {
+        _acmA->SendCodec(myCodec);
+    }
+    else
+    {
+        _acmB->SendCodec(myCodec);
+    }
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\n");
+        fprintf(stdout, "Send codec in Side A\n");
+        fprintf(stdout, "----------------------------\n");
+        fprintf(stdout, "Name................. %s\n", myCodec.plname);
+        fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq);
+        fprintf(stdout, "Rate................. %d\n", myCodec.rate);
+        fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype);
+        fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize);
+    }
+
+    Wait(100);
+}
+
+void
+APITest::ChangeCodec(char side)
+{
+    CodecInst myCodec;
+    AudioCodingModule* myACM;
+    WebRtc_UWord8* codecCntr;
+    bool* thereIsEncoder;
+    bool* vad;
+    bool* dtx;
+    ACMVADMode* mode;
+    Channel* myChannel;
+    EventWrapper* myEvent = EventWrapper::Create();
+    // Reset and Wait
+    if(!_randomTest)
+    {
+        fprintf(stdout, "Reset Encoder Side A \n");
+    }
+    if(side == 'A')
+    {
+        myACM = _acmA;
+        codecCntr = &_codecCntrA;
+        {
+            WriteLockScoped wl(_apiTestRWLock);
+            thereIsEncoder = &_thereIsEncoderA;
+        }
+        vad = &_sendVADA;
+        dtx = &_sendDTXA;
+        mode = &_sendVADModeA;
+        myChannel = _channel_A2B;
+    }
+    else
+    {
+        myACM = _acmB;
+        codecCntr = &_codecCntrB;
+        {
+            WriteLockScoped wl(_apiTestRWLock);
+            thereIsEncoder = &_thereIsEncoderB;
+        }
+        vad = &_sendVADB;
+        dtx = &_sendDTXB;
+        mode = &_sendVADModeB;
+        myChannel = _channel_B2A;
+    }
+
+    myACM->ResetEncoder();  
+    Wait(100);
+
+    // Register the next codec
+    do
+    {
+        *codecCntr = (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1)? 
+            (*codecCntr + 1):0;     
+
+        if(*codecCntr == 0)
+        {
+            //printf("Initialize Sender Side A \n");
+            {
+                WriteLockScoped wl(_apiTestRWLock);
+                *thereIsEncoder = false;
+            }
+            CHECK_ERROR_MT(myACM->InitializeSender());
+            Wait(1000);   
+
+            // After Initialization CN is lost, re-register them
+            if(AudioCodingModule::Codec("CN", myCodec, 8000) >= 0)
+            {
+                CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
+            }
+            if(AudioCodingModule::Codec("CN", myCodec, 16000) >= 0)
+            {
+                CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
+            }
+            // VAD & DTX are disabled after initialization
+            *vad = false;
+            *dtx = false;
+            _writeToFile = false;
+        }
+
+        AudioCodingModule::Codec(*codecCntr, myCodec);
+    } while(!STR_CASE_CMP(myCodec.plname, "CN")          ||
+        !STR_CASE_CMP(myCodec.plname, "telephone-event") ||
+        !STR_CASE_CMP(myCodec.plname, "RED"));
+
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n====================================================================\n");
+        fprintf(stdout, "      Registering New Codec %s, %d kHz, %d kbps\n",
+            myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000);
+    }
+    //std::cout<< std::flush;
+
+    // NO DTX for supe-wideband codec at this point
+    if(myCodec.plfreq == 32000)
+    {
+        *dtx = false;
+        CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode));
+
+    }
+
+    CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec));
+    myChannel->ResetStats();
+    {
+        WriteLockScoped wl(_apiTestRWLock);
+        *thereIsEncoder = true;
+    }
+    Wait(500);
+}
+
+ 
+void 
+APITest::LookForDTMF(char side)
+{
+    if(!_randomTest)
+    {
+        fprintf(stdout, "\n\nLooking for DTMF Signal in Side %c\n", side);
+        fprintf(stdout, "----------------------------------------\n");
+    }
+ 
+    if(side == 'A')
+    {
+        _acmB->RegisterIncomingMessagesCallback(NULL);
+        _acmA->RegisterIncomingMessagesCallback(_dtmfCallback);    
+        Wait(1000);
+        _acmA->RegisterIncomingMessagesCallback(NULL);
+    }
+    else
+    {
+        _acmA->RegisterIncomingMessagesCallback(NULL);
+        _acmB->RegisterIncomingMessagesCallback(_dtmfCallback);
+        Wait(1000);
+        _acmB->RegisterIncomingMessagesCallback(NULL);
+    }
+}
diff --git a/src/modules/audio_coding/main/test/APITest.h b/src/modules/audio_coding/main/test/APITest.h
new file mode 100644
index 0000000..52ecb27
--- /dev/null
+++ b/src/modules/audio_coding/main/test/APITest.h
@@ -0,0 +1,174 @@
+/*
+ *  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 API_TEST_H
+#define API_TEST_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+#include "event_wrapper.h"
+#include "utility.h"
+
+enum APITESTAction {TEST_CHANGE_CODEC_ONLY = 0, DTX_TEST = 1};
+
+class APITest : public ACMTest
+{
+public:
+    APITest();
+    ~APITest();
+
+    void Perform();
+private:
+    WebRtc_Word16 SetUp();
+    
+    static bool PushAudioThreadA(void* obj);
+    static bool PullAudioThreadA(void* obj);
+    static bool ProcessThreadA(void* obj);
+    static bool APIThreadA(void* obj);
+
+    static bool PushAudioThreadB(void* obj);
+    static bool PullAudioThreadB(void* obj);
+    static bool ProcessThreadB(void* obj);
+    static bool APIThreadB(void* obj);
+
+    void CheckVADStatus(char side);
+
+    // Set Min delay, get delay, playout timestamp
+    void TestDelay(char side);
+
+    // Unregister a codec & register again.
+    void TestRegisteration(char side);
+
+    // Playout Mode, background noise mode.
+    // Receiver Frequency, playout frequency.
+    void TestPlayout(char receiveSide);
+
+    // set/get receiver VAD status & mode.
+    void TestReceiverVAD(char side);
+
+    // 
+    void TestSendVAD(char side);
+
+    void CurrentCodec(char side);
+    
+    void ChangeCodec(char side);
+    
+    void Wait(WebRtc_UWord32 waitLengthMs);
+
+    void LookForDTMF(char side);
+
+    void RunTest(char thread);
+    
+    bool PushAudioRunA();    
+    bool PullAudioRunA();
+    bool ProcessRunA();
+    bool APIRunA();
+  
+    bool PullAudioRunB();
+    bool PushAudioRunB();
+    bool ProcessRunB();
+    bool APIRunB();
+
+
+
+    //--- ACMs
+    AudioCodingModule* _acmA;
+    AudioCodingModule* _acmB;
+    
+    //--- Channels
+    Channel* _channel_A2B;
+    Channel* _channel_B2A;
+    
+    //--- I/O files
+    // A
+    PCMFile _inFileA;
+    PCMFile _outFileA;
+    // B
+    PCMFile _outFileB;
+    PCMFile _inFileB;
+    
+    //--- I/O params
+    // A
+    WebRtc_Word32 _outFreqHzA;
+    // B
+    WebRtc_Word32 _outFreqHzB;
+    
+    // Should we write to file.
+    // we might skip writing to file if we
+    // run the test for a long time.
+    bool _writeToFile;
+    //--- Events
+    // A
+    EventWrapper* _pullEventA;      // pulling data from ACM
+    EventWrapper* _pushEventA;      // pushing data to ACM
+    EventWrapper* _processEventA;   // process
+    EventWrapper* _apiEventA;       // API calls
+    // B
+    EventWrapper* _pullEventB;      // pulling data from ACM
+    EventWrapper* _pushEventB;      // pushing data to ACM
+    EventWrapper* _processEventB;   // process
+    EventWrapper* _apiEventB;       // API calls
+
+    // keep track of the codec in either side.
+    WebRtc_UWord8 _codecCntrA;
+    WebRtc_UWord8 _codecCntrB;
+
+    // keep track of tests
+    WebRtc_UWord8 _testCntrA;
+    WebRtc_UWord8 _testCntrB;
+
+    // Is set to true if there is no encoder in either side
+    bool _thereIsEncoderA;
+    bool _thereIsEncoderB;
+    bool _thereIsDecoderA;
+    bool _thereIsDecoderB;
+
+    bool             _sendVADA;
+    bool             _sendDTXA;
+    ACMVADMode       _sendVADModeA;
+
+    bool             _sendVADB;
+    bool             _sendDTXB;
+    ACMVADMode       _sendVADModeB;
+
+    WebRtc_Word32    _minDelayA;
+    WebRtc_Word32    _minDelayB;
+    bool             _payloadUsed[32];
+        
+    AudioPlayoutMode    _playoutModeA;
+    AudioPlayoutMode    _playoutModeB;
+
+    ACMBackgroundNoiseMode _bgnModeA;
+    ACMBackgroundNoiseMode _bgnModeB;
+
+
+    WebRtc_UWord64   _receiveVADActivityA[3];
+    WebRtc_UWord64   _receiveVADActivityB[3];
+    bool           _verbose;
+    
+    int            _dotPositionA;
+    int            _dotMoveDirectionA;
+    int            _dotPositionB;
+    int            _dotMoveDirectionB;
+
+    char           _movingDot[41];
+    
+    DTMFDetector*  _dtmfCallback;
+    VADCallback*   _vadCallbackA;
+    VADCallback*   _vadCallbackB;
+    RWLockWrapper&    _apiTestRWLock;
+    bool           _randomTest;
+    int            _testNumA;
+    int            _testNumB;
+};
+
+
+#endif
diff --git a/src/modules/audio_coding/main/test/Channel.cpp b/src/modules/audio_coding/main/test/Channel.cpp
new file mode 100644
index 0000000..bf440ea
--- /dev/null
+++ b/src/modules/audio_coding/main/test/Channel.cpp
@@ -0,0 +1,481 @@
+/*
+ *  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 <assert.h>
+#include <iostream>
+
+#include "audio_coding_module.h"
+#include "Channel.h"
+#include "tick_util.h"
+#include "typedefs.h"
+#include "common_types.h"
+
+using namespace webrtc;
+
+WebRtc_Word32 
+Channel::SendData(
+        const FrameType       frameType,
+        const WebRtc_UWord8   payloadType,
+        const WebRtc_UWord32  timeStamp,
+        const WebRtc_UWord8*  payloadData, 
+        const WebRtc_UWord16  payloadSize,
+        const RTPFragmentationHeader* fragmentation)
+{
+    WebRtcRTPHeader rtpInfo;
+    WebRtc_Word32   status;
+    WebRtc_UWord16  payloadDataSize = payloadSize;
+
+    rtpInfo.header.markerBit = false;
+    rtpInfo.header.ssrc = 0;
+    rtpInfo.header.sequenceNumber = _seqNo++;
+    rtpInfo.header.payloadType = payloadType;
+    rtpInfo.header.timestamp = timeStamp;
+    if(frameType == kAudioFrameCN)
+    {
+        rtpInfo.type.Audio.isCNG = true;
+    }
+    else
+    {
+        rtpInfo.type.Audio.isCNG = false;
+    }
+    if(frameType == kFrameEmpty)
+    {
+        // Skip this frame
+        return 0;
+    }
+
+    rtpInfo.type.Audio.channel = 1;
+    // Treat fragmentation separately
+    if(fragmentation != NULL)
+    {
+        if((fragmentation->fragmentationTimeDiff[1] <= 0x3fff) && // silence for too long send only new data
+            (fragmentation->fragmentationVectorSize == 2))
+        {
+            // only 0x80 if we have multiple blocks
+            _payloadData[0] = 0x80 + fragmentation->fragmentationPlType[1];
+            WebRtc_UWord32 REDheader =  (((WebRtc_UWord32)fragmentation->fragmentationTimeDiff[1]) << 10) + fragmentation->fragmentationLength[1];
+            _payloadData[1] = WebRtc_UWord8((REDheader >> 16) & 0x000000FF);
+            _payloadData[2] = WebRtc_UWord8((REDheader >> 8) & 0x000000FF);
+            _payloadData[3] = WebRtc_UWord8(REDheader & 0x000000FF);
+
+            _payloadData[4] = fragmentation->fragmentationPlType[0];
+            // copy the RED data
+            memcpy(_payloadData + 5,
+                payloadData + fragmentation->fragmentationOffset[1],
+                fragmentation->fragmentationLength[1]);
+            // copy the normal data
+            memcpy(_payloadData + 5 + fragmentation->fragmentationLength[1],
+                payloadData + fragmentation->fragmentationOffset[0],
+                fragmentation->fragmentationLength[0]);
+            payloadDataSize += 5;
+        } else
+        {
+            // single block (newest one)
+            memcpy(_payloadData,
+                payloadData + fragmentation->fragmentationOffset[0],
+                fragmentation->fragmentationLength[0]);
+            payloadDataSize = WebRtc_UWord16(fragmentation->fragmentationLength[0]);
+            rtpInfo.header.payloadType = fragmentation->fragmentationPlType[0];
+        }
+    }
+    else
+    {
+        memcpy(_payloadData, payloadData, payloadDataSize);
+        if(_isStereo)
+        {
+            if(_leftChannel)
+            {
+                memcpy(&_rtpInfo, &rtpInfo, sizeof(WebRtcRTPHeader));
+                _leftChannel = false;
+                rtpInfo.type.Audio.channel = 1;
+            }
+            else
+            {
+                memcpy(&rtpInfo, &_rtpInfo, sizeof(WebRtcRTPHeader));
+                _leftChannel = true;
+                rtpInfo.type.Audio.channel = 2;
+            }
+        }
+    }
+    
+    _channelCritSect->Enter();
+    if(_saveBitStream)
+    {
+        //fwrite(payloadData, sizeof(WebRtc_UWord8), payloadSize, _bitStreamFile);
+    }
+
+    if(!_isStereo)
+    {
+        CalcStatistics(rtpInfo, payloadSize);
+    }
+    _lastInTimestamp = timeStamp;
+    _totalBytes += payloadDataSize;
+    _channelCritSect->Leave();
+
+    if(_useFECTestWithPacketLoss)
+    {
+        _packetLoss += 1;
+        if(_packetLoss == 3)
+        {
+            _packetLoss = 0;
+            return 0;
+        }
+    }
+
+    
+    //status = _receiverACM->IncomingPayload((WebRtc_Word8*)_payloadData, payloadSize, payloadType, timeStamp);
+    status = _receiverACM->IncomingPacket((WebRtc_Word8*)_payloadData, payloadDataSize, rtpInfo);
+
+    //delete [] payloadData;
+
+    
+
+    return status;
+}
+
+void 
+Channel::CalcStatistics(
+    WebRtcRTPHeader& rtpInfo, 
+    WebRtc_UWord16   payloadSize)
+{
+    int n;
+    if((rtpInfo.header.payloadType != _lastPayloadType) &&
+        (_lastPayloadType != -1))
+    {
+        // payload-type is changed.
+        // we have to terminate the calculations on the previous payload type
+        // we ignore the last packet in that payload type just to make things 
+        // easier.
+        for(n = 0; n < MAX_NUM_PAYLOADS; n++)
+        {
+            if(_lastPayloadType == _payloadStats[n].payloadType)
+            {
+                _payloadStats[n].newPacket = true;
+                break;
+            }
+        }
+    }
+    _lastPayloadType = rtpInfo.header.payloadType;
+
+    bool newPayload = true;
+    ACMTestPayloadStats* currentPayloadStr;
+    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
+    {
+        if(rtpInfo.header.payloadType == _payloadStats[n].payloadType)
+        {
+            newPayload = false;
+            currentPayloadStr = &_payloadStats[n];
+            break;
+        }
+    }
+
+    if(!newPayload)
+    {
+        if(!currentPayloadStr->newPacket)
+        {
+            WebRtc_UWord32 lastFrameSizeSample = (WebRtc_UWord32)((WebRtc_UWord32)rtpInfo.header.timestamp -
+                (WebRtc_UWord32)currentPayloadStr->lastTimestamp);
+            assert(lastFrameSizeSample > 0);
+            int k = 0;
+            while((currentPayloadStr->frameSizeStats[k].frameSizeSample !=
+                lastFrameSizeSample) && 
+                (currentPayloadStr->frameSizeStats[k].frameSizeSample != 0))
+            {
+                k++;
+            }
+            ACMTestFrameSizeStats* currentFrameSizeStats = 
+                &(currentPayloadStr->frameSizeStats[k]);
+            currentFrameSizeStats->frameSizeSample = (WebRtc_Word16)lastFrameSizeSample;
+
+            // increment the number of encoded samples.
+            currentFrameSizeStats->totalEncodedSamples +=
+                lastFrameSizeSample;
+            // increment the number of recveived packets
+            currentFrameSizeStats->numPackets++;
+            // increment the total number of bytes (this is based on
+            // the previous payload we don't know the frame-size of
+            // the current payload.
+            currentFrameSizeStats->totalPayloadLenByte += 
+                currentPayloadStr->lastPayloadLenByte;
+            // store the maximum payload-size (this is based on
+            // the previous payload we don't know the frame-size of
+            // the current payload.
+            if(currentFrameSizeStats->maxPayloadLen < 
+                currentPayloadStr->lastPayloadLenByte)
+            {
+                currentFrameSizeStats->maxPayloadLen = 
+                    currentPayloadStr->lastPayloadLenByte;
+            }
+            // store the current values for the next time
+            currentPayloadStr->lastTimestamp = rtpInfo.header.timestamp;
+            currentPayloadStr->lastPayloadLenByte = payloadSize;
+        }
+        else
+        {
+            currentPayloadStr->newPacket          = false;
+            currentPayloadStr->lastPayloadLenByte = payloadSize;
+            currentPayloadStr->lastTimestamp      = rtpInfo.header.timestamp;
+            currentPayloadStr->payloadType        = rtpInfo.header.payloadType;
+        }
+    }
+    else
+    {
+        n = 0;
+        while(_payloadStats[n].payloadType != -1)
+        {
+            n++;
+        }
+        // first packet
+        _payloadStats[n].newPacket          = false;
+        _payloadStats[n].lastPayloadLenByte = payloadSize;
+        _payloadStats[n].lastTimestamp      = rtpInfo.header.timestamp;
+        _payloadStats[n].payloadType        = rtpInfo.header.payloadType;
+    }
+}
+
+Channel::Channel(WebRtc_Word16 chID) :
+_receiverACM(NULL),
+_seqNo(0),
+_channelCritSect(CriticalSectionWrapper::CreateCriticalSection()),
+_bitStreamFile(NULL),
+_saveBitStream(false),
+_lastPayloadType(-1),
+_isStereo(false),
+_leftChannel(true),
+_useFECTestWithPacketLoss(false),
+_packetLoss(0),
+_lastInTimestamp(0),
+_chID(chID),
+_beginTime(TickTime::MillisecondTimestamp()),
+_totalBytes(0)
+{
+    int n;
+    int k;
+    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
+    {
+        _payloadStats[n].payloadType = -1;
+        _payloadStats[n].newPacket   = true;
+        for(k = 0; k < MAX_NUM_FRAMESIZES; k++)
+        {
+            _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
+            _payloadStats[n].frameSizeStats[k].maxPayloadLen   = 0;
+            _payloadStats[n].frameSizeStats[k].numPackets      = 0;
+            _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
+            _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
+        }
+    }
+    if(chID >= 0)
+    {
+        _saveBitStream = true;
+        char bitStreamFileName[500];
+        sprintf(bitStreamFileName, "bitStream_%d.dat", chID); 
+        _bitStreamFile = fopen(bitStreamFileName, "wb");
+    }
+    else
+    {
+        _saveBitStream = false;
+    }
+}
+
+Channel::~Channel()
+{
+    delete _channelCritSect;
+}
+
+void 
+Channel::RegisterReceiverACM(AudioCodingModule* acm)
+{
+    _receiverACM = acm;
+    return;
+}
+
+void 
+Channel::ResetStats()
+{
+    int n;
+    int k;
+    _channelCritSect->Enter();
+    _lastPayloadType = -1;
+    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
+    {
+        _payloadStats[n].payloadType = -1;
+        _payloadStats[n].newPacket   = true;
+        for(k = 0; k < MAX_NUM_FRAMESIZES; k++)
+        {
+            _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
+            _payloadStats[n].frameSizeStats[k].maxPayloadLen   = 0;
+            _payloadStats[n].frameSizeStats[k].numPackets      = 0;
+            _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
+            _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
+        }
+    }
+    _beginTime = TickTime::MillisecondTimestamp();
+    _totalBytes = 0;
+    _channelCritSect->Leave();
+}
+
+WebRtc_Word16 
+Channel::Stats(CodecInst& codecInst, ACMTestPayloadStats& payloadStats)
+{
+    _channelCritSect->Enter();
+    int n;
+    payloadStats.payloadType = -1;
+    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
+    {
+        if(_payloadStats[n].payloadType == codecInst.pltype)
+        {
+            memcpy(&payloadStats, &_payloadStats[n], sizeof(ACMTestPayloadStats));
+            break;
+        }
+    }
+    if(payloadStats.payloadType == -1)
+    {
+        _channelCritSect->Leave();
+        return -1;
+    }
+    for(n = 0; n < MAX_NUM_FRAMESIZES; n++)
+    {
+        if(payloadStats.frameSizeStats[n].frameSizeSample == 0)
+        {
+            _channelCritSect->Leave();
+            return 0;
+        }
+        payloadStats.frameSizeStats[n].usageLenSec = 
+            (double)payloadStats.frameSizeStats[n].totalEncodedSamples
+            / (double)codecInst.plfreq;
+
+        payloadStats.frameSizeStats[n].rateBitPerSec = 
+            payloadStats.frameSizeStats[n].totalPayloadLenByte * 8 / 
+            payloadStats.frameSizeStats[n].usageLenSec;
+
+    }
+    _channelCritSect->Leave();
+    return 0;
+}
+
+void 
+Channel::Stats(WebRtc_UWord32* numPackets)
+{
+    _channelCritSect->Enter();
+    int k;
+    int n;
+    memset(numPackets, 0, MAX_NUM_PAYLOADS * sizeof(WebRtc_UWord32));
+    for(k = 0; k < MAX_NUM_PAYLOADS; k++)
+    {
+        if(_payloadStats[k].payloadType == -1)
+        {
+            break;
+        }
+        numPackets[k] = 0;
+        for(n = 0; n < MAX_NUM_FRAMESIZES; n++)
+        {
+            if(_payloadStats[k].frameSizeStats[n].frameSizeSample == 0)
+            {
+                break;
+            }
+            numPackets[k] += 
+                _payloadStats[k].frameSizeStats[n].numPackets;
+        }
+    }
+    _channelCritSect->Leave();
+}
+
+void 
+Channel::Stats(WebRtc_UWord8* payloadType, WebRtc_UWord32* payloadLenByte)
+{
+    _channelCritSect->Enter();
+    
+    int k;
+    int n;
+    memset(payloadLenByte, 0, MAX_NUM_PAYLOADS * sizeof(WebRtc_UWord32));
+    for(k = 0; k < MAX_NUM_PAYLOADS; k++)
+    {
+        if(_payloadStats[k].payloadType == -1)
+        {
+            break;
+        }
+        payloadType[k] = (WebRtc_UWord8)_payloadStats[k].payloadType;
+        payloadLenByte[k] = 0;
+        for(n = 0; n < MAX_NUM_FRAMESIZES; n++)
+        {
+            if(_payloadStats[k].frameSizeStats[n].frameSizeSample == 0)
+            {
+                break;
+            }
+            payloadLenByte[k] += (WebRtc_UWord16)
+                _payloadStats[k].frameSizeStats[n].totalPayloadLenByte;
+        }
+    }
+
+    _channelCritSect->Leave();
+}
+
+
+void
+Channel::PrintStats(CodecInst& codecInst)
+{
+    ACMTestPayloadStats payloadStats;
+    Stats(codecInst, payloadStats);
+    printf("%s %d kHz\n", 
+        codecInst.plname,
+        codecInst.plfreq / 1000);
+    printf("=====================================================\n");
+    if(payloadStats.payloadType == -1)
+    {
+        printf("No Packets are sent with payload-type %d (%s)\n\n",
+            codecInst.pltype,
+            codecInst.plname);
+        return;
+    }
+    for(int k = 0; k < MAX_NUM_FRAMESIZES; k++)
+    {
+        if(payloadStats.frameSizeStats[k].frameSizeSample == 0)
+        {
+            break;
+        }
+        printf("Frame-size.................... %d samples\n", 
+            payloadStats.frameSizeStats[k].frameSizeSample);
+        printf("Average Rate.................. %.0f bits/sec\n", 
+            payloadStats.frameSizeStats[k].rateBitPerSec);
+        printf("Maximum Payload-Size.......... %d Bytes\n",
+            payloadStats.frameSizeStats[k].maxPayloadLen);
+        printf("Maximum Instantaneous Rate.... %.0f bits/sec\n",
+            ((double)payloadStats.frameSizeStats[k].maxPayloadLen * 8.0 * 
+            (double)codecInst.plfreq) / 
+            (double)payloadStats.frameSizeStats[k].frameSizeSample);
+        printf("Number of Packets............. %u\n",
+               (unsigned int)payloadStats.frameSizeStats[k].numPackets);
+        printf("Duration...................... %0.3f sec\n\n", 
+            payloadStats.frameSizeStats[k].usageLenSec);
+
+    }
+
+}
+
+WebRtc_UWord32
+Channel::LastInTimestamp()
+{
+    WebRtc_UWord32 timestamp;
+    _channelCritSect->Enter();
+    timestamp = _lastInTimestamp;
+    _channelCritSect->Leave();
+    return timestamp;
+}
+
+double
+Channel::BitRate()
+{
+    double rate;
+    WebRtc_UWord64 currTime = TickTime::MillisecondTimestamp();
+    _channelCritSect->Enter();
+    rate =   ((double)_totalBytes * 8.0)/ (double)(currTime - _beginTime);
+    _channelCritSect->Leave();
+    return rate;
+}   
diff --git a/src/modules/audio_coding/main/test/Channel.h b/src/modules/audio_coding/main/test/Channel.h
new file mode 100644
index 0000000..396fadc
--- /dev/null
+++ b/src/modules/audio_coding/main/test/Channel.h
@@ -0,0 +1,125 @@
+/*
+ *  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 CHANNEL_H
+#define CHANNEL_H
+
+#include <stdio.h>
+
+#include "audio_coding_module.h"
+#include "critical_section_wrapper.h"
+#include "rw_lock_wrapper.h"
+
+
+#define MAX_NUM_PAYLOADS   50
+#define MAX_NUM_FRAMESIZES  6
+
+
+struct ACMTestFrameSizeStats
+{
+    WebRtc_UWord16 frameSizeSample;
+    WebRtc_Word16  maxPayloadLen;
+    WebRtc_UWord32 numPackets;
+    WebRtc_UWord64 totalPayloadLenByte;
+    WebRtc_UWord64 totalEncodedSamples;
+    double       rateBitPerSec;
+    double       usageLenSec;
+           
+};
+
+struct ACMTestPayloadStats
+{
+    bool                  newPacket;
+    WebRtc_Word16           payloadType;
+    WebRtc_Word16           lastPayloadLenByte;
+    WebRtc_UWord32          lastTimestamp;
+    ACMTestFrameSizeStats frameSizeStats[MAX_NUM_FRAMESIZES];
+};
+
+using namespace webrtc;
+
+class Channel: public AudioPacketizationCallback
+{
+public:
+
+    Channel(
+        WebRtc_Word16 chID = -1);
+    ~Channel();
+
+    WebRtc_Word32 SendData(
+        const FrameType       frameType,
+        const WebRtc_UWord8   payloadType,
+        const WebRtc_UWord32  timeStamp,
+        const WebRtc_UWord8*  payloadData, 
+        const WebRtc_UWord16  payloadSize,
+        const RTPFragmentationHeader* fragmentation);
+
+    void RegisterReceiverACM(
+        AudioCodingModule *acm);
+    
+    void ResetStats();
+    
+    WebRtc_Word16 Stats(
+        CodecInst&     codecInst, 
+        ACMTestPayloadStats& payloadStats);
+    
+    void Stats(
+        WebRtc_UWord32* numPackets);
+    
+    void Stats(
+        WebRtc_UWord8*  payloadLenByte, 
+        WebRtc_UWord32* payloadType);
+    
+    void PrintStats(
+        CodecInst& codecInst);
+    
+    void SetIsStereo(bool isStereo)
+    {
+        _isStereo = isStereo;
+    }
+
+    WebRtc_UWord32 LastInTimestamp();
+    
+    void SetFECTestWithPacketLoss(bool usePacketLoss)
+    {
+        _useFECTestWithPacketLoss = usePacketLoss;
+    }
+
+    double BitRate();
+
+private:
+    void CalcStatistics(
+        WebRtcRTPHeader& rtpInfo, 
+        WebRtc_UWord16   payloadSize);
+
+    AudioCodingModule* _receiverACM;
+    WebRtc_UWord16           _seqNo;
+    // 60 msec * 32 sample (max) / msec * 2 description (maybe) * 2 bytes / sample
+    WebRtc_UWord8            _payloadData[60 * 32 * 2 * 2]; 
+
+    CriticalSectionWrapper* _channelCritSect;
+    FILE*                _bitStreamFile;
+    bool                 _saveBitStream;
+    WebRtc_Word16          _lastPayloadType;
+    ACMTestPayloadStats  _payloadStats[MAX_NUM_PAYLOADS];
+    bool                 _isStereo;
+    WebRtcRTPHeader        _rtpInfo;
+    bool                 _leftChannel;
+    WebRtc_UWord32         _lastInTimestamp;
+    // FEC Test variables
+    WebRtc_Word16          _packetLoss;
+    bool                 _useFECTestWithPacketLoss;
+    WebRtc_Word16          _chID;
+    WebRtc_UWord64         _beginTime;
+    WebRtc_UWord64         _totalBytes;
+};
+
+
+#endif
diff --git a/src/modules/audio_coding/main/test/EncodeDecodeTest.cpp b/src/modules/audio_coding/main/test/EncodeDecodeTest.cpp
new file mode 100644
index 0000000..08555da
--- /dev/null
+++ b/src/modules/audio_coding/main/test/EncodeDecodeTest.cpp
@@ -0,0 +1,303 @@
+/*
+ *  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 "EncodeDecodeTest.h"
+#include "common_types.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include "trace.h"
+#include "utility.h"
+
+Receiver::Receiver()
+:
+_playoutLengthSmpls(WEBRTC_10MS_PCM_AUDIO),
+_payloadSizeBytes(MAX_INCOMING_PAYLOAD)
+{
+}
+
+void Receiver::Setup(AudioCodingModule *acm, RTPStream *rtpStream)
+{
+    struct CodecInst recvCodec;
+    int noOfCodecs;
+    acm->InitializeReceiver();
+
+    noOfCodecs = acm->NumberOfCodecs();
+    for (int i=0; i < noOfCodecs; i++)
+    {
+        acm->Codec((WebRtc_UWord8)i, recvCodec);      
+        if (acm->RegisterReceiveCodec(recvCodec) != 0)
+        {
+            printf("Unable to register codec: for run: codecId: %d\n", codeId);
+            exit(1);
+        }
+    }
+     
+    char filename[128];
+    _rtpStream = rtpStream;
+    int playSampFreq;
+
+    if (testMode == 1)
+    {
+      playSampFreq=recvCodec.plfreq;
+      //output file for current run
+      sprintf(filename,"./modules/audio_coding/main/test/res_tests/out%dFile.pcm",codeId);
+      _pcmFile.Open(filename, recvCodec.plfreq, "wb+");
+    }
+    else if (testMode == 0)
+    {
+        playSampFreq=32000;
+      //output file for current run
+      sprintf(filename,"./modules/audio_coding/main/test/res_autotests/encodeDecode_out%d.pcm",codeId);
+      _pcmFile.Open(filename, 32000/*recvCodec.plfreq*/, "wb+");
+    }
+    else
+    {
+        printf("\nValid output frequencies:\n");
+        printf("8000\n16000\n32000\n-1, which means output freq equal to received signal freq");
+        printf("\n\nChoose output sampling frequency: ");       
+        scanf("%d", &playSampFreq);
+        char fileName[] = "./modules/audio_coding/main/test/outFile.pcm";
+        _pcmFile.Open(fileName, 32000, "wb+");
+    }
+     
+    _realPayloadSizeBytes = 0;
+    _playoutBuffer = new WebRtc_Word16[WEBRTC_10MS_PCM_AUDIO];
+    _frequency = playSampFreq;
+    _acm = acm;
+    _firstTime = true;
+}
+
+void Receiver::Teardown()
+{
+    delete [] _playoutBuffer;
+    _pcmFile.Close();
+    if (testMode > 1) Trace::ReturnTrace();
+}
+
+bool Receiver::IncomingPacket()
+{
+    if (!_rtpStream->EndOfFile())
+    {
+        if (_firstTime)
+        {
+            _firstTime = false;
+            _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, _payloadSizeBytes, &_nextTime);
+            if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile())
+            {
+                _firstTime = true;
+                return true;
+            }
+        }
+        
+       WebRtc_Word32 ok = _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes, _rtpInfo);
+        if (ok != 0)
+        {
+            printf("Error when inserting packet to ACM, for run: codecId: %d\n", codeId);
+            exit(1);
+        }
+        _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, _payloadSizeBytes, &_nextTime);
+        if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile())
+        {
+            _firstTime = true;
+        }
+    }
+    return true;
+}
+
+bool Receiver::PlayoutData()
+{
+    AudioFrame audioFrame;
+
+    if (_acm->PlayoutData10Ms(_frequency, audioFrame) != 0)
+    {
+        printf("Error when calling PlayoutData10Ms, for run: codecId: %d\n", codeId);
+        exit(1);
+    }
+    if (_playoutLengthSmpls == 0)
+    {
+        return false;
+    }
+    _pcmFile.Write10MsData(audioFrame._payloadData, audioFrame._payloadDataLengthInSamples);
+    return true;
+}
+
+void Receiver::Run()
+{
+    WebRtc_UWord8 counter500Ms = 50;
+    
+    WebRtc_UWord32 clock = 0;
+
+    while (counter500Ms > 0)
+    {
+        if (clock == 0 || clock >= _nextTime)
+        {
+            IncomingPacket();
+            if (clock == 0)
+            {
+                clock = _nextTime;
+            }
+        }
+        if ((clock % 10) == 0)
+        {
+            if (!PlayoutData())
+            {
+                clock++;
+                continue;
+            }
+        }
+        if (_rtpStream->EndOfFile())
+        {
+            counter500Ms--;
+        }
+        clock++;
+    }
+}
+
+EncodeDecodeTest::EncodeDecodeTest()
+{
+    _testMode = 2;
+    Trace::CreateTrace();
+    Trace::SetTraceFile("acm_encdec_test.txt");
+}
+
+EncodeDecodeTest::EncodeDecodeTest(int testMode)
+{
+    //testMode == 0 for autotest
+    //testMode == 1 for testing all codecs/parameters
+    //testMode > 1 for specific user-input test (as it was used before)
+   _testMode = testMode;
+   if(_testMode != 0)
+   {
+       Trace::CreateTrace();
+       Trace::SetTraceFile("acm_encdec_test.txt");
+   }
+}
+void EncodeDecodeTest::Perform()
+{
+
+    if(_testMode == 0)
+    {
+        printf("Running Encode/Decode Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- EncodeDecodeTest ----------");
+    }
+
+    int numCodecs = 1;
+    int codePars[3]; //freq, pacsize, rate     
+    int playoutFreq[3]; //8, 16, 32k   
+
+    int numPars[52]; //number of codec parameters sets (rate,freq,pacsize)to test, for a given codec                    
+        
+    codePars[0]=0;
+    codePars[1]=0;
+    codePars[2]=0;
+
+    if (_testMode == 1)
+    {
+        AudioCodingModule *acmTmp = AudioCodingModule::Create(0);
+        struct CodecInst sendCodecTmp;
+        numCodecs = acmTmp->NumberOfCodecs();
+        printf("List of supported codec.\n");
+        for(int n = 0; n < numCodecs; n++)
+        {
+            acmTmp->Codec(n, sendCodecTmp);
+            if (STR_CASE_CMP(sendCodecTmp.plname, "telephone-event") == 0) {
+                numPars[n] = 0;
+            } else if (STR_CASE_CMP(sendCodecTmp.plname, "cn") == 0) {
+                numPars[n] = 0;
+            } else if (STR_CASE_CMP(sendCodecTmp.plname, "red") == 0) {
+                numPars[n] = 0;
+            } else {
+                numPars[n] = 1;
+                printf("%d %s\n", n, sendCodecTmp.plname);
+            }
+        }
+        AudioCodingModule::Destroy(acmTmp);
+        playoutFreq[1]=16000;
+    }
+    else if (_testMode == 0)
+    {
+        AudioCodingModule *acmTmp = AudioCodingModule::Create(0);
+        numCodecs = acmTmp->NumberOfCodecs();
+        AudioCodingModule::Destroy(acmTmp);
+        struct CodecInst dummyCodec;
+
+        //chose range of testing for codecs/parameters
+        for(int i = 0 ; i < numCodecs ; i++)
+        {
+            numPars[i] = 1;
+            acmTmp->Codec(i, dummyCodec);
+            if (STR_CASE_CMP(dummyCodec.plname, "telephone-event") == 0)
+            {
+                numPars[i] = 0;
+            } else if (STR_CASE_CMP(dummyCodec.plname, "cn") == 0) {
+                numPars[i] = 0;
+            } else if (STR_CASE_CMP(dummyCodec.plname, "red") == 0) {
+                numPars[i] = 0;
+            }
+        }
+        playoutFreq[1] = 16000;
+    }
+    else 
+    {
+        numCodecs = 1;
+        numPars[0] = 1;
+        playoutFreq[1]=16000;
+    }
+
+    _receiver.testMode = _testMode;
+
+     //loop over all codecs:
+     for(int codeId=0;codeId<numCodecs;codeId++)
+     {
+         //only encode using real encoders, not telephone-event anc cn
+         for(int loopPars=1;loopPars<=numPars[codeId];loopPars++)
+         {
+             if (_testMode == 1)
+             {
+                 printf("\n");
+                 printf("***FOR RUN: codeId: %d\n",codeId);
+                 printf("\n");
+             }
+             else if (_testMode == 0)
+             {
+                 printf(".");
+             }
+
+             EncodeToFileTest::Perform(1, codeId, codePars, _testMode);
+
+             AudioCodingModule *acm = AudioCodingModule::Create(10);
+             RTPFile rtpFile;
+             char fileName[] = "outFile.rtp";
+             rtpFile.Open(fileName, "rb");
+
+             _receiver.codeId = codeId;
+
+             rtpFile.ReadHeader();
+             _receiver.Setup(acm, &rtpFile);
+             _receiver.Run();
+             _receiver.Teardown();
+             rtpFile.Close();
+             AudioCodingModule::Destroy(acm);
+
+             if (_testMode == 1)
+             {
+                 printf("***COMPLETED RUN FOR: codecID: %d ***\n",
+                     codeId);
+             }
+        }
+    }
+    if (_testMode == 0)
+    {
+        printf("Done!\n");
+    }
+    if (_testMode == 1) Trace::ReturnTrace();
+}
+
diff --git a/src/modules/audio_coding/main/test/EncodeDecodeTest.h b/src/modules/audio_coding/main/test/EncodeDecodeTest.h
new file mode 100644
index 0000000..01172f3
--- /dev/null
+++ b/src/modules/audio_coding/main/test/EncodeDecodeTest.h
@@ -0,0 +1,64 @@
+/*
+ *  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 ENCODEDECODETEST_H
+#define ENCODEDECODETEST_H
+
+#include "EncodeToFileTest.h"
+
+#define MAX_INCOMING_PAYLOAD 8096
+#include "audio_coding_module.h"
+
+class Receiver
+{
+public:
+    Receiver();
+    void Setup(AudioCodingModule *acm, RTPStream *rtpStream);
+    void Teardown();
+    void Run();
+    bool IncomingPacket();
+    bool PlayoutData();    
+
+    //for auto_test and logging
+    WebRtc_UWord8             codeId;
+    WebRtc_UWord8             testMode;
+
+private:
+    AudioCodingModule*    _acm;
+    bool                  _rtpEOF;
+    RTPStream*            _rtpStream;
+    PCMFile               _pcmFile;
+    WebRtc_Word16*        _playoutBuffer;
+    WebRtc_UWord16        _playoutLengthSmpls;
+    WebRtc_Word8          _incomingPayload[MAX_INCOMING_PAYLOAD];
+    WebRtc_UWord16        _payloadSizeBytes;
+    WebRtc_UWord16        _realPayloadSizeBytes;
+    WebRtc_Word32         _frequency;
+    bool                  _firstTime;
+    WebRtcRTPHeader       _rtpInfo;
+    WebRtc_UWord32        _nextTime;
+};
+
+class EncodeDecodeTest : public EncodeToFileTest
+{
+public:
+    EncodeDecodeTest();
+    EncodeDecodeTest(int testMode);
+    virtual void Perform();
+    WebRtc_UWord16            _playoutFreq;    
+    WebRtc_UWord8             _testMode;
+protected:
+    Receiver    _receiver;    
+};      
+
+
+
+#endif
+
diff --git a/src/modules/audio_coding/main/test/EncodeToFileTest.cpp b/src/modules/audio_coding/main/test/EncodeToFileTest.cpp
new file mode 100644
index 0000000..6eed2ea
--- /dev/null
+++ b/src/modules/audio_coding/main/test/EncodeToFileTest.cpp
@@ -0,0 +1,188 @@
+/*
+ *  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 "EncodeToFileTest.h"
+#include "audio_coding_module.h"
+#include "common_types.h"
+
+#ifdef WIN32
+#   include <Winsock2.h>
+#else
+#   include <arpa/inet.h>
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+TestPacketization::TestPacketization(RTPStream *rtpStream, WebRtc_UWord16 frequency)
+:
+_frequency(frequency),
+_seqNo(0)
+{
+    _rtpStream = rtpStream;
+}
+
+TestPacketization::~TestPacketization()
+{
+}
+
+WebRtc_Word32 TestPacketization::SendData(
+    const FrameType       /* frameType */,
+    const WebRtc_UWord8   payloadType,
+    const WebRtc_UWord32  timeStamp,
+    const WebRtc_UWord8*  payloadData, 
+    const WebRtc_UWord16  payloadSize,
+    const RTPFragmentationHeader* /* fragmentation */)
+{
+    _rtpStream->Write(payloadType, timeStamp, _seqNo++, payloadData, payloadSize, _frequency);
+    //delete [] payloadData;
+    return 1;
+}
+
+Sender::Sender()
+:
+_acm(NULL),
+//_payloadData(NULL),
+_payloadSize(0),
+_timeStamp(0)
+{
+}
+
+void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream)
+{
+    acm->InitializeSender();
+    struct CodecInst sendCodec;
+    int noOfCodecs = acm->NumberOfCodecs();
+    int codecNo;
+    
+    if (testMode == 1)
+    {
+        //set the codec, input file, and parameters for the current test    
+        codecNo = codeId;
+        //use same input file for now
+        char fileName[] = "./modules/audio_coding/main/test/testfile32kHz.pcm";
+        _pcmFile.Open(fileName, 32000, "rb");
+    }
+    else if (testMode == 0)
+    {
+        //set the codec, input file, and parameters for the current test    
+        codecNo = codeId;
+        acm->Codec(codecNo, sendCodec);
+        //use same input file for now
+        char fileName[] = "./modules/audio_coding/main/test/testfile32kHz.pcm";
+        _pcmFile.Open(fileName, 32000, "rb");
+    }
+    else
+    {
+        printf("List of supported codec.\n");
+        for(int n = 0; n < noOfCodecs; n++)
+        {
+            acm->Codec(n, sendCodec);
+            printf("%d %s\n", n, sendCodec.plname);
+        }
+        printf("Choose your codec:");
+    
+        scanf("%d", &codecNo);
+        char fileName[] = "./modules/audio_coding/main/test/testfile32kHz.pcm";
+        _pcmFile.Open(fileName, 32000, "rb");
+    }
+
+    acm->Codec(codecNo, sendCodec);
+    acm->RegisterSendCodec(sendCodec);
+    _packetization = new TestPacketization(rtpStream, sendCodec.plfreq);
+    if(acm->RegisterTransportCallback(_packetization) < 0)
+    {
+        printf("Registering Transport Callback failed, for run: codecId: %d: --\n",
+                codeId);
+    }
+
+    _acm = acm;
+}
+
+void Sender::Teardown()
+{
+    _pcmFile.Close();
+    delete _packetization;
+}
+
+bool Sender::Add10MsData()
+{
+    if (!_pcmFile.EndOfFile())
+    {
+        _pcmFile.Read10MsData(_audioFrame);
+        WebRtc_Word32 ok = _acm->Add10MsData(_audioFrame);
+        if (ok != 0)
+        {
+            printf("Error calling Add10MsData: for run: codecId: %d\n",
+                codeId);
+            exit(1);
+        }
+        //_audioFrame._timeStamp += _pcmFile.PayloadLength10Ms();
+        return true;
+    }
+    return false;
+}
+
+bool Sender::Process()
+{
+    WebRtc_Word32 ok = _acm->Process();
+    if (ok < 0)
+    {
+        printf("Error calling Add10MsData: for run: codecId: %d\n",
+                codeId);
+        exit(1);
+    }
+    return true;
+}
+
+void Sender::Run()
+{
+    while (true)
+    {
+        if (!Add10MsData())
+        {
+            break;
+        }
+        if (!Process()) // This could be done in a processing thread
+        {
+            break;
+        }
+    }
+}
+
+EncodeToFileTest::EncodeToFileTest()
+{
+}
+
+
+void EncodeToFileTest::Perform(int fileType, int codeId, int* codePars, int testMode)
+{
+    AudioCodingModule *acm = AudioCodingModule::Create(0);
+    RTPFile rtpFile;
+    char fileName[] = "outFile.rtp";
+    rtpFile.Open(fileName, "wb+");
+    rtpFile.WriteHeader();
+
+    //for auto_test and logging
+    _sender.testMode = testMode;
+    _sender.codeId = codeId;
+
+    _sender.Setup(acm, &rtpFile);
+    struct CodecInst sendCodecInst;
+    if(acm->SendCodec(sendCodecInst) >= 0)
+    {
+        _sender.Run();
+    }
+    _sender.Teardown();
+    rtpFile.Close();
+    AudioCodingModule::Destroy(acm);
+}
diff --git a/src/modules/audio_coding/main/test/EncodeToFileTest.h b/src/modules/audio_coding/main/test/EncodeToFileTest.h
new file mode 100644
index 0000000..fdd3804
--- /dev/null
+++ b/src/modules/audio_coding/main/test/EncodeToFileTest.h
@@ -0,0 +1,79 @@
+/*
+ *  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 ENCODETOFILETEST_H
+#define ENCODETOFILETEST_H
+
+#include "ACMTest.h"
+#include "audio_coding_module.h"
+#include "typedefs.h"
+#include "RTPFile.h"
+#include "PCMFile.h"
+#include <stdio.h>
+
+using namespace webrtc;
+
+// TestPacketization callback which writes the encoded payloads to file
+class TestPacketization : public AudioPacketizationCallback
+{
+public:
+    TestPacketization(RTPStream *rtpStream, WebRtc_UWord16 frequency);
+    ~TestPacketization();
+    virtual WebRtc_Word32 SendData(const FrameType frameType,
+        const WebRtc_UWord8 payloadType,
+        const WebRtc_UWord32 timeStamp,
+        const WebRtc_UWord8* payloadData, 
+        const WebRtc_UWord16 payloadSize,
+        const RTPFragmentationHeader* fragmentation);
+
+private:
+    static void MakeRTPheader(WebRtc_UWord8* rtpHeader, 
+                              WebRtc_UWord8 payloadType, WebRtc_Word16 seqNo,
+                              WebRtc_UWord32 timeStamp, WebRtc_UWord32 ssrc);
+    RTPStream*      _rtpStream;
+    WebRtc_Word32    _frequency;
+    WebRtc_Word16     _seqNo;
+};
+
+class Sender
+{
+public:
+    Sender();
+    void Setup(AudioCodingModule *acm, RTPStream *rtpStream);
+    void Teardown();
+    void Run();
+    bool Add10MsData();
+    bool Process();
+
+    //for auto_test and logging
+    WebRtc_UWord8             testMode;
+    WebRtc_UWord8             codeId;
+
+private:
+    AudioCodingModule*  _acm;
+    PCMFile             _pcmFile;
+    //WebRtc_Word16*    _payloadData;
+    AudioFrame          _audioFrame;
+    WebRtc_UWord16      _payloadSize;
+    WebRtc_UWord32      _timeStamp;
+    TestPacketization*  _packetization;
+};
+
+// Test class
+class EncodeToFileTest : public ACMTest
+{
+public:
+    EncodeToFileTest();
+    virtual void Perform(int fileType, int codeId, int* codePars, int testMode);
+protected:
+    Sender _sender;
+};
+
+#endif
diff --git a/src/modules/audio_coding/main/test/PCMFile.cpp b/src/modules/audio_coding/main/test/PCMFile.cpp
new file mode 100644
index 0000000..7418a3e
--- /dev/null
+++ b/src/modules/audio_coding/main/test/PCMFile.cpp
@@ -0,0 +1,300 @@
+/*
+ *  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 <cctype>
+#include <stdio.h>
+#include <string.h>
+
+
+#include "PCMFile.h"
+#include "module_common_types.h"
+
+#define MAX_FILE_NAME_LENGTH_BYTE 500
+
+
+
+PCMFile::PCMFile(): 
+_pcmFile(NULL), 
+_nSamples10Ms(160), 
+_frequency(16000), 
+_endOfFile(false), 
+_autoRewind(false), 
+_rewinded(false),
+_timestamp(0),
+_readStereo(false),
+_saveStereo(false)
+{
+    _timestamp = (((WebRtc_UWord32)rand() & 0x0000FFFF) << 16) |
+        ((WebRtc_UWord32)rand() & 0x0000FFFF);
+}
+
+/*
+PCMFile::~PCMFile()
+{
+    if(_pcmFile != NULL)
+    {
+        fclose(_pcmFile);
+        _pcmFile = NULL;
+    }
+}
+*/
+
+WebRtc_Word16
+PCMFile::ChooseFile(
+    char*       fileName, 
+    WebRtc_Word16 maxLen)
+{
+    WebRtc_Word8 tmpName[MAX_FILE_NAME_LENGTH_BYTE];
+    //strcpy(_fileName, "in.pcm");
+    //printf("\n\nPlease enter the input file: ");
+    fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin);
+    tmpName[MAX_FILE_NAME_LENGTH_BYTE-1] = '\0';
+    WebRtc_Word16 n = 0;
+
+    // removing leading spaces
+    while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
+        (tmpName[n] != 0) && 
+        (n < MAX_FILE_NAME_LENGTH_BYTE))
+    {
+        n++;
+    }
+    if(n > 0)
+    {
+        memmove(tmpName, &tmpName[n], MAX_FILE_NAME_LENGTH_BYTE - n);
+    }
+
+    //removing trailing spaces
+    n = (WebRtc_Word16)(strlen(tmpName) - 1);
+    if(n >= 0)
+    {
+        while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
+            (n >= 0))
+        {
+            n--;
+        }
+    }
+    if(n >= 0)
+    {
+        tmpName[n + 1] = '\0';
+    }
+
+    WebRtc_Word16 len = (WebRtc_Word16)strlen(tmpName);
+    if(len > maxLen)
+    {
+        return -1;
+    }    
+    if(len > 0)
+    {
+        strncpy(fileName, tmpName, len+1);
+    }
+    return 0;
+}
+
+WebRtc_Word16
+PCMFile::ChooseFile(
+    char*         fileName, 
+    WebRtc_Word16   maxLen, 
+    WebRtc_UWord16* frequencyHz)
+{
+    WebRtc_Word8 tmpName[MAX_FILE_NAME_LENGTH_BYTE];
+    //strcpy(_fileName, "in.pcm");
+    //printf("\n\nPlease enter the input file: ");
+    fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin);
+    tmpName[MAX_FILE_NAME_LENGTH_BYTE-1] = '\0';
+    WebRtc_Word16 n = 0;
+
+    // removing leading spaces
+    while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
+        (tmpName[n] != 0) && 
+        (n < MAX_FILE_NAME_LENGTH_BYTE))
+    {
+        n++;
+    }
+    if(n > 0)
+    {
+        memmove(tmpName, &tmpName[n], MAX_FILE_NAME_LENGTH_BYTE - n);
+    }
+
+    //removing trailing spaces
+    n = (WebRtc_Word16)(strlen(tmpName) - 1);
+    if(n >= 0)
+    {
+        while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
+            (n >= 0))
+        {
+            n--;
+        }
+    }
+    if(n >= 0)
+    {
+        tmpName[n + 1] = '\0';
+    }
+
+    WebRtc_Word16 len = (WebRtc_Word16)strlen(tmpName);
+    if(len > maxLen)
+    {
+        return -1;
+    }    
+    if(len > 0)
+    {
+        strncpy(fileName, tmpName, len+1);
+    }
+    printf("Enter the sampling frequency (in Hz) of the above file [%u]: ", *frequencyHz);
+    fgets(tmpName, 10, stdin);
+    WebRtc_UWord16 tmpFreq = (WebRtc_UWord16)atoi(tmpName);
+    if(tmpFreq > 0)
+    {
+        *frequencyHz = tmpFreq;
+    }
+    return 0;
+}
+
+void 
+PCMFile::Open(
+    char*        filename, 
+    WebRtc_UWord16 frequency, 
+    const char*  mode, 
+    bool         autoRewind)
+{
+    if ((_pcmFile = fopen(filename, mode)) == NULL)
+    {
+        printf("Cannot open file %s.\n", filename);
+        throw "Unable to read file";
+        exit(1);
+    }
+    _frequency = frequency;
+    _nSamples10Ms = (WebRtc_UWord16)(_frequency / 100);
+    _autoRewind = autoRewind;
+    _endOfFile = false;
+    _rewinded = false;
+}
+
+WebRtc_Word32 
+PCMFile::SamplingFrequency() const
+{
+    return _frequency;
+}
+
+WebRtc_UWord16 
+PCMFile::PayloadLength10Ms() const
+{
+    return _nSamples10Ms;
+}
+
+WebRtc_Word32 
+PCMFile::Read10MsData(
+    AudioFrame& audioFrame)
+{
+    WebRtc_UWord16 noChannels = 1;
+    if (_readStereo)
+    {
+        noChannels = 2;
+    }
+
+    WebRtc_Word32 payloadSize = (WebRtc_Word32)fread(audioFrame._payloadData, sizeof(WebRtc_UWord16), _nSamples10Ms*noChannels, _pcmFile);
+    if (payloadSize < _nSamples10Ms*noChannels) {
+        for (int k = payloadSize; k < _nSamples10Ms*noChannels; k++)
+        {
+            audioFrame._payloadData[k] = 0;
+        }
+        if(_autoRewind)
+        {
+            rewind(_pcmFile);
+            _rewinded = true;
+        }
+        else
+        {
+            _endOfFile = true;
+        }
+    }
+    audioFrame._payloadDataLengthInSamples = _nSamples10Ms;
+    audioFrame._frequencyInHz = _frequency;
+    audioFrame._audioChannel = noChannels;
+    audioFrame._timeStamp = _timestamp;
+    _timestamp += _nSamples10Ms;
+    return _nSamples10Ms;
+}
+
+void 
+PCMFile::Write10MsData(
+    AudioFrame& audioFrame)
+{
+    if(audioFrame._audioChannel == 1)
+    {
+        if(!_saveStereo)
+        {
+            fwrite(audioFrame._payloadData, sizeof(WebRtc_UWord16), 
+                audioFrame._payloadDataLengthInSamples, _pcmFile);
+        }
+        else
+        {
+            WebRtc_Word16* stereoAudio = new WebRtc_Word16[2 * 
+                audioFrame._payloadDataLengthInSamples];
+            int k;
+            for(k = 0; k < audioFrame._payloadDataLengthInSamples; k++)
+            {
+                stereoAudio[k<<1] = audioFrame._payloadData[k];
+                stereoAudio[(k<<1) + 1] = audioFrame._payloadData[k];
+            }
+            fwrite(stereoAudio, sizeof(WebRtc_Word16), 2*audioFrame._payloadDataLengthInSamples,
+                _pcmFile);
+            delete [] stereoAudio;
+        }
+    }
+    else
+    {
+        fwrite(audioFrame._payloadData, sizeof(WebRtc_Word16), 
+            audioFrame._audioChannel * audioFrame._payloadDataLengthInSamples, _pcmFile);
+    }
+}
+
+
+void 
+PCMFile::Write10MsData(
+    WebRtc_Word16* playoutBuffer, 
+    WebRtc_UWord16 playoutLengthSmpls)
+{
+    fwrite(playoutBuffer, sizeof(WebRtc_UWord16), playoutLengthSmpls, _pcmFile);
+}
+
+
+void 
+PCMFile::Close()
+{
+    fclose(_pcmFile);
+    _pcmFile = NULL;
+}
+
+void 
+PCMFile::Rewind()
+{
+    rewind(_pcmFile);
+    _endOfFile = false;
+}
+
+bool 
+PCMFile::Rewinded()
+{
+    return _rewinded;
+}
+
+void
+PCMFile::SaveStereo(
+    bool saveStereo)
+{
+    _saveStereo = saveStereo;
+}
+
+void
+PCMFile::ReadStereo(
+    bool readStereo)
+{
+    _readStereo = readStereo;
+}
diff --git a/src/modules/audio_coding/main/test/PCMFile.h b/src/modules/audio_coding/main/test/PCMFile.h
new file mode 100644
index 0000000..dd8d06f
--- /dev/null
+++ b/src/modules/audio_coding/main/test/PCMFile.h
@@ -0,0 +1,76 @@
+/*
+ *  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 PCMFILE_H
+#define PCMFILE_H
+
+#include "typedefs.h"
+#include "module_common_types.h"
+#include <cstdio>
+#include <cstdlib>
+
+// class PCMStream
+// {
+// protected:    
+//     PCMStream(){}
+//     ~PCMStream(){}
+// public:
+//     virtual WebRtc_Word32 Read10MsData(AudioFrame& audioFrame) = 0;
+//     virtual void Write10MsData(WebRtc_Word16 *playoutBuffer, WebRtc_UWord16 playoutLengthSmpls) = 0;
+//     virtual WebRtc_UWord16 PayloadLength10Ms() const = 0;
+//     virtual WebRtc_Word32 SamplingFrequency() const = 0;
+// };
+
+
+using namespace webrtc;
+
+class PCMFile /*: public PCMStream*/
+{
+public:
+    PCMFile();
+    ~PCMFile()
+    {
+        if(_pcmFile != NULL)
+        {
+            fclose(_pcmFile);
+        }
+    }
+    void Open(char *filename, WebRtc_UWord16 frequency, const char *mode, bool autoRewind = false);
+    
+    WebRtc_Word32 Read10MsData(AudioFrame& audioFrame);
+    
+    void Write10MsData(WebRtc_Word16 *playoutBuffer, WebRtc_UWord16 playoutLengthSmpls);
+    void Write10MsData(AudioFrame& audioFrame);
+
+    WebRtc_UWord16 PayloadLength10Ms() const;
+    WebRtc_Word32 SamplingFrequency() const;
+    void Close();
+    bool EndOfFile() const { return _endOfFile; }
+    void Rewind();
+    static WebRtc_Word16 ChooseFile(char* fileName, WebRtc_Word16 maxLen, WebRtc_UWord16* frequencyHz);
+    static WebRtc_Word16 ChooseFile(char* fileName, WebRtc_Word16 maxLen);
+    bool Rewinded();
+    void SaveStereo(
+        bool saveStereo = true);
+    void ReadStereo(
+        bool readStereo = true);
+private:
+    FILE*           _pcmFile;
+    WebRtc_UWord16    _nSamples10Ms;
+    WebRtc_Word32     _frequency;
+    bool            _endOfFile;
+    bool            _autoRewind;
+    bool            _rewinded;
+    WebRtc_UWord32    _timestamp;
+    bool            _saveStereo;
+    bool            _readStereo;
+};
+
+#endif
diff --git a/src/modules/audio_coding/main/test/RTPFile.cpp b/src/modules/audio_coding/main/test/RTPFile.cpp
new file mode 100644
index 0000000..23d78d7
--- /dev/null
+++ b/src/modules/audio_coding/main/test/RTPFile.cpp
@@ -0,0 +1,297 @@
+/*
+ *  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 "RTPFile.h"
+#include "rw_lock_wrapper.h"
+#include "engine_configurations.h"
+#include <stdlib.h>
+
+#ifdef WIN32
+#   include <Winsock2.h>
+#else
+#   include <arpa/inet.h>
+#endif
+
+#include "audio_coding_module.h"
+
+void RTPStream::ParseRTPHeader(WebRtcRTPHeader* rtpInfo, const WebRtc_UWord8* rtpHeader)
+{
+    rtpInfo->header.payloadType = rtpHeader[1];
+    rtpInfo->header.sequenceNumber = (static_cast<WebRtc_UWord16>(rtpHeader[2])<<8) | rtpHeader[3];
+    rtpInfo->header.timestamp = (static_cast<WebRtc_UWord32>(rtpHeader[4])<<24) |
+                         (static_cast<WebRtc_UWord32>(rtpHeader[5])<<16) |
+                         (static_cast<WebRtc_UWord32>(rtpHeader[6])<<8) |
+                         rtpHeader[7];
+    rtpInfo->header.ssrc = (static_cast<WebRtc_UWord32>(rtpHeader[8])<<24) |
+                    (static_cast<WebRtc_UWord32>(rtpHeader[9])<<16) |
+                    (static_cast<WebRtc_UWord32>(rtpHeader[10])<<8) |
+                    rtpHeader[11];
+}
+
+void RTPStream::MakeRTPheader(WebRtc_UWord8* rtpHeader, 
+                              WebRtc_UWord8 payloadType, WebRtc_Word16 seqNo,
+                              WebRtc_UWord32 timeStamp, WebRtc_UWord32 ssrc)
+{
+    rtpHeader[0]=(unsigned char)0x80;
+    rtpHeader[1]=(unsigned char)(payloadType & 0xFF);
+    rtpHeader[2]=(unsigned char)((seqNo>>8)&0xFF);
+    rtpHeader[3]=(unsigned char)((seqNo)&0xFF);
+    rtpHeader[4]=(unsigned char)((timeStamp>>24)&0xFF);
+    rtpHeader[5]=(unsigned char)((timeStamp>>16)&0xFF);
+
+    rtpHeader[6]=(unsigned char)((timeStamp>>8)&0xFF); 
+    rtpHeader[7]=(unsigned char)(timeStamp & 0xFF);
+
+    rtpHeader[8]=(unsigned char)((ssrc>>24)&0xFF);
+    rtpHeader[9]=(unsigned char)((ssrc>>16)&0xFF);
+
+    rtpHeader[10]=(unsigned char)((ssrc>>8)&0xFF);
+    rtpHeader[11]=(unsigned char)(ssrc & 0xFF);
+}
+
+
+RTPPacket::RTPPacket(WebRtc_UWord8 payloadType, WebRtc_UWord32 timeStamp,
+                                    WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                                    WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency)
+                                    :
+payloadType(payloadType),
+timeStamp(timeStamp),
+seqNo(seqNo),
+payloadSize(payloadSize),
+frequency(frequency)
+{
+    if (payloadSize > 0)
+    {
+        this->payloadData = new WebRtc_UWord8[payloadSize];
+        memcpy(this->payloadData, payloadData, payloadSize);
+    }
+}
+
+RTPPacket::~RTPPacket()
+{
+    delete [] payloadData;
+}
+
+RTPBuffer::RTPBuffer()
+{
+    _queueRWLock = RWLockWrapper::CreateRWLock();
+}
+
+RTPBuffer::~RTPBuffer()
+{
+    delete _queueRWLock;
+}
+
+void
+RTPBuffer::Write(const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp,
+                                    const WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                                    const WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency)
+{
+    RTPPacket *packet = new RTPPacket(payloadType, timeStamp, seqNo, payloadData, payloadSize, frequency);
+    _queueRWLock->AcquireLockExclusive();
+    _rtpQueue.push(packet);
+    _queueRWLock->ReleaseLockExclusive();
+}
+
+WebRtc_UWord16
+RTPBuffer::Read(WebRtcRTPHeader* rtpInfo,
+                WebRtc_Word8* payloadData, 
+                WebRtc_UWord16 payloadSize,
+                WebRtc_UWord32* offset)
+{
+    _queueRWLock->AcquireLockShared();
+    RTPPacket *packet = _rtpQueue.front();
+    _rtpQueue.pop();
+    _queueRWLock->ReleaseLockShared();
+    rtpInfo->header.markerBit = 1;
+    rtpInfo->header.payloadType = packet->payloadType;
+    rtpInfo->header.sequenceNumber = packet->seqNo;
+    rtpInfo->header.ssrc = 0;
+    rtpInfo->header.timestamp = packet->timeStamp;
+    if (packet->payloadSize > 0 && payloadSize >= packet->payloadSize)
+    {
+        memcpy(payloadData, packet->payloadData, packet->payloadSize);
+    }
+    else
+    {
+        throw "Payload buffer too small";
+        exit(1);
+    }
+/*#ifdef WEBRTC_CODEC_G722
+    if(ACMCodecDB::_mycodecs[ACMCodecDB::g722].pltype == packet->payloadType)
+    {
+        *offset = (packet->timeStamp/(packet->frequency/1000))<<1;
+    }
+    else
+    {
+#endif*/
+        *offset = (packet->timeStamp/(packet->frequency/1000));
+/*#ifdef WEBRTC_CODEC_G722
+    }
+#endif*/
+    return packet->payloadSize;
+}
+
+bool
+RTPBuffer::EndOfFile() const
+{
+    _queueRWLock->AcquireLockShared();
+    bool eof = _rtpQueue.empty();
+    _queueRWLock->ReleaseLockShared();
+    return eof;
+}
+
+void RTPFile::Open(char *filename, const char *mode)
+{
+    if ((_rtpFile = fopen(filename, mode)) == NULL)
+    {
+        printf("Cannot write file %s.\n", filename);
+        throw "Unable to write file";
+        exit(1);
+    }
+}
+
+void RTPFile::Close()
+{
+    if (_rtpFile != NULL)
+    {
+        fclose(_rtpFile);
+        _rtpFile = NULL;
+    }
+}
+
+
+void RTPFile::WriteHeader()
+{
+    // Write data in a format that NetEQ and RTP Play can parse
+    fprintf(_rtpFile, "#!RTPencode%s\n", "1.0");
+    WebRtc_UWord32 dummy_variable = 0; // should be converted to network endian format, but does not matter when 0
+    fwrite(&dummy_variable, 4, 1, _rtpFile);
+    fwrite(&dummy_variable, 4, 1, _rtpFile);
+    fwrite(&dummy_variable, 4, 1, _rtpFile);
+    fwrite(&dummy_variable, 2, 1, _rtpFile);
+    fwrite(&dummy_variable, 2, 1, _rtpFile);
+    fflush(_rtpFile);
+}
+
+void RTPFile::ReadHeader()
+{
+    WebRtc_UWord32 start_sec, start_usec, source;
+    WebRtc_UWord16 port, padding;
+    char fileHeader[40];
+    fgets(fileHeader, 40, _rtpFile);
+    fread(&start_sec, 4, 1, _rtpFile);
+    start_sec=ntohl(start_sec);
+    fread(&start_usec, 4, 1, _rtpFile);
+    start_usec=ntohl(start_usec);
+    fread(&source, 4, 1, _rtpFile);
+    source=ntohl(source);
+    fread(&port, 2, 1, _rtpFile);
+    port=ntohs(port);
+    fread(&padding, 2, 1, _rtpFile);
+    padding=ntohs(padding);
+}
+
+void RTPFile::Write(const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp,
+                    const WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                    const WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency)
+{
+    /* write RTP packet to file */
+    WebRtc_UWord8 rtpHeader[12];
+    MakeRTPheader(rtpHeader, payloadType, seqNo, timeStamp, 0);
+    WebRtc_UWord16 lengthBytes = htons(12 + payloadSize + 8);
+    WebRtc_UWord16 plen = htons(12 + payloadSize);
+    WebRtc_UWord32 offsetMs;
+/*#ifdef WEBRTC_CODEC_G722
+    if(ACMCodecDB::_mycodecs[ACMCodecDB::g722].pltype == payloadType)
+    {
+        offsetMs = (timeStamp/(frequency/1000))<<1;
+    }
+    else
+    {
+#endif*/
+    offsetMs = (timeStamp/(frequency/1000));
+/*#ifdef WEBRTC_CODEC_G722
+    }
+#endif*/
+    offsetMs = htonl(offsetMs);
+    fwrite(&lengthBytes, 2, 1, _rtpFile);
+    fwrite(&plen, 2, 1, _rtpFile);
+    fwrite(&offsetMs, 4, 1, _rtpFile);
+    fwrite(rtpHeader, 12, 1, _rtpFile);
+    fwrite(payloadData, 1, payloadSize, _rtpFile);
+}
+
+WebRtc_UWord16 RTPFile::Read(WebRtcRTPHeader* rtpInfo,
+                   WebRtc_Word8* payloadData, 
+                   WebRtc_UWord16 payloadSize,
+                   WebRtc_UWord32* offset)
+{
+    WebRtc_UWord16 lengthBytes;
+    WebRtc_UWord16 plen;
+    WebRtc_UWord8 rtpHeader[12];
+    fread(&lengthBytes, 2, 1, _rtpFile);
+    if (feof(_rtpFile))
+    {
+        _rtpEOF = true;
+        return 0;
+    }
+    fread(&plen, 2, 1, _rtpFile);
+    if (feof(_rtpFile))
+    {
+        _rtpEOF = true;
+        return 0;
+    }
+    fread(offset, 4, 1, _rtpFile);
+    if (feof(_rtpFile))
+    {
+        _rtpEOF = true;
+        return 0;
+    }
+    lengthBytes = ntohs(lengthBytes);
+    plen = ntohs(plen);
+    *offset = ntohl(*offset);
+    if (plen < 12)
+    {
+        throw "Unable to read RTP file";
+        exit(1);
+    }
+    fread(rtpHeader, 12, 1, _rtpFile);
+    if (feof(_rtpFile))
+    {
+        _rtpEOF = true;
+        return 0;
+    }
+    ParseRTPHeader(rtpInfo, rtpHeader);
+    rtpInfo->type.Audio.isCNG = false;
+    rtpInfo->type.Audio.channel = 1;
+    if (lengthBytes != plen + 8)
+    {
+        throw "Length parameters in RTP file doesn't match";
+        exit(1);
+    }
+    if (plen == 0)
+    {
+        return 0;
+    }
+    else if (lengthBytes - 20 > payloadSize)
+    {
+        throw "Payload buffer too small";
+        exit(1);
+    }
+    lengthBytes -= 20;
+    fread(payloadData, 1, lengthBytes, _rtpFile);
+    if (feof(_rtpFile))
+    {
+        _rtpEOF = true;
+    }
+    return lengthBytes;
+}
+
diff --git a/src/modules/audio_coding/main/test/RTPFile.h b/src/modules/audio_coding/main/test/RTPFile.h
new file mode 100644
index 0000000..23a43d0
--- /dev/null
+++ b/src/modules/audio_coding/main/test/RTPFile.h
@@ -0,0 +1,99 @@
+/*
+ *  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 RTPFILE_H
+#define RTPFILE_H
+
+#include "audio_coding_module.h"
+#include "module_common_types.h"
+#include "typedefs.h"
+#include "rw_lock_wrapper.h"
+#include <stdio.h>
+#include <queue>
+
+using namespace webrtc;
+
+class RTPStream
+{
+public:
+    virtual ~RTPStream(){}
+    
+    virtual void Write(const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp,
+                                     const WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                                     const WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency) = 0;
+    virtual WebRtc_UWord16 Read(WebRtcRTPHeader* rtpInfo,
+                    WebRtc_Word8* payloadData, 
+                    WebRtc_UWord16 payloadSize,
+                    WebRtc_UWord32* offset) = 0;
+    virtual bool EndOfFile() const = 0;
+
+protected:
+    void MakeRTPheader(WebRtc_UWord8* rtpHeader, 
+                                      WebRtc_UWord8 payloadType, WebRtc_Word16 seqNo, 
+                                      WebRtc_UWord32 timeStamp, WebRtc_UWord32 ssrc);
+    void ParseRTPHeader(WebRtcRTPHeader* rtpInfo, const WebRtc_UWord8* rtpHeader);
+};
+
+class RTPPacket
+{
+public:
+    RTPPacket(WebRtc_UWord8 payloadType, WebRtc_UWord32 timeStamp,
+                                     WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                                     WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency);
+    ~RTPPacket();
+    WebRtc_UWord8 payloadType;
+    WebRtc_UWord32 timeStamp;
+    WebRtc_Word16 seqNo;
+    WebRtc_UWord8* payloadData;
+    WebRtc_UWord16 payloadSize;
+    WebRtc_UWord32 frequency;
+};
+
+class RTPBuffer : public RTPStream
+{
+public:
+    RTPBuffer();
+    ~RTPBuffer();
+    void Write(const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp,
+                                     const WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                                     const WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency);
+    WebRtc_UWord16 Read(WebRtcRTPHeader* rtpInfo,
+                    WebRtc_Word8* payloadData, 
+                    WebRtc_UWord16 payloadSize,
+                    WebRtc_UWord32* offset);
+    virtual bool EndOfFile() const;
+private:
+    RWLockWrapper*             _queueRWLock;
+    std::queue<RTPPacket *>   _rtpQueue;
+};
+
+class RTPFile : public RTPStream
+{
+public:
+    ~RTPFile(){}
+    RTPFile() : _rtpFile(NULL),_rtpEOF(false) {}
+    void Open(char *outFilename, const char *mode);
+    void Close();
+    void WriteHeader();
+    void ReadHeader();
+    void Write(const WebRtc_UWord8 payloadType, const WebRtc_UWord32 timeStamp,
+                                     const WebRtc_Word16 seqNo, const WebRtc_UWord8* payloadData,
+                                     const WebRtc_UWord16 payloadSize, WebRtc_UWord32 frequency);
+    WebRtc_UWord16 Read(WebRtcRTPHeader* rtpInfo,
+                    WebRtc_Word8* payloadData, 
+                    WebRtc_UWord16 payloadSize,
+                    WebRtc_UWord32* offset);
+    bool EndOfFile() const { return _rtpEOF; }
+private:
+    FILE*   _rtpFile;
+    bool    _rtpEOF;
+};
+
+#endif
diff --git a/src/modules/audio_coding/main/test/SpatialAudio.cpp b/src/modules/audio_coding/main/test/SpatialAudio.cpp
new file mode 100644
index 0000000..016ec0a
--- /dev/null
+++ b/src/modules/audio_coding/main/test/SpatialAudio.cpp
@@ -0,0 +1,239 @@
+/*
+ *  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 <string.h>
+
+#include <math.h>
+
+#include "SpatialAudio.h"
+#include "utility.h"
+#include "trace.h"
+#include "common_types.h"
+
+using namespace webrtc;
+
+#define NUM_PANN_COEFFS 10
+
+SpatialAudio::SpatialAudio(int testMode)
+{
+    _testMode = testMode;
+}
+
+SpatialAudio::~SpatialAudio()
+{
+    AudioCodingModule::Destroy(_acmLeft);
+    AudioCodingModule::Destroy(_acmRight);
+    AudioCodingModule::Destroy(_acmReceiver);
+    delete _channel;
+    _inFile.Close();
+    _outFile.Close();
+}
+
+WebRtc_Word16 
+SpatialAudio::Setup()
+{
+    // Create ACMs and the Channel;
+    _acmLeft = AudioCodingModule::Create(1);
+    _acmRight = AudioCodingModule::Create(2);
+    _acmReceiver = AudioCodingModule::Create(3);
+    _channel = new Channel;
+
+    // Register callback for the sender side.
+    CHECK_ERROR(_acmLeft->RegisterTransportCallback(_channel));
+    CHECK_ERROR(_acmRight->RegisterTransportCallback(_channel));
+    // Register the receiver ACM in channel
+    _channel->RegisterReceiverACM(_acmReceiver);
+
+    WebRtc_Word8 audioFileName[MAX_FILE_NAME_LENGTH_BYTE];
+    WebRtc_UWord16 sampFreqHz = 32000;
+
+    strncpy(audioFileName, "./modules/audio_coding/main/test/testfile32kHz.pcm",
+            MAX_FILE_NAME_LENGTH_BYTE - 1);
+    if(_testMode == 1)
+    {
+        printf("Enter the input file [%s]: ", audioFileName);
+        PCMFile::ChooseFile(audioFileName, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
+    }
+    _inFile.Open(audioFileName, sampFreqHz, "rb", false);
+
+    if(_testMode == 0)
+    {
+        strncpy(audioFileName, "./modules/audio_coding/main/test/res_autotests/out_spatial_autotest.pcm",
+                MAX_FILE_NAME_LENGTH_BYTE - 1);
+    }
+    else if(_testMode == 1)
+    {
+        printf("\n");
+        strncpy(audioFileName, "./modules/audio_coding/main/test/res_tests/testspatial_out.pcm",
+                MAX_FILE_NAME_LENGTH_BYTE - 1);
+        printf("Enter the output file [%s]: ", audioFileName);
+        PCMFile::ChooseFile(audioFileName, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz);
+    }
+    else
+    {
+        strncpy(audioFileName, "./modules/audio_coding/main/test/res_tests/testspatial_out.pcm",
+                        MAX_FILE_NAME_LENGTH_BYTE - 1);
+    }
+    _outFile.Open(audioFileName, sampFreqHz, "wb", false);
+    _outFile.SaveStereo(true);
+
+
+    // Register couple of codecs as receive codec    
+    CodecInst codecInst;
+
+    _acmLeft->Codec((WebRtc_UWord8)0, codecInst);    
+    codecInst.channels = 2;
+    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));
+
+    _acmLeft->Codec((WebRtc_UWord8)3, codecInst);    
+    codecInst.channels = 2;
+    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));
+ 
+    _acmLeft->Codec((WebRtc_UWord8)1, codecInst);
+    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));
+    
+    _acmLeft->Codec((WebRtc_UWord8)4, codecInst);
+    CHECK_ERROR(_acmReceiver->RegisterReceiveCodec(codecInst));
+
+    return 0;
+}
+
+void
+SpatialAudio::Perform()
+{
+    if(_testMode == 0)
+    {
+        printf("Running SpatialAudio Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- SpatialAudio ----------");
+    }
+
+    Setup();
+
+    CodecInst codecInst;
+    _acmLeft->Codec((WebRtc_UWord8)1, codecInst);
+    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
+    EncodeDecode();
+
+    WebRtc_Word16 pannCntr = 0;
+
+    double leftPanning[NUM_PANN_COEFFS] =  
+        {1.00, 0.95, 0.90, 0.85, 0.80, 0.75, 0.70, 0.60, 0.55, 0.50};
+    double rightPanning[NUM_PANN_COEFFS] = 
+        {0.50, 0.55, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00};
+
+    while((pannCntr + 1) < NUM_PANN_COEFFS)
+    {
+        _acmLeft->Codec((WebRtc_UWord8)0, codecInst);    
+        codecInst.pacsize = 480;
+        CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
+        CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
+
+        EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
+        pannCntr++;
+
+        // Change codec    
+        _acmLeft->Codec((WebRtc_UWord8)3, codecInst);    
+        codecInst.pacsize = 320;
+        CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
+        CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
+
+        EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
+        pannCntr++;
+        if(_testMode == 0)
+        {
+            printf(".");
+        }
+    }
+
+    _acmLeft->Codec((WebRtc_UWord8)4, codecInst);
+    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
+    EncodeDecode();
+
+    _acmLeft->Codec((WebRtc_UWord8)0, codecInst);    
+    codecInst.pacsize = 480;
+    CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst));
+    CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst));
+    pannCntr = NUM_PANN_COEFFS -1;
+    while(pannCntr >= 0)
+    {
+        EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]);
+        pannCntr--;
+        if(_testMode == 0)
+        {
+            printf(".");
+        }
+    }
+    if(_testMode == 0)
+    {
+        printf("Done!\n");
+    }
+}
+
+void 
+SpatialAudio::EncodeDecode(
+    const double leftPanning, 
+    const double rightPanning)
+{
+    AudioFrame audioFrame;
+    WebRtc_Word32 outFileSampFreq = _outFile.SamplingFrequency();
+
+    const double rightToLeftRatio = rightPanning / leftPanning;
+
+    _channel->SetIsStereo(true);
+
+    while(!_inFile.EndOfFile())
+    {
+        _inFile.Read10MsData(audioFrame);
+        for(int n = 0; n < audioFrame._payloadDataLengthInSamples; n++)
+        {
+            audioFrame._payloadData[n] = (WebRtc_Word16)floor(
+                audioFrame._payloadData[n] * leftPanning + 0.5);
+        }
+        CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));
+
+        for(int n = 0; n < audioFrame._payloadDataLengthInSamples; n++)
+        {
+            audioFrame._payloadData[n] = (WebRtc_Word16)floor(
+                audioFrame._payloadData[n] * rightToLeftRatio + 0.5);
+        }
+        CHECK_ERROR(_acmRight->Add10MsData(audioFrame));
+
+        CHECK_ERROR(_acmLeft->Process());
+        CHECK_ERROR(_acmRight->Process());
+
+        CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, audioFrame));
+        _outFile.Write10MsData(audioFrame);
+    }
+    _inFile.Rewind();
+}
+
+void 
+SpatialAudio::EncodeDecode()
+{
+    AudioFrame audioFrame;
+    WebRtc_Word32 outFileSampFreq = _outFile.SamplingFrequency();
+
+    _channel->SetIsStereo(false);
+
+    while(!_inFile.EndOfFile())
+    {
+        _inFile.Read10MsData(audioFrame);
+        CHECK_ERROR(_acmLeft->Add10MsData(audioFrame));
+
+        CHECK_ERROR(_acmLeft->Process());
+
+        CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, audioFrame));
+        _outFile.Write10MsData(audioFrame);
+    }
+    _inFile.Rewind();
+}
+
+
diff --git a/src/modules/audio_coding/main/test/SpatialAudio.h b/src/modules/audio_coding/main/test/SpatialAudio.h
new file mode 100644
index 0000000..6a137d4
--- /dev/null
+++ b/src/modules/audio_coding/main/test/SpatialAudio.h
@@ -0,0 +1,43 @@
+/*
+ *  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 ACM_TEST_SPATIAL_AUDIO_H
+#define ACM_TEST_SPATIAL_AUDIO_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+#include "audio_coding_module.h"
+#include "utility.h"
+
+#define MAX_FILE_NAME_LENGTH_BYTE 500
+
+
+class SpatialAudio : public ACMTest
+{
+public:
+    SpatialAudio(int testMode);
+    ~SpatialAudio();
+
+    void Perform();
+private:
+    WebRtc_Word16 Setup();
+    void EncodeDecode(double leftPanning, double rightPanning);
+    void EncodeDecode();
+
+    AudioCodingModule* _acmLeft;
+    AudioCodingModule* _acmRight;
+    AudioCodingModule* _acmReceiver;
+    Channel*               _channel;
+    PCMFile                _inFile;
+    PCMFile                _outFile;
+    int                    _testMode;
+};
+#endif
diff --git a/src/modules/audio_coding/main/test/TestAllCodecs.cpp b/src/modules/audio_coding/main/test/TestAllCodecs.cpp
new file mode 100644
index 0000000..35e5b0a
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestAllCodecs.cpp
@@ -0,0 +1,858 @@
+/*
+ *  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 "TestAllCodecs.h"
+
+#include "audio_coding_module_typedefs.h"
+#include "common_types.h"
+#include "engine_configurations.h"
+#include <cassert>
+#include <iostream>
+#include "trace.h"
+#include "utility.h"
+
+// Class for simulating packet handling
+TestPack::TestPack():
+_receiverACM(NULL),
+_seqNo(0),
+_timeStampDiff(0),
+_lastInTimestamp(0),
+_totalBytes(0),
+_payloadSize(0)
+{
+}
+TestPack::~TestPack()
+{
+}
+
+void 
+TestPack::RegisterReceiverACM(AudioCodingModule* acm)
+{
+    _receiverACM = acm;
+    return;
+}
+WebRtc_Word32 
+TestPack::SendData(
+        const FrameType       frameType,
+        const WebRtc_UWord8   payloadType,
+        const WebRtc_UWord32  timeStamp,
+        const WebRtc_UWord8*  payloadData, 
+        const WebRtc_UWord16  payloadSize,
+        const RTPFragmentationHeader* fragmentation)
+{
+    WebRtcRTPHeader rtpInfo;
+    WebRtc_Word32   status;
+    WebRtc_UWord16  payloadDataSize = payloadSize;
+
+    rtpInfo.header.markerBit = false;
+    rtpInfo.header.ssrc = 0;
+    rtpInfo.header.sequenceNumber = _seqNo++;
+    rtpInfo.header.payloadType = payloadType;
+    rtpInfo.header.timestamp = timeStamp;
+    if(frameType == kAudioFrameCN)
+    {
+        rtpInfo.type.Audio.isCNG = true;
+    }
+    else
+    {
+        rtpInfo.type.Audio.isCNG = false;
+    }
+    if(frameType == kFrameEmpty)
+    {
+        // Skip this frame
+        return 0;
+    }
+
+    rtpInfo.type.Audio.channel = 1;
+    memcpy(_payloadData, payloadData, payloadDataSize);
+    
+    status = _receiverACM->IncomingPacket((WebRtc_Word8*)_payloadData, payloadDataSize, rtpInfo);
+
+    _payloadSize = payloadDataSize;
+    _timeStampDiff = timeStamp - _lastInTimestamp;
+    _lastInTimestamp = timeStamp;
+    _totalBytes += payloadDataSize;
+    return status;
+}
+
+WebRtc_UWord16
+TestPack::GetPayloadSize()
+{
+    return _payloadSize;
+}
+
+
+WebRtc_UWord32
+TestPack::GetTimeStampDiff()
+{
+    return _timeStampDiff;
+}
+
+void 
+TestPack::ResetPayloadSize()
+{
+    _payloadSize = 0;
+}
+
+TestAllCodecs::TestAllCodecs(int testMode):
+_acmA(NULL),
+_acmB(NULL),
+_channelA2B(NULL),
+_testCntr(0),
+_packSizeSamp(0),
+_packSizeBytes(0),
+_counter(0)
+{
+    // testMode = 0 for silent test (auto test)
+    _testMode = testMode;
+}
+
+using namespace std;
+TestAllCodecs::~TestAllCodecs()
+{
+    if(_acmA != NULL)
+    {
+        AudioCodingModule::Destroy(_acmA);
+        _acmA = NULL;
+    }
+    if(_acmB != NULL)
+    {
+        AudioCodingModule::Destroy(_acmB);
+        _acmB = NULL;
+    }
+    if(_channelA2B != NULL)
+    {
+        delete _channelA2B;
+        _channelA2B = NULL;
+    }
+}
+
+void TestAllCodecs::Perform()
+{
+
+    char file[] = "./modules/audio_coding/main/test/testfile32kHz.pcm";
+    _inFileA.Open(file, 32000, "rb");
+
+    if(_testMode == 0)
+    {
+        printf("Running All Codecs Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
+                     "---------- TestAllCodecs ----------");
+    }
+
+    _acmA = AudioCodingModule::Create(0);
+    _acmB = AudioCodingModule::Create(1);
+
+    _acmA->InitializeReceiver();
+    _acmB->InitializeReceiver();
+
+    WebRtc_UWord8 numEncoders = _acmA->NumberOfCodecs();
+    CodecInst myCodecParam;
+ 
+    for(WebRtc_UWord8 n = 0; n < numEncoders; n++)
+    {
+        _acmB->Codec(n, myCodecParam);
+        _acmB->RegisterReceiveCodec(myCodecParam);
+    }
+
+    // Create and connect the channel
+    _channelA2B = new TestPack;    
+    _acmA->RegisterTransportCallback(_channelA2B);
+    _channelA2B->RegisterReceiverACM(_acmB);
+
+    // All codecs are tested for all allowed sampling frequencies, rates and packet sizes
+#ifdef WEBRTC_CODEC_GSMAMR
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecAMR[] = "AMR";
+    RegisterSendCodec('A', codecAMR, 8000, 4750, 160, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 4750, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 4750, 480, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 5150, 160, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 5150, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 5150, 480, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 5900, 160, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 5900, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 5900, 480, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 6700, 160, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 6700, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 6700, 480, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 7400, 160, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 7400, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 7400, 480, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 7950, 160, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 7950, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 7950, 480, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 10200, 160, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 10200, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 10200, 480, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 12200, 160, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 12200, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMR, 8000, 12200, 480, 3);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_GSMAMRWB
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    char codecAMRWB[] = "AMR-WB";
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecAMRWB, 16000, 7000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 7000, 640, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 7000, 960, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 9000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 9000, 640, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 9000, 960, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 12000, 320, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 12000, 640, 6);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 12000, 960, 8);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 14000, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 14000, 640, 4);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 14000, 960, 5);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 16000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 16000, 640, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 16000, 960, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 18000, 320, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 18000, 640, 4);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 18000, 960, 5);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 20000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 20000, 640, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 20000, 960, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 23000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 23000, 640, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 23000, 960, 3);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 24000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 24000, 640, 2);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecAMRWB, 16000, 24000, 960, 2);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_G722
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecG722[] = "G722";
+    RegisterSendCodec('A', codecG722, 16000, 64000, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 480, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 640, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 800, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 960, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_G722_1
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecG7221_1[] = "G7221";
+    RegisterSendCodec('A', codecG7221_1, 16000, 32000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7221_1, 16000, 24000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7221_1, 16000, 16000, 320, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_G722_1C
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecG7221_2[] = "G7221";
+    RegisterSendCodec('A', codecG7221_2, 32000, 48000, 640, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7221_2, 32000, 32000, 640, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7221_2, 32000, 24000, 640, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_G729
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecG729[] = "G729";
+    RegisterSendCodec('A', codecG729, 8000, 8000, 80, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG729, 8000, 8000, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG729, 8000, 8000, 240, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG729, 8000, 8000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG729, 8000, 8000, 400, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG729, 8000, 8000, 480, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_G729_1
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecG7291[] = "G7291";
+    RegisterSendCodec('A', codecG7291, 16000, 8000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 8000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 8000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 12000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 12000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 12000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 14000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 14000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 14000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 16000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 16000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 16000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 18000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 18000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 18000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 20000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 20000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 20000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 22000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 22000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 22000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 24000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 24000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 24000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 26000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 26000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 26000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 28000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 28000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 28000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 30000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 30000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 30000, 960, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 32000, 320, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 32000, 640, 1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG7291, 16000, 32000, 960, 1);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_GSMFR
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecGSM[] = "GSM";
+    RegisterSendCodec('A', codecGSM, 8000, 13200, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecGSM, 8000, 13200, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecGSM, 8000, 13200, 480, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_ILBC
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecILBC[] = "ILBC";
+    RegisterSendCodec('A', codecILBC, 8000, 13300, 240, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecILBC, 8000, 13300, 480, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecILBC, 8000, 15200, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecILBC, 8000, 15200, 320, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecISAC[] = "ISAC";
+    RegisterSendCodec('A', codecISAC, 16000, -1, 480, -1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecISAC, 16000, -1, 960, -1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecISAC, 16000, 15000, 480, -1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecISAC, 16000, 32000, 960, -1);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_ISAC
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecISAC, 32000, -1, 960, -1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecISAC, 32000, 56000, 960, -1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecISAC, 32000, 37000, 960, -1);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecISAC, 32000, 32000, 960, -1);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++; 
+    OpenOutFile(_testCntr);
+    char codecL16[] = "L16";
+    RegisterSendCodec('A', codecL16, 8000, 128000, 80, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 240, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 320, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;  
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 480, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 640, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++; 
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecL16, 32000, 512000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 32000, 512000, 640, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++; 
+    OpenOutFile(_testCntr);
+    char codecPCMA[] = "PCMA";
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 80, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 240, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 400, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 480, 0);
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    Run(_channelA2B);
+    char codecPCMU[] = "PCMU";
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 80, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 240, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 400, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 480, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#ifdef WEBRTC_CODEC_SPEEX
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;   
+    OpenOutFile(_testCntr);
+    char codecSPEEX[] = "SPEEX";
+    RegisterSendCodec('A', codecSPEEX, 8000, 2400, 160, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecSPEEX, 8000, 8000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecSPEEX, 8000, 18200, 480, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;  
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecSPEEX, 16000, 4000, 320, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecSPEEX, 16000, 12800, 640, 0);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecSPEEX, 16000, 34200, 960, 0);
+    Run(_channelA2B);
+    _outFileB.Close();
+#endif
+
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf("Done!\n");
+    }
+
+    /* Print out all codecs that were not tested in the run */
+
+
+    if(_testMode != 0) {
+        printf("The following codecs was not included in the test:\n");
+#ifndef WEBRTC_CODEC_GSMAMR
+        printf("   GSMAMR\n");
+#endif
+#ifndef WEBRTC_CODEC_GSMAMRWB
+        printf("   GSMAMR-wb\n");
+#endif
+#ifndef WEBRTC_CODEC_G722
+        printf("   G.722\n");
+#endif
+#ifndef WEBRTC_CODEC_G722_1
+        printf("   G.722.1\n");
+#endif
+#ifndef WEBRTC_CODEC_G722_1C
+        printf("   G.722.1C\n");
+#endif
+#ifndef WEBRTC_CODEC_G729
+        printf("   G.729\n");
+#endif
+#ifndef WEBRTC_CODEC_G729_1
+        printf("   G.729.1\n");
+#endif
+#ifndef WEBRTC_CODEC_GSMFR
+        printf("   GSMFR\n");
+#endif
+#ifndef WEBRTC_CODEC_ILBC
+        printf("   iLBC\n");
+#endif
+#ifndef WEBRTC_CODEC_ISAC
+        printf("   ISAC float\n");
+#endif
+#ifndef WEBRTC_CODEC_ISACFX
+        printf("   ISAC fix\n");
+#endif
+#ifndef WEBRTC_CODEC_PCM16
+        printf("   PCM16\n");
+#endif
+#ifndef WEBRTC_CODEC_SPEEX
+        printf("   Speex\n");
+#endif
+
+        printf("\nTo complete the test, listen to the %d number of output files.\n", _testCntr);
+    }
+}
+
+// Register Codec to use in the test
+//
+// Input:   side            - which ACM to use, 'A' or 'B'
+//          codecName       - name to use when register the codec
+//          samplingFreqHz  - sampling frequency in Herz
+//          rate            - bitrate in bytes
+//          packSize        - packet size in samples
+//          extraByte       - if extra bytes needed compared to the bitrate 
+//                            used when registering, can be an internal header
+//                            set to -1 if the codec is a variable rate codec
+WebRtc_Word16 TestAllCodecs::RegisterSendCodec(char side, 
+                                             char* codecName, 
+                                             WebRtc_Word32 samplingFreqHz,
+                                             int rate,
+                                             int packSize,
+                                             int extraByte)
+{
+    if(_testMode != 0) {
+        // Print out codec and settings
+        printf("codec: %s Freq: %d Rate: %d PackSize: %d", codecName, samplingFreqHz, rate, packSize);
+    }
+
+    // Store packetsize in samples, used to validate the recieved packet
+    _packSizeSamp = packSize;
+
+    // Store the expected packet size in bytes, used to validate the recieved packet
+    // If variable rate codec (extraByte == -1), set to -1 (65535)
+    if (extraByte != -1) 
+    {
+        // Add 0.875 to always round up to a whole byte
+        _packSizeBytes = (WebRtc_UWord16)((float)(packSize*rate)/(float)(samplingFreqHz*8)+0.875)+extraByte;
+    } 
+    else 
+    {
+        // Packets will have a variable size
+        _packSizeBytes = -1;
+    }
+
+    // Set pointer to the ACM where to register the codec
+    AudioCodingModule* myACM;
+    switch(side)
+    {
+    case 'A':
+        {
+            myACM = _acmA;
+            break;
+        }
+    case 'B':
+        {
+            myACM = _acmB;
+            break;
+        }
+    default:
+        return -1;
+    }
+
+    if(myACM == NULL)
+    {
+        assert(false);
+        return -1;
+    }
+    CodecInst myCodecParam;
+
+    // Get all codec paramters before registering
+    CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam, samplingFreqHz));
+    myCodecParam.rate = rate;
+    myCodecParam.pacsize = packSize;
+    CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam));
+
+    // initialization was succesful
+    return 0;
+}
+
+void TestAllCodecs::Run(TestPack* channel)
+{
+    AudioFrame audioFrame;
+
+    WebRtc_UWord16 SamplesIn10MsecA = _inFileA.PayloadLength10Ms();
+    WebRtc_UWord32 timestampA = 1;
+    WebRtc_Word32 outFreqHzB = _outFileB.SamplingFrequency();
+    WebRtc_UWord16 recSize;
+    WebRtc_UWord32 timeStampDiff;
+    channel->ResetPayloadSize();
+    int errorCount = 0;
+
+    // Only run 1 second for each test case
+    while((_counter<1000)&& (!_inFileA.EndOfFile()))
+    {
+        // Add 10 msec to ACM
+         _inFileA.Read10MsData(audioFrame);
+        CHECK_ERROR(_acmA->Add10MsData(audioFrame));
+
+        // Run sender side of ACM
+        CHECK_ERROR(_acmA->Process());
+
+        // Verify that the received packet size matches the settings
+        recSize = channel->GetPayloadSize();
+        if (recSize) {
+            if ((recSize != _packSizeBytes) && (_packSizeBytes < 65535)) {
+                errorCount++;
+            }
+
+        // Verify that the timestamp is updated with expected length
+        timeStampDiff = channel->GetTimeStampDiff();
+        if ((_counter > 10) && (timeStampDiff != _packSizeSamp))
+            errorCount++;
+        }
+
+
+        // Run received side of ACM
+        CHECK_ERROR(_acmB->PlayoutData10Ms(outFreqHzB, audioFrame));
+
+        // Write output speech to file
+        _outFileB.Write10MsData(audioFrame._payloadData, audioFrame._payloadDataLengthInSamples);
+    }
+
+    if (errorCount) 
+    {
+        printf(" - test FAILED\n");
+    }
+    else if(_testMode != 0)
+    {
+        printf(" - test PASSED\n");
+    }
+
+    // Reset _counter
+    if (_counter == 1000) {
+        _counter = 0;
+    }
+    if (_inFileA.EndOfFile()) {
+        _inFileA.Rewind();
+    }
+}
+
+void TestAllCodecs::OpenOutFile(WebRtc_Word16 testNumber)
+{
+    char fileName[500] = "testallcodecs_out_";
+    char cntrStr[10];
+
+    sprintf(cntrStr, "%02d.pcm", testNumber);
+    strcat(fileName, cntrStr);
+    _outFileB.Open(fileName, 32000, "wb");
+}
+
+void TestAllCodecs::DisplaySendReceiveCodec()
+{
+    CodecInst myCodecParam;
+    _acmA->SendCodec(myCodecParam);
+    printf("%s -> ", myCodecParam.plname);
+    _acmB->ReceiveCodec(myCodecParam);
+    printf("%s\n", myCodecParam.plname);
+}
+
diff --git a/src/modules/audio_coding/main/test/TestAllCodecs.h b/src/modules/audio_coding/main/test/TestAllCodecs.h
new file mode 100644
index 0000000..958cefd
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestAllCodecs.h
@@ -0,0 +1,94 @@
+/*
+ *  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 TEST_ALL_CODECS_H
+#define TEST_ALL_CODECS_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+
+class TestPack : public AudioPacketizationCallback
+{
+public:
+    TestPack();
+    ~TestPack();
+    
+    void RegisterReceiverACM(AudioCodingModule* acm);
+    
+    virtual WebRtc_Word32 SendData(const FrameType frameType,
+        const WebRtc_UWord8 payloadType,
+        const WebRtc_UWord32 timeStamp,
+        const WebRtc_UWord8* payloadData, 
+        const WebRtc_UWord16 payloadSize,
+        const RTPFragmentationHeader* fragmentation);
+
+    WebRtc_UWord16 GetPayloadSize();
+    WebRtc_UWord32 GetTimeStampDiff();
+    void ResetPayloadSize();
+
+private:
+    AudioCodingModule* _receiverACM;
+    WebRtc_Word16            _seqNo;
+    WebRtc_UWord8            _payloadData[60 * 32 * 2 * 2]; 
+    WebRtc_UWord32           _timeStampDiff;
+    WebRtc_UWord32           _lastInTimestamp;
+    WebRtc_UWord64           _totalBytes;
+    WebRtc_UWord16           _payloadSize;
+};
+
+class TestAllCodecs : public ACMTest
+{
+public:
+    TestAllCodecs(int testMode);
+    ~TestAllCodecs();
+
+    void Perform();
+private:
+    // The default value of '-1' indicates that the registration is based only on codec name
+    // and a sampling frequncy matching is not required. This is useful for codecs which support
+    // several sampling frequency.
+    WebRtc_Word16 RegisterSendCodec(char side, 
+        char* codecName, 
+        WebRtc_Word32 sampFreqHz,
+        int rate,
+        int packSize,
+        int extraByte);
+
+    void Run(TestPack* channel);
+    void OpenOutFile(WebRtc_Word16 testNumber);
+    void DisplaySendReceiveCodec();
+
+    WebRtc_Word32 SendData(
+        const FrameType       frameType,
+        const WebRtc_UWord8   payloadType,
+        const WebRtc_UWord32  timeStamp,
+        const WebRtc_UWord8*  payloadData, 
+        const WebRtc_UWord16  payloadSize,
+        const RTPFragmentationHeader* fragmentation);
+
+    int                     _testMode;
+
+    AudioCodingModule*      _acmA;
+    AudioCodingModule*      _acmB;
+
+    TestPack*               _channelA2B;
+
+    PCMFile                _inFileA;
+    PCMFile                _outFileB;
+    WebRtc_Word16          _testCntr;
+    WebRtc_UWord16         _packSizeSamp;
+    WebRtc_UWord16         _packSizeBytes;
+    int                    _counter;
+};
+
+
+#endif // TEST_ALL_CODECS_H
+
diff --git a/src/modules/audio_coding/main/test/TestFEC.cpp b/src/modules/audio_coding/main/test/TestFEC.cpp
new file mode 100644
index 0000000..829e1de
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestFEC.cpp
@@ -0,0 +1,627 @@
+/*
+ *  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 "TestFEC.h"
+
+#include "audio_coding_module_typedefs.h"
+#include "common_types.h"
+#include "engine_configurations.h"
+
+#include <cassert>
+#include <iostream>
+#include "trace.h"
+#include "utility.h"
+
+TestFEC::TestFEC(int testMode):
+_acmA(NULL),
+_acmB(NULL),
+_channelA2B(NULL),
+_testCntr(0)
+{
+    _testMode = testMode;
+}
+
+using namespace std;
+
+TestFEC::~TestFEC()
+{
+    if(_acmA != NULL)
+    {
+        AudioCodingModule::Destroy(_acmA);
+        _acmA = NULL;
+    }
+    if(_acmB != NULL)
+    {
+        AudioCodingModule::Destroy(_acmB);
+        _acmB = NULL;
+    }
+    if(_channelA2B != NULL)
+    {
+        delete _channelA2B;
+        _channelA2B = NULL;
+    }
+}
+
+void TestFEC::Perform()
+{
+
+    if(_testMode == 0)
+    {
+        printf("Running FEC Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
+                     "---------- TestFEC ----------");
+    }
+    char fileName[] = "./modules/audio_coding/main/test/testfile32kHz.pcm";
+    _inFileA.Open(fileName, 32000, "rb");
+
+
+    bool fecEnabled;
+
+    _acmA = AudioCodingModule::Create(0);
+    _acmB = AudioCodingModule::Create(1);
+
+    _acmA->InitializeReceiver();
+    _acmB->InitializeReceiver();
+
+    WebRtc_UWord8 numEncoders = _acmA->NumberOfCodecs();
+    CodecInst myCodecParam;
+    if(_testMode != 0)
+    {
+        printf("Registering codecs at receiver... \n");
+    }
+    for(WebRtc_UWord8 n = 0; n < numEncoders; n++)
+    {
+        _acmB->Codec(n, myCodecParam);
+        if(_testMode != 0)
+        {
+            printf("%s\n", myCodecParam.plname);
+        }
+        _acmB->RegisterReceiveCodec(myCodecParam);
+    }
+
+    // Create and connect the channel
+    _channelA2B = new Channel;    
+    _acmA->RegisterTransportCallback(_channelA2B);
+    _channelA2B->RegisterReceiverACM(_acmB);
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+#ifndef WEBRTC_CODEC_G722
+    printf("G722 needs to be activated to run this test\n");
+    exit(-1);
+#endif
+    char nameG722[] = "G722";
+    RegisterSendCodec('A', nameG722, 16000);
+    char nameCN[] = "CN";
+    RegisterSendCodec('A', nameCN, 16000);
+    char nameRED[] = "RED";
+    RegisterSendCodec('A', nameRED);
+    OpenOutFile(_testCntr);
+    SetVAD(true, true, VADAggr);
+    _acmA->SetFECStatus(false);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    OpenOutFile(_testCntr);
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    char nameISAC[] = "iSAC";
+    RegisterSendCodec('A',nameISAC, 16000);
+    OpenOutFile(_testCntr);
+    SetVAD(true, true, VADVeryAggr);
+    _acmA->SetFECStatus(false);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    OpenOutFile(_testCntr);
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+
+    RegisterSendCodec('A', nameISAC, 32000);
+    OpenOutFile(_testCntr);
+    SetVAD(true, true, VADVeryAggr);
+    _acmA->SetFECStatus(false);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    OpenOutFile(_testCntr);
+    Run();
+    _outFileB.Close();
+
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+
+    RegisterSendCodec('A', nameISAC, 32000);
+    OpenOutFile(_testCntr);
+    SetVAD(false, false, VADNormal);
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+
+    
+    RegisterSendCodec('A', nameISAC, 16000);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+
+    RegisterSendCodec('A', nameISAC, 32000);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+
+    RegisterSendCodec('A', nameISAC, 16000);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+
+
+
+
+    _channelA2B->SetFECTestWithPacketLoss(true);
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+
+    RegisterSendCodec('A',nameG722);
+    RegisterSendCodec('A', nameCN, 16000);
+    OpenOutFile(_testCntr);
+    SetVAD(true, true, VADAggr);
+    _acmA->SetFECStatus(false);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    OpenOutFile(_testCntr);
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    RegisterSendCodec('A', nameISAC, 16000);
+    OpenOutFile(_testCntr);
+    SetVAD(true, true, VADVeryAggr);
+    _acmA->SetFECStatus(false);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    OpenOutFile(_testCntr);
+    Run();
+    _outFileB.Close();
+
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    RegisterSendCodec('A', nameISAC, 32000);
+    OpenOutFile(_testCntr);
+    SetVAD(true, true, VADVeryAggr);
+    _acmA->SetFECStatus(false);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    OpenOutFile(_testCntr);
+    Run();
+    _outFileB.Close();
+
+
+
+
+
+
+    if(_testMode != 0)
+    {
+        printf("=======================================================================\n");
+        printf("%d ",_testCntr++);
+    }
+    else
+    {
+        printf(".");
+    }
+    RegisterSendCodec('A', nameISAC, 32000);
+    OpenOutFile(_testCntr);
+    SetVAD(false, false, VADNormal);
+    _acmA->SetFECStatus(true);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+
+    
+    RegisterSendCodec('A', nameISAC, 16000);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+
+    RegisterSendCodec('A', nameISAC, 32000);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+
+    RegisterSendCodec('A', nameISAC, 16000);
+    fecEnabled = _acmA->FECStatus();
+    if(_testMode != 0)
+    {
+        printf("FEC currently %s\n",(fecEnabled?"ON":"OFF"));
+        DisplaySendReceiveCodec();
+    }
+    Run();
+    _outFileB.Close();
+
+
+
+    if(_testMode == 0)
+    {
+        printf("Done!\n");
+    }
+}
+
+WebRtc_Word32 TestFEC::SetVAD(bool enableDTX, bool enableVAD, ACMVADMode vadMode)
+{
+    if(_testMode != 0)
+    {
+        printf("DTX %s; VAD %s; VAD-Mode %d\n", 
+            enableDTX? "ON":"OFF", 
+            enableVAD? "ON":"OFF", 
+            (WebRtc_Word16)vadMode);
+    }
+    return _acmA->SetVAD(enableDTX, enableVAD, vadMode);
+}
+
+WebRtc_Word16 TestFEC::RegisterSendCodec(char side, char* codecName, WebRtc_Word32 samplingFreqHz)
+{
+    if(_testMode != 0)
+    {
+        if(samplingFreqHz > 0)
+        {
+            printf("Registering %s-%d for side %c\n", codecName, samplingFreqHz, side);
+        }
+        else
+        {
+            printf("Registering %s for side %c\n", codecName, side);
+        }
+    }
+    cout << flush;
+    AudioCodingModule* myACM;
+    switch(side)
+    {
+    case 'A':
+        {
+            myACM = _acmA;
+            break;
+        }
+    case 'B':
+        {
+            myACM = _acmB;
+            break;
+        }
+    default:
+        return -1;
+    }
+
+    if(myACM == NULL)
+    {
+        assert(false);
+        return -1;
+    }
+    CodecInst myCodecParam;
+
+    CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam, samplingFreqHz));
+
+    CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam));
+
+    // initialization was succesful
+    return 0;
+}
+
+void TestFEC::Run()
+{
+    AudioFrame audioFrame;
+
+    WebRtc_UWord16 msecPassed = 0;
+    WebRtc_UWord32 secPassed  = 0;
+    WebRtc_UWord16 SamplesIn10MsecA = _inFileA.PayloadLength10Ms();
+    WebRtc_UWord32 timestampA = 1;
+    WebRtc_Word32 outFreqHzB = _outFileB.SamplingFrequency();
+
+    while(!_inFileA.EndOfFile())
+    {
+        _inFileA.Read10MsData(audioFrame);
+        //audioFrame._timeStamp = timestampA;
+        //timestampA += SamplesIn10MsecA;
+        CHECK_ERROR(_acmA->Add10MsData(audioFrame));
+
+        CHECK_ERROR(_acmA->Process());
+
+        CHECK_ERROR(_acmB->PlayoutData10Ms(outFreqHzB, audioFrame));
+        _outFileB.Write10MsData(audioFrame._payloadData, audioFrame._payloadDataLengthInSamples);
+        msecPassed += 10;
+        if(msecPassed >= 1000)
+        {
+            msecPassed = 0;
+            secPassed++;
+        }
+        if(((secPassed%5) == 4) && (msecPassed == 0) && (_testCntr > 14))
+        {
+            printf("%3u:%3u  ", secPassed, msecPassed);
+            _acmA->SetFECStatus(false);
+            printf("FEC currently %s\n",(_acmA->FECStatus()?"ON":"OFF"));
+        }
+        if(((secPassed%5) == 4) && (msecPassed >= 990) && (_testCntr > 14))
+        {
+            printf("%3u:%3u  ", secPassed, msecPassed);
+            _acmA->SetFECStatus(true);
+            printf("FEC currently %s\n",(_acmA->FECStatus()?"ON":"OFF"));
+        }
+    }
+    _inFileA.Rewind();
+}
+
+void TestFEC::OpenOutFile(WebRtc_Word16 testNumber)
+{
+    char fileName[500] = "./modules/audio_coding/main/test/res_tests/TestFEC_outFile_";
+    char cntrStr[10];
+
+    if(_testMode == 0)
+    {
+        sprintf(fileName, "./modules/audio_coding/main/test/res_autotests/TestFEC_outFile_");
+    }
+    sprintf(cntrStr, "%02d.pcm", testNumber);
+    strcat(fileName, cntrStr);
+    _outFileB.Open(fileName, 32000, "wb");
+}
+
+void TestFEC::DisplaySendReceiveCodec()
+{
+    CodecInst myCodecParam;
+    _acmA->SendCodec(myCodecParam);
+    printf("%s -> ", myCodecParam.plname);
+    _acmB->ReceiveCodec(myCodecParam);
+    printf("%s\n", myCodecParam.plname);
+}
diff --git a/src/modules/audio_coding/main/test/TestFEC.h b/src/modules/audio_coding/main/test/TestFEC.h
new file mode 100644
index 0000000..09d1009
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestFEC.h
@@ -0,0 +1,47 @@
+/*
+ *  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 TEST_FEC_H
+#define TEST_FEC_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+
+class TestFEC : public ACMTest
+{
+public:
+    TestFEC(int testMode);
+    ~TestFEC();
+
+    void Perform();
+private:
+    // The default value of '-1' indicates that the registration is based only on codec name
+    // and a sampling frequncy matching is not required. This is useful for codecs which support
+    // several sampling frequency.
+    WebRtc_Word16 RegisterSendCodec(char side, char* codecName, WebRtc_Word32 sampFreqHz = -1);
+    void Run();
+    void OpenOutFile(WebRtc_Word16 testNumber);
+    void DisplaySendReceiveCodec();
+    WebRtc_Word32 SetVAD(bool enableDTX, bool enableVAD, ACMVADMode vadMode);
+    AudioCodingModule* _acmA;
+    AudioCodingModule* _acmB;
+
+    Channel*               _channelA2B;
+
+    PCMFile                _inFileA;
+    PCMFile                _outFileB;
+    WebRtc_Word16            _testCntr;
+    int                    _testMode;
+};
+
+
+#endif
+
diff --git a/src/modules/audio_coding/main/test/TestStereo.cpp b/src/modules/audio_coding/main/test/TestStereo.cpp
new file mode 100644
index 0000000..bb4c40b
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestStereo.cpp
@@ -0,0 +1,553 @@
+/*
+ *  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 "TestStereo.h"
+
+#include "common_types.h"
+#include "audio_coding_module_typedefs.h"
+#include "engine_configurations.h"
+#include <iostream>
+#include "utility.h"
+#include <cassert>
+#include "trace.h"
+
+
+// Class for simulating packet handling
+TestPackStereo::TestPackStereo():
+_receiverACM(NULL),
+_seqNo(0),
+_timeStampDiff(0),
+_lastInTimestamp(0),
+_totalBytes(0),
+_payloadSize(0),
+_noChannels(1),
+_codecType(0)
+{
+}
+TestPackStereo::~TestPackStereo()
+{
+}
+
+void 
+TestPackStereo::RegisterReceiverACM(AudioCodingModule* acm)
+{
+    _receiverACM = acm;
+    return;
+}
+
+
+WebRtc_Word32 
+TestPackStereo::SendData(
+        const FrameType       frameType,
+        const WebRtc_UWord8   payloadType,
+        const WebRtc_UWord32  timeStamp,
+        const WebRtc_UWord8*  payloadData, 
+        const WebRtc_UWord16  payloadSize,
+        const RTPFragmentationHeader* fragmentation)
+{
+    WebRtcRTPHeader rtpInfo;
+    WebRtc_Word32   status;
+    WebRtc_UWord16  payloadDataSize = payloadSize;
+    WebRtc_UWord8 payloadDataMaster[60 * 32 * 2 * 2]; 
+    WebRtc_UWord8 payloadDataSlave[60 * 32 * 2 * 2]; 
+    bool twoBytePerSample = false;
+    bool oneBytePerSample = true;
+    bool frameBased = false;
+
+    rtpInfo.header.markerBit = false;
+    rtpInfo.header.ssrc = 0;
+    rtpInfo.header.sequenceNumber = _seqNo++;
+    rtpInfo.header.payloadType = payloadType;
+    rtpInfo.header.timestamp = timeStamp;
+    if(frameType == kFrameEmpty)
+    {
+        // Skip this frame
+        return 0;
+    }    
+    if(frameType != kAudioFrameCN)
+    {
+        rtpInfo.type.Audio.isCNG = false;
+
+        // For stereo we need to call ACM with two incoming packets, one for each channel.
+        // Different packet-splitting depending on codec.
+        if (_codecType == 0) {
+            // one byte per sample
+            for (int i=0, j=0; i<payloadDataSize; i+=2, j++)
+            {
+                payloadDataMaster[j] = payloadData[i];
+                payloadDataSlave[j] = payloadData[i+1];
+            }
+        } else if (_codecType == 1) {
+            // two bytes per sample
+            for (int i=0, j=0; i<payloadDataSize; i+=4, j+=2)
+            {
+                payloadDataMaster[j] = payloadData[i];
+                payloadDataMaster[j+1] = payloadData[i+1];
+                payloadDataSlave[j] = payloadData[i+2];
+                payloadDataSlave[j+1] = payloadData[i+3];
+            }
+        } else if (_codecType == 2) {
+            // frameBased
+            memcpy(payloadDataMaster, &payloadData[0], payloadDataSize/2);
+            memcpy(payloadDataSlave, &payloadData[payloadDataSize/2], payloadDataSize/2);
+        } else if (_codecType == 3) {
+            // four bits per sample
+            for (int i=0, j=0; i<payloadDataSize; i+=2, j++)
+            {
+                payloadDataMaster[j] = (payloadData[i] & 0xF0) + (payloadData[i+1] >> 4);
+                payloadDataSlave[j] = ((payloadData[i] & 0x0F) << 4) + (payloadData[i+1] & 0x0F);
+            }
+        }
+    }
+    else
+    {
+        // If CNG packet, send the same packet to both master and slave.
+        rtpInfo.type.Audio.isCNG = true;
+        memcpy(payloadDataMaster, payloadData, payloadSize);
+        memcpy(payloadDataSlave, payloadData, payloadSize);
+        payloadDataSize = payloadSize*2;
+    }
+
+    // Call ACM with two packets, one for each channel
+    rtpInfo.type.Audio.channel = 1;
+    status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadDataMaster, payloadDataSize/2, rtpInfo);
+    rtpInfo.type.Audio.channel = 2;
+    status = _receiverACM->IncomingPacket((WebRtc_Word8*)payloadDataSlave, payloadDataSize/2, rtpInfo);
+
+    if (frameType != kAudioFrameCN) {
+        _payloadSize = payloadDataSize;
+    } else {
+        _payloadSize = -1;
+    }
+    _timeStampDiff = timeStamp - _lastInTimestamp;
+    _lastInTimestamp = timeStamp;
+    _totalBytes += payloadDataSize;
+    return status;
+}
+
+WebRtc_UWord16
+TestPackStereo::GetPayloadSize()
+{
+    return _payloadSize;
+}
+
+
+WebRtc_UWord32
+TestPackStereo::GetTimeStampDiff()
+{
+    return _timeStampDiff;
+}
+
+void 
+TestPackStereo::ResetPayloadSize()
+{
+    _payloadSize = 0;
+}
+
+void 
+TestPackStereo::SetCodecType(int codecType)
+{
+    _codecType = codecType;
+}
+
+TestStereo::TestStereo(int testMode):
+_acmA(NULL),
+_acmB(NULL),
+_channelA2B(NULL),
+_testCntr(0),
+_packSizeSamp(0),
+_packSizeBytes(0),
+_counter(0)
+{
+    // testMode = 0 for silent test (auto test)
+    _testMode = testMode;
+}
+
+using namespace std;
+TestStereo::~TestStereo()
+{
+    if(_acmA != NULL)
+    {
+        AudioCodingModule::Destroy(_acmA);
+        _acmA = NULL;
+    }
+    if(_acmB != NULL)
+    {
+        AudioCodingModule::Destroy(_acmB);
+        _acmB = NULL;
+    }
+    if(_channelA2B != NULL)
+    {
+        delete _channelA2B;
+        _channelA2B = NULL;
+    }
+}
+
+void TestStereo::Perform()
+{
+     char fileName[500];
+     WebRtc_UWord16 frequencyHz;
+
+     if(_testMode == 0)
+      {
+          printf("Running Stereo Test");
+          WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
+                       "---------- TestStereo ----------");
+      }
+
+     strcpy(fileName, "./modules/audio_coding/main/test/teststereo32kHz.pcm");
+     frequencyHz = 32000;
+
+    _inFileA.Open(fileName, frequencyHz, "rb");
+    _inFileA.ReadStereo(true);
+
+    _acmA = AudioCodingModule::Create(0);
+    _acmB = AudioCodingModule::Create(1);
+
+    _acmA->InitializeReceiver();
+    _acmB->InitializeReceiver();
+
+    WebRtc_UWord8 numEncoders = _acmA->NumberOfCodecs();
+    CodecInst myCodecParam;
+ 
+    for(WebRtc_UWord8 n = 0; n < numEncoders; n++)
+    {
+        _acmB->Codec(n, myCodecParam);
+        if(!strcmp(myCodecParam.plname, "L16") || 
+            !strcmp(myCodecParam.plname, "PCMA")|| 
+            !strcmp(myCodecParam.plname, "PCMU")|| 
+            !strcmp(myCodecParam.plname, "G722"))
+        {
+            myCodecParam.channels=2;
+            _acmB->RegisterReceiveCodec(myCodecParam);
+        }
+    }
+
+    // Create and connect the channel
+    _channelA2B = new TestPackStereo;    
+    _acmA->RegisterTransportCallback(_channelA2B);
+    _channelA2B->RegisterReceiverACM(_acmB);
+    
+    // All codecs are tested for all allowed sampling frequencies, rates and packet sizes
+#ifdef WEBRTC_CODEC_G722
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _channelA2B->SetCodecType(3);
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    char codecG722[] = "G722";
+    RegisterSendCodec('A', codecG722, 16000, 64000, 160);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 320);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 480);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 640);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 800);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 960);
+    Run(_channelA2B);
+    _acmA->SetVAD(true, true, VADNormal);
+    RegisterSendCodec('A', codecG722, 16000, 64000, 320);
+    Run(_channelA2B);
+    _acmA->SetVAD(false, false, VADNormal);
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _channelA2B->SetCodecType(1);
+    _testCntr++; 
+    OpenOutFile(_testCntr);
+    char codecL16[] = "L16";
+    RegisterSendCodec('A', codecL16, 8000, 128000, 80);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 160);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 240);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 320);
+    Run(_channelA2B);
+    _acmA->SetVAD(true, true, VADNormal);
+    RegisterSendCodec('A', codecL16, 8000, 128000, 80);
+    Run(_channelA2B);
+    _acmA->SetVAD(false, false, VADNormal);
+    _outFileB.Close();
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;  
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 160);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 320);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 480);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 640);
+    Run(_channelA2B);
+    _acmA->SetVAD(true, true, VADNormal);
+    RegisterSendCodec('A', codecL16, 16000, 256000, 160);
+    Run(_channelA2B);
+    _acmA->SetVAD(false, false, VADNormal);
+    _outFileB.Close();
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++; 
+    OpenOutFile(_testCntr);
+    RegisterSendCodec('A', codecL16, 32000, 512000, 320);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecL16, 32000, 512000, 640);
+    Run(_channelA2B);
+    _acmA->SetVAD(true, true, VADNormal);
+    RegisterSendCodec('A', codecL16, 32000, 512000, 320);
+    Run(_channelA2B);
+    _acmA->SetVAD(false, false, VADNormal);
+    _outFileB.Close();
+#endif
+#define PCMA_AND_PCMU
+#ifdef PCMA_AND_PCMU
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _channelA2B->SetCodecType(0);
+    _testCntr++; 
+    OpenOutFile(_testCntr);
+    char codecPCMA[] = "PCMA";
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 80);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 160);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 240);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 320);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 400);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 480);
+    _acmA->SetVAD(true, true, VADNormal);
+    RegisterSendCodec('A', codecPCMA, 8000, 64000, 80);
+    Run(_channelA2B);
+    _acmA->SetVAD(false, false, VADNormal);
+    _outFileB.Close();
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+    _testCntr++;
+    OpenOutFile(_testCntr);
+    Run(_channelA2B);
+    char codecPCMU[] = "PCMU";
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 80);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 160);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 240);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 320);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 400);
+    Run(_channelA2B);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 480);
+    _acmA->SetVAD(true, true, VADNormal);
+    RegisterSendCodec('A', codecPCMU, 8000, 64000, 80);
+    Run(_channelA2B);
+    _acmA->SetVAD(false, false, VADNormal);
+    Run(_channelA2B);
+    _outFileB.Close();
+    if(_testMode != 0) {
+        printf("=======================================================================\n");
+    } else {
+        printf(".");
+    }
+#endif
+
+    /* Print out which codecs were tested, and which were not, in the run */
+
+    if(_testMode != 0) {
+        printf("The following codecs was INCLUDED in the test:\n");
+#ifdef WEBRTC_CODEC_G722
+        printf("   G.722\n");
+#endif
+#ifdef WEBRTC_CODEC_PCM16
+        printf("   PCM16\n");
+#endif
+        printf("   G.711\n");
+
+        printf("\nTo complete the test, listen to the %d number of output files.\n", _testCntr);
+    } else {
+        printf("Done!\n");
+    }
+}
+
+// Register Codec to use in the test
+//
+// Input:   side            - which ACM to use, 'A' or 'B'
+//          codecName       - name to use when register the codec
+//          samplingFreqHz  - sampling frequency in Herz
+//          rate            - bitrate in bytes
+//          packSize        - packet size in samples
+//          extraByte       - if extra bytes needed compared to the bitrate 
+//                            used when registering, can be an internal header
+//                            set to -1 if the codec is a variable rate codec
+WebRtc_Word16 TestStereo::RegisterSendCodec(char side, 
+                                          char* codecName, 
+                                          WebRtc_Word32 samplingFreqHz,
+                                          int rate,
+                                          int packSize)
+{
+    if(_testMode != 0) {
+        // Print out codec and settings
+        printf("codec: %s Freq: %d Rate: %d PackSize: %d", codecName, samplingFreqHz, rate, packSize);
+    }
+
+    // Store packetsize in samples, used to validate the recieved packet
+    _packSizeSamp = packSize;
+
+    // Store the expected packet size in bytes, used to validate the recieved packet
+    // Add 0.875 to always round up to a whole byte
+    _packSizeBytes = (WebRtc_UWord16)((float)(packSize*rate)/(float)(samplingFreqHz*8)+0.875);
+
+    // Set pointer to the ACM where to register the codec
+    AudioCodingModule* myACM;
+    switch(side)
+    {
+    case 'A':
+        {
+            myACM = _acmA;
+            break;
+        }
+    case 'B':
+        {
+            myACM = _acmB;
+            break;
+        }
+    default:
+        return -1;
+    }
+
+    if(myACM == NULL)
+    {
+        assert(false);
+        return -1;
+    }
+    CodecInst myCodecParam;
+
+    // Get all codec paramters before registering
+    CHECK_ERROR(AudioCodingModule::Codec(codecName, myCodecParam, samplingFreqHz));
+    myCodecParam.rate = rate;
+    myCodecParam.pacsize = packSize;
+    myCodecParam.channels = 2;
+    CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam));
+
+    // initialization was succesful
+    return 0;
+}
+
+void TestStereo::Run(TestPackStereo* channel)
+{
+    AudioFrame audioFrame;
+
+    WebRtc_UWord16 SamplesIn10MsecA = _inFileA.PayloadLength10Ms();
+    WebRtc_UWord32 timestampA = 1;
+    WebRtc_Word32 outFreqHzB = _outFileB.SamplingFrequency();
+    WebRtc_UWord16 recSize;
+    WebRtc_UWord32 timeStampDiff;
+    channel->ResetPayloadSize();
+    int errorCount = 0;
+
+    // Only run 1 second for each test case
+    while((_counter<1000)&& (!_inFileA.EndOfFile()))
+    {
+        // Add 10 msec to ACM
+         _inFileA.Read10MsData(audioFrame);
+        CHECK_ERROR(_acmA->Add10MsData(audioFrame));
+
+        // Run sender side of ACM
+        CHECK_ERROR(_acmA->Process());
+
+        // Verify that the received packet size matches the settings
+        recSize = channel->GetPayloadSize();
+        if ((0<recSize) & (recSize<65535)) {
+            if ((recSize != _packSizeBytes*2) && (_packSizeBytes < 65535)) {
+                errorCount++;
+            }
+
+            // Verify that the timestamp is updated with expected length
+            timeStampDiff = channel->GetTimeStampDiff();
+            if ((_counter > 10) && (timeStampDiff != _packSizeSamp)) {
+                errorCount++;
+            }
+        }
+
+        // Run received side of ACM
+        CHECK_ERROR(_acmB->PlayoutData10Ms(outFreqHzB, audioFrame));
+
+        // Write output speech to file
+        _outFileB.Write10MsData(audioFrame._payloadData, audioFrame._payloadDataLengthInSamples*audioFrame._audioChannel);
+    }
+
+    if (errorCount) 
+    {
+        printf(" - test FAILED\n");
+    } 
+    else if(_testMode != 0)
+    {
+        printf(" - test PASSED\n");
+    }
+
+    // Reset _counter
+    if (_counter == 1000) {
+        _counter = 0;
+    }
+    if (_inFileA.EndOfFile()) {
+        _inFileA.Rewind();
+    }
+}
+
+void TestStereo::OpenOutFile(WebRtc_Word16 testNumber)
+{
+    char fileName[500] = "./modules/audio_coding/main/test/res_tests/teststereo_out_";
+    char cntrStr[10];
+
+    sprintf(cntrStr, "%02d.pcm", testNumber);
+    strcat(fileName, cntrStr);
+
+    _outFileB.Open(fileName, 32000, "wb");
+}
+
+void TestStereo::DisplaySendReceiveCodec()
+{
+    CodecInst myCodecParam;
+    _acmA->SendCodec(myCodecParam);
+    if(_testMode != 0) {
+        printf("%s -> ", myCodecParam.plname);
+    }
+    _acmB->ReceiveCodec(myCodecParam);
+    if(_testMode != 0) {
+        printf("%s\n", myCodecParam.plname);
+    }
+}
+
diff --git a/src/modules/audio_coding/main/test/TestStereo.h b/src/modules/audio_coding/main/test/TestStereo.h
new file mode 100644
index 0000000..07c32de
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestStereo.h
@@ -0,0 +1,99 @@
+/*
+ *  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 TEST_STEREO_H
+#define TEST_STEREO_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+
+class TestPackStereo : public AudioPacketizationCallback
+{
+public:
+    TestPackStereo();
+    ~TestPackStereo();
+    
+    void RegisterReceiverACM(AudioCodingModule* acm);
+    
+    virtual WebRtc_Word32 SendData(const FrameType frameType,
+        const WebRtc_UWord8 payloadType,
+        const WebRtc_UWord32 timeStamp,
+        const WebRtc_UWord8* payloadData, 
+        const WebRtc_UWord16 payloadSize,
+        const RTPFragmentationHeader* fragmentation);
+
+    WebRtc_UWord16 GetPayloadSize();
+    WebRtc_UWord32 GetTimeStampDiff();
+    void ResetPayloadSize();
+    void SetCodecType(int codecType);
+
+
+private:
+    AudioCodingModule* _receiverACM;
+    WebRtc_Word16            _seqNo;
+    WebRtc_UWord8            _payloadData[60 * 32 * 2 * 2]; 
+    WebRtc_UWord32           _timeStampDiff;
+    WebRtc_UWord32           _lastInTimestamp;
+    WebRtc_UWord64           _totalBytes;
+    WebRtc_UWord16           _payloadSize;
+    WebRtc_UWord16           _noChannels;
+    int                    _codecType;
+};
+
+class TestStereo : public ACMTest
+{
+public:
+    TestStereo(int testMode);
+    ~TestStereo();
+
+    void Perform();
+private:
+    // The default value of '-1' indicates that the registration is based only on codec name
+    // and a sampling frequncy matching is not required. This is useful for codecs which support
+    // several sampling frequency.
+    WebRtc_Word16 RegisterSendCodec(char side, 
+        char* codecName, 
+        WebRtc_Word32 sampFreqHz,
+        int rate,
+        int packSize);
+
+    void Run(TestPackStereo* channel);
+    void OpenOutFile(WebRtc_Word16 testNumber);
+    void DisplaySendReceiveCodec();
+
+    WebRtc_Word32 SendData(
+        const FrameType       frameType,
+        const WebRtc_UWord8   payloadType,
+        const WebRtc_UWord32  timeStamp,
+        const WebRtc_UWord8*  payloadData, 
+        const WebRtc_UWord16  payloadSize,
+        const RTPFragmentationHeader* fragmentation);
+
+    int                    _testMode;
+
+    AudioCodingModule*     _acmA;
+    AudioCodingModule*     _acmB;
+
+    TestPackStereo*        _channelA2B;
+
+    PCMFile                _inFileA;
+    PCMFile                _outFileB;
+    PCMFile                _inFileStereo;
+    WebRtc_Word16          _testCntr;
+    WebRtc_UWord16         _packSizeSamp;
+    WebRtc_UWord16         _packSizeBytes;
+    int                    _counter;
+    int                    _codecType;
+};
+
+
+#endif
+
diff --git a/src/modules/audio_coding/main/test/TestVADDTX.cpp b/src/modules/audio_coding/main/test/TestVADDTX.cpp
new file mode 100644
index 0000000..8186f62
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestVADDTX.cpp
@@ -0,0 +1,503 @@
+/*
+ *  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 "TestVADDTX.h"
+
+#include "common_types.h"
+#include "audio_coding_module_typedefs.h"
+#include "utility.h"
+#include "engine_configurations.h"
+#include <iostream>
+#include "trace.h"
+
+
+TestVADDTX::TestVADDTX(int testMode):
+_acmA(NULL),
+_acmB(NULL),
+_channelA2B(NULL),
+_testResults(0)
+{
+    //testMode == 1 for more extensive testing
+    //testMode == 0 for quick test (autotest)
+   _testMode = testMode;
+}
+
+using namespace std;
+TestVADDTX::~TestVADDTX()
+{
+    if(_acmA != NULL)
+    {
+        AudioCodingModule::Destroy(_acmA);
+        _acmA = NULL;
+    }
+    if(_acmB != NULL)
+    {
+        AudioCodingModule::Destroy(_acmB);
+        _acmB = NULL;
+    }
+    if(_channelA2B != NULL)
+    {
+        delete _channelA2B;
+        _channelA2B = NULL;
+    }
+}
+
+void TestVADDTX::Perform()
+{
+
+    if(_testMode == 0)
+    {
+        printf("Running VAD/DTX Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1,
+                     "---------- TestVADDTX ----------");
+    }
+    char fileName[] = "./modules/audio_coding/main/test/testfile32kHz.pcm";
+    _inFileA.Open(fileName, 32000, "rb");
+
+    _acmA = AudioCodingModule::Create(0);
+    _acmB = AudioCodingModule::Create(1);
+
+    _acmA->InitializeReceiver();
+    _acmB->InitializeReceiver();
+
+    WebRtc_UWord8 numEncoders = _acmA->NumberOfCodecs();
+    CodecInst myCodecParam;
+    if(_testMode != 0)
+    {
+        printf("Registering codecs at receiver... \n");
+    }
+    for(WebRtc_UWord8 n = 0; n < numEncoders; n++)
+    {
+        _acmB->Codec(n, myCodecParam);
+        if(_testMode != 0)
+        {
+            printf("%s\n", myCodecParam.plname);
+        }
+        _acmB->RegisterReceiveCodec(myCodecParam);
+    }
+
+    // Create and connect the channel
+    _channelA2B = new Channel;    
+    _acmA->RegisterTransportCallback(_channelA2B);
+    _channelA2B->RegisterReceiverACM(_acmB);
+
+    _acmA->RegisterVADCallback(&_monitor);
+
+
+    WebRtc_Word16 testCntr = 1;
+    VADDTXstruct setDTX, getDTX, expectedDTX;
+    bool dtxReplaced;
+    WebRtc_Word16 testResults = 0;
+
+#ifdef WEBRTC_CODEC_ISAC
+    // Open outputfile
+    OpenOutFile(testCntr++);
+
+    // Register iSAC WB as send codec
+    char nameISAC[] = "ISAC";
+    RegisterSendCodec('A', nameISAC, 16000);
+
+    // Run the five test cased
+    runTestCases();
+
+    // Close file
+    _outFileB.Close();
+
+   // Open outputfile
+    OpenOutFile(testCntr++);
+
+    // Register iSAC SWB as send codec
+    RegisterSendCodec('A', nameISAC, 32000);
+
+    // Run the five test cased
+    runTestCases();
+
+    // Close file
+    _outFileB.Close();
+#endif
+#ifdef WEBRTC_CODEC_ILBC
+    // Open outputfile
+    OpenOutFile(testCntr++);
+
+    // Register iLBC as send codec
+    char nameILBC[] = "ilbc";
+    RegisterSendCodec('A', nameILBC);
+
+    // Run the five test cased
+    runTestCases();
+
+    // Close file
+    _outFileB.Close();
+
+#endif
+    if(_testMode) {
+        printf("Done!\n");
+    }
+
+    printf("VAD/DTX test completed with %d subtests failed\n", testResults);
+    if (testResults > 0)
+    {
+        printf("Press return\n\n", testResults);
+        getchar();
+    }
+}
+
+void TestVADDTX::runTestCases()
+{
+    if(_testMode != 0)
+    {
+        CodecInst myCodecParam;
+        _acmA->SendCodec(myCodecParam);
+        printf("%s\n", myCodecParam.plname);
+    }
+    else
+    {
+        printf(".");
+    }
+    // #1 DTX = OFF, VAD = ON, VADNormal
+    if(_testMode != 0)
+        printf("Test #1 ");
+    SetVAD(false, true, VADNormal);
+    Run();
+    _testResults += VerifyTest();
+     
+    // #2 DTX = OFF, VAD = ON, VADAggr
+    if(_testMode != 0)
+        printf("Test #2 ");
+    SetVAD(false, true, VADAggr);
+    Run();
+    _testResults += VerifyTest();
+    
+    // #3 DTX = ON, VAD = ON, VADLowBitrate
+    if(_testMode != 0)
+        printf("Test #3 ");
+    SetVAD(true, true, VADLowBitrate);
+    Run();
+    _testResults += VerifyTest();
+
+    // #4 DTX = ON, VAD = ON, VADVeryAggr
+    if(_testMode != 0)
+        printf("Test #4 ");
+    SetVAD(true, true, VADVeryAggr);
+    Run();
+    _testResults += VerifyTest();
+
+    // #5 DTX = ON, VAD = OFF, VADNormal
+    if(_testMode != 0)
+        printf("Test #5 ");
+    SetVAD(true, false, VADNormal);
+    Run();
+    _testResults += VerifyTest();
+
+}
+void TestVADDTX::runTestInternalDTX()
+{
+    // #6 DTX = ON, VAD = ON, VADNormal
+    if(_testMode != 0)
+        printf("Test #6 ");
+
+    SetVAD(true, true, VADNormal);
+    if(_acmA->ReplaceInternalDTXWithWebRtc(true) < 0) {
+        printf("Was not able to replace DTX since CN was not registered\n");
+     }
+    Run();
+    _testResults += VerifyTest();
+}
+
+void TestVADDTX::SetVAD(bool statusDTX, bool statusVAD, WebRtc_Word16 vadMode)
+{
+    WebRtc_Word32 status;
+    bool dtxEnabled, vadEnabled;
+    ACMVADMode vadModeSet;
+ 
+    status = _acmA->SetVAD(statusDTX, statusVAD, (ACMVADMode) vadMode);
+    status = _acmA->VAD(dtxEnabled, vadEnabled, vadModeSet);
+
+    if(_testMode != 0)
+    {
+        if(statusDTX != dtxEnabled) 
+        {
+            printf("DTX: %s not the same as requested: %s\n", 
+            dtxEnabled? "ON":"OFF", dtxEnabled? "OFF":"ON");
+        }
+        if((statusVAD == true) && (vadEnabled == false) || 
+           (statusVAD == false) && (vadEnabled == false) && (statusDTX == true)) 
+        {
+            printf("VAD: %s not the same as requested: %s\n", 
+            vadEnabled? "ON":"OFF", vadEnabled? "OFF":"ON");
+        }        
+        if(vadModeSet != vadMode) 
+        {
+            printf("VAD mode: %d not the same as requested: %d\n", 
+            (WebRtc_Word16)vadModeSet, (WebRtc_Word16)vadMode);
+        }
+    }
+
+    // Requested VAD/DTX settings
+    _setStruct.statusDTX = statusDTX;
+    _setStruct.statusVAD = statusVAD;
+    _setStruct.vadMode = (ACMVADMode) vadMode;
+
+    // VAD settings after setting VAD in ACM
+    _getStruct.statusDTX = dtxEnabled;
+    _getStruct.statusVAD = vadEnabled;
+    _getStruct.vadMode = vadModeSet;
+
+}
+
+VADDTXstruct TestVADDTX::GetVAD()
+{
+    VADDTXstruct retStruct;
+    WebRtc_Word32 status;
+    bool dtxEnabled, vadEnabled;
+    ACMVADMode vadModeSet;
+
+    status = _acmA->VAD(dtxEnabled, vadEnabled, vadModeSet);
+
+    retStruct.statusDTX = dtxEnabled;
+    retStruct.statusVAD = vadEnabled;
+    retStruct.vadMode = vadModeSet;
+    return retStruct;
+}
+
+WebRtc_Word16 TestVADDTX::RegisterSendCodec(char side, 
+                                          char* codecName, 
+                                          WebRtc_Word32 samplingFreqHz,
+                                          WebRtc_Word32 rateKbps)
+{
+    if(_testMode != 0)
+    {
+        printf("Registering %s for side %c\n", codecName, side);
+    }
+    cout << flush;
+    AudioCodingModule* myACM;
+    switch(side)
+    {
+    case 'A':
+        {
+            myACM = _acmA;
+            break;
+        }
+    case 'B':
+        {
+            myACM = _acmB;
+            break;
+        }
+    default:
+        return -1;
+    }
+
+    if(myACM == NULL)
+    {
+        return -1;
+    }
+    
+    CodecInst myCodecParam;
+    for(WebRtc_Word16 codecCntr = 0; codecCntr < myACM->NumberOfCodecs(); 
+        codecCntr++)
+    {
+        CHECK_ERROR(myACM->Codec((WebRtc_UWord8)codecCntr, myCodecParam));
+        if(!STR_CASE_CMP(myCodecParam.plname, codecName))
+        {
+            if((samplingFreqHz == -1) || (myCodecParam.plfreq == samplingFreqHz))
+            {
+                if((rateKbps == -1) || (myCodecParam.rate == rateKbps))
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+    CHECK_ERROR(myACM->RegisterSendCodec(myCodecParam));
+
+    // initialization was succesful
+    return 0;
+}
+
+void TestVADDTX::Run()
+{
+    AudioFrame audioFrame;
+
+    WebRtc_UWord16 SamplesIn10MsecA = _inFileA.PayloadLength10Ms();
+    WebRtc_UWord32 timestampA = 1;
+    WebRtc_Word32 outFreqHzB = _outFileB.SamplingFrequency();
+
+    while(!_inFileA.EndOfFile())
+    {
+        _inFileA.Read10MsData(audioFrame);
+        audioFrame._timeStamp = timestampA;
+        timestampA += SamplesIn10MsecA;
+        CHECK_ERROR(_acmA->Add10MsData(audioFrame));
+
+        CHECK_ERROR(_acmA->Process());
+
+        CHECK_ERROR(_acmB->PlayoutData10Ms(outFreqHzB, audioFrame));
+        _outFileB.Write10MsData(audioFrame._payloadData, audioFrame._payloadDataLengthInSamples);
+    }
+#ifdef PRINT_STAT
+    _monitor.PrintStatistics(_testMode);
+#endif
+    _inFileA.Rewind();
+    _monitor.GetStatistics(_statCounter);
+    _monitor.ResetStatistics();
+}
+
+void TestVADDTX::OpenOutFile(WebRtc_Word16 testNumber)
+{
+    char fileName[500] = "./modules/audio_coding/main/test/res_tests/testVADDTX_outFile_";
+    char cntrStr[10];
+
+    if(_testMode == 0)
+    {
+        sprintf(fileName, "./modules/audio_coding/main/test/res_autotests/testVADDTX_outFile_");
+    }
+    sprintf(cntrStr, "%02d.pcm", testNumber);
+    strcat(fileName, cntrStr);
+    _outFileB.Open(fileName, 16000, "wb");
+}
+
+
+WebRtc_Word16 TestVADDTX::VerifyTest()
+{
+    // Verify empty frame result
+    WebRtc_UWord8 statusEF = 0;
+    WebRtc_UWord8 vadPattern = 0;
+    WebRtc_UWord8 emptyFramePattern[6];
+    CodecInst myCodecParam;
+    _acmA->SendCodec(myCodecParam);
+    bool dtxInUse = true;
+    bool isReplaced = false;
+    if ((STR_CASE_CMP(myCodecParam.plname,"G729") == 0) ||
+        (STR_CASE_CMP(myCodecParam.plname,"G723") == 0) ||
+        (STR_CASE_CMP(myCodecParam.plname,"AMR") == 0) ||
+        (STR_CASE_CMP(myCodecParam.plname,"AMR-wb") == 0) ||
+        (STR_CASE_CMP(myCodecParam.plname,"speex") == 0)) 
+    {
+        _acmA->IsInternalDTXReplacedWithWebRtc(isReplaced);
+        if (!isReplaced)
+        {
+            dtxInUse = false;
+        }
+    }
+    
+    // Check for error in VAD/DTX settings
+    if (_getStruct.statusDTX != _setStruct.statusDTX){
+        // DTX status doesn't match expected
+        vadPattern |= 4;
+    }
+    if (_getStruct.statusDTX){
+        if ((!_getStruct.statusVAD && dtxInUse) || (!dtxInUse && (_getStruct.statusVAD !=_setStruct.statusVAD)))
+        {            
+            // Missmatch in VAD setting
+            vadPattern |= 2;
+        }
+    } else {
+        if (_getStruct.statusVAD != _setStruct.statusVAD){
+            // VAD status doesn't match expected    
+            vadPattern |= 2;
+        }
+    }
+    if (_getStruct.vadMode != _setStruct.vadMode){
+        // VAD Mode doesn't match expected
+        vadPattern |= 1;
+    }
+
+    // Set expected empty frame pattern
+    int ii;
+    for (ii = 0; ii < 6; ii++) {
+        emptyFramePattern[ii] = 0;
+    }
+    emptyFramePattern[0] = 1; // "kNoEncoding", not important to check. Codecs with packetsize != 80 samples will get this output.
+    emptyFramePattern[1] = 1; // Expect to always receive some frames labeled "kActiveNormalEncoded"
+    emptyFramePattern[2] = (((!_getStruct.statusDTX && _getStruct.statusVAD) || (!dtxInUse && _getStruct.statusDTX))); // "kPassiveNormalEncoded"
+    emptyFramePattern[3] = ((_getStruct.statusDTX && dtxInUse && (_acmA->SendFrequency() == 8000))); // "kPassiveDTXNB"
+    emptyFramePattern[4] = ((_getStruct.statusDTX && dtxInUse && (_acmA->SendFrequency() == 16000))); // "kPassiveDTXWB"
+    emptyFramePattern[5] = ((_getStruct.statusDTX && dtxInUse && (_acmA->SendFrequency() == 32000))); // "kPassiveDTXSWB"
+
+    // Check pattern 1-5 (skip 0)
+    for (int ii = 1; ii < 6; ii++)
+    {
+        if (emptyFramePattern[ii])
+        {
+            statusEF |= (_statCounter[ii] == 0);
+        }
+        else
+        {
+            statusEF |= (_statCounter[ii] > 0);
+        }
+    }
+    if ((statusEF == 0) && (vadPattern == 0))
+    {
+        if(_testMode != 0)
+        {
+            printf(" Test OK!\n");
+        }
+        return 0;
+    }
+    else
+    {
+        if (statusEF)
+        {
+            printf("\t\t\tUnexpected empty frame result!\n");
+        }
+        if (vadPattern)
+        {
+            printf("\t\t\tUnexpected SetVAD() result!\tDTX: %d\tVAD: %d\tMode: %d\n", (vadPattern >> 2) & 1, (vadPattern >> 1) & 1, vadPattern & 1);
+        }
+        return 1;
+    }
+}
+
+ActivityMonitor::ActivityMonitor()
+{
+    _counter[0] = _counter[1] = _counter[2] = _counter[3] = _counter[4] = _counter[5] = 0;
+}
+
+ActivityMonitor::~ActivityMonitor()
+{
+}
+
+WebRtc_Word32 ActivityMonitor::InFrameType(WebRtc_Word16 frameType)
+{
+    _counter[frameType]++;
+    return 0;
+}
+
+void ActivityMonitor::PrintStatistics(int testMode)
+{
+    if(testMode != 0)
+    {
+        printf("\n");
+        printf("kActiveNormalEncoded  kPassiveNormalEncoded  kPassiveDTXWB  kPassiveDTXNB kPassiveDTXSWB kFrameEmpty\n");
+
+        printf("%19u", _counter[1]);
+        printf("%22u", _counter[2]);
+        printf("%14u", _counter[3]);
+        printf("%14u", _counter[4]);
+        printf("%14u", _counter[5]);
+        printf("%11u", _counter[0]);
+
+        printf("\n\n");
+    }
+}
+
+void ActivityMonitor::ResetStatistics()
+{
+    _counter[0] = _counter[1] = _counter[2] = _counter[3] = _counter[4] = _counter[5] = 0;
+}
+
+void ActivityMonitor::GetStatistics(WebRtc_UWord32* getCounter)
+{
+    for (int ii = 0; ii < 6; ii++)
+    {
+        getCounter[ii] = _counter[ii];
+    }
+}
diff --git a/src/modules/audio_coding/main/test/TestVADDTX.h b/src/modules/audio_coding/main/test/TestVADDTX.h
new file mode 100644
index 0000000..cf9088b
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TestVADDTX.h
@@ -0,0 +1,87 @@
+/*
+ *  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 TEST_VAD_DTX_H
+#define TEST_VAD_DTX_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+
+typedef struct 
+{
+    bool statusDTX;
+    bool statusVAD;
+    ACMVADMode vadMode;
+} VADDTXstruct;
+
+class ActivityMonitor : public ACMVADCallback
+{
+public:
+    ActivityMonitor();
+    ~ActivityMonitor();
+    WebRtc_Word32 InFrameType(WebRtc_Word16 frameType);
+    void PrintStatistics(int testMode);
+    void ResetStatistics();
+    void GetStatistics(WebRtc_UWord32* getCounter);
+private:
+    // counting according to
+    /*enum WebRtcACMEncodingType
+    {
+        kNoEncoding,
+        kActiveNormalEncoded,
+        kPassiveNormalEncoded,
+        kPassiveDTXNB,
+        kPassiveDTXWB,
+        kPassiveDTXSWB
+    };*/
+    WebRtc_UWord32 _counter[6];
+};
+
+class TestVADDTX : public ACMTest
+{
+public:
+    TestVADDTX(int testMode);
+    ~TestVADDTX();
+
+    void Perform();
+private:
+    // Registration can be based on codec name only, codec name and sampling frequency, or 
+    // codec name, sampling frequency and rate.
+    WebRtc_Word16 RegisterSendCodec(char side, 
+        char* codecName, 
+        WebRtc_Word32 samplingFreqHz = -1,
+        WebRtc_Word32 rateKhz = -1);
+    void Run();
+    void OpenOutFile(WebRtc_Word16 testNumber);
+    void runTestCases();
+    void runTestInternalDTX();
+    void SetVAD(bool statusDTX, bool statusVAD, WebRtc_Word16 vadMode);
+    VADDTXstruct GetVAD();
+    WebRtc_Word16 VerifyTest();//VADDTXstruct setDTX, VADDTXstruct getDTX);
+    AudioCodingModule* _acmA;
+    AudioCodingModule* _acmB;
+
+    Channel*               _channelA2B;
+
+    PCMFile                _inFileA;
+    PCMFile                _outFileB;
+
+    ActivityMonitor        _monitor;
+    WebRtc_UWord32           _statCounter[6];
+
+    int                    _testMode;
+    int                    _testResults;
+    VADDTXstruct           _setStruct;
+    VADDTXstruct           _getStruct;
+};
+
+
+#endif
diff --git a/src/modules/audio_coding/main/test/Tester.cpp b/src/modules/audio_coding/main/test/Tester.cpp
new file mode 100644
index 0000000..1049cad
--- /dev/null
+++ b/src/modules/audio_coding/main/test/Tester.cpp
@@ -0,0 +1,131 @@
+/*
+ *  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 <vector>
+
+#include "audio_coding_module.h"
+#include "trace.h"
+
+#include "APITest.h"
+#include "EncodeDecodeTest.h"
+#include "EncodeToFileTest.h"
+#include "iSACTest.h"
+#include "SpatialAudio.h"
+#include "TestAllCodecs.h"
+#include "TestFEC.h"
+#include "TestStereo.h"
+#include "TestVADDTX.h"
+#include "TwoWayCommunication.h"
+
+// Be sure to create the following directories before running the tests:
+// ./modules/audio_coding/main/test/res_tests
+// ./modules/audio_coding/main/test/res_autotests
+
+// Choose what tests to run by defining one or more of the following:
+#define ACM_AUTO_TEST            // Most common codecs and settings will be tested
+//#define ACM_TEST_ENC_DEC        // You decide what to test in run time.
+                                  // Used for debugging and for testing while implementing.
+//#define ACM_TEST_TWO_WAY        // Debugging
+//#define ACM_TEST_ALL_ENC_DEC    // Loop through all defined codecs and settings
+//#define ACM_TEST_STEREO         // Run stereo and spatial audio tests
+//#define ACM_TEST_VAD_DTX        // Run all VAD/DTX tests
+//#define ACM_TEST_FEC            // Test FEC (also called RED)
+//#define ACM_TEST_CODEC_SPEC_API // Only iSAC has codec specfic APIs in this version
+//#define ACM_TEST_FULL_API       // Test all APIs with threads (long test)
+
+
+void PopulateTests(std::vector<ACMTest*>* tests)
+{
+
+     Trace::CreateTrace();
+     Trace::SetTraceFile("./modules/audio_coding/main/test/res_tests/test_trace.txt");
+
+     printf("The following tests will be executed:\n");
+#ifdef ACM_AUTO_TEST
+    printf("  ACM auto test\n");
+    tests->push_back(new EncodeDecodeTest(0));
+    tests->push_back(new TwoWayCommunication(0));
+    tests->push_back(new TestAllCodecs(0));
+    tests->push_back(new TestStereo(0));
+    tests->push_back(new SpatialAudio(0));
+    tests->push_back(new TestVADDTX(0));
+    tests->push_back(new TestFEC(0));
+    tests->push_back(new ISACTest(0));
+#endif
+#ifdef ACM_TEST_ENC_DEC
+    printf("  ACM encode-decode test\n");
+    tests->push_back(new EncodeDecodeTest(2));
+#endif
+#ifdef ACM_TEST_TWO_WAY
+    printf("  ACM two-way communication test\n");
+    tests->push_back(new TwoWayCommunication(1));
+#endif
+#ifdef ACM_TEST_ALL_ENC_DEC
+    printf("  ACM all codecs test\n");
+    tests->push_back(new TestAllCodecs(1));
+#endif
+#ifdef ACM_TEST_STEREO
+    printf("  ACM stereo test\n");
+    tests->push_back(new TestStereo(1));
+    tests->push_back(new SpatialAudio(2));
+#endif
+#ifdef ACM_TEST_VAD_DTX
+    printf("  ACM VAD-DTX test\n");
+    tests->push_back(new TestVADDTX(1));
+#endif
+#ifdef ACM_TEST_FEC
+    printf("  ACM FEC test\n");
+    tests->push_back(new TestFEC(1));
+#endif
+#ifdef ACM_TEST_CODEC_SPEC_API
+    printf("  ACM codec API test\n");
+    tests->push_back(new ISACTest(1));
+#endif
+#ifdef ACM_TEST_FULL_API
+    printf("  ACM full API test\n");
+    tests->push_back(new APITest());
+#endif
+    printf("\n");
+}
+
+int main()
+{
+    std::vector<ACMTest*> tests;
+    PopulateTests(&tests);
+    std::vector<ACMTest*>::iterator it;
+    WebRtc_Word8 version[5000];
+    version[0] = '\0';
+
+    WebRtc_UWord32 remainingBufferInByte = 4999;
+    WebRtc_UWord32 position = 0;
+    AudioCodingModule::GetVersion(version, remainingBufferInByte, position);
+    
+    printf("%s\n", version);
+    for (it=tests.begin() ; it < tests.end(); it++)
+    {
+        try {
+
+            (*it)->Perform();
+        }
+        catch (char *except)
+        {
+            printf("Test failed with message: %s", except);
+            getchar(); 
+            return -1;
+        }
+        delete (*it);
+    }
+
+    Trace::ReturnTrace();
+    printf("ACM test completed\n");
+
+    return 0;
+}
diff --git a/src/modules/audio_coding/main/test/TimedTrace.cpp b/src/modules/audio_coding/main/test/TimedTrace.cpp
new file mode 100644
index 0000000..6bf301f
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TimedTrace.cpp
@@ -0,0 +1,77 @@
+/*
+ *  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 "TimedTrace.h"
+#include <math.h>
+
+double TimedTrace::_timeEllapsedSec = 0;
+FILE*  TimedTrace::_timedTraceFile = NULL;
+
+TimedTrace::TimedTrace()
+{
+
+}
+
+TimedTrace::~TimedTrace()
+{
+    if(_timedTraceFile != NULL)
+    {
+        fclose(_timedTraceFile);
+    }
+    _timedTraceFile = NULL;
+}
+
+WebRtc_Word16
+TimedTrace::SetUp(char* fileName)
+{
+    if(_timedTraceFile == NULL)
+    {
+        _timedTraceFile = fopen(fileName, "w");
+    }
+    if(_timedTraceFile == NULL)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+void
+TimedTrace::SetTimeEllapsed(double timeEllapsedSec)
+{
+    _timeEllapsedSec = timeEllapsedSec;
+}
+
+double
+TimedTrace::TimeEllapsed()
+{
+    return _timeEllapsedSec;
+}
+
+void
+TimedTrace::Tick10Msec()
+{
+    _timeEllapsedSec += 0.010;
+}
+
+void
+TimedTrace::TimedLogg(char* message)
+{    
+    unsigned int minutes = (WebRtc_UWord32)floor(_timeEllapsedSec / 60.0);
+    double seconds = _timeEllapsedSec - minutes * 60;
+    //char myFormat[100] = "%8.2f, %3u:%05.2f: %s\n";
+    if(_timedTraceFile != NULL)
+    {
+        fprintf(_timedTraceFile, "%8.2f, %3u:%05.2f: %s\n", 
+            _timeEllapsedSec, 
+            minutes, 
+            seconds, 
+            message);
+    }
+}
diff --git a/src/modules/audio_coding/main/test/TimedTrace.h b/src/modules/audio_coding/main/test/TimedTrace.h
new file mode 100644
index 0000000..d37d287
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TimedTrace.h
@@ -0,0 +1,38 @@
+/*
+ *  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 TIMED_TRACE_H
+#define TIMED_TRACE_H
+
+#include "typedefs.h"
+
+#include <cstdio>
+#include <cstdlib>
+
+
+class TimedTrace
+{
+public:
+    TimedTrace();
+    ~TimedTrace();
+
+    void SetTimeEllapsed(double myTime);
+    double TimeEllapsed();
+    void Tick10Msec();
+    WebRtc_Word16 SetUp(char* fileName);
+    void TimedLogg(char* message);
+
+private:
+    static double _timeEllapsedSec;
+    static FILE*  _timedTraceFile;
+
+};
+
+#endif
diff --git a/src/modules/audio_coding/main/test/TwoWayCommunication.cpp b/src/modules/audio_coding/main/test/TwoWayCommunication.cpp
new file mode 100644
index 0000000..21d4012
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TwoWayCommunication.cpp
@@ -0,0 +1,503 @@
+/*
+ *  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 <cctype>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
+#include "TwoWayCommunication.h"
+#include "engine_configurations.h"
+#include "PCMFile.h"
+#include "utility.h"
+#include "trace.h"
+#include "common_types.h"
+
+using namespace webrtc;
+
+#define MAX_FILE_NAME_LENGTH_BYTE 500
+
+TwoWayCommunication::TwoWayCommunication(int testMode)
+{
+    _testMode = testMode;
+}
+
+TwoWayCommunication::~TwoWayCommunication()
+{
+    AudioCodingModule::Destroy(_acmA);
+    AudioCodingModule::Destroy(_acmB);
+
+    AudioCodingModule::Destroy(_acmRefA);
+    AudioCodingModule::Destroy(_acmRefB);
+
+    delete _channel_A2B;
+    delete _channel_B2A;
+
+    delete _channelRef_A2B;
+    delete _channelRef_B2A;
+#ifdef WEBRTC_DTMF_DETECTION
+    if(_dtmfDetectorA != NULL)
+    {
+        delete _dtmfDetectorA;
+    }
+    if(_dtmfDetectorB != NULL)
+    {
+        delete _dtmfDetectorB;
+    }
+#endif
+    _inFileA.Close();
+    _inFileB.Close();
+    _outFileA.Close();
+    _outFileB.Close();
+    _outFileRefA.Close();
+    _outFileRefB.Close();
+}
+
+
+WebRtc_UWord8
+TwoWayCommunication::ChooseCodec(WebRtc_UWord8* codecID_A, WebRtc_UWord8* codecID_B)
+{
+    AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
+    WebRtc_UWord8 noCodec = tmpACM->NumberOfCodecs();
+    CodecInst codecInst;
+    printf("List of Supported Codecs\n");
+    printf("========================\n");
+    for(WebRtc_UWord8 codecCntr = 0; codecCntr < noCodec; codecCntr++)
+    {
+        tmpACM->Codec(codecCntr, codecInst);
+        printf("%d- %s\n", codecCntr, codecInst.plname);
+    }
+    printf("\nChoose a send codec for side A [0]: ");
+    char myStr[15] = "";
+    fgets(myStr, 10, stdin);
+    *codecID_A = (WebRtc_UWord8)atoi(myStr);
+
+    printf("\nChoose a send codec for side B [0]: ");
+    fgets(myStr, 10, stdin);
+    *codecID_B = (WebRtc_UWord8)atoi(myStr);
+
+    AudioCodingModule::Destroy(tmpACM);
+    printf("\n");
+    return 0;
+}
+
+WebRtc_Word16
+TwoWayCommunication::ChooseFile(char* fileName, WebRtc_Word16 maxLen, WebRtc_UWord16* frequencyHz)
+{
+    WebRtc_Word8 tmpName[MAX_FILE_NAME_LENGTH_BYTE];
+    //strcpy(_fileName, "in.pcm");
+    //printf("\n\nPlease enter the input file: ");
+    fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin);
+    tmpName[MAX_FILE_NAME_LENGTH_BYTE-1] = '\0';
+    WebRtc_Word16 n = 0;
+
+    // removing leading spaces
+    while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
+        (tmpName[n] != 0) && 
+        (n < MAX_FILE_NAME_LENGTH_BYTE))
+    {
+        n++;
+    }
+    if(n > 0)
+    {
+        memmove(tmpName, &tmpName[n], MAX_FILE_NAME_LENGTH_BYTE - n);
+    }
+
+    //removing trailing spaces
+    n = (WebRtc_Word16)(strlen(tmpName) - 1);
+    if(n >= 0)
+    {
+        while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
+            (n >= 0))
+        {
+            n--;
+        }
+    }
+    if(n >= 0)
+    {
+        tmpName[n + 1] = '\0';
+    }
+
+    WebRtc_Word16 len = (WebRtc_Word16)strlen(tmpName);
+    if(len > maxLen)
+    {
+        return -1;
+    }    
+    if(len > 0)
+    {
+        strncpy(fileName, tmpName, len+1);
+    }
+    printf("Enter the sampling frequency (in Hz) of the above file [%u]: ", *frequencyHz);
+    fgets(tmpName, 6, stdin);
+    WebRtc_UWord16 tmpFreq = (WebRtc_UWord16)atoi(tmpName);
+    if(tmpFreq > 0)
+    {
+        *frequencyHz = tmpFreq;
+    }
+    return 0;
+}
+
+WebRtc_Word16 TwoWayCommunication::SetUp()
+{
+    _acmA = AudioCodingModule::Create(1);
+    _acmB = AudioCodingModule::Create(2);
+
+    _acmRefA = AudioCodingModule::Create(3);
+    _acmRefB = AudioCodingModule::Create(4);
+
+    WebRtc_UWord8 codecID_A;
+    WebRtc_UWord8 codecID_B;
+
+    ChooseCodec(&codecID_A, &codecID_B);
+    CodecInst codecInst_A;
+    CodecInst codecInst_B;
+    CodecInst dummyCodec;
+    _acmA->Codec(codecID_A, codecInst_A);
+    _acmB->Codec(codecID_B, codecInst_B);
+
+    _acmA->Codec(6, dummyCodec);
+
+    //--- Set A codecs
+    CHECK_ERROR(_acmA->RegisterSendCodec(codecInst_A));
+    CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
+#ifdef WEBRTC_DTMF_DETECTION
+    _dtmfDetectorA = new(DTMFDetector);
+    CHECK_ERROR(_acmA->RegisterIncomingMessagesCallback(_dtmfDetectorA, ACMUSA));
+#endif
+    //--- Set ref-A codecs
+    CHECK_ERROR(_acmRefA->RegisterSendCodec(codecInst_A));
+    CHECK_ERROR(_acmRefA->RegisterReceiveCodec(codecInst_B));
+
+    //--- Set B codecs
+    CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
+    CHECK_ERROR(_acmB->RegisterReceiveCodec(codecInst_A));
+#ifdef WEBRTC_DTMF_DETECTION
+    _dtmfDetectorB = new(DTMFDetector);
+    CHECK_ERROR(_acmB->RegisterIncomingMessagesCallback(_dtmfDetectorB, ACMUSA));
+#endif
+
+    //--- Set ref-B codecs
+    CHECK_ERROR(_acmRefB->RegisterSendCodec(codecInst_B));
+    CHECK_ERROR(_acmRefB->RegisterReceiveCodec(codecInst_A));
+
+    char fileName[500];
+    char refFileName[500];
+    WebRtc_UWord16 frequencyHz;
+    
+    //--- Input A
+    strcpy(fileName, "./modules/audio_coding/main/test/testfile32kHz.pcm");
+    frequencyHz = 32000;
+    printf("Enter input file at side A [%s]: ", fileName);
+    ChooseFile(fileName, 499, &frequencyHz);
+
+
+    _inFileA.Open(fileName, frequencyHz, "rb");
+
+    //--- Output A
+    strcpy(fileName, "outA.pcm");
+    frequencyHz = 16000;
+    printf("Enter output file at side A [%s]: ", fileName);
+    ChooseFile(fileName, 499, &frequencyHz);
+    _outFileA.Open(fileName, frequencyHz, "wb");
+    strcpy(refFileName, "ref_");
+    strcat(refFileName, fileName);
+    _outFileRefA.Open(refFileName, frequencyHz, "wb");
+
+    //--- Input B
+    strcpy(fileName, "./modules/audio_coding/main/test/testfile32kHz.pcm");
+    frequencyHz = 32000;
+    printf("\n\nEnter input file at side B [%s]: ", fileName);
+    ChooseFile(fileName, 499, &frequencyHz);
+    _inFileB.Open(fileName, frequencyHz, "rb");
+
+    //--- Output B
+    strcpy(fileName, "outB.pcm");
+    frequencyHz = 16000;
+    printf("Enter output file at side B [%s]: ", fileName);
+    ChooseFile(fileName, 499, &frequencyHz);
+    _outFileB.Open(fileName, frequencyHz, "wb");
+    strcpy(refFileName, "ref_");
+    strcat(refFileName, fileName);
+    _outFileRefB.Open(refFileName, frequencyHz, "wb");
+    
+    //--- Set A-to-B channel
+    _channel_A2B = new Channel;
+    _acmA->RegisterTransportCallback(_channel_A2B);
+    _channel_A2B->RegisterReceiverACM(_acmB);
+    //--- Do the same for the reference
+    _channelRef_A2B = new Channel;
+    _acmRefA->RegisterTransportCallback(_channelRef_A2B);
+    _channelRef_A2B->RegisterReceiverACM(_acmRefB);
+
+    //--- Set B-to-A channel
+    _channel_B2A = new Channel;
+    _acmB->RegisterTransportCallback(_channel_B2A);
+    _channel_B2A->RegisterReceiverACM(_acmA);
+    //--- Do the same for reference
+    _channelRef_B2A = new Channel;
+    _acmRefB->RegisterTransportCallback(_channelRef_B2A);
+    _channelRef_B2A->RegisterReceiverACM(_acmRefA);
+
+    // The clicks will be more obvious when we 
+    // are in FAX mode.
+    _acmB->SetPlayoutMode(fax);
+    _acmRefB->SetPlayoutMode(fax);
+
+    return 0;
+}
+
+WebRtc_Word16 TwoWayCommunication::SetUpAutotest()
+{
+    _acmA = AudioCodingModule::Create(1);
+    _acmB = AudioCodingModule::Create(2);
+
+    _acmRefA = AudioCodingModule::Create(3);
+    _acmRefB = AudioCodingModule::Create(4);
+
+    CodecInst codecInst_A;
+    CodecInst codecInst_B;
+    CodecInst dummyCodec;
+
+    _acmA->Codec("ISAC", codecInst_A, 16000);
+    _acmB->Codec("L16", codecInst_B, 8000);
+    _acmA->Codec(6, dummyCodec);
+
+    //--- Set A codecs
+    CHECK_ERROR(_acmA->RegisterSendCodec(codecInst_A));
+    CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
+#ifdef WEBRTC_DTMF_DETECTION
+    _dtmfDetectorA = new(DTMFDetector);
+    CHECK_ERROR(_acmA->RegisterIncomingMessagesCallback(_dtmfDetectorA, ACMUSA));
+#endif
+
+    //--- Set ref-A codecs
+    CHECK_ERROR(_acmRefA->RegisterSendCodec(codecInst_A));
+    CHECK_ERROR(_acmRefA->RegisterReceiveCodec(codecInst_B));
+
+    //--- Set B codecs
+    CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
+    CHECK_ERROR(_acmB->RegisterReceiveCodec(codecInst_A));
+#ifdef WEBRTC_DTMF_DETECTION
+    _dtmfDetectorB = new(DTMFDetector);
+    CHECK_ERROR(_acmB->RegisterIncomingMessagesCallback(_dtmfDetectorB, ACMUSA));
+#endif
+
+    //--- Set ref-B codecs
+    CHECK_ERROR(_acmRefB->RegisterSendCodec(codecInst_B));
+    CHECK_ERROR(_acmRefB->RegisterReceiveCodec(codecInst_A));
+
+    char fileName[500];
+    char refFileName[500];
+    WebRtc_UWord16 frequencyHz;
+
+
+    //--- Input A
+    strcpy(fileName, "./modules/audio_coding/main/test/testfile32kHz.pcm");
+    frequencyHz = 16000;
+    _inFileA.Open(fileName, frequencyHz, "rb");
+
+    //--- Output A
+    strcpy(fileName, "./modules/audio_coding/main/test/res_autotests/outAutotestA.pcm");
+    frequencyHz = 16000;
+    _outFileA.Open(fileName, frequencyHz, "wb");
+    strcpy(refFileName, "./modules/audio_coding/main/test/res_autotests/ref_outAutotestA.pcm");
+    _outFileRefA.Open(refFileName, frequencyHz, "wb");
+
+    //--- Input B
+    strcpy(fileName, "./modules/audio_coding/main/test/testfile32kHz.pcm");
+    frequencyHz = 16000;
+    _inFileB.Open(fileName, frequencyHz, "rb");
+
+    //--- Output B
+    strcpy(fileName, "./modules/audio_coding/main/test/res_autotests/outAutotestB.pcm");
+    frequencyHz = 16000;
+    _outFileB.Open(fileName, frequencyHz, "wb");
+    strcpy(refFileName, "./modules/audio_coding/main/test/res_autotests/ref_outAutotestB.pcm");
+    _outFileRefB.Open(refFileName, frequencyHz, "wb");
+
+    //--- Set A-to-B channel
+    _channel_A2B = new Channel;
+    _acmA->RegisterTransportCallback(_channel_A2B);
+    _channel_A2B->RegisterReceiverACM(_acmB);
+    //--- Do the same for the reference
+    _channelRef_A2B = new Channel;
+    _acmRefA->RegisterTransportCallback(_channelRef_A2B);
+    _channelRef_A2B->RegisterReceiverACM(_acmRefB);
+
+    //--- Set B-to-A channel
+    _channel_B2A = new Channel;
+    _acmB->RegisterTransportCallback(_channel_B2A);
+    _channel_B2A->RegisterReceiverACM(_acmA);
+    //--- Do the same for reference
+    _channelRef_B2A = new Channel;
+    _acmRefB->RegisterTransportCallback(_channelRef_B2A);
+    _channelRef_B2A->RegisterReceiverACM(_acmRefA);
+
+    // The clicks will be more obvious when we 
+    // are in FAX mode.
+    _acmB->SetPlayoutMode(fax);
+    _acmRefB->SetPlayoutMode(fax);
+
+    return 0;
+}
+
+void
+TwoWayCommunication::Perform()
+{
+    if(_testMode == 0)
+    {
+        printf("Running TwoWayCommunication Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- TwoWayCommunication ----------");
+        SetUpAutotest();
+    }
+    else
+    {
+        SetUp();
+    }
+    unsigned int msecPassed = 0;
+    unsigned int secPassed  = 0;
+
+    WebRtc_Word32 outFreqHzA = _outFileA.SamplingFrequency();
+    WebRtc_Word32 outFreqHzB = _outFileB.SamplingFrequency();
+
+    AudioFrame audioFrame;
+
+    CodecInst codecInst_B;
+    CodecInst dummy;
+
+    _acmB->SendCodec(codecInst_B);
+
+    if(_testMode != 0)
+    {
+        printf("\n");
+        printf("sec:msec                   A                                                  B\n");
+        printf("--------                 -----                                              -----\n");
+    }
+
+    while(!_inFileA.EndOfFile() && !_inFileB.EndOfFile())
+    {
+        _inFileA.Read10MsData(audioFrame);
+        _acmA->Add10MsData(audioFrame);
+        _acmRefA->Add10MsData(audioFrame);
+
+        _inFileB.Read10MsData(audioFrame);
+        _acmB->Add10MsData(audioFrame);
+        _acmRefB->Add10MsData(audioFrame);
+
+
+        _acmA->Process();
+        _acmB->Process();
+        _acmRefA->Process();
+        _acmRefB->Process();
+
+        _acmA->PlayoutData10Ms(outFreqHzA, audioFrame);
+        _outFileA.Write10MsData(audioFrame);
+
+        _acmRefA->PlayoutData10Ms(outFreqHzA, audioFrame);
+        _outFileRefA.Write10MsData(audioFrame);
+
+        _acmB->PlayoutData10Ms(outFreqHzB, audioFrame);
+        _outFileB.Write10MsData(audioFrame);
+
+        _acmRefB->PlayoutData10Ms(outFreqHzB, audioFrame);
+        _outFileRefB.Write10MsData(audioFrame);
+
+        msecPassed += 10;
+        if(msecPassed >= 1000)
+        {
+            msecPassed = 0;
+            secPassed++;
+        }
+        if(((secPassed%5) == 4) && (msecPassed == 0))
+        {
+            if(_testMode != 0)
+            {
+                printf("%3u:%3u  ", secPassed, msecPassed);
+            }
+            _acmA->ResetEncoder();
+            if(_testMode == 0)
+            {
+                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- Errors epected");
+                printf(".");
+            }
+            else
+            {
+                printf("Reset Encoder (click in side B)               ");
+                printf("Initialize Sender (no audio in side A)\n");
+            }
+            CHECK_ERROR(_acmB->InitializeSender());
+        }
+        if(((secPassed%5) == 4) && (msecPassed >= 990))
+        {
+            if(_testMode == 0)
+            {
+                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "----- END: Errors epected");
+                printf(".");
+            }
+            else
+            {
+                printf("%3u:%3u  ", secPassed, msecPassed);
+                printf("                                              ");
+                printf("Register Send Codec (audio back in side A)\n");
+            }
+            CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
+            CHECK_ERROR(_acmB->SendCodec(dummy));
+        }
+        if(((secPassed%7) == 6) && (msecPassed == 0))
+        {
+            CHECK_ERROR(_acmB->ResetDecoder());
+            if(_testMode == 0)
+            {
+                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- Errors epected");
+                printf(".");
+            }
+            else
+            {
+                printf("%3u:%3u  ", secPassed, msecPassed);
+                printf("Initialize Receiver (no audio in side A)      ");
+                printf("Reset Decoder\n");
+            }
+            CHECK_ERROR(_acmA->InitializeReceiver());
+        }
+        if(((secPassed%7) == 6) && (msecPassed >= 990))
+        {
+            if(_testMode == 0)
+            {
+                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "----- END: Errors epected");
+                printf(".");
+            }
+            else
+            {
+                printf("%3u:%3u  ", secPassed, msecPassed);
+                printf("Register Receive Coded (audio back in side A)\n");
+            }
+            CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
+        }
+        //Sleep(9);
+    }
+    if(_testMode == 0)
+    {
+        printf("Done!\n");
+    }
+
+#ifdef WEBRTC_DTMF_DETECTION
+    printf("\nDTMF at Side A\n");
+    _dtmfDetectorA->PrintDetectedDigits();
+
+    printf("\nDTMF at Side B\n");
+    _dtmfDetectorB->PrintDetectedDigits();
+#endif
+
+
+}
+
diff --git a/src/modules/audio_coding/main/test/TwoWayCommunication.h b/src/modules/audio_coding/main/test/TwoWayCommunication.h
new file mode 100644
index 0000000..66ede04
--- /dev/null
+++ b/src/modules/audio_coding/main/test/TwoWayCommunication.h
@@ -0,0 +1,62 @@
+/*
+ *  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 TWO_WAY_COMMUNICATION_H
+#define TWO_WAY_COMMUNICATION_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+#include "audio_coding_module.h"
+#include "utility.h"
+
+
+class TwoWayCommunication : public ACMTest
+{
+public:
+    TwoWayCommunication(int testMode = 1);
+    ~TwoWayCommunication();
+
+    void Perform();
+private:
+    WebRtc_UWord8 ChooseCodec(WebRtc_UWord8* codecID_A, WebRtc_UWord8* codecID_B);
+    WebRtc_Word16 ChooseFile(char* fileName, WebRtc_Word16 maxLen, WebRtc_UWord16* frequencyHz);
+    WebRtc_Word16 SetUp();
+    WebRtc_Word16 SetUpAutotest();
+
+    AudioCodingModule* _acmA;
+    AudioCodingModule* _acmB;
+
+    AudioCodingModule* _acmRefA;
+    AudioCodingModule* _acmRefB;
+
+    Channel* _channel_A2B;
+    Channel* _channel_B2A;
+
+    Channel* _channelRef_A2B;
+    Channel* _channelRef_B2A;
+
+    PCMFile _inFileA;
+    PCMFile _inFileB;
+
+    PCMFile _outFileA;
+    PCMFile _outFileB;
+
+    PCMFile _outFileRefA;
+    PCMFile _outFileRefB;
+
+    DTMFDetector* _dtmfDetectorA;
+    DTMFDetector* _dtmfDetectorB;
+
+    int _testMode;
+};
+
+
+#endif
diff --git a/src/modules/audio_coding/main/test/iSACTest.cpp b/src/modules/audio_coding/main/test/iSACTest.cpp
new file mode 100644
index 0000000..b1c0119
--- /dev/null
+++ b/src/modules/audio_coding/main/test/iSACTest.cpp
@@ -0,0 +1,597 @@
+/*
+ *  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 <cctype>
+#include <stdio.h>
+#include <string.h>
+
+#if _WIN32
+#include <windows.h>
+#elif WEBRTC_LINUX
+#include <ctime>
+#else
+#include <sys/time.h>
+#include <time.h>
+#endif 
+
+#include "event_wrapper.h"
+#include "iSACTest.h"
+#include "utility.h"
+#include "trace.h"
+
+#include "tick_util.h"
+
+
+void SetISACConfigDefault(
+    ACMTestISACConfig& isacConfig)
+{
+    isacConfig.currentRateBitPerSec = 0;
+    isacConfig.currentFrameSizeMsec = 0;
+    isacConfig.maxRateBitPerSec     = 0;
+    isacConfig.maxPayloadSizeByte   = 0;
+    isacConfig.encodingMode         = -1;
+    isacConfig.initRateBitPerSec    = 0;
+    isacConfig.initFrameSizeInMsec  = 0;
+    isacConfig.enforceFrameSize     = false;
+    return;
+}
+
+
+WebRtc_Word16 SetISAConfig(
+    ACMTestISACConfig& isacConfig,
+    AudioCodingModule* acm,
+    int testMode)
+{
+
+    if((isacConfig.currentRateBitPerSec != 0) ||
+        (isacConfig.currentFrameSizeMsec != 0))
+    {
+        CodecInst sendCodec;
+        acm->SendCodec(sendCodec);
+        if(isacConfig.currentRateBitPerSec < 0)
+        {
+            sendCodec.rate = -1;
+            CHECK_ERROR(acm->RegisterSendCodec(sendCodec));
+            if(testMode != 0)
+            {
+                printf("ISAC-%s Registered in adaptive (channel-dependent) mode.\n", 
+                    (sendCodec.plfreq == 32000)? "swb":"wb");
+            }
+        }
+        else
+        {
+
+            if(isacConfig.currentRateBitPerSec != 0)
+            {
+                sendCodec.rate = isacConfig.currentRateBitPerSec;
+            }
+            if(isacConfig.currentFrameSizeMsec != 0)
+            {
+                sendCodec.pacsize = isacConfig.currentFrameSizeMsec *
+                    (sendCodec.plfreq / 1000);
+            }
+            CHECK_ERROR(acm->RegisterSendCodec(sendCodec));
+            if(testMode != 0)
+            {
+                printf("Target rate is set to %d bit/sec with frame-size %d ms \n",
+                    (int)isacConfig.currentRateBitPerSec,
+                    (int)sendCodec.pacsize / (sendCodec.plfreq / 1000));
+            }
+        }
+    }
+
+    if(isacConfig.maxRateBitPerSec > 0)
+    {
+        CHECK_ERROR(acm->SetISACMaxRate(isacConfig.maxRateBitPerSec));
+        if(testMode != 0)
+        {
+            printf("Max rate is set to %u bit/sec\n",
+                isacConfig.maxRateBitPerSec);
+        }
+    }
+    if(isacConfig.maxPayloadSizeByte > 0)
+    {
+        CHECK_ERROR(acm->SetISACMaxPayloadSize(isacConfig.maxPayloadSizeByte));
+        if(testMode != 0)
+        {
+            printf("Max payload-size is set to %u bit/sec\n",
+                isacConfig.maxPayloadSizeByte);
+        }
+    }
+    if((isacConfig.initFrameSizeInMsec != 0) ||
+        (isacConfig.initRateBitPerSec != 0))
+    {
+        CHECK_ERROR(acm->ConfigISACBandwidthEstimator(
+            (WebRtc_UWord8)isacConfig.initFrameSizeInMsec,
+            (WebRtc_UWord16)isacConfig.initRateBitPerSec, 
+            isacConfig.enforceFrameSize));
+        if((isacConfig.initFrameSizeInMsec != 0) && (testMode != 0))
+        {
+            printf("Initialize BWE to %d msec frame-size\n",
+                isacConfig.initFrameSizeInMsec);
+        }
+        if((isacConfig.initRateBitPerSec != 0) && (testMode != 0))
+        {
+            printf("Initialize BWE to %u bit/sec send-bandwidth\n",
+                isacConfig.initRateBitPerSec);
+        }
+    }
+
+    return 0;
+}
+
+
+ISACTest::ISACTest(int testMode)
+{
+    _testMode = testMode;
+}
+
+ISACTest::~ISACTest()
+{
+    AudioCodingModule::Destroy(_acmA);
+    AudioCodingModule::Destroy(_acmB);
+
+    delete _channel_A2B;
+    delete _channel_B2A;
+}
+
+
+WebRtc_Word16
+ISACTest::Setup()
+{
+    int codecCntr;
+    CodecInst codecParam;
+
+    _acmA = AudioCodingModule::Create(1);
+    _acmB = AudioCodingModule::Create(2);
+
+    for(codecCntr = 0; codecCntr < AudioCodingModule::NumberOfCodecs(); codecCntr++)
+    {
+        AudioCodingModule::Codec(codecCntr, codecParam);
+        if(!STR_CASE_CMP(codecParam.plname, "ISAC") && codecParam.plfreq == 16000)
+        {
+            memcpy(&_paramISAC16kHz, &codecParam, sizeof(CodecInst));
+            _idISAC16kHz = codecCntr;
+        }
+        if(!STR_CASE_CMP(codecParam.plname, "ISAC") && codecParam.plfreq == 32000)
+        {
+            memcpy(&_paramISAC32kHz, &codecParam, sizeof(CodecInst));
+            _idISAC32kHz = codecCntr;
+        }        
+    }
+
+    // register both iSAC-wb & iSAC-swb in both sides as receiver codecs
+    CHECK_ERROR(_acmA->RegisterReceiveCodec(_paramISAC16kHz));
+    CHECK_ERROR(_acmA->RegisterReceiveCodec(_paramISAC32kHz));
+    CHECK_ERROR(_acmB->RegisterReceiveCodec(_paramISAC16kHz));
+    CHECK_ERROR(_acmB->RegisterReceiveCodec(_paramISAC32kHz));
+
+    //--- Set A-to-B channel
+    _channel_A2B = new Channel;
+    CHECK_ERROR(_acmA->RegisterTransportCallback(_channel_A2B));
+    _channel_A2B->RegisterReceiverACM(_acmB);
+
+    //--- Set B-to-A channel
+    _channel_B2A = new Channel;
+    CHECK_ERROR(_acmB->RegisterTransportCallback(_channel_B2A));
+    _channel_B2A->RegisterReceiverACM(_acmA);
+
+    strncpy(_fileNameSWB, "./modules/audio_coding/main/test/testfile32kHz.pcm",
+            MAX_FILE_NAME_LENGTH_BYTE);
+
+    _acmB->RegisterSendCodec(_paramISAC16kHz);
+    _acmA->RegisterSendCodec(_paramISAC32kHz);
+
+    if(_testMode != 0)
+    {
+        printf("Side A Send Codec\n");
+        printf("%s %d\n", _paramISAC32kHz.plname, _paramISAC32kHz.plfreq);
+
+        printf("Side B Send Codec\n");
+        printf("%s %d\n", _paramISAC16kHz.plname, _paramISAC16kHz.plfreq);
+    }
+
+    _inFileA.Open(_fileNameSWB, 32000, "rb");
+    if(_testMode == 0)
+    {
+        char fileNameA[] = "./modules/audio_coding/main/test/res_autotests/testisac_a.pcm";
+        char fileNameB[] = "./modules/audio_coding/main/test/res_autotests/testisac_b.pcm";
+        _outFileA.Open(fileNameA, 32000, "wb");
+        _outFileB.Open(fileNameB, 32000, "wb");
+    }
+    else
+    {
+        char fileNameA[] = "./modules/audio_coding/main/test/res_tests/testisac_a.pcm";
+        char fileNameB[] = "./modules/audio_coding/main/test/res_tests/testisac_b.pcm";
+        _outFileA.Open(fileNameA, 32000, "wb");
+        _outFileB.Open(fileNameB, 32000, "wb");
+    }
+
+    while(!_inFileA.EndOfFile())
+    {
+        Run10ms();
+    }
+    CodecInst receiveCodec;
+    CHECK_ERROR(_acmA->ReceiveCodec(receiveCodec));
+    if(_testMode != 0)
+    {
+        printf("Side A Receive Codec\n");
+        printf("%s %d\n", receiveCodec.plname, receiveCodec.plfreq);
+    }
+
+    CHECK_ERROR(_acmB->ReceiveCodec(receiveCodec));
+    if(_testMode != 0)
+    {
+        printf("Side B Receive Codec\n");
+        printf("%s %d\n", receiveCodec.plname, receiveCodec.plfreq);
+    }
+
+    _inFileA.Close();
+    _outFileA.Close();
+    _outFileB.Close();
+
+    return 0;
+}
+
+
+void
+ISACTest::Perform()
+{
+    if(_testMode == 0)
+    {
+        printf("Running iSAC Test");
+        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- iSACTest ----------");
+    }
+
+    Setup();
+
+    WebRtc_Word16 testNr = 0;
+    ACMTestISACConfig wbISACConfig;
+    ACMTestISACConfig swbISACConfig;
+
+    SetISACConfigDefault(wbISACConfig);
+    SetISACConfigDefault(swbISACConfig);
+
+    wbISACConfig.currentRateBitPerSec = -1;
+    swbISACConfig.currentRateBitPerSec = -1;
+    testNr++;
+    EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+
+    if (_testMode != 0)
+    {
+        SetISACConfigDefault(wbISACConfig);
+        SetISACConfigDefault(swbISACConfig);
+
+        wbISACConfig.currentRateBitPerSec = -1;
+        swbISACConfig.currentRateBitPerSec = -1;
+        wbISACConfig.initRateBitPerSec = 13000;
+        wbISACConfig.initFrameSizeInMsec = 60;
+        swbISACConfig.initRateBitPerSec = 20000;
+        swbISACConfig.initFrameSizeInMsec = 30;
+        testNr++;
+        EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+
+        SetISACConfigDefault(wbISACConfig);
+        SetISACConfigDefault(swbISACConfig);
+
+        wbISACConfig.currentRateBitPerSec = 20000;
+        swbISACConfig.currentRateBitPerSec = 48000;
+        testNr++;
+        EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+
+        wbISACConfig.currentRateBitPerSec = 16000;
+        swbISACConfig.currentRateBitPerSec = 30000;
+        wbISACConfig.currentFrameSizeMsec = 60;
+        testNr++;
+        EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+    }
+
+    SetISACConfigDefault(wbISACConfig);
+    SetISACConfigDefault(swbISACConfig);
+    testNr++;
+    EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+    
+    int dummy;
+    if((_testMode == 0) || (_testMode == 1))
+    {
+        swbISACConfig.maxPayloadSizeByte = (WebRtc_UWord16)200;
+        wbISACConfig.maxPayloadSizeByte = (WebRtc_UWord16)200;
+    }
+    else
+    {
+        printf("Enter the max payload-size for side A: ");
+        scanf("%d", &dummy);
+        swbISACConfig.maxPayloadSizeByte = (WebRtc_UWord16)dummy;
+        printf("Enter the max payload-size for side B: ");
+        scanf("%d", &dummy);
+        wbISACConfig.maxPayloadSizeByte = (WebRtc_UWord16)dummy;
+    }
+    testNr++;
+    EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+
+    _acmA->ResetEncoder();
+    _acmB->ResetEncoder();
+    SetISACConfigDefault(wbISACConfig);
+    SetISACConfigDefault(swbISACConfig);
+
+    if((_testMode == 0) || (_testMode == 1))
+    {
+        swbISACConfig.maxRateBitPerSec = (WebRtc_UWord32)48000;
+        wbISACConfig.maxRateBitPerSec = (WebRtc_UWord32)48000;
+    }
+    else
+    {
+        printf("Enter the max rate for side A: ");
+        scanf("%d", &dummy);
+        swbISACConfig.maxRateBitPerSec = (WebRtc_UWord32)dummy;
+        printf("Enter the max rate for side B: ");
+        scanf("%d", &dummy);
+        wbISACConfig.maxRateBitPerSec = (WebRtc_UWord32)dummy;
+    }
+ 
+    testNr++;
+    EncodeDecode(testNr, wbISACConfig, swbISACConfig);
+
+
+    testNr++;
+    if(_testMode == 0)
+    {
+        SwitchingSamplingRate(testNr, 4);
+        printf("Done!\n");
+    }
+    else
+    {
+        SwitchingSamplingRate(testNr, 80);
+    }
+}
+
+
+void
+ISACTest::Run10ms()
+{
+    AudioFrame audioFrame;
+
+    _inFileA.Read10MsData(audioFrame);
+    CHECK_ERROR(_acmA->Add10MsData(audioFrame));
+
+    CHECK_ERROR(_acmB->Add10MsData(audioFrame));
+
+    CHECK_ERROR(_acmA->Process());
+    CHECK_ERROR(_acmB->Process());
+
+    CHECK_ERROR(_acmA->PlayoutData10Ms(32000, audioFrame));
+    _outFileA.Write10MsData(audioFrame);
+
+    CHECK_ERROR(_acmB->PlayoutData10Ms(32000, audioFrame));
+    _outFileB.Write10MsData(audioFrame);
+}
+
+void
+ISACTest::EncodeDecode(
+    int                testNr,
+    ACMTestISACConfig& wbISACConfig,
+    ACMTestISACConfig& swbISACConfig)
+{
+    if(_testMode == 0)
+    {
+        printf(".");
+    }
+    else
+    {
+        printf("\nTest %d:\n\n", testNr);
+    }
+    char fileNameOut[MAX_FILE_NAME_LENGTH_BYTE];
+
+    // Files in Side A 
+    _inFileA.Open(_fileNameSWB, 32000, "rb", true);
+    if(_testMode == 0)
+    {
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_autotests/out_iSACTest_%s_%02d.pcm",
+                "A",
+                testNr);
+    }
+    else
+    {
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_tests/out%s_%02d.pcm",
+                "A",
+                testNr);
+    }
+    _outFileA.Open(fileNameOut, 32000, "wb");
+
+    // Files in Side B
+    _inFileB.Open(_fileNameSWB, 32000, "rb", true);
+    if(_testMode == 0)
+    {
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_autotests/out_iSACTest_%s_%02d.pcm",
+                "B",
+                testNr);
+    }
+    else
+    {
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_tests/out%s_%02d.pcm",
+                "B",
+                testNr);
+    }
+    _outFileB.Open(fileNameOut, 32000, "wb");
+    
+    CHECK_ERROR(_acmA->RegisterSendCodec(_paramISAC16kHz));
+    CHECK_ERROR(_acmA->RegisterSendCodec(_paramISAC32kHz));
+    
+    CHECK_ERROR(_acmB->RegisterSendCodec(_paramISAC32kHz));
+    CHECK_ERROR(_acmB->RegisterSendCodec(_paramISAC16kHz));
+    if(_testMode != 0)
+    {
+        printf("Side A Sending Super-Wideband \n");
+        printf("Side B Sending Wideband\n\n");
+    }
+
+    SetISAConfig(swbISACConfig, _acmA, _testMode);
+    SetISAConfig(wbISACConfig,  _acmB, _testMode);
+
+    bool adaptiveMode = false;
+    if((swbISACConfig.currentRateBitPerSec == -1) ||
+        (wbISACConfig.currentRateBitPerSec == -1))
+    {
+        adaptiveMode = true;
+    }
+    _myTimer.Reset();
+    _channel_A2B->ResetStats();
+    _channel_B2A->ResetStats();
+
+    char currentTime[500];
+    if(_testMode == 2) printf("\n");
+    CodecInst sendCodec;
+    EventWrapper* myEvent = EventWrapper::Create();
+    myEvent->StartTimer(true, 10);
+    while(!(_inFileA.EndOfFile() || _inFileA.Rewinded()))
+    {
+        Run10ms();
+        _myTimer.Tick10ms();
+        _myTimer.CurrentTimeHMS(currentTime);
+        if(_testMode == 2) printf("\r%s   ", currentTime);
+
+        if((adaptiveMode) && (_testMode != 0))
+        {
+            myEvent->Wait(5000);
+
+            _acmA->SendCodec(sendCodec);
+            if(_testMode == 2) printf("[%d]  ", sendCodec.rate);
+            _acmB->SendCodec(sendCodec);
+            if(_testMode == 2) printf("[%d]  ", sendCodec.rate);
+        }
+    }
+
+    if(_testMode != 0)
+    {
+        printf("\n\nSide A statistics\n\n");
+        _channel_A2B->PrintStats(_paramISAC32kHz);
+
+        printf("\n\nSide B statistics\n\n");
+        _channel_B2A->PrintStats(_paramISAC16kHz);
+    }
+    
+    _channel_A2B->ResetStats();
+    _channel_B2A->ResetStats();
+
+    if(_testMode != 0) printf("\n");
+    _outFileA.Close();
+    _outFileB.Close();
+    _inFileA.Close();
+    _inFileB.Close();
+}
+
+void
+ISACTest::SwitchingSamplingRate(
+    int testNr, 
+    int maxSampRateChange)
+{
+    char fileNameOut[MAX_FILE_NAME_LENGTH_BYTE];
+        
+    // Files in Side A 
+    _inFileA.Open(_fileNameSWB, 32000, "rb");
+    if(_testMode == 0)
+    {
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_autotests/out_iSACTest_%s_%02d.pcm",
+                "A",
+                testNr);
+    }
+    else
+    {
+        printf("\nTest %d", testNr);
+        printf("    Alternate between WB and SWB at the sender Side\n\n");
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_tests/out%s_%02d.pcm",
+                "A",
+                testNr);
+    }
+    _outFileA.Open(fileNameOut, 32000, "wb", true);
+    
+    // Files in Side B
+    _inFileB.Open(_fileNameSWB, 32000, "rb");
+    if(_testMode == 0)
+    {
+        sprintf(fileNameOut,
+                "./modules/audio_coding/main/test/res_autotests/out_iSACTest_%s_%02d.pcm",
+                "B",
+                testNr);
+    }
+    else
+    {
+        sprintf(fileNameOut, "./modules/audio_coding/main/test/res_tests/out%s_%02d.pcm",
+                "B",
+                testNr);
+    }
+    _outFileB.Open(fileNameOut, 32000, "wb", true);
+
+    CHECK_ERROR(_acmA->RegisterSendCodec(_paramISAC32kHz));
+    CHECK_ERROR(_acmB->RegisterSendCodec(_paramISAC16kHz));
+    if(_testMode != 0)
+    {
+        printf("Side A Sending Super-Wideband \n");
+        printf("Side B Sending Wideband\n");
+    }
+
+    int numSendCodecChanged = 0;
+    _myTimer.Reset();
+    char currentTime[50];
+    while(numSendCodecChanged < (maxSampRateChange<<1))
+    {
+        Run10ms();
+        _myTimer.Tick10ms();
+        _myTimer.CurrentTimeHMS(currentTime);
+        if(_testMode == 2) printf("\r%s", currentTime);
+        if(_inFileA.EndOfFile())
+        {
+            if(_inFileA.SamplingFrequency() == 16000)
+            {
+                if(_testMode != 0) printf("\nSide A switched to Send Super-Wideband\n");
+                _inFileA.Close();
+                _inFileA.Open(_fileNameSWB, 32000, "rb");
+                CHECK_ERROR(_acmA->RegisterSendCodec(_paramISAC32kHz));
+            }
+            else
+            {
+                if(_testMode != 0) printf("\nSide A switched to Send Wideband\n");
+                _inFileA.Close();
+                _inFileA.Open(_fileNameSWB, 32000, "rb");
+                CHECK_ERROR(_acmA->RegisterSendCodec(_paramISAC16kHz));
+            }
+            numSendCodecChanged++;
+        }
+
+        if(_inFileB.EndOfFile())
+        {
+            if(_inFileB.SamplingFrequency() == 16000)
+            {
+                if(_testMode != 0) printf("\nSide B switched to Send Super-Wideband\n");
+                _inFileB.Close();
+                _inFileB.Open(_fileNameSWB, 32000, "rb");
+                CHECK_ERROR(_acmB->RegisterSendCodec(_paramISAC32kHz));
+            }
+            else
+            {
+                if(_testMode != 0) printf("\nSide B switched to Send Wideband\n");
+                _inFileB.Close();
+                _inFileB.Open(_fileNameSWB, 32000, "rb");
+                CHECK_ERROR(_acmB->RegisterSendCodec(_paramISAC16kHz));
+            }
+            numSendCodecChanged++;
+        }
+    }
+    _outFileA.Close();
+    _outFileB.Close();
+    _inFileA.Close();
+    _inFileB.Close();
+}
diff --git a/src/modules/audio_coding/main/test/iSACTest.h b/src/modules/audio_coding/main/test/iSACTest.h
new file mode 100644
index 0000000..c6d4b9c
--- /dev/null
+++ b/src/modules/audio_coding/main/test/iSACTest.h
@@ -0,0 +1,100 @@
+/*
+ *  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 ACM_ISAC_TEST_H
+#define ACM_ISAC_TEST_H
+
+#include "ACMTest.h"
+#include "Channel.h"
+#include "PCMFile.h"
+#include "audio_coding_module.h"
+#include "utility.h"
+#include "common_types.h"
+
+#define MAX_FILE_NAME_LENGTH_BYTE 500
+#define NO_OF_CLIENTS             15
+
+struct ACMTestISACConfig
+{
+    WebRtc_Word32  currentRateBitPerSec;
+    WebRtc_Word16  currentFrameSizeMsec;
+    WebRtc_UWord32 maxRateBitPerSec;
+    WebRtc_Word16  maxPayloadSizeByte;
+    WebRtc_Word16  encodingMode;
+    WebRtc_UWord32 initRateBitPerSec;
+    WebRtc_Word16  initFrameSizeInMsec;
+    bool           enforceFrameSize;
+};
+
+
+
+class ISACTest : public ACMTest
+{
+public:
+    ISACTest(int testMode);
+    ~ISACTest();
+
+    void Perform();
+private:
+    WebRtc_Word16 Setup();
+    WebRtc_Word16 SetupConference();
+    WebRtc_Word16 RunConference();    
+    
+
+    void Run10ms();
+
+    void EncodeDecode(
+        int                testNr,
+        ACMTestISACConfig& wbISACConfig,
+        ACMTestISACConfig& swbISACConfig);
+    
+    void TestBWE(
+        int testNr);
+
+    void SwitchingSamplingRate(
+        int testNr, 
+        int maxSampRateChange);
+
+    AudioCodingModule* _acmA;
+    AudioCodingModule* _acmB;
+
+    Channel* _channel_A2B;
+    Channel* _channel_B2A;
+
+    PCMFile _inFileA;
+    PCMFile _inFileB;
+
+    PCMFile _outFileA;
+    PCMFile _outFileB;
+
+    WebRtc_UWord8 _idISAC16kHz;
+    WebRtc_UWord8 _idISAC32kHz;
+    CodecInst _paramISAC16kHz;
+    CodecInst _paramISAC32kHz;
+
+    char _fileNameWB[MAX_FILE_NAME_LENGTH_BYTE];
+    char _fileNameSWB[MAX_FILE_NAME_LENGTH_BYTE];
+
+    ACMTestTimer _myTimer;
+    int _testMode;
+    
+    AudioCodingModule* _defaultACM32;
+    AudioCodingModule* _defaultACM16;
+    
+    AudioCodingModule* _confACM[NO_OF_CLIENTS];
+    AudioCodingModule* _clientACM[NO_OF_CLIENTS];
+    Channel*               _conf2Client[NO_OF_CLIENTS];
+    Channel*               _client2Conf[NO_OF_CLIENTS];
+
+    PCMFile                _clientOutFile[NO_OF_CLIENTS];
+};
+
+
+#endif
diff --git a/src/modules/audio_coding/main/test/utility.cpp b/src/modules/audio_coding/main/test/utility.cpp
new file mode 100644
index 0000000..c654019
--- /dev/null
+++ b/src/modules/audio_coding/main/test/utility.cpp
@@ -0,0 +1,431 @@
+/*
+ *  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 "utility.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#include "audio_coding_module.h"
+#include "common_types.h"
+
+
+#define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13
+
+
+ACMTestTimer::ACMTestTimer() :
+_msec(0),
+_sec(0),
+_min(0),
+_hour(0)
+{
+    return;
+}
+
+ACMTestTimer::~ACMTestTimer()
+{
+    return;
+}
+
+void ACMTestTimer::Reset()
+{
+    _msec = 0;
+    _sec = 0;
+    _min = 0;
+    _hour = 0;
+    return;
+}
+void ACMTestTimer::Tick10ms()
+{
+    _msec += 10;
+    Adjust();
+    return;
+}
+
+void ACMTestTimer::Tick1ms()
+{
+    _msec++;
+    Adjust();
+    return;
+}
+
+void ACMTestTimer::Tick100ms()
+{
+    _msec += 100;
+    Adjust();
+    return;
+}
+
+void ACMTestTimer::Tick1sec()
+{
+    _sec++;
+    Adjust();
+    return;
+}
+
+void ACMTestTimer::CurrentTimeHMS(char* currTime)
+{
+    sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min, (double)_sec + (double)_msec / 1000.); 
+    return;
+}
+
+void ACMTestTimer::CurrentTime(
+        unsigned long&  h, 
+        unsigned char&  m,
+        unsigned char&  s,
+        unsigned short& ms)
+{
+    h = _hour;
+    m = _min;
+    s = _sec;
+    ms = _msec;
+    return;
+}
+
+void ACMTestTimer::Adjust()
+{
+    unsigned int n;
+    if(_msec >= 1000)
+    {
+        n = _msec / 1000;
+        _msec -= (1000 * n);
+        _sec += n;
+    }
+    if(_sec >= 60)
+    {
+        n = _sec / 60;
+        _sec -= (n * 60);
+        _min += n;
+    }
+    if(_min >= 60)
+    {
+        n = _min / 60;
+        _min -= (n * 60);
+        _hour += n;
+    }
+}
+
+
+WebRtc_Word16
+ChooseCodec(
+    CodecInst& codecInst)
+{
+
+    PrintCodecs();
+    //AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
+    WebRtc_UWord8 noCodec = AudioCodingModule::NumberOfCodecs();
+    WebRtc_Word8 codecID;
+    bool outOfRange = false;
+    char myStr[15] = "";
+    do
+    {
+        printf("\nChoose a codec [0]: ");
+        fgets(myStr, 10, stdin);
+        codecID = atoi(myStr);
+        if((codecID < 0) || (codecID >= noCodec))
+        {
+            printf("\nOut of range.\n");
+            outOfRange = true;
+        }
+    } while(outOfRange);
+
+    CHECK_ERROR(AudioCodingModule::Codec((WebRtc_UWord8)codecID, codecInst));
+    return 0;
+}
+
+void
+PrintCodecs()
+{
+    WebRtc_UWord8 noCodec = AudioCodingModule::NumberOfCodecs();
+        
+    CodecInst codecInst;
+    printf("No  Name                [Hz]    [bps]\n");     
+    for(WebRtc_UWord8 codecCntr = 0; codecCntr < noCodec; codecCntr++)
+    {
+        AudioCodingModule::Codec(codecCntr, codecInst);
+        printf("%2d- %-18s %5d   %6d\n", 
+            codecCntr, codecInst.plname, codecInst.plfreq, codecInst.rate);
+    }
+
+}
+
+CircularBuffer::CircularBuffer(WebRtc_UWord32 len):
+_buffIsFull(false),
+_calcAvg(false),
+_calcVar(false),
+_sum(0),
+_sumSqr(0),
+_idx(0),
+_buff(NULL)
+{
+    _buff = new(double[len]);
+    if(_buff == NULL)
+    {
+        _buffLen = 0;
+    }
+    else
+    {
+        for(WebRtc_UWord32 n = 0; n < len; n++)
+        {
+            _buff[n] = 0;
+        }
+        _buffLen = len;
+    }
+}
+
+CircularBuffer::~CircularBuffer()
+{
+    if(_buff != NULL)
+    {
+        delete [] _buff;
+        _buff = NULL;
+    }
+}
+
+void
+CircularBuffer::Update(
+    const double newVal)
+{
+    assert(_buffLen > 0);
+    
+    // store the value that is going to be overwritten
+    double oldVal = _buff[_idx];
+    // record the new value
+    _buff[_idx] = newVal;
+    // increment the index, to point to where we would
+    // write next
+    _idx++;
+    // it is a circular buffer, if we are at the end
+    // we have to cycle to the beginning 
+    if(_idx >= _buffLen)
+    {
+        // flag that the buffer is filled up.
+        _buffIsFull = true;
+        _idx = 0;
+    }
+    
+    // Update 
+
+    if(_calcAvg)
+    {
+        // for the average we have to update
+        // the sum
+        _sum += (newVal - oldVal);
+    }
+
+    if(_calcVar)
+    {
+        // to calculate variance we have to update
+        // the sum of squares 
+        _sumSqr += (double)(newVal - oldVal) * (double)(newVal + oldVal);
+    }
+}
+
+void 
+CircularBuffer::SetArithMean(
+    bool enable)
+{
+    assert(_buffLen > 0);
+
+    if(enable && !_calcAvg)
+    {
+        WebRtc_UWord32 lim;
+        if(_buffIsFull)
+        {
+            lim = _buffLen;
+        }
+        else
+        {
+            lim = _idx;
+        }
+        _sum = 0;
+        for(WebRtc_UWord32 n = 0; n < lim; n++)
+        {
+            _sum += _buff[n];
+        }
+    }
+    _calcAvg = enable;
+}
+
+void
+CircularBuffer::SetVariance(
+    bool enable)
+{
+    assert(_buffLen > 0);
+
+    if(enable && !_calcVar)
+    {
+        WebRtc_UWord32 lim;
+        if(_buffIsFull)
+        {
+            lim = _buffLen;
+        }
+        else
+        {
+            lim = _idx;
+        }
+        _sumSqr = 0;
+        for(WebRtc_UWord32 n = 0; n < lim; n++)
+        {
+            _sumSqr += _buff[n] * _buff[n];
+        }
+    }
+    _calcAvg = enable;
+}
+
+WebRtc_Word16
+CircularBuffer::ArithMean(double& mean)
+{
+    assert(_buffLen > 0);
+
+    if(_buffIsFull)
+    {
+
+        mean = _sum / (double)_buffLen;
+        return 0;
+    }
+    else
+    {
+        if(_idx > 0)
+        {
+            mean = _sum / (double)_idx;
+            return 0;
+        }
+        else
+        {
+            return -1;
+        }
+
+    }
+}
+
+WebRtc_Word16
+CircularBuffer::Variance(double& var)
+{
+    assert(_buffLen > 0);
+
+    if(_buffIsFull)
+    {
+        var = _sumSqr / (double)_buffLen;
+        return 0;
+    }
+    else
+    {
+        if(_idx > 0)
+        {
+            var = _sumSqr / (double)_idx;
+            return 0;
+        }
+        else
+        {
+            return -1;
+        }
+    }
+}
+
+
+
+bool
+FixedPayloadTypeCodec(const char* payloadName)
+{
+    char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = {
+        "PCMU",
+        "PCMA",
+        "GSM",
+        "G723",
+        "DVI4",
+        "LPC",
+        "PCMA",
+        "G722",
+        "QCELP",
+        "CN",
+        "MPA",
+        "G728",
+        "G729"
+    };
+
+    for(int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++)
+    {
+        if(!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n]))
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+DTMFDetector::DTMFDetector()
+{
+    for(WebRtc_Word16 n = 0; n < 1000; n++)
+    {
+        _toneCntr[n] = 0;
+    }
+}
+
+DTMFDetector::~DTMFDetector()
+{
+}
+
+WebRtc_Word32 DTMFDetector::IncomingDtmf(const WebRtc_UWord8 digitDtmf, const bool /* toneEnded */)
+{
+    fprintf(stdout, "%d-",digitDtmf);
+    _toneCntr[digitDtmf]++;
+    return 0;
+}
+
+void DTMFDetector::PrintDetectedDigits()
+{
+    for(WebRtc_Word16 n = 0; n < 1000; n++)
+    {
+        if(_toneCntr[n] > 0)
+        {
+            fprintf(stdout, "%d %u  msec, \n", n, _toneCntr[n]*10);
+        }
+    }
+    fprintf(stdout, "\n");
+    return;
+}
+
+void 
+VADCallback::Reset()
+{
+    for(int n = 0; n < 6; n++)
+    {
+        _numFrameTypes[n] = 0;
+    }
+}
+
+VADCallback::VADCallback()
+{
+    for(int n = 0; n < 6; n++)
+    {
+        _numFrameTypes[n] = 0;
+    }
+}
+
+void
+VADCallback::PrintFrameTypes()
+{
+    fprintf(stdout, "No encoding.................. %d\n", _numFrameTypes[0]);
+    fprintf(stdout, "Active normal encoded........ %d\n", _numFrameTypes[1]);
+    fprintf(stdout, "Passive normal encoded....... %d\n", _numFrameTypes[2]);
+    fprintf(stdout, "Passive DTX wideband......... %d\n", _numFrameTypes[3]);
+    fprintf(stdout, "Passive DTX narrowband....... %d\n", _numFrameTypes[4]);
+    fprintf(stdout, "Passive DTX super-wideband... %d\n", _numFrameTypes[5]);
+}
+
+WebRtc_Word32 
+VADCallback::InFrameType(
+    WebRtc_Word16 frameType)
+{
+    _numFrameTypes[frameType]++;
+    return 0;
+}
diff --git a/src/modules/audio_coding/main/test/utility.h b/src/modules/audio_coding/main/test/utility.h
new file mode 100644
index 0000000..b25de44
--- /dev/null
+++ b/src/modules/audio_coding/main/test/utility.h
@@ -0,0 +1,202 @@
+/*
+ *  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 ACM_TEST_UTILITY_H
+#define ACM_TEST_UTILITY_H
+
+#include "audio_coding_module.h"
+
+//-----------------------------
+#define CHECK_ERROR(f)                                                                      \
+    do {                                                                                    \
+        if(f < 0) {                                                                         \
+            char errString[500];                                                            \
+            sprintf(errString, "Error Calling API in file %s at line %d \n",                \
+                __FILE__, __LINE__);                                                        \
+            throw errString;                                                                \
+        }                                                                                   \
+    }while(0)
+
+//-----------------------------
+#define CHECK_PROTECTED(f)                                                                  \
+    do {                                                                                    \
+        if(f >= 0) {                                                                        \
+            char errString[500];                                                            \
+            sprintf(errString, "Error Calling API in file %s at line %d \n",                \
+                __FILE__, __LINE__);                                                        \
+            throw errString;                                                                \
+        }                                                                                   \
+        else {                                                                              \
+            printf("An expected error is caught.\n");                                       \
+        }                                                                                   \
+    }while(0)
+
+//----------------------------
+#define CHECK_ERROR_MT(f)                                                                   \
+    do {                                                                                    \
+        if(f < 0) {                                                                         \
+            fprintf(stderr, "Error Calling API in file %s at line %d \n",                   \
+                __FILE__, __LINE__);                                                        \
+        }                                                                                   \
+    }while(0)
+
+//----------------------------
+#define CHECK_PROTECTED_MT(f)                                                               \
+    do {                                                                                    \
+        if(f >= 0) {                                                                        \
+            fprintf(stderr, "Error Calling API in file %s at line %d \n",                   \
+                __FILE__, __LINE__);                                                        \
+        }                                                                                   \
+        else {                                                                              \
+            printf("An expected error is caught.\n");                                       \
+        }                                                                                   \
+    }while(0)
+
+
+
+#ifdef WIN32
+    /* Exclude rarely-used stuff from Windows headers */
+    //#define WIN32_LEAN_AND_MEAN 
+    /* OS-dependent case-insensitive string comparison */
+    #define STR_CASE_CMP(x,y) ::_stricmp(x,y)
+#else
+    /* OS-dependent case-insensitive string comparison */
+    #define STR_CASE_CMP(x,y) ::strcasecmp(x,y)
+#endif
+
+#define DESTROY_ACM(acm)                                                                    \
+    do {                                                                                    \
+        if(acm != NULL) {                                                                   \
+            AudioCodingModule::Destroy(acm);                       \
+            acm = NULL;                                                                     \
+        }                                                                                   \
+    } while(0)
+
+
+#define DELETE_POINTER(p)                                                                   \
+    do {                                                                                    \
+        if(p != NULL) {                                                                     \
+            delete p;                                                                       \
+            p = NULL;                                                                       \
+        }                                                                                   \
+    } while(0)
+
+using namespace webrtc;
+
+class ACMTestTimer
+{
+public:
+    ACMTestTimer();
+    ~ACMTestTimer();
+
+    void Reset();
+    void Tick10ms();
+    void Tick1ms();
+    void Tick100ms();
+    void Tick1sec();
+    void CurrentTimeHMS(
+        char* currTime);
+    void CurrentTime(
+        unsigned long&  h, 
+        unsigned char&  m,
+        unsigned char&  s,
+        unsigned short& ms);
+
+private:
+    void Adjust();
+
+    unsigned short _msec;
+    unsigned char  _sec;
+    unsigned char  _min;
+    unsigned long  _hour;  
+};
+
+
+
+class CircularBuffer
+{
+public:
+    CircularBuffer(WebRtc_UWord32 len);
+    ~CircularBuffer();
+
+    void SetArithMean(
+        bool enable);
+    void SetVariance(
+        bool enable);
+
+    void Update(
+        const double newVal);
+    void IsBufferFull();
+    
+    WebRtc_Word16 Variance(double& var);
+    WebRtc_Word16 ArithMean(double& mean);
+
+protected:
+    double* _buff;
+    WebRtc_UWord32 _idx;
+    WebRtc_UWord32 _buffLen;
+
+    bool         _buffIsFull;
+    bool         _calcAvg;
+    bool         _calcVar;
+    double       _sum;
+    double       _sumSqr;
+};
+
+
+
+
+
+WebRtc_Word16 ChooseCodec(
+    CodecInst& codecInst);
+
+void PrintCodecs();
+
+bool FixedPayloadTypeCodec(const char* payloadName);
+
+
+
+
+class DTMFDetector: public AudioCodingFeedback
+{
+public:
+    DTMFDetector();
+    ~DTMFDetector();
+    // used for inband DTMF detection
+    WebRtc_Word32 IncomingDtmf(const WebRtc_UWord8 digitDtmf, const bool toneEnded);
+    void PrintDetectedDigits();
+
+private:
+    WebRtc_UWord32 _toneCntr[1000];
+
+};
+
+
+
+
+class VADCallback : public ACMVADCallback
+{
+public:
+    VADCallback();
+    ~VADCallback(){}
+
+    WebRtc_Word32 InFrameType(
+        WebRtc_Word16 frameType);
+
+    void PrintFrameTypes();
+    void Reset();
+
+private:
+    WebRtc_UWord32 _numFrameTypes[6];
+};
+
+
+
+#endif // ACM_TEST_UTILITY_H