stm32 SD Card Микширование аудио - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь прочитать 2 файла с FATFS с моей SD через SDIO и смешать 16-битные аудиоданные PCM. Это работает, но выходной звук при воспроизведении 2 файлов медленнее и не очень хорошо звучит.

Я использую I2S для отправки данных на I C. Мой размер буфера - 4096. Без микширования двух буферов качество звука хорошее. Когда я использую пример для микширования буферов, которые я нашел в Интернете, вы можете услышать много шума.

Есть идеи?

мой код:

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;
}
...