/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


/*
 * This file contains the resampling by two functions.
 * The description header can be found in signal_processing_library.h
 *
 */

#include "signal_processing_library.h"

#ifdef WEBRTC_ARCH_ARM_V7A

// allpass filter coefficients.
static const WebRtc_UWord32 kResampleAllpass1[3] = {3284, 24441, 49528 << 15};
static const WebRtc_UWord32 kResampleAllpass2[3] =
  {12199, 37471 << 15, 60255 << 15};

// Multiply two 32-bit values and accumulate to another input value.
// Return: state + ((diff * tbl_value) >> 16)

static __inline WebRtc_Word32 MUL_ACCUM_1(WebRtc_Word32 tbl_value,
                                          WebRtc_Word32 diff,
                                          WebRtc_Word32 state) {
  WebRtc_Word32 result;
  __asm__("smlawb %r0, %r1, %r2, %r3": "=r"(result): "r"(diff),
                                       "r"(tbl_value), "r"(state));
  return result;
}

// Multiply two 32-bit values and accumulate to another input value.
// Return: Return: state + (((diff << 1) * tbl_value) >> 32)
//
// The reason to introduce this function is that, in case we can't use smlawb
// instruction (in MUL_ACCUM_1) due to input value range, we can still use 
// smmla to save some cycles.

static __inline WebRtc_Word32 MUL_ACCUM_2(WebRtc_Word32 tbl_value,
                                          WebRtc_Word32 diff,
                                          WebRtc_Word32 state) {
  WebRtc_Word32 result;
  __asm__("smmla %r0, %r1, %r2, %r3": "=r"(result): "r"(diff << 1),
                                      "r"(tbl_value), "r"(state));
  return result;
}

#else

// allpass filter coefficients.
static const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528};
static const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255};

// Multiply a 32-bit value with a 16-bit value and accumulate to another input:
#define MUL_ACCUM_1(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)
#define MUL_ACCUM_2(a, b, c) WEBRTC_SPL_SCALEDIFF32(a, b, c)

#endif  // WEBRTC_ARCH_ARM_V7A


// decimator
void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len,
                             WebRtc_Word16* out, WebRtc_Word32* filtState) {
  WebRtc_Word32 tmp1, tmp2, diff, in32, out32;
  WebRtc_Word16 i;

  register WebRtc_Word32 state0 = filtState[0];
  register WebRtc_Word32 state1 = filtState[1];
  register WebRtc_Word32 state2 = filtState[2];
  register WebRtc_Word32 state3 = filtState[3];
  register WebRtc_Word32 state4 = filtState[4];
  register WebRtc_Word32 state5 = filtState[5];
  register WebRtc_Word32 state6 = filtState[6];
  register WebRtc_Word32 state7 = filtState[7];

  for (i = (len >> 1); i > 0; i--) {
    // lower allpass filter
    in32 = (WebRtc_Word32)(*in++) << 10;
    diff = in32 - state1;
    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state0);
    state0 = in32;
    diff = tmp1 - state2;
    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state1);
    state1 = tmp1;
    diff = tmp2 - state3;
    state3 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state2);
    state2 = tmp2;

    // upper allpass filter
    in32 = (WebRtc_Word32)(*in++) << 10;
    diff = in32 - state5;
    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state4);
    state4 = in32;
    diff = tmp1 - state6;
    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state5);
    state5 = tmp1;
    diff = tmp2 - state7;
    state7 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state6);
    state6 = tmp2;

    // add two allpass outputs, divide by two and round
    out32 = (state3 + state7 + 1024) >> 11;

    // limit amplitude to prevent wrap-around, and write to output array
    *out++ = WebRtcSpl_SatW32ToW16(out32);
  }

  filtState[0] = state0;
  filtState[1] = state1;
  filtState[2] = state2;
  filtState[3] = state3;
  filtState[4] = state4;
  filtState[5] = state5;
  filtState[6] = state6;
  filtState[7] = state7;
}


void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len,
                           WebRtc_Word16* out, WebRtc_Word32* filtState) {
  WebRtc_Word32 tmp1, tmp2, diff, in32, out32;
  WebRtc_Word16 i;

  register WebRtc_Word32 state0 = filtState[0];
  register WebRtc_Word32 state1 = filtState[1];
  register WebRtc_Word32 state2 = filtState[2];
  register WebRtc_Word32 state3 = filtState[3];
  register WebRtc_Word32 state4 = filtState[4];
  register WebRtc_Word32 state5 = filtState[5];
  register WebRtc_Word32 state6 = filtState[6];
  register WebRtc_Word32 state7 = filtState[7];

  for (i = len; i > 0; i--) {
    // lower allpass filter
    in32 = (WebRtc_Word32)(*in++) << 10;
    diff = in32 - state1;
    tmp1 = MUL_ACCUM_1(kResampleAllpass1[0], diff, state0);
    state0 = in32;
    diff = tmp1 - state2;
    tmp2 = MUL_ACCUM_1(kResampleAllpass1[1], diff, state1);
    state1 = tmp1;
    diff = tmp2 - state3;
    state3 = MUL_ACCUM_2(kResampleAllpass1[2], diff, state2);
    state2 = tmp2;

    // round; limit amplitude to prevent wrap-around; write to output array
    out32 = (state3 + 512) >> 10;
    *out++ = WebRtcSpl_SatW32ToW16(out32);

    // upper allpass filter
    diff = in32 - state5;
    tmp1 = MUL_ACCUM_1(kResampleAllpass2[0], diff, state4);
    state4 = in32;
    diff = tmp1 - state6;
    tmp2 = MUL_ACCUM_2(kResampleAllpass2[1], diff, state5);
    state5 = tmp1;
    diff = tmp2 - state7;
    state7 = MUL_ACCUM_2(kResampleAllpass2[2], diff, state6);
    state6 = tmp2;

    // round; limit amplitude to prevent wrap-around; write to output array
    out32 = (state7 + 512) >> 10;
    *out++ = WebRtcSpl_SatW32ToW16(out32);
  }

  filtState[0] = state0;
  filtState[1] = state1;
  filtState[2] = state2;
  filtState[3] = state3;
  filtState[4] = state4;
  filtState[5] = state5;
  filtState[6] = state6;
  filtState[7] = state7;
}
