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
|
||||
%endif
|
||||
|
||||
; //========================================================================================
|
||||
; // .crtemui section (emulates crt functions)
|
||||
; //========================================================================================
|
||||
;-------------------------------------------------------------------------------
|
||||
; FloatRandomNumber function
|
||||
;-------------------------------------------------------------------------------
|
||||
; Output: st0 : result
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(crtemui)
|
||||
|
||||
EXPORT MANGLE_FUNC(FloatRandomNumber,0)
|
||||
@ -124,58 +126,62 @@ EXPORT MANGLE_FUNC(FloatRandomNumber,0)
|
||||
pop eax
|
||||
ret
|
||||
|
||||
; //========================================================================================
|
||||
; // .g4kcod* sections (code for go4k)
|
||||
; //========================================================================================
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Waveshaper function
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Input : st0 : shaping coeff
|
||||
; // st1 : input
|
||||
; // Output: st0 : result
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; Waveshaper function
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: st0 : a - the shaping coefficient
|
||||
; st1 : x - input value
|
||||
; 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
|
||||
;-------------------------------------------------------------------------------
|
||||
%ifdef INCLUDE_WAVESHAPER
|
||||
|
||||
SECT_TEXT(g4kcod2)
|
||||
|
||||
go4kWaveshaper:
|
||||
go4kWaveshaper: ; a x
|
||||
%ifdef GO4K_USE_WAVESHAPER_CLIP
|
||||
fxch
|
||||
fld1 ; // 1 val
|
||||
fucomi st1 ; // 1 val
|
||||
jbe short go4kWaveshaper_clip
|
||||
fchs ; // -1 val
|
||||
fucomi st1 ; // -1 val
|
||||
fcmovb st0, st1 ; // val -1 (if val > -1)
|
||||
fxch ; x a
|
||||
fld1 ; 1 x a
|
||||
fucomi st1 ; if (1 <= x)
|
||||
jbe short go4kWaveshaper_clip ; goto go4kWaveshaper_clip
|
||||
fchs ; -1 x a
|
||||
fucomi st1 ; if (-1 < x)
|
||||
fcmovb st0, st1 ; x x a
|
||||
go4kWaveshaper_clip:
|
||||
fstp st1 ; // newval
|
||||
fxch
|
||||
fstp st1 ; x' a, where x' = clamp(x)
|
||||
fxch ; a x' (from now on just called x)
|
||||
%endif
|
||||
fsub dword [c_0_5]
|
||||
fadd st0
|
||||
fst dword [esp-4] ; // amnt in
|
||||
fadd st0 ; // 2*amnt in
|
||||
fld1 ; // 1 2*amnt in
|
||||
fsub dword [esp-4] ; // 1-amnt 2*amnt in
|
||||
fdivp st1, st0 ; // k in
|
||||
fld st1 ; // sin k in
|
||||
fabs ; // a(in) k in
|
||||
fmul st1 ; // k*a(in) k in
|
||||
fld1
|
||||
faddp st1, st0 ; // 1+k*a(in) k in
|
||||
fxch st1 ; // k 1+k*a(in) in
|
||||
fld1
|
||||
faddp st1, st0 ; // 1+k 1+k*a(in) in
|
||||
fmulp st2 ; // 1+k*a(in) (1+k)*in
|
||||
fdivp st1, st0 ; // out
|
||||
fsub dword [c_0_5] ; a-.5 x
|
||||
fadd st0 ; 2*a-1 x
|
||||
fst dword [esp-4] ; m=2*a-1 x
|
||||
fadd st0 ; 2*m x
|
||||
fld1 ; 1 2*m x
|
||||
fsub dword [esp-4] ; 1-m 2*m x
|
||||
fdivp st1, st0 ; k=2*m/(1-m) x
|
||||
fld st1 ; x k x
|
||||
fabs ; abs(x) k x
|
||||
fmul st1 ; k*abs(x) k x
|
||||
fld1 ; 1 k*abs(x) k x
|
||||
faddp st1, st0 ; 1+k*abs(x) k x
|
||||
fxch st1 ; k 1+k*abs(x) x
|
||||
fld1 ; 1 k 1+k*abs(x) x
|
||||
faddp st1, st0 ; 1+k 1+k*abs(x) x
|
||||
fmulp st2 ; 1+k*abs(x) (1+k)*x
|
||||
fdivp st1, st0 ; (1+k)*x/(1+k*abs(x))
|
||||
ret
|
||||
|
||||
%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)
|
||||
|
||||
go4kTransformValues:
|
||||
@ -197,22 +203,27 @@ go4kTransformValues_loop:
|
||||
pop ecx
|
||||
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)
|
||||
|
||||
go4kENVMap:
|
||||
fld dword [edx+eax*4]
|
||||
fimul dword [c_24]
|
||||
fchs
|
||||
fld dword [edx+eax*4] ; x, where x is the parameter in the range 0-1
|
||||
fimul dword [c_24] ; 24*x
|
||||
fchs ; -24*x
|
||||
; flow into Power function, which outputs 2^(-24*x)
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Power function (2^x)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Input : st0 : x
|
||||
; // Output: st0 : 2^x
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; Power function (2^x)
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: st0 : x
|
||||
; Output: st0 : 2^x
|
||||
;-------------------------------------------------------------------------------
|
||||
EXPORT MANGLE_FUNC(Power,0) ; x
|
||||
fld1 ; 1 x
|
||||
fld st1 ; x 1 x
|
||||
@ -225,159 +236,83 @@ EXPORT MANGLE_FUNC(Power,0) ; x
|
||||
fstp st1 ; 2^x
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ENV Tick
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; ENV Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; Output: st0 : envelope value, [gain]*level. The slopes of
|
||||
; 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)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kENV_func,0)
|
||||
TRANSFORM_VALUES go4kENV_val
|
||||
%ifdef GO4K_USE_ENV_CHECK
|
||||
; check if current note still active
|
||||
mov eax, dword [ecx-4]
|
||||
test eax, eax
|
||||
jne go4kENV_func_do
|
||||
mov eax, dword [ecx-4] ; eax = go4k_instrument.note
|
||||
test eax, eax ; if (eax != 0) // if current note still active
|
||||
jne go4kENV_func_do ; goto go4kENV_func_do
|
||||
fldz
|
||||
ret
|
||||
ret ; return 0
|
||||
%endif
|
||||
go4kENV_func_do:
|
||||
mov eax, dword [ecx-8] ; // is the instrument in release mode (note off)?
|
||||
test eax, eax
|
||||
je go4kENV_func_process
|
||||
mov dword [WRK+go4kENV_wrk.state], ENV_STATE_RELEASE
|
||||
mov eax, dword [ecx-8] ; eax = go4k_instrument.release
|
||||
test eax, eax ; if (eax == 0)
|
||||
je go4kENV_func_process ; goto process
|
||||
mov dword [WRK+go4kENV_wrk.state], ENV_STATE_RELEASE ; [state]=RELEASE
|
||||
go4kENV_func_process:
|
||||
mov eax, dword [WRK+go4kENV_wrk.state]
|
||||
fld dword [WRK+go4kENV_wrk.level] ; // val -
|
||||
; // check for sustain state
|
||||
cmp al, ENV_STATE_SUSTAIN
|
||||
je short go4kENV_func_leave2
|
||||
mov eax, dword [WRK+go4kENV_wrk.state] ; al=[state]
|
||||
fld dword [WRK+go4kENV_wrk.level] ; x=[level]
|
||||
cmp al, ENV_STATE_SUSTAIN ; if (al==SUSTAIN)
|
||||
je short go4kENV_func_leave2 ; goto leave2
|
||||
go4kENV_func_attac:
|
||||
cmp al, ENV_STATE_ATTAC
|
||||
jne short go4kENV_func_decay
|
||||
call go4kENVMap ; // newval
|
||||
faddp st1, st0
|
||||
; // check for end of attac
|
||||
fld1 ; // 1 newval
|
||||
fucomi st1 ; // 1 newval
|
||||
fcmovnb st0, st1 ; // newval 1 (if newval < 1)
|
||||
jbe short go4kENV_func_statechange
|
||||
cmp al, ENV_STATE_ATTAC ; if (al!=ATTAC)
|
||||
jne short go4kENV_func_decay ; goto decay
|
||||
call go4kENVMap ; a x, where a=attack
|
||||
faddp st1, st0 ; a+x
|
||||
fld1 ; 1 a+x
|
||||
fucomi st1 ; if (a+x<=1) // is attack complete?
|
||||
fcmovnb st0, st1 ; a+x a+x
|
||||
jbe short go4kENV_func_statechange ; else goto statechange
|
||||
go4kENV_func_decay:
|
||||
cmp al, ENV_STATE_DECAY
|
||||
jne short go4kENV_func_release
|
||||
call go4kENVMap ; // newval
|
||||
fsubp st1, st0
|
||||
; // check for end of decay
|
||||
fld dword [edx+go4kENV_val.sustain] ; // sustain newval
|
||||
fucomi st1 ; // sustain newval
|
||||
fcmovb st0, st1 ; // newval sustain (if newval > sustain)
|
||||
jnc short go4kENV_func_statechange
|
||||
cmp al, ENV_STATE_DECAY ; if (al!=DECAY)
|
||||
jne short go4kENV_func_release ; goto release
|
||||
call go4kENVMap ; d x, where d=decay
|
||||
fsubp st1, st0 ; x-d
|
||||
fld dword [edx+go4kENV_val.sustain] ; s x-d, where s=sustain
|
||||
fucomi st1 ; if (x-d>s) // is decay complete?
|
||||
fcmovb st0, st1 ; x-d x-d
|
||||
jnc short go4kENV_func_statechange ; else goto statechange
|
||||
go4kENV_func_release:
|
||||
; // release state?
|
||||
cmp al, ENV_STATE_RELEASE
|
||||
jne short go4kENV_func_leave
|
||||
call go4kENVMap ; // newval
|
||||
fsubp st1, st0
|
||||
; // check for end of release
|
||||
fldz ; // 0 newval
|
||||
fucomi st1 ; // 0 newval
|
||||
fcmovb st0, st1 ; // newval 0 (if newval > 0)
|
||||
cmp al, ENV_STATE_RELEASE ; if (al!=RELEASE)
|
||||
jne short go4kENV_func_leave ; goto leave
|
||||
call go4kENVMap ; r x, where r=release
|
||||
fsubp st1, st0 ; x-r
|
||||
fldz ; 0 x-r
|
||||
fucomi st1 ; if (x-r>0) // is release complete?
|
||||
fcmovb st0, st1 ; x-r x-r, then goto leave
|
||||
jc short go4kENV_func_leave
|
||||
go4kENV_func_statechange: ; // newval
|
||||
inc dword [WRK+go4kENV_wrk.state]
|
||||
go4kENV_func_leave: ; // newval bla
|
||||
fstp st1
|
||||
; // store new env value
|
||||
fst dword [WRK+go4kENV_wrk.level]
|
||||
go4kENV_func_statechange:
|
||||
inc dword [WRK+go4kENV_wrk.state] ; [state]++
|
||||
go4kENV_func_leave:
|
||||
fstp st1 ; x', where x' is the new value
|
||||
fst dword [WRK+go4kENV_wrk.level] ; [level]=x'
|
||||
go4kENV_func_leave2:
|
||||
; // mul by gain
|
||||
fmul dword [edx+go4kENV_val.gain]
|
||||
fmul dword [edx+go4kENV_val.gain] ; [gain]*x'
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCO Tick
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; VCO Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; Output: st0 : oscillator value
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodb)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kVCO_func,0)
|
||||
@ -506,15 +441,86 @@ go4kVCO_func_stereodone:
|
||||
%endif
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // VCF Tick
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; 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)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kVCF_func,0)
|
||||
@ -594,15 +600,16 @@ go4kVCF_func_processdone:
|
||||
go4kVCF_func_end: ; // value - - - -
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DST Tick
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; DST Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : signal
|
||||
; Output: st0 : distorted signal
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodd)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kDST_func,0)
|
||||
@ -666,15 +673,16 @@ go4kDST_func_monohold:
|
||||
|
||||
%endif
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // DLL Tick
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; DLL Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : signal
|
||||
; Output: st0 : delayed signal
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodf)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kDLL_func,0)
|
||||
@ -810,15 +818,16 @@ go4kDLL_func_buffer_nowrap2:
|
||||
ret
|
||||
%endif
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // GLITCH Tick
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; GLITCH Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; ?
|
||||
; Output: ?
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodu)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kGLITCH_func,0)
|
||||
@ -924,15 +933,16 @@ go4kGLITCH_func_leave:
|
||||
ret
|
||||
%endif
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FOP Tick (various fp stack based operations)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; FOP Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; stX : depends on the operation
|
||||
; Output: stX : depends on the operation
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodg)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kFOP_func,0)
|
||||
@ -989,15 +999,16 @@ go4kFOP_func_mulp2:
|
||||
fmulp st2, st0
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FST Tick (stores a value somewhere in the local workspace)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; FST Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : signal
|
||||
; Output: (st0) : signal, unless popped
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodh)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kFST_func,0)
|
||||
@ -1019,35 +1030,35 @@ go4kFST_func_set:
|
||||
go4kFST_func_done:
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FLD Tick (load a value on stack, optionally add a modulation signal beforehand)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT : signal-signal*pan , signal*pan
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; FLD Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; Output: st0 : 2*v-1, where v is the loaded value
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodm)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kFLD_func,0) ;// in main env
|
||||
EXPORT MANGLE_FUNC(go4kFLD_func,0)
|
||||
%ifdef GO4K_USE_FLD
|
||||
TRANSFORM_VALUES go4kFLD_val
|
||||
fld dword [edx+go4kFLD_val.value] ;// value in
|
||||
fsub dword [c_0_5]
|
||||
fadd st0
|
||||
fld dword [edx+go4kFLD_val.value] ; v
|
||||
fsub dword [c_0_5] ; v-.5
|
||||
fadd st0 ; 2*v-1
|
||||
%endif
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // FSTG Tick (stores a value anywhere in the synth (and in each voice))
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; FSTG Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : signal
|
||||
; Output: (st0) : signal, unless popped
|
||||
; Dirty: eax, edx
|
||||
;-------------------------------------------------------------------------------
|
||||
%ifdef GO4K_USE_FSTG
|
||||
|
||||
SECT_TEXT(g4kcodi)
|
||||
@ -1087,39 +1098,45 @@ go4kFSTG_func_done:
|
||||
ret
|
||||
%endif
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // PAN Tick (multiplies signal with main envelope and converts to stereo)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT : signal-signal*pan , signal*pan
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; PAN Tick
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; 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)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kPAN_func,0) ;// in main env
|
||||
EXPORT MANGLE_FUNC(go4kPAN_func,0)
|
||||
%ifdef GO4K_USE_PAN
|
||||
TRANSFORM_VALUES go4kPAN_val
|
||||
fld dword [edx+go4kPAN_val.panning] ;// pan in
|
||||
fmul st1 ;// r in
|
||||
fsub st1, st0 ;// r l
|
||||
fxch ;// l r
|
||||
fld dword [edx+go4kPAN_val.panning] ; p s
|
||||
fmul st1 ; p*s s
|
||||
fsub st1, st0 ; p*s s-p*s
|
||||
; Equal to
|
||||
; s*p s*(1-p)
|
||||
fxch ; s*(1-p) s*p
|
||||
%else
|
||||
fmul dword [c_0_5]
|
||||
fld st0
|
||||
fmul dword [c_0_5] ; s*.5
|
||||
fld st0 ; s*.5 s*.5
|
||||
%endif
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // OUT Tick ( stores stereo signal pair in temp buffers of the instrument)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; OUT Tick (stores stereo signal pair in temp buffers of the instrument)
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; st0 : l, the left signal
|
||||
; st1 : r, the right signal
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodk)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kOUT_func,0) ;// l r
|
||||
@ -1157,15 +1174,15 @@ EXPORT MANGLE_FUNC(go4kOUT_func,0) ;// l r
|
||||
%endif
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // ACC Tick (stereo signal accumulation for synth commands only -> dont use in instrument commands)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : WRK = unit workspace
|
||||
; // IN : VAL = unit values
|
||||
; // IN : ecx = global workspace
|
||||
; // OUT :
|
||||
; // DIRTY : eax
|
||||
; //----------------------------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; ACC Tick (stereo signal accumulation)
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: WRK : pointer to unit workspace
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ecx : pointer to global workspace
|
||||
; Dirty: eax,edx
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodl)
|
||||
|
||||
EXPORT MANGLE_FUNC(go4kACC_func,0)
|
||||
@ -1188,14 +1205,9 @@ go4kACC_func_loop:
|
||||
popad
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Update Instrument (allocate voices, set voice to release)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN :
|
||||
; // IN :
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; Update Instrument (allocate voices, set voice to release)
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodw)
|
||||
|
||||
go4kUpdateInstrument:
|
||||
@ -1239,14 +1251,9 @@ go4kUpdateInstrument_newNote:
|
||||
go4kUpdateInstrument_done:
|
||||
ret
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // Render Voices
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN :
|
||||
; // IN :
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; Render Voices
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodx)
|
||||
|
||||
go4kRenderVoices:
|
||||
@ -1312,9 +1319,12 @@ go4k_render_instrument_next2:
|
||||
pop ecx ; // restore instrument counter
|
||||
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)
|
||||
|
||||
EXPORT MANGLE_FUNC(_4klang_render,4)
|
||||
@ -1457,28 +1467,26 @@ go4k_render_nogroove:
|
||||
popad
|
||||
ret 4
|
||||
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // the magic behind it :)
|
||||
; //----------------------------------------------------------------------------------------
|
||||
; // IN : edi = instrument pointer
|
||||
; // IN : esi = instrumet values
|
||||
; // IN : ebx = instrument instructions
|
||||
; // OUT :
|
||||
; // DIRTY :
|
||||
; //----------------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
; VM_process function (the virtual machine behind the synth)
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input: edi : pointer to the instrument structure
|
||||
; VAL : pointer to unit values as bytes
|
||||
; ebx : pointer to instrument instructions
|
||||
;-------------------------------------------------------------------------------
|
||||
SECT_TEXT(g4kcodz)
|
||||
|
||||
go4k_VM_process:
|
||||
lea WRK, [edi+8] ; // get current workspace pointer
|
||||
mov ecx, WRK ; // ecx = workspace start
|
||||
lea WRK, [edi+8] ; WRK = workspace start
|
||||
mov ecx, WRK ; ecx = workspace start
|
||||
go4k_VM_process_loop:
|
||||
movzx eax, byte [ebx] ; // get command byte
|
||||
movzx eax, byte [ebx] ; eax = command byte
|
||||
inc ebx
|
||||
test eax, eax
|
||||
je go4k_VM_process_done ; // command byte = 0? so done
|
||||
call dword [eax*4+go4k_synth_commands]
|
||||
add WRK, MAX_UNIT_SLOTS*4 ; // go to next workspace slot
|
||||
test eax, eax ; if (eax == 0)
|
||||
je go4k_VM_process_done ; goto done
|
||||
call dword [eax*4+go4k_synth_commands] ; call the function corresponding to command
|
||||
add WRK, MAX_UNIT_SLOTS*4 ; move WRK to next workspace
|
||||
jmp short go4k_VM_process_loop
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user