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

📄 adpcm.asm

📁 Training embedded apps to process speech may be as easy as finding the right 8-bit micro. Don t let
💻 ASM
字号:
 cblock	<StartAddress>
	PrevSampleL
	PrevSampleH
	PrevIndex
	DiffL
	DiffH
	StepL
	StepH
	PredSampleL
	PredSampleH
	PredSampleU
	DiffqL
	DiffqH
	Index
	SampleL
	SampleH
	Code
 endc

;**********************************************************************
;* Table of index changes
;********************************************************************** 
IndexTable
	addwf	PCL,F
dt	0xff,0xff,0xff,0xff,2,4,6,8,0xff,0xff,0xff,0xff,2,4,6,8

;********************************************************************** 
;* Quantizer step size lookup table
;********************************************************************** 
StepSizeTable
	addwf  PCL,F
dt	0x07,0x00,0x08,0x00,0x09,0x00,0x0A,0x00,0x0B,0x00,0x0C,0x00,0x0D
dt	0x00,0x0E,0x00,0x10,0x00,0x11,0x00,0x13,0x00,0x15,0x00,0x17,0x00
dt	0x19,0x00,0x1C,0x00,0x1F,0x00,0x22,0x00,0x25,0x00,0x29,0x00,0x2D
dt	0x00,0x32,0x00,0x37,0x00,0x3C,0x00,0x42,0x00,0x49,0x00,0x50,0x00
dt	0x58,0x00,0x61,0x00,0x6B,0x00,0x76,0x00,0x82,0x00,0x8F,0x00,0x9D
dt	0x00,0xAD,0x00,0xBE,0x00,0xD1,0x00,0xE6,0x00,0xFD,0x00,0x17,0x01
dt	0x33,0x01,0x51,0x01,0x73,0x01,0x98,0x01,0xC1,0x01,0xEE,0x01,0x20
dt	0x02,0x56,0x02,0x92,0x02,0xD4,0x02,0x1C,0x03,0x6C,0x03,0xC3,0x03
dt	0x24,0x04,0x8E,0x04,0x02,0x05,0x83,0x05,0x10,0x06,0xAB,0x06,0x56
dt	0x07,0x12,0x08,0xE0,0x08,0xC3,0x09,0xBD,0x0A,0xD0,0x0B,0xFF,0x0C
dt	0x4C,0x0E,0xBA,0x0F,0x4C,0x11,0x07,0x13,0xEE,0x14,0x06,0x17,0x54
dt	0x19,0xDC,0x1B,0xA5,0x1E,0xB6,0x21,0x15,0x25,0xCA,0x28,0xDF,0x2C
dt	0x5B,0x31,0x4B,0x36,0xB9,0x3B,0xB2,0x41,0x44,0x48,0x7E,0x4F,0x71
dt	0x57,0x2F,0x60,0xCE,0x69,0x62,0x74,0xFF,0x7F

;********************************************************************** 
;*   ADPCMEncoder - ADPCM encoder routine
;*   The sample to be encoded is loaded into SampleH:SampleL before
;*   calling this routine.
;********************************************************************** 
ADPCMEncoder
	bcf    STATUS,RP0

; Restore prev values of predicted sample & quantizer step size index
	movf   PrevSampleL,W		;predsample = state.prevsample;
	movwf  PredSampleL
	movf   PrevSampleH,W
	movwf  PredSampleH
	movlw  0xFF
	movwf  PredSampleU
	btfss  PredSampleH,7
	clrf   PredSampleU,F
	movf   PrevIndex,W		;index = state.previndex;
	movwf  Index
	movf   Index,W			;step = StepSizeTable[index];
	movwf  FSR
	bcf    STATUS,C
	rlf    FSR,F
	movlw  0x00
	movwf  PCLATH
	movf   FSR,W
	call   StepSizeTable
	bcf    STATUS,RP0
	movwf  StepL
	incf   FSR,F
	movlw  0x00
	movwf  PCLATH
	movf   FSR,W
	call   StepSizeTable
	bcf    STATUS,RP0
	movwf  StepH

