home *** CD-ROM | disk | FTP | other *** search
- ;; Author - Rick Vander Kam
- ;; Copyright (c) 1992 - All rights reserved
- ;; Modification history
- ;; --------------------
- ;; 2/22/92 - rvk - initial file created from /usr/lib/dsp/ugsrc/onepole.asm
- ;; added threshold argument to get variable clipping behavior
- ;;
- ;;------------------------------ DOCUMENTATION ---------------------------
- ;; NAME
- ;; cubicnl (UG macro) - cubic polynomial filter section
- ;;
- ;; SYNOPSIS
- ;; cubicnl pf,ic,sout,aout0,sinp,ainp0,aa10,aa20,aa30,thr0
- ;;
- ;; MACRO ARGUMENTS
- ;; pf = global label prefix (any text unique to invoking macro)
- ;; ic = instance count (s.t. pf\_cubicnl_\ic\_ is globally unique)
- ;; sout = output vector memory space ('x' or 'y')
- ;; aout0 = initial output vector memory address
- ;; sinp = input vector memory space ('x' or 'y')
- ;; ainp0 = initial input vector memory address
- ;; aa10 = initial coefficient of (input^1)
- ;; aa20 = initial coeff of (input^2)
- ;; aa30 = initial coeff of (input^3)
- ;; thr0 = threshold value
- ;;
- ;; DSP MEMORY ARGUMENTS
- ;; Access Description Initialization
- ;; ------ ----------- --------------
- ;; x:(R_X)+ Current output address aout0
- ;; y:(R_Y)+ Current input address ainp0
- ;; x:(R_X)+ aa1 coefficient aa10
- ;; y:(R_Y)+ aa2 coefficient aa20
- ;; y:(R_Y)+ aa3 coefficient aa30
- ;; x:(R_X)+ thr value thr0
- ;;
- ;; DESCRIPTION
- ;; The cubicnl unit-generator implements a nonlinear,
- ;; cubic polynomial filter section in direct form. It has
- ;; a variable threshold level, and any sample whose value
- ;; is above the threshold will be hard-limited. In pseudo-C notation:
- ;;
- ;; ainp = y:(R_Y)+;
- ;; aout = x:(R_X)+;
- ;; aa1 = x:(R_X)+;
- ;; aa2 = y:(R_Y)+;
- ;; aa3 = y:(R_Y)+;
- ;; thr = x:(R_X)+;
- ;;
- ;; for (n=0;n<I_NTICK;n++) {
- ;; if(sinp:ainp[n]<thr) {
- ;; sout:aout[n] = aa1*sinp:ainp[n]
- ;; +aa2*(ainp[n]*ainp[n])
- ;; +aa3*(ainp[n]*ainp[n]*ainp[n]);
- ;; }
- ;; else sout:aout[n] = thr;
- ;; }
- ;;
- ;; DSPWRAP ARGUMENT INFO
- ;; cubicnl (prefix)pf,(instance)ic,
- ;; (dspace)sout,(output)aout,
- ;; (dspace)sinp,(input)ainp,aa1,aa2,aa3,thr
- ;;
- ;; MAXIMUM EXECUTION TIME
- ;; ???
- ;;
- ;; MINIMUM EXECUTION TIME
- ;; ???
- ;;
- ;; SOURCE
- ;; /user/rvk/ee265/test/cubicnlUG
- ;;
- ;; SEE ALSO
- ;; /usr/lib/dsp/ugsrc/onezero.asm - one-zero filter section
- ;; /usr/lib/dsp/ugsrc/twopole.asm - two-pole filter section
- ;; /usr/lib/dsp/ugsrc/biquad.asm - two-pole, two-zero filter section
- ;; /usr/lib/dsp/ugsrc/onezero.asm - one-zero filter section
- ;;
- ;; ALU REGISTER USE
- ;; X0 = input sample raised to powers
- ;; Y0 = aa2
- ;; X1 = aa1 and temp. input holder
- ;; Y1 = aa3 and temp. coeff holder
- ;; A = output value accumulator, threshold comparison
- ;; B = working multiplications accumulator
-
- cubicnl macro pf,ic,sout,aout0,sinp,ainp0,aa10,aa20,aa30,thr0
- new_xarg pf\_cubicnl_\ic\_,aout,aout0 ; output address arg
- new_yarg pf\_cubicnl_\ic\_,ainp,ainp0 ; input address arg
- new_xarg pf\_cubicnl_\ic\_,aa1,aa10 ; coeff of x
- new_yarg pf\_cubicnl_\ic\_,aa2,aa20 ; coeff of x^2
- new_yarg pf\_cubicnl_\ic\_,aa3,aa30 ; coeff of x^3
- new_xarg pf\_cubicnl_\ic\_,thr,thr0 ; coeff of x
-
- move x:(R_X)+,R_O ; output address to R_O
- move x:(R_Y)+,R_I1 ; input address to R_I1
- move x:(R_X)+,X1 y:(R_Y)+,Y0 ;aa1->X1, aa2->Y0
-
- do #I_NTICK,pf\_cubicnl_\ic\_tickloop
- move sinp:(R_I1)+,X0 ;input->X0, B cleared for altout
- mpy X0,X1,A X1,Y1 ;aa1*in->A, aa1 saved
- mpyr X0,X0,B X0,X1 ;in^2->B, in->X1
- move B,X0 ;in^2->X0
- mpyr X0,X1,B ;in^3->B
- mac Y0,X0,A Y1,X1 ;A+=aa2*in^2, restore aa1
- move B,X0 y:(R_Y),Y1 ;in^3->X0, aa3->Y1
- macr Y1,X0,A x:(R_X),B ;A+=aa3*in^3, threshold value -> B
- cmpm A,B ;check output against threshold
- jle pf\_cubicnl_\ic\_altout
- jmp pf\_cubicnl_\ic\_out
- pf\_cubicnl_\ic\_altout
- tfr B,A A,B ;get threshold value in A
- jclr #23,B1,pf\_cubicnl_\ic\_out ;input is (+), so write A as output
- neg A ;input is (-), so negate A first
- pf\_cubicnl_\ic\_out
- move A,sout:(R_O)+ ;ship A as output
- pf\_cubicnl_\ic\_tickloop
- move x:(R_X)+,X0 y:(R_Y)+,Y1 ;(dummy) increment R_X and R_Y
- endm
-
-