Code: Select all
; High shelf with fixed fc and ks
; fc is set by mreg 14 (kf1)
; Shelf level (ks1) set by mreg 15
;
.equ fs 32000 ; Sample rate
; Registers, may need to change so they do not conflict with other items
.rn lp r9
.rn shelf r5
.rn temp r8
.rn temp2 r4
; User settings
.equ fc 500 ; The desired fc frequency in Hz
.mreg kf1 kfc ; Put the value of the fc coefficient in mreg so it's there on startup
.mreg ks1 0.5 ; Put the value of the shelf coefficient in mreg
.rn kf1 mr14 ; Frequency coefficient for fc
.rn ks1 mr15 ; ks = shelving coefficient (controls boost/cut)
.rn lpsaveLS2 mr11 ; Location to save the lp value between iterations
; Constants and equations
.equ e 2.71828183
.equ pi 3.14159265359
; Calculate the fc coefficient
.equ kfc 1-e^(-2*pi*fc/fs)
; The filters: intended as a 'subroutine'
; Input Signal should be in acc32
; Output signal will be in acc32
; Uses CREGS lp, hp, temp and temp2
; lp is reusable for any filter (must be saved in a separate MREG for each filter)
; temp and temp2 are temporary CREGs for use within a routine
; values in temp and temp2 are not important on input and undefined on output
cpy_cs acc32,in0 ; Read in the input - required for testing only
; ========== Entry point here with signal in acc32 ======================
cpy_cc temp,acc32 ; We need it again below so save in temp
cpy_cm lp,lpsaveLS2 ; Get the saved lp value Ylp[n-1]
cpy_cm temp2, ks1 ; Get the shelf boost/cut from the preset (constant) value in the MREG
; First high shelf
subs temp, lp ; Yhp[n] = X[n] -Ylp[n-1]
multrr temp2, acc32 ; adjust the shelf level from the ks scaling above
adds acc32, temp ; add the input
cpy_cc shelf, acc32 ; Save high shelf result
cpy_cm temp2, kf1 ; save K into a core register
; Now low pass
subs temp, lp ; X[n] - Ylp[n]
multrr acc32, temp2 ; *kf
adds acc32, lp ; + Ylp[n]
cpy_cc lp, acc32 ; Save low pass result
cpy_cc acc32, shelf ; High shelf out on acc32
cpy_mc lpsaveLS2, lp ; Save the lp value for next iteration
cpy_sc out0, acc32 ; High shelf out on out0 - required for testing only
The low shelf filter code is as follows:
Code: Select all
; Low shelf with fixed fc and ks
; fc is set by mreg 16 (kf2)
; Shelf level (ks) set by mreg 17 (ks2)
;
.equ fs 32000 ; Sample rate
; Registers, may need to change so they do not conflict with other items
.rn lp r9
.rn shelf r5
.rn temp r8
.rn temp2 r4
; User settings
.equ fc 500 ; The desired fc frequency in Hz
.mreg kf2 kfc ; Put the value of the fc coefficient in mreg so it's there on startup
.mreg ks2 0.5 ; Put the value of the shelf coefficient in mreg
.rn kf2 mr16 ; Frequency coefficient for fc
.rn ks2 mr17 ; ks = shelving coefficient (controls boost/cut)
.rn lpsaveLS2 mr11 ; Location to save the lp value between iterations
.rn lpsaveLS1 mr10
; Constants and equations
.equ e 2.71828183
.equ pi 3.14159265359
; Calculate the fc coefficient
.equ kfc 1-e^(-2*pi*fc/fs)
; The filters 'subroutine'
; Input Signal should be in acc32
; Output signal will be in acc32
; Uses CREGS lp, shelf, temp and temp2
; lp is reusable for any filter (must be saved in a separate MREG for each filter)
; temp and temp2 are temporary CREGs for use within a routine
; values in temp and temp2 are not important on input and undefined on output
cpy_cs acc32,in0 ; Read in the input - required for testing only
; ========== Entry point here with signal in acc32 ======================
cpy_cc temp,acc32 ; We need it again below so save in temp
cpy_cm lp,lpsaveLS1 ; Get the saved lp value Ylp[n-1]
cpy_cm temp2, ks2 ; Get the shelf boost/cut from the preset (constant) value in the MREG
; First low shelf
;subs temp, lp ; Yhp[n] = X[n] -Ylp[n-1]
multrr temp2, lp ; adjust the shelf level from the ks scaling above
adds acc32, temp ; add the input
cpy_cc shelf, acc32 ; Save high shelf result
cpy_cm temp2, kf2 ; save K into a core register
; Now low pass
subs temp, lp ; X[n] - Ylp[n]
multrr acc32, temp2 ; *kf
adds acc32, lp ; + Ylp[n]
cpy_cc lp, acc32 ; Save low pass result
cpy_mc lpsaveLS1, lp ; Save the lp value for next iteration
cpy_cc acc32, shelf ; High shelf out on acc32
cpy_sc out0, acc32 ; High shelf out on out0 - required for testing only