;	PCM SOUND PHASE SHIFT DELAY
;
;
;		Hiroshi TODA
;
;		1995 1 High C 用
;
;	phaseDelay( sourceSNDdata, distnationSNDdata, para, work ) ;
;	para:maindelay,phasedelay,mix1,mix2,md1,sp1,ang1,nd2,sp2,ang2
;	work:512Byte work area
; 


	.386p


param	struc

	dd	?
	dd	?
source	dd	?		; source snd.data address
new		dd	?		; new snd.data address
paradd	dd	?		; para. address
wadd	dd	? 		; work address

param   ends


work	struc

;data area

delay1	dd	?		; main delay Byte
delay2	dd	?		; phase delay Byte
mix1	dd	?		; main mix rate
mix2	dd	?		; vibrato mix rate
md1	dd	?		; modulation1
sp1	dd	?		; speed1 (90 = 10000H)
ang1	dd	?		; angle1
md2	dd	?		; modulation2
sp2	dd	?		; speed2 (90 = 10000H)
ang2	dd	?		; angle2

point0	dd	?		; 10000H-point1
point1	dd	?		; ov.sampling point (decimal)
point2	dd	?		; ov.sampling point (integer)
buf1	dd	?		; sampling add buf.

;	これ以下 1995 1 に追加
sourceStart	dd	?		; source data の 開始アドレス
sourceEnd	dd	?		; source data の 終了アドレス
dly		dd	?		; delay1 - delay2

work	ends


cseg	segment	dword public use32 'CODE'
	assume	cs:cseg,ds:cseg

	public	sndPhaseDelay
	db	'sndPhaseDelay',13
sndPhaseDelay	proc	near
	push	ebp
	mov		ebp,esp
	push	esi
	push	edi
	push	ebx

	mov	esi,[ebp].wadd		; esi <-- work area top add
	mov	edi,[ebp].source	; edi <-- source data add.
	mov	ebx,[ebp].new		; ebx <-- new data add.
	mov	ecx,[ebp].paradd	; ecx <-- para. add.
	xor	edx,edx			; edx=count
main00:
	mov	eax,[ecx][edx*4]	; para. --> work area
	mov	[esi][edx*4],eax
	inc	edx
	cmp	edx,10
	jb	main00

	mov	eax,[esi].delay1	; dly = delay1 - delay2
	sub	eax,[esi].delay2
	mov	[esi].dly,eax

	mov	edx,edi
	add	edx,32
	mov	[esi].sourceStart,edx	; sourceStart = source start address
	add	edx,[edi+12]
	mov	[esi].sourceEnd,edx		; sourceEnd = source end address

	mov	ecx,[edi+12]		; length
	cmp	ecx,0
	jbe	mainE				; jb を jbe に変更 1993 12

	xor	edx,edx				; snd head trans
main01:
	mov	eax,[edi][edx*4]
	mov	[ebx][edx*4],eax
	inc	edx
	cmp	edx,8
	jb	main01

	add	ebx,32
	add	edi,32
	add	edi,[esi].delay2	; ediはphaseに合わせる

main02:
	mov	[esi].point2,edi	; ov.sampling point cal.
	xor	eax,eax
	mov	[esi].point1,eax
	mov	eax,[esi].ang1
	call	sin			; eax = sin(eax)*10000H
	imul	dword ptr [esi].md1
	mov	[esi].buf1,eax
	mov	eax,[esi].ang2
	call	sin			; eax = sin(eax)*10000H
	imul	dword ptr [esi].md2
	add	eax,[esi].buf1
	cdq
	add	[esi].point1+2,eax
	adc	word ptr [esi].point2+2,dx

	mov	eax,[esi].point2	; source start〜end check
	cmp	eax,[esi].sourceEnd
	jae	main021
	cmp	eax,[esi].sourceStart
	jae	main03
main021:
	xor	eax,eax
	jmp	main04
main03:
	lea	eax,[esi].point1	; over sampling
	call	smp
