%include TRACK_INCLUDE

%define SND_PCM_FORMAT_S16_LE 0x2
%define SND_PCM_FORMAT_FLOAT 0xE
%define SND_PCM_ACCESS_RW_INTERLEAVED 0x3
%define SND_PCM_STREAM_PLAYBACK 0x0

section .bss
sound_buffer:
	resb SU_LENGTH_IN_SAMPLES * SU_SAMPLE_SIZE * SU_CHANNEL_COUNT

render_thread:
	resd 1

pcm_handle:
	resd 1

section .data
default_device:
	db "default", 0

section .text
symbols:
	extern pthread_create
	extern sleep
	extern snd_pcm_open
	extern snd_pcm_set_params
	extern snd_pcm_writei

	global main
main:
	; elf32 uses the cdecl calling convention. This is more readable imo ;)

	; Prologue
	push	ebp
	mov	 ebp, esp
	sub	 esp, 0x10

	; Unix does not have gm.dls, no need to ifdef and setup here.

	; We render in the background while playing already.
	push sound_buffer
	lea eax, su_render_song
	push eax
	push 0
	push render_thread
	call pthread_create

	; We can't start playing too early or the missing samples will be audible.
	push 0x2
	call sleep

	; Play the track.
	push 0x0
	push SND_PCM_STREAM_PLAYBACK
	push default_device
	push pcm_handle
	call snd_pcm_open

	push SU_LENGTH_IN_SAMPLES
	push 0
	push SU_SAMPLE_RATE
	push SU_CHANNEL_COUNT
	push SND_PCM_ACCESS_RW_INTERLEAVED
%ifdef SU_SAMPLE_FLOAT
	push SND_PCM_FORMAT_FLOAT
%else ; SU_SAMPLE_FLOAT
	push SND_PCM_FORMAT_S16_LE
%endif ; SU_SAMPLE_FLOAT
	push dword [pcm_handle]
	call snd_pcm_set_params

	push SU_LENGTH_IN_SAMPLES
	push sound_buffer
	push dword [pcm_handle]
	call snd_pcm_writei

exit:
	; At least we can skip the epilogue :)
	leave
	ret