Added support for 96 kHz sampling frequency.

Updated resampler_unittests with the new valid combinations.
Verified audio quality on files.

TEST=resampler_unittests, voe_auto_test
BUILDTYPE=Debug, Release
PLATFORM=Linux
Review URL: http://webrtc-codereview.appspot.com/294001

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1002 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/common_audio/resampler/include/resampler.h b/src/common_audio/resampler/include/resampler.h
index 41f1a87..38e6bd3 100644
--- a/src/common_audio/resampler/include/resampler.h
+++ b/src/common_audio/resampler/include/resampler.h
@@ -43,6 +43,7 @@
     kResamplerMode1To3,
     kResamplerMode1To4,
     kResamplerMode1To6,
+    kResamplerMode1To12,
     kResamplerMode2To3,
     kResamplerMode2To11,
     kResamplerMode4To11,
@@ -53,6 +54,7 @@
     kResamplerMode3To1,
     kResamplerMode4To1,
     kResamplerMode6To1,
+    kResamplerMode12To1,
     kResamplerMode3To2,
     kResamplerMode11To2,
     kResamplerMode11To4,
diff --git a/src/common_audio/resampler/resampler.cc b/src/common_audio/resampler/resampler.cc
index b175e27..2db27b1 100644
--- a/src/common_audio/resampler/resampler.cc
+++ b/src/common_audio/resampler/resampler.cc
@@ -209,6 +209,9 @@
             case 6:
                 my_mode_ = kResamplerMode1To6;
                 break;
+            case 12:
+                my_mode_ = kResamplerMode1To12;
+                break;
             default:
                 my_type_ = kResamplerInvalid;
                 return -1;
@@ -229,6 +232,9 @@
             case 6:
                 my_mode_ = kResamplerMode6To1;
                 break;
+            case 12:
+                my_mode_ = kResamplerMode12To1;
+                break;
             default:
                 my_type_ = kResamplerInvalid;
                 return -1;
@@ -299,6 +305,18 @@
             state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
             WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
             break;
+        case kResamplerMode1To12:
+            // 1:2
+            state1_ = malloc(8 * sizeof(WebRtc_Word32));
+            memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
+            // 2:4
+            state2_ = malloc(8 * sizeof(WebRtc_Word32));
+            memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
+            // 4:12
+            state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
+            WebRtcSpl_ResetResample16khzTo48khz(
+                (WebRtcSpl_State16khzTo48khz*) state3_);
+            break;
         case kResamplerMode2To3:
             // 2:6
             state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
@@ -367,6 +385,18 @@
             state2_ = malloc(8 * sizeof(WebRtc_Word32));
             memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
             break;
+        case kResamplerMode12To1:
+            // 12:4
+            state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
+            WebRtcSpl_ResetResample48khzTo16khz(
+                (WebRtcSpl_State48khzTo16khz*) state1_);
+            // 4:2
+            state2_ = malloc(8 * sizeof(WebRtc_Word32));
+            memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
+            // 2:1
+            state3_ = malloc(8 * sizeof(WebRtc_Word32));
+            memset(state3_, 0, 8 * sizeof(WebRtc_Word32));
+            break;
         case kResamplerMode3To2:
             // 3:6
             state1_ = malloc(8 * sizeof(WebRtc_Word32));
@@ -458,8 +488,9 @@
         return 0;
     }
 
-    // Container for temp samples
+    // Containers for temp samples
     WebRtc_Word16* tmp;
+    WebRtc_Word16* tmp_2;
     // tmp data for resampling routines
     WebRtc_Word32* tmp_mem;
 
@@ -545,6 +576,41 @@
             free(tmp);
 
             return 0;
