Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board.

Dependencies:   ST_I2S ST_FREQUENCY_DIVIDER USBDEVICE

Dependents:   HelloWorld_CCA02M1 HelloWorld_CCA02M1_mbedOS HelloWorld_CCA02M1 Karaoke_CCA01M1_CCA02M1_mbedOS

Fork of X_NUCLEO_CCA02M1 by ST Expansion SW Team

MEMS Microphones Library

Library to handle the X-NUCLEO-CCA02M1 MEMS Microphones Expansion Board. A single board allows to record a standard 2-channel stereo signal as an array of PCM samples (16 bit/sample); in principle, it could make use of six additional MEMS microphones to realize a 8-channel audio system.


Microphones configuration

Currently the configurations supported are the following:

  • Stereo@48KHz
  • Stereo@44.1KHz (CD audio quality)
  • Stereo@32KHz
  • Stereo@16KHz
  • Stereo@8KHz
  • Mono@48KHz
  • Mono@44.1KHz
  • Mono@32KHz
  • Mono@16KHz
  • Mono@8KHz

Mono configurations need a Jumper connecting PB_5 and PB_13 on the Morpho connector to properly work.


Platform compatibility

  • This board can be currently used with the Nucleo F4 Family only, please see the ST_I2S library compatibility for further information.
  • The library is compatible both with mbed OS 5.x and mbed classic 2.x (to work with mbed classic, the main application has to import the "events" library, which is not included into the "mbed" library).


I2S Peripheral Usage

By default this board makes use of the I2S peripheral available on Nucleo boards.


Acquiring through the USB

In order to acquire the recorded PCM audio channel with an audio SW on a PC, please connect the expansion board to a USB port of the PC, and the Nucleo board to a USB power supply.

