ST / X_NUCLEO_CCA02M1

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PDM2PCMAudio.cpp Source File

PDM2PCMAudio.cpp

00001 /**
00002  ******************************************************************************
00003  * @file    PDM2PCMAudio_class.cpp
00004  * @author  AST / Software Platforms and Cloud
00005  * @version V1.0
00006  * @date    November 10th, 2016
00007  * @brief   Implementation file for the PDM2PCMAudio conversion library.
00008  ******************************************************************************
00009  * @attention
00010  *
00011  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *   1. Redistributions of source code must retain the above copyright notice,
00016  *      this list of conditions and the following disclaimer.
00017  *   2. Redistributions in binary form must reproduce the above copyright notice,
00018  *      this list of conditions and the following disclaimer in the documentation
00019  *      and/or other materials provided with the distribution.
00020  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021  *      may be used to endorse or promote products derived from this software
00022  *      without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  ******************************************************************************
00036  */
00037 
00038 
00039 /* Includes ------------------------------------------------------------------*/
00040 
00041 #include "PDM2PCMAudio.h"
00042 
00043 
00044 /* Variables -----------------------------------------------------------------*/
00045 
00046 /* Demux filter. */
00047 const uint8_t PDM2PCMAudio::_demux_filter[DEMUX_FILTER_SIZE] =
00048 {
00049     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00050     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00051     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00052     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00053     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00054     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00055     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00056     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00057     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00058     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00059     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
00060     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
00061     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00062     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00063     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
00064     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
00065 };
00066 
00067 
00068 /* Methods -------------------------------------------------------------------*/
00069 
00070 /**
00071  * @brief  Getting number of PCM samples from nummber of PDM samples.
00072  * @param  PCM_samples Number of PCM samples.
00073  * @retval Number of equivalent PDM samples.
00074  */
00075 uint32_t PDM2PCMAudio::pcm2pdm_samples(uint32_t PCM_samples)
00076 {
00077     return PCM_samples * (_decimation_factor >> 4);
00078 }
00079 
00080 /**
00081  * @brief  Converting audio data from PDM to PCM.
00082  * @param  output_buffer     Pointer to output PCM buffer data.
00083  * @param  input_buffer      Pointer to input PDM buffer data.
00084  * @param  volume            Volume level (it must be in the range [0..PDM2PCM_MAX_VOLUME]).
00085  * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
00086  */
00087 status_t PDM2PCMAudio::convert(int16_t *output_buffer, uint16_t *input_buffer, uint32_t volume)
00088 {
00089     if (!(volume <= PDM2PCM_MAX_VOLUME))
00090         error("Volume level not supported: it must be in the range [0..%d].\r\n", PDM2PCM_MAX_VOLUME);
00091 
00092 #ifdef PDM2PCM_AUDIO_DEBUG
00093                 _pdm2pcm_audio_signal = 1;
00094 #endif
00095     switch (_decimation_factor)
00096     {
00097         case 64:
00098             for (uint32_t index = 0; index < _channels; index++) {
00099 #ifdef USE_OPEN_PDM2PCM_LIBRARY
00100                 Open_PDM_Filter_64(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
00101 #else                
00102                 PDM_Filter_64_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
00103 #endif
00104             }
00105             break;
00106 
00107         case 128:
00108             for (uint32_t index = 0; index < _channels; index++) {
00109 #ifdef USE_OPEN_PDM2PCM_LIBRARY
00110                 Open_PDM_Filter_128(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (TPDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
00111 #else                
00112                 PDM_Filter_128_LSB(&((uint8_t *) input_buffer)[index], (uint16_t *) &(output_buffer[index]), volume, (PDMFilter_InitStruct *) &_PDM2PCM_filter[index]);
00113 #endif
00114             }
00115             break;
00116 
00117         default:
00118             error("Decimation factor not supported: it must be either 64 or 128.\r\n");
00119     }
00120 #ifdef PDM2PCM_AUDIO_DEBUG
00121                 _pdm2pcm_audio_signal = 0;
00122 #endif
00123 
00124     return COMPONENT_OK;
00125 }
00126 
00127 /**
00128  * @brief  Scrambling audio data.
00129  * @param  output_buffer Pointer to output PDM buffer data.
00130  * @param  input_buffer  Pointer to input PDM buffer data.
00131  * @param  size          Size of the buffers (thay has to be equally sized).
00132  * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
00133  */
00134 status_t PDM2PCMAudio::scramble(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
00135 {
00136     for (uint32_t index = 0; index < size; index++) {
00137         output_buffer[index] = HTONS(input_buffer[index]);
00138     }
00139 
00140     return COMPONENT_OK;
00141 }
00142 
00143 /**s
00144  * @brief  Demuxing audio data.
00145  * @param  output_buffer Pointer to output PDM buffer data.
00146  * @param  input_buffer  Pointer to input PDM buffer data.
00147  * @param  size          Size of the buffers (thay has to be equally sized).
00148  * @retval COMPONENT_OK in case of success, COMPONENT_ERROR otherwise.
00149  */
00150 status_t PDM2PCMAudio::demux(uint16_t *output_buffer, uint16_t *input_buffer, uint32_t size)
00151 {
00152     for (uint32_t index = 0; index < size; index++) {
00153         uint8_t a = ((uint8_t *) input_buffer)[index * 2];
00154         uint8_t b = ((uint8_t *) input_buffer)[index * 2 + 1];
00155         ((uint8_t *) (output_buffer))[index * 2] = _demux_filter[a & DEMUX_FILTER_MASK] | _demux_filter[b & DEMUX_FILTER_MASK] << 4;
00156         ((uint8_t *) (output_buffer))[index * 2 + 1] = _demux_filter[(a >> 1) & DEMUX_FILTER_MASK] | _demux_filter[(b >> 1) & DEMUX_FILTER_MASK] << 4;
00157     }
00158 
00159     return COMPONENT_OK;
00160 }
00161 
00162 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/