; Compute difference between the acutal sample and the predicted sample
	movf   PredSampleL,W		;diff = sample - predsample;
	subwf  SampleL,W
	movwf  DiffL
	movf   PredSampleH,W
	btfss  STATUS,C
	addlw  0x01
	subwf  SampleH,W
	movwf  DiffH
	btfsc  DiffH,7			;if(diff >= 0)
	goto   EInvertDiff
	clrf   Code				;	code = 0;
	goto   EQuantize			;else
EInvertDiff					;{
	movlw  0x08				;	code = 8;
	movwf  Code
	comf   DiffH,F			;	diff = -diff;
	comf   DiffL,F
	incf   DiffL,F
	btfss  STATUS,Z
	goto   EQuantize
	bcf    STATUS,RP0
	incf   DiffH,F			;}

; Quantize diff into 4-bit ADPCM code using the quantizer step size &
; Inverse quantize into predicted diff using quantizer step size
EQuantize
	bcf    STATUS,RP0			;diffq = step >> 3;
	movf   StepL,W
	movwf  DiffqL
	movf   StepH,W
	movwf  DiffqH
	rlf    DiffqH,W
	rrf    DiffqH,F
	rrf    DiffqL,F
	rlf    DiffqH,W
	rrf    DiffqH,F
	rrf    DiffqL,F
	rlf    DiffqH,W
	rrf    DiffqH,F
	rrf    DiffqL,F
	movf   StepL,W			;if( diff >= step )
	subwf  DiffL,W			:{
	movlw  0x80           
	xorwf  DiffH,W          
	movwf  29            
	movlw  0x80           
	xorwf  StepH,W          
	btfss  STATUS,C          
	addlw  0x01           
	subwf  29,W          
	btfss  STATUS,C          
	goto   ECode2
	bcf    STATUS,RP0			;	code |= 4;
	bsf    Code,2
	movf   StepL,W			;	diff -= step;
	subwf  DiffL,F
	movf   StepH,W
	btfss  STATUS,C
	addlw  0x01
	subwf  DiffH,F
	movf   StepL,W			;	diffq += step;
	addwf  DiffqL,F
	movf   StepH,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  DiffqH,F			;}
ECode2
	bcf    STATUS,RP0			;step >>= 1;
	rlf    StepH,W
	rrf    StepH
	rrf    StepL
	movf   StepL,W			;if( diff >= step )
	subwf  DiffL,W			;{
	movlw  0x80           
	xorwf  DiffH,W          
	movwf  29            
	movlw  0x80           
	xorwf  StepH,W          
	btfss  STATUS,C          
	addlw  0x01           
	subwf  29,W          
	btfss  STATUS,C          
	goto   ECode1
	bcf    STATUS,RP0			;	code |= 2;
	bsf    Code,1
	movf   StepL,W			;	diff -= step;
	subwf  DiffL,F
	movf   StepH,W
	btfss  STATUS,C
	addlw  0x01
	subwf  DiffH,F
	movf   StepL,W			;	diffq += step;
	addwf  DiffqL,F
	movf   StepH,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  DiffqH,F			;}
ECode1
	bcf    STATUS,RP0		;step >>= 1;
	rlf    StepH,W
	rrf    StepH,F
	rrf    StepL,F
	movf   StepL,W			;if( diff >= step )
	subwf  DiffL,W			;{
	movlw  0x80           
	xorwf  DiffH,W          
	movwf  29            
	movlw  0x80
	xorwf  StepH,W          
	btfss  STATUS,C          
	addlw  0x01           
	subwf  29,W          
	btfss  STATUS,C          
	goto   ENewPredict
	bcf    STATUS,RP0		;	code |= 1;
	bsf    Code,0
	movf   StepL,W			;	diffq += step;
	addwf  DiffqL
	movf   StepH,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  DiffqH,F			;}

