Вопрос

У меня есть буфер со множеством положительных 16-битных значений (которые хранятся как двойные значения), которые я хотел бы квантовать до 8-битных (значения 0–255).

В соответствии с Википедия процесс будет:

  • Нормализовать 16-битные значения.Т.е.найдите самое большое и разделите на него.
  • Используйте формулу Q(x) с M=8.

Итак, мне интересно, есть ли в C функция, которая может выполнять такое квантование, или знает ли кто-нибудь о реализации C, которую я мог бы использовать?

Много любви, Луиза

Это было полезно?

Решение

Предполагая значение d находится в интервале [0.0, max]:

unsigned char quantize(double d, double max)
{
    return (unsigned char)((d / max) * 255.0);
}

Я не уверен, что вы имеете в виду под "16-битными значениями"; Двойные значения точности составляют 64-разрядные в любой системе с использованием IEEE-754.Однако если у вас есть значения другого числового типа, процесс фактически тот же.

Другие советы

Это похоже на обработку аудиосигнала, где ваш вход — 16-битные данные PCM, ваш выход — 8-битные данные PCM, и вы используете двойные значения в качестве промежуточного значения.

Однако 8-битные волновые данные PCM НЕ просто квантуются, их представление представляет собой беззнаковые значения, превышающие 128 обозначений.(например, как показатели степени хранятся в числах с плавающей запятой)

Нахождение наибольшего значения первым будет означать не только квантование, но и масштабирование.Итак, в псевдокоде

double dMax = max_of_all_values(); // 
...
foreach (dValue in array_of_doubles)
{
   signed char bValue = (signed char)((dValue / dMax)*127.0);
}

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

Примечание:этот подписанный символ НЕ является правильным, если выходные данные представляют собой 8-битные данные PCM, но, поскольку вопросы специально не запрашивают это, я пропустил это.

Редактировать:если это будет использоваться как данные пикселей, вам нужны беззнаковые значения.Я вижу, что Джеймс уже дал правильный ответ для беззнаковых значений, когда входные данные беззнаковые (значения в дБ из нормализованных данных на самом деле должны быть отрицательными)

Из вашего вопроса неясно, что такое кодировка, поскольку "положительные 16-битные значения (которые хранятся как двойные значения)«не имеет реального смысла;они либо 16-битные, либо двойные, они не могут быть обоими.

Однако если предположить, что это 16-битные беззнаковые данные, нормализованные до 1,0 (поэтому значения варьируются от 0,0 <= с <= 1,0), то все, что вам нужно сделать, чтобы расширить их до 8-битных целочисленных значений, — это умножить каждую выборку на 255.

unsigned char s8 = s * 255 ;

Если диапазон не 0,0 <= с <= 1,0, но 0,0 <= с <= Макс затем:

unsigned char s8 = s / max * 255 ;

В любом случае, не существует никакой функции «квантования», кроме той, которую вы можете написать сами;но необходимое преобразование, несомненно, будет простым арифметическим выражением (хотя и не таким простым, если данные, возможно, компандируются - т.е.Например, кодирование μ-lay или A-law).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top