sointu/vm/compiler/templates/wasm/sinks.wat
5684185+vsariola@users.noreply.github.com 01bf409929 refactor(vm): rename Commands/Values to Opcodes/Operands
The commands and values were not very good names to what the
byte sequences actually are: opcodes and their operands. In
many other places, we were already calling the byte in the Command
stream as Opcode, so a logical name for a sequence of these is
Opcodes. Values is such a generic name that it's not immediately
clear that this sequence is related to the opcodes. Operands is not
perfect but clearly suggests that this sequence is related to
the Opcodes.
2023-10-18 19:53:47 +03:00

207 lines
7.2 KiB
Plaintext

{{- if .HasOp "outaux"}}
;;-------------------------------------------------------------------------------
;; OUTAUX opcode: outputs to main and aux1 outputs and pops the signal
;;-------------------------------------------------------------------------------
;; Mono: add outgain*ST0 to main left port and auxgain*ST0 to aux1 left
;; Stereo: also add outgain*ST1 to main right port and auxgain*ST1 to aux1 right
;;-------------------------------------------------------------------------------
(func $su_op_outaux (param $stereo i32) (local $addr i32)
(local.set $addr (i32.const {{index .Labels "su_globalports"}}))
{{- if .Stereo "outaux"}}
loop $stereoLoop
{{- end}}
(f32.store ;; send
(local.get $addr)
(f32.add
(f32.mul
(call $peek)
(call $input (i32.const {{.InputNumber "outaux" "outgain"}}))
)
(f32.load (local.get $addr))
)
)
(f32.store offset=8
(local.get $addr)
(f32.add
(f32.mul
(call $pop)
(call $input (i32.const {{.InputNumber "outaux" "auxgain"}}))
)
(f32.load offset=8 (local.get $addr))
)
)
{{- if .Stereo "outaux"}}
(local.set $addr (i32.add (local.get $addr) (i32.const 4)))
(br_if $stereoLoop (i32.eqz (local.tee $stereo (i32.eqz (local.get $stereo)))))
end
{{- end}}
)
{{end}}
{{- if .HasOp "aux"}}
;;-------------------------------------------------------------------------------
;; AUX opcode: outputs the signal to aux (or main) port and pops the signal
;;-------------------------------------------------------------------------------
;; Mono: add gain*ST0 to left port
;; Stereo: also add gain*ST1 to right port
;;-------------------------------------------------------------------------------
(func $su_op_aux (param $stereo i32) (local $addr i32)
(local.set $addr (i32.add (i32.mul (call $scanOperand) (i32.const 4)) (i32.const {{index .Labels "su_globalports"}})))
{{- if .Stereo "aux"}}
loop $stereoLoop
{{- end}}
(f32.store
(local.get $addr)
(f32.add
(f32.mul
(call $pop)
(call $input (i32.const {{.InputNumber "aux" "gain"}}))
)
(f32.load (local.get $addr))
)
)
{{- if .Stereo "aux"}}
(local.set $addr (i32.add (local.get $addr) (i32.const 4)))
(br_if $stereoLoop (i32.eqz (local.tee $stereo (i32.eqz (local.get $stereo)))))
end
{{- end}}
)
{{end}}
{{- if .HasOp "send"}}
;;-------------------------------------------------------------------------------
;; SEND opcode: adds the signal to a port
;;-------------------------------------------------------------------------------
;; Mono: adds signal to a memory address, defined by a word in VAL stream
;; Stereo: also add right signal to the following address
;;-------------------------------------------------------------------------------
(func $su_op_send (param $stereo i32) (local $address i32) (local $scaledAddress i32)
(local.set $address (i32.add (call $scanOperand) (i32.shl (call $scanOperand) (i32.const 8))))
(if (i32.eqz (i32.and (local.get $address) (i32.const 8)))(then
{{- if .Stereo "send"}}
(if (local.get $stereo)(then
(call $push (call $peek2))
(call $push (call $peek2))
)(else
{{- end}}
(call $push (call $peek))
{{- if .Stereo "send"}}
))
{{- end}}
))
{{- if .Stereo "send"}}
loop $stereoLoop
{{- end}}
(local.set $scaledAddress (i32.add (i32.mul (i32.and (local.get $address) (i32.const 0x7FF7)) (i32.const 4))
{{- if .SupportsGlobalSend}}
(select
(i32.const {{index .Labels "su_synth"}})
{{- end}}
(global.get $voice)
{{- if .SupportsGlobalSend}}
(i32.and (local.get $address)(i32.const 0x8000))
)
{{- end}}
))
(f32.store offset=32
(local.get $scaledAddress)
(f32.add
(f32.load offset=32 (local.get $scaledAddress))
(f32.mul
(call $inputSigned (i32.const {{.InputNumber "send" "amount"}}))
(call $pop)
)
)
)
{{- if .Stereo "send"}}
(local.set $address (i32.add (local.get $address) (i32.const 1)))
(br_if $stereoLoop (i32.eqz (local.tee $stereo (i32.eqz (local.get $stereo)))))
end
{{- end}}
)
{{end}}
{{- if .HasOp "out"}}
;;-------------------------------------------------------------------------------
;; OUT opcode: outputs and pops the signal
;;-------------------------------------------------------------------------------
{{- if .Mono "out"}}
;; Mono: add ST0 to main left port, then pop
{{- end}}
{{- if .Stereo "out"}}
;; Stereo: add ST0 to left out and ST1 to right out, then pop
{{- end}}
;;-------------------------------------------------------------------------------
(func $su_op_out (param $stereo i32) (local $ptr i32)
(local.set $ptr (i32.const {{index .Labels "su_globalports"}})) ;; synth.left
(f32.store (local.get $ptr)
(f32.add
(f32.mul
(call $pop)
(call $input (i32.const {{.InputNumber "out" "gain"}}))
)
(f32.load (local.get $ptr))
)
)
{{- if .StereoAndMono "out"}}
(if (local.get $stereo)(then
{{- end}}
{{- if .Stereo "out"}}
(local.set $ptr (i32.const {{add (index .Labels "su_globalports") 4}})) ;; synth.right
(f32.store (local.get $ptr)
(f32.add
(f32.mul
(call $pop)
(call $input (i32.const {{.InputNumber "out" "gain"}}))
)
(f32.load (local.get $ptr))
)
)
{{- end}}
{{- if .StereoAndMono "out"}}
))
{{- end}}
)
{{end}}
{{- if .HasOp "speed"}}
;;-------------------------------------------------------------------------------
;; SPEED opcode: modulate the speed (bpm) of the song based on ST0
;;-------------------------------------------------------------------------------
;; Mono: adds or subtracts the ticks, a value of 0.5 is neutral & will7
;; result in no speed change.
;; There is no STEREO version.
;;-------------------------------------------------------------------------------
(func $su_op_speed (param $stereo i32) (local $r f32) (local $w i32)
(f32.store
(global.get $WRK)
(local.tee $r
(f32.sub
(local.tee $r
(f32.add
(f32.load (global.get $WRK))
(f32.sub
(call $pow2
(f32.mul
(call $pop)
(f32.const 2.206896551724138)
)
)
(f32.const 1)
)
)
)
(f32.convert_i32_s
(local.tee $w (i32.trunc_f32_s (local.get $r))) ;; note: small difference from x86, as this is trunc; x86 rounds to nearest)
)
)
)
)
(global.set $sample (i32.add (global.get $sample) (local.get $w)))
)
{{end}}