mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
137 lines
5.2 KiB
NASM
137 lines
5.2 KiB
NASM
; source file for compiling sointu as a library
|
|
%define SU_DISABLE_PLAYER
|
|
|
|
%include "sointu/header.inc"
|
|
|
|
; TODO: make sure compile everything in
|
|
|
|
USE_ENVELOPE
|
|
USE_OSCILLAT
|
|
USE_MULP
|
|
USE_PAN
|
|
USE_OUT
|
|
|
|
%define INCLUDE_TRISAW
|
|
%define INCLUDE_SINE
|
|
%define INCLUDE_PULSE
|
|
%define INCLUDE_GATE
|
|
%define INCLUDE_STEREO_OSCILLAT
|
|
%define INCLUDE_STEREO_ENVELOPE
|
|
%define INCLUDE_STEREO_OUT
|
|
%define INCLUDE_POLYPHONY
|
|
%define INCLUDE_MULTIVOICE_TRACKS
|
|
|
|
%include "sointu/footer.inc"
|
|
|
|
section .text
|
|
|
|
struc su_synth
|
|
.synthwrk resb su_synthworkspace.size
|
|
.delaywrks resb su_delayline_wrk.size * 64
|
|
.randseed resd 1
|
|
.globaltime resd 1
|
|
.commands resb 32 * 64
|
|
.values resb 32 * 64 * 8
|
|
.polyphony resd 1
|
|
.numvoices resd 1
|
|
endstruc
|
|
|
|
SECT_TEXT(sursampl)
|
|
|
|
EXPORT MANGLE_FUNC(su_render,16)
|
|
%if BITS == 32 ; stdcall
|
|
pushad ; push registers
|
|
mov ecx, [esp + 4 + 32] ; ecx = &synthState
|
|
mov edx, [esp + 8 + 32] ; edx = &buffer
|
|
mov esi, [esp + 12 + 32] ; esi = &samples
|
|
mov ebx, [esp + 16 + 32] ; ebx = &time
|
|
%else
|
|
%ifidn __OUTPUT_FORMAT__,win64 ; win64 ABI: rcx = &synth, rdx = &buffer, r8 = &bufsize, r9 = &time
|
|
push_registers rdi, rsi, rbx, rbp ; win64 ABI: these registers are non-volatile
|
|
mov rsi, r8 ; rsi = &samples
|
|
mov rbx, r9 ; rbx = &time
|
|
%else ; System V ABI: rdi = &synth, rsi = &buffer, rdx = &samples, rcx = &time
|
|
push_registers rbx, rbp ; System V ABI: these registers are non-volatile
|
|
mov rbx, rcx ; rbx points to time
|
|
xchg rsi, rdx ; rdx points to buffer, rsi points to samples
|
|
mov rcx, rdi ; rcx = &Synthstate
|
|
%endif
|
|
%endif
|
|
push _SI ; push the pointer to samples
|
|
push _BX ; push the pointer to time
|
|
xor eax, eax ; samplenumber starts at 0
|
|
push _AX ; push samplenumber to stack
|
|
mov esi, [_SI] ; zero extend dereferenced pointer
|
|
push _SI ; push bufsize
|
|
push _DX ; push bufptr
|
|
push _CX ; this takes place of the voicetrack
|
|
mov eax, [_CX + su_synth.randseed]
|
|
push _AX ; randseed
|
|
mov eax, [_CX + su_synth.globaltime]
|
|
push _AX ; global tick time
|
|
mov ebx, dword [_BX] ; zero extend dereferenced pointer
|
|
push _BX ; the nominal rowlength should be time_in
|
|
xor eax, eax ; rowtick starts at 0
|
|
su_render_samples_loop:
|
|
cmp eax, [_SP] ; if rowtick >= maxtime
|
|
jge su_render_samples_time_finish ; goto finish
|
|
mov ecx, [_SP + PTRSIZE*5] ; ecx = buffer length in samples
|
|
cmp [_SP + PTRSIZE*6], ecx ; if samples >= maxsamples
|
|
jge su_render_samples_time_finish ; goto finish
|
|
inc eax ; time++
|
|
inc dword [_SP + PTRSIZE*6] ; samples++
|
|
mov _CX, [_SP + PTRSIZE*3]
|
|
push _AX ; push rowtick
|
|
mov eax, [_CX + su_synth.polyphony]
|
|
push _AX ;polyphony
|
|
mov eax, [_CX + su_synth.numvoices]
|
|
push _AX ;numvoices
|
|
lea _DX, [_CX+ su_synth.synthwrk]
|
|
lea COM, [_CX+ su_synth.commands]
|
|
lea VAL, [_CX+ su_synth.values]
|
|
lea WRK, [_DX + su_synthworkspace.voices]
|
|
lea _CX, [_CX+ su_synth.delaywrks - su_delayline_wrk.filtstate]
|
|
call MANGLE_FUNC(su_run_vm,0)
|
|
pop _AX
|
|
pop _AX
|
|
mov _DI, [_SP + PTRSIZE*5] ; edi containts buffer ptr
|
|
mov _CX, [_SP + PTRSIZE*4]
|
|
lea _SI, [_CX + su_synth.synthwrk + su_synthworkspace.left]
|
|
movsd ; copy left channel to output buffer
|
|
movsd ; copy right channel to output buffer
|
|
mov [_SP + PTRSIZE*5], _DI ; save back the updated ptr
|
|
lea _DI, [_SI-8]
|
|
xor eax, eax
|
|
stosd ; clear left channel so the VM is ready to write them again
|
|
stosd ; clear right channel so the VM is ready to write them again
|
|
pop _AX
|
|
inc dword [_SP + PTRSIZE] ; increment global time, used by delays
|
|
jmp su_render_samples_loop
|
|
su_render_samples_time_finish:
|
|
pop _CX
|
|
pop _BX
|
|
pop _DX
|
|
pop _CX
|
|
mov [_CX + su_synth.randseed], edx
|
|
mov [_CX + su_synth.globaltime], ebx
|
|
pop _BX
|
|
pop _BX
|
|
pop _DX
|
|
pop _BX ; pop the pointer to time
|
|
pop _SI ; pop the pointer to samples
|
|
mov dword [_SI], edx ; *samples = samples rendered
|
|
mov dword [_BX], eax ; *time = time ticks rendered
|
|
xor eax, eax ; TODO: set eax to possible error code, now just 0
|
|
%if BITS == 32 ; stdcall
|
|
mov [_SP + 28],eax ; we want to return eax, but popad pops everything, so put eax to stack for popad to pop
|
|
popad
|
|
ret 16
|
|
%else
|
|
%ifidn __OUTPUT_FORMAT__,win64
|
|
pop_registers rdi, rsi, rbx, rbp ; win64 ABI: these registers are non-volatile
|
|
%else
|
|
pop_registers rbx, rbp ; System V ABI: these registers are non-volatile
|
|
%endif
|
|
ret
|
|
%endif
|