Есть ли в C функция квантования?
-
21-09-2019 - |
Вопрос
У меня есть буфер со множеством положительных 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).