Перейти к содержанию
    

Перевод в дециБеллы

В 16-битном контроллере есть 12-битное АЦП, необходимо значения АЦП перевести в дБ, Причём искомая величина х=10*log(100*отсчёты АЦП/4095), либо х=10*ln(100*отсчёты АЦП/4095). Сложность заключается в том, что рассчёты необходимо производить максимально быстро в реальном времени, желательно не выходя за размер 2 байт. Что можете порекомендовать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 16-битном контроллере есть 12-битное АЦП, необходимо значения АЦП перевести в дБ, Причём искомая величина х=10*log(100*отсчёты АЦП/4095), либо х=10*ln(100*отсчёты АЦП/4095). Сложность заключается в том, что рассчёты необходимо производить максимально быстро в реальном времени, желательно не выходя за размер 2 байт.  Что можете порекомендовать?

Таблицу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а формулой слабо? 12 кБайт под ногами не валяется.

 

Формулой и 2 байт и логарифм? А контроллер какой?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а точность какая нужна?

 

можно сделать с табличкой вида

1 -72,25

2 -66,23

4 -60,21

8 -54,19

16 -48,16

32 -42,14

64 -36,12

128 -30,1

512 -18,06

1024 -12,04

2048 -6,02

4095 0

 

а значения между интерполировать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость Miron
а точность какая нужна?

 

можно сделать с табличкой вида

1 -72,25

2 -66,23

4 -60,21

8 -54,19

16 -48,16

32 -42,14

64 -36,12

128 -30,1

512 -18,06

1024 -12,04

2048 -6,02

4095 0

 

а значения между интерполировать

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а формулой слабо? 12 кБайт под ногами не валяется.

 

Формулой и 2 байт и логарифм? А контроллер какой?

 

можно и формулой LogRatio = 10*log(Ey/Ex)

 

int LogRatio(int Exx, int Eyy)

{

int i, j;

int i1, i2, v1, v2;

// != 0

i1 = norm_l(Eyy+1);

i2 = norm_l(Exx+1);

 

j = i1 - i2;

v1 = L_shl(Eyy, i1);

v2 = L_shl(Exx, i2);

v1 = (v2-v1+(1<<12))>>13;

j = 3*j + (((v1>>1) + v1 + 0x02a3*j +(1<<15))>>16);

return j;

}

 

Вычисления здесь 32-разрядные, используется библиотека ETSI (можно найти внутри референсного кода любого вокодера, для DSP - norm_l и L_shl - 32 разрядные операции выполняемые одной инструкцией), максимальная ошибка 1 дб в диапазоне -40 - + 40 дб.

 

Но проще таблицей + интерполяцией. Хотя таблица + интерполяция при больших отношениях развалится и всё равно что-то нужно делать с двоичной экспонентой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообщето контроллер - MSP430F149, 16-битный, с аппаратным умножением 2Б*2Б=4 Байта, 2 кБ ОЗУ,FW на Си.

Предполагаемый диапазон - 0..20 дБ, точность - 0,2 дБ, хотелось бы 0,1 дБ (на части диапазона). Похоже действительно придётся в таблицу забивать и методом двоичного поиска рыскать. Что-то ряды меня не радуют: для получения аналогичной точности приходится вычислять до 10 степени.

float ln_r(float t);

{ int i;

float x;

float ln_rec(int i);

{ float u;

if (i<9) {число слагаемых в сумме}

ln_rec:=1/(i+1)-x*ln_rec(i+1);

else ln_rec:=1;

}

{// begin

x:=t-1;

i:=0;

ln_r:=x*ln_rec(i);

}// end;

(переделывал с паскаля, за работоспособность не ручаюсь, но принцип работает)

 

Интерполяция - это хорошо, только с точностью проблемы. Более интересное решение - представить число в виде произведения (2^n)*(float k<2), 2^n взять табличное, а float k можно и вычислить, в диапазоне 0,1..2 дБ достаточно 4 слогаемых вместо 9.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да нет, с интерполяцией проблем обычно нет, если интерполяция кусочно-линейная между соседними уровнями. И точность можно получить очень высокую с относительно короткой таблицей, если уровни квантования таблицы нелинейны - выбрать их так чтобы ошибка линейной апроксимации по всем уровням была примерно одинаковой (разница между соседними уровнями обратно пропорциональна второй производной)

 

Ну и рыскать поиском ;-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Итак при табличном методе: 0-30 дб с разрешением 0,2 - 151 ячейки по 2 байта. Набивать надоело :smile3046: .

 

Теперь о втором методе :w00t: : забиваем таблицу 0..31 раз <=> 0..xx дБ, потом значение АЦП сдвигаем вправо(т.е. делим на 2), пока оно не станет меньше 32. Количество сдвиганий n соответствует n*3 дБ ослабления, остаток - это сомножитель, из таблицы находим дБ, которому он соответствует и складываем дБ :cheers: . Кто может опровергнуть идею? B)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. log10 функция не линейная и может принимать значения меньше 0.

2. MSP430F149 - я так понимаю он целочисленный.

3. Таблица из 4095 значений отпадает.

4. Точность 0.2 дБ

 

Тогда значения удобно записывать в виде

<41 : х=10*log(100*отсчёты АЦП/4095) * -1 * 10 (x = от -161 до 0)

>41 : х=10*log(100*отсчёты АЦП/4095) * 10 (x = от 0 до 151)

тогда они будут занимать 1 байт

 

Начиная с некоторого места начнется повторение по 3 и более раз.

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

( if i<41 then ... if i<51 ... )

 

В Exel'e хорошо видно.

Столбец 1 задаем =10*(LOG(100*RC[1]/4095))

Столбец 2 задаем =СТРОКА()

Столбец 3 задаем ==ОКРУГЛ(10*RC[-3]; 0)

Копируем до 4096 и смотрим =)

 

Думаю, что скорость будет быстрее чем просто вычислять.

Если еще посмотреть распределение отсчетов_АЦП и исходя из этого расположить переходы по if =)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:cranky: вообщето основная проблема была перевести в дБ, используя только целые 16-битные числа 0..[ (2^16) - 1 ]. А с остальным понятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...