1/*
2 * Copyright (c) 2007-2008 Ian Caulfield
3 *               2009 Ramiro Polla
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavcodec/mlp.h"
23#include "dsputil.h"
24
25static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff,
26                                  int firorder, int iirorder,
27                                  unsigned int filter_shift, int32_t mask, int blocksize,
28                                  int32_t *sample_buffer)
29{
30    int32_t *firbuf = state;
31    int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
32    const int32_t *fircoeff = coeff;
33    const int32_t *iircoeff = coeff + MAX_FIR_ORDER;
34    int i;
35
36    for (i = 0; i < blocksize; i++) {
37        int32_t residual = *sample_buffer;
38        unsigned int order;
39        int64_t accum = 0;
40        int32_t result;
41
42        for (order = 0; order < firorder; order++)
43            accum += (int64_t) firbuf[order] * fircoeff[order];
44        for (order = 0; order < iirorder; order++)
45            accum += (int64_t) iirbuf[order] * iircoeff[order];
46
47        accum  = accum >> filter_shift;
48        result = (accum + residual) & mask;
49
50        *--firbuf = result;
51        *--iirbuf = result - accum;
52
53        *sample_buffer = result;
54        sample_buffer += MAX_CHANNELS;
55    }
56}
57
58void ff_mlp_init(DSPContext* c, AVCodecContext *avctx)
59{
60    c->mlp_filter_channel = ff_mlp_filter_channel;
61    if (ARCH_X86)
62        ff_mlp_init_x86(c, avctx);
63}
64