mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-03 09:08:18 -04:00
Re-engineer delay, to use stack for the delay WRK pointer and to support note-syncing transpose.
This commit is contained in:
parent
afbff66e36
commit
6f06306f0c
@ -313,79 +313,98 @@ su_effects_stereohelper_mono:
|
|||||||
SECT_TEXT(sudelay)
|
SECT_TEXT(sudelay)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(su_op_delay,0)
|
EXPORT MANGLE_FUNC(su_op_delay,0)
|
||||||
lodsb ; eax = delay index
|
lodsw ; al = delay index, ah = delay count
|
||||||
mov edi, eax
|
push_registers VAL, COM, WRK ; these are non-volatile according to our convention
|
||||||
lodsb ; eax = delay count
|
%ifdef INCLUDE_DELAY_MODULATION ; TODO: at the moment, this must be manually enabled, as the PORT macro is a singleline macro and cannot toggle this. Will have to think of a good solution.
|
||||||
|
mov esi, dword [WRK+su_unit.ports+su_delay_ports.delaymod]
|
||||||
|
mov [INP+su_delay_ports.delaymod],esi ; move the modulation to the transformed values, as we will not have access to WRK soon
|
||||||
|
%endif
|
||||||
|
movzx ebx, al
|
||||||
|
apply {lea _BX,},MANGLE_DATA(su_delay_times),_BX*2,{} ; _BP now points to the right position within delay time table
|
||||||
|
movzx esi, word [_SP + su_stack.tick + PUSH_REG_SIZE(3)] ; notice that we load word, so we wrap at 65536
|
||||||
|
mov WRK, PTRWORD [_SP + su_stack.delaywrk + PUSH_REG_SIZE(3)] ; WRK is now the separate delay workspace, as they require a lot more space
|
||||||
%ifdef INCLUDE_STEREO_DELAY
|
%ifdef INCLUDE_STEREO_DELAY
|
||||||
jnc su_op_delay_mono
|
jnc su_op_delay_mono
|
||||||
fxch
|
push _AX ; save _ah (delay count)
|
||||||
call su_op_delay_mono ; do right delay
|
fxch ; r l
|
||||||
fxch
|
call su_op_delay_do ; D(r) l process delay for the right channel
|
||||||
add edi, eax ; the second delay is done with the delay time index added by count
|
pop _AX ; restore the count for second run
|
||||||
su_op_delay_mono:
|
fxch ; l D(r)
|
||||||
|
su_op_delay_mono: ; flow into mono delay
|
||||||
%endif
|
%endif
|
||||||
push_registers _AX, _CX, _BX, WRK, _SI, _DI
|
call su_op_delay_do ; when stereo delay is not enabled, we could inline this to save 5 bytes, but I expect stereo delay to be farely popular so maybe not worth the hassle
|
||||||
mov ebx, edi; ugly register juggling, refactor
|
mov PTRWORD [_SP + su_stack.delaywrk + PUSH_REG_SIZE(3)],WRK ; move delay workspace pointer back to stack.
|
||||||
%ifdef DELAY_NOTE_SYNC
|
pop_registers VAL, COM, WRK
|
||||||
test ebx, ebx ; note s
|
%ifdef INCLUDE_DELAY_MODULATION
|
||||||
jne su_op_delay_skipnotesync
|
xor eax, eax
|
||||||
fld1
|
mov dword [WRK+su_unit.ports+su_delay_ports.delaymod], eax ; zero it
|
||||||
fild dword [_CX+su_unit.size-su_voice.workspace+su_voice.note]
|
|
||||||
apply fmul dword, c_i12
|
|
||||||
call MANGLE_FUNC(su_power,0)
|
|
||||||
apply fmul dword, c_freq_normalize ; // normalize
|
|
||||||
fdivp st1, st0 ; // invert to get numer of samples
|
|
||||||
apply fistp word, MANGLE_DATA(su_delay_times) ; store current comb size
|
|
||||||
su_op_delay_skipnotesync:
|
|
||||||
%endif
|
%endif
|
||||||
kmDLL_func_process:
|
ret
|
||||||
mov ecx, eax ;// ecx is the number of parallel delays
|
|
||||||
apply {mov WRK, PTRWORD},MANGLE_DATA(su_delay_buffer_ofs) ;// ebp is current delay
|
|
||||||
fld st0 ; x x
|
|
||||||
fmul dword [INP+su_delay_ports.dry] ; dr*x x
|
|
||||||
fxch ; x dr*x
|
|
||||||
fmul dword [INP+su_delay_ports.pregain] ; p*x dr*x
|
|
||||||
fmul dword [INP+su_delay_ports.pregain] ; p^2*x dr*x
|
|
||||||
|
|
||||||
kmDLL_func_loop:
|
%ifdef INCLUDE_DELAY_MODULATION
|
||||||
mov edi, dword [WRK + su_delayline_wrk.time]
|
%define INCLUDE_DELAY_FLOAT_TIME
|
||||||
inc edi
|
%endif
|
||||||
and edi, MAX_DELAY-1
|
|
||||||
mov dword [WRK + su_delayline_wrk.time],edi
|
;-------------------------------------------------------------------------------
|
||||||
apply {movzx esi, word},MANGLE_DATA(su_delay_times),_BX*2,{} ; esi = comb size from the delay times table
|
; su_op_delay_do: executes the actual delay
|
||||||
mov eax, edi
|
;-------------------------------------------------------------------------------
|
||||||
sub eax, esi
|
su_op_delay_do: ; x y
|
||||||
and eax, MAX_DELAY-1
|
fld st0
|
||||||
apply fld dword, su_delayline_wrk.buffer, WRK, _AX*4,{} ; s p^2*x dr*x, where s is the sample from delay buffer
|
fmul dword [INP+su_delay_ports.pregain] ; p*x y
|
||||||
;// add comb output to current output
|
fmul dword [INP+su_delay_ports.pregain] ; p*p*x y
|
||||||
fadd st2, st0 ; s p^2*x dr*x+s
|
fxch ; y p*p*x
|
||||||
fld1 ; 1 s p^2*x dr*x+s
|
fmul dword [INP+su_delay_ports.dry] ; dr*y p*p*x
|
||||||
fsub dword [INP+su_delay_ports.damp] ; 1-da s p^2*x dr*x+s
|
su_op_delay_loop:
|
||||||
fmulp st1, st0 ; s*(1-da) p^2*x dr*x+s
|
%ifdef INCLUDE_DELAY_FLOAT_TIME ; delaytime modulation or note syncing require computing the delay time in floats
|
||||||
fld dword [INP+su_delay_ports.damp] ; da s*(1-da) p^2*x dr*x+s
|
fild word [_BX] ; k dr*y p*p*x, where k = delay time
|
||||||
fmul dword [WRK+su_delayline_wrk.filtstate] ; o*da s*(1-da) p^2*x dr*x+s, where o is stored
|
%ifdef INCLUDE_DELAY_NOTETRACKING
|
||||||
faddp st1, st0 ; o*da+s*(1-da) p^2*x dr*x+s
|
test ah, 1 ; note syncing is the least significant bit of ah, 0 = ON, 1 = OFF
|
||||||
fst dword [WRK+su_delayline_wrk.filtstate] ; o'=o*da+s*(1-da), o' p^2*x dr*x+s
|
jne su_op_delay_skipnotesync
|
||||||
fmul dword [INP+su_delay_ports.feedback] ; f*o' p^2*x dr*x+s
|
fild dword [_CX+su_unit.size-su_voice.workspace+su_voice.note]
|
||||||
fadd st0, st1 ; f*o'+p^2*x p^2*x dr*x+s
|
apply fmul dword, c_i12
|
||||||
fstp dword [WRK+_DI*4+su_delayline_wrk.buffer]; save f*o'+p^2*x to delay buffer
|
call MANGLE_FUNC(su_power,0)
|
||||||
inc ebx ;// go to next delay lenkmh index
|
fdivp st1, st0 ; use 10787 for delaytime to have neutral transpose
|
||||||
add WRK, su_delayline_wrk.size ;// go to next delay
|
su_op_delay_skipnotesync:
|
||||||
apply mov PTRWORD, MANGLE_DATA(su_delay_buffer_ofs),{, WRK} ;// store next delay offset
|
%endif
|
||||||
loopne kmDLL_func_loop
|
%ifdef INCLUDE_DELAY_MODULATION
|
||||||
fstp st0 ; dr*x+s1+s2+s3+...
|
fld dword [INP+su_delay_ports.delaymod]
|
||||||
|
apply fmul dword, c_32767 ; scale it up, as the modulations would be too small otherwise
|
||||||
|
faddp st1, st0
|
||||||
|
%endif
|
||||||
|
fistp dword [_SP-4] ; dr*y p*p*x, dword [_SP-4] = integer amount of delay (samples)
|
||||||
|
mov edi, esi ; edi = esi = current time
|
||||||
|
sub di, word [_SP-4] ; we perform the math in 16-bit to wrap around
|
||||||
|
%else
|
||||||
|
mov edi, esi
|
||||||
|
sub di, word [_BX] ; we perform the math in 16-bit to wrap around
|
||||||
|
%endif
|
||||||
|
fld dword [WRK+su_delayline_wrk.buffer+_DI*4]; s dr*y p*p*x, where s is the sample from delay buffer
|
||||||
|
fadd st1, st0 ; s dr*y+s p*p*x (add comb output to current output)
|
||||||
|
fld1 ; 1 s dr*y+s p*p*x
|
||||||
|
fsub dword [INP+su_delay_ports.damp] ; 1-da s dr*y+s p*p*x
|
||||||
|
fmulp st1, st0 ; s*(1-da) dr*y+s p*p*x
|
||||||
|
fld dword [INP+su_delay_ports.damp] ; da s*(1-da) dr*y+s p*p*x
|
||||||
|
fmul dword [WRK+su_delayline_wrk.filtstate] ; o*da s*(1-da) dr*y+s p*p*x, where o is stored
|
||||||
|
faddp st1, st0 ; o*da+s*(1-da) dr*y+s p*p*x
|
||||||
|
fst dword [WRK+su_delayline_wrk.filtstate] ; o'=o*da+s*(1-da), o' dr*y+s p*p*x
|
||||||
|
fmul dword [INP+su_delay_ports.feedback] ; f*o' dr*y+s p*p*x
|
||||||
|
fadd st0, st2 ; f*o'+p*p*x dr*y+s p*p*x
|
||||||
|
fstp dword [WRK+su_delayline_wrk.buffer+_SI*4]; save f*o'+p*p*x to delay buffer
|
||||||
|
add _BX,2 ; move to next index
|
||||||
|
add WRK, su_delayline_wrk.size ; go to next delay delay workspace
|
||||||
|
sub ah, 2
|
||||||
|
jg su_op_delay_loop ; if ah > 0, goto loop
|
||||||
|
fstp st1 ; dr*y+s1+s2+s3+...
|
||||||
; DC-filtering
|
; DC-filtering
|
||||||
sub WRK, su_delayline_wrk.size ; the reason to use the last su_delayline_wrk instead of su_delay_wrk is that su_delay_wrk is wiped by retriggering
|
|
||||||
fld dword [WRK+su_delayline_wrk.dcout] ; o s
|
fld dword [WRK+su_delayline_wrk.dcout] ; o s
|
||||||
apply fmul dword, c_dc_const ; c*o s
|
apply fmul dword, c_dc_const ; c*o s
|
||||||
fsub dword [WRK+su_delayline_wrk.dcin] ; c*o-i s
|
fsub dword [WRK+su_delayline_wrk.dcin] ; c*o-i s
|
||||||
fxch ; s c*o-i
|
fxch ; s c*o-i
|
||||||
fst dword [WRK+su_delayline_wrk.dcin] ; i'=s, s c*o-i
|
fst dword [WRK+su_delayline_wrk.dcin] ; i'=s, s c*o-i
|
||||||
faddp st1 ; s+c*o-i
|
faddp st1 ; s+c*o-i
|
||||||
apply fadd dword, c_0_5 ;// add and sub small offset to prevent denormalization
|
apply fadd dword, c_0_5 ; add and sub small offset to prevent denormalization
|
||||||
apply fsub dword, c_0_5
|
apply fsub dword, c_0_5
|
||||||
fst dword [WRK+su_delayline_wrk.dcout] ; o'=s+c*o-i
|
fst dword [WRK+su_delayline_wrk.dcout] ; o'=s+c*o-i
|
||||||
pop_registers _AX, _CX, _BX, WRK, _SI, _DI
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
@ -393,9 +412,6 @@ kmDLL_func_loop:
|
|||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
SECT_BSS(sudelbuf)
|
SECT_BSS(sudelbuf)
|
||||||
|
|
||||||
EXPORT MANGLE_DATA(su_delay_buffer_ofs)
|
|
||||||
RESPTR 1
|
|
||||||
|
|
||||||
EXPORT MANGLE_DATA(su_delay_buffer)
|
EXPORT MANGLE_DATA(su_delay_buffer)
|
||||||
resb NUM_DELAY_LINES*su_delayline_wrk.size
|
resb NUM_DELAY_LINES*su_delayline_wrk.size
|
||||||
|
|
||||||
@ -406,11 +422,14 @@ SECT_DATA(suconst)
|
|||||||
%define C_DC_CONST
|
%define C_DC_CONST
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%ifndef C_FREQ_NORMALIZE
|
%ifdef INCLUDE_DELAY_MODULATION
|
||||||
c_freq_normalize dd 0.000092696138 ; // 220.0/(2^(69/12)) / 44100.0
|
%ifndef C_32767
|
||||||
%define C_FREQ_NORMALIZE
|
c_32767 dd 32767.0
|
||||||
|
%define C_32767
|
||||||
|
%endif
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
%endif ; DELAY_ID > -1
|
%endif ; DELAY_ID > -1
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
@ -281,7 +281,7 @@ endstruc
|
|||||||
%endif
|
%endif
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%define MAX_DELAY 65536
|
%define MAX_DELAY 65536 ; warning: this is pretty much fixed, as we use 16-bit math to wraparound the delay buffers
|
||||||
%assign NUM_DELAY_LINES 0
|
%assign NUM_DELAY_LINES 0
|
||||||
|
|
||||||
%macro SU_DELAY 7
|
%macro SU_DELAY 7
|
||||||
@ -297,8 +297,9 @@ endstruc
|
|||||||
%if %1 == STEREO
|
%if %1 == STEREO
|
||||||
%define INCLUDE_STEREO_DELAY
|
%define INCLUDE_STEREO_DELAY
|
||||||
%endif
|
%endif
|
||||||
%if %6 == 0
|
%if (%7) & NOTETRACKING == 0
|
||||||
%define DELAY_NOTE_SYNC
|
%define INCLUDE_DELAY_NOTETRACKING
|
||||||
|
%define INCLUDE_DELAY_FLOAT_TIME
|
||||||
%endif
|
%endif
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
@ -306,7 +307,6 @@ endstruc
|
|||||||
SECT_DATA(sudeltim)
|
SECT_DATA(sudeltim)
|
||||||
|
|
||||||
EXPORT MANGLE_DATA(su_delay_times)
|
EXPORT MANGLE_DATA(su_delay_times)
|
||||||
dw 0
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%define SU_END_DELTIMES
|
%define SU_END_DELTIMES
|
||||||
@ -325,7 +325,8 @@ endstruc
|
|||||||
%define DEPTH(val) val
|
%define DEPTH(val) val
|
||||||
%define DAMP(val) val
|
%define DAMP(val) val
|
||||||
%define DELAY(val) val
|
%define DELAY(val) val
|
||||||
%define COUNT(val) val
|
%define COUNT(val) (2*val-1)
|
||||||
|
%define NOTETRACKING 1
|
||||||
|
|
||||||
struc su_delay_ports
|
struc su_delay_ports
|
||||||
.pregain resd 1
|
.pregain resd 1
|
||||||
@ -333,19 +334,18 @@ struc su_delay_ports
|
|||||||
.feedback resd 1
|
.feedback resd 1
|
||||||
.damp resd 1
|
.damp resd 1
|
||||||
.freq resd 1
|
.freq resd 1
|
||||||
|
.delaymod resd 1 ; note that this is not converted from integer, only modulated
|
||||||
.ports
|
.ports
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
struc su_delayline_wrk
|
struc su_delayline_wrk
|
||||||
.time resd 1
|
|
||||||
.filtstate resd 1
|
|
||||||
.dcin resd 1
|
.dcin resd 1
|
||||||
.dcout resd 1
|
.dcout resd 1
|
||||||
|
.filtstate resd 1
|
||||||
.buffer resd MAX_DELAY
|
.buffer resd MAX_DELAY
|
||||||
.size
|
.size
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
; COMPRES effect related defines
|
; COMPRES effect related defines
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
@ -65,7 +65,7 @@ EXPORT MANGLE_FUNC(su_op_speed,0)
|
|||||||
fist dword [_SP] ; Main stack: k=int(t+2^p-1)
|
fist dword [_SP] ; Main stack: k=int(t+2^p-1)
|
||||||
fisub dword [_SP] ; t+2^p-1-k, the remainder
|
fisub dword [_SP] ; t+2^p-1-k, the remainder
|
||||||
pop _AX
|
pop _AX
|
||||||
add dword [_SP+su_stack.curtick], eax ; add the whole ticks to song tick count, [esp+24] is the current tick in the row
|
add dword [_SP+su_stack.rowtick], eax ; add the whole ticks to row tick count
|
||||||
fstp dword [WRK+su_speed_wrk.remainder] ; save the remainder for future
|
fstp dword [WRK+su_speed_wrk.remainder] ; save the remainder for future
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
%if BITS == 32
|
%if BITS == 32
|
||||||
%define BUFFER_STACK_LOC 44
|
%define BUFFER_STACK_LOC 48
|
||||||
%define render_prologue pushad ; stdcall & everything nonvolatile except eax, ecx, edx
|
%define render_prologue pushad ; stdcall & everything nonvolatile except eax, ecx, edx
|
||||||
%macro render_epilogue 0
|
%macro render_epilogue 0
|
||||||
popad
|
popad
|
||||||
ret 4 ; clean the passed parameter from stack.
|
ret 4 ; clean the passed parameter from stack.
|
||||||
%endmacro
|
%endmacro
|
||||||
%elifidn __OUTPUT_FORMAT__,win64
|
%elifidn __OUTPUT_FORMAT__,win64
|
||||||
%define BUFFER_STACK_LOC 48
|
%define BUFFER_STACK_LOC 56
|
||||||
%define render_prologue push_registers rcx,rdi,rsi,rbx,rbp ; rcx = ptr to buf. rdi,rsi,rbx,rbp nonvolatile
|
%define render_prologue push_registers rcx,rdi,rsi,rbx,rbp ; rcx = ptr to buf. rdi,rsi,rbx,rbp nonvolatile
|
||||||
%macro render_epilogue 0
|
%macro render_epilogue 0
|
||||||
pop_registers rcx,rdi,rsi,rbx,rbp
|
pop_registers rcx,rdi,rsi,rbx,rbp
|
||||||
ret
|
ret
|
||||||
%endmacro
|
%endmacro
|
||||||
%else ; 64 bit mac & linux
|
%else ; 64 bit mac & linux
|
||||||
%define BUFFER_STACK_LOC 48
|
%define BUFFER_STACK_LOC 40
|
||||||
%define render_prologue push_registers rdi,rbx,rbp ; rdi = ptr to buf. rbx & rbp nonvolatile
|
%define render_prologue push_registers rdi,rbx,rbp ; rdi = ptr to buf. rbx & rbp nonvolatile
|
||||||
%macro render_epilogue 0
|
%macro render_epilogue 0
|
||||||
pop_registers rdi,rbx,rbp
|
pop_registers rdi,rbx,rbp
|
||||||
@ -116,6 +116,7 @@ EXPORT MANGLE_FUNC(su_render,PTRSIZE) ; Stack: ptr
|
|||||||
call su_gmdls_load
|
call su_gmdls_load
|
||||||
%endif
|
%endif
|
||||||
xor eax, eax ; ecx is the current row
|
xor eax, eax ; ecx is the current row
|
||||||
|
push _AX ; global tick time
|
||||||
su_render_rowloop: ; loop through every row in the song
|
su_render_rowloop: ; loop through every row in the song
|
||||||
push _AX ; Stack: row pushad ptr
|
push _AX ; Stack: row pushad ptr
|
||||||
call su_update_voices ; update instruments for the new row
|
call su_update_voices ; update instruments for the new row
|
||||||
@ -125,6 +126,7 @@ su_render_sampleloop: ; loop through every sample in the row
|
|||||||
call MANGLE_FUNC(su_run_vm,0) ; run through the VM code
|
call MANGLE_FUNC(su_run_vm,0) ; run through the VM code
|
||||||
output_sound ; *ptr++ = left, *ptr++ = right
|
output_sound ; *ptr++ = left, *ptr++ = right
|
||||||
pop _AX ; Stack: row pushad ptr
|
pop _AX ; Stack: row pushad ptr
|
||||||
|
inc dword [_SP + PTRSIZE] ; increment global time, used by delays
|
||||||
inc eax
|
inc eax
|
||||||
cmp eax, SAMPLES_PER_ROW
|
cmp eax, SAMPLES_PER_ROW
|
||||||
jl su_render_sampleloop
|
jl su_render_sampleloop
|
||||||
@ -132,6 +134,7 @@ su_render_sampleloop: ; loop through every sample in the row
|
|||||||
inc eax
|
inc eax
|
||||||
cmp eax, TOTAL_ROWS
|
cmp eax, TOTAL_ROWS
|
||||||
jl su_render_rowloop
|
jl su_render_rowloop
|
||||||
|
pop _AX
|
||||||
render_epilogue
|
render_epilogue
|
||||||
|
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
pop %1
|
pop %1
|
||||||
%endrep
|
%endrep
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
%define PUSH_REG_SIZE(n) (n*8)
|
||||||
%else
|
%else
|
||||||
%define WRK ebp ; alias for unit workspace
|
%define WRK ebp ; alias for unit workspace
|
||||||
%define VAL esi ; alias for unit values (transformed/untransformed)
|
%define VAL esi ; alias for unit values (transformed/untransformed)
|
||||||
@ -91,6 +93,8 @@
|
|||||||
%macro pop_registers 1-*
|
%macro pop_registers 1-*
|
||||||
popad
|
popad
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
%define PUSH_REG_SIZE(n) 32
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
struc su_stack ; the structure of stack _as the units see it_
|
struc su_stack ; the structure of stack _as the units see it_
|
||||||
@ -99,8 +103,13 @@ struc su_stack ; the structure of stack _as the units see it_
|
|||||||
.wrk RESPTR 1
|
.wrk RESPTR 1
|
||||||
.val RESPTR 1
|
.val RESPTR 1
|
||||||
.com RESPTR 1
|
.com RESPTR 1
|
||||||
|
%if DELAY_ID > -1
|
||||||
|
.delaywrk RESPTR 1
|
||||||
|
%endif
|
||||||
.retaddrvm RESPTR 1
|
.retaddrvm RESPTR 1
|
||||||
.curtick RESPTR 1
|
.rowtick RESPTR 1 ; which tick within this row are we at
|
||||||
|
.row RESPTR 1 ; which total row of the song are we at
|
||||||
|
.tick RESPTR 1 ; which total tick of the song are we at
|
||||||
endstruc
|
endstruc
|
||||||
|
|
||||||
;===============================================================================
|
;===============================================================================
|
||||||
@ -157,6 +166,14 @@ su_polyphony_bitmask dd POLYPHONY_BITMASK ; does the next voice reuse th
|
|||||||
SECT_TEXT(surunvm)
|
SECT_TEXT(surunvm)
|
||||||
|
|
||||||
EXPORT MANGLE_FUNC(su_run_vm,0)
|
EXPORT MANGLE_FUNC(su_run_vm,0)
|
||||||
|
%if DELAY_ID > -1
|
||||||
|
%if BITS == 64 ; TODO: find a way to do this with a macro
|
||||||
|
mov _AX,PTRWORD MANGLE_DATA(su_delay_buffer-su_delayline_wrk.filtstate)
|
||||||
|
push _AX ; reset delaywrk to first delayline
|
||||||
|
%else
|
||||||
|
push PTRWORD MANGLE_DATA(su_delay_buffer-su_delayline_wrk.filtstate)
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
mov COM, PTRWORD MANGLE_DATA(su_commands) ; COM points to vm code
|
mov COM, PTRWORD MANGLE_DATA(su_commands) ; COM points to vm code
|
||||||
mov VAL, PTRWORD MANGLE_DATA(su_params) ; VAL points to unit params
|
mov VAL, PTRWORD MANGLE_DATA(su_params) ; VAL points to unit params
|
||||||
; su_unit.size will be added back before WRK is used
|
; su_unit.size will be added back before WRK is used
|
||||||
@ -164,15 +181,6 @@ EXPORT MANGLE_FUNC(su_run_vm,0)
|
|||||||
push COM ; Stack: COM
|
push COM ; Stack: COM
|
||||||
push VAL ; Stack: VAL COM
|
push VAL ; Stack: VAL COM
|
||||||
push WRK ; Stack: WRK VAL COM
|
push WRK ; Stack: WRK VAL COM
|
||||||
%if DELAY_ID > -1
|
|
||||||
%if BITS == 64 ; TODO: find a way to do this with a macro
|
|
||||||
mov r9,PTRWORD MANGLE_DATA(su_delay_buffer_ofs)
|
|
||||||
mov _AX,PTRWORD MANGLE_DATA(su_delay_buffer)
|
|
||||||
mov qword [r9],_AX ; reset delaywrk to first delayline
|
|
||||||
%else
|
|
||||||
mov dword [MANGLE_DATA(su_delay_buffer_ofs)],MANGLE_DATA(su_delay_buffer) ; reset delaywrk to first
|
|
||||||
%endif
|
|
||||||
%endif
|
|
||||||
xor ecx, ecx ; voice = 0
|
xor ecx, ecx ; voice = 0
|
||||||
push _CX ; Stack: voice WRK VAL COM
|
push _CX ; Stack: voice WRK VAL COM
|
||||||
su_run_vm_loop: ; loop until all voices done
|
su_run_vm_loop: ; loop until all voices done
|
||||||
|
@ -130,6 +130,7 @@ regression_test(test_delay_feedbackmod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND"
|
|||||||
regression_test(test_delay_pregainmod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
regression_test(test_delay_pregainmod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
||||||
regression_test(test_delay_dampmod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
regression_test(test_delay_dampmod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
||||||
regression_test(test_delay_drymod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
regression_test(test_delay_drymod "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
||||||
|
regression_test(test_delay_flanger "ENVELOPE;FOP_MULP;PANNING;VCO_SINE;SEND")
|
||||||
|
|
||||||
regression_test(test_envelope_mod "VCO_SINE;ENVELOPE;SEND")
|
regression_test(test_envelope_mod "VCO_SINE;ENVELOPE;SEND")
|
||||||
regression_test(test_envelope_16bit ENVELOPE "" test_envelope)
|
regression_test(test_envelope_16bit ENVELOPE "" test_envelope)
|
||||||
|
BIN
tests/expected_output/test_delay_flanger.raw
Normal file
BIN
tests/expected_output/test_delay_flanger.raw
Normal file
Binary file not shown.
Binary file not shown.
@ -16,7 +16,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(1)
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(1)
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_OUT STEREO, GAIN(128)
|
SU_OUT STEREO, GAIN(128)
|
||||||
SU_END_INSTRUMENT
|
SU_END_INSTRUMENT
|
||||||
|
@ -16,7 +16,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(1)
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(1)
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_OUT STEREO,GAIN(128)
|
SU_OUT STEREO,GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
||||||
|
@ -16,7 +16,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(1)
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(1)
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_OUT STEREO,GAIN(128)
|
SU_OUT STEREO,GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
||||||
|
@ -16,7 +16,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(1)
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(1)
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_OUT STEREO,GAIN(128)
|
SU_OUT STEREO,GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
||||||
|
32
tests/test_delay_flanger.asm
Normal file
32
tests/test_delay_flanger.asm
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
%define BPM 100
|
||||||
|
%define USE_SECTIONS
|
||||||
|
%define INCLUDE_DELAY_MODULATION
|
||||||
|
|
||||||
|
%include "../src/sointu.inc"
|
||||||
|
|
||||||
|
SU_BEGIN_PATTERNS
|
||||||
|
PATTERN 80, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD, 0, 0, 0, 0, 0
|
||||||
|
SU_END_PATTERNS
|
||||||
|
|
||||||
|
SU_BEGIN_TRACKS
|
||||||
|
TRACK VOICES(1),0
|
||||||
|
SU_END_TRACKS
|
||||||
|
|
||||||
|
SU_BEGIN_PATCH
|
||||||
|
SU_BEGIN_INSTRUMENT VOICES(1) ; Instrument0
|
||||||
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||||
|
SU_MULP MONO
|
||||||
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(0),DAMP(64),DELAY(0),COUNT(1)
|
||||||
|
SU_PAN MONO,PANNING(64)
|
||||||
|
SU_OUT STEREO,GAIN(128)
|
||||||
|
SU_OSCILLAT MONO,TRANSPOSE(50),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
||||||
|
SU_SEND MONO,AMOUNT(65),PORT(3,delay,delaymod) + SEND_POP
|
||||||
|
SU_END_INSTRUMENT
|
||||||
|
SU_END_PATCH
|
||||||
|
|
||||||
|
SU_BEGIN_DELTIMES
|
||||||
|
DELTIME 1000
|
||||||
|
SU_END_DELTIMES
|
||||||
|
|
||||||
|
%include "../src/sointu.asm"
|
@ -20,7 +20,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(64),SHAPE(127),GAIN(64),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(64),SHAPE(127),GAIN(64),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_FILTER MONO,FREQUENCY(32),RESONANCE(128),FLAGS(LOWPASS + BANDPASS + HIGHPASS)
|
SU_FILTER MONO,FREQUENCY(32),RESONANCE(128),FLAGS(LOWPASS + BANDPASS + HIGHPASS)
|
||||||
SU_DELAY MONO,PREGAIN(128),DRY(128),FEEDBACK(128),DAMP(16),DELAY(0),COUNT(1)
|
SU_DELAY MONO,PREGAIN(128),DRY(128),FEEDBACK(128),DAMP(16),DELAY(0),COUNT(1) + NOTETRACKING
|
||||||
SU_FILTER MONO,FREQUENCY(24),RESONANCE(128),FLAGS(LOWPASS + BANDPASS + HIGHPASS)
|
SU_FILTER MONO,FREQUENCY(24),RESONANCE(128),FLAGS(LOWPASS + BANDPASS + HIGHPASS)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
@ -29,6 +29,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_END_PATCH
|
SU_END_PATCH
|
||||||
|
|
||||||
SU_BEGIN_DELTIMES
|
SU_BEGIN_DELTIMES
|
||||||
|
DELTIME 10787
|
||||||
SU_END_DELTIMES
|
SU_END_DELTIMES
|
||||||
|
|
||||||
%include "../src/sointu.asm"
|
%include "../src/sointu.asm"
|
@ -16,7 +16,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(1)
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(1)
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_OUT STEREO,GAIN(128)
|
SU_OUT STEREO,GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
SU_OSCILLAT MONO,TRANSPOSE(70),DETUNE(64),PHASE(64),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE+LFO)
|
||||||
|
@ -16,7 +16,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
SU_ENVELOPE MONO,ATTAC(80),DECAY(80),SUSTAIN(64),RELEASE(80),GAIN(128)
|
||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(9)
|
SU_DELAY MONO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(8)
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_OUT STEREO, GAIN(128)
|
SU_OUT STEREO, GAIN(128)
|
||||||
SU_END_INSTRUMENT
|
SU_END_INSTRUMENT
|
||||||
|
@ -17,7 +17,7 @@ SU_BEGIN_PATCH
|
|||||||
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
SU_OSCILLAT MONO,TRANSPOSE(64),DETUNE(64),PHASE(0),COLOR(128),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||||
SU_MULP MONO
|
SU_MULP MONO
|
||||||
SU_PAN MONO,PANNING(64)
|
SU_PAN MONO,PANNING(64)
|
||||||
SU_DELAY STEREO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(1),COUNT(1)
|
SU_DELAY STEREO,PREGAIN(40),DRY(128),FEEDBACK(125),DAMP(64),DELAY(0),COUNT(1)
|
||||||
SU_OUT STEREO, GAIN(128)
|
SU_OUT STEREO, GAIN(128)
|
||||||
SU_END_INSTRUMENT
|
SU_END_INSTRUMENT
|
||||||
SU_END_PATCH
|
SU_END_PATCH
|
||||||
@ -27,5 +27,4 @@ SU_BEGIN_DELTIMES
|
|||||||
DELTIME 21025
|
DELTIME 21025
|
||||||
SU_END_DELTIMES
|
SU_END_DELTIMES
|
||||||
|
|
||||||
%include "../src/sointu.asm"
|
%include "../src/sointu.asm"
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user