Digital Signal Processing Logic

CONTINUOUS VARIABLE SLOPE DELTA (CVSD)

Bob Ammerman wrote:

Here is my understanding so far, expressed in C-like pseudocode:

     FULL_SCALE = the highest valid sample value
     MIN_DELTA = a constant
     MAX_DELTA = another constant

     cur_delta = MIN_DELTA;

     cur_value = FULL_SCALE / 2;        // Current output value

     for (;;)        // loop as long as we have samples to encode
     {
         // see if we are in a slope overload condition
         if (last 3 bits have all been 0's or all been 1's)
             overload = 1;
         else
             overload = 0;

         // given our current delta, and whether we are in a slope
         // overload, compute our new delta. This will probably be done
         // via lookup in a precomputed table. The function implemented
         // is an exponential (ie: like a capacitor charge/discharge curve)
         // limited at MIN_DELTA and MAX_DELTA. We 'charge' the cap
         // when overload is 1 and 'discharge' when overload is 0.

         cur_delta = compute_new_delta(cur_delta, overload);

         // adjust the output value in the correct direction
         if (input_value > cur_value)
         {
             output a 1;
             cur_value += cur_delta;
             if (cur_value > FULL_SCALE)
                 cur_value = FULL_SCALE;
         }
         else
         {
             output a 0;
             cur_value -= cur_delta;
             if (cur_value < 0)
                 cur_value = 0
         }
     }

Richard Ottosen says:

I fired up my old Apple ][ (that's an oxymoron) and pulled off the CVSD files. I have attached them in a zip file. Use them at your own risk since I haven't looked at them in a dozen years. They are in a slightly unusual (for the 6502 microprocessor) assembler syntax.
;ECHOCVSD.P65
;THIS PROGRAM WILL INPUT SOUNDS FROM
;AN A/D AND OUTPUT THOSE SOUNDS TO THE
;THE D/A.
;A MOUNTAIN HARDWARE A/D+D/A CARD IS
;EXPECTED TO BE IN SLOT 5.
;THE DATA IS CONTINUOUS VARIABLE SLOPE
;DELTA (CVSD) MODULATED AND DEMODULATED
;BEFORE OUTPUTTING. THERE IS ABOUT 37K
;BYTES OF STORAGE. THE DATA IS PACKED
;8 BITS PER BYTE.



;DEFINE WHERE THE A/D AND D/A CONVERTORS
;ARE AT

	.DEF	A2D0=$C0D0	;A/D CHANNEL 0
	.DEF	D2A0=$C0D0	;D/A CHANNEL 0

;DEFINE TOP OF BUFFER MEMORY
	.DEF	BUFFEND=$A0	;TOP PAGE OF BUFFER +1

	.LOC	$56

PTR:	.WORD			;FOR ADDRESSING THE BUFFER

DIR:	.BYTE			;DIRECTION OF INTEGRATION
				;CARRY CLEAR FOR UP, CARRY SET
				; FOR DOWN

;MODULATOR VARIABLES
MSLOPE:	.BYTE			;SLOPE OF INTEGRATION
MINT:	.BYTE			;INTERGRATOR
MSHIFT:	.BYTE			;ALGORITHM SHIFT REGISTER
MTEMP:	.BYTE

;DEMODULATOR VARIABLES
DSLOPE:	.BYTE			;SLOPE OF INTEGRATION
DINT:	.BYTE			;INTERGRATOR
DSHIFT:	.BYTE			;ALGORITHM SHIFT REGISTER
DTEMP:	.BYTE


	.LOC	$800

START:	DMOV#	$1000,PTR	;INIT POINTER FOR BUFFER
	LDY#	0		; Y TOO
	LDA#	128		;INIT INTEGRATORS TO CENTER
	STA	MINT
	STA	DINT
	LDA#	1
	STA	MSLOPE		;INIT TO A CONSTANT SLOPE
	STA	DSLOPE
	LDA#	$55		;SET FOR NO SLOPE INTEGRATION
	STA	MSHIFT
	STA	DSHIFT

LOOP:	LDX#	8		;8 BITS PACKED PER BYTE
M05:	LDA	MINT		;GET INTEGRATOR AND A2D INPUT
	CMP	A2D0		;IS THE INPUT LARGER THAN THE
	BCS	M30		; LAST VALUE INTEGRATED TO?
M10:	ADC	MSLOPE		;IF SO, ADD A SLOPE INCREMENT
	BCC	M100
	LDA#	255
M20:	CLC			;INDICATE POSITIVE SLOPE
	BCC	M100
M30:	SBC	MSLOPE		; SUBTRACT THE SLOPE
	BCS	M100
	LDA#	0
M40:	SEC			;INDICATE NEGATIVE SLOPE
M100:	STA	MINT
	ROL	MSHIFT		;PUT DIR IN SHIFT REG.
	LDA	MSHIFT
	AND#	7		;DO 3 BIT ALGORITHM
	BEQ	M250
	CMP#	7
	BEQ	M250
	DEC	MSLOPE	
	BNE	M300		;DON'T LET SLOPE GO NEGATIVE
;NOTE: EVEN 0 MAY NOT BE DESIRABLE
M250:	INC	MSLOPE
	
M300:	DEX			;BYTE PACKED FULL YET?
	BNE	M05
	LDA	MSHIFT
	STA@Y	PTR		;STORE BYTE IN BUFFER

	INY			;INC POINTER AND
	BNE	LOOP
	INC	PTR +1
	LDA#	BUFFEND		;ARE WE PAST TOP PAGE OF BUFFER?
	CMP	PTR +1
	BNE	LOOP


;ECHO IT
LOOP3:	DMOV#	$1000,PTR

LOOP2:	LDX#	8		;8 PACKED BITS PER BYTE
	LDA@Y	PTR		;SIG:=SIG +/- SLOPE
	STA	DIR
D05:	LDA	DINT
	ROL	DIR
	BCS	D30		; LAST VALUE INTEGRATED TO?

D10:	ADC	DSLOPE		;IF SO, ADD A SLOPE INCREMENT
	BCC	D100
	LDA#	255
D20:	CLC			;INDICATE POSITIVE SLOPE
	BCC	D100
D30:	SBC	DSLOPE		; SUBTRACT THE SLOPE
	BCS	D100
	LDA#	0
D40:	SEC			;INDICATE NEGATIVE SLOPE
D100:	STA	DINT		;SAVE INTO INTEGRATOR
	STA	D2A0		;OUTPUT IT
	ROL	DSHIFT		;PUT DIR IN SHIFT REG.
	LDA	DSHIFT
	AND#	7		;DO 3 BIT ALGORITHM
	BEQ	D250
	CMP#	7
	BEQ	D250
	DEC	DSLOPE	
	BNE	D300		;DON'T LET SLOPE GO NEGATIVE
;NOTE: EVEN 0 MAY NOT BE DESIRABLE
D250:	INC	DSLOPE
	
D300:	DEX			;BYTE UNPACKED YET?
	BNE	D05

	INY
	BNE	LOOP2
	INC	PTR +1
	LDA#	BUFFEND
	CMP	PTR +1
	BNE	LOOP2

	JMP	START		;DO FOREVER

	.END

See also:

Questions: