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