fix(vm)!: first modulate delay time, then notetracking

BREAKING CHANGE: the order of these operations was inconsistent
across the different VMs. Go VM was the only one to first modulate
and then apply note tracking multiplication. But that made most
sense. So now all different VM versions work in this same way.
This commit is contained in:
5684185+vsariola@users.noreply.github.com
2025-04-16 23:17:08 +03:00
parent 78fc6302a0
commit 95af8da939
6 changed files with 73 additions and 19 deletions

View File

@ -309,6 +309,12 @@ su_op_delay_mono: ; flow into mono delay
su_op_delay_loop:
{{- if or (.SupportsModulation "delay" "delaytime") (.SupportsParamValue "delay" "notetracking" 1)}} ; delaytime modulation or note syncing require computing the delay time in floats
fild word [{{.BX}}] ; k dr*y p*p*x, where k = delay time
{{- if .SupportsModulation "delay" "delaytime"}}
fld dword [{{.Modulation "delay" "delaytime"}}]
{{- .Float 32767.0 | .Prepare | indent 8}}
fmul dword [{{.Float 32767.0 | .Use}}] ; scale it up, as the modulations would be too small otherwise
faddp st1, st0
{{- end}}
{{- if .SupportsParamValue "delay" "notetracking" 1}}
test ah, 1 ; note syncing is the least significant bit of ah, 0 = ON, 1 = OFF
jne su_op_delay_skipnotesync
@ -319,12 +325,6 @@ su_op_delay_loop:
fdivp st1, st0 ; use 10787 for delaytime to have neutral transpose
su_op_delay_skipnotesync:
{{- end}}
{{- if .SupportsModulation "delay" "delaytime"}}
fld dword [{{.Modulation "delay" "delaytime"}}]
{{- .Float 32767.0 | .Prepare | indent 8}}
fmul dword [{{.Float 32767.0 | .Use}}] ; scale it up, as the modulations would be too small otherwise
faddp st1, st0
{{- end}}
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

View File

@ -295,10 +295,23 @@
(i32.sub ;; globalTick-delaytimes[delayIndex]
(global.get $globaltick)
{{- if or (.SupportsModulation "delay" "delaytime") (.SupportsParamValue "delay" "notetracking" 1)}} ;; delaytime modulation or note syncing require computing the delay time in floats
{{- if .SupportsModulation "delay" "delaytime"}}
(local.set $delayTime (f32.add
(f32.convert_i32_u (i32.load16_u
offset={{index .Labels "su_delay_times"}}
(local.get $delayIndex)
))
(f32.mul
(f32.load offset={{.InputNumber "delay" "delaytime" | mul 4 | add 32}} (global.get $WRK))
(f32.const 32767)
)
))
{{- else}}
(local.set $delayTime (f32.convert_i32_u (i32.load16_u
offset={{index .Labels "su_delay_times"}}
(local.get $delayIndex)
)))
{{- end}}
{{- if .SupportsParamValue "delay" "notetracking" 1}}
(if (i32.eqz (i32.and (local.get $delayCount) (i32.const 1)))(then
(local.set $delayTime (f32.div
@ -312,20 +325,7 @@
))
))
{{- end}}
{{- if .SupportsModulation "delay" "delaytime"}}
(i32.trunc_f32_s (f32.add
(f32.add
(local.get $delayTime)
(f32.mul
(f32.load offset={{.InputNumber "delay" "delaytime" | mul 4 | add 32}} (global.get $WRK))
(f32.const 32767)
)
)
(f32.const 0.5)
))
{{- else}}
(i32.trunc_f32_s (f32.add (local.get $delayTime) (f32.const 0.5)))
{{- end}}
{{- else}}
(i32.load16_u
offset={{index .Labels "su_delay_times"}}