[sdiy] IIR Shift Filter problem - help with bug spotting in PIC ASM
Roman Sowa
modular at go2.pl
Thu Mar 9 15:19:05 CET 2017
Hi,
I think you should start the 4x downshift from asrf, not rrf.
That's probably the typo you didn't see "in the trees".
Roman
W dniu 2017-03-09 o 14:23, Tom Wiltshire pisze:
> Hi All,
>
> If you could cast your eyes over this, I'd be grateful. I'm having one of those "can't see the wood for the trees" moments.
>
> The code below is a simple single-pole IIR filter (a digital RC LPF). The INPUT is a 10-bit variable, which is left-aligned, so I have six empty bits below it.
>
> Now, I've actually got this code working (the good version below), but what I don't understand is why the BAD version doesn't do the same thing. I don't see why testing the Borrow flag and sticking the bits in "manually" is really any different from shifting the Borrow flag in. What am I missing, oh wise SynthDIY list? ;)
>
> Thanks for any pointers!
> Tom
>
> ; The Good Version
>
> WaveformSmoothing:
> ; Subtract FILTER from new INPUT
> movf FILTER_LO, w
> subwf INPUT_LO, f ; INPUT = INPUT - FILTER
> movf FILTER_HI, w
> subwfb INPUT_HI, f
>
> ; Borrow is zero if result required borrow (negative result)
> ; Is borrow set?
> bcf FLAGS, 3
> btfss BORROW ; Skip if positive
> bsf FLAGS, 3 ; Flag set if negative
>
> ; Do the downshifts (x 1/16th effectively)
> lsrf INPUT_HI, f
> rrf INPUT_LO, f
> lsrf INPUT_HI, f
> rrf INPUT_LO, f
> lsrf INPUT_HI, f
> rrf INPUT_LO, f
> lsrf INPUT_HI, f
> rrf INPUT_LO, f ; 4 shifts total
>
> ; Add the extra bits back in if negative
> movlw 0xF0
> btfsc FLAGS, 3
> addwf INPUT_HI, f
>
> ; Add it to FILTER
> movf INPUT_LO, w
> addwf FILTER_LO, f
> movf INPUT_HI, w
> addwfc FILTER_HI, f
> ; We now have a smoothed copy of our INPUT in FILTER
>
>
> ; The BAD Version
>
> WaveformSmoothing:
> ; Subtract FILTER from new INPUT
> movf FILTER_LO, w
> subwf INPUT_LO, f ; INPUT = INPUT - FILTER
> movf FILTER_HI, w
> subwfb INPUT_HI, f
>
> ; Borrow is zero if result required borrow (negative result)
> ; Flip the state of the borrow flag
> movlw 0x01
> xorwf STATUS, f ; Borrow set if negative
>
> ; Do the downshifts (x 1/16th effectively)
> rrf INPUT_HI, f ; Rotate the borrow flag in
> rrf INPUT_LO, f
> asrf INPUT_HI, f ; Propagate it down to lower bits
> rrf INPUT_LO, f
> asrf INPUT_HI, f
> rrf INPUT_LO, f
> asrf INPUT_HI, f
> rrf INPUT_LO, f ; 4 shifts total
>
> ; Add it to FILTER
> movf INPUT_LO, w
> addwf FILTER_LO, f
> movf INPUT_HI, w
> addwfc FILTER_HI, f
> ; We now have a smoothed copy of our INPUT in FILTER
>
>
>
> If you'd like to know more about this technique, full details are here (I've brought this useful StackExchange post up here before):
>
> http://electronics.stackexchange.com/questions/30370/fast-and-memory-efficient-moving-average-calculation
>
> The crucial part is the filter equation:
> FILT <-- FILT + FF(NEW - FILT)
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at synth-diy.org
> http://synth-diy.org/mailman/listinfo/synth-diy
>
More information about the Synth-diy
mailing list