我正在尝试通过 SDIO 从我的 SD 中读取 2 个带有 FATFS 的文件并混合 16 位 PCM 音频数据。它可以工作,但输出声音在播放 2 个文件时速度较慢,听起来不太好。
我使用 I2S 将数据发送到 IC。我的 Buffersize 是 4096。如果不混合 2 个缓冲区,音频质量就很好。当我使用该示例混合我在网上找到的缓冲区时,您会听到很多噪音。
有任何想法吗?
我的代码:
volatile uint16_t* signal_play_buff = NULL;
uint16_t* signal_read_buff = NULL;
uint16_t* signal_read_buff2 = NULL;
volatile uint16_t signal_buff1[4096];
volatile uint16_t signal_buff2[4096];
HAL_StatusTypeDef hal_res;
int nsamples = sizeof(signal_buff1) / sizeof(signal_buff1[0]);
hal_res = HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal_buff1, nsamples);
if(hal_res != HAL_OK) {
UART_Printf("I2S - HAL_I2S_Transmit failed, hal_res = %d!\r\n", hal_res);
f_close(&file);
return -12;
}
FIL file2;
FRESULT res2 = f_open(&file2, "over.raw", FA_READ);
while(bytesRead >= sizeof(signal_buff1)) {
if(!read_next_chunk) {
continue;
}
read_next_chunk = false;
res = f_read(&file, (uint8_t*)signal_read_buff, sizeof(signal_buff1), &bytesRead);
res2 = f_read(&file2, (uint8_t*)signal_buff3, sizeof(signal_buff3), &bytesRead2);
for(int i = 0; i < sizeof(signal_buff1) /2; i++){
uint16_t a = signal_read_buff[i]; // first sample
uint16_t b = signal_buff3[i]; // second sample
uint16_t m; // mixed result will go here
// Pick the equation
if ((a < 32768) || (b < 32768)) {
// Viktor's first equation when both sources are "quiet"
// (i.e. less than middle of the dynamic range)
m = a * b / 32768;
} else {
// Viktor's second equation when one or both sources are loud
m = 2 * (a + b) - (a * b) / 32768 - 65536;
}
if (m == 65536) m = 65535;
signal_read_buff[i] = m;
}
if(res != FR_OK) {
UART_Printf("f_read() failed, res = %d\r\n", res);
f_close(&file);
return -13;
}
}
end_of_file_reached = true;
res = f_close(&file);
if(res != FR_OK) {
UART_Printf("f_close() failed, res = %d\r\n", res);
return -14;
}
return 0;
}
I2S 回调发送下一个缓冲区
void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) {
if(end_of_file_reached)
return;
volatile uint16_t* temp = signal_play_buff;
signal_play_buff = signal_read_buff;
signal_read_buff = temp;
int nsamples = sizeof(signal_buff1) / sizeof(signal_buff1[0]);
HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal_play_buff, nsamples);
read_next_chunk = true;
}