main04:
	imul	eax,[esi].mix2		; mix
	mov	[esi].buf1,eax

	mov	eax,edi				; source start〜end check
	add	eax,[esi].dly
	cmp	eax,[esi].sourceEnd
	jae	main041
	cmp	eax,[esi].sourceStart
	jae	main05
main041:
	xor	eax,eax
	jmp	main06
main05:
	mov	edx,[esi].dly
	mov	al,[edi][edx]
	and	eax,0ffH
	cmp	eax,128
	jb	main06
	mov	edx,eax
	mov	eax,128
	sub	eax,edx
main06:
	imul	eax,[esi].mix1
	add	eax,[esi].buf1
	sar	eax,8
	js	main07			; eax --> pcm data
	je	main07
	cmp	eax,128			; +
	jb	main08
	mov	eax,127
	jmp	main08
main07:
	mov	edx,eax			; -
	mov	eax,128
	sub	eax,edx
	cmp	eax,256-1	; data255はloopStopの意味があるから除外 1993 12
	jb	main08
	mov	eax,255-1	; data255はloopStopの意味があるから除外 1993 12
main08:
	mov	[ebx],al

	mov	eax,[esi].sp1
	add	[esi].ang1,eax
	mov	eax,[esi].sp2
	add	[esi].ang2,eax
	inc	edi
	inc	ebx
	dec	ecx
	jne	main02

mainE:
	pop	ebx
	pop	edi
	pop	esi
	mov	esp,ebp
	pop	ebp
	ret

;	OVER SAMPLING for PCM DATA(8bit)
;input	eax = 64bit(32bit/decimal,32bit/integer) data address(ds:)
;output	eax = over sampring data ( 32bit sign (-128 -- +127) )

smp:	push	ebx
	push	ecx
	push	edx
	push	esi
	push	edi
	mov	ebx,[eax]		; ebx = decimal
	mov	esi,[eax+4]		; esi = integer
	shr	ebx,24			; ebx --> 8bit
	jne	smp00

	mov	al,[esi]		; decimal=0
	and	eax,0ffH
	cmp	eax,128
	jb	smp0A
	mov	edx,eax
	mov	eax,128
	sub	eax,edx
smp0A:	jmp	smp06

smp00:
	mov	eax,[esi-1]		; 周囲がみな無信号ならノイズを出さないよう直接0を返す
	cmp	eax,80808080h
	jne	smp0B
	xor	eax,eax
	jmp	smp06

smp0B:
	call	smp01
smp01:	pop	edi
	add	edi,smptb-smp01		; edi = table point

	mov	al,[esi]
	and	eax,0ffH
	cmp	eax,128
	jb	smp02
	mov	edx,eax
	mov	eax,128
	sub	eax,edx
smp02:	add	eax,128
	mul	byte ptr cs:[edi][ebx]
	mov	ecx,eax

	mov	al,[esi-1]
	and	eax,0ffH
	cmp	eax,128
	jb	smp03
	mov	edx,eax
	mov	eax,128
	sub	eax,edx
smp03:	add	eax,128
	mul	byte ptr cs:[edi][ebx+256]
	sub	ecx,eax

	mov	eax,ebx			; ebx = 256 - ebx
	mov	ebx,256
	sub	ebx,eax

	mov	al,[esi+1]
	and	eax,0ffH
	cmp	eax,128
	jb	smp04
	mov	edx,eax
	mov	eax,128
	sub	eax,edx
smp04:	add	eax,128
	mul	byte ptr cs:[edi][ebx]
	add	ecx,eax

	mov	al,[esi+2]
	and	eax,0ffH
	cmp	eax,128
	jb	smp05
	mov	edx,eax
	mov	eax,128
	sub	eax,edx
smp05:	add	eax,128
	mul	byte ptr cs:[edi][ebx+256]
	sub	ecx,eax
	sub	ecx,128*256
	sar	ecx,8
	mov	eax,ecx

smp06:	pop	edi
	pop	esi
	pop	edx
	pop	ecx
	pop	ebx
	ret	

