Запись 8-битного PCM-файла синусоидальной волны PCM создает обертоны

Я написал программу на C++ для генерации WAV-файла для синусоидальной волны 800 Гц (1-канальная, 8-битная, 16000 Гц, 32000 выборок, длительностью 2 секунды), но когда я воспроизводил его или изучал его спектрограмму в Audacity, он имел обертоны.

Я думаю, что проблема в алгоритме преобразования синусоиды в PCM; Я не уверен, где поставить "нулевое" смещение, на 127, или 127,5, или 128 и т. Д.

char data[32000];
for (int j = 0; j < 32000; ++j)
{
    data[j] = (char) (round(127 + 60 * (sin(2.0 * 3.14159265358979323846264338327950 * j / 20.0))));
}

и полученный файл выглядит так: output.wav

Если необходимо, вот файл cpp: wavwriter.cpp

Спасибо!

РЕДАКТИРОВАТЬ 2: я изменил char на uint8_t

uint8_t data[32000];
for (int j = 0; j < 32000; ++j)
{ 
    data[j] = round(127 + 60 * (sin(2.0 * 3.14159265358979323846264338327950 * j / 20.0)));


}
outfile.write((char *)&data[0], sizeof data);


outfile.close();
return true;

чтобы избежать неопределенного поведения. Та же проблема все еще применяется.

1 ответ

Вы добавили шум округления и детерминированный шум квантования. Ваша синусоида повторяется с точным целым числом образцов; таким образом, ошибка округления (или разность между значением с плавающей точкой и значением UInt_8 вашей синусоиды) повторяется ровно периодически, что создает слышимые гармоники.

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

Сглаживание (или добавление дробных случайных значений к каждой выборке перед округлением) удаляет детерминированный шум. Результирующий шум будет белее, а не из обертонов.

Шумовая фильтрация не просто отбрасывает дробную часть из округления, но объединяет этот дробный остаток с БИХ-фильтром, чтобы переместить шум квантования туда, где он может быть менее слышимым и с меньшей вероятностью создать смещение постоянного тока.

Другие вопросы по тегам