stm32h743_player/User/audio/audio_hal.c
2024-04-08 23:51:58 +08:00

98 lines
2.8 KiB
C

#include "audio_hal.h"
#include <string.h>
#include "main.h"
#include "elog.h"
#include "FreeRTOS.h"
#include "queue.h"
#include "heap.h"
static const char *TAG = "audio_hal";
typedef struct {
void *buffer_ptr;
uint32_t buffer_size;
} audio_sample_t;
static QueueHandle_t audio_queue = NULL;
static uint8_t *audio_buffer = NULL;
static uint32_t audio_buffer_length = 0;
void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
BaseType_t need_yield = pdFALSE;
// audio_sample_t sample;
if (xQueueReceiveFromISR(audio_queue, &audio_buffer[0], &need_yield) == pdTRUE) {
// memcpy(&audio_buffer[0], sample.buffer_ptr, sample.buffer_size); //复制到第一个缓冲区
// free(sample.buffer_ptr); //释放使用完的缓冲区
}
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
portYIELD_FROM_ISR(need_yield);
}
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
{
BaseType_t need_yield = pdFALSE;
// audio_sample_t sample;
if (xQueueReceiveFromISR(audio_queue, &audio_buffer[audio_buffer_length / 2], &need_yield) == pdTRUE) {
// memcpy(&audio_buffer[audio_buffer_length / 2], sample.buffer_ptr, sample.buffer_size); //复制到第二个缓冲区
// free(sample.buffer_ptr); //释放使用完的缓冲区
}
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
portYIELD_FROM_ISR(need_yield);
}
void audio_hal_start(uint32_t sample_count, uint8_t sample_size)
{
audio_buffer_length = sample_count * sample_size * 2; //双缓冲
elog_info(TAG, "audio_hal_start: sample_count=%d, sample_size=%d, allocating %d bytes for audio buffer",
sample_count, sample_size, audio_buffer_length);
if (audio_buffer != NULL) {
elog_warn(TAG, "audio_hal_start: audio_buffer is not freed");
free_ahb(audio_buffer);
}
audio_buffer = malloc_ahb(audio_buffer_length);
memset(audio_buffer, 0, audio_buffer_length);
if (audio_queue != NULL) {
elog_warn(TAG, "audio_hal_start: audio_queue is not deleted");
vQueueDelete(audio_queue);
}
audio_queue = xQueueCreate(AUDIO_HAL_SAMPLE_QUEUE_SIZE, audio_buffer_length/2);
HAL_SAI_Transmit_DMA(&hsai_BlockB1, audio_buffer, sample_count * 2); //开始DMA循环发送
}
void audio_hal_stop(void)
{
HAL_SAI_DMAStop(&hsai_BlockB1);
vQueueDelete(audio_queue);
audio_queue = NULL;
free_ahb(audio_buffer);
audio_buffer = NULL;
}
void audio_hal_write(void *buffer_ptr, uint32_t buffer_size)
{
if (buffer_size == 0) {
return;
}
// audio_sample_t sample = {
// .buffer_ptr = buffer_ptr,
// .buffer_size = buffer_size
// };
if (uxQueueSpacesAvailable(audio_queue) == AUDIO_HAL_SAMPLE_QUEUE_SIZE) {
elog_warn(TAG, "audio_hal_write: queue is empty before xQueueSend");
}
xQueueSend(audio_queue, buffer_ptr, portMAX_DELAY); //发送缓冲区到队列中
}