Теперь реализация на ассемблере.
Для фильтров приведены по два варианта операции умножения, точная и упрощенная. Упрощенная реализация короче примерно на 10 операций, но дает погрешность в самом младшем бите (недоучитывается возможный перенос от суммирования трех чисел в дополнительном младшем отбрасываемом байте).
-----------------------------------------------------------------
переменные
f1L equ 0x80 ;signed word f1
f1H equ 0x81
f2L equ 0x82 ;signed word f2
f2H equ 0x83
scale1 equ 0x84 ;unsigned fractional byte scale1
scale2 equ 0x85 ;unsigned fractional byte scale2
AL equ 0x86 ;unsigned fractional word A
AH equ 0x87
BL equ 0x88 ;unsigned fractional word B
BH equ 0x89
amp equ 0x8A ;unsigned fractional byte amp
tmp1L equ 0x70 ;signed word tmp1
tmp1H equ 0x71
tmp2L equ 0x72 ;signed word tmp2
tmp2H equ 0x73
gen1L equ 0x74 ;signed word gen1
gen1H equ 0x75
gen2L equ 0x76 ;signed word gen2
gen2H equ 0x77
XL equ 0x78 ;signed word X
XH equ 0x79
VL equ 0x7A ;signed word V
VH equ 0x7B
prod1 equ 0x7C ;дополнительный младший байт, использующийся для осуществелния умножения с соблюдением точности.
;---------------------------
movf f1L,w ;gen1=gen1+f1
addwf gen1L,f
movf f1H,w
addwfc gen1H,f
movf f2L,w ;gen2=gen2+f2
addwf gen2L,f
movf f2H,w
addwfc gen2H,f
movf scale1,w ;tmp1=gen1 * scale
mulwf gen1H
movff PRODL,tmp1L
movff PRODH,tmp1H
btfsc gen1H,7
subwf tmp1H,f
mulwf gen1L
movf PRODH,w
addwf tmp1L,f
clrf WREG
addwfc tmp1H,f
movf scale2,w ;tmp1=tmp1+gen2*scale2
mulwf gen2H
movf PRODL,w
addwf tmp1L,f
movf PRODH,w
addwfc tmp1H,f
movf scale2,w
btfsc gen2H,7
subwf tmp2H,f
mulwf gen2L
movf PRODH,w
addwf tmp1L,f
clrf WREG
addwfc tmp2H,f
;movf AL,w ;tmp2=A*V - точное умножение
;mulwf VL
;movff PRODH,prod1
;movf AH,w
;mulwf VH
;movff PRODL,tmp2L
;movff PRODH,tmp2H
;mulwf VL
;movf PRODL,w
;addwf prod1,f
;movf PRODH,w
;addwfc tmp2L,f
;clrf WREG
;addwfc tmp2H,f
;movf AL,w
;mulwf VH
;movf PRODL,w
;addwf prod1,f
;movf PRODH,w
;addwfc tmp2L,f
;clrf WREG
;addwfc tmp2H,f
;movf VH,w ;знаковая коррекция
;bnn filt1
;movf AL,w
;subwf tmp2L,f
;movf AH,w
;subwfb tmp2H,f
;filt1:
movf AH,w ;tmp2=A*V - упрощенное умножение
mulwf VH
movff PRODL,tmp2L
movff PRODH,tmp2H
mulwf VL
movf PRODH,w
addwf tmp2L,f
clrf WREG
addwfc tmp2H,f
movf AL,w
mulwf VH
movf PRODH,w
addwf tmp2L,f
clrf WREG
addwfc tmp2H,f
movf VH,w ;знаковая коррекция
bnn filt1
movf AL,w
subwf tmp2L,f
movf AH,w
subwfb tmp2H,f
filt1:
movf XL,w ;tmp1=tmp1-X
subwf tmp1L,f
movf XH,w
subwfb tmp1H,f
;movf BL,w ;tmp2=tmp2+B*tmp1 - точное умножение
;mulwf tmp1L
;movf PRODH,w
;addwf prod1,f
;clrf WREG
;addwfc tmp2L,f
;addwfc tmp2H,f
;movf BH,w
;mulwf tmp1H
;movf PRODL,w
;addwf tmp2L,f
;movf PRODH,w
;addwfc tmp2H,f
;movf BH,w
;mulwf tmp1L
;movf PRODL,w
;addwf prod1,f
;movf PRODH,w
;addwfc tmp2L,f
;clrf WREG
;addwfc tmp2H,f
;movf BL,w
;mulwf tmp1H
;movf PRODL,w
;addwf prod1,f
;movf PRODH,w
;addwfc tmp2L,f
;clrf WREG
;addwfc tmp2H,f
;movf tmp1H,w ;знаковая коррекция
;bnn filt2
;movf BL,w
;subwf tmp2L,f
;movf BH,w
;subwfb tmp2H,f
;filt2:
movf BH,w ;tmp2=tmp2+B*tmp1 - упрощенное умножение
mulwf tmp1H
movf PRODL,w
addwf tmp2L,f
movf PRODH,w
addwfc tmp2H,f
movf BH,w
mulwf tmp1L
movf PRODH,w
addwf tmp2L,f
clrf WREG
addwfc tmp2H,f
movf BL,w
mulwf tmp1H
movf PRODH,w
addwf tmp2L,f
clrf WREG
addwfc tmp2H,f
movf tmp1H,w ;знаковая коррекция
bnn filt2
movf BL,w
subwf tmp2L,f
movf BH,w
subwfb tmp2H,f
filt2:
movf VL,w ;X=X+V
addwf XL,f
movf VH,w
addwfc XH,f
movf tmp2L,w ;V=V+tmp2
addwf VL,f
movf tmp2H,w
addwfv VH,f
movf amp,w ;tmp1=amp*X
mulwf XH
movff PRODL,tmp1L
movff PRODH,tmp1H
btfsc XH,7
subwf tmp1H,f
mulwf XL
movf PRODH,w
addwf tmp1L,f
clrf WREG
addwfc tmp1H,f
movff tmp1L,LATB ;out (tmp1)
movff tmp1H,LATC
Итого 103 операции, с учетом восьми 2х-цикловых операций movff в наихудшем случае, когда во всех умножениях выполняются знаковые коррекции, имеем 111 машинных циклов на расчет одной выборки одного голоса.
При частоте кварца 40 мГц имеем 10 млн машинных циклов в секунду. Значит, при частоте дискретизации 40кГц имеем по 250 машинных циклов на выборку. Если предположить, что вся низкочастотная часть (на схеме ниже пунктирной линии) вынесена на отдельный управляющий контроллер, то контроллер, занимающийся исключительно звукочастотной частью, сможет просчитывать два голоса.
В общем, мои предположения (по 5-6 голосов на контроллер) оказались завышенными, но не сильно, все равно мы гуляем на грани возможностей контроллера, а не далеко за его пределами

В основном я просчитался с умножениями - они потребовали гораздо больше операций, чем я ожидал.
Зато, если вышеуказанные вычисления точны, то остается резерв около 25-30 машинных циклов на одну выборку, то есть, порядка миллиона машинных циклов в секунду - этого может вполне хватить на то, чтоб в этом же контроллере реализовать и "медленную" часть - прием миди-сообщений, генерация огибающих и вибрато с дискретизацией порядка 100Гц и запись параметров для "быстрой" части. Например, быструю часть можно реализовать в виде основного цикла, а медленную часть обрабатывать по прерываниям от UART и от таймера 100Гц. И если двухголосия достаточно - то может оказаться, что вся электроника обходится одним контроллером и ЦАП-ом.