+        case kResamplerMode1To12:
+            // We can only handle blocks of 40 samples
+            // Can be fixed, but I don't think it's needed
+            if ((lengthIn % 40) != 0) {
+              return -1;
+            }
+            if (maxLen < (lengthIn * 12)) {
+              return -1;
+            }
+
+            tmp_mem = (WebRtc_Word32*) malloc(336 * sizeof(WebRtc_Word32));
+            tmp = (WebRtc_Word16*) malloc(sizeof(WebRtc_Word16) * 4 * lengthIn);
+            //1:2
+            WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
+                                  (WebRtc_Word32*) state1_);
+            outLen = lengthIn * 2;
+            //2:4
+            WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp, (WebRtc_Word32*) state2_);
+            outLen = outLen * 2;
+            // 4:12
+            for (int i = 0; i < outLen; i += 160) {
+              // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples
+              // as input and outputs a resampled block of 480 samples. The
+              // data is now actually in 32 kHz sampling rate, despite the
+              // function name, and with a resampling factor of three becomes
+              // 96 kHz.
+              WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
+                                             (WebRtcSpl_State16khzTo48khz*) state3_,
+                                             tmp_mem);
+            }
+            outLen = outLen * 3;
+            free(tmp_mem);
+            free(tmp);
+
+            return 0;
         case kResamplerMode2To3:
             if (maxLen < (lengthIn * 3 / 2))
             {
@@ -783,6 +849,43 @@
             free(tmp);
             outLen = outLen / 2;
             return 0;
+        case kResamplerMode12To1:
+            // We can only handle blocks of 480 samples
+            // Can be fixed, but I don't think it's needed
+            if ((lengthIn % 480) != 0) {
+              return -1;
+            }
+            if (maxLen < (lengthIn / 12)) {
+              return -1;
+            }
+
+            tmp_mem = (WebRtc_Word32*) malloc(496 * sizeof(WebRtc_Word32));
+            tmp = (WebRtc_Word16*) malloc((sizeof(WebRtc_Word16) * lengthIn) / 3);
+            tmp_2 = (WebRtc_Word16*) malloc((sizeof(WebRtc_Word16) * lengthIn) / 6);
+            // 12:4
+            for (int i = 0; i < lengthIn; i += 480) {
+              // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples
+              // as input and outputs a resampled block of 160 samples. The
+              // data is now actually in 96 kHz sampling rate, despite the
+              // function name, and with a resampling factor of 1/3 becomes
+              // 32 kHz.
+              WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
+                                             (WebRtcSpl_State48khzTo16khz*) state1_,
+                                             tmp_mem);
+            }
+            outLen = lengthIn / 3;
+            free(tmp_mem);
+            // 4:2
+            WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2,
+                                    (WebRtc_Word32*) state2_);
+            outLen = outLen / 2;
+            free(tmp);
+            // 2:1
+            WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut,
+                                    (WebRtc_Word32*) state3_);
+            free(tmp_2);
+            outLen = outLen / 2;
+            return 0;
         case kResamplerMode3To2:
             if (maxLen < (lengthIn * 2 / 3))
             {
diff --git a/src/common_audio/resampler/resampler_unittest.cc b/src/common_audio/resampler/resampler_unittest.cc
index c0cd418..f50034d 100644
--- a/src/common_audio/resampler/resampler_unittest.cc
+++ b/src/common_audio/resampler/resampler_unittest.cc
@@ -42,9 +42,7 @@
 bool ValidRates(int in_rate, int out_rate) {
   // Not the most compact notation, for clarity.
   if ((in_rate == 44000 && (out_rate == 48000 || out_rate == 96000)) ||
-      (out_rate == 44000 && (in_rate == 48000 || in_rate == 96000))  ||
-      (in_rate == 8000 && out_rate == 96000) ||
-      (in_rate == 96000 && out_rate == 8000)) {
+      (out_rate == 44000 && (in_rate == 48000 || in_rate == 96000))) {
     return false;
   }
 
@@ -62,14 +60,11 @@
   int16_t data_out_[kDataSize];
 };
 
-ResamplerTest::ResamplerTest() {
-}
+ResamplerTest::ResamplerTest() {}
 
-void ResamplerTest::SetUp() {
-}
+void ResamplerTest::SetUp() {}
 
-void ResamplerTest::TearDown() {
-}
+void ResamplerTest::TearDown() {}
 
 TEST_F(ResamplerTest, Reset) {
   // The only failure mode for the constructor is if Reset() fails. For the