; ; This program originally available on the Motorola DSP bulletin board. ; It is provided under a DISCLAMER OF WARRANTY available from ; Motorola DSP Operation, 6501 Wm. Cannon Drive W., Austin, Tx., 78735. ; ; Durbin Solution for PARCOR (LPC) Coefficients ; ; Last Update 3 June 87 Version 1.2 ; ; Implements the Durbin LPC algorithm. ; opt cex page 132,66,3,3 ; ; i/o file definitions ; datain equ $ffff dataout equ $fffe nk equ 10 ;10th order LPC analysis org x:0 ;I/O values in X: memory r ds nk+1 ;autocorrelation coefficients k ds nk ;reflection coefficients org y:0 ;temporary values in Y: memory acoeffs dc $7fffff ;define a[0] = 1.0 ds nk ;LPC filter coefficients anew dc $7fffff ;define anew[0] = 1.0 ds nk ;updated LPC filter coefficients alpha ds 1 ;Durbin alpha error ds 1 ;Durbin error org p:$100 ; ; find out how many frames to process ; movep y:datain,n0 do n0,endframe ; ; load the autocorrelations from an external file ; move #r,r0 ;load autocorrelation do #nk+1,loadr ;get nk+1 autocorrelation values movep y:datain,a ;get next autocorrelation value move a,x:(r0)+ ;and save it in the r array ; ; The following registers correspond to the C variables: ; ; r0 - r[i] r4 - acoeffs[i] ; r1 - k[i-1] r5 - acoeffs[j-1] ; r2 - r[i-j+1] r6 - acoeffs[i-j+1] ; r3 - anew[j-1] r7 - loop counter ; ; Approximate analysis times: ; ; 8th order: 63.5 uS ; 10th order: 85.6 uS ; 16th order: 165.7 uS ; ; Initialization ; loadr move #r,r0 ;r(0) points to r[0] move #k,r1 ;r(1) points to k[0] ; ; Begin Durbin Algorithm ; move x:(r0)+,x0 ;get r[0] move x:(r0)+,a ;get r[1], r(0) points to r[i] abs a a,b ;get abs(r[1]), copy r[1] to b eor x0,b #acoeffs+1,r4 ;N = sign bit, r(4) points to a[i] and #$fe,ccr ;make quotient positive rep #24 ;set up for 24-bit quotient div x0,a ;get abs(r[1])/r[0] jmi L1 ;check sign bit N neg a ;negate quotient if needed L1 move a0,a ;move -r[1]/r[0] to A clr b a,x:(r1)+ a,y0 ;k[0] = -r[1]/r[0], copy k[0] to y0 move #$800000,b1 ;b = 1.0, r(1) points to k[i-1] macr -y0,y0,b #2,r7 ;b=1.0-(k[0]*k[0]),loop counter=2 move b,x1 a,y:(r4)+ ;x1 = 1.0-(k[0] * k[0]), a[1] = k[0] mpyr x1,x0,a #2,n7 ;a1 = r[0] * (1.0 - (k[0] * k[0])) move a,y1 ;alpha = r[0] * (1.0 - k[0] * k[0])) move #-2,n5 ;initialize n(5) ; ; outer do loop (note: alpha = y1) ; do #nk-1,L6 ;do outer do loop (nk-1) times move r0,r2 ;r(2) points to r[i] move #acoeffs,r5 ;r(5) points to a[0] move (r0)+ ;r(0) points to next r[i] clr a x:(r2)-,x0 y:(r5)+,y0 ;error = 0, preload 1st operand set ; ; inner do loop #1 (note: r7 = i) ; do r7,L2 ;do inner do loop #1 (i) times mac x0,y0,a x:(r2)-,x0 y:(r5)+,y0 ;error += a[j-1] * r[i-j+1] ; ; back to outer do loop (note: error = a) ; L2 abs a a,b ;get abs(error), copy error to b eor y1,b #2,n6 ;N = sign bit, y1 = alpha and #$fe,ccr ;make quotient positive rep #24 ;set up for 24-bit quotient div y1,a ;get abs(error)/alpha jmi L3 ;check sign bit N neg a ;negate quotient if needed L3 move a0,a ;move k[i-1] = -(error/alpha) to a clr b a,x0 a,y:(r4)+ ;put k[i-1] in x0, a[i] = k[i-1] move a,x:(r1)+ y:(r7)-,a ;k[i-1] = -(error/alpha), dec r(7) move #$800000,b1 ;b = 1.0 macr -x0,x0,b r4,r6 ;b = 1.0 - (k[i-1] * k[i-1]) move b,x1 ;r(6) points to a[i+1] mpyr x1,y1,b (r6)-n6 ;b = alpha * (1.0-(k[i-1]*k[I-1])) move b,y1 ;save alpha=alpha*(1-k[i-1]*k[i-1]) move #acoeffs+1,r5 ;r(5) points to a[j-1] move #anew+1,r3 ;r(3) points to anew[j-1] move y:(r6)-,y0 ;y0 = a[i-j+1], x0 = k[i-1] move y:(r5)+,a ;a = a[j-1] ; ; inner do loop #2 (note: r7 = (i-1)) ; do r7,L4 ;do inner do loop #2 (i-1) times macr x0,y0,a y:(r6)-,y0 ;get anew[j-1], y0 = next a[i-j+1] move a,y:(r3)+ ;anew[j-1]=a[j-1]+k[i-1]*a[i-j+1] move y:(r5)+,a ;a = a[j-1] ; ; end of inner do loop #2 ; ; inner do loop #3 (note: r7 = (i-1)) ; L4 move x:(r3)-,x0 y:(r5)+n5,y0 ;dummy reads to dec r(3) and r(5) do r7,L5 ;do inner do loop #3 (i-1) times move y:(r3)-,a ;get anew[j-1] move a,y:(r5)- ;a[j-1] = anew[j-1] ; ; end of inner do loop #3 ; ; end of outer do loop ; ; end of analysis ; ; output reflection coefficients to an external file ; L5 move (r7)+n7 ;update loop counter L6 move #k,r1 ;point to reflection coeffs. do #nk,endsend ;output nk k values move x:(r1)+,x0 ;get next k value move x0,y:dataout ;output next K coefficient value endsend nop endframe nop end