1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_mfcc_f16.c
4 * Description: MFCC function for the f16 version
5 *
6 * $Date: 07 September 2021
7 * $Revision: V1.10.0
8 *
9 * Target Processor: Cortex-M and Cortex-A cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29
30 #include "dsp/transform_functions_f16.h"
31 #include "dsp/statistics_functions_f16.h"
32 #include "dsp/basic_math_functions_f16.h"
33 #include "dsp/complex_math_functions_f16.h"
34 #include "dsp/fast_math_functions_f16.h"
35 #include "dsp/matrix_functions_f16.h"
36
37 #if defined(ARM_FLOAT16_SUPPORTED)
38
39 /**
40 @ingroup groupTransforms
41 */
42
43
44 /**
45 @defgroup MFCC MFCC
46
47 MFCC Transform
48
49 There are separate functions for floating-point, Q15, and Q31 data types.
50 */
51
52
53
54 /**
55 @addtogroup MFCCF16
56 @{
57 */
58
59 /**
60 @brief MFCC F16
61 @param[in] S points to the mfcc instance structure
62 @param[in] pSrc points to the input samples
63 @param[out] pDst points to the output MFCC values
64 @param[inout] pTmp points to a temporary buffer of complex
65
66 @par Description
67 The number of input samples if the FFT length used
68 when initializing the instance data structure.
69
70 The temporary buffer has a 2*fft length size when MFCC
71 is implemented with CFFT.
72 It has length FFT Length + 2 when implemented with RFFT
73 (default implementation).
74
75 The source buffer is modified by this function.
76
77 */
arm_mfcc_f16(const arm_mfcc_instance_f16 * S,float16_t * pSrc,float16_t * pDst,float16_t * pTmp)78 ARM_DSP_ATTRIBUTE void arm_mfcc_f16(
79 const arm_mfcc_instance_f16 * S,
80 float16_t *pSrc,
81 float16_t *pDst,
82 float16_t *pTmp
83 )
84 {
85 float16_t maxValue;
86 uint32_t index;
87 uint32_t i;
88 float16_t result;
89 const float16_t *coefs=S->filterCoefs;
90 arm_matrix_instance_f16 pDctMat;
91
92 /* Normalize */
93 arm_absmax_f16(pSrc,S->fftLen,&maxValue,&index);
94
95 if ((_Float16)maxValue != 0.0f16)
96 {
97 arm_scale_f16(pSrc,1.0f16/(_Float16)maxValue,pSrc,S->fftLen);
98 }
99
100 /* Multiply by window */
101 arm_mult_f16(pSrc,S->windowCoefs,pSrc,S->fftLen);
102
103 /* Compute spectrum magnitude
104 */
105 #if defined(ARM_MFCC_CFFT_BASED)
106 /* some HW accelerator for CMSIS-DSP used in some boards
107 are only providing acceleration for CFFT.
108 With ARM_MFCC_CFFT_BASED enabled, CFFT is used and the MFCC
109 will be accelerated on those boards.
110
111 The default is to use RFFT
112 */
113 /* Convert from real to complex */
114 for(i=0; i < S->fftLen ; i++)
115 {
116 pTmp[2*i] = pSrc[i];
117 pTmp[2*i+1] = 0.0f16;
118 }
119 arm_cfft_f16(&(S->cfft),pTmp,0,1);
120 #else
121 /* Default RFFT based implementation */
122 arm_rfft_fast_f16(&(S->rfft),pSrc,pTmp,0);
123 /* Unpack real values */
124 pTmp[S->fftLen]=pTmp[1];
125 pTmp[S->fftLen+1]=0.0f16;
126 pTmp[1]=0.0f;
127 #endif
128 arm_cmplx_mag_f16(pTmp,pSrc,S->fftLen);
129 if ((_Float16)maxValue != 0.0f16)
130 {
131 arm_scale_f16(pSrc,maxValue,pSrc,S->fftLen);
132 }
133
134 /* Apply MEL filters */
135 for(i=0; i<S->nbMelFilters; i++)
136 {
137 arm_dot_prod_f16(pSrc+S->filterPos[i],
138 coefs,
139 S->filterLengths[i],
140 &result);
141
142 coefs += S->filterLengths[i];
143
144 pTmp[i] = result;
145
146 }
147
148 /* Compute the log */
149 arm_offset_f16(pTmp,1.0e-4f16,pTmp,S->nbMelFilters);
150 arm_vlog_f16(pTmp,pTmp,S->nbMelFilters);
151
152 /* Multiply with the DCT matrix */
153
154 pDctMat.numRows=S->nbDctOutputs;
155 pDctMat.numCols=S->nbMelFilters;
156 pDctMat.pData=(float16_t*)S->dctCoefs;
157
158 arm_mat_vec_mult_f16(&pDctMat, pTmp, pDst);
159
160
161 }
162
163 #endif /* defined(ARM_FLOAT16_SUPPORTED) */
164 /**
165 @} end of MFCC group
166 */
167