; Fixed predictor computes new predicted sample by adding the old predicted sample 
; to predicted difference
ENewPredict
	bcf    STATUS,RP0		;if( code & 8 )
	btfss  Code,3          
	goto   EAddDiff
	movf   DiffqL,W			;	predsample -= diffq;
	subwf  PredSampleL,F
	movf   DiffqH,W
	btfss  STATUS,C
	addlw  0x01
	subwf  PredSampleH,F
	clrw
	btfss  STATUS,C
	addlw  0x01
	subwf  PredSampleU,F
	goto   EOverflow
EAddDiff					;else
	movf   DiffqL,W			;	predsample += diffq;
	addwf  PredSampleL
	movf   DiffqH,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  PredSampleH,F
	clrw
	btfsc  STATUS,C
	addlw  0x01
	addwf  PredSampleU,F

; Check for overflow of the new predicted sample
EOverflow
	movf   PredSampleU,F		;if( predsample > 32767 )
	btfss  STATUS,Z
	goto   ECheckNeg
	btfss  PredSampleH,7
	goto   ECheckNeg
	movlw  0xFF				;	predsample = 32767;
	bcf    STATUS,RP0
	movwf  PredSampleL
	movlw  0x7F
	movwf  PredSampleH
	goto   ENewIndex
ECheckNeg					;else if( predsample < -32768)
	incf   PredSampleU,W
	btfss  STATUS,Z
	goto   ENewIndex
	btfsc  PredSampleH,7
	goto   ENewIndex
	bcf    STATUS,RP0			;	predsample = -32768
	clrf   PredSampleL
	movlw  0x80
	movwf  PredSampleH

; Find new quantizer stepsize index by adding old index to table lookup 
; using the ADPCM code
ENewIndex
	clrf   PCLATH			;index += IndexTable[code];
	bcf    STATUS,RP0
	movf   Code,W
	call   IndexTable
	bcf    STATUS,RP0
	addwf  Index,F

; Check for overflow of the new quantizer step size index
	btfsc  Index,7			;if( index < 0 )
	clrf   Index			;	index = 0;
	movlw  0x80				;if( index > 88 )
	xorwf  Index,W          
	movwf  21            
	movlw  0xD8           
	subwf  21,W          
	btfss  STATUS,Z          
	btfss  STATUS,C          
	goto   ESave         
	movlw  0x58				;	index = 88;
	bcf    STATUS,RP0
	movwf  Index

; Save predicted sample & quantizer step size index for next iteration
ESave
	bcf    STATUS,RP0			;state.prevsample = predsample;
	movf   PredSampleL,W
	movwf  PrevSampleL
	movf   PredSampleH,W
	movwf  PrevSampleH
	movf   Index,W			;state.previndex = index;
	movwf  PrevIndex

; ADPCM code is in the register Code
	return 				;}

