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
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.
BSP/PDM2PCMAudio.cpp@2:9f389fd8fb2e, 2017-04-21 (annotated)
- Committer:
- davide.aliprandi@st.com
- Date:
- Fri Apr 21 10:33:08 2017 +0200
- Revision:
- 2:9f389fd8fb2e
- Child:
- 7:9d6a4a53e640
Aligned to ARM mbed codinmg style; OpenPDM2PCM middleware added.
Who changed what in which revision?
User | Revision | Line number | New 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>© 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 | /** |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 71 | * @brief Converting audio data from PDM to PCM. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 72 | * @param output_buffer Pointer to output PCM buffer data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 73 | * @param input_buffer Pointer to input PDM buffer data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 74 | * @param volume Volume level (it must be in the range [0..64]). |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 75 | * @param decimation_factor Decimation factor (it must be either 64 or 128). |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 76 | * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 77 | */ |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 78 | status_t PDM2PCMAudio::convert(int16_t *output_buffer, uint16_t *input_buffer, uint32_t volume, uint32_t decimation_factor) |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 79 | { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 80 | if (!(volume <= PDM2PCM_MAX_VOLUME)) |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 81 | error("Volume level not supported: it must be in the range [0..64].\r\n"); |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 82 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 83 | switch (decimation_factor) |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 84 | { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 85 | case 64: |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 86 | for (uint32_t index = 0; index < 1/*_channels*/; index++) { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 87 | #ifdef PDM2PCM_AUDIO_DEBUG |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 88 | _pdm2pcm_audio_signal = 1; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 89 | #endif |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 90 | #ifdef USE_OPEN_PDM2PCM_LIBRARY |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 91 | Open_PDM_Filter(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]); |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 92 | #else |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 93 | 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 | 94 | #endif |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 95 | #ifdef PDM2PCM_AUDIO_DEBUG |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 96 | _pdm2pcm_audio_signal = 0; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 97 | #endif |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 98 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 99 | break; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 100 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 101 | case 128: |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 102 | for (uint32_t index = 0; index < _channels; index++) { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 103 | #ifdef USE_OPEN_PDM2PCM_LIBRARY |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 104 | Open_PDM_Filter(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]); |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 105 | #else |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 106 | 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 | 107 | #endif |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 108 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 109 | break; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 110 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 111 | default: |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 112 | error("Decimation factor not supported: it must be either 64 or 128.\r\n"); |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 113 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 114 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 115 | return COMPONENT_OK; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 116 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 117 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 118 | /** |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 119 | * @brief Scrambling audio data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 120 | * @param output_buffer Pointer to output PDM buffer data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 121 | * @param input_buffer Pointer to input PDM buffer data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 122 | * @param size Size of the buffers (thay has to be equally sized). |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 123 | * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 124 | */ |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 125 | status_t PDM2PCMAudio::scramble(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size) |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 126 | { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 127 | for (uint32_t index = 0; index < size; index++) { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 128 | output_buffer[index] = HTONS(input_buffer[index]); |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 129 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 130 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 131 | return COMPONENT_OK; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 132 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 133 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 134 | /**s |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 135 | * @brief Demuxing audio data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 136 | * @param output_buffer Pointer to output PDM buffer data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 137 | * @param input_buffer Pointer to input PDM buffer data. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 138 | * @param size Size of the buffers (thay has to be equally sized). |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 139 | * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise. |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 140 | */ |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 141 | status_t PDM2PCMAudio::demux(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size) |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 142 | { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 143 | for (uint32_t index = 0; index < size; index++) { |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 144 | uint8_t a = ((uint8_t *) input_buffer)[index * 2]; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 145 | uint8_t b = ((uint8_t *) input_buffer)[index * 2 + 1]; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 146 | ((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 | 147 | ((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 | 148 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 149 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 150 | return COMPONENT_OK; |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 151 | } |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 152 | |
davide.aliprandi@st.com | 2:9f389fd8fb2e | 153 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |