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:
20:9952bef19da1
Update LICENSE.txt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davide.aliprandi@st.com 2:9f389fd8fb2e 1 /**
davide.aliprandi@st.com 2:9f389fd8fb2e 2 ******************************************************************************
davide.aliprandi@st.com 2:9f389fd8fb2e 3 * @file PDM2PCMAudio_class.cpp
davide.aliprandi@st.com 2:9f389fd8fb2e 4 * @author AST / Software Platforms and Cloud
davide.aliprandi@st.com 2:9f389fd8fb2e 5 * @version V1.0
davide.aliprandi@st.com 2:9f389fd8fb2e 6 * @date November 10th, 2016
davide.aliprandi@st.com 2:9f389fd8fb2e 7 * @brief Implementation file for the PDM2PCMAudio conversion library.
davide.aliprandi@st.com 2:9f389fd8fb2e 8 ******************************************************************************
davide.aliprandi@st.com 2:9f389fd8fb2e 9 * @attention
davide.aliprandi@st.com 2:9f389fd8fb2e 10 *
davide.aliprandi@st.com 2:9f389fd8fb2e 11 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
davide.aliprandi@st.com 2:9f389fd8fb2e 12 *
davide.aliprandi@st.com 2:9f389fd8fb2e 13 * Redistribution and use in source and binary forms, with or without modification,
davide.aliprandi@st.com 2:9f389fd8fb2e 14 * are permitted provided that the following conditions are met:
davide.aliprandi@st.com 2:9f389fd8fb2e 15 * 1. Redistributions of source code must retain the above copyright notice,
davide.aliprandi@st.com 2:9f389fd8fb2e 16 * this list of conditions and the following disclaimer.
davide.aliprandi@st.com 2:9f389fd8fb2e 17 * 2. Redistributions in binary form must reproduce the above copyright notice,
davide.aliprandi@st.com 2:9f389fd8fb2e 18 * this list of conditions and the following disclaimer in the documentation
davide.aliprandi@st.com 2:9f389fd8fb2e 19 * and/or other materials provided with the distribution.
davide.aliprandi@st.com 2:9f389fd8fb2e 20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
davide.aliprandi@st.com 2:9f389fd8fb2e 21 * may be used to endorse or promote products derived from this software
davide.aliprandi@st.com 2:9f389fd8fb2e 22 * without specific prior written permission.
davide.aliprandi@st.com 2:9f389fd8fb2e 23 *
davide.aliprandi@st.com 2:9f389fd8fb2e 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
davide.aliprandi@st.com 2:9f389fd8fb2e 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
davide.aliprandi@st.com 2:9f389fd8fb2e 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
davide.aliprandi@st.com 2:9f389fd8fb2e 27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
davide.aliprandi@st.com 2:9f389fd8fb2e 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
davide.aliprandi@st.com 2:9f389fd8fb2e 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
davide.aliprandi@st.com 2:9f389fd8fb2e 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
davide.aliprandi@st.com 2:9f389fd8fb2e 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
davide.aliprandi@st.com 2:9f389fd8fb2e 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
davide.aliprandi@st.com 2:9f389fd8fb2e 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
davide.aliprandi@st.com 2:9f389fd8fb2e 34 *
davide.aliprandi@st.com 2:9f389fd8fb2e 35 ******************************************************************************
davide.aliprandi@st.com 2:9f389fd8fb2e 36 */
davide.aliprandi@st.com 2:9f389fd8fb2e 37
davide.aliprandi@st.com 2:9f389fd8fb2e 38
davide.aliprandi@st.com 2:9f389fd8fb2e 39 /* Includes ------------------------------------------------------------------*/
davide.aliprandi@st.com 2:9f389fd8fb2e 40
davide.aliprandi@st.com 2:9f389fd8fb2e 41 #include "PDM2PCMAudio.h"
davide.aliprandi@st.com 2:9f389fd8fb2e 42
davide.aliprandi@st.com 2:9f389fd8fb2e 43
davide.aliprandi@st.com 2:9f389fd8fb2e 44 /* Variables -----------------------------------------------------------------*/
davide.aliprandi@st.com 2:9f389fd8fb2e 45
davide.aliprandi@st.com 2:9f389fd8fb2e 46 /* Demux filter. */
davide.aliprandi@st.com 2:9f389fd8fb2e 47 const uint8_t PDM2PCMAudio::_demux_filter[DEMUX_FILTER_SIZE] =
davide.aliprandi@st.com 2:9f389fd8fb2e 48 {
davide.aliprandi@st.com 2:9f389fd8fb2e 49 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 2:9f389fd8fb2e 50 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 2:9f389fd8fb2e 51 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 2:9f389fd8fb2e 52 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 2:9f389fd8fb2e 53 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 2:9f389fd8fb2e 54 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
davide.aliprandi@st.com 2:9f389fd8fb2e 55 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 2:9f389fd8fb2e 56 0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
davide.aliprandi@st.com 2:9f389fd8fb2e 57 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 2:9f389fd8fb2e 58 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 2:9f389fd8fb2e 59 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
davide.aliprandi@st.com 2:9f389fd8fb2e 60 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
davide.aliprandi@st.com 2:9f389fd8fb2e 61 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 2:9f389fd8fb2e 62 0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
davide.aliprandi@st.com 2:9f389fd8fb2e 63 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
davide.aliprandi@st.com 2:9f389fd8fb2e 64 0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
davide.aliprandi@st.com 2:9f389fd8fb2e 65 };
davide.aliprandi@st.com 2:9f389fd8fb2e 66
davide.aliprandi@st.com 2:9f389fd8fb2e 67
davide.aliprandi@st.com 2:9f389fd8fb2e 68 /* Methods -------------------------------------------------------------------*/
davide.aliprandi@st.com 2:9f389fd8fb2e 69
davide.aliprandi@st.com 2:9f389fd8fb2e 70 /**
Davidroid 20:9952bef19da1 71 * @brief Getting number of PCM samples from nummber of PDM samples.
Davidroid 20:9952bef19da1 72 * @param PCM_samples Number of PCM samples.
Davidroid 20:9952bef19da1 73 * @retval Number of equivalent PDM samples.
Davidroid 20:9952bef19da1 74 */
Davidroid 20:9952bef19da1 75 uint32_t PDM2PCMAudio::pcm2pdm_samples(uint32_t PCM_samples)
Davidroid 20:9952bef19da1 76 {
Davidroid 20:9952bef19da1 77 return PCM_samples * (_decimation_factor >> 4);
Davidroid 20:9952bef19da1 78 }
Davidroid 20:9952bef19da1 79
Davidroid 20:9952bef19da1 80 /**
Davidroid 20:9952bef19da1 81 * @brief Converting audio data from PDM to PCM.
Davidroid 20:9952bef19da1 82 * @param output_buffer Pointer to output PCM buffer data.
Davidroid 20:9952bef19da1 83 * @param input_buffer Pointer to input PDM buffer data.
Davidroid 20:9952bef19da1 84 * @param volume Volume level (it must be in the range [0..PDM2PCM_MAX_VOLUME]).
Davidroid 20:9952bef19da1 85 * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
Davidroid 20:9952bef19da1 86 */
Davidroid 20:9952bef19da1 87 status_t PDM2PCMAudio::convert(int16_t *output_buffer, uint16_t *input_buffer, uint32_t volume)
davide.aliprandi@st.com 2:9f389fd8fb2e 88 {
davide.aliprandi@st.com 2:9f389fd8fb2e 89 if (!(volume <= PDM2PCM_MAX_VOLUME))
Davidroid 20:9952bef19da1 90 error("Volume level not supported: it must be in the range [0..%d].\r\n", PDM2PCM_MAX_VOLUME);
davide.aliprandi@st.com 2:9f389fd8fb2e 91
Davidroid 20:9952bef19da1 92 #ifdef PDM2PCM_AUDIO_DEBUG
Davidroid 20:9952bef19da1 93 _pdm2pcm_audio_signal = 1;
Davidroid 20:9952bef19da1 94 #endif
Davidroid 20:9952bef19da1 95 switch (_decimation_factor)
davide.aliprandi@st.com 2:9f389fd8fb2e 96 {
davide.aliprandi@st.com 2:9f389fd8fb2e 97 case 64:
davide.aliprandi@st.com 7:9d6a4a53e640 98 for (uint32_t index = 0; index < _channels; index++) {
davide.aliprandi@st.com 2:9f389fd8fb2e 99 #ifdef USE_OPEN_PDM2PCM_LIBRARY
Davidroid 20:9952bef19da1 100 Open_PDM_Filter_64(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
davide.aliprandi@st.com 2:9f389fd8fb2e 101 #else
davide.aliprandi@st.com 2:9f389fd8fb2e 102 PDM_Filter_64_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
davide.aliprandi@st.com 2:9f389fd8fb2e 103 #endif
davide.aliprandi@st.com 2:9f389fd8fb2e 104 }
davide.aliprandi@st.com 2:9f389fd8fb2e 105 break;
davide.aliprandi@st.com 2:9f389fd8fb2e 106
davide.aliprandi@st.com 2:9f389fd8fb2e 107 case 128:
davide.aliprandi@st.com 2:9f389fd8fb2e 108 for (uint32_t index = 0; index < _channels; index++) {
davide.aliprandi@st.com 2:9f389fd8fb2e 109 #ifdef USE_OPEN_PDM2PCM_LIBRARY
Davidroid 20:9952bef19da1 110 Open_PDM_Filter_128(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
davide.aliprandi@st.com 2:9f389fd8fb2e 111 #else
davide.aliprandi@st.com 2:9f389fd8fb2e 112 PDM_Filter_128_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
davide.aliprandi@st.com 2:9f389fd8fb2e 113 #endif
davide.aliprandi@st.com 2:9f389fd8fb2e 114 }
davide.aliprandi@st.com 2:9f389fd8fb2e 115 break;
davide.aliprandi@st.com 2:9f389fd8fb2e 116
davide.aliprandi@st.com 2:9f389fd8fb2e 117 default:
davide.aliprandi@st.com 2:9f389fd8fb2e 118 error("Decimation factor not supported: it must be either 64 or 128.\r\n");
davide.aliprandi@st.com 2:9f389fd8fb2e 119 }
Davidroid 20:9952bef19da1 120 #ifdef PDM2PCM_AUDIO_DEBUG
Davidroid 20:9952bef19da1 121 _pdm2pcm_audio_signal = 0;
Davidroid 20:9952bef19da1 122 #endif
davide.aliprandi@st.com 2:9f389fd8fb2e 123
davide.aliprandi@st.com 2:9f389fd8fb2e 124 return COMPONENT_OK;
davide.aliprandi@st.com 2:9f389fd8fb2e 125 }
davide.aliprandi@st.com 2:9f389fd8fb2e 126
davide.aliprandi@st.com 2:9f389fd8fb2e 127 /**
davide.aliprandi@st.com 2:9f389fd8fb2e 128 * @brief Scrambling audio data.
davide.aliprandi@st.com 2:9f389fd8fb2e 129 * @param output_buffer Pointer to output PDM buffer data.
davide.aliprandi@st.com 2:9f389fd8fb2e 130 * @param input_buffer Pointer to input PDM buffer data.
davide.aliprandi@st.com 2:9f389fd8fb2e 131 * @param size Size of the buffers (thay has to be equally sized).
davide.aliprandi@st.com 2:9f389fd8fb2e 132 * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
davide.aliprandi@st.com 2:9f389fd8fb2e 133 */
davide.aliprandi@st.com 2:9f389fd8fb2e 134 status_t PDM2PCMAudio::scramble(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
davide.aliprandi@st.com 2:9f389fd8fb2e 135 {
davide.aliprandi@st.com 2:9f389fd8fb2e 136 for (uint32_t index = 0; index < size; index++) {
davide.aliprandi@st.com 2:9f389fd8fb2e 137 output_buffer[index] = HTONS(input_buffer[index]);
davide.aliprandi@st.com 2:9f389fd8fb2e 138 }
davide.aliprandi@st.com 2:9f389fd8fb2e 139
davide.aliprandi@st.com 2:9f389fd8fb2e 140 return COMPONENT_OK;
davide.aliprandi@st.com 2:9f389fd8fb2e 141 }
davide.aliprandi@st.com 2:9f389fd8fb2e 142
davide.aliprandi@st.com 2:9f389fd8fb2e 143 /**s
davide.aliprandi@st.com 2:9f389fd8fb2e 144 * @brief Demuxing audio data.
davide.aliprandi@st.com 2:9f389fd8fb2e 145 * @param output_buffer Pointer to output PDM buffer data.
davide.aliprandi@st.com 2:9f389fd8fb2e 146 * @param input_buffer Pointer to input PDM buffer data.
davide.aliprandi@st.com 2:9f389fd8fb2e 147 * @param size Size of the buffers (thay has to be equally sized).
davide.aliprandi@st.com 2:9f389fd8fb2e 148 * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
davide.aliprandi@st.com 2:9f389fd8fb2e 149 */
davide.aliprandi@st.com 2:9f389fd8fb2e 150 status_t PDM2PCMAudio::demux(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
davide.aliprandi@st.com 2:9f389fd8fb2e 151 {
davide.aliprandi@st.com 2:9f389fd8fb2e 152 for (uint32_t index = 0; index < size; index++) {
davide.aliprandi@st.com 2:9f389fd8fb2e 153 uint8_t a = ((uint8_t *) input_buffer)[index * 2];
davide.aliprandi@st.com 2:9f389fd8fb2e 154 uint8_t b = ((uint8_t *) input_buffer)[index * 2 + 1];
davide.aliprandi@st.com 2:9f389fd8fb2e 155 ((uint8_t *) (output_buffer))[index * 2] = _demux_filter[a & DEMUX_FILTER_MASK] | _demux_filter[b & DEMUX_FILTER_MASK] << 4;
davide.aliprandi@st.com 2:9f389fd8fb2e 156 ((uint8_t *) (output_buffer))[index * 2 + 1] = _demux_filter[(a >> 1) & DEMUX_FILTER_MASK] | _demux_filter[(b >> 1) & DEMUX_FILTER_MASK] << 4;
davide.aliprandi@st.com 2:9f389fd8fb2e 157 }
davide.aliprandi@st.com 2:9f389fd8fb2e 158
davide.aliprandi@st.com 2:9f389fd8fb2e 159 return COMPONENT_OK;
davide.aliprandi@st.com 2:9f389fd8fb2e 160 }
davide.aliprandi@st.com 2:9f389fd8fb2e 161
davide.aliprandi@st.com 2:9f389fd8fb2e 162 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/