;********************************************************************** 
;*   ADPCMDecoder - ADPCM decoder routine
;*   The ADPCM code to decode is stored in the register Code before
;*   calling this routine.
;********************************************************************** 
ADPCMDecoder				;{
	bcf    STATUS,RP0

; Restore prev values of predicted sample & quantizer step size index
	movf   PrevSampleL,W		;predsample = state.prevsample;
	movwf  PredSampleL
	movf   PrevSampleH,W
	movwf  PredSampleH
	movlw  0xFF
	movwf  PredSampleU
	btfss  PredSampleH,7
	clrf   PredSampleU,F
	movf   PrevIndex,W		;index = state.previndex;
	movwf  Index

; Find quantizer step size from lookup table using index
	movf   Index,W			;step = StepSizeTable[index];
	movwf  FSR
	bcf    STATUS,C
	rlf    FSR,F
	movlw  0x00
	movwf  PCLATH
	movf   FSR,W
	call   StepSizeTable
	bcf    STATUS,RP0
	movwf  StepL
	incf   FSR,F
	movlw  0x00
	movwf  PCLATH
	movf   FSR,W
	call   StepSizeTable
	bcf    STATUS,RP0
	movwf  StepH

; Inverse quantize ADPCM code into diff using the quantizer step size
	movf   StepL,W			;diffq = step >> 3;
	movwf  DiffqL
	movf   StepH,W
	movwf  DiffqH
	rlf    DiffqH,W
	rrf    DiffqH,F
	rrf    DiffqL,F
	rlf    DiffqH,W
	rrf    DiffqH,F
	rrf    DiffqL,F
	rlf    DiffqH,W
	rrf    DiffqH,F
	rrf    DiffqL,F
	btfss  Code,2			;if( code & 4 )
	goto   DCode2
	movf   StepL,W			;	diffq += step;
	addwf  DiffqL
	movf   StepH,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  DiffqH,F
DCode2
	btfss  Code,1			;if( code & 2 )
	goto   DCode1
	movf   StepL,W			;	diffq += step >> 1;
	movwf  28
	movf   StepH,W
	movwf  29
	rlf    29,W
	rrf    29
	rrf    28
	movf   28,W
	addwf  DiffqL
	movf   29,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  DiffqH,F
DCode1
	btfss  Code,0			;if( code & 1 )
	goto   DNewPredict
	movf   StepL,W			;	diffq += step >> 2;
	movwf  28
	movf   StepH,W
	movwf  29
	rlf    29,W
	rrf    29
	rrf    28
	rlf    29,W
	rrf    29
	rrf    28
	movf   28,W
	addwf  DiffqL,F
	movf   29,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  DiffqH,F

; Add the difference to the predicted sample
DNewPredict
	btfss  Code,3			;if( code & 8 )
	goto   DAddDiff
	movf   DiffqL,W			;	predsample -= diffq;
	subwf  PredSampleL,F
	movf   DiffqH,W
	btfss  STATUS,C
	addlw  0x01
	subwf  PredSampleH,F
	clrw
	btfss  STATUS,C
	addlw  0x01
	subwf  PredSampleU,F
	goto   DOverflow
DAddDiff					;else
	movf   DiffqL,W			;	predsample += diffq;
	addwf  PredSampleL
	movf   DiffqH,W
	btfsc  STATUS,C
	addlw  0x01
	addwf  PredSampleH,F
	clrw
	btfsc  STATUS,C
	addlw  0x01
	addwf  PredSampleH,F

; Check for overflow of the new predicted sample
DOverflow
	movf   PredSampleU,F		;if( predsample > 32767 )
	btfss  STATUS,Z
	goto   DCheckNeg
	btfss  PredSampleH,7
	goto   DCheckNeg
	movlw  0xFF				;	predsample = 32767;
	bcf    STATUS,RP0
	movwf  PredSampleL
	movlw  0x7F
	movwf  PredSampleH
	goto   DNewIndex
DCheckNeg					;else if( predsample < -32768 )
	incf   PredSampleU,W
	btfss  STATUS,Z
	goto   DNewIndex
	btfsc  PredSampleH,7
	goto   DNewIndex
	bcf    STATUS,RP0			;	predsample = -32768;
	clrf   PredSampleL
	movlw  0x80
	movwf  PredSampleH

; Find new quantizer step size by adding old index and a table lookup
; using the ADPCM code
DNewIndex
	clrf   PCLATH			;index += IndexTable[code];
	bcf    STATUS,RP0
	movf   Code,W
	call   IndexTable
	bcf    STATUS,RP0
	addwf  Index,F

; Check for overflow of the new quantizer step size index
	btfsc  Index,7			;if( index < 0 )
	clrf   Index			;	index = 0;
	movlw  0x80				;if( index > 88 )
	xorwf  Index,W          
	movwf  21            
	movlw  0x,D8           
	subwf  21,W          
	btfss  STATUS,Z          
	btfss  STATUS,C          
	goto   DSave
	movlw  0x58				;	index = 88;
	bcf    STATUS,RP0
	movwf  Index


; Save predicted sample & quantizer step size index for next iteration
DSave
	bcf    STATUS,RP0			;state.prevsample = predsample;
	movf   PredSampleL,W
	movwf  PrevSampleL
	clrf   PrevSampleH
	btfsc  PrevSampleL,7
	decf   PrevSampleH
	bcf    STATUS,RP0			;state.previndex = index;
	movf   Index,W
	movwf  PrevIndex

; Speech sample is in the registers PredSampleH:PredSampleL
	return 				;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -