2017-02-01 15 views
0

Я использую функцию фиксированной связи сторонней стороны antilog() для вычисления величины от децибела out_mag = 10^(in_db/20). antilog() принимает в качестве входного сигнала формат Q6.25 и предоставляет Q16.15 на выходе.Исправлена ​​ошибка: out_Q15 = антилог (in_Q25), избегая переполнения?

Проблема заключается в том, что antilog() быстро переполняется для некоторого более высокого значения дБ, например, 100 дБ: 10^(100/20) = 100000. Максимальное значение Q16.15 может иметь формат 2^16-1=65535, поэтому 100000 не подходит.

Есть ли уловка, чтобы избежать переполнения? Допустимое значение входного знака?

+0

Как насчет того, чтобы просто прижиматься к Q6.25? – unwind

+0

Не могли бы вы уточнить? – Danijel

+0

Как насчет предварительного масштабирования входного значения, то есть out_mag_p = 10^(in_db/20/p), а затем ваше окончательное значение величины становится: out_mag = out_mag_p^p –

ответ

0

Мне удалось найти решение. Это немного сложно.

Во-первых, структура, которая будет содержать результат вывода необходимо:

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 и т. Д. Идея есть.