[uquote="linkov1959",url="/forum/viewtopic.php?p=3888602#p3888602"]Степень двойки тут не прокатит, там пять связанных коэффициентов.[/uquote]
Шозабред? ЛЮБОЕ дробное число может быть представлено в формате фикспойнт при домножении его на степень двойки. Естественно, как и флоат, дробное число будет представлено с конечной точностью. Причем точность фикспойнта при 32 разрядах выше точности флоата, у которого мантисса имеет лишь 24 разряда.
В моем предложении выше речь шла о формате фикспойнта 14.18 (иногда пишут 14q18). При 12 разрядах сигнала - это запредельная избыточность по точности-разрешению.
[uquote="linkov1959",url="/forum/viewtopic.php?p=3888602#p3888602"]Я вот думаю вместо преобразований Фурье сделать сканирование и получить спектр нужного диапазона. Что скажете?[/uquote]
Еще одна фееричная глупость.
Спектр получают либо дискретным преобразованием Фурье (ДПФ-DFT), либо быстрым (БПФ-FFT)
В первом случае для получения синусно-косинусного спектра количество умножений пропорционально N^2, а во втором - N*log(N).
В зависимости от системы команд МК пересечение равных производительностей методов DFT/FFT может быть на разном количестве фильтров.
ДПФ по сути представляет из себя квадратурный приемник прямого преобразования по каждому из фильтров. С точки зрения самостоятельной реализации "от нуля" без особого изучения - это самый простой вариант. Очень похож на FIR по своей реализации. Сумма произведений отсчетов сигнала на отсчеты синуса и косинуса дают синусно-косинусную (алгебраическую) форму комплексного значения 1 фильтра ДПФ. Для получения модуля (амплитуды сигнала) находят корень квадратный из суммы квадратов синусного (Imaginary) и косинусного (Real) значений сигнала в фильтре.
БПФ - это, прежде всего, расчет элементарного узла - "бабочки". Компл
ексная сумма
A=
A+
B и компл
ексная разность с умножением на компл
ексный коэффициент
B=(
A-
B)
W.
Расчет "бабочки" БПФ эффективен при наличии trueDSP инструкций в МК. Скажем, для dsPIC33 я сумел написать "бабочку" на АСМе с выполнением ее за 23 машинных цикла. Но это лишь одна "бабочка", а их N*logN, не считая загрузки указателей на данные-коэффициенты (p
A, p
B, p
W) для функции "бабочки".
Код: Выделить всё
; W10=pA
; W11=pB
; W8=pW
; A=A+B
; B=(A-B)W
BtflCmplx:
mov #0x7FFF, W4 ; W4=0.99999
clr A, [W10]+=2, W6 ; W6=Ar, [W10]->Ai
clr B, [W8]+=2, W5, [W11]+=2, W7 ; W7=Br, [W11]->Bi, W5=Wr [W8]->Wi
;--- perform A
mac W4*W6, A, [W10]-=2, W6 ; ACCA+=(1*Ar), W6=Ai, [W10]->Ar
mac W4*W7, A, [W11]-=2, W7 ; ACCA+=(1*Br), W7=Bi, [W11]->Br
sac.r A, #-1, [W13++] ; Ar(new)=ACCA.rnd->buf
mac W4*W6, B, [W10]+=2, W6 ; ACCB+=(1*Ai), W6=Ar, [W10]->Ai
mac W4*W7, B, [W11]+=2, W7 ; ACCB+=(1*Bi), W7=Br, [W11]->Bi
sac.r B, #-1, [W13++] ; Ai(new)=ACCB.rnd->buf
;--- perform B
mpy W5*W6, A, [W10]-=2, W6 ; ACCA=Wr*Ar, W6=Ai, [W10]->Ar
msc W5*W7, A, [W8]-=2, W5, [W11]-=2, W7 ; ACCA-=(Wr*Br), W5=Wi, [W8]->Wr, W7=Bi, [W11]->Br
msc W5*W6, A ; ACCA-=(Wi*Ai)
mac W5*W7, A, [W8]+=2, W5 ; ACCA+=(Wi*Bi), W5=Wr, [W8]->Wi
sac.r A, #-1, [W13++] ; Br(new)=ACCA.rnd->buf
mpy W5*W6, B, [W10]+=2, W6 ; ACCB=Wr*Ai, W6=Ar, [W10]->Ai
msc W5*W7, B, [W8], W5, [W11]+=2, W7 ; ACCB-=(Wr*Bi), W5=Wi, W7=Br, [W11]->Bi
mac W5*W6, B ; ACCB+=(Wi*Ar)
msc W5*W7, B ; ACCB-=(Wi*Br)
sac.r B, #-1, [W13] ; Bi(new)=ACCB.rnd->buf
;--- save result
mov [W13--], [W11--] ; save Bi
mov [W13--], [W11] ; save Br
mov [W13--], [W10--] ; save Ai
mov [W13], [W10] ; save Ar
return
Обратите внимание на комментарии к каждой инструкции (после точки с запятой). Это действия выполняемые этой инструкцией за 1 машинный цикл. Индексы i и r в комментариях, как Вы уже поняли, это мнимая (imaginary) и действительная (real) компоненты компл
ексных операндов.