xref: /aosp_15_r20/external/libopus/silk/arm/NSQ_neon.h (revision a58d3d2adb790c104798cd88c8a3aff4fa8b82cc)
1*a58d3d2aSXin Li /***********************************************************************
2*a58d3d2aSXin Li Copyright (C) 2014 Vidyo
3*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without
4*a58d3d2aSXin Li modification, are permitted provided that the following conditions
5*a58d3d2aSXin Li are met:
6*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright notice,
7*a58d3d2aSXin Li this list of conditions and the following disclaimer.
8*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright
9*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the
10*a58d3d2aSXin Li documentation and/or other materials provided with the distribution.
11*a58d3d2aSXin Li - Neither the name of Internet Society, IETF or IETF Trust, nor the
12*a58d3d2aSXin Li names of specific contributors, may be used to endorse or promote
13*a58d3d2aSXin Li products derived from this software without specific prior written
14*a58d3d2aSXin Li permission.
15*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16*a58d3d2aSXin Li AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*a58d3d2aSXin Li IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*a58d3d2aSXin Li ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19*a58d3d2aSXin Li LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20*a58d3d2aSXin Li CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21*a58d3d2aSXin Li SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*a58d3d2aSXin Li INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*a58d3d2aSXin Li CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24*a58d3d2aSXin Li ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*a58d3d2aSXin Li POSSIBILITY OF SUCH DAMAGE.
26*a58d3d2aSXin Li ***********************************************************************/
27*a58d3d2aSXin Li #ifndef SILK_NSQ_NEON_H
28*a58d3d2aSXin Li #define SILK_NSQ_NEON_H
29*a58d3d2aSXin Li 
30*a58d3d2aSXin Li #include "cpu_support.h"
31*a58d3d2aSXin Li #include "SigProc_FIX.h"
32*a58d3d2aSXin Li 
33*a58d3d2aSXin Li #undef silk_short_prediction_create_arch_coef
34*a58d3d2aSXin Li /* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */
silk_short_prediction_create_arch_coef_neon(opus_int32 * out,const opus_int16 * in,opus_int order)35*a58d3d2aSXin Li static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order)
36*a58d3d2aSXin Li {
37*a58d3d2aSXin Li     out[15] = silk_LSHIFT32(in[0], 15);
38*a58d3d2aSXin Li     out[14] = silk_LSHIFT32(in[1], 15);
39*a58d3d2aSXin Li     out[13] = silk_LSHIFT32(in[2], 15);
40*a58d3d2aSXin Li     out[12] = silk_LSHIFT32(in[3], 15);
41*a58d3d2aSXin Li     out[11] = silk_LSHIFT32(in[4], 15);
42*a58d3d2aSXin Li     out[10] = silk_LSHIFT32(in[5], 15);
43*a58d3d2aSXin Li     out[9]  = silk_LSHIFT32(in[6], 15);
44*a58d3d2aSXin Li     out[8]  = silk_LSHIFT32(in[7], 15);
45*a58d3d2aSXin Li     out[7]  = silk_LSHIFT32(in[8], 15);
46*a58d3d2aSXin Li     out[6]  = silk_LSHIFT32(in[9], 15);
47*a58d3d2aSXin Li 
48*a58d3d2aSXin Li     if (order == 16)
49*a58d3d2aSXin Li     {
50*a58d3d2aSXin Li         out[5] = silk_LSHIFT32(in[10], 15);
51*a58d3d2aSXin Li         out[4] = silk_LSHIFT32(in[11], 15);
52*a58d3d2aSXin Li         out[3] = silk_LSHIFT32(in[12], 15);
53*a58d3d2aSXin Li         out[2] = silk_LSHIFT32(in[13], 15);
54*a58d3d2aSXin Li         out[1] = silk_LSHIFT32(in[14], 15);
55*a58d3d2aSXin Li         out[0] = silk_LSHIFT32(in[15], 15);
56*a58d3d2aSXin Li     }
57*a58d3d2aSXin Li     else
58*a58d3d2aSXin Li     {
59*a58d3d2aSXin Li         out[5] = 0;
60*a58d3d2aSXin Li         out[4] = 0;
61*a58d3d2aSXin Li         out[3] = 0;
62*a58d3d2aSXin Li         out[2] = 0;
63*a58d3d2aSXin Li         out[1] = 0;
64*a58d3d2aSXin Li         out[0] = 0;
65*a58d3d2aSXin Li     }
66*a58d3d2aSXin Li }
67*a58d3d2aSXin Li 
68*a58d3d2aSXin Li #if defined(OPUS_ARM_PRESUME_NEON_INTR)
69*a58d3d2aSXin Li 
70*a58d3d2aSXin Li #define silk_short_prediction_create_arch_coef(out, in, order) \
71*a58d3d2aSXin Li     (silk_short_prediction_create_arch_coef_neon(out, in, order))
72*a58d3d2aSXin Li 
73*a58d3d2aSXin Li #elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
74*a58d3d2aSXin Li 
75*a58d3d2aSXin Li #define silk_short_prediction_create_arch_coef(out, in, order) \
76*a58d3d2aSXin Li     do { if (arch >= OPUS_ARCH_ARM_NEON) { silk_short_prediction_create_arch_coef_neon(out, in, order); } } while (0)
77*a58d3d2aSXin Li 
78*a58d3d2aSXin Li #endif
79*a58d3d2aSXin Li 
80*a58d3d2aSXin Li opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order);
81*a58d3d2aSXin Li 
82*a58d3d2aSXin Li opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order);
83*a58d3d2aSXin Li 
84*a58d3d2aSXin Li #if defined(OPUS_ARM_PRESUME_NEON_INTR)
85*a58d3d2aSXin Li #undef silk_noise_shape_quantizer_short_prediction
86*a58d3d2aSXin Li #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \
87*a58d3d2aSXin Li     ((void)arch,silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order))
88*a58d3d2aSXin Li 
89*a58d3d2aSXin Li #undef silk_NSQ_noise_shape_feedback_loop
90*a58d3d2aSXin Li #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch)  ((void)arch,silk_NSQ_noise_shape_feedback_loop_neon(data0, data1, coef, order))
91*a58d3d2aSXin Li 
92*a58d3d2aSXin Li #elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
93*a58d3d2aSXin Li 
94*a58d3d2aSXin Li /* silk_noise_shape_quantizer_short_prediction implementations take different parameters based on arch
95*a58d3d2aSXin Li    (coef vs. coefRev) so can't use the usual IMPL table implementation */
96*a58d3d2aSXin Li #undef silk_noise_shape_quantizer_short_prediction
97*a58d3d2aSXin Li #define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch)  \
98*a58d3d2aSXin Li     (arch >= OPUS_ARCH_ARM_NEON ? \
99*a58d3d2aSXin Li         silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order) : \
100*a58d3d2aSXin Li         silk_noise_shape_quantizer_short_prediction_c(in, coef, order))
101*a58d3d2aSXin Li 
102*a58d3d2aSXin Li extern opus_int32
103*a58d3d2aSXin Li  (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])(
104*a58d3d2aSXin Li  const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef,
105*a58d3d2aSXin Li  opus_int order);
106*a58d3d2aSXin Li 
107*a58d3d2aSXin Li #undef silk_NSQ_noise_shape_feedback_loop
108*a58d3d2aSXin Li #define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) \
109*a58d3d2aSXin Li  (SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[(arch)&OPUS_ARCHMASK](data0, data1, \
110*a58d3d2aSXin Li  coef, order))
111*a58d3d2aSXin Li 
112*a58d3d2aSXin Li #endif
113*a58d3d2aSXin Li 
114*a58d3d2aSXin Li #endif /* SILK_NSQ_NEON_H */
115