15140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org/*
25140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
35140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *
45140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
55140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
65140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
75140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
85140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
95140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org */
105140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
115140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
125140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org/*
135140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org * This file contains the resampling by two functions.
145140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org * The description header can be found in signal_processing_library.h
155140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org *
165140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org */
175140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
185140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#if defined(MIPS32_LE)
195140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
20aa30bb7ef5b02c9026dc2c036a0bed9999ae4cf2pbos@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
215140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
225140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org// allpass filter coefficients.
23b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.orgstatic const uint16_t kResampleAllpass1[3] = {3284, 24441, 49528};
24b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.orgstatic const uint16_t kResampleAllpass2[3] = {12199, 37471, 60255};
255140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
265140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org// Multiply a 32-bit value with a 16-bit value and accumulate to another input:
275140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
285140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
295140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
305140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org// decimator
31b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.orgvoid WebRtcSpl_DownsampleBy2(const int16_t* in,
32dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                             size_t len,
33b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org                             int16_t* out,
34b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org                             int32_t* filtState) {
35b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t out32;
36dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t i, len1;
37b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org
38b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state0 = filtState[0];
39b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state1 = filtState[1];
40b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state2 = filtState[2];
41b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state3 = filtState[3];
42b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state4 = filtState[4];
43b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state5 = filtState[5];
44b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state6 = filtState[6];
45b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  register int32_t state7 = filtState[7];
465140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
475140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#if defined(MIPS_DSP_R2_LE)
48b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t k1Res0, k1Res1, k1Res2, k2Res0, k2Res1, k2Res2;
495140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
505140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  k1Res0= 3284;
515140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  k1Res1= 24441;
525140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  k1Res2= 49528;
535140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  k2Res0= 12199;
545140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  k2Res1= 37471;
555140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  k2Res2= 60255;
565140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  len1 = (len >> 1);
575140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
58b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  const int32_t* inw = (int32_t*)in;
59b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t tmp11, tmp12, tmp21, tmp22;
60b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t in322, in321;
61b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t diff1, diff2;
625140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  for (i = len1; i > 0; i--) {
635140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    __asm__ volatile (
645140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "lh         %[in321],    0(%[inw])                  \n\t"
655140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "lh         %[in322],    2(%[inw])                  \n\t"
665140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
675140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "sll        %[in321],    %[in321],      10          \n\t"
685140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "sll        %[in322],    %[in322],      10          \n\t"
695140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
705140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[inw],      %[inw],        4           \n\t"
715140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
725140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "subu       %[diff1],    %[in321],      %[state1]   \n\t"
735140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "subu       %[diff2],    %[in322],      %[state5]   \n\t"
745140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
755140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : [in322] "=&r" (in322), [in321] "=&r" (in321),
765140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [diff1] "=&r" (diff1), [diff2] "=r" (diff2), [inw] "+r" (inw)
775140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : [state1] "r" (state1), [state5] "r" (state5)
785140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : "memory"
795140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    );
805140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
815140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    __asm__ volatile (
825140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "mult       $ac0,       %[diff1],       %[k2Res0]   \n\t"
835140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "mult       $ac1,       %[diff2],       %[k1Res0]   \n\t"
845140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
855140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "extr.w     %[tmp11],   $ac0,           16          \n\t"
865140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "extr.w     %[tmp12],   $ac1,           16          \n\t"
875140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
885140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[tmp11],   %[state0],      %[tmp11]    \n\t"
895140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[tmp12],   %[state4],      %[tmp12]    \n\t"
905140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
915140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[state0],  %[in321],       0           \n\t"
925140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[state4],  %[in322],       0           \n\t"
935140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
945140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "subu       %[diff1],   %[tmp11],       %[state2]   \n\t"
955140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "subu       %[diff2],   %[tmp12],       %[state6]   \n\t"
965140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
975140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "mult       $ac0,       %[diff1],       %[k2Res1]   \n\t"
985140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "mult       $ac1,       %[diff2],       %[k1Res1]   \n\t"
995140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1005140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "extr.w     %[tmp21],   $ac0,           16          \n\t"
1015140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "extr.w     %[tmp22],   $ac1,           16          \n\t"
1025140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1035140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[tmp21],   %[state1],      %[tmp21]    \n\t"
1045140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[tmp22],   %[state5],      %[tmp22]    \n\t"
1055140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1065140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[state1],  %[tmp11],       0           \n\t"
1075140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[state5],  %[tmp12],       0           \n\t"
1085140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : [tmp22] "=r" (tmp22), [tmp21] "=&r" (tmp21),
1095140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [tmp11] "=&r" (tmp11), [state0] "+r" (state0),
1105140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [state1] "+r" (state1),
1115140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [state2] "+r" (state2),
1125140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [state4] "+r" (state4), [tmp12] "=&r" (tmp12),
1135140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [state6] "+r" (state6), [state5] "+r" (state5)
1145140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : [k1Res1] "r" (k1Res1), [k2Res1] "r" (k2Res1), [k2Res0] "r" (k2Res0),
1155140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [diff2] "r" (diff2), [diff1] "r" (diff1), [in322] "r" (in322),
1165140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [in321] "r" (in321), [k1Res0] "r" (k1Res0)
1175140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : "hi", "lo", "$ac1hi", "$ac1lo"
1185140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    );
1195140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1205140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // upper allpass filter
1215140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    __asm__ volatile (
1225140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "subu       %[diff1],   %[tmp21],       %[state3]   \n\t"
1235140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "subu       %[diff2],   %[tmp22],       %[state7]   \n\t"
1245140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1255140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "mult       $ac0,       %[diff1],       %[k2Res2]   \n\t"
1265140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "mult       $ac1,       %[diff2],       %[k1Res2]   \n\t"
1275140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "extr.w     %[state3],  $ac0,           16          \n\t"
1285140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "extr.w     %[state7],  $ac1,           16          \n\t"
1295140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[state3],  %[state2],      %[state3]   \n\t"
1305140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[state7],  %[state6],      %[state7]   \n\t"
1315140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1325140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[state2],  %[tmp21],       0           \n\t"
1335140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[state6],  %[tmp22],       0           \n\t"
1345140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1355140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      // add two allpass outputs, divide by two and round
1365140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addu       %[out32],   %[state3],      %[state7]   \n\t"
1375140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "addiu      %[out32],   %[out32],       1024        \n\t"
1385140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      "sra        %[out32],   %[out32],       11          \n\t"
1395140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : [state3] "+r" (state3), [state6] "+r" (state6),
1405140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [state2] "+r" (state2), [diff2] "=&r" (diff2),
1415140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [out32] "=r" (out32), [diff1] "=&r" (diff1), [state7] "+r" (state7)
1425140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : [tmp22] "r" (tmp22), [tmp21] "r" (tmp21),
1435140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org        [k1Res2] "r" (k1Res2), [k2Res2] "r" (k2Res2)
1445140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      : "hi", "lo", "$ac1hi", "$ac1lo"
1455140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    );
1465140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1475140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // limit amplitude to prevent wrap-around, and write to output array
1485140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    *out++ = WebRtcSpl_SatW32ToW16(out32);
1495140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  }
1505140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#else  // #if defined(MIPS_DSP_R2_LE)
151b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t tmp1, tmp2, diff;
152b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org  int32_t in32;
1535140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  len1 = (len >> 1)/4;
1545140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  for (i = len1; i > 0; i--) {
1555140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // lower allpass filter
156b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
1575140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state1;
1585140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
1595140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state0 = in32;
1605140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state2;
1615140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
1625140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state1 = tmp1;
1635140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state3;
1645140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
1655140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state2 = tmp2;
1665140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1675140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // upper allpass filter
168b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
1695140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state5;
1705140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
1715140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state4 = in32;
1725140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state6;
1735140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
1745140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state5 = tmp1;
1755140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state7;
1765140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
1775140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state6 = tmp2;
1785140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1795140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // add two allpass outputs, divide by two and round
1805140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    out32 = (state3 + state7 + 1024) >> 11;
1815140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1825140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // limit amplitude to prevent wrap-around, and write to output array
1835140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    *out++ = WebRtcSpl_SatW32ToW16(out32);
1845140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // lower allpass filter
185b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
1865140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state1;
1875140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
1885140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state0 = in32;
1895140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state2;
1905140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
1915140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state1 = tmp1;
1925140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state3;
1935140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
1945140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state2 = tmp2;
1955140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
1965140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // upper allpass filter
197b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
1985140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state5;
1995140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
2005140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state4 = in32;
2015140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state6;
2025140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
2035140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state5 = tmp1;
2045140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state7;
2055140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
2065140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state6 = tmp2;
2075140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2085140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // add two allpass outputs, divide by two and round
2095140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    out32 = (state3 + state7 + 1024) >> 11;
2105140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2115140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // limit amplitude to prevent wrap-around, and write to output array
2125140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    *out++ = WebRtcSpl_SatW32ToW16(out32);
2135140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // lower allpass filter
214b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
2155140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state1;
2165140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
2175140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state0 = in32;
2185140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state2;
2195140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
2205140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state1 = tmp1;
2215140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state3;
2225140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
2235140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state2 = tmp2;
2245140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2255140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // upper allpass filter
226b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
2275140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state5;
2285140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
2295140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state4 = in32;
2305140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state6;
2315140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
2325140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state5 = tmp1;
2335140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state7;
2345140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
2355140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state6 = tmp2;
2365140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2375140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // add two allpass outputs, divide by two and round
2385140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    out32 = (state3 + state7 + 1024) >> 11;
2395140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2405140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // limit amplitude to prevent wrap-around, and write to output array
2415140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    *out++ = WebRtcSpl_SatW32ToW16(out32);
2425140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // lower allpass filter
243b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
2445140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state1;
2455140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
2465140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state0 = in32;
2475140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state2;
2485140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
2495140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state1 = tmp1;
2505140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state3;
2515140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
2525140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state2 = tmp2;
2535140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2545140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // upper allpass filter
255b09130763b8949023a061f3cfa665a3a6bbac0f0pbos@webrtc.org    in32 = (int32_t)(*in++) << 10;
2565140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = in32 - state5;
2575140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
2585140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state4 = in32;
2595140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp1 - state6;
2605140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
2615140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state5 = tmp1;
2625140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    diff = tmp2 - state7;
2635140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
2645140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    state6 = tmp2;
2655140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2665140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // add two allpass outputs, divide by two and round
2675140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    out32 = (state3 + state7 + 1024) >> 11;
2685140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2695140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    // limit amplitude to prevent wrap-around, and write to output array
2705140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    *out++ = WebRtcSpl_SatW32ToW16(out32);
2715140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  }
2725140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#endif  // #if defined(MIPS_DSP_R2_LE)
2735140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  __asm__ volatile (
2745140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state0],      0(%[filtState])     \n\t"
2755140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state1],      4(%[filtState])     \n\t"
2765140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state2],      8(%[filtState])     \n\t"
2775140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state3],      12(%[filtState])    \n\t"
2785140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state4],      16(%[filtState])    \n\t"
2795140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state5],      20(%[filtState])    \n\t"
2805140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state6],      24(%[filtState])    \n\t"
2815140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    "sw       %[state7],      28(%[filtState])    \n\t"
2825140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    :
2835140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    : [state0] "r" (state0), [state1] "r" (state1), [state2] "r" (state2),
2845140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      [state3] "r" (state3), [state4] "r" (state4), [state5] "r" (state5),
2855140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org      [state6] "r" (state6), [state7] "r" (state7), [filtState] "r" (filtState)
2865140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org    : "memory"
2875140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org  );
2885140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org}
2895140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org
2905140e240372d85aaf6c51476b4f1bad92e61bf80andrew@webrtc.org#endif  // #if defined(MIPS32_LE)
291