Committer:
Davidroid
Date:
Wed Dec 12 15:44:02 2018 +0000
Revision:
26:53f8b511f2a1
Parent:
25:f2c04f757003
Update LICENSE.txt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davide.aliprandi@st.com 2:9f389fd8fb2e 1 /**
Davidroid 25:f2c04f757003 2 *******************************************************************************
Davidroid 25:f2c04f757003 3 * @file OpenPDMFilter.c
Davidroid 25:f2c04f757003 4 * @author CL
Davidroid 25:f2c04f757003 5 * @version V1.0.0
Davidroid 25:f2c04f757003 6 * @date 9-September-2015
Davidroid 25:f2c04f757003 7 * @brief Open PDM audio software decoding Library.
Davidroid 25:f2c04f757003 8 * This Library is used to decode and reconstruct the audio signal
Davidroid 25:f2c04f757003 9 * produced by ST MEMS microphone (MP45Dxxx, MP34Dxxx).
Davidroid 25:f2c04f757003 10 *******************************************************************************
Davidroid 25:f2c04f757003 11 * @attention
Davidroid 25:f2c04f757003 12 *
Davidroid 25:f2c04f757003 13 * <h2><center>&copy; COPYRIGHT 2018 STMicroelectronics</center></h2>
Davidroid 25:f2c04f757003 14 *
Davidroid 25:f2c04f757003 15 * Licensed under the Apache License, Version 2.0 (the "License");
Davidroid 25:f2c04f757003 16 * you may not use this file except in compliance with the License.
Davidroid 25:f2c04f757003 17 * You may obtain a copy of the License at
Davidroid 25:f2c04f757003 18 *
Davidroid 25:f2c04f757003 19 * http://www.apache.org/licenses/LICENSE-2.0
Davidroid 25:f2c04f757003 20 *
Davidroid 25:f2c04f757003 21 * Unless required by applicable law or agreed to in writing, software
Davidroid 25:f2c04f757003 22 * distributed under the License is distributed on an "AS IS" BASIS,
Davidroid 25:f2c04f757003 23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Davidroid 25:f2c04f757003 24 * See the License for the specific language governing permissions and
Davidroid 25:f2c04f757003 25 * limitations under the License.
Davidroid 25:f2c04f757003 26 *******************************************************************************
Davidroid 25:f2c04f757003 27 */
davide.aliprandi@st.com 2:9f389fd8fb2e 28
davide.aliprandi@st.com 2:9f389fd8fb2e 29
davide.aliprandi@st.com 2:9f389fd8fb2e 30 /* Includes ------------------------------------------------------------------*/
davide.aliprandi@st.com 2:9f389fd8fb2e 31
davide.aliprandi@st.com 2:9f389fd8fb2e 32 #include "OpenPDMFilter.h"
davide.aliprandi@st.com 2:9f389fd8fb2e 33
davide.aliprandi@st.com 2:9f389fd8fb2e 34
davide.aliprandi@st.com 2:9f389fd8fb2e 35 /* Variables -----------------------------------------------------------------*/
davide.aliprandi@st.com 2:9f389fd8fb2e 36
davide.aliprandi@st.com 16:4ab2eac7be21 37 uint32_t div_const = 0;
davide.aliprandi@st.com 16:4ab2eac7be21 38 int64_t sub_const = 0;
Davidroid 20:9952bef19da1 39 uint32_t sinc[DECIMATION_MAX * SINCN];
davide.aliprandi@st.com 15:17bdadc6aa9c 40 uint32_t sinc1[DECIMATION_MAX];
davide.aliprandi@st.com 16:4ab2eac7be21 41 uint32_t sinc2[DECIMATION_MAX * 2];
Davidroid 20:9952bef19da1 42 uint32_t coef[SINCN][DECIMATION_MAX];
davide.aliprandi@st.com 15:17bdadc6aa9c 43 #ifdef USE_LUT
Davidroid 20:9952bef19da1 44 int32_t lut[256][DECIMATION_MAX / 8][SINCN];
davide.aliprandi@st.com 15:17bdadc6aa9c 45 #endif
davide.aliprandi@st.com 2:9f389fd8fb2e 46
davide.aliprandi@st.com 2:9f389fd8fb2e 47
davide.aliprandi@st.com 2:9f389fd8fb2e 48 /* Functions -----------------------------------------------------------------*/
davide.aliprandi@st.com 2:9f389fd8fb2e 49
davide.aliprandi@st.com 15:17bdadc6aa9c 50 #ifdef USE_LUT
Davidroid 20:9952bef19da1 51 int32_t filter_table_mono_64(uint8_t *data, uint8_t sincn)
davide.aliprandi@st.com 16:4ab2eac7be21 52 {
davide.aliprandi@st.com 16:4ab2eac7be21 53 return (int32_t)
davide.aliprandi@st.com 16:4ab2eac7be21 54 lut[data[0]][0][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 55 lut[data[1]][1][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 56 lut[data[2]][2][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 57 lut[data[3]][3][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 58 lut[data[4]][4][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 59 lut[data[5]][5][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 60 lut[data[6]][6][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 61 lut[data[7]][7][sincn];
davide.aliprandi@st.com 16:4ab2eac7be21 62 }
Davidroid 20:9952bef19da1 63 int32_t filter_table_stereo_64(uint8_t *data, uint8_t sincn)
davide.aliprandi@st.com 15:17bdadc6aa9c 64 {
davide.aliprandi@st.com 16:4ab2eac7be21 65 return (int32_t)
davide.aliprandi@st.com 16:4ab2eac7be21 66 lut[data[0]][0][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 67 lut[data[2]][1][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 68 lut[data[4]][2][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 69 lut[data[6]][3][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 70 lut[data[8]][4][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 71 lut[data[10]][5][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 72 lut[data[12]][6][sincn] +
davide.aliprandi@st.com 16:4ab2eac7be21 73 lut[data[14]][7][sincn];
davide.aliprandi@st.com 15:17bdadc6aa9c 74 }
Davidroid 20:9952bef19da1 75 int32_t filter_table_mono_128(uint8_t *data, uint8_t sincn)
Davidroid 20:9952bef19da1 76 {
Davidroid 20:9952bef19da1 77 return (int32_t)
Davidroid 20:9952bef19da1 78 lut[data[0]][0][sincn] +
Davidroid 20:9952bef19da1 79 lut[data[1]][1][sincn] +
Davidroid 20:9952bef19da1 80 lut[data[2]][2][sincn] +
Davidroid 20:9952bef19da1 81 lut[data[3]][3][sincn] +
Davidroid 20:9952bef19da1 82 lut[data[4]][4][sincn] +
Davidroid 20:9952bef19da1 83 lut[data[5]][5][sincn] +
Davidroid 20:9952bef19da1 84 lut[data[6]][6][sincn] +
Davidroid 20:9952bef19da1 85 lut[data[7]][7][sincn] +
Davidroid 20:9952bef19da1 86 lut[data[8]][8][sincn] +
Davidroid 20:9952bef19da1 87 lut[data[9]][9][sincn] +
Davidroid 20:9952bef19da1 88 lut[data[10]][10][sincn] +
Davidroid 20:9952bef19da1 89 lut[data[11]][11][sincn] +
Davidroid 20:9952bef19da1 90 lut[data[12]][12][sincn] +
Davidroid 20:9952bef19da1 91 lut[data[13]][13][sincn] +
Davidroid 20:9952bef19da1 92 lut[data[14]][14][sincn] +
Davidroid 20:9952bef19da1 93 lut[data[15]][15][sincn];
Davidroid 20:9952bef19da1 94 }
Davidroid 20:9952bef19da1 95 int32_t filter_table_stereo_128(uint8_t *data, uint8_t sincn)
Davidroid 20:9952bef19da1 96 {
Davidroid 20:9952bef19da1 97 return (int32_t)
Davidroid 20:9952bef19da1 98 lut[data[0]][0][sincn] +
Davidroid 20:9952bef19da1 99 lut[data[2]][1][sincn] +
Davidroid 20:9952bef19da1 100 lut[data[4]][2][sincn] +
Davidroid 20:9952bef19da1 101 lut[data[6]][3][sincn] +
Davidroid 20:9952bef19da1 102 lut[data[8]][4][sincn] +
Davidroid 20:9952bef19da1 103 lut[data[10]][5][sincn] +
Davidroid 20:9952bef19da1 104 lut[data[12]][6][sincn] +
Davidroid 20:9952bef19da1 105 lut[data[14]][7][sincn] +
Davidroid 20:9952bef19da1 106 lut[data[16]][8][sincn] +
Davidroid 20:9952bef19da1 107 lut[data[18]][9][sincn] +
Davidroid 20:9952bef19da1 108 lut[data[20]][10][sincn] +
Davidroid 20:9952bef19da1 109 lut[data[22]][11][sincn] +
Davidroid 20:9952bef19da1 110 lut[data[24]][12][sincn] +
Davidroid 20:9952bef19da1 111 lut[data[26]][13][sincn] +
Davidroid 20:9952bef19da1 112 lut[data[28]][14][sincn] +
Davidroid 20:9952bef19da1 113 lut[data[30]][15][sincn];
Davidroid 20:9952bef19da1 114 }
Davidroid 20:9952bef19da1 115 int32_t (* filter_tables_64[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono_64, filter_table_stereo_64};
Davidroid 20:9952bef19da1 116 int32_t (* filter_tables_128[2]) (uint8_t *data, uint8_t sincn) = {filter_table_mono_128, filter_table_stereo_128};
davide.aliprandi@st.com 15:17bdadc6aa9c 117 #else
Davidroid 20:9952bef19da1 118 int32_t filter_table(uint8_t *data, uint8_t sincn, TPDMFilter_InitStruct *param)
davide.aliprandi@st.com 2:9f389fd8fb2e 119 {
Davidroid 13:90465220b75f 120 uint8_t c, i;
davide.aliprandi@st.com 11:b2f7f79026e4 121 uint16_t data_index = 0;
Davidroid 20:9952bef19da1 122 uint32_t *coef_p = &coef[sincn][0];
Davidroid 20:9952bef19da1 123 int32_t F = 0;
Davidroid 20:9952bef19da1 124 uint8_t decimation = param->Decimation;
Davidroid 20:9952bef19da1 125 uint8_t channels = param->In_MicChannels;
davide.aliprandi@st.com 2:9f389fd8fb2e 126
Davidroid 20:9952bef19da1 127 for (i = 0; i < decimation; i += 8) {
davide.aliprandi@st.com 11:b2f7f79026e4 128 c = data[data_index];
davide.aliprandi@st.com 11:b2f7f79026e4 129 F += ((c >> 7) ) * coef_p[i ] +
davide.aliprandi@st.com 11:b2f7f79026e4 130 ((c >> 6) & 0x01) * coef_p[i + 1] +
davide.aliprandi@st.com 11:b2f7f79026e4 131 ((c >> 5) & 0x01) * coef_p[i + 2] +
davide.aliprandi@st.com 11:b2f7f79026e4 132 ((c >> 4) & 0x01) * coef_p[i + 3] +
davide.aliprandi@st.com 11:b2f7f79026e4 133 ((c >> 3) & 0x01) * coef_p[i + 4] +
davide.aliprandi@st.com 11:b2f7f79026e4 134 ((c >> 2) & 0x01) * coef_p[i + 5] +
davide.aliprandi@st.com 11:b2f7f79026e4 135 ((c >> 1) & 0x01) * coef_p[i + 6] +
davide.aliprandi@st.com 11:b2f7f79026e4 136 ((c ) & 0x01) * coef_p[i + 7];
davide.aliprandi@st.com 11:b2f7f79026e4 137 data_index += channels;
davide.aliprandi@st.com 2:9f389fd8fb2e 138 }
davide.aliprandi@st.com 2:9f389fd8fb2e 139 return F;
davide.aliprandi@st.com 2:9f389fd8fb2e 140 }
davide.aliprandi@st.com 15:17bdadc6aa9c 141 #endif
davide.aliprandi@st.com 2:9f389fd8fb2e 142
Davidroid 20:9952bef19da1 143 void convolve(uint32_t Signal[/* SignalLen */], unsigned short SignalLen,
Davidroid 20:9952bef19da1 144 uint32_t Kernel[/* KernelLen */], unsigned short KernelLen,
Davidroid 20:9952bef19da1 145 uint32_t Result[/* SignalLen + KernelLen - 1 */])
Davidroid 20:9952bef19da1 146 {
Davidroid 20:9952bef19da1 147 uint16_t n;
Davidroid 20:9952bef19da1 148
Davidroid 20:9952bef19da1 149 for (n = 0; n < SignalLen + KernelLen - 1; n++)
Davidroid 20:9952bef19da1 150 {
Davidroid 20:9952bef19da1 151 unsigned short kmin, kmax, k;
Davidroid 20:9952bef19da1 152
Davidroid 20:9952bef19da1 153 Result[n] = 0;
Davidroid 20:9952bef19da1 154
Davidroid 20:9952bef19da1 155 kmin = (n >= KernelLen - 1) ? n - (KernelLen - 1) : 0;
Davidroid 20:9952bef19da1 156 kmax = (n < SignalLen - 1) ? n : SignalLen - 1;
Davidroid 20:9952bef19da1 157
Davidroid 20:9952bef19da1 158 for (k = kmin; k <= kmax; k++) {
Davidroid 20:9952bef19da1 159 Result[n] += Signal[k] * Kernel[n - k];
Davidroid 20:9952bef19da1 160 }
Davidroid 20:9952bef19da1 161 }
Davidroid 20:9952bef19da1 162 }
Davidroid 20:9952bef19da1 163
davide.aliprandi@st.com 2:9f389fd8fb2e 164 void Open_PDM_Filter_Init(TPDMFilter_InitStruct *Param)
davide.aliprandi@st.com 2:9f389fd8fb2e 165 {
davide.aliprandi@st.com 16:4ab2eac7be21 166 uint16_t i, j;
davide.aliprandi@st.com 2:9f389fd8fb2e 167 int64_t sum = 0;
Davidroid 20:9952bef19da1 168
Davidroid 20:9952bef19da1 169 uint8_t decimation = Param->Decimation;
Davidroid 20:9952bef19da1 170
Davidroid 20:9952bef19da1 171 for (i = 0; i < SINCN; i++) {
davide.aliprandi@st.com 16:4ab2eac7be21 172 Param->Coef[i] = 0;
davide.aliprandi@st.com 16:4ab2eac7be21 173 Param->bit[i] = 0;
davide.aliprandi@st.com 2:9f389fd8fb2e 174 }
Davidroid 20:9952bef19da1 175 for (i = 0; i < decimation; i++) {
davide.aliprandi@st.com 16:4ab2eac7be21 176 sinc1[i] = 1;
davide.aliprandi@st.com 2:9f389fd8fb2e 177 }
davide.aliprandi@st.com 16:4ab2eac7be21 178
davide.aliprandi@st.com 16:4ab2eac7be21 179 Param->OldOut = Param->OldIn = Param->OldZ = 0;
Davidroid 20:9952bef19da1 180 Param->LP_ALFA = (Param->LP_HZ != 0 ? (uint16_t) (Param->LP_HZ * 256 / (Param->LP_HZ + Param->Fs / (2 * 3.14159))) : 0);
Davidroid 20:9952bef19da1 181 Param->HP_ALFA = (Param->HP_HZ != 0 ? (uint16_t) (Param->Fs * 256 / (2 * 3.14159 * Param->HP_HZ + Param->Fs)) : 0);
davide.aliprandi@st.com 16:4ab2eac7be21 182
Davidroid 20:9952bef19da1 183 Param->FilterLen = decimation * SINCN;
davide.aliprandi@st.com 16:4ab2eac7be21 184 sinc[0] = 0;
Davidroid 20:9952bef19da1 185 sinc[decimation * SINCN - 1] = 0;
Davidroid 20:9952bef19da1 186 convolve(sinc1, decimation, sinc1, decimation, sinc2);
Davidroid 20:9952bef19da1 187 convolve(sinc2, decimation * 2 - 1, sinc1, decimation, &sinc[1]);
Davidroid 20:9952bef19da1 188 for(j = 0; j < SINCN; j++) {
Davidroid 20:9952bef19da1 189 for (i = 0; i < decimation; i++) {
Davidroid 20:9952bef19da1 190 coef[j][i] = sinc[j * decimation + i];
Davidroid 20:9952bef19da1 191 sum += sinc[j * decimation + i];
davide.aliprandi@st.com 2:9f389fd8fb2e 192 }
davide.aliprandi@st.com 2:9f389fd8fb2e 193 }
davide.aliprandi@st.com 16:4ab2eac7be21 194
davide.aliprandi@st.com 16:4ab2eac7be21 195 sub_const = sum >> 1;
Davidroid 20:9952bef19da1 196 div_const = sub_const * Param->MaxVolume / 32768 / FILTER_GAIN;
davide.aliprandi@st.com 16:4ab2eac7be21 197 div_const = (div_const == 0 ? 1 : div_const);
davide.aliprandi@st.com 15:17bdadc6aa9c 198
davide.aliprandi@st.com 15:17bdadc6aa9c 199 #ifdef USE_LUT
davide.aliprandi@st.com 15:17bdadc6aa9c 200 /* Look-Up Table. */
davide.aliprandi@st.com 15:17bdadc6aa9c 201 uint16_t c, d, s;
Davidroid 20:9952bef19da1 202 for (s = 0; s < SINCN; s++)
davide.aliprandi@st.com 15:17bdadc6aa9c 203 {
davide.aliprandi@st.com 15:17bdadc6aa9c 204 uint32_t *coef_p = &coef[s][0];
davide.aliprandi@st.com 15:17bdadc6aa9c 205 for (c = 0; c < 256; c++)
Davidroid 20:9952bef19da1 206 for (d = 0; d < decimation / 8; d++)
davide.aliprandi@st.com 15:17bdadc6aa9c 207 lut[c][d][s] = ((c >> 7) ) * coef_p[d * 8 ] +
davide.aliprandi@st.com 15:17bdadc6aa9c 208 ((c >> 6) & 0x01) * coef_p[d * 8 + 1] +
davide.aliprandi@st.com 15:17bdadc6aa9c 209 ((c >> 5) & 0x01) * coef_p[d * 8 + 2] +
davide.aliprandi@st.com 15:17bdadc6aa9c 210 ((c >> 4) & 0x01) * coef_p[d * 8 + 3] +
davide.aliprandi@st.com 15:17bdadc6aa9c 211 ((c >> 3) & 0x01) * coef_p[d * 8 + 4] +
davide.aliprandi@st.com 15:17bdadc6aa9c 212 ((c >> 2) & 0x01) * coef_p[d * 8 + 5] +
davide.aliprandi@st.com 15:17bdadc6aa9c 213 ((c >> 1) & 0x01) * coef_p[d * 8 + 6] +
davide.aliprandi@st.com 15:17bdadc6aa9c 214 ((c ) & 0x01) * coef_p[d * 8 + 7];
davide.aliprandi@st.com 15:17bdadc6aa9c 215 }
davide.aliprandi@st.com 15:17bdadc6aa9c 216 #endif
davide.aliprandi@st.com 2:9f389fd8fb2e 217 }
davide.aliprandi@st.com 2:9f389fd8fb2e 218
Davidroid 20:9952bef19da1 219 void Open_PDM_Filter_64(uint8_t* data, uint16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
davide.aliprandi@st.com 2:9f389fd8fb2e 220 {
davide.aliprandi@st.com 16:4ab2eac7be21 221 uint8_t i, data_out_index;
davide.aliprandi@st.com 16:4ab2eac7be21 222 uint8_t channels = Param->In_MicChannels;
Davidroid 20:9952bef19da1 223 uint8_t data_inc = ((DECIMATION_MAX >> 4) * channels);
davide.aliprandi@st.com 16:4ab2eac7be21 224 int64_t Z, Z0, Z1, Z2;
Davidroid 20:9952bef19da1 225 int64_t OldOut, OldIn, OldZ;
davide.aliprandi@st.com 16:4ab2eac7be21 226
davide.aliprandi@st.com 16:4ab2eac7be21 227 OldOut = Param->OldOut;
davide.aliprandi@st.com 16:4ab2eac7be21 228 OldIn = Param->OldIn;
davide.aliprandi@st.com 16:4ab2eac7be21 229 OldZ = Param->OldZ;
davide.aliprandi@st.com 16:4ab2eac7be21 230
Davidroid 20:9952bef19da1 231 #ifdef USE_LUT
Davidroid 20:9952bef19da1 232 uint8_t j = channels - 1;
Davidroid 20:9952bef19da1 233 #endif
Davidroid 20:9952bef19da1 234
Davidroid 20:9952bef19da1 235 for (i = 0, data_out_index = 0; i < Param->Fs / 1000; i++, data_out_index += channels) {
davide.aliprandi@st.com 16:4ab2eac7be21 236 #ifdef USE_LUT
Davidroid 20:9952bef19da1 237 Z0 = filter_tables_64[j](data, 0);
Davidroid 20:9952bef19da1 238 Z1 = filter_tables_64[j](data, 1);
Davidroid 20:9952bef19da1 239 Z2 = filter_tables_64[j](data, 2);
davide.aliprandi@st.com 16:4ab2eac7be21 240 #else
Davidroid 20:9952bef19da1 241 Z0 = filter_table(data, 0, Param);
Davidroid 20:9952bef19da1 242 Z1 = filter_table(data, 1, Param);
Davidroid 20:9952bef19da1 243 Z2 = filter_table(data, 2, Param);
davide.aliprandi@st.com 16:4ab2eac7be21 244 #endif
davide.aliprandi@st.com 16:4ab2eac7be21 245
davide.aliprandi@st.com 16:4ab2eac7be21 246 Z = Param->Coef[1] + Z2 - sub_const;
davide.aliprandi@st.com 16:4ab2eac7be21 247 Param->Coef[1] = Param->Coef[0] + Z1;
davide.aliprandi@st.com 16:4ab2eac7be21 248 Param->Coef[0] = Z0;
davide.aliprandi@st.com 16:4ab2eac7be21 249
davide.aliprandi@st.com 16:4ab2eac7be21 250 OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
davide.aliprandi@st.com 16:4ab2eac7be21 251 OldIn = Z;
Davidroid 20:9952bef19da1 252 OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
davide.aliprandi@st.com 16:4ab2eac7be21 253
Davidroid 20:9952bef19da1 254 Z = OldZ * volume;
davide.aliprandi@st.com 16:4ab2eac7be21 255 Z = RoundDiv(Z, div_const);
davide.aliprandi@st.com 16:4ab2eac7be21 256 Z = SaturaLH(Z, -32700, 32700);
davide.aliprandi@st.com 16:4ab2eac7be21 257
davide.aliprandi@st.com 16:4ab2eac7be21 258 dataOut[data_out_index] = Z;
davide.aliprandi@st.com 16:4ab2eac7be21 259 data += data_inc;
davide.aliprandi@st.com 16:4ab2eac7be21 260 }
davide.aliprandi@st.com 16:4ab2eac7be21 261
davide.aliprandi@st.com 16:4ab2eac7be21 262 Param->OldOut = OldOut;
davide.aliprandi@st.com 16:4ab2eac7be21 263 Param->OldIn = OldIn;
davide.aliprandi@st.com 16:4ab2eac7be21 264 Param->OldZ = OldZ;
davide.aliprandi@st.com 2:9f389fd8fb2e 265 }
Davidroid 20:9952bef19da1 266
Davidroid 20:9952bef19da1 267 void Open_PDM_Filter_128(uint8_t* data, uint16_t* dataOut, uint16_t volume, TPDMFilter_InitStruct *Param)
Davidroid 20:9952bef19da1 268 {
Davidroid 20:9952bef19da1 269 uint8_t i, data_out_index;
Davidroid 20:9952bef19da1 270 uint8_t channels = Param->In_MicChannels;
Davidroid 20:9952bef19da1 271 uint8_t data_inc = ((DECIMATION_MAX >> 3) * channels);
Davidroid 20:9952bef19da1 272 int64_t Z, Z0, Z1, Z2;
Davidroid 20:9952bef19da1 273 int64_t OldOut, OldIn, OldZ;
Davidroid 20:9952bef19da1 274
Davidroid 20:9952bef19da1 275 OldOut = Param->OldOut;
Davidroid 20:9952bef19da1 276 OldIn = Param->OldIn;
Davidroid 20:9952bef19da1 277 OldZ = Param->OldZ;
Davidroid 20:9952bef19da1 278
Davidroid 20:9952bef19da1 279 #ifdef USE_LUT
Davidroid 20:9952bef19da1 280 uint8_t j = channels - 1;
Davidroid 20:9952bef19da1 281 #endif
Davidroid 20:9952bef19da1 282
Davidroid 20:9952bef19da1 283 for (i = 0, data_out_index = 0; i < Param->Fs / 1000; i++, data_out_index += channels) {
Davidroid 20:9952bef19da1 284 #ifdef USE_LUT
Davidroid 20:9952bef19da1 285 Z0 = filter_tables_128[j](data, 0);
Davidroid 20:9952bef19da1 286 Z1 = filter_tables_128[j](data, 1);
Davidroid 20:9952bef19da1 287 Z2 = filter_tables_128[j](data, 2);
Davidroid 20:9952bef19da1 288 #else
Davidroid 20:9952bef19da1 289 Z0 = filter_table(data, 0, Param);
Davidroid 20:9952bef19da1 290 Z1 = filter_table(data, 1, Param);
Davidroid 20:9952bef19da1 291 Z2 = filter_table(data, 2, Param);
Davidroid 20:9952bef19da1 292 #endif
Davidroid 20:9952bef19da1 293
Davidroid 20:9952bef19da1 294 Z = Param->Coef[1] + Z2 - sub_const;
Davidroid 20:9952bef19da1 295 Param->Coef[1] = Param->Coef[0] + Z1;
Davidroid 20:9952bef19da1 296 Param->Coef[0] = Z0;
Davidroid 20:9952bef19da1 297
Davidroid 20:9952bef19da1 298 OldOut = (Param->HP_ALFA * (OldOut + Z - OldIn)) >> 8;
Davidroid 20:9952bef19da1 299 OldIn = Z;
Davidroid 20:9952bef19da1 300 OldZ = ((256 - Param->LP_ALFA) * OldZ + Param->LP_ALFA * OldOut) >> 8;
Davidroid 20:9952bef19da1 301
Davidroid 20:9952bef19da1 302 Z = OldZ * volume;
Davidroid 20:9952bef19da1 303 Z = RoundDiv(Z, div_const);
Davidroid 20:9952bef19da1 304 Z = SaturaLH(Z, -32700, 32700);
Davidroid 20:9952bef19da1 305
Davidroid 20:9952bef19da1 306 dataOut[data_out_index] = Z;
Davidroid 20:9952bef19da1 307 data += data_inc;
Davidroid 20:9952bef19da1 308 }
Davidroid 20:9952bef19da1 309
Davidroid 20:9952bef19da1 310 Param->OldOut = OldOut;
Davidroid 20:9952bef19da1 311 Param->OldIn = OldIn;
Davidroid 20:9952bef19da1 312 Param->OldZ = OldZ;
Davidroid 20:9952bef19da1 313 }