mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
fix(asm/wasm): oscillator phase was causing rounding errors once large enough
gopher had fixed this, but we foolishly removed it. reintroducing fix, although this could be optional only for those who really care. ultimate size optimizers could still want to get rid of it.
This commit is contained in:
parent
7974f0ff82
commit
c02c5c3c3d
@ -172,20 +172,31 @@ su_op_oscillat_normalize_note:
|
||||
fmul dword [{{.Float 0.000092696138 | .Use}}] ; // st0 is now frequency
|
||||
su_op_oscillat_normalized:
|
||||
fadd dword [{{.WRK}}]
|
||||
fst dword [{{.WRK}}]
|
||||
fadd dword [{{.Input "oscillator" "phase"}}]
|
||||
{{- if .SupportsParamValue "oscillator" "type" .Sample}}
|
||||
test al, byte 0x80
|
||||
jz short su_op_oscillat_not_sample
|
||||
fst dword [{{.WRK}}] ; for samples, we store the phase without mod(p,1)
|
||||
{{- if or (.SupportsParamValueOtherThan "oscillator" "phase" 0) (.SupportsModulation "oscillator" "phase")}}
|
||||
fadd dword [{{.Input "oscillator" "phase"}}]
|
||||
{{- end}}
|
||||
{{.Call "su_oscillat_sample"}}
|
||||
jmp su_op_oscillat_shaping ; skip the rest to avoid color phase normalization and colorloading
|
||||
su_op_oscillat_not_sample:
|
||||
{{- end}}
|
||||
fld1
|
||||
fadd st1, st0
|
||||
fld1 ; we need to take mod(p,1) so the frequency does not drift as the float
|
||||
fadd st1, st0 ; make no mistake: without this, there is audible drifts in oscillator pitch
|
||||
fxch ; as the actual period changes once the phase becomes too big
|
||||
fprem ; we actually computed mod(p+1,1) instead of mod(p,1) as the fprem takes mod
|
||||
fstp st1 ; towards zero
|
||||
fst dword [{{.WRK}}] ; store back the updated phase
|
||||
{{- if or (.SupportsParamValueOtherThan "oscillator" "phase" 0) (.SupportsModulation "oscillator" "phase")}}
|
||||
fadd dword [{{.Input "oscillator" "phase"}}]
|
||||
fld1 ; this is a bit stupid, but we need to take mod(x,1) again after phase modulations
|
||||
fadd st1, st0 ; as the actual oscillator functions expect x in [0,1]
|
||||
fxch
|
||||
fprem
|
||||
fstp st1
|
||||
{{- end}}
|
||||
fld dword [{{.Input "oscillator" "color"}}] ; // c p
|
||||
; every oscillator test included if needed
|
||||
{{- if .SupportsParamValue "oscillator" "type" .Sine}}
|
||||
|
@ -121,27 +121,34 @@
|
||||
{{- end}}
|
||||
(f32.store ;; update phase
|
||||
(global.get $WRK)
|
||||
;; Transpose calculation starts
|
||||
(f32.div
|
||||
(call $inputSigned (i32.const {{.InputNumber "oscillator" "transpose"}}))
|
||||
(f32.const 0.015625)
|
||||
) ;; scale back to 0 - 128
|
||||
(f32.add (local.get $detune)) ;; add detune. detune is -1 to 1 so can detune a full note up or down at max
|
||||
(f32.add (select
|
||||
(f32.const 0)
|
||||
(f32.convert_i32_u (i32.load (global.get $voice)))
|
||||
(i32.and (local.get $flags) (i32.const 0x8))
|
||||
)) ;; if lfo is not enabled, add the note number to it
|
||||
(f32.mul (f32.const 0.0833333)) ;; /12, in full octaves
|
||||
(call $pow2)
|
||||
(f32.mul (select
|
||||
(f32.const 0.000038) ;; pretty random scaling constant to get LFOs into reasonable range. Historical reasons, goes all the way back to 4klang
|
||||
(f32.const 0.000092696138) ;; scaling constant to get middle-C to where it should be
|
||||
(i32.and (local.get $flags) (i32.const 0x8))
|
||||
))
|
||||
(f32.add (f32.load (global.get $WRK))) ;; add the current phase of the oscillator
|
||||
(local.tee $phase
|
||||
(f32.sub
|
||||
(local.tee $phase
|
||||
;; Transpose calculation starts
|
||||
(f32.div
|
||||
(call $inputSigned (i32.const {{.InputNumber "oscillator" "transpose"}}))
|
||||
(f32.const 0.015625)
|
||||
) ;; scale back to 0 - 128
|
||||
(f32.add (local.get $detune)) ;; add detune. detune is -1 to 1 so can detune a full note up or down at max
|
||||
(f32.add (select
|
||||
(f32.const 0)
|
||||
(f32.convert_i32_u (i32.load (global.get $voice)))
|
||||
(i32.and (local.get $flags) (i32.const 0x8))
|
||||
)) ;; if lfo is not enabled, add the note number to it
|
||||
(f32.mul (f32.const 0.0833333)) ;; /12, in full octaves
|
||||
(call $pow2)
|
||||
(f32.mul (select
|
||||
(f32.const 0.000038) ;; pretty random scaling constant to get LFOs into reasonable range. Historical reasons, goes all the way back to 4klang
|
||||
(f32.const 0.000092696138) ;; scaling constant to get middle-C to where it should be
|
||||
(i32.and (local.get $flags) (i32.const 0x8))
|
||||
))
|
||||
(f32.add (f32.load (global.get $WRK))) ;; add the current phase of the oscillator
|
||||
)
|
||||
(f32.floor (local.get $phase))
|
||||
)
|
||||
)
|
||||
)
|
||||
(f32.add (f32.load (global.get $WRK)) (call $input (i32.const {{.InputNumber "oscillator" "phase"}})))
|
||||
(f32.add (local.get $phase) (call $input (i32.const {{.InputNumber "oscillator" "phase"}})))
|
||||
(local.set $phase (f32.sub (local.tee $phase) (f32.floor (local.get $phase)))) ;; phase = phase mod 1.0
|
||||
(local.set $color (call $input (i32.const {{.InputNumber "oscillator" "color"}})))
|
||||
{{- if .SupportsParamValue "oscillator" "type" .Sine}}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -85,7 +85,7 @@ if (process.argv.length <= 3) {
|
||||
}
|
||||
errorCount++
|
||||
}
|
||||
if (errorCount > 100) {
|
||||
if (errorCount > 200) {
|
||||
console.error("got different buffer than expected. First error at: "+(firstErrorPos/2|0)+(firstErrorPos%1," right"," left"));
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user