📄 adpcm.dsp
字号:
AR=AX0-AY0, AY0=DM(I3,M1); {Continue to check for }
IF LT AF=AF-1;
AR=AX0-AY0, AY0=DM(I3,M1); {where dl fits in quantizer}
IF LT AF=AF-1;
AR=AX0-AY0, AY0=DM(I3,M1);
IF LT AF=AF-1;
AR=AX0-AY0, AY0=DM(I3,M1);
IF LT AF=AF-1;
AR=AX0-AY0, AY0=DM(I3,M1);
IF LT AF=AF-1;
AR=AX0-AY0;
IF LT AF=AF-1;
AR=PASS AF;
IF NEG AR=NOT AF; {Negate value if ds negative}
IF EQ AR=NOT AR; {Send 15 for 0}
RTS;
reconst: AF=ABS AR;
IF NEG AR=NOT AR; {Find absolute value}
M3=AR; {Use this for table lookup}
I3=^dq_values; {Point to dq table}
MODIFY(I3,M3); {Set pointer to proper spot}
AX1=DM(I3,M1); {Read dq from table}
adda: AR=AX1+AY1; {Add y>>2 to dq}
antilog: SR=ASHIFT AR BY 9 (LO); {Get antilog of dq}
AY1=127; {Mask mantisa}
AX0=SR1, AR=AR AND AY1; {Save sign of DQ+Y in AX0}
AY1=128; {Add 1 to mantissa}
AR=AR+AY1;
AY0=-7; {Compute magnitude of shift}
SI=AR, AR=SR1+AY0;
SE=AR;
SR=ASHIFT SI (HI); {Shift mantissa }
AR=SR1, AF=PASS AX0;
IF LT AR=PASS 0; {If DQ+Y <0, set to zero}
IF NEG AR=-SR1; {Negate DQ if I value negative}
RTS;
trans: sr=ashift si by -9 (hi); {Get integer of yl}
SE=SR1; {Save for shift}
SR=LSHIFT SR0 BY -11 (HI); {Get 5 MSBs of fraction of yl}
AY0=32;
AR=SR1+AY0; {Add one to fractional part}
AX0=SE, SR=LSHIFT AR (HI); {Shift into proper format}
AY0=8;
AR=H#3E00; {Maximum value}
AF=AX0-AY0;
IF LE AR=PASS SR1; {Cap at maximum value}
AF=ABS AX1, AY0=AR; {Get absolute value of dq}
SR=LSHIFT AR BY -1 (HI);
AR=SR1+AY0;
SR=LSHIFT AR BY -1 (HI);
AF=SR1-AF, AR=MR1; {tdp must be set for tr true}
IF GE AR=PASS 0; {If dq exceeds threshold no tr}
RTS;
functw: I3=^w_values; {Get scale factor multiplier}
MODIFY(I3,M3); {Based on I value}
AF=PASS 0, SI=DM(I3,M1);
I3=^f_values;
filtd: SR=ASHIFT SI BY 1 (LO); {Update fast quantizer factor}
AR=SR0-AY0, SE=DM(I3,M1); {Compute difference}
SI=AR, AR=SR1-AF+C-1; {in double precision}
SR=ASHIFT AR (HI), AX0=DM(I3,M1);{Time constant is 1/32}
SR=SR OR LSHIFT SI (LO), AY1=DM(I3,M1);
AR=SR0+AY0, AY0=DM(I3,M1); {Add gain}
limb: AF=AR-AY1, SI=DM(I3,M3); {Limit fast scale factor}
IF GT AR=PASS AY1; {Upper limit 10}
AF=AR-AY0, AY1=MY1;
IF LT AR=PASS AY0; {Lower limit 1.06}
filte: AF=AX0-AY1, AY0=MY0; {Update quantizer slow factor}
AF=AX0-AY0+C-1, AX0=DM(I3,M1); {Compute difference}
AX1=AR, AR=AR+AF;
SR=ASHIFT AR BY -6 (HI); {Time constant is 1/64}
AR=SR0+AY1, AY1=MX0; {Add gain}
MY1=AR, AR=SR1+AY0+C; {in double precision}
filta: MY0=AR, AR=AX0-AY1; {Update short term I average}
SR=ASHIFT AR (HI), SI=AX0; {Time constant is 1/32}
AR=SR1+AY1, AY0=MX1; {Add gain}
filtb: SR=LSHIFT SI BY 2 (HI); {Update long term I average}
MX0=AR, AR=SR1-AY0;
SR=ASHIFT AR BY -7 (HI); {Time constant is 1/128}
AR=SR1+AY0, SI=MX0; {Add gain}
subtc: SR=ASHIFT AR BY -3 (HI); {Compute difference of long}
AF=PASS AR, AX0=SR1; {and short term I averages}
SR=ASHIFT SI BY 2 (HI);
MX1=AR, AR=SR1-AF;
AF=ABS AR;
AR=MR2, AF=AX0-AF; {tdp must be true for ax 0}
IF LE AR=PASS 1;
AY0=1536;
AF=MR1-AY0, AY0=MR0;
IF LT AR=PASS 1; {Y>3 for ax to be 0}
filtc: SR=ASHIFT AR BY 9 (HI); {Update speed control}
AR=SR1-AY0; {Compute difference}
SR=ASHIFT AR BY -4 (HI); {Time constant is 1/16}
AR=SR1+AY0; {Add gain}
RTS;
trigger_true: CNTR=6; {Only called when trigger true}
AX0=0;
DO trigger UNTIL CE;
trigger: PM(I4,M5)=AX0; {Set all b-coefficients to 0}
AX1=DM(dq);
DM(tdp)=AX0; {Set tdp to 0}
PM(I5,M5)=AX0; {Set a2 to 0}
PM(I5,M5)=AX0; {Set a1 to 0}
AR=ABS AX1; {Add dq to delay line}
SE=EXP AR (HI);
AX0=SE, SR=NORM AR (HI);
SR=LSHIFT SR1 BY -9 (HI);
AY0=11;
AY1=32;
AR=SR1 OR AY1;
AY1=DM(a_ik);
SR=LSHIFT AR BY 2 (HI);
AR=AX0+AY0, DM(I0,M1)=AY1;
DM(I0,M1)=AR;
DM(I0,M1)=SR1;
AY0=DM(sez); {Compute new p values}
AR=AX1+AY0;
AX0=DM(p);
AY0=DM(p_o);
DM(p)=AR;
DM(p_o)=AX0;
DM(p_o_o)=AY0;
AR=256;
DM(ap)=AR; {Set ap to triggered value}
RTS;
update_filter: AX0=DM(dq); {Get value of current dq}
AR=128;
AF=PASS AX0, AY1=DM(I0,M0); {Read sign of dq(6)}
IF EQ AR=PASS 0; {If dq 0 then gain 0}
SE=-8; {Time constand is 1/256}
AX1=AR;
CNTR=6;
DO update_b UNTIL CE; {Update all b-coefficients}
AF=AX0 XOR AY1, AY0=PM(I4,M4);{Get sign of update}
IF LT AR=-AX1;
AF=AR+AY0, SI=AY0; {Add update to original b}
SR=ASHIFT SI (HI), AY1=DM(I0,M0);{Get next dq(k)}
AR=AF-SR1; {Subtract leak factor}
update_b: PM(I4,M5)=AR, AR=PASS AX1; {Write out new b-coefficient}
place_dq: AR=ABS AX0, AY0=DM(I0,M2); {Take absolute value of dq}
SE=EXP AR (HI); {Determine exponent adjust}
SR1=H#4000; {Set minimum value into SR1}
AX1=SE, SR=SR OR NORM AR (HI); {Normalize dq}
AY0=11; {Used for exponent adjustment}
SR=LSHIFT SR1 BY -9 (HI); {Remove lower bits}
SR=LSHIFT SR1 BY 2 (HI); {Adjust for ADSP-210x version}
DM(I0,M2)=SR1, AR=AX1+AY0; {Save mantisa, compute exp.}
DM(I0,M2)=AR; {Save exponent}
AX1=DM(a_ik); {Use sign of I, not dq}
DM(I0,M0)=AX1; {Save sign}
update_p: AY0=DM(sez); {Get result of predictor}
AR=AX0+AY0; {Use dq from above}
AY1=DM(p); {Delay all old p's by 1}
AY0=DM(p_o);
DM(p)=AR;
DM(p_o)=AY1;
DM(p_o_o)=AY0;
AX1=AR, AR=AR XOR AY0; {Compute p xor poo}
MR1=AR, AR=AX1 XOR AY1; {Compute p xor po}
MR0=AR;
upa2: I3=^a_data;
SI=PM(I5,M5); {Hold a2 for later}
AR=PM(I5,M5); {Get a1 for computation of f}
AR=ABS AR, AY0=DM(I3,M1); {Cap magnitude of a1 at 1/2}
AF=AR-AY0, SE=DM(I3,M1);
IF GT AR=PASS AY0;
IF NEG AR=-AR; {Restore sign}
SR=ASHIFT AR (LO), AY0=DM(I3,M1);
AF=ABS MR0, AY1=DM(I3,M1); {If p xor po = 0 negate f}
AR=SR0, AF=PASS SR1;
IF POS AR=AY1-SR0; {Double precision}
IF POS AF=AY1-SR1+C-1;
SR0=AR, AR=PASS AF;
SR1=AR, AF=ABS MR1; {If p xor poo = 1 subtract}
AR=SR0+AY0, SE=DM(I3,M1);
AF=SR1+AY1+C, AX0=DM(I3,M1);
IF NEG AR=SR0-AY0;
IF NEG AF=SR1-AY1+C-1;
SR=LSHIFT AR (LO);
AR=PASS AF;
SR=SR OR ASHIFT AR (HI), AY0=SI;
AY1=SR0, SR=ASHIFT SI (HI); {Downshift a2 for adjustment}
AR=AY0-SR1, AY0=DM(I3,M1);
AF=PASS AX1;
IF NE AR=AR+AY1; {If sigpk = 1, no gain}
limc: AF=AR-AY0, AY1=DM(I3,M1); {Limit a2 to .75 max}
IF GT AR=PASS AY0;
AF=AR-AY1, AY0=DM(I3,M1); {Limit a2 to -.75 min}
IF LT AR=PASS AY1;
PM(I5,M5)=AR; {Store new a2}
tone: AF=AR-AY0, AY1=AR; {If a2 < .71, tone = 1}
AR=0;
IF LT AR=PASS 1;
DM(tdp)=AR; {Store new tdp value (for ap)}
upa1: AR=AX0, AF=PASS MR0;
IF LT AR=-AX0;
AF=PASS AX1, SI=PM(I5,M4);
IF EQ AR=PASS 0;
SR=ASHIFT SI BY -8 (HI); {Leak Factor = 1/256}
AF=PASS AR, AR=SI;
AF=AF-SR1;
AR=AR+AF, AX1=DM(I3,M1);
limd: AX0=AR, AR=AX1-AY1; {Limit a1 based on a2}
AY0=AR, AR=AY1-AX1;
AY1=AR, AR=PASS AX0;
AF=AR-AY0;
IF GT AR=PASS AY0; {Upper limit 1 - 2^-4 - a2}
AF=AR-AY1;
IF LT AR=PASS AY1; {Lower limit a2 - 1 + 2^-4}
PM(I5,M5)=AR; {Store new a1}
RTS;
trigger_true_r: CNTR=6; {Here only if trigger true}
AX0=0;
DO trigger_r UNTIL CE;
trigger_r: PM(I4,M5)=AX0; {Set all b-coefficients to 0}
AX1=DM(dq_r);
DM(tdp_r)=AX0; {Set tdp to 0}
PM(I5,M5)=AX0; {Set a2 to 0}
PM(I5,M5)=AX0; {Set a1 to 0}
AR=ABS AX1; {Add dq_r to delay line}
SE=EXP AR (HI);
AX0=SE, SR=NORM AR (HI);
SR=LSHIFT SR1 BY -9 (HI);
AY0=11;
AY1=32;
AR=SR1 OR AY1;
AY1=DM(a_ik_r);
SR=LSHIFT AR BY 2 (HI);
AR=AX0+AY0, DM(I0,M1)=AY1;
DM(I0,M1)=AR;
DM(I0,M1)=SR1;
AY0=DM(sez); {Compute new p_r's}
AR=AX1+AY0;
AX0=DM(p_r);
AY0=DM(p_o_r);
DM(p_r)=AR;
DM(p_o_r)=AX0;
DM(p_o_o_r)=AY0;
AR=256;
DM(ap_r)=AR; {Set ap_r to triggered value}
RTS;
update_filter_r:AX0=DM(dq_r); {Get dq_r}
AR=128; {Set possible gain}
AF=PASS AX0, AY1=DM(I0,M0); {Get sign of dq(6)}
IF EQ AR=PASS 0; {If dq_r 0, gain 0}
SE=-8; {Leak factor 1/256}
AX1=AR;
CNTR=6;
DO update_b_r UNTIL CE; {Update all b-coefficients}
AF=AX0 XOR AY1, AY0=PM(I4,M4);{Get sign of gain}
IF LT AR=-AX1;
AF=AR+AY0, SI=AY0; {Add gain to original b}
SR=ASHIFT SI (HI); {Time constant is 1/256}
AR=AF-SR1, AY1=DM(I0,M0); {Compute new b-value}
update_b_r: PM(I4,M5)=AR, AR=PASS AX1; {Store new b-value}
place_dq_r: AR=ABS AX0, AY0=DM(I0,M2); {Get absolute value fo dq_r}
SE=EXP AR (HI); {Determine exponent adjustment}
SR1=H#4000; {Set SR to minimum value}
AX1=SE, SR=SR OR NORM AR (HI); {Normalize dq_r}
AY0=11; {Used for exponent adjust}
SR=LSHIFT SR1 BY -9 (HI); {Remove lower bits}
SR=LSHIFT SR1 BY 2 (HI); {Adjust for ADSP-210x version}
DM(I0,M2)=SR1, AR=AX1+AY0; {Store mantissa, compute exp}
AX1=DM(a_ik_r); {Use sign of I, not dq}
DM(I0,M2)=AR; {Store exponent}
DM(I0,M0)=AX1; {Store sign}
update_p_r: AY0=DM(sez); {Compute new p}
AR=AX0+AY0; {Use dq_r from above}
AY1=DM(p_r); {Delay old p's by 1}
AY0=DM(p_o_r);
DM(p_r)=AR;
DM(p_o_r)=AY1;
DM(p_o_o_r)=AY0;
AX1=AR, AR=AR XOR AY0; {Compute p and poo}
MR1=AR, AR=AX1 XOR AY1; {Compute p and po}
MR0=AR;
upa2_r: I3=^a_data;
SI=PM(I5,M5); {Hold a2 for later}
AR=PM(I5,M5); {Get a1 for computation of f}
AR=ABS AR, AY0=DM(I3,M1); {Cap magnitude of a1 to 1/2}
AF=AR-AY0, SE=DM(I3,M1);
IF GT AR=PASS AY0;
IF NEG AR=-AR; {Restore sign of f}
SR=ASHIFT AR (LO), AY0=DM(I3,M1);
AF=ABS MR0, AY1=DM(I3,M1); {If p_r xor poo_r =1 subtract}
AR=SR0, AF=PASS SR1;
IF POS AR=AY1-SR0;
IF POS AF=AY1-SR1+C-1;
SR0=AR, AR=PASS AF;
SR1=AR, AF=ABS MR1;
AR=SR0+AY0, SE=DM(I3,M1);
AF=SR1+AY1+C, AX0=DM(I3,M1);
IF NEG AR=SR0-AY0;
IF NEG AF=SR1-AY1+C-1;
SR=LSHIFT AR (LO);
AR=PASS AF;
SR=SR OR ASHIFT AR (HI), AY0=SI;
AY1=SR0, SR=ASHIFT SI (HI); {Leak factor of 1/128}
AR=AY0-SR1, AY0=DM(I3,M1);
AF=PASS AX1;
IF NE AR=AR+AY1; {If sigpk = 1 , no gain}
limc_r: AF=AR-AY0, AY1=DM(I3,M1); {Limit a2 to .75 max}
IF GT AR=PASS AY0;
AF=AR-AY1, AY0=DM(I3,M1); {Limit a2 to -.75 min}
IF LT AR=PASS AY1;
PM(I5,M5)=AR; {Store new a2}
tone_r: AF=AR-AY0, AY1=AR;
AR=0;
IF LT AR=PASS 1; {If a2 < .71, tdp = 1}
DM(tdp_r)=AR;
upa1_r: AR=AX0, AF=PASS MR0;
IF LT AR=-AX0;
AF=PASS AX1, SI=PM(I5,M4);
IF EQ AR=PASS 0;
SR=ASHIFT SI BY -8 (HI); {Leak Factor = 1/256}
AF=PASS AR, AR=SI;
AF=AF-SR1;
AR=AR+AF, AX1=DM(I3,M1);
limd_r: AX0=AR, AR=AX1-AY1; {Limit a1 based on a2}
AY0=AR, AR=AY1-AX1;
AY1=AR, AR=PASS AX0;
AF=AR-AY0;
IF GT AR=PASS AY0; {Upper limit 1 - 2^-4 -a2}
AF=AR-AY1;
IF LT AR=PASS AY1; {Lower limit a2 - 1 + 2^-4}
PM(I5,M5)=AR; {Store new a1 }
RTS;
sync: AX0=DM(a_ik_r); {Get input value of I}
AY1=AR, AF=ABS AR;
IF NEG AR=AY1+1; {Convert 1's comp to 2's comp}
AY1=AX0, AF=ABS AX0;
IF NEG AF=AY1+1; {Same for new I value }
AR=AR-AF;
AR=DM(sp_r);
IF GT JUMP decrement_sp; {Next most negative value}
IF LT JUMP increment_sp; {Next most positive value}
AF=PASS AX0; {Check for invalid 0 input}
IF NE RTS;
increment_sp: SR=LSHIFT AR BY 8 (HI); {Get sign of PCM value}
AY0=H#80;
AF=AR-AY0;
IF EQ RTS; {Already maximum value}
AF=ABS SR1;
AF=PASS 1;
IF NEG AF=PASS -1; {If negative, subtract 1}
AR=AR+AF; {Compute adjusted PCM value}
RTS;
decrement_sp: SR=LSHIFT AR BY 8 (HI); {Get sign of PCM value}
AR=PASS AR;
IF EQ RTS; {Already minimum value}
AY0=H#FF;
AF=AR-AY0;
IF NE JUMP no_sign_chn; {If input is H#FF}
AR=H#7E; {New output will be h#7E}
RTS;
no_sign_chn: AF=ABS SR1; {Otherwise adjust by 1}
AF=PASS -1;
IF NEG AF=PASS 1; {Add 1 for negative values}
AR=AR+AF; {Compute adjusted PCM value}
RTS;
.ENDMOD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -