ESP32, воспроизводящий wav, звучит искаженно или слишком быстро (но не все wav)

Я создаю звуковой проект на ESP 32 через I2S, используя пример из: https://github.com/nhatuan84/esp32-i2s-sdcard-wav-player

Это прекрасно работает с примером wav-файла t.wav, размещенного в репозитории.

Но когда я пытаюсь использовать пользовательский wav, который я экспортировал из audacity, он звучит искаженно и / или слишком медленно / быстро (это звучит нормально, когда я проигрываю его в audacity).

Это пример, который полностью искажается при воспроизведении с esp с помощью I2S: плохо звучащий wav Хотя это звучит нормально, когда играешь от audacity.

Я пробовал разные настройки при экспорте audacity 16 бит, 32 бит. 44100 Гц, 11025.

Какие-нибудь подсказки или советы, что я мог бы попробовать или делаю неправильно?

Спасибо!

Йерун

, 👍1

Обсуждение

Предоставленный файл из репозитория является 16-битным моно с частотой 11025 Гц. Вы пробовали эти настройки?, @chrisl

@crisl да, я сделал (по крайней мере, я думаю, что сделал, но я не эксперт по дерзости ...), Это этот файл: [ссылка] (http://vandevorst.com/temp/starting11025 ) файл 11025. Этот файл не искажается, но воспроизводится слишком быстро (я думаю, в два раза быстрее)., @Jeroen

@jstola. Не уверен, что понимаю, что вы предлагаете. Я создал wav-файл из https://text-to-speech-demo.ng.bluemix.net /. Затем я открыл его в audacity, преобразовал его в несколько разных частот дискретизации, экспортировал файл в 16-битный pcm wav и поместил его на sd. Я просто попытался скопировать файл обратно с компьютера и воспроизвести его, и это работает нормально, @Jeroen

похоже, возможно, скорость передачи данных слишком высока или низка, в зависимости от вашей точки зрения. я вижу файл github как монофонический 32-битный файл с плавающей запятой при 11 кб. скорее всего, вам просто нужно продолжать пробовать перестановки настроек, пока вы не добьетесь успеха., @dandavis


1 ответ


2

Я знаю, что это старый вопрос, но я столкнулся с той же проблемой и потратил несколько дней, пытаясь разобраться в ней, поэтому я надеюсь, что этот ответ сможет спасти от этого еще одну бедную душу:

В чем проблема

Для справки, у меня есть ESP32 (HUZZAH32 от Adafruit), подключенный к распределительной плате, которая использует микросхему PCM5102a в качестве внешнего ЦАП. Я бы установил частоту дискретизации на 44,1 кГц, но, похоже, моя песня, которая, как я подтвердил, имела точные данные, будет воспроизводиться с удвоенной скоростью. Снижение частоты дискретизации до 22,05 кГц позволило ему воспроизводиться с правильной скоростью, но качество, казалось, снизилось.

Первопричина

Проблема заключалась в том, что для моего значения .channel_format было установлено значение I2S_CHANNEL_FMT_RIGHT_LEFT, однако мои данные были смешаны с mono в Audacity. Эта проблема может проявляться по-разному в зависимости от того, как вы передаете байты через I2S, но для меня это означало двойную скорость. Это связано с тем, что протокол считывал каждые 2 выборки (которые должны быть отдельными) как левый / правый каналы. Фактически это означало, что он пропускал все остальные сэмплы, что удваивало скорость воспроизведения в два раза.

Фрагменты кода

Мой код i2s_config_t:

#define DMA_BUFFER_COUNT 8
#define DMA_BUFFER_LENGTH 1024

i2s_config_t i2s_config = {
    .mode = I2S_MODE_MASTER | I2S_MODE_TX,
    .sample_rate = 44100,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // это приводило к удвоению скорости из-за того, что I2S_CHANNEL_FMT_RIGHT_LEFT 
    .communication_format = (i2s_comm_format_t) (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .tx_desc_auto_clear = true,
    .dma_buf_count = DMA_BUFFER_COUNT,
    .dma_buf_len = DMA_BUFFER_LENGTH,
    .use_apll = false, 
    .intr_alloc_flags = 0
};

Мой код для отправки байтов во внешний ЦАП (что является его собственной задачей):

(rx_buffer и readPointer здесь являются частью кольцевого буфера, который я передал через Wi-Fi для отдельной задачи, пожалуйста, используйте только в качестве ссылки и замените свои собственные звуковые данные)

int FRAMES_TO_SEND = 1024;
int32_t frames[FRAMES_TO_SEND];

for (int i = 0; i < FRAMES_TO_SEND; i++) {
    // скопировать в буфер i2s
    int32_t sample = (int32_t)rx_buffer[readPointer]; 
    
    // запись байтов на периферийное устройство i2s
    esp_err_t err = i2s_write(i2s_num, (char *) &sample,
        sizeof(int32_t), &bytesWritten, 100);
            
    if(err != ESP_OK) {
        printf("ESP32 i2s Errorcode %i", err);
    }

    readPointer++;
    if (readPointer == TOTAL_BUFFER_SIZE) {
        readPointer = 0;
    }
}

Надеюсь, это поможет некоторым из вас или, по крайней мере, поможет вам найти решение. К сожалению, протокол I2S на ESP32 не очень хорошо документирован, поэтому приходится прибегать к множеству проб и ошибок. Продолжайте в том же духе!

,