; This Program make a wav audio file with Tetris Melody
; Author Dj Mauretto
; E-mail diciccomauro@katamail.com

include '%fasminc%\win32ax.inc'

.data
;================
; Data File
;================
align 16
Address		dd ?
WAVFILE		db "Tetris.Wav",0

align 4
handle		dd  ?
Temp		dd  ?

;================
; Header Wave
;================
align 16
Wave_Header	db "RIFF"					; Header
Length_File	dd 0x00109a24					; Length File - 8
Wave_ID		db "WAVE"					; Wave ID
Chunk_fmt	db "fmt "					; Chunk fmt
Length_fmt	dd 0x00000010					; 16 Byte
Format_TAG	dw 0x0001					; Windows PCM
Channels	dw 0x0001					; MONO
Sample_Rate	dd 44100					; 44100
Avg_Byte	dd 2*44100					; 44100 * 2 
Block_Align	dw 0x0002					; Align Word
Bits_x_Sample	dw 0x0010					; 16 bit
Chunk_data	db "data"					; Chunk data
Length_data	dd 0x00109a00					; Length data

;================
; DATI Waveform
;================
align 16
PI_x_Rcp	dq 1.4247585730565955729989312395825e-4		; PI*(44100/2)
Zero_Cinque	dd 0.5
Zero_Uno	dd 0.1
Zero_ZZ_Uno	dd 0.0001
Due_Punto_Tre	dd 2.3
DPHIF		dd 0.0
Amp_Env		dd 1.0
Zero_Nove	dd 0.9998
Filt_Env	dd 0.0
Phase		dd 0.0
Y_0 		dd 0.0
Y_1		dd 0.0
Amp_Sample	dd 12000.0
FLAG		db 0

;==================
; Bass frequency
;==================
align 16
Freq_Bass	dd  82.4, 164.5,  82.4, 164.5, 82.4, 164.5,  82.4, 164.5
		dd 110.0, 220.0, 110.0, 220.0,110.0, 220.0, 110.0, 220.0
		dd 103.82,207.6, 103.82,207.6, 82.4, 164.5,  82.4, 164.5
		dd 110.0, 220.0, 110.0, 220.0,110.0, 110.0, 123.47,130.8
		dd 146.8, 110.0
		dd  65.4, 130.8,  65.4, 130.8, 49.0,  98.0,  49.0 , 98.0
		dd 123.47,246.9, 123.47,246.9, 82.4, 164.5, 103.82, 207.6
		dd 110.0, 220.0, 110.0, 220.0,110.0, 220.0, 110.0, 220.0

;===============
; Bass rhythm
;===============
align 16
Beat_Bass	dw 8500,8500,8500,8500,8500,8500,8500,8500
		dw 8500,8500,8500,8500,8500,8500,8500,8500
		dw 8500,8500,8500,8500,8500,8500,8500,8500
		dw 8500,8500,8500,8500,8500,8500,8500,8500
		dw 51000,17000
		dw 8500,8500,8500,8500,8500,8500,8500,8500
		dw 8500,8500,8500,8500,8500,8500,8500,8500
		dw 8500,8500,8500,8500,8500,8500,8500,8500

;====================
; Melody frequency
;====================
align 16
Freq_Melody	dd 659.2, 493.8, 523.2, 587.3, 523.2, 493.8
		dd 440.0, 440.0, 523.2, 659.2, 587.3, 523.2
		dd 493.8, 523.2, 587.3, 659.2
		dd 523.2, 440.0, 440.0
		dd 587.3, 698.5, 880.0, 784.0, 698.5
		dd 659.2, 523.2, 659.2, 587.3, 523.2
		dd 493.8, 493.8, 523.2, 587.3, 659.2
		dd 523.2, 440.0, 440.0

align 16
Beat_Melody	dw 17000, 8500, 8500,17000, 8500,8500
		dw 17000, 8500, 8500,17000, 8500,8500
		dw 25500, 8500,17000,17000
		dw 17000,17000,42500
		dw 17000, 8500,17000, 8500, 8500
		dw 25500, 8500,17000, 8500, 8500
		dw 17000, 8500, 8500,17000,17000
		dw 17000,17000,17000

