Конвертировать 16 бит PCM в 8 бит - PullRequest
5 голосов
/ 19 апреля 2011

У меня аудио pcm хранится в байтовом массиве.Это 16 бит на выборку.Я хочу сделать это 8 бит на семпл аудио.

Кто-нибудь может предложить хороший алгоритм для этого?

Я не упомянул битрейт, потому что я думаю, что это не важно для алгоритма - верно?

Ответы [ 4 ]

8 голосов
/ 19 апреля 2011

Я не вижу сейчас, почему недостаточно просто взять старший байт, то есть отбросить младшие 8 бит каждого семпла.

Это, конечно, предполагает, что образцы являются линейными; если это не так, возможно, вам нужно что-то сделать для их линеаризации, прежде чем отбрасывать биты.

short sixteenBit = 0xfeed;
byte eightBit = sixteenBit >> 8;
// eightBit is now 0xfe.

Как было предложено AShelly в комментарии, было бы неплохо округлить, т.е. добавить 1, если отбрасываемый нами байт больше половины своего максимума:

eightBit += eightBit < 0xff && ((sixteenBit & 0xff) > 0x80);

В тесте против 0xff реализовано ограничение, поэтому мы не рискуем добавить 1 к 0xff и перенести его в 0x00, что было бы плохо.

6 голосов
/ 13 сентября 2013

16-битные сэмплы обычно подписаны, а 8-битные сэмплы, как правило, без знака, поэтому самый простой ответ заключается в том, что вам необходимо преобразовать 16-битные сэмплы из подписанных (16-битные сэмплы почти всегда хранятся в диапазоне от От -32768 до +32767) до знака без знака и затем взять верхние 8 битов результата. В C это может быть выражено как output = (unsigned char) ((unsigned short) (input + 32768) >> 8). Это хорошее начало, и может быть достаточно для ваших нужд, но звучит не очень хорошо. Звучит грубо из-за "шума квантования".

Шум квантования - это разница между исходным входом и выходом вашего алгоритма. Независимо от того, что вы делаете, вы будете иметь шум, и шум будет в среднем «полусредним». С этим ничего нельзя поделать, но есть способы сделать шум менее заметным.

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

Чтобы получить хороший результат, необходимо добавить дизеринг. Дизеринг - это метод, который пытается сгладить шум квантования. Самое простое сглаживание просто удаляет шаблоны из шума, чтобы шаблоны шума не отвлекали от фактических сигналов. Лучшее сглаживание может пойти еще дальше и предпринять шаги по снижению шума, сложив значения ошибок из нескольких выборок, а затем добавив поправку, когда общая ошибка становится достаточно большой, чтобы ее стоило исправить.

Вы можете найти объяснения и примеры кода для различных алгоритмов дизеринга в Интернете. Хорошей областью для исследования может быть инструмент SoX, http://en.wikipedia.org/wiki/SoX. Проверьте источник на наличие эффекта сглаживания и поэкспериментируйте с преобразованием различных звуков из 16-битных в 8-битные с включенным и без включения сглаживания. Вы будете удивлены различием в качестве, которое может создать сглаживание при преобразовании в 8-битный звук.

1 голос
/ 09 декабря 2015
byteData = (byte) (((shortData +32768)>>8)& 0xFF) 

это сработало для меня.

1 голос
/ 12 ноября 2012

Нормализуйте 16-битные выборки, затем измените масштаб на максимальное значение вашей 8-битной выборки.

Это дает более точное преобразование, так как младшие 8 бит каждого семпла не отбрасываются.Однако мое решение в вычислительном отношении дороже, чем выбранный ответ.

...