2021-02-23 07:40 PM
I am learning I2S to record voice but I met some questions.
Q1: I try to change the Filter.Fs form 16000 to 24000 ,but I can't get clear voice.
I don't Know why. How can i do?
Q2: I read the AN3998 "PDM audio software decoding library description "
and I calculate Input buffer length and Output buffer length are 64 and 8
respectively, why PCM_OUT_SIZE of this code is 16 not 8 ?
Output frequency = 8000
decimation factor = 64
Input Microphone Channels =1
Output Microphone Channels =1
Input buffer length = 8000 / 1000 * 64 *1/8 =64
Output buffer length= 8000 / 1000 *1 =8 <=
*following description is "PDM audio software decoding library description"
The PDM library is composed of a structure and the implementation of four PDM filter functions. The library uses two buffers, the PDM Input buffer and the PCM Output buffer; the application must define these buffers in the main program.
�? Input buffer (data) is a uint8 variable with a length equal to (Output frequency / 1000 * decimation factor * Input Microphone Channels / 8) at least.
�? Output buffer (dataOut) is a uint16 variable with a length equal to (Output frequency / 1000 * Output Microphone Channels) at least. The structure is defined in the pdm_filter.h file and is used to configure the filter; it is composed as follows: typedef struct { uint16_t Fs; float LP_HZ; float HP_HZ; uint16_t Out_MicChannels; char InternalFilter[34]; } PDMFilter_InitStruct;
*following code is sample code.
/* Audio recording frequency in Hz */
#define REC_FREQ 8000
/* PDM buffer input size */
#define INTERNAL_BUFF_SIZE 64
/* PCM buffer output size */
#define PCM_OUT_SIZE 16
uint32_t WaveRecorderInit(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
{
/* Check if the interface is already initialized */
if (AudioRecInited)
{
/* No need for initialization */
return 0;
}
else
{
/* Enable CRC module */
RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN;
/* Filter LP & HP Init */
Filter.LP_HZ = 8000;
Filter.HP_HZ = 100;
Filter.Fs = 16000;
Filter.Out_MicChannels = 1;
Filter.In_MicChannels = 1;
PDM_Filter_Init((PDMFilter_InitStruct *)&Filter);
/* Configure the GPIOs */
WaveRecorder_GPIO_Init();
/* Configure the interrupts (for timer) */
WaveRecorder_NVIC_Init();
/* Configure the SPI */
WaveRecorder_SPI_Init(AudioFreq);
/* Set the local parameters */
AudioRecBitRes = BitRes;
AudioRecChnlNbr = ChnlNbr;
/* Set state of the audio recorder to initialized */
AudioRecInited = 1;
/* Return 0 if all operations are OK */
return 0;
}
}
void AUDIO_REC_SPI_IRQHANDLER(void)
{
u16 volume;
u16 app;
/* Check if data are available in SPI Data register */
if (SPI_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
{
app = SPI_I2S_ReceiveData(SPI2);
InternalBuffer[InternalBufferSize++] = HTONS(app);
/* Check to prevent overflow condition */
if (InternalBufferSize >= INTERNAL_BUFF_SIZE)
{
InternalBufferSize = 0;
volume = 50;
PDM_Filter_64_LSB((uint8_t *)InternalBuffer, (uint16_t *)pAudioRecBuf, volume , (PDMFilter_InitStruct *)&Filter);
Data_Status = 1;
}
}
}