Chris@69
|
1 /* Copyright (c) 2015 Xiph.Org Foundation
|
Chris@69
|
2 Written by Viswanath Puttagunta */
|
Chris@69
|
3 /**
|
Chris@69
|
4 @file celt_fft_ne10.c
|
Chris@69
|
5 @brief ARM Neon optimizations for fft using NE10 library
|
Chris@69
|
6 */
|
Chris@69
|
7
|
Chris@69
|
8 /*
|
Chris@69
|
9 Redistribution and use in source and binary forms, with or without
|
Chris@69
|
10 modification, are permitted provided that the following conditions
|
Chris@69
|
11 are met:
|
Chris@69
|
12
|
Chris@69
|
13 - Redistributions of source code must retain the above copyright
|
Chris@69
|
14 notice, this list of conditions and the following disclaimer.
|
Chris@69
|
15
|
Chris@69
|
16 - Redistributions in binary form must reproduce the above copyright
|
Chris@69
|
17 notice, this list of conditions and the following disclaimer in the
|
Chris@69
|
18 documentation and/or other materials provided with the distribution.
|
Chris@69
|
19
|
Chris@69
|
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
Chris@69
|
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
Chris@69
|
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
Chris@69
|
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
Chris@69
|
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
Chris@69
|
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
Chris@69
|
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
Chris@69
|
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
Chris@69
|
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
Chris@69
|
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
Chris@69
|
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Chris@69
|
31 */
|
Chris@69
|
32
|
Chris@69
|
33 #ifndef SKIP_CONFIG_H
|
Chris@69
|
34 #ifdef HAVE_CONFIG_H
|
Chris@69
|
35 #include "config.h"
|
Chris@69
|
36 #endif
|
Chris@69
|
37 #endif
|
Chris@69
|
38
|
Chris@69
|
39 #include <NE10_dsp.h>
|
Chris@69
|
40 #include "os_support.h"
|
Chris@69
|
41 #include "kiss_fft.h"
|
Chris@69
|
42 #include "stack_alloc.h"
|
Chris@69
|
43
|
Chris@69
|
44 #if !defined(FIXED_POINT)
|
Chris@69
|
45 # define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon
|
Chris@69
|
46 # define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t
|
Chris@69
|
47 # define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t
|
Chris@69
|
48 # define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32
|
Chris@69
|
49 # define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t
|
Chris@69
|
50 # define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon
|
Chris@69
|
51 #else
|
Chris@69
|
52 # define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft)
|
Chris@69
|
53 # define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t
|
Chris@69
|
54 # define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t
|
Chris@69
|
55 # define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
|
Chris@69
|
56 # define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
|
Chris@69
|
57 # define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t
|
Chris@69
|
58 # define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon
|
Chris@69
|
59 #endif
|
Chris@69
|
60
|
Chris@69
|
61 #if defined(CUSTOM_MODES)
|
Chris@69
|
62
|
Chris@69
|
63 /* nfft lengths in NE10 that support scaled fft */
|
Chris@69
|
64 # define NE10_FFTSCALED_SUPPORT_MAX 4
|
Chris@69
|
65 static const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = {
|
Chris@69
|
66 480, 240, 120, 60
|
Chris@69
|
67 };
|
Chris@69
|
68
|
Chris@69
|
69 int opus_fft_alloc_arm_neon(kiss_fft_state *st)
|
Chris@69
|
70 {
|
Chris@69
|
71 int i;
|
Chris@69
|
72 size_t memneeded = sizeof(struct arch_fft_state);
|
Chris@69
|
73
|
Chris@69
|
74 st->arch_fft = (arch_fft_state *)opus_alloc(memneeded);
|
Chris@69
|
75 if (!st->arch_fft)
|
Chris@69
|
76 return -1;
|
Chris@69
|
77
|
Chris@69
|
78 for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) {
|
Chris@69
|
79 if(st->nfft == ne10_fft_scaled_support[i])
|
Chris@69
|
80 break;
|
Chris@69
|
81 }
|
Chris@69
|
82 if (i == NE10_FFTSCALED_SUPPORT_MAX) {
|
Chris@69
|
83 /* This nfft length (scaled fft) is not supported in NE10 */
|
Chris@69
|
84 st->arch_fft->is_supported = 0;
|
Chris@69
|
85 st->arch_fft->priv = NULL;
|
Chris@69
|
86 }
|
Chris@69
|
87 else {
|
Chris@69
|
88 st->arch_fft->is_supported = 1;
|
Chris@69
|
89 st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft);
|
Chris@69
|
90 if (st->arch_fft->priv == NULL) {
|
Chris@69
|
91 return -1;
|
Chris@69
|
92 }
|
Chris@69
|
93 }
|
Chris@69
|
94 return 0;
|
Chris@69
|
95 }
|
Chris@69
|
96
|
Chris@69
|
97 void opus_fft_free_arm_neon(kiss_fft_state *st)
|
Chris@69
|
98 {
|
Chris@69
|
99 NE10_FFT_CFG_TYPE_T cfg;
|
Chris@69
|
100
|
Chris@69
|
101 if (!st->arch_fft)
|
Chris@69
|
102 return;
|
Chris@69
|
103
|
Chris@69
|
104 cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv;
|
Chris@69
|
105 if (cfg)
|
Chris@69
|
106 NE10_FFT_DESTROY_C2C_TYPE(cfg);
|
Chris@69
|
107 opus_free(st->arch_fft);
|
Chris@69
|
108 }
|
Chris@69
|
109 #endif
|
Chris@69
|
110
|
Chris@69
|
111 void opus_fft_neon(const kiss_fft_state *st,
|
Chris@69
|
112 const kiss_fft_cpx *fin,
|
Chris@69
|
113 kiss_fft_cpx *fout)
|
Chris@69
|
114 {
|
Chris@69
|
115 NE10_FFT_STATE_TYPE_T state;
|
Chris@69
|
116 NE10_FFT_CFG_TYPE_T cfg = &state;
|
Chris@69
|
117 VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
|
Chris@69
|
118 SAVE_STACK;
|
Chris@69
|
119 ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
|
Chris@69
|
120
|
Chris@69
|
121 if (!st->arch_fft->is_supported) {
|
Chris@69
|
122 /* This nfft length (scaled fft) not supported in NE10 */
|
Chris@69
|
123 opus_fft_c(st, fin, fout);
|
Chris@69
|
124 }
|
Chris@69
|
125 else {
|
Chris@69
|
126 memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
|
Chris@69
|
127 state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
|
Chris@69
|
128 #if !defined(FIXED_POINT)
|
Chris@69
|
129 state.is_forward_scaled = 1;
|
Chris@69
|
130
|
Chris@69
|
131 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
Chris@69
|
132 (NE10_FFT_CPX_TYPE_T *)fin,
|
Chris@69
|
133 cfg, 0);
|
Chris@69
|
134 #else
|
Chris@69
|
135 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
Chris@69
|
136 (NE10_FFT_CPX_TYPE_T *)fin,
|
Chris@69
|
137 cfg, 0, 1);
|
Chris@69
|
138 #endif
|
Chris@69
|
139 }
|
Chris@69
|
140 RESTORE_STACK;
|
Chris@69
|
141 }
|
Chris@69
|
142
|
Chris@69
|
143 void opus_ifft_neon(const kiss_fft_state *st,
|
Chris@69
|
144 const kiss_fft_cpx *fin,
|
Chris@69
|
145 kiss_fft_cpx *fout)
|
Chris@69
|
146 {
|
Chris@69
|
147 NE10_FFT_STATE_TYPE_T state;
|
Chris@69
|
148 NE10_FFT_CFG_TYPE_T cfg = &state;
|
Chris@69
|
149 VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
|
Chris@69
|
150 SAVE_STACK;
|
Chris@69
|
151 ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
|
Chris@69
|
152
|
Chris@69
|
153 if (!st->arch_fft->is_supported) {
|
Chris@69
|
154 /* This nfft length (scaled fft) not supported in NE10 */
|
Chris@69
|
155 opus_ifft_c(st, fin, fout);
|
Chris@69
|
156 }
|
Chris@69
|
157 else {
|
Chris@69
|
158 memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
|
Chris@69
|
159 state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
|
Chris@69
|
160 #if !defined(FIXED_POINT)
|
Chris@69
|
161 state.is_backward_scaled = 0;
|
Chris@69
|
162
|
Chris@69
|
163 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
Chris@69
|
164 (NE10_FFT_CPX_TYPE_T *)fin,
|
Chris@69
|
165 cfg, 1);
|
Chris@69
|
166 #else
|
Chris@69
|
167 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
Chris@69
|
168 (NE10_FFT_CPX_TYPE_T *)fin,
|
Chris@69
|
169 cfg, 1, 0);
|
Chris@69
|
170 #endif
|
Chris@69
|
171 }
|
Chris@69
|
172 RESTORE_STACK;
|
Chris@69
|
173 }
|