⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adpcm.dsp

📁 adsp21x的数字信号处理器ADPCM音频压缩源代码
💻 DSP
📖 第 1 页 / 共 2 页
字号:
		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 + -