Metropoli BBS
VIEWER: resample.asm MODE: TEXT (ASCII)
	.model large,c
	.386

	LOCALS
	JUMPS

	public VC_ResampleMixMono
	public VC_ResampleMixStereo
	public VC_Sample16To8Copy
	public VC_MemSet
	extrn  ampbuf

.code


SampleMono MACRO
	mov  bl,ds:[si]				; get byte from sample
	mov  ax,fs:[ebx*2]			; get volume-adjusted word
	add  es:[di],ax				; add word to mix-buffer
	add  edi,edx				; di+=2 iter+=fraction
	adc  si,cx					; si+=carry+whole
	ENDM


SampleStereo MACRO
	mov  bl,ds:[si]				; sample to bl
	mov  ax,fs:[ebx*2]			; left volume-adjusted word to ax
	add  es:[di],ax				; mix it
	mov  ax,gs:[ebx*2]			; right """
	add  es:2[di],ax			; mix it
	add  edi,edx				; di+=4 iter+=fraction
	adc  si,cx					; si+=carry+whole
	ENDM


S16To8 MACRO
	mov bx,ds:[si]
	mov al,fs:[bx]
	mov es:[di],al
	inc di
	add si,2
	ENDM


VC_MemSet proc

	USES CX,ES,DI

	ARG dest : far ptr;
	ARG data : word ;
	ARG count: word ;

	les di,small dest
	mov cx,count
	mov ax,data
	cld
	rep stosw
	ret

	endp


; This macro executes 'function' unfolds*counter times.. unfolds should be
; a constant number, and counter should be a variable or register
;

MyLoop MACRO function,unfolds,counter
	LOCAL entr,lplb

	jmp entr
lplb:
	REPT unfolds
	function
	ENDM
entr:
	dec counter
	jns lplb
	ENDM



VC_ResampleMixMono proc

	USES ES,DS,FS,GS,ESI,EDI,EDX,EBX

	ARG  srce  : far ptr
	ARG  dest  : far ptr
	ARG  volt  : far ptr
	ARG  todo  : word 	;
	ARG  telo  : dword	;
	ARG  itrr  : far ptr 	;

	LOCAL cnt32: word;
	LOCAL cnt01: word;

	mov  ax,todo
	shr  ax,5
	mov  cnt32,ax

	mov  ax,todo
	and  ax,31
	mov  cnt01,ax

	lds  si,small itrr
	mov  di,[si]           		; di=iter
	ror  edi,16					; edi=iter:?

	lds  si,small srce
	push si

	lfs  di,small volt			;voltab to fs:di
	les  di,small dest			; edi=iter:dest

	mov  dx,word ptr [telo]		; dx is fraction
	ror  edx,16					; edx = fraction:?
	mov  dx,2					; edx = fraction:2

	mov  cx,word ptr [telo+2]	; cx is whole

	xor  ebx,ebx

	MyLoop SampleMono,32,cnt32
	MyLoop SampleMono,1,cnt01

	mov  ax,si
	pop  bx
	sub  ax,bx

	ror  edi,16
	lds  si,small itrr
	mov  ds:[si],di

	ret
	endp



VC_ResampleMixStereo proc

	USES ES,DS,FS,ESI,EDI,EDX,EBX

	ARG  srce  : far ptr
	ARG  dest  : far ptr
	ARG  voll  : far ptr
	ARG  volr  : far ptr
	ARG  todo  : word 	;
	ARG  telo  : dword	;
	ARG  itrr  : far ptr 	;

	LOCAL cnt32: word;
	LOCAL cnt01: word;

	mov  ax,todo
	shr  ax,5
	mov  cnt32,ax

	mov  ax,todo
	and  ax,31
	mov  cnt01,ax

	lds  si,small itrr
	mov  di,[si]				; di=iter
	ror  edi,16					; edi=iter:?

	lds  si,small srce
	push si

	lfs  di,small voll			; left voltab to fs:di
	lgs  di,small volr			; right voltab to gs:di
	les  di,small dest

	mov  dx,word ptr [telo]		; dx is fraction
	ror  edx,16					; edx = fraction:?
	mov  dx,4					; edx = fraction:4

	mov  cx,word ptr [telo+2]	; cx is whole

	xor  ebx,ebx				; clear ebx

	MyLoop SampleStereo,32,cnt32
	MyLoop SampleStereo,1,cnt01

	mov  ax,si
	pop  bx
	sub  ax,bx

	ror  edi,16
	lds  si,small itrr
	mov  ds:[si],di

	ret
	endp




VC_Sample16To8Copy proc
	USES FS,ES,DS,SI,DI

	ARG srce: far ptr	;16 bits samples source
	ARG dest: far ptr	; 8 bits samples destiny
	ARG cnt : word		;number of samples to convert
						;
	lds  si,small srce	;ds:si source pointer (pointing to 16 bit samples)
	les  di,small dest	;es:di destiny (8 bit samplebuffer)

	mov  ax,seg ampbuf
	mov  fs,ax          ;fs:0000h is address of amplify table

	mov  cx,cnt			;cx = number of samples to convert
	shr  cx,5			;div 32

	MyLoop S16To8,32,cx	;do large blocks of 32 samples at a time

	mov  cx,cnt         ;
	and  cx,31			;cx = number of samples left to do

	MyLoop S16To8,1,cx	;

	ret                 ;
	endp


	END
[ RETURN TO DIRECTORY ]