smptb	db	255,255,255,254,254,253,253,252
	db	252,251,251,250,249,249,248,248
	db	247,246,246,245,244,244,243,243
	db	242,241,240,240,239,238,238,237
	db	236,236,235,234,233,233,232,231
	db	230,229,229,228,227,226,225,225
	db	224,223,222,221,221,220,219,218
	db	217,216,215,214,214,213,212,211
	db	210,209,208,207,206,205,204,204
	db	203,202,201,200,199,198,197,196
	db	195,194,193,192,191,190,189,188
	db	187,186,185,184,183,182,181,180
	db	179,178,177,176,175,174,172,171
	db	170,169,168,167,166,165,164,163
	db	162,161,160,158,157,156,155,154
	db	153,152,151,150,148,147,146,145
	db	144,143,142,141,139,138,137,136
	db	135,134,133,132,130,129,128,127
	db	126,125,123,122,121,120,119,118
	db	117,115,114,113,112,111,110,108
	db	107,106,105,104,103,101,100,099
	db	098,097,096,094,093,092,091,090
	db	089,087,086,085,084,083,082,080
	db	079,078,077,076,075,073,072,071
	db	070,069,068,067,065,064,063,062
	db	061,060,058,057,056,055,054,053
	db	052,051,049,048,047,046,045,044
	db	043,042,040,039,038,037,036,035
	db	034,033,032,030,029,028,027,026
	db	025,024,023,022,021,020,019,018
	db	016,015,014,013,012,011,010,009
	db	008,007,006,005,004,003,002,001

	db	000,000,001,001,001,002,002,002
	db	003,003,003,003,004,004,004,005
	db	005,005,005,006,006,006,006,007
	db	007,007,007,008,008,008,008,009
	db	009,009,009,009,010,010,010,010
	db	010,011,011,011,011,011,011,012
	db	012,012,012,012,012,013,013,013
	db	013,013,013,013,014,014,014,014
	db	014,014,014,014,014,015,015,015
	db	015,015,015,015,015,015,015,015
	db	015,016,016,016,016,016,016,016
	db	016,016,016,016,016,016,016,016
	db	016,016,016,016,016,016,016,016
	db	016,016,016,016,016,016,016,016
	db	016,016,016,016,016,016,016,016
	db	016,016,016,016,016,016,016,016
	db	016,016,016,016,016,016,016,016
	db	016,016,015,015,015,015,015,015
	db	015,015,015,015,015,015,015,015
	db	014,014,014,014,014,014,014,014
	db	014,014,014,013,013,013,013,013
	db	013,013,013,013,012,012,012,012
	db	012,012,012,012,012,011,011,011
	db	011,011,011,011,011,010,010,010
	db	010,010,010,010,009,009,009,009
	db	009,009,009,008,008,008,008,008
	db	008,008,007,007,007,007,007,007
	db	007,006,006,006,006,006,006,005
	db	005,005,005,005,005,004,004,004
	db	004,004,004,003,003,003,003,003
	db	003,002,002,002,002,002,002,001
	db	001,001,001,001,001,000,000,000



sin:	push	ebx
	push	ecx
	push	edx
	mov	edx,eax
	and	edx,30000H
	cmp	edx,10000H
	je	sin01
	cmp	edx,30000H
	je	sin01
	jmp	sin02
sin01:	mov	bx,ax
	mov	ax,0ffffH
	sub	ax,bx
sin02:	and	eax,0ffffH
	call	sin03
sin03:	pop	ecx
	add	ecx,sintb-sin03
	push	eax
	shr	eax,8
	mov	bx,cs:[ecx][eax*2]
	mov	cx,cs:[ecx+2][eax*2]
	and	ebx,0ffffH
	and	ecx,0ffffH
	sub	ecx,ebx
	pop	eax
	and	eax,0ffH
	imul	eax,ecx
	shr	eax,8
	add	eax,ebx
	cmp	edx,20000H
	jb	sin04
	mov	ebx,eax
	xor	eax,eax
	sub	eax,ebx
sin04:	pop	edx
	pop	ecx
	pop	ebx
	ret

