Matlab处理音频文件
Audio_filename = ‘Audio.wav’;
% 获取原音频数据
[Audio,Audio_Fs]=audioread(Audio_filename, ‘native’);
% 取单声道
Audio_1 = int32(Audio(:, 1));
% -32768~32768 加偏移得到 0~65536
Audio_Output = uint16(Audio_1 + 32768);
% 写入文件
fid = fopen(‘Audio.bin’, ‘w’);
fwrite(fid, Audio_Output, ‘uint16’);
fclose(fid);
DAC播放
Tim2触发DAC+DMA播放音频
DAC配置
DAC_HandleTypeDef hdac1;
DMA_HandleTypeDef hdma_dac_ch1;
/* DAC1 init function */
void MX_DAC1_Init(void)
{
DAC_ChannelConfTypeDef sConfig = {0};
/** DAC Initialization
*/
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/** DAC channel OUT1 config
*/
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(dacHandle-》Instance==DAC1)
{
/* DAC1 clock enable */
__HAL_RCC_DAC1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**DAC1 GPIO Configuration
PA4 ------》 DAC1_OUT1
*/
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* DAC1 DMA Init */
/* DAC_CH1 Init */
hdma_dac_ch1.Instance = DMA2_Channel4;
hdma_dac_ch1.Init.Request = DMA_REQUEST_3;
hdma_dac_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_dac_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dac_ch1.Init.MemInc = DMA_MINC_ENABLE;
hdma_dac_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_dac_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_dac_ch1.Init.Mode = DMA_CIRCULAR;
hdma_dac_ch1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_dac_ch1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(dacHandle,DMA_Handle1,hdma_dac_ch1);
/* DAC1 interrupt Init */
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn);
}
}
void TIM6_DAC_IRQHandler(void)
{
HAL_DAC_IRQHandler(&hdac1);
}
void DMA2_Channel4_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_dac_ch1);
}
Tim配置
播放音频频率为441000
/* TIM2 init function */
/* 44.1KHz */
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 2;
htim2.Init.Period = 907-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
开始
#define AUDIO_SIZE 2048
uint8_t audio_data[AUDIO_SIZE*2] = {0};
void StartPlayer(void)
{
Player_StreamBuffer = xStreamBufferCreate(AUDIO_SIZE*10,AUDIO_SIZE);
if(NULL == Player_StreamBuffer)
Debug(“Player_StreamBuffer Create ERROR”);
/* 获取音频长度 */
AudioLen = *(uint32_t *)ADDR_AUDIO_LEN_START;
if ((AudioLen == 0xFFFFFFFF) || (AudioLen 》= E_FLASH_AUDIO_SIZE))
AudioLen = 1024*1024;
MX_DAC1_Init();
MX_TIM2_Init();
HAL_TIM_Base_Start(&htim2);
/* 左对齐的方式,取16位音频数据的高12位播放 */
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t *)audio_data, AUDIO_SIZE, DAC_ALIGN_12B_L);
}
应用层数据流向
数据流
void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac)
{
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
static uint8_t silent = 0;
if(xStreamBufferBytesAvailable(Player_StreamBuffer) 》= AUDIO_SIZE)
{
xStreamBufferReceiveFromISR(Player_StreamBuffer,audio_data,AUDIO_SIZE,&pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
if(silent)
{
silent = 0;
Debug(“Player Half Stream Be Recover rn”);
}
}
else
{
if(!silent)
{
silent = 1;
memset(audio_data,0,AUDIO_SIZE);
Debug(“Player Half Stream Be Empty rn”);
}
}
}
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
{
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
static uint8_t silent = 0;
if(xStreamBufferBytesAvailable(Player_StreamBuffer) 》= AUDIO_SIZE)
{
xStreamBufferReceiveFromISR(Player_StreamBuffer,(uint8_t*)(audio_data+AUDIO_SIZE),AUDIO_SIZE,&pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
if(silent)
{
silent = 0;
Debug(“Player Cplt Stream Be Recover rn”);
}
}
else
{
if(!silent)
{
silent = 1;
memset((uint8_t*)(audio_data+AUDIO_SIZE),0,AUDIO_SIZE);
Debug(“Player Cplt Stream Be Empty rn”);
}
}
}
获取音频
void GetAudioFormFlash(void)
{
size_t i;
if(xStreamBufferSpacesAvailable(Player_StreamBuffer) 》= AUDIO_SIZE)
{
if (flash_addr 》 (E_FLASH_AUDIO_START_ADDR + AudioLen))
{
/* 回到初始地址再次播放 */
flash_addr = E_FLASH_AUDIO_START_ADDR;
}
QSPI_ReadBuffer(audio_buffer, flash_addr, AUDIO_SIZE);
xStreamBufferSend(Player_StreamBuffer,audio_buffer,AUDIO_SIZE,0);
flash_addr += AUDIO_SIZE;
}
}
Matlab处理音频文件
Audio_filename = ‘Audio.wav’;
% 获取原音频数据
[Audio,Audio_Fs]=audioread(Audio_filename, ‘native’);
% 取单声道
Audio_1 = int32(Audio(:, 1));
% -32768~32768 加偏移得到 0~65536
Audio_Output = uint16(Audio_1 + 32768);
% 写入文件
fid = fopen(‘Audio.bin’, ‘w’);
fwrite(fid, Audio_Output, ‘uint16’);
fclose(fid);
DAC播放
Tim2触发DAC+DMA播放音频
DAC配置
DAC_HandleTypeDef hdac1;
DMA_HandleTypeDef hdma_dac_ch1;
/* DAC1 init function */
void MX_DAC1_Init(void)
{
DAC_ChannelConfTypeDef sConfig = {0};
/** DAC Initialization
*/
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/** DAC channel OUT1 config
*/
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_T2_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(dacHandle-》Instance==DAC1)
{
/* DAC1 clock enable */
__HAL_RCC_DAC1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**DAC1 GPIO Configuration
PA4 ------》 DAC1_OUT1
*/
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* DAC1 DMA Init */
/* DAC_CH1 Init */
hdma_dac_ch1.Instance = DMA2_Channel4;
hdma_dac_ch1.Init.Request = DMA_REQUEST_3;
hdma_dac_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_dac_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dac_ch1.Init.MemInc = DMA_MINC_ENABLE;
hdma_dac_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_dac_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_dac_ch1.Init.Mode = DMA_CIRCULAR;
hdma_dac_ch1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_dac_ch1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(dacHandle,DMA_Handle1,hdma_dac_ch1);
/* DAC1 interrupt Init */
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn);
}
}
void TIM6_DAC_IRQHandler(void)
{
HAL_DAC_IRQHandler(&hdac1);
}
void DMA2_Channel4_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_dac_ch1);
}
Tim配置
播放音频频率为441000
/* TIM2 init function */
/* 44.1KHz */
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 2;
htim2.Init.Period = 907-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
开始
#define AUDIO_SIZE 2048
uint8_t audio_data[AUDIO_SIZE*2] = {0};
void StartPlayer(void)
{
Player_StreamBuffer = xStreamBufferCreate(AUDIO_SIZE*10,AUDIO_SIZE);
if(NULL == Player_StreamBuffer)
Debug(“Player_StreamBuffer Create ERROR”);
/* 获取音频长度 */
AudioLen = *(uint32_t *)ADDR_AUDIO_LEN_START;
if ((AudioLen == 0xFFFFFFFF) || (AudioLen 》= E_FLASH_AUDIO_SIZE))
AudioLen = 1024*1024;
MX_DAC1_Init();
MX_TIM2_Init();
HAL_TIM_Base_Start(&htim2);
/* 左对齐的方式,取16位音频数据的高12位播放 */
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t *)audio_data, AUDIO_SIZE, DAC_ALIGN_12B_L);
}
应用层数据流向
数据流
void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac)
{
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
static uint8_t silent = 0;
if(xStreamBufferBytesAvailable(Player_StreamBuffer) 》= AUDIO_SIZE)
{
xStreamBufferReceiveFromISR(Player_StreamBuffer,audio_data,AUDIO_SIZE,&pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
if(silent)
{
silent = 0;
Debug(“Player Half Stream Be Recover rn”);
}
}
else
{
if(!silent)
{
silent = 1;
memset(audio_data,0,AUDIO_SIZE);
Debug(“Player Half Stream Be Empty rn”);
}
}
}
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
{
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
static uint8_t silent = 0;
if(xStreamBufferBytesAvailable(Player_StreamBuffer) 》= AUDIO_SIZE)
{
xStreamBufferReceiveFromISR(Player_StreamBuffer,(uint8_t*)(audio_data+AUDIO_SIZE),AUDIO_SIZE,&pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
if(silent)
{
silent = 0;
Debug(“Player Cplt Stream Be Recover rn”);
}
}
else
{
if(!silent)
{
silent = 1;
memset((uint8_t*)(audio_data+AUDIO_SIZE),0,AUDIO_SIZE);
Debug(“Player Cplt Stream Be Empty rn”);
}
}
}
获取音频
void GetAudioFormFlash(void)
{
size_t i;
if(xStreamBufferSpacesAvailable(Player_StreamBuffer) 》= AUDIO_SIZE)
{
if (flash_addr 》 (E_FLASH_AUDIO_START_ADDR + AudioLen))
{
/* 回到初始地址再次播放 */
flash_addr = E_FLASH_AUDIO_START_ADDR;
}
QSPI_ReadBuffer(audio_buffer, flash_addr, AUDIO_SIZE);
xStreamBufferSend(Player_StreamBuffer,audio_buffer,AUDIO_SIZE,0);
flash_addr += AUDIO_SIZE;
}
}
举报