1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/*
2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *
4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  Use of this source code is governed by a BSD-style license
5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  that can be found in the LICENSE file in the root of the source
6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  tree. An additional intellectual property rights grant can be found
7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  in the file PATENTS.  All contributing project authors may
8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *  be found in the AUTHORS file in the root of the source tree.
9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */
10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/*
13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * This file contains the function WebRtcSpl_DownsampleFast().
14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * The description header can be found in signal_processing_library.h
15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent *
16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */
17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "signal_processing_library.h"
19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint WebRtcSpl_DownsampleFast(WebRtc_Word16 *in_ptr, WebRtc_Word16 in_length,
21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                             WebRtc_Word16 *out_ptr, WebRtc_Word16 out_length,
22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                             WebRtc_Word16 *B, WebRtc_Word16 B_length, WebRtc_Word16 factor,
23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                             WebRtc_Word16 delay)
24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{
25e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word32 o;
26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    int i, j;
27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word16 *downsampled_ptr = out_ptr;
29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word16 *b_ptr;
30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word16 *x_ptr;
31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    WebRtc_Word16 endpos = delay
32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(factor, (out_length - 1)) + 1;
33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (in_length < endpos)
35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        return -1;
37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
38e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    for (i = delay; i < endpos; i += factor)
40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    {
41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        b_ptr = &B[0];
42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        x_ptr = &in_ptr[i];
43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        o = (WebRtc_Word32)2048; // Round val
45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        for (j = 0; j < B_length; j++)
47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        {
48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            o += WEBRTC_SPL_MUL_16_16(*b_ptr++, *x_ptr--);
49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        }
50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        o = WEBRTC_SPL_RSHIFT_W32(o, 12);
52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        // If output is higher than 32768, saturate it. Same with negative side
54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
55c55a96383497a772a307b346368133960b02ad03Eric Laurent        *downsampled_ptr++ = WebRtcSpl_SatW32ToW16(o);
56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    }
57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    return 0;
59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent}
60