sintb	dw	00000H,00192H,00324H,004B6H,00648H,007DAH,0096CH,00AFDH
	dw	00C8FH,00E21H,00FB2H,01143H,012D5H,01465H,015F6H,01787H
	dw	01917H,01AA7H,01C37H,01DC6H,01F56H,020E5H,02273H,02402H
	dw	0250FH,0271DH,028AAH,02A37H,02BC3H,02D4FH,02EDBH,03066H
	dw	031F1H,0337BH,03505H,0368EH,03816H,0399EH,03B26H,03CADH
	dw	03E33H,03FB9H,0413EH,042C3H,04447H,045CAH,0474CH,048CEH
	dw	04A4FH,04BD0H,04D4FH,04ECEH,0504DH,051CAH,05347H,054C3H
	dw	0563EH,057B8H,05931H,05AAAH,05C21H,05D98H,05F0EH,06083H
	dw	061F7H,0636AH,064DCH,0664DH,067BDH,0692CH,06A9AH,06C07H
	dw	06D73H,06EDEH,07048H,071B1H,07319H,0747FH,075E5H,07749H
	dw	078ACH,07A0FH,07B64H,07CCFH,07E2EH,07F8DH,080E7H,08242H
	dw	0839BH,084F3H,0864AH,087A0H,088F5H,08A48H,08B99H,08CEAH
	dw	08E39H,08F86H,090D3H,0921EH,09367H,094AFH,095F6H,0973BH
	dw	0987FH,099C1H,09B02H,09C41H,09D7FH,09EBBH,09FF6H,0A12FH
	dw	0A266H,0A39CH,0A4D1H,0A604H,0A735H,0A865H,0A993H,0AABFH
	dw	0ABEAH,0AD13H,0AE3BH,0AF60H,0B085H,0B1A7H,0B2C8H,0B3E6H
	dw	0B504H,0B61FH,0B739H,0B851H,0B967H,0BA7BH,0BB8EH,0BC9FH
	dw	0BDAEH,0BEBBH,0BFC6H,0C0D0H,0C1D7H,0C2DDH,0C3E1H,0C4E3H
	dw	0C5E3H,0C6E1H,0C7DDH,0C8D7H,0C9D0H,0CAC6H,0CBBBH,0CCADH
	dw	0CD9EH,0CE8CH,0CF79H,0D063H,0D14CH,0D232H,0D317H,0D3F9H
	dw	0D4DAH,0D5B8H,0D695H,0D76FH,0D847H,0D91DH,0D9F1H,0DAC3H
	dw	0DB93H,0DC60H,0DD2CH,0DDF5H,0DEBDH,0DF82H,0E045H,0E106H
	dw	0E1C4H,0E281H,0E33BH,0E3F3H,0E4A9H,0E55DH,0E60EH,0E6BDH
	dw	0E76AH,0E815H,0E8BEH,0E964H,0EA08H,0EAAAH,0EB4AH,0EBE7H
	dw	0EC82H,0ED1BH,0EDB1H,0EE45H,0EED7H,0EF67H,0EFF4H,0F07FH
	dw	0F108H,0F18EH,0F212H,0F293H,0F313H,0F390H,0F40AH,0F483H
	dw	0F4F9H,0F56CH,0F5DDH,0F64CH,0F6B9H,0F723H,0F78AH,0F7F0H
	dw	0F852H,0F8B3H,0F911H,0F96DH,0F9C6H,0FA1DH,0FA72H,0FAC4H
	dw	0FB13H,0FB60H,0FBABH,0FBF4H,0FC3AH,0FC7DH,0FCBEH,0FCFDH
	dw	0FD39H,0FD73H,0FDAAH,0FDDFH,0FE12H,0FE42H,0FE6FH,0FE9AH
	dw	0FEC3H,0FEE9H,0FF0DH,0FF2EH,0FF2EH,0FF4DH,0FF83H,0FF9BH
	dw	0FFB0H,0FFC2H,0FFD2H,0FFE0H,0FFEBH,0FFF3H,0FFFAH,0FFFDH
	dw	0FFFFH

sndPhaseDelay	endp

cseg	ends
	end
