/ Drivers / CMSIS / DSP / Source / TransformFunctions / arm_mfcc_f32.c
arm_mfcc_f32.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_mfcc_f32.c
  4   * Description:  MFCC function for the f32 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  
 31  #include "dsp/transform_functions.h"
 32  #include "dsp/statistics_functions.h"
 33  #include "dsp/basic_math_functions.h"
 34  #include "dsp/complex_math_functions.h"
 35  #include "dsp/fast_math_functions.h"
 36  #include "dsp/matrix_functions.h"
 37  
 38  /**
 39    @ingroup groupTransforms
 40   */
 41  
 42  
 43  /**
 44    @defgroup MFCC MFCC
 45  
 46    MFCC Transform
 47  
 48    There are separate functions for floating-point, Q15, and Q31 data types.
 49   */
 50  
 51  
 52  
 53  /**
 54    @addtogroup MFCC
 55    @{
 56   */
 57  
 58  /**
 59    @brief         MFCC F32
 60    @param[in]    S       points to the mfcc instance structure
 61    @param[in]     pSrc points to the input samples
 62    @param[out]     pDst  points to the output MFCC values
 63    @param[inout]     pTmp  points to a temporary buffer of complex
 64  
 65    @return        none
 66  
 67    @par           Description
 68                     The number of input samples if the FFT length used
 69                     when initializing the instance data structure.
 70  
 71                     The temporary buffer has a 2*fft length size when MFCC
 72                     is implemented with CFFT.
 73                     It has length FFT Length + 2 when implemented with RFFT
 74                     (default implementation).
 75  
 76                     The source buffer is modified by this function.
 77  
 78   */
 79  void arm_mfcc_f32(
 80    const arm_mfcc_instance_f32 * S,
 81    float32_t *pSrc,
 82    float32_t *pDst,
 83    float32_t *pTmp
 84    )
 85  {
 86    float32_t maxValue;
 87    uint32_t  index; 
 88    uint32_t i;
 89    float32_t result;
 90    const float32_t *coefs=S->filterCoefs;
 91    arm_matrix_instance_f32 pDctMat;
 92  
 93    /* Normalize */
 94    arm_absmax_f32(pSrc,S->fftLen,&maxValue,&index);
 95  
 96    arm_scale_f32(pSrc,1.0f/maxValue,pSrc,S->fftLen);
 97  
 98    /* Multiply by window */
 99    arm_mult_f32(pSrc,S->windowCoefs,pSrc,S->fftLen);
100  
101    /* Compute spectrum magnitude 
102    */
103  #if defined(ARM_MFCC_CFFT_BASED)
104    /* some HW accelerator for CMSIS-DSP used in some boards
105       are only providing acceleration for CFFT.
106       With ARM_MFCC_CFFT_BASED enabled, CFFT is used and the MFCC
107       will be accelerated on those boards.
108   
109       The default is to use RFFT
110    */
111    /* Convert from real to complex */
112    for(i=0; i < S->fftLen ; i++)
113    {
114      pTmp[2*i] = pSrc[i];
115      pTmp[2*i+1] = 0.0f;
116    }
117    arm_cfft_f32(&(S->cfft),pTmp,0,1);
118  #else
119    /* Default RFFT based implementation */
120    arm_rfft_fast_f32(&(S->rfft),pSrc,pTmp,0);
121    /* Unpack real values */
122    pTmp[S->fftLen]=pTmp[1];
123    pTmp[S->fftLen+1]=0.0f;
124    pTmp[1]=0.0f;
125  #endif
126    arm_cmplx_mag_f32(pTmp,pSrc,S->fftLen);
127  
128    /* Apply MEL filters */
129    for(i=0; i<S->nbMelFilters; i++)
130    {
131        arm_dot_prod_f32(pSrc+S->filterPos[i],
132          coefs,
133          S->filterLengths[i],
134          &result);
135  
136        coefs += S->filterLengths[i];
137  
138        pTmp[i] = result;
139  
140    }
141  
142    /* Compute the log */
143    arm_offset_f32(pTmp,1.0e-6f,pTmp,S->nbMelFilters);
144    arm_vlog_f32(pTmp,pTmp,S->nbMelFilters);
145  
146    /* Multiply with the DCT matrix */
147  
148    pDctMat.numRows=S->nbDctOutputs;
149    pDctMat.numCols=S->nbMelFilters;
150    pDctMat.pData=(float32_t*)S->dctCoefs;
151  
152    arm_mat_vec_mult_f32(&pDctMat, pTmp, pDst);
153        
154  
155  }
156  
157  /**
158    @} end of MFCC group
159   */