Мне удалось найти решение. Это немного сложно.
Во-первых, структура, которая будет содержать результат вывода необходимо:
typedef struct
{
q15 v; // Value (within the [MIN, MAX] range for Q16.15).
int32 s; // Scalefactor.
} q15_t;
Идея заключается в том, чтобы обеспечить результат, как выход с Scalefactor, где
Output = 10^y
Scale = 2^scalefactor
Окончательный выход Output
сдвинутой влево scalefactor
раз.
Вот математика.
Формат ввода Q31 - значение дБ, масштабируемое до [-1,1], с масштабом, составляющим 2^scalefactor. Нам нужно вычислить:
Out = 10^(2^scalefactor * in/20.0)
= 10^(p+y) // rewriting as sum
= 10^p * 10^y // to enable exponent multiplication
= 2^scalefactor * 10^y // making it power of 2 to be able to just shift
Таким образом, мы не ограничены Q16.15 максимального значения.
Мы уже знаем 2^scalefactor
, но нужно найти y
:
2^scalefactor * in = p + y
10^p = 2^scalefactor => p = scalefactor*log(2) // rewrite as power of 2
2^scalefactor * in = scalefactor*log(2) + y // replace p
y = 2^scalefactor*in - scalefactor*log(2) // and find y
Вычислить у, и кормить его в antilog
.
Если входной сигнал 100 dB
, то величина выходного сигнала должна быть 100.000
, что не соответствует формату Q16.15
. Используя вышеуказанное решение, Output = 50.000
(это соответствует Q16.15
!) И scalefactor = 1
, что означает, что конечный результат равен 50.000
, сдвинутому влево 1
. Это дает 100.000
в качестве конечного результата. В зависимости от вашей реализации вы можете получить тот же результат, что и 25.000
с scalefactor = 2
и т. Д. Идея есть.
Как насчет того, чтобы просто прижиматься к Q6.25? – unwind
Не могли бы вы уточнить? – Danijel
Как насчет предварительного масштабирования входного значения, то есть out_mag_p = 10^(in_db/20/p), а затем ваше окончательное значение величины становится: out_mag = out_mag_p^p –