home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / MISC / ADPCM.ZIP / NS_ADPCM.DSP < prev   
Encoding:
Text File  |  1989-03-06  |  20.9 KB  |  658 lines

  1. {
  2.     The code below represents a full duplex Adaptive Differential
  3.     Pulse Code Modulation (ADPCM) transcoder.  Although 
  4.     developed in accordance with ANSI specification T1.301-1987 and
  5.     CCITT G.721 (bis), it has been modified to improve its speed.
  6.  
  7.     The modifications include the removal of the synchronous coding 
  8.     adjustment and the tone and transition detectors.  These deletions 
  9.     should not noticably affect speech-only coding.
  10.  
  11.     An Application Note is available which describes the operation
  12.     of the algorithm in detail.  A copy of this Note can be obtained
  13.     from Analog Devices, DSP Division.
  14.  
  15.     Analog Devices        American National    Consultive Committee
  16.     DSP Division        Standards Institute    on International
  17.     P.O. Box 9106        1430 Broadway        Telephone and Telegraph
  18.     Norwood, Ma 02062-9106    New York, N.Y. 10018
  19.     (617) 461 - 3672
  20.  
  21.     Gordon A. Sterling     
  22.     Analog Devices
  23.     DSP Division
  24.        9/3/88
  25.  
  26.         Calling Parameters
  27.     AR = Companded PCM value (encoder)
  28.          ADPCM I value (decoder)
  29.  
  30.     M0=3;        L0=18;
  31.     M1=1;        L1=6;
  32.     M2=-1    
  33.             L3=0;
  34.     M4=0        L4=6;
  35.     M5=1        L5=2
  36.     M6=-1        L6=5
  37.  
  38.         Return Values
  39.     AR = ADPCM I value (encoder)
  40.          Companded PCM value (decoder)
  41.  
  42.         Altered Registers
  43.     AX0, AX1, AY0, AY1, AF, AR,
  44.     MX0, MX1, MY0, MY1, MR,
  45.     I0, I1, I3, I4, I5, I6
  46.     SI, SR
  47.     M3
  48.  
  49.         Cycle Count
  50.     437 cycles for encode 
  51.     409 cycles for decode
  52.  
  53. }
  54.  
  55. .MODULE        Adaptive_Differential_PCM;
  56.  
  57. .ENTRY        ns_adpcm_encode, ns_adpcm_decode;
  58.  
  59. .VAR/PM/CIRC     b_buf[6];            {b coefficients for encode}
  60. .VAR/PM/CIRC    a_buf[2];            {a coefficients for encode}
  61. .VAR/PM/CIRC    b_buf_r[6];            {b coefficients for decode}
  62. .VAR/PM/CIRC    a_buf_r[2];            {a coefficients for decode}
  63.  
  64. .VAR/DM/CIRC    b_delay_r[18];            {dq delay for decode}
  65. .VAR/DM/CIRC    a_delay_r[6];            {sr delay for decode}
  66. .VAR/DM/CIRC    b_delay[18];            {dq delay for encode}
  67. .VAR/DM/CIRC    a_delay[6];            {sr delay for encode}
  68.  
  69. .VAR/DM/CIRC    mult_data[5];            {Predictor immediate data}
  70.  
  71. .VAR/DM        qn_values[10],dq_values[8];    {quantizer and dequantizer data}
  72. .VAR/DM        f_values[12], w_values[8];    {Update coefficient data}
  73. .VAR/DM        a_data[10];
  74.  
  75. .VAR/DM        s_e,s_r,a_ik,dq,p;
  76. .VAR/DM        sez,sl,yu,yl_h,yl_l,y,y_2,ap,p_o,p_o_o,dms,dml,tdp,tr;
  77. .VAR/DM        a_ik_r,dq_r,p_r;
  78. .VAR/DM        yu_r,yl_h_r,yl_l_r,ap_r,p_o_r;
  79. .VAR/DM     p_o_o_r,dms_r,dml_r,tdp_r;
  80.  
  81. .VAR/DM        sp_r;                {PCM code word for synchronous adj}
  82.  
  83. .VAR/DM        hld_a_t, hld_b_t, hld_a_r, hld_b_r;
  84.  
  85. .INIT        qn_values:    7, 14, H#3F80, 
  86.                 400, 349, 300, 246, 178, 80, H#FF84;
  87.  
  88. .INIT        dq_values :     h#F800, 4, 135, 213, 273, 323, 373, 425;
  89.  
  90. .INIT        f_values :     -5, 0, 5120, 544, 
  91.                 0, 0, 0, 512, 512, 512, 1536, 3584;    
  92.  
  93. .INIT        w_values:    65344, 288, 656, 1024, 1792, 3168, 5680, 17952;
  94.  
  95. .INIT        mult_data :     H#1FFF, H#4000, h#7E00, H#7FFF, H#FFFE;
  96.  
  97. .INIT        a_data :    H#1FFF, 2, 16384, 0, -7, 192, H#3000, H#D000, 
  98.                 H#D200, H#3C00;
  99.  
  100. .INIT        hld_a_t : ^a_delay;
  101. .INIT        hld_b_t : ^b_delay;
  102. .INIT        hld_a_r : ^a_delay_r;
  103. .INIT        hld_b_r : ^b_delay_r;
  104.  
  105. .INIT        b_buf : 0,0,0,0,0,0;                {2.14}
  106. .INIT        a_buf : 0,0;                    {2.14}
  107. .INIT        b_delay : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;    {16.0, 16.0, 0.16}
  108. .INIT        a_delay : 0,0,0,0,0,0;                {16.0, 16.0, 0.16}
  109. .INIT        p : 0;                        {16.0}
  110. .INIT         yu :0;                        {7.9}
  111. .INIT        yl_h : 0;                    {7.9}
  112. .INIT        yl_l : 0;                    {0.16}
  113. .INIT        ap : 0;                        {8.8}
  114. .INIT        p_o : 0;                    {16.0}
  115. .INIT        p_o_o : 0;                    {16.0}
  116. .INIT        dms : 0;                    {7.9}
  117. .INIT        dml : 0;                    {5.11}
  118. .INIT        tdp : 0;                    {16.0}
  119.  
  120. .INIT        b_buf_r : 0,0,0,0,0,0;                {2.14}
  121. .INIT        a_buf_r : 0,0;                    {2.14}
  122. .INIT        b_delay_r : 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;{16.0, 16.0, 0.16}
  123. .INIT        a_delay_r : 0,0,0,0,0,0;            {16.0, 16.0, 0.16}
  124. .INIT        p_r : 0;                    {16.0}
  125. .INIT         yu_r :0;                    {7.9}
  126. .INIT        yl_h_r : 0;                    {7.9}
  127. .INIT        yl_l_r : 0;                    {0.16}
  128. .INIT        ap_r : 0;                    {8.8}
  129. .INIT        p_o_r : 0;                    {16.0}
  130. .INIT        p_o_o_r : 0;                    {16.0}
  131. .INIT        dms_r : 0;                    {7.9}
  132. .INIT        dml_r : 0;                    {5.11}
  133. .INIT        tdp_r : 0;                    {16.0}
  134.  
  135. ns_adpcm_encode:I4=^b_buf;            {Set pointer to b-coefficients}
  136.         I5=^a_buf;            {Set pointer to a-coefficients}
  137.         I6=^mult_data;            {Set pointer to predictor data}
  138.         I1=DM(hld_a_t);            {Restore pointer to s_r delay}
  139.         I0=DM(hld_b_t);            {Restore pointer to dq delay}
  140.         
  141.         CALL expand;            {Expand 8-bit log-PCM to12 bits}
  142.         DM(sl)=AR;            {Store linear PCM value in sl}
  143.         CALL predict;            {Call s_e and sez predictors}
  144.         AX1=DM(ap);
  145.         AY0=DM(yl_h);
  146.         AX0=DM(yu);
  147.         CALL lima;            {Limit ap and compute y}
  148.         DM(y)=AR;            {Save y for later updates}
  149.         DM(y_2)=SR1;            {Save y>>2 for log and reconst}
  150.         AX0=DM(sl);
  151.         AY0=DM(s_e);
  152.         AY1=SR1, AR=AX0-AY0;        {Compute difference signal, d}
  153.         CALL log;            {Determine I value from d}
  154.         DM(a_ik)=AR;
  155.         CALL reconst;            {Compute dq based ONLY on }
  156.         DM(dq)=AR; 
  157.         AY0=DM(s_e);
  158.         AR=AR+AY0;            {Compute reconstructed signal}
  159.         DM(s_r)=AR;
  160.  
  161.         DM(I1,M1)=AR, AR=ABS AR;    {Convert s_r to floating point}
  162.         SR1=H#4000;            {Set SR1 to minimum value}
  163.         SE=EXP AR (HI);            {Determine exponent adjust}
  164.         AX0=SE, SR=SR OR NORM AR (HI);    {Normalize into SR}
  165.         SR=LSHIFT SR1 BY -9 (HI);    {Delete lower bits}
  166.         AY0=11;                {Base exponent}
  167.         SR=LSHIFT SR1 BY 2 (HI);    {Adjust for ADSP-210x version}
  168.         AR=AX0+AY0;            {Compute exponent}
  169.         DM(I1,M1)=AR;            {Save exponent}
  170.         DM(I1,M1)=SR1;            {Save mantissa}
  171.  
  172.         CALL update_filter;    {Update filter if trigger false}
  173.     
  174.         MR0=DM(ap);            {Load variables for updating}
  175.         MR1=DM(y);
  176.         MR2=DM(tdp);            {Always load MR2 after MR1!}
  177.         MY0=DM(yl_h);
  178.         MY1=DM(yl_l);
  179.         AY0=DM(y);
  180.         MX0=DM(dms);
  181.         MX1=DM(dml);
  182.         CALL functw;            {Update variables}
  183.         DM(ap)=AR;            {Store updated variables}
  184.         DM(yu)=AX1;
  185.         DM(yl_l)=MY1;
  186.         DM(yl_h)=MY0;
  187.         DM(dms)=MX0;
  188.         DM(dml)=MX1;
  189.  
  190.         AX0=DM(a_ik);            {Get I value for return}
  191.         AY0=H#F;            {Only 4 LSBs are used}
  192.         AR=AX0 AND AY0;            {So mask redundant sign bits}
  193.  
  194.         DM(hld_a_t)=I1;            {Save s_r delay pointer}
  195.         DM(hld_b_t)=I0;            {Save dq delay pointer}
  196.  
  197.         RTS;                {Return to caller}
  198.  
  199. ns_adpcm_decode:I1=DM(hld_a_r);            {Restore s_r delay pointer}
  200.         I0=DM(hld_b_r);            {Restore dq delay pointer}
  201.         I4=^b_buf_r;            {Set pointer to b-coefficients}
  202.         I5=^a_buf_r;            {Set pointer to a-coefficients}
  203.         I6=^mult_data;            {Set pointer to predictor data}
  204.         
  205.         SR=LSHIFT AR BY 12 (HI);    {Get sign of ADPCM I value here}
  206.         SR=ASHIFT SR1 BY -12 (HI);    {Sign extend ADPCM value to 16}
  207.         DM(a_ik_r)=SR1;            {Save I value}
  208.         CALL predict;            {Call s_e and sez predictor}
  209.         AX1=DM(ap_r);
  210.         AY0=DM(yl_h_r);
  211.         AX0=DM(yu_r);
  212.         CALL lima;            {Limit ap and compute y}
  213.         DM(y)=AR;
  214.         DM(y_2)=SR1;
  215.         AY1=DM(y_2);
  216.         AR=DM(a_ik_r);
  217.         CALL reconst;            {Compute dq from received I}
  218.         DM(dq_r)=AR; 
  219.         AY0=DM(s_e);
  220.         AR=AR+AY0;            {Compute reconstructed signal}
  221.         DM(s_r)=AR;
  222.     
  223.         DM(I1,M1)=AR, AR=ABS AR;    {Make s_r floating point}
  224.         SR1=H#4000;            {Set SR1 to minimum value}
  225.         SE=EXP AR (HI);            {Determine exponent adjust}
  226.         AX0=SE, SR=SR OR NORM AR (HI);    {Normalize value}
  227.         SR=LSHIFT SR1 BY -9 (HI);    {Remove LSBs per spec}
  228.         AY0=11;                {Base exponent}
  229.         SR=LSHIFT SR1 BY 2 (HI);    {Adjust for ADSP-210x version}
  230.         AR=AX0+AY0;            {Compute exponent}
  231.         DM(I1,M1)=AR;            {Store exponent}
  232.         DM(I1,M1)=SR1;            {Store mantissa}
  233.         
  234.         CALL update_filter_r;    {Update filter if trigger false}
  235.     
  236.         AY0=DM(y);            {Load uariables for updating}
  237.         MY1=DM(yl_l_r);
  238.         MY0=DM(yl_h_r);
  239.         MR0=DM(ap_r);
  240.         MR1=DM(y);
  241.         MR2=DM(tdp_r);            {Always load MR2 after MR1!}
  242.         MX0=DM(dms_r);
  243.         MX1=DM(dml_r);
  244.         CALL functw;            {Update variables}
  245.         DM(yu_r)=AX1;            {Stored updated variables}
  246.         DM(yl_l_r)=MY1;
  247.         DM(yl_h_r)=MY0;
  248.         DM(ap_r)=AR;
  249.         DM(dms_r)=MX0;
  250.         DM(dml_r)=MX1;
  251.     
  252.         CALL compress;            {Compress PCM value}
  253.     
  254.         DM(hld_a_r)=I1;            {Save s_r delay pointer}
  255.         DM(hld_b_r)=I0;            {Save dq delay pointer}
  256.     
  257.         RTS;
  258.  
  259. compress:    AR=DM(s_r);            {Get reconstructed signal}
  260.         AR=ABS AR;            {Take absolute value}
  261.         AY0=33;                {Add offset of boundries}
  262.         AR=AR+AY0;
  263.         AY0=8191;            {Maximum PCM value}
  264.         AF=AR-AY0;            {Cap input}
  265.         IF GT AR=PASS AY0;        {If in excess}
  266.         SE=EXP AR (HI);            {Find exponent adjustmet}
  267.         AX0=SE, SR=NORM AR (LO);    {Normalize input}
  268.         AY0=H#4000;
  269.         AR=SR0 XOR AY0;            {Remove first significant bit}
  270.         SR=LSHIFT AR BY -10 (LO);    {Shift position bits}
  271.         AR=PASS AY0;
  272.         IF POS AR=PASS 0;        {Create sign bit}
  273.         SR=SR OR LSHIFT AR BY -7 (LO);    {Position sign bit}
  274.         AY0=9;
  275.         AR=AX0+AY0;            {Compute segment}
  276.         IF LT AR=PASS 0;
  277.         SR=SR OR LSHIFT AR BY 4 (LO);    {Position segment bits}
  278.         AY0=H#FF;
  279.         AR=SR0 XOR AY0;            {Invert bits}
  280.         RTS;
  281.  
  282. expand:        AY0=H#FF;            {Mask unwanted bits}
  283.         AF=AR AND AY0, AX0=AY0;
  284.         AF=AX0 XOR AF;            {Invert bits}
  285.         AX0=H#70;
  286.         AR=AX0 AND AF;            {Isolate segment bits}
  287.         SR=LSHIFT AR BY -4 (LO);    {Shift to LSBs}
  288.         SE=SR0, AR=AR XOR AF;        {Remove segment bits}
  289.         AY0=H#FF80;
  290.         AF=AR+AY0;
  291.         IF LT JUMP posval;        {Detemine sign}
  292.         AR=PASS AF;
  293.         AR=AR+AF;            {Shift left by 1 bit}
  294.         AY0=33;
  295.         AR=AR+AY0;            {Add segment offset}
  296.         SR=ASHIFT AR (LO);        {Position bits}
  297.         AR=AY0-SR0;            {Remove segment offset}
  298.         RTS;
  299.  
  300. posval:        AF=PASS AR;
  301.         AR=AR+AF;            {Shift left by 1}
  302.         AY0=33;    
  303.         AR=AR+AY0;            {Add segment offset}
  304.         SR=ASHIFT AR (LO);
  305.         AR=SR0-AY0;            {Remove segment offset}
  306.         RTS;
  307.         
  308. predict:    AX1=DM(I0,M2), AY1=PM(I4,M6);    {Point to dq6 and b6}
  309.         AF=PASS 0, SI=PM(I4,M4);    {AF hold partial sum}
  310.         AY0=DM(I6,M5);        
  311.         MX1=3;                {This multiply will give the}
  312.         MY1=32768;            {+48>>4 term}
  313.         SR=ASHIFT SI BY -2 (HI);    {Downshift b6 per spec}
  314.         CNTR=6;                {Loop once for each b}
  315.         DO sez_cmp UNTIL CE;
  316.            AR=ABS SR1, SR1=DM(I6,M5);    {Get absolute value of b}
  317.            AR=AR AND AY0, AY0=DM(I6,M5);{Mask bits per spec}
  318.            SE=EXP AR (HI), MY0=DM(I0,M2);{Find exponent adjust}
  319.            AX0=SE, SR=SR OR NORM AR (HI);{Compute bnMANT}
  320.            AR=SR1 AND AY0, AY0=DM(I0,M2);{Mask bits per spec}
  321.            MR=AR*MY0 (SS), AX1=DM(I0,M2), AY1=PM(I4,M6);
  322.            AR=AX0+AY0, AY0=DM(I6,M5);    {Compute WbEXP}
  323.            SE=AR, MR=MR+MX1*MY1 (SU);    {Compute WbnMANT}
  324.            SR=LSHIFT MR1 (HI), SE=DM(I6,M5);{Compute Wbn}
  325.            AR=SR1 AND AY0, SI=PM(I4,M4);{Mask Wbn per spec}
  326.            AX0=AR, AR=AX1 XOR AY1;    {Determine sign of Wbn}
  327.            AR=AX0, SR=ASHIFT SI (HI);    {Downshift b(n-1) per spec}
  328.            IF LT AR=-AX0;        {Negate Wbn if necessary}
  329. sez_cmp:       AF=AR+AF, AY0=DM(I6,M5);    {Add Wbn to partial sum}
  330.         AR=PASS AF, AX1=DM(I0,M1), AY1=PM(I5,M6);{Get sezi}
  331.         SR=ASHIFT AR BY -1 (HI);    {Downshift to produce sez}
  332.         DM(sez)=SR1;
  333.         SI=PM(I5,M4);            {Get a2}
  334.         SR=ASHIFT SI (HI);         {Downshift a2 per spec}
  335.         AX1=DM(I1,M2), AY1=PM(I4,M5);    {Restore bn and dqn pointers}
  336.         CNTR=2;                {Loop once for each a}
  337.         DO s_e_cmp UNTIL CE;
  338.            AR=ABS SR1, SR1=DM(I6,M5);    {Get absolute value of a}
  339.            AR=AR AND AY0, AY0=DM(I6,M5);{Mask bits per spec}
  340.            SE=EXP AR (HI), MY0=DM(I1,M2);{Get exponent adjust for a}
  341.            AX0=SE, SR=SR OR NORM AR (HI);{Compute anMANT}
  342.            AR=SR1 AND AY0, AY0=DM(I1,M2);{Mask bits per spec}
  343.            MR=AR*MY0(SS), AX1=DM(I1,M2), AY1=PM(I5,M6);
  344.            AR=AX0+AY0, AY0=DM(I6,M5);    {Compute WanEXP}
  345.            SE=AR, MR=MR+MX1*MY1 (SU);    {Complete WanMANT computation}
  346.            SR=LSHIFT MR1 (HI), SE=DM(I6,M5);{Compute Wan}
  347.            AR=SR1 AND AY0, SI=PM(I5,M4);{Mask Wan per spec}
  348.            AX0=AR, AR=AX1 XOR AY1;    {Determine sign of Wan}
  349.            AR=AX0, SR=ASHIFT SI (HI);    {Downshift a1 per spec}
  350.            IF LT AR=-AX0;        {Negate Wan if necessary}
  351. s_e_cmp:       AF=AR+AF, AY0=DM(I6,M5);    {Add Wan to partial sum}
  352.         AR=PASS AF, AX1=DM(I1,M1), AY1=PM(I5,M5);{Get sei}
  353.         SR=ASHIFT AR BY -1 (HI);    {Compute se}
  354.         DM(s_e)=SR1;
  355.         RTS;
  356.  
  357. lima:        AY1=256;            {Maximum value for ap}
  358.         AR=AX1, AF=AX1-AY1;        {Cap if it exceeds}
  359.         IF GE AR=PASS AY1;
  360.         SR=ASHIFT AR BY -2 (HI);    {>>2 to produce al}
  361.         SR=LSHIFT SR1 BY 9 (HI);    {Adjust for ADSP-210x version}
  362.         
  363. mix:        MY0=SR1, AR=AX0-AY0;        {MY0=al, AR=diff}
  364.         AR=ABS AR;            {Take absolute value of diff}
  365.         MR=AR*MY0 (SU);            {Generate prod}
  366.         AR=MR1+AY0;            {Add to yu}
  367.         IF NEG AR=AY0-MR1;        {Subtract if diff < 0}
  368.         SR=ASHIFT AR BY -2 (HI);    {Generate y>>2}
  369.         RTS;
  370.     
  371. log:        I3=^qn_values;            {Point to data array}
  372.         AR=ABS AR, AX1=DM(I3,M1);    {Take absolute of d}
  373.         SE=EXP AR (HI), AX0=DM(I3,M1);    {Determine exponent adjust}
  374.         AY0=SE, SR=NORM AR (HI);    {Normalize}
  375.         AR=AX0+AY0, AY0=DM(I3,M1);    {Compute exponent}
  376.         IF LT AR=PASS 0;        {Check for exponent -1}
  377.         SI=AR, AR=SR1 AND AY0;        {Mask mantissa bits}
  378.         SR=LSHIFT AR BY -7 (HI);    {Position mantissa}
  379.         SR=SR OR LSHIFT SI BY 7 (HI);    {Position exponent}
  380.  
  381. subtb:        AR=SR1-AY1, AY0=DM(I3,M1);    {Subtract y>>2 for log}
  382.         AX0=AR, AF=PASS AX1;        {Setup for quantizing}
  383.  
  384. quan:        AR=AX0-AY0, AY0=DM(I3,M1);    {Is dl less then upper limit?}
  385.         IF LT AF=AF-1;
  386.         AR=AX0-AY0, AY0=DM(I3,M1);    {Continue to check for }
  387.         IF LT AF=AF-1;
  388.         AR=AX0-AY0, AY0=DM(I3,M1);    {where dl fits in quantizer}
  389.         IF LT AF=AF-1;
  390.         AR=AX0-AY0, AY0=DM(I3,M1);
  391.         IF LT AF=AF-1;
  392.         AR=AX0-AY0, AY0=DM(I3,M1);
  393.         IF LT AF=AF-1;
  394.         AR=AX0-AY0, AY0=DM(I3,M1);
  395.         IF LT AF=AF-1;
  396.         AR=AX0-AY0;
  397.         IF LT AF=AF-1;
  398.         AR=PASS AF;
  399.         IF NEG AR=NOT AF;        {Negate value if ds negative}
  400.         IF EQ AR=NOT AR;        {Send 15 for 0}
  401.         RTS;
  402.         
  403. reconst:    AF=ABS AR;
  404.         IF NEG AR=NOT AR;        {Find absolute value}    
  405.         M3=AR;                {Use this for table lookup}
  406.         I3=^dq_values;            {Point to dq table}
  407.         MODIFY(I3,M3);            {Set pointer to proper spot}
  408.         AX1=DM(I3,M1);            {Read dq from table}
  409.  
  410. adda:        AR=AX1+AY1;            {Add y>>2 to dq}
  411.  
  412. antilog:    SR=ASHIFT AR BY 9 (LO);        {Get antilog of dq}
  413.         AY1=127;            {Mask mantisa}
  414.         AX0=SR1, AR=AR AND AY1;        {Save sign of DQ+Y in AX0}
  415.         AY1=128;            {Add 1 to mantissa}
  416.         AR=AR+AY1;
  417.         AY0=-7;             {Compute magnitude of shift}
  418.         SI=AR, AR=SR1+AY0;
  419.         SE=AR;
  420.         SR=ASHIFT SI (HI);        {Shift mantissa }
  421.         AR=SR1, AF=PASS AX0;
  422.         IF LT AR=PASS 0;        {If DQ+Y <0, set to zero}
  423.         IF NEG AR=-SR1;            {Negate DQ if I value negative}
  424.         RTS;
  425.         
  426. functw:        I3=^w_values;            {Get scale factor multiplier}
  427.         MODIFY(I3,M3);            {Based on I value}
  428.         AF=PASS 0, SI=DM(I3,M1);
  429.         I3=^f_values;
  430.  
  431. filtd:        SR=ASHIFT SI BY 1 (LO);        {Update fast quantizer factor}
  432.         AR=SR0-AY0, SE=DM(I3,M1);    {Compute difference}
  433.         SI=AR, AR=SR1-AF+C-1;        {in double precision}
  434.         SR=ASHIFT AR (HI), AX0=DM(I3,M1);{Time constant is 1/32}
  435.         SR=SR OR LSHIFT SI (LO), AY1=DM(I3,M1);
  436.         AR=SR0+AY0, AY0=DM(I3,M1);    {Add gain}
  437.  
  438. limb:        AF=AR-AY1, SI=DM(I3,M3);    {Limit fast scale factor}
  439.         IF GT AR=PASS AY1;        {Upper limit 10}
  440.         AF=AR-AY0, AY1=MY1;
  441.         IF LT AR=PASS AY0;        {Lower limit 1.06}
  442.  
  443. filte:        AF=AX0-AY1, AY0=MY0;        {Update quantizer slow factor}
  444.         AF=AX0-AY0+C-1, AX0=DM(I3,M1);    {Compute difference}
  445.         AX1=AR, AR=AR+AF;
  446.         SR=ASHIFT AR BY -6 (HI);    {Time constant is 1/64}
  447.         AR=SR0+AY1, AY1=MX0;        {Add gain}
  448.         MY1=AR, AR=SR1+AY0+C;        {in double precision}
  449.  
  450. filta:        MY0=AR, AR=AX0-AY1;        {Update short term I average}
  451.         SR=ASHIFT AR (HI), SI=AX0;    {Time constant is 1/32}
  452.         AR=SR1+AY1, AY0=MX1;        {Add gain}
  453.  
  454. filtb:        SR=LSHIFT SI BY 2 (HI);        {Update long term I average}
  455.         MX0=AR, AR=SR1-AY0;
  456.         SR=ASHIFT AR BY -7 (HI);    {Time constant is 1/128}
  457.         AR=SR1+AY0, SI=MX0;        {Add gain}
  458.  
  459. subtc:        SR=ASHIFT AR BY -3 (HI);    {Compute difference of long}
  460.         AF=PASS AR, AX0=SR1;        {and short term I averages}
  461.         SR=ASHIFT SI BY 2 (HI);
  462.         MX1=AR, AR=SR1-AF;
  463.         AF=ABS AR;
  464.         AR=MR2, AF=AX0-AF;        {tdp must be true for ax 0}
  465.         IF LE AR=PASS 1;        
  466.         AY0=1536;
  467.         AF=MR1-AY0, AY0=MR0;
  468.         IF LT AR=PASS 1;        {Y>3 for ax to be 0}
  469.  
  470. filtc:        SR=ASHIFT AR BY 9 (HI);        {Update speed control}
  471.         AR=SR1-AY0;            {Compute difference}
  472.         SR=ASHIFT AR BY -4 (HI);    {Time constant is 1/16}
  473.         AR=SR1+AY0;            {Add gain}
  474.         RTS;
  475.     
  476. update_filter:    AX0=DM(dq);            {Get value of current dq}
  477.         AR=128;
  478.         AF=PASS AX0, AY1=DM(I0,M0);    {Read sign of dq(6)}
  479.         IF EQ AR=PASS 0;        {If dq 0 then gain 0}
  480.         SE=-8;                {Time constand is 1/256}
  481.         AX1=AR;
  482.         CNTR=6;
  483.         DO update_b UNTIL CE;        {Update all b-coefficients}
  484.            AF=AX0 XOR AY1, AY0=PM(I4,M4);{Get sign of update}
  485.            IF LT AR=-AX1;
  486.            AF=AR+AY0, SI=AY0;        {Add update to original b}
  487.            SR=ASHIFT SI (HI), AY1=DM(I0,M0);{Get next dq(k)}
  488.            AR=AF-SR1;            {Subtract leak factor}
  489. update_b:       PM(I4,M5)=AR, AR=PASS AX1;    {Write out new b-coefficient}
  490.  
  491. place_dq:    AR=ABS AX0, AY0=DM(I0,M2);    {Take absolute value of dq}
  492.         SE=EXP AR (HI);            {Determine exponent adjust}
  493.         SR1=H#4000;            {Set minimum value into SR1}
  494.         AX1=SE, SR=SR OR NORM AR (HI);    {Normalize dq}
  495.         AY0=11;                {Used for exponent adjustment}
  496.         SR=LSHIFT SR1 BY -9 (HI);    {Remove lower bits}
  497.         SR=LSHIFT SR1 BY 2 (HI);    {Adjust for ADSP-210x version}
  498.         DM(I0,M2)=SR1, AR=AX1+AY0;    {Save mantisa, compute exp.}
  499.         DM(I0,M2)=AR;            {Save exponent}
  500.         AX1=DM(a_ik);            {Use sign of I, not dq}
  501.         DM(I0,M0)=AX1;            {Save sign}
  502.  
  503. update_p:    AY0=DM(sez);            {Get result of predictor}
  504.         AR=AX0+AY0;            {Use dq from above}
  505.         AY1=DM(p);            {Delay all old p's by 1}
  506.         AY0=DM(p_o);
  507.         DM(p)=AR;
  508.         DM(p_o)=AY1;
  509.         DM(p_o_o)=AY0;
  510.         AX1=AR, AR=AR XOR AY0;        {Compute p xor poo}
  511.         MR1=AR, AR=AX1 XOR AY1;        {Compute p xor po}
  512.         MR0=AR;
  513.  
  514. upa2:        I3=^a_data;
  515.         SI=PM(I5,M5);            {Hold a2 for later}
  516.         AR=PM(I5,M5);            {Get a1 for computation of f}
  517.         AR=ABS AR, AY0=DM(I3,M1);    {Cap magnitude of a1 at 1/2}
  518.         AF=AR-AY0, SE=DM(I3,M1);
  519.         IF GT AR=PASS AY0;
  520.         IF NEG AR=-AR;            {Restore sign}    
  521.         SR=ASHIFT AR (LO), AY0=DM(I3,M1);
  522.         AF=ABS MR0, AY1=DM(I3,M1);    {If p xor po = 0 negate f}
  523.         AR=SR0, AF=PASS SR1;
  524.         IF POS AR=AY1-SR0;        {Double precision}
  525.         IF POS AF=AY1-SR1+C-1;
  526.         SR0=AR, AR=PASS AF;
  527.         SR1=AR, AF=ABS MR1;        {If p xor poo = 1 subtract} 
  528.         AR=SR0+AY0, SE=DM(I3,M1);
  529.         AF=SR1+AY1+C, AX0=DM(I3,M1);
  530.         IF NEG AR=SR0-AY0;
  531.         IF NEG AF=SR1-AY1+C-1;
  532.         SR=LSHIFT AR (LO);
  533.         AR=PASS AF;
  534.         SR=SR OR ASHIFT AR (HI), AY0=SI;
  535.         AY1=SR0, SR=ASHIFT SI (HI);    {Downshift a2 for adjustment}
  536.         AR=AY0-SR1, AY0=DM(I3,M1);
  537.         AF=PASS AX1;
  538.         IF NE AR=AR+AY1;        {If sigpk = 1, no gain}
  539.  
  540. limc:        AF=AR-AY0, AY1=DM(I3,M1);    {Limit a2 to .75 max}
  541.         IF GT AR=PASS AY0;
  542.         AF=AR-AY1, AY0=DM(I3,M1);    {Limit a2 to -.75 min}
  543.         IF LT AR=PASS AY1;
  544.         PM(I5,M5)=AR;            {Store new a2}
  545.         
  546. upa1:        AR=AX0, AF=PASS MR0;
  547.         IF LT AR=-AX0;
  548.         AF=PASS AX1, SI=PM(I5,M4);
  549.         IF EQ AR=PASS 0;
  550.         SR=ASHIFT SI BY -8 (HI);    {Leak Factor = 1/256}
  551.         AF=PASS AR, AR=SI;
  552.         AF=AF-SR1;
  553.         AR=AR+AF, AX1=DM(I3,M1);
  554.  
  555. limd:        AX0=AR, AR=AX1-AY1;        {Limit a1 based on a2}
  556.         AY0=AR, AR=AY1-AX1;
  557.         AY1=AR, AR=PASS AX0;
  558.         AF=AR-AY0;
  559.         IF GT AR=PASS AY0;        {Upper limit 1 - 2^-4 - a2}
  560.         AF=AR-AY1;
  561.         IF LT AR=PASS AY1;        {Lower limit a2 - 1 + 2^-4}
  562.         PM(I5,M5)=AR;            {Store new a1}
  563.  
  564.         RTS;
  565.  
  566. update_filter_r:AX0=DM(dq_r);            {Get dq_r}
  567.         AR=128;                {Set possible gain}
  568.         AF=PASS AX0, AY1=DM(I0,M0);    {Get sign of dq(6)}
  569.         IF EQ AR=PASS 0;        {If dq_r 0, gain 0}
  570.         SE=-8;                {Leak factor 1/256}
  571.         AX1=AR;
  572.         CNTR=6;
  573.         DO update_b_r UNTIL CE;        {Update all b-coefficients}
  574.            AF=AX0 XOR AY1, AY0=PM(I4,M4);{Get sign of gain}
  575.            IF LT AR=-AX1;
  576.            AF=AR+AY0, SI=AY0;        {Add gain to original b}
  577.            SR=ASHIFT SI (HI);        {Time constant is 1/256}
  578.            AR=AF-SR1, AY1=DM(I0,M0);    {Compute new b-value}
  579. update_b_r:       PM(I4,M5)=AR, AR=PASS AX1;    {Store new b-value}
  580.  
  581. place_dq_r:    AR=ABS AX0, AY0=DM(I0,M2);    {Get absolute value fo dq_r}
  582.         SE=EXP AR (HI);            {Determine exponent adjustment}
  583.         SR1=H#4000;            {Set SR to minimum value}
  584.         AX1=SE, SR=SR OR NORM AR (HI);    {Normalize dq_r}    
  585.         AY0=11;                {Used for exponent adjust}
  586.         SR=LSHIFT SR1 BY -9 (HI);    {Remove lower bits}
  587.         SR=LSHIFT SR1 BY 2 (HI);    {Adjust for ADSP-210x version}
  588.         DM(I0,M2)=SR1, AR=AX1+AY0;    {Store mantissa, compute exp}
  589.         AX1=DM(a_ik_r);            {Use sign of I, not dq}
  590.         DM(I0,M2)=AR;            {Store exponent}
  591.         DM(I0,M0)=AX1;            {Store sign}
  592.  
  593. update_p_r:    AY0=DM(sez);            {Compute new p}
  594.         AR=AX0+AY0;            {Use dq_r from above}
  595.         AY1=DM(p_r);            {Delay old p's by 1}
  596.         AY0=DM(p_o_r);
  597.         DM(p_r)=AR;
  598.         DM(p_o_r)=AY1;
  599.         DM(p_o_o_r)=AY0;
  600.         AX1=AR, AR=AR XOR AY0;        {Compute p and poo}
  601.         MR1=AR, AR=AX1 XOR AY1;        {Compute p and po}
  602.         MR0=AR;
  603.  
  604. upa2_r:        I3=^a_data;
  605.         SI=PM(I5,M5);            {Hold a2 for later}
  606.         AR=PM(I5,M5);            {Get a1 for computation of f}
  607.         AR=ABS AR, AY0=DM(I3,M1);    {Cap magnitude of a1 to 1/2}
  608.         AF=AR-AY0, SE=DM(I3,M1);
  609.         IF GT AR=PASS AY0;
  610.         IF NEG AR=-AR;            {Restore sign of f}
  611.         SR=ASHIFT AR (LO), AY0=DM(I3,M1);
  612.         AF=ABS MR0, AY1=DM(I3,M1);    {If p_r xor poo_r =1 subtract}
  613.         AR=SR0, AF=PASS SR1;
  614.         IF POS AR=AY1-SR0;
  615.         IF POS AF=AY1-SR1+C-1;
  616.         SR0=AR, AR=PASS AF;
  617.         SR1=AR, AF=ABS MR1;
  618.         AR=SR0+AY0, SE=DM(I3,M1);
  619.         AF=SR1+AY1+C, AX0=DM(I3,M1);
  620.         IF NEG AR=SR0-AY0;
  621.         IF NEG AF=SR1-AY1+C-1;
  622.         SR=LSHIFT AR (LO);
  623.         AR=PASS AF;
  624.         SR=SR OR ASHIFT AR (HI), AY0=SI;
  625.         AY1=SR0, SR=ASHIFT SI (HI);    {Leak factor of 1/128}
  626.         AR=AY0-SR1, AY0=DM(I3,M1);
  627.         AF=PASS AX1;
  628.         IF NE AR=AR+AY1;        {If sigpk = 1 , no gain} 
  629.  
  630. limc_r:        AF=AR-AY0, AY1=DM(I3,M1);    {Limit a2 to .75 max}
  631.         IF GT AR=PASS AY0;
  632.         AF=AR-AY1, AY0=DM(I3,M1);    {Limit a2 to -.75 min}
  633.         IF LT AR=PASS AY1;
  634.         PM(I5,M5)=AR;            {Store new a2}
  635.         
  636. upa1_r:        AR=AX0, AF=PASS MR0;
  637.         IF LT AR=-AX0;
  638.         AF=PASS AX1, SI=PM(I5,M4);
  639.         IF EQ AR=PASS 0;
  640.         SR=ASHIFT SI BY -8 (HI);    {Leak Factor = 1/256}
  641.         AF=PASS AR, AR=SI;
  642.         AF=AF-SR1;
  643.         AR=AR+AF, AX1=DM(I3,M1);
  644.  
  645. limd_r:        AX0=AR, AR=AX1-AY1;        {Limit a1 based on a2}
  646.         AY0=AR, AR=AY1-AX1;
  647.         AY1=AR, AR=PASS AX0;
  648.         AF=AR-AY0;
  649.         IF GT AR=PASS AY0;        {Upper limit 1 - 2^-4 -a2}
  650.         AF=AR-AY1;
  651.         IF LT AR=PASS AY1;        {Lower limit a2 - 1 + 2^-4}
  652.         PM(I5,M5)=AR;            {Store new a1 }
  653.  
  654.         RTS;
  655.  
  656. .ENDMOD;
  657.  
  658.