mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
Improve comments and formatting.
This commit is contained in:
parent
212951c75d
commit
3c3fe6caf8
686
src/4klang.asm
686
src/4klang.asm
@ -110,9 +110,11 @@ EXPORT MANGLE_DATA(LFO_NORMALIZE)
|
|||||||
go4k_groove_pattern dw 0011100111001110b
|
go4k_groove_pattern dw 0011100111001110b
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
; //========================================================================================
|
;-------------------------------------------------------------------------------
|
||||||
; // .crtemui section (emulates crt functions)
|
; FloatRandomNumber function
|
||||||
; //========================================================================================
|
;-------------------------------------------------------------------------------
|
||||||
|
; Output: st0 : result
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(crtemui)
|
SECT_TEXT(crtemui)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(FloatRandomNumber,0)
|
EXPORT MANGLE_FUNC(FloatRandomNumber,0)
|
||||||
@ -124,58 +126,62 @@ EXPORT MANGLE_FUNC(FloatRandomNumber,0)
|
|||||||
pop eax
|
pop eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //========================================================================================
|
;-------------------------------------------------------------------------------
|
||||||
; // .g4kcod* sections (code for go4k)
|
; Waveshaper function
|
||||||
; //========================================================================================
|
;-------------------------------------------------------------------------------
|
||||||
|
; Input: st0 : a - the shaping coefficient
|
||||||
; //----------------------------------------------------------------------------------------
|
; st1 : x - input value
|
||||||
; // Waveshaper function
|
; Output: st0 : (1+k)*x/(1+k*abs(x)), where k=2*m/(1-m) and m=2*a-1
|
||||||
; //----------------------------------------------------------------------------------------
|
; and x is clamped first if GO4K_USE_WAVESHAPER_CLIP
|
||||||
; // Input : st0 : shaping coeff
|
;-------------------------------------------------------------------------------
|
||||||
; // st1 : input
|
|
||||||
; // Output: st0 : result
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
%ifdef INCLUDE_WAVESHAPER
|
%ifdef INCLUDE_WAVESHAPER
|
||||||
|
|
||||||
SECT_TEXT(g4kcod2)
|
SECT_TEXT(g4kcod2)
|
||||||
|
|
||||||
go4kWaveshaper:
|
go4kWaveshaper: ; a x
|
||||||
%ifdef GO4K_USE_WAVESHAPER_CLIP
|
%ifdef GO4K_USE_WAVESHAPER_CLIP
|
||||||
fxch
|
fxch ; x a
|
||||||
fld1 ; // 1 val
|
fld1 ; 1 x a
|
||||||
fucomi st1 ; // 1 val
|
fucomi st1 ; if (1 <= x)
|
||||||
jbe short go4kWaveshaper_clip
|
jbe short go4kWaveshaper_clip ; goto go4kWaveshaper_clip
|
||||||
fchs ; // -1 val
|
fchs ; -1 x a
|
||||||
fucomi st1 ; // -1 val
|
fucomi st1 ; if (-1 < x)
|
||||||
fcmovb st0, st1 ; // val -1 (if val > -1)
|
fcmovb st0, st1 ; x x a
|
||||||
go4kWaveshaper_clip:
|
go4kWaveshaper_clip:
|
||||||
fstp st1 ; // newval
|
fstp st1 ; x' a, where x' = clamp(x)
|
||||||
fxch
|
fxch ; a x' (from now on just called x)
|
||||||
%endif
|
%endif
|
||||||
fsub dword [c_0_5]
|
fsub dword [c_0_5] ; a-.5 x
|
||||||
fadd st0
|
fadd st0 ; 2*a-1 x
|
||||||
fst dword [esp-4] ; // amnt in
|
fst dword [esp-4] ; m=2*a-1 x
|
||||||
fadd st0 ; // 2*amnt in
|
fadd st0 ; 2*m x
|
||||||
fld1 ; // 1 2*amnt in
|
fld1 ; 1 2*m x
|
||||||
fsub dword [esp-4] ; // 1-amnt 2*amnt in
|
fsub dword [esp-4] ; 1-m 2*m x
|
||||||
fdivp st1, st0 ; // k in
|
fdivp st1, st0 ; k=2*m/(1-m) x
|
||||||
fld st1 ; // sin k in
|
fld st1 ; x k x
|
||||||
fabs ; // a(in) k in
|
fabs ; abs(x) k x
|
||||||
fmul st1 ; // k*a(in) k in
|
fmul st1 ; k*abs(x) k x
|
||||||
fld1
|
fld1 ; 1 k*abs(x) k x
|
||||||
faddp st1, st0 ; // 1+k*a(in) k in
|
faddp st1, st0 ; 1+k*abs(x) k x
|
||||||
fxch st1 ; // k 1+k*a(in) in
|
fxch st1 ; k 1+k*abs(x) x
|
||||||
fld1
|
fld1 ; 1 k 1+k*abs(x) x
|
||||||
faddp st1, st0 ; // 1+k 1+k*a(in) in
|
faddp st1, st0 ; 1+k 1+k*abs(x) x
|
||||||
fmulp st2 ; // 1+k*a(in) (1+k)*in
|
fmulp st2 ; 1+k*abs(x) (1+k)*x
|
||||||
fdivp st1, st0 ; // out
|
fdivp st1, st0 ; (1+k)*x/(1+k*abs(x))
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%endif ; INCLUDE_WAVESHAPER
|
%endif ; INCLUDE_WAVESHAPER
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // unit values preparation/transform
|
; TransformValues function
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
; Input: [esp] : number of bytes to transform
|
||||||
|
; esi : pointer to byte stream
|
||||||
|
; Output: eax : last transformed byte (zero extended)
|
||||||
|
; edx : pointer to go4k_transformed_values, containing
|
||||||
|
; each byte transformed as x/128.0f+modulations
|
||||||
|
; esi : updated to point after the transformed bytes
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcod3)
|
SECT_TEXT(g4kcod3)
|
||||||
|
|
||||||
go4kTransformValues:
|
go4kTransformValues:
|
||||||
@ -197,22 +203,27 @@ go4kTransformValues_loop:
|
|||||||
pop ecx
|
pop ecx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // Envelope param mapping
|
; ENVMap function
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
; Input: eax : envelope parameter (0 = attac, 1 = decay...)
|
||||||
|
; edx : pointer to go4k_transformed_values
|
||||||
|
; Output: st0 : 2^(-24*x), where x is the parameter in the range 0-1
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcod4)
|
SECT_TEXT(g4kcod4)
|
||||||
|
|
||||||
go4kENVMap:
|
go4kENVMap:
|
||||||
fld dword [edx+eax*4]
|
fld dword [edx+eax*4] ; x, where x is the parameter in the range 0-1
|
||||||
fimul dword [c_24]
|
fimul dword [c_24] ; 24*x
|
||||||
fchs
|
fchs ; -24*x
|
||||||
|
; flow into Power function, which outputs 2^(-24*x)
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // Power function (2^x)
|
; Power function (2^x)
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // Input : st0 : x
|
; Input: st0 : x
|
||||||
; // Output: st0 : 2^x
|
; Output: st0 : 2^x
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
EXPORT MANGLE_FUNC(Power,0) ; x
|
EXPORT MANGLE_FUNC(Power,0) ; x
|
||||||
fld1 ; 1 x
|
fld1 ; 1 x
|
||||||
fld st1 ; x 1 x
|
fld st1 ; x 1 x
|
||||||
@ -225,159 +236,83 @@ EXPORT MANGLE_FUNC(Power,0) ; x
|
|||||||
fstp st1 ; 2^x
|
fstp st1 ; 2^x
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // ENV Tick
|
; ENV Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; Output: st0 : envelope value, [gain]*level. The slopes of
|
||||||
; // DIRTY : eax
|
; level is 2^(-24*p) per sample, where p is either
|
||||||
; //----------------------------------------------------------------------------------------
|
; attack, decay or release in [0,1] range
|
||||||
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcoda)
|
SECT_TEXT(g4kcoda)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kENV_func,0)
|
EXPORT MANGLE_FUNC(go4kENV_func,0)
|
||||||
TRANSFORM_VALUES go4kENV_val
|
TRANSFORM_VALUES go4kENV_val
|
||||||
%ifdef GO4K_USE_ENV_CHECK
|
%ifdef GO4K_USE_ENV_CHECK
|
||||||
; check if current note still active
|
mov eax, dword [ecx-4] ; eax = go4k_instrument.note
|
||||||
mov eax, dword [ecx-4]
|
test eax, eax ; if (eax != 0) // if current note still active
|
||||||
test eax, eax
|
jne go4kENV_func_do ; goto go4kENV_func_do
|
||||||
jne go4kENV_func_do
|
|
||||||
fldz
|
fldz
|
||||||
ret
|
ret ; return 0
|
||||||
%endif
|
%endif
|
||||||
go4kENV_func_do:
|
go4kENV_func_do:
|
||||||
mov eax, dword [ecx-8] ; // is the instrument in release mode (note off)?
|
mov eax, dword [ecx-8] ; eax = go4k_instrument.release
|
||||||
test eax, eax
|
test eax, eax ; if (eax == 0)
|
||||||
je go4kENV_func_process
|
je go4kENV_func_process ; goto process
|
||||||
mov dword [WRK+go4kENV_wrk.state], ENV_STATE_RELEASE
|
mov dword [WRK+go4kENV_wrk.state], ENV_STATE_RELEASE ; [state]=RELEASE
|
||||||
go4kENV_func_process:
|
go4kENV_func_process:
|
||||||
mov eax, dword [WRK+go4kENV_wrk.state]
|
mov eax, dword [WRK+go4kENV_wrk.state] ; al=[state]
|
||||||
fld dword [WRK+go4kENV_wrk.level] ; // val -
|
fld dword [WRK+go4kENV_wrk.level] ; x=[level]
|
||||||
; // check for sustain state
|
cmp al, ENV_STATE_SUSTAIN ; if (al==SUSTAIN)
|
||||||
cmp al, ENV_STATE_SUSTAIN
|
je short go4kENV_func_leave2 ; goto leave2
|
||||||
je short go4kENV_func_leave2
|
|
||||||
go4kENV_func_attac:
|
go4kENV_func_attac:
|
||||||
cmp al, ENV_STATE_ATTAC
|
cmp al, ENV_STATE_ATTAC ; if (al!=ATTAC)
|
||||||
jne short go4kENV_func_decay
|
jne short go4kENV_func_decay ; goto decay
|
||||||
call go4kENVMap ; // newval
|
call go4kENVMap ; a x, where a=attack
|
||||||
faddp st1, st0
|
faddp st1, st0 ; a+x
|
||||||
; // check for end of attac
|
fld1 ; 1 a+x
|
||||||
fld1 ; // 1 newval
|
fucomi st1 ; if (a+x<=1) // is attack complete?
|
||||||
fucomi st1 ; // 1 newval
|
fcmovnb st0, st1 ; a+x a+x
|
||||||
fcmovnb st0, st1 ; // newval 1 (if newval < 1)
|
jbe short go4kENV_func_statechange ; else goto statechange
|
||||||
jbe short go4kENV_func_statechange
|
|
||||||
go4kENV_func_decay:
|
go4kENV_func_decay:
|
||||||
cmp al, ENV_STATE_DECAY
|
cmp al, ENV_STATE_DECAY ; if (al!=DECAY)
|
||||||
jne short go4kENV_func_release
|
jne short go4kENV_func_release ; goto release
|
||||||
call go4kENVMap ; // newval
|
call go4kENVMap ; d x, where d=decay
|
||||||
fsubp st1, st0
|
fsubp st1, st0 ; x-d
|
||||||
; // check for end of decay
|
fld dword [edx+go4kENV_val.sustain] ; s x-d, where s=sustain
|
||||||
fld dword [edx+go4kENV_val.sustain] ; // sustain newval
|
fucomi st1 ; if (x-d>s) // is decay complete?
|
||||||
fucomi st1 ; // sustain newval
|
fcmovb st0, st1 ; x-d x-d
|
||||||
fcmovb st0, st1 ; // newval sustain (if newval > sustain)
|
jnc short go4kENV_func_statechange ; else goto statechange
|
||||||
jnc short go4kENV_func_statechange
|
|
||||||
go4kENV_func_release:
|
go4kENV_func_release:
|
||||||
; // release state?
|
cmp al, ENV_STATE_RELEASE ; if (al!=RELEASE)
|
||||||
cmp al, ENV_STATE_RELEASE
|
jne short go4kENV_func_leave ; goto leave
|
||||||
jne short go4kENV_func_leave
|
call go4kENVMap ; r x, where r=release
|
||||||
call go4kENVMap ; // newval
|
fsubp st1, st0 ; x-r
|
||||||
fsubp st1, st0
|
fldz ; 0 x-r
|
||||||
; // check for end of release
|
fucomi st1 ; if (x-r>0) // is release complete?
|
||||||
fldz ; // 0 newval
|
fcmovb st0, st1 ; x-r x-r, then goto leave
|
||||||
fucomi st1 ; // 0 newval
|
|
||||||
fcmovb st0, st1 ; // newval 0 (if newval > 0)
|
|
||||||
jc short go4kENV_func_leave
|
jc short go4kENV_func_leave
|
||||||
go4kENV_func_statechange: ; // newval
|
go4kENV_func_statechange:
|
||||||
inc dword [WRK+go4kENV_wrk.state]
|
inc dword [WRK+go4kENV_wrk.state] ; [state]++
|
||||||
go4kENV_func_leave: ; // newval bla
|
go4kENV_func_leave:
|
||||||
fstp st1
|
fstp st1 ; x', where x' is the new value
|
||||||
; // store new env value
|
fst dword [WRK+go4kENV_wrk.level] ; [level]=x'
|
||||||
fst dword [WRK+go4kENV_wrk.level]
|
|
||||||
go4kENV_func_leave2:
|
go4kENV_func_leave2:
|
||||||
; // mul by gain
|
fmul dword [edx+go4kENV_val.gain] ; [gain]*x'
|
||||||
fmul dword [edx+go4kENV_val.gain]
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // VCO Tick
|
; VCO Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; Output: st0 : oscillator value
|
||||||
; // DIRTY : eax
|
; Dirty: eax, edx
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodp)
|
|
||||||
|
|
||||||
go4kVCO_pulse:
|
|
||||||
fucomi st1 ; // c p
|
|
||||||
fld1
|
|
||||||
jnc short go4kVCO_func_pulse_up ; // +1 c p
|
|
||||||
fchs ; // -1 c p
|
|
||||||
go4kVCO_func_pulse_up:
|
|
||||||
fstp st1 ; // +-1 p
|
|
||||||
fstp st1 ; // +-1
|
|
||||||
ret
|
|
||||||
|
|
||||||
SECT_TEXT(g4kcodt)
|
|
||||||
|
|
||||||
go4kVCO_trisaw:
|
|
||||||
fucomi st1 ; // c p
|
|
||||||
jnc short go4kVCO_func_trisaw_up
|
|
||||||
fld1 ; // 1 c p
|
|
||||||
fsubr st2, st0 ; // 1 c 1-p
|
|
||||||
fsubrp st1, st0 ; // 1-c 1-p
|
|
||||||
go4kVCO_func_trisaw_up:
|
|
||||||
fdivp st1, st0 ; // tp'/tc
|
|
||||||
fadd st0 ; // 2*''
|
|
||||||
fld1 ; // 1 2*''
|
|
||||||
fsubp st1, st0 ; // 2*''-1
|
|
||||||
ret
|
|
||||||
|
|
||||||
SECT_TEXT(g4kcods)
|
|
||||||
|
|
||||||
go4kVCO_sine:
|
|
||||||
fucomi st1 ; // c p
|
|
||||||
jnc short go4kVCO_func_sine_do
|
|
||||||
fstp st1
|
|
||||||
fsub st0, st0 ; // 0
|
|
||||||
ret
|
|
||||||
go4kVCO_func_sine_do
|
|
||||||
fdivp st1, st0 ; // p/c
|
|
||||||
fldpi ; // pi p
|
|
||||||
fadd st0 ; // 2*pi p
|
|
||||||
fmulp st1, st0 ; // 2*pi*p
|
|
||||||
fsin ; // sin(2*pi*p)
|
|
||||||
ret
|
|
||||||
|
|
||||||
%ifdef GO4K_USE_VCO_GATE
|
|
||||||
|
|
||||||
SECT_TEXT(g4kcodq)
|
|
||||||
|
|
||||||
go4kVCO_gate:
|
|
||||||
fxch ; // p c
|
|
||||||
fstp st1 ; // p
|
|
||||||
fmul dword [c_16] ; // p'
|
|
||||||
push eax
|
|
||||||
push eax
|
|
||||||
fistp dword [esp] ; // -
|
|
||||||
fld1 ; // 1
|
|
||||||
pop eax
|
|
||||||
and al, 0xf
|
|
||||||
bt word [VAL-5],ax
|
|
||||||
jc go4kVCO_gate_bit
|
|
||||||
fsub st0, st0 ; // 0
|
|
||||||
go4kVCO_gate_bit:
|
|
||||||
fld dword [WRK+go4kVCO_wrk.gatestate] ; // f x
|
|
||||||
fsub st1 ; // f-x x
|
|
||||||
fmul dword [c_dc_const] ; // c(f-x) x
|
|
||||||
faddp st1, st0 ; // x'
|
|
||||||
fst dword [WRK+go4kVCO_wrk.gatestate]
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
%endif
|
|
||||||
|
|
||||||
SECT_TEXT(g4kcodb)
|
SECT_TEXT(g4kcodb)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kVCO_func,0)
|
EXPORT MANGLE_FUNC(go4kVCO_func,0)
|
||||||
@ -506,15 +441,86 @@ go4kVCO_func_stereodone:
|
|||||||
%endif
|
%endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
SECT_TEXT(g4kcodp)
|
||||||
; // VCF Tick
|
|
||||||
; //----------------------------------------------------------------------------------------
|
go4kVCO_pulse:
|
||||||
; // IN : WRK = unit workspace
|
fucomi st1 ; // c p
|
||||||
; // IN : VAL = unit values
|
fld1
|
||||||
; // IN : ecx = global workspace
|
jnc short go4kVCO_func_pulse_up ; // +1 c p
|
||||||
; // OUT :
|
fchs ; // -1 c p
|
||||||
; // DIRTY : eax
|
go4kVCO_func_pulse_up:
|
||||||
; //----------------------------------------------------------------------------------------
|
fstp st1 ; // +-1 p
|
||||||
|
fstp st1 ; // +-1
|
||||||
|
ret
|
||||||
|
|
||||||
|
SECT_TEXT(g4kcodt)
|
||||||
|
|
||||||
|
go4kVCO_trisaw:
|
||||||
|
fucomi st1 ; // c p
|
||||||
|
jnc short go4kVCO_func_trisaw_up
|
||||||
|
fld1 ; // 1 c p
|
||||||
|
fsubr st2, st0 ; // 1 c 1-p
|
||||||
|
fsubrp st1, st0 ; // 1-c 1-p
|
||||||
|
go4kVCO_func_trisaw_up:
|
||||||
|
fdivp st1, st0 ; // tp'/tc
|
||||||
|
fadd st0 ; // 2*''
|
||||||
|
fld1 ; // 1 2*''
|
||||||
|
fsubp st1, st0 ; // 2*''-1
|
||||||
|
ret
|
||||||
|
|
||||||
|
SECT_TEXT(g4kcods)
|
||||||
|
|
||||||
|
go4kVCO_sine:
|
||||||
|
fucomi st1 ; // c p
|
||||||
|
jnc short go4kVCO_func_sine_do
|
||||||
|
fstp st1
|
||||||
|
fsub st0, st0 ; // 0
|
||||||
|
ret
|
||||||
|
go4kVCO_func_sine_do
|
||||||
|
fdivp st1, st0 ; // p/c
|
||||||
|
fldpi ; // pi p
|
||||||
|
fadd st0 ; // 2*pi p
|
||||||
|
fmulp st1, st0 ; // 2*pi*p
|
||||||
|
fsin ; // sin(2*pi*p)
|
||||||
|
ret
|
||||||
|
|
||||||
|
%ifdef GO4K_USE_VCO_GATE
|
||||||
|
|
||||||
|
SECT_TEXT(g4kcodq)
|
||||||
|
|
||||||
|
go4kVCO_gate:
|
||||||
|
fxch ; // p c
|
||||||
|
fstp st1 ; // p
|
||||||
|
fmul dword [c_16] ; // p'
|
||||||
|
push eax
|
||||||
|
push eax
|
||||||
|
fistp dword [esp] ; // -
|
||||||
|
fld1 ; // 1
|
||||||
|
pop eax
|
||||||
|
and al, 0xf
|
||||||
|
bt word [VAL-5],ax
|
||||||
|
jc go4kVCO_gate_bit
|
||||||
|
fsub st0, st0 ; // 0
|
||||||
|
go4kVCO_gate_bit:
|
||||||
|
fld dword [WRK+go4kVCO_wrk.gatestate] ; // f x
|
||||||
|
fsub st1 ; // f-x x
|
||||||
|
fmul dword [c_dc_const] ; // c(f-x) x
|
||||||
|
faddp st1, st0 ; // x'
|
||||||
|
fst dword [WRK+go4kVCO_wrk.gatestate]
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
%endif
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; VCF Tick
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; Input: WRK : pointer to unit workspace
|
||||||
|
; VAL : pointer to unit values as bytes
|
||||||
|
; ecx : pointer to global workspace
|
||||||
|
; st0 : signal
|
||||||
|
; Output: st0 : filtered signal
|
||||||
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodc)
|
SECT_TEXT(g4kcodc)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kVCF_func,0)
|
EXPORT MANGLE_FUNC(go4kVCF_func,0)
|
||||||
@ -594,15 +600,16 @@ go4kVCF_func_processdone:
|
|||||||
go4kVCF_func_end: ; // value - - - -
|
go4kVCF_func_end: ; // value - - - -
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // DST Tick
|
; DST Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; st0 : signal
|
||||||
; // DIRTY : eax
|
; Output: st0 : distorted signal
|
||||||
; //----------------------------------------------------------------------------------------
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodd)
|
SECT_TEXT(g4kcodd)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kDST_func,0)
|
EXPORT MANGLE_FUNC(go4kDST_func,0)
|
||||||
@ -666,15 +673,16 @@ go4kDST_func_monohold:
|
|||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // DLL Tick
|
; DLL Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; st0 : signal
|
||||||
; // DIRTY : eax
|
; Output: st0 : delayed signal
|
||||||
; //----------------------------------------------------------------------------------------
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodf)
|
SECT_TEXT(g4kcodf)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kDLL_func,0)
|
EXPORT MANGLE_FUNC(go4kDLL_func,0)
|
||||||
@ -810,15 +818,16 @@ go4kDLL_func_buffer_nowrap2:
|
|||||||
ret
|
ret
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // GLITCH Tick
|
; GLITCH Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; ?
|
||||||
; // DIRTY : eax
|
; Output: ?
|
||||||
; //----------------------------------------------------------------------------------------
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodu)
|
SECT_TEXT(g4kcodu)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kGLITCH_func,0)
|
EXPORT MANGLE_FUNC(go4kGLITCH_func,0)
|
||||||
@ -924,15 +933,16 @@ go4kGLITCH_func_leave:
|
|||||||
ret
|
ret
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // FOP Tick (various fp stack based operations)
|
; FOP Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; stX : depends on the operation
|
||||||
; // DIRTY :
|
; Output: stX : depends on the operation
|
||||||
; //----------------------------------------------------------------------------------------
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodg)
|
SECT_TEXT(g4kcodg)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kFOP_func,0)
|
EXPORT MANGLE_FUNC(go4kFOP_func,0)
|
||||||
@ -989,15 +999,16 @@ go4kFOP_func_mulp2:
|
|||||||
fmulp st2, st0
|
fmulp st2, st0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // FST Tick (stores a value somewhere in the local workspace)
|
; FST Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; st0 : signal
|
||||||
; // DIRTY :
|
; Output: (st0) : signal, unless popped
|
||||||
; //----------------------------------------------------------------------------------------
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodh)
|
SECT_TEXT(g4kcodh)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kFST_func,0)
|
EXPORT MANGLE_FUNC(go4kFST_func,0)
|
||||||
@ -1019,35 +1030,35 @@ go4kFST_func_set:
|
|||||||
go4kFST_func_done:
|
go4kFST_func_done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // FLD Tick (load a value on stack, optionally add a modulation signal beforehand)
|
; FLD Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; Output: st0 : 2*v-1, where v is the loaded value
|
||||||
; // OUT : signal-signal*pan , signal*pan
|
; Dirty: eax, edx
|
||||||
; // DIRTY :
|
;-------------------------------------------------------------------------------
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
SECT_TEXT(g4kcodm)
|
SECT_TEXT(g4kcodm)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kFLD_func,0) ;// in main env
|
EXPORT MANGLE_FUNC(go4kFLD_func,0)
|
||||||
%ifdef GO4K_USE_FLD
|
%ifdef GO4K_USE_FLD
|
||||||
TRANSFORM_VALUES go4kFLD_val
|
TRANSFORM_VALUES go4kFLD_val
|
||||||
fld dword [edx+go4kFLD_val.value] ;// value in
|
fld dword [edx+go4kFLD_val.value] ; v
|
||||||
fsub dword [c_0_5]
|
fsub dword [c_0_5] ; v-.5
|
||||||
fadd st0
|
fadd st0 ; 2*v-1
|
||||||
%endif
|
%endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // FSTG Tick (stores a value anywhere in the synth (and in each voice))
|
; FSTG Tick
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : WRK = unit workspace
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : VAL = unit values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ecx = global workspace
|
; ecx : pointer to global workspace
|
||||||
; // OUT :
|
; st0 : signal
|
||||||
; // DIRTY :
|
; Output: (st0) : signal, unless popped
|
||||||
; //----------------------------------------------------------------------------------------
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
%ifdef GO4K_USE_FSTG
|
%ifdef GO4K_USE_FSTG
|
||||||
|
|
||||||
SECT_TEXT(g4kcodi)
|
SECT_TEXT(g4kcodi)
|
||||||
@ -1087,39 +1098,45 @@ go4kFSTG_func_done:
|
|||||||
ret
|
ret
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
; // PAN Tick (multiplies signal with main envelope and converts to stereo)
|
;-------------------------------------------------------------------------------
|
||||||
; //----------------------------------------------------------------------------------------
|
; PAN Tick
|
||||||
; // IN : WRK = unit workspace
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : VAL = unit values
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : ecx = global workspace
|
; VAL : pointer to unit values as bytes
|
||||||
; // OUT : signal-signal*pan , signal*pan
|
; ecx : pointer to global workspace
|
||||||
; // DIRTY :
|
; st0 : s, the signal
|
||||||
; //----------------------------------------------------------------------------------------
|
; Output: st0 : s*(1-p), where p is the panning in [0,1] range
|
||||||
|
; st1 : s*p
|
||||||
|
; Dirty: eax, edx
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodj)
|
SECT_TEXT(g4kcodj)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kPAN_func,0) ;// in main env
|
EXPORT MANGLE_FUNC(go4kPAN_func,0)
|
||||||
%ifdef GO4K_USE_PAN
|
%ifdef GO4K_USE_PAN
|
||||||
TRANSFORM_VALUES go4kPAN_val
|
TRANSFORM_VALUES go4kPAN_val
|
||||||
fld dword [edx+go4kPAN_val.panning] ;// pan in
|
fld dword [edx+go4kPAN_val.panning] ; p s
|
||||||
fmul st1 ;// r in
|
fmul st1 ; p*s s
|
||||||
fsub st1, st0 ;// r l
|
fsub st1, st0 ; p*s s-p*s
|
||||||
fxch ;// l r
|
; Equal to
|
||||||
|
; s*p s*(1-p)
|
||||||
|
fxch ; s*(1-p) s*p
|
||||||
%else
|
%else
|
||||||
fmul dword [c_0_5]
|
fmul dword [c_0_5] ; s*.5
|
||||||
fld st0
|
fld st0 ; s*.5 s*.5
|
||||||
%endif
|
%endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
; // OUT Tick ( stores stereo signal pair in temp buffers of the instrument)
|
;-------------------------------------------------------------------------------
|
||||||
; //----------------------------------------------------------------------------------------
|
; OUT Tick (stores stereo signal pair in temp buffers of the instrument)
|
||||||
; // IN : WRK = unit workspace
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : VAL = unit values
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : ecx = global workspace
|
; VAL : pointer to unit values as bytes
|
||||||
; // OUT :
|
; ecx : pointer to global workspace
|
||||||
; // DIRTY :
|
; st0 : l, the left signal
|
||||||
; //----------------------------------------------------------------------------------------
|
; st1 : r, the right signal
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodk)
|
SECT_TEXT(g4kcodk)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kOUT_func,0) ;// l r
|
EXPORT MANGLE_FUNC(go4kOUT_func,0) ;// l r
|
||||||
@ -1157,15 +1174,15 @@ EXPORT MANGLE_FUNC(go4kOUT_func,0) ;// l r
|
|||||||
%endif
|
%endif
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
; // ACC Tick (stereo signal accumulation for synth commands only -> dont use in instrument commands)
|
;-------------------------------------------------------------------------------
|
||||||
; //----------------------------------------------------------------------------------------
|
; ACC Tick (stereo signal accumulation)
|
||||||
; // IN : WRK = unit workspace
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : VAL = unit values
|
; Input: WRK : pointer to unit workspace
|
||||||
; // IN : ecx = global workspace
|
; VAL : pointer to unit values as bytes
|
||||||
; // OUT :
|
; ecx : pointer to global workspace
|
||||||
; // DIRTY : eax
|
; Dirty: eax,edx
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcodl)
|
SECT_TEXT(g4kcodl)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(go4kACC_func,0)
|
EXPORT MANGLE_FUNC(go4kACC_func,0)
|
||||||
@ -1188,14 +1205,9 @@ go4kACC_func_loop:
|
|||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // Update Instrument (allocate voices, set voice to release)
|
; Update Instrument (allocate voices, set voice to release)
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN :
|
|
||||||
; // IN :
|
|
||||||
; // OUT :
|
|
||||||
; // DIRTY :
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
SECT_TEXT(g4kcodw)
|
SECT_TEXT(g4kcodw)
|
||||||
|
|
||||||
go4kUpdateInstrument:
|
go4kUpdateInstrument:
|
||||||
@ -1239,14 +1251,9 @@ go4kUpdateInstrument_newNote:
|
|||||||
go4kUpdateInstrument_done:
|
go4kUpdateInstrument_done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // Render Voices
|
; Render Voices
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN :
|
|
||||||
; // IN :
|
|
||||||
; // OUT :
|
|
||||||
; // DIRTY :
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
SECT_TEXT(g4kcodx)
|
SECT_TEXT(g4kcodx)
|
||||||
|
|
||||||
go4kRenderVoices:
|
go4kRenderVoices:
|
||||||
@ -1312,9 +1319,12 @@ go4k_render_instrument_next2:
|
|||||||
pop ecx ; // restore instrument counter
|
pop ecx ; // restore instrument counter
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // the entry point for the synth
|
; _4klang_render function: the entry point for the synth
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
; Has the signature _4klang_render(void *ptr), where ptr is a pointer to
|
||||||
|
; the output buffer
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
SECT_TEXT(g4kcody)
|
SECT_TEXT(g4kcody)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(_4klang_render,4)
|
EXPORT MANGLE_FUNC(_4klang_render,4)
|
||||||
@ -1457,28 +1467,26 @@ go4k_render_nogroove:
|
|||||||
popad
|
popad
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // the magic behind it :)
|
; VM_process function (the virtual machine behind the synth)
|
||||||
; //----------------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; // IN : edi = instrument pointer
|
; Input: edi : pointer to the instrument structure
|
||||||
; // IN : esi = instrumet values
|
; VAL : pointer to unit values as bytes
|
||||||
; // IN : ebx = instrument instructions
|
; ebx : pointer to instrument instructions
|
||||||
; // OUT :
|
;-------------------------------------------------------------------------------
|
||||||
; // DIRTY :
|
|
||||||
; //----------------------------------------------------------------------------------------
|
|
||||||
SECT_TEXT(g4kcodz)
|
SECT_TEXT(g4kcodz)
|
||||||
|
|
||||||
go4k_VM_process:
|
go4k_VM_process:
|
||||||
lea WRK, [edi+8] ; // get current workspace pointer
|
lea WRK, [edi+8] ; WRK = workspace start
|
||||||
mov ecx, WRK ; // ecx = workspace start
|
mov ecx, WRK ; ecx = workspace start
|
||||||
go4k_VM_process_loop:
|
go4k_VM_process_loop:
|
||||||
movzx eax, byte [ebx] ; // get command byte
|
movzx eax, byte [ebx] ; eax = command byte
|
||||||
inc ebx
|
inc ebx
|
||||||
test eax, eax
|
test eax, eax ; if (eax == 0)
|
||||||
je go4k_VM_process_done ; // command byte = 0? so done
|
je go4k_VM_process_done ; goto done
|
||||||
call dword [eax*4+go4k_synth_commands]
|
call dword [eax*4+go4k_synth_commands] ; call the function corresponding to command
|
||||||
add WRK, MAX_UNIT_SLOTS*4 ; // go to next workspace slot
|
add WRK, MAX_UNIT_SLOTS*4 ; move WRK to next workspace
|
||||||
jmp short go4k_VM_process_loop
|
jmp short go4k_VM_process_loop
|
||||||
go4k_VM_process_done:
|
go4k_VM_process_done:
|
||||||
add edi, go4k_instrument.size ; // go to next instrument voice
|
add edi, go4k_instrument.size ; move edi to next instrument
|
||||||
ret
|
ret
|
Loading…
x
Reference in New Issue
Block a user