xref: /aosp_15_r20/external/libopus/celt/mdct.h (revision a58d3d2adb790c104798cd88c8a3aff4fa8b82cc)
1*a58d3d2aSXin Li /* Copyright (c) 2007-2008 CSIRO
2*a58d3d2aSXin Li    Copyright (c) 2007-2008 Xiph.Org Foundation
3*a58d3d2aSXin Li    Written by Jean-Marc Valin */
4*a58d3d2aSXin Li /*
5*a58d3d2aSXin Li    Redistribution and use in source and binary forms, with or without
6*a58d3d2aSXin Li    modification, are permitted provided that the following conditions
7*a58d3d2aSXin Li    are met:
8*a58d3d2aSXin Li 
9*a58d3d2aSXin Li    - Redistributions of source code must retain the above copyright
10*a58d3d2aSXin Li    notice, this list of conditions and the following disclaimer.
11*a58d3d2aSXin Li 
12*a58d3d2aSXin Li    - Redistributions in binary form must reproduce the above copyright
13*a58d3d2aSXin Li    notice, this list of conditions and the following disclaimer in the
14*a58d3d2aSXin Li    documentation and/or other materials provided with the distribution.
15*a58d3d2aSXin Li 
16*a58d3d2aSXin Li    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17*a58d3d2aSXin Li    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18*a58d3d2aSXin Li    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19*a58d3d2aSXin Li    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20*a58d3d2aSXin Li    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21*a58d3d2aSXin Li    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22*a58d3d2aSXin Li    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23*a58d3d2aSXin Li    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24*a58d3d2aSXin Li    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25*a58d3d2aSXin Li    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26*a58d3d2aSXin Li    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*a58d3d2aSXin Li */
28*a58d3d2aSXin Li 
29*a58d3d2aSXin Li /* This is a simple MDCT implementation that uses a N/4 complex FFT
30*a58d3d2aSXin Li    to do most of the work. It should be relatively straightforward to
31*a58d3d2aSXin Li    plug in pretty much and FFT here.
32*a58d3d2aSXin Li 
33*a58d3d2aSXin Li    This replaces the Vorbis FFT (and uses the exact same API), which
34*a58d3d2aSXin Li    was a bit too messy and that was ending up duplicating code
35*a58d3d2aSXin Li    (might as well use the same FFT everywhere).
36*a58d3d2aSXin Li 
37*a58d3d2aSXin Li    The algorithm is similar to (and inspired from) Fabrice Bellard's
38*a58d3d2aSXin Li    MDCT implementation in FFMPEG, but has differences in signs, ordering
39*a58d3d2aSXin Li    and scaling in many places.
40*a58d3d2aSXin Li */
41*a58d3d2aSXin Li 
42*a58d3d2aSXin Li #ifndef MDCT_H
43*a58d3d2aSXin Li #define MDCT_H
44*a58d3d2aSXin Li 
45*a58d3d2aSXin Li #include "opus_defines.h"
46*a58d3d2aSXin Li #include "kiss_fft.h"
47*a58d3d2aSXin Li #include "arch.h"
48*a58d3d2aSXin Li 
49*a58d3d2aSXin Li typedef struct {
50*a58d3d2aSXin Li    int n;
51*a58d3d2aSXin Li    int maxshift;
52*a58d3d2aSXin Li    const kiss_fft_state *kfft[4];
53*a58d3d2aSXin Li    const kiss_twiddle_scalar * OPUS_RESTRICT trig;
54*a58d3d2aSXin Li } mdct_lookup;
55*a58d3d2aSXin Li 
56*a58d3d2aSXin Li #if defined(HAVE_ARM_NE10)
57*a58d3d2aSXin Li #include "arm/mdct_arm.h"
58*a58d3d2aSXin Li #endif
59*a58d3d2aSXin Li 
60*a58d3d2aSXin Li 
61*a58d3d2aSXin Li int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch);
62*a58d3d2aSXin Li void clt_mdct_clear(mdct_lookup *l, int arch);
63*a58d3d2aSXin Li 
64*a58d3d2aSXin Li /** Compute a forward MDCT and scale by 4/N, trashes the input array */
65*a58d3d2aSXin Li void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in,
66*a58d3d2aSXin Li                         kiss_fft_scalar * OPUS_RESTRICT out,
67*a58d3d2aSXin Li                         const opus_val16 *window, int overlap,
68*a58d3d2aSXin Li                         int shift, int stride, int arch);
69*a58d3d2aSXin Li 
70*a58d3d2aSXin Li /** Compute a backward MDCT (no scaling) and performs weighted overlap-add
71*a58d3d2aSXin Li     (scales implicitly by 1/2) */
72*a58d3d2aSXin Li void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in,
73*a58d3d2aSXin Li       kiss_fft_scalar * OPUS_RESTRICT out,
74*a58d3d2aSXin Li       const opus_val16 * OPUS_RESTRICT window,
75*a58d3d2aSXin Li       int overlap, int shift, int stride, int arch);
76*a58d3d2aSXin Li 
77*a58d3d2aSXin Li #if !defined(OVERRIDE_OPUS_MDCT)
78*a58d3d2aSXin Li /* Is run-time CPU detection enabled on this platform? */
79*a58d3d2aSXin Li #if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10)
80*a58d3d2aSXin Li 
81*a58d3d2aSXin Li extern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(
82*a58d3d2aSXin Li       const mdct_lookup *l, kiss_fft_scalar *in,
83*a58d3d2aSXin Li       kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
84*a58d3d2aSXin Li       int overlap, int shift, int stride, int arch);
85*a58d3d2aSXin Li 
86*a58d3d2aSXin Li #define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
87*a58d3d2aSXin Li    ((*CLT_MDCT_FORWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \
88*a58d3d2aSXin Li                                                    _window, _overlap, _shift, \
89*a58d3d2aSXin Li                                                    _stride, _arch))
90*a58d3d2aSXin Li 
91*a58d3d2aSXin Li extern void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(
92*a58d3d2aSXin Li       const mdct_lookup *l, kiss_fft_scalar *in,
93*a58d3d2aSXin Li       kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
94*a58d3d2aSXin Li       int overlap, int shift, int stride, int arch);
95*a58d3d2aSXin Li 
96*a58d3d2aSXin Li #define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
97*a58d3d2aSXin Li    (*CLT_MDCT_BACKWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \
98*a58d3d2aSXin Li                                                    _window, _overlap, _shift, \
99*a58d3d2aSXin Li                                                    _stride, _arch)
100*a58d3d2aSXin Li 
101*a58d3d2aSXin Li #else /* if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) */
102*a58d3d2aSXin Li 
103*a58d3d2aSXin Li #define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
104*a58d3d2aSXin Li    clt_mdct_forward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)
105*a58d3d2aSXin Li 
106*a58d3d2aSXin Li #define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
107*a58d3d2aSXin Li    clt_mdct_backward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)
108*a58d3d2aSXin Li 
109*a58d3d2aSXin Li #endif /* end if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) && !defined(FIXED_POINT) */
110*a58d3d2aSXin Li #endif /* end if !defined(OVERRIDE_OPUS_MDCT) */
111*a58d3d2aSXin Li 
112*a58d3d2aSXin Li #endif
113