.code
start:
;==============================================================================
;		                 *****	main *****
;==============================================================================
;		push	0x109a10				; number of bytes
;		push	0					; flag
;		call	[GlobalAlloc]				; memory alloc
		invoke	GlobalAlloc,GMEM_FIXED,0x109a10

		or	eax,eax
		jz	@error
		mov	[Address],eax

;		push	0
;		push	0x20
;		push	2
;		push	0
;		push	0
;		push	0x0c0000000				; r/w
;		push	WAVFILE
;		call	[CreateFile]
		invoke	CreateFile,WAVFILE,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0
		cmp	eax,-1
		jz	@error
		mov	[handle],eax

;		push	0
;		push	Temp
;		push	44
;		push	Wave_Header
;		push	eax
;		call	[WriteFile]
		invoke	WriteFile,eax,Wave_Header,44,Temp,0

		finit						; init coprocessor
		mov	ebx,[Address]
		mov	esi,Freq_Bass				; offset frequency
		mov	edi,Beat_Bass				; offset rhythm
		mov	ecx,58					; number of note
		call	@tetris_wav				; compute waveform


		finit						; init coprocessor
		mov	[FLAG],1
		mov	ebx,[Address]
		mov	esi,Freq_Melody				; offset frequency
		mov	edi,Beat_Melody				; offset rhythm
		mov	ecx,37					; number of note
		call	@tetris_wav				; compute waveform

;		push	0
;		push	Temp
;		push	0x109a00
;		push	[Address]
;		push	[handle]
;		call	[WriteFile]
		invoke	WriteFile,[handle],[Address],0x109a00,Temp,0

;		push	[handle]
;		call	[CloseHandle]
		invoke	CloseHandle,[handle]
@error:
;		push	0
;		call	[ExitProcess]
		invoke	ExitProcess,0

;=================================================================
;           		***** procedures ******
;=================================================================
align 16
@tetris_wav:	fld	[Zero_Cinque]
		fld	[Zero_Uno]

@change_note:	fld	dword [esi]
		fld	st
		fmul	[PI_x_Rcp]
		fxch
		fmul    [Zero_ZZ_Uno]
		fld1
		fxch
		fsubp	st1,st0
		fmul	[Due_Punto_Tre]
		fxch	st2
		fxch

@@:		fld	st
		fsub	[DPHIF]
		fmul	st0,st2
		fadd	[DPHIF]
		fstp	[DPHIF]
		fld	[Amp_Env]
		fmul	[Zero_Nove]
		fld	st
		fsub	[Filt_Env]
		fmul	st0,st3
		fadd	[Filt_Env]
		fstp	[Filt_Env]
		fstp	[Amp_Env]
		fldpi
		fld	[Phase]
		fadd	[DPHIF]

		fcom	st1
		fnstsw	ax
		test	ah,1
		jnz	@no_zero

		fxch
		fld	st0
		fadd	st0,st1

		fsub	st2,st0
		fstp	st
		fxch

@no_zero:	fst	[Phase]
		fxch	st4
		fld	st0
		fmul	[Y_0]
		fadd	st0,st5
		fcos
		fld	st0
		fadd	[Y_0]
		fmul	st0,st7
		fstp	[Y_0]
		fxch
		fld	st0
		fmul	[Y_1]
		fxch	st1
		fxch	st3
		faddp	st1,st0
		fadd	st0,st5
		fcos
		fld	st0
		fadd	[Y_1]
		fmul    st0,st7
		fstp	[Y_1]
		fsubp	st1,st0
		fmul	[Filt_Env]
		fmul 	[Amp_Sample]

		cmp	[FLAG],1
		jnc	@add_melody

		fistp	word [ebx]
		fxch	st3
		fstp	st0

		add	ebx,2
		sub	word [edi],1
		jnz	@b

		fstp	st0
		fxch
		fstp	st0

		mov	[Amp_Env],0x3f800000
		add	edi,2
		add	esi,4
		sub	ecx,1
		jnz	@change_note

		ret

@add_melody:	fild    word [ebx]
		faddp	st1,st0

		fistp	word [ebx]
		fxch	st3
		fstp	st0

		add	ebx,2
		sub	word [edi],1
		jnz	@b

		fstp	st0
		fxch
		fstp	st0

		mov	[Amp_Env],0x3f800000
		add	edi,2
		add	esi,4
		sub	ecx,1
		jnz	@change_note

		ret

.end start