Масштабирование целочисленных значений (из числа с плавающей точкой) - PullRequest
2 голосов
/ 27 января 2011

Я разрабатываю подключаемый модуль VST Audio, который требует извлечения амплитудных данных из входящего сигнала, который будет использоваться для настройки скорости в области миди.

По сути, я буду получать значения в диапазоне 0-1(float) и нужно преобразовать их в 0-127 int.

В настоящее время процесс будет состоять в умножении значения с плавающей запятой на 100, чтобы получить целое значение с +3 десятичными разрядами, т.е.1006 * Отсюда я округлю значения с плавающей точкой до целых, используя функцию floor ().

Однако это оставит меня со значениями от 0 до 100;однако мне нужно масштабировать их до 0-127.

Будем весьма благодарны за любые предложения о том, как это можно сделать.

Ответы [ 7 ]

5 голосов
/ 27 января 2011

Правильный способ сделать это:

int amplitude = 128 * value ;
if (amplitude == 128) amplitude = 127 ;
5 голосов
/ 27 января 2011

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

Вы можете подумать, что округление поможет, но это не так.Число значений в 127 будет по-прежнему только вдвое меньше других значений, и теперь число значений в 0 также будет вдвое меньше среднего.

Правильная формула:

int amplitude = static_cast<int>(value * (128-epsilon)); // where epsilon is a very small floating point value
4 голосов
/ 27 января 2011

Преобразование диапазона не так просто. В случае масштабирования целочисленного диапазона [-n; n] для плавания, используя наивный подход простого умножения, приводит к тому, что обратное отображение, скорее всего, не будет отображаться в исходные значения. Скажем, у вас есть набор всех чисел в целочисленном диапазоне и набор одинаковой величины в диапазоне с плавающей запятой, наивное отображение не является биективным.

Есть хороший документ об этом и примере кода, о том, как реализовать монотонность и упорядочение сохраняющих отображений в http://kaba.hilvi.org/programming/range/index.htm

4 голосов
/ 27 января 2011

Просто умножьте свое значение на 127 и приведите к int. [0,1]*127 => [0,127]

2 голосов
/ 27 января 2011

Я думаю, что я что-то упускаю.почему бы не умножить на 127,0 вместо 100?

1 голос
/ 01 декабря 2018

Я использую этот эффективный обходной путь, чтобы покрыть все значения с помощью функции round ().

выход = круглый (ампиэза * 127,5 + 127,5)

ampiezza - подписанное число с плавающей точкой от -1 до +1 вывод - 8-битное целое число

выходной диапазон от 0 до 255 с центром между 127 и 128

Надеюсь, это поможет.

0 голосов
/ 27 января 2011

Умножьте полученное значение на 1,27 перед использованием floor()?

...