mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
feat(vm): add dbgain unit, where gain is defined in decibels
Closes #78
This commit is contained in:
parent
f698986718
commit
04fbc9f6a7
@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
- Dbgain unit, which allows defining the gain in decibels (-40 dB to +40dB)
|
||||||
|
|
||||||
## v0.3.0
|
## v0.3.0
|
||||||
### Added
|
### Added
|
||||||
- Scroll bars to menus, shown when a menu is too long to fit.
|
- Scroll bars to menus, shown when a menu is too long to fit.
|
||||||
|
8
patch.go
8
patch.go
@ -82,6 +82,9 @@ var UnitTypes = map[string]([]UnitParameter){
|
|||||||
"invgain": []UnitParameter{
|
"invgain": []UnitParameter{
|
||||||
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
|
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
|
||||||
{Name: "invgain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
|
{Name: "invgain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
|
||||||
|
"dbgain": []UnitParameter{
|
||||||
|
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
|
||||||
|
{Name: "decibels", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
|
||||||
"filter": []UnitParameter{
|
"filter": []UnitParameter{
|
||||||
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
|
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
|
||||||
{Name: "frequency", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
|
{Name: "frequency", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
|
||||||
@ -494,6 +497,11 @@ func (p Patch) ParamHintString(instrIndex, unitIndex int, param string) string {
|
|||||||
return "aux3 right"
|
return "aux3 right"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "dbgain":
|
||||||
|
switch param {
|
||||||
|
case "decibels":
|
||||||
|
return fmt.Sprintf("%.2f dB", 40*(float32(value)/64-1))
|
||||||
|
}
|
||||||
case "crush":
|
case "crush":
|
||||||
switch param {
|
switch param {
|
||||||
case "resolution":
|
case "resolution":
|
||||||
|
@ -72,6 +72,8 @@ regression_test(test_gain LOADVAL GAIN)
|
|||||||
regression_test(test_gain_stereo GAIN)
|
regression_test(test_gain_stereo GAIN)
|
||||||
regression_test(test_invgain LOADVAL INVGAIN)
|
regression_test(test_invgain LOADVAL INVGAIN)
|
||||||
regression_test(test_invgain_stereo INVGAIN)
|
regression_test(test_invgain_stereo INVGAIN)
|
||||||
|
regression_test(test_dbgain LOADVAL DBGAIN)
|
||||||
|
regression_test(test_dbgain_stereo DBGAIN)
|
||||||
regression_test(test_send LOADVAL SEND)
|
regression_test(test_send LOADVAL SEND)
|
||||||
regression_test(test_send_stereo SEND)
|
regression_test(test_send_stereo SEND)
|
||||||
regression_test(test_send_global SEND SEND_GLOBAL)
|
regression_test(test_send_global SEND SEND_GLOBAL)
|
||||||
|
1
tests/expected_output/test_dbgain.raw
Normal file
1
tests/expected_output/test_dbgain.raw
Normal file
File diff suppressed because one or more lines are too long
1
tests/expected_output/test_dbgain_stereo.raw
Normal file
1
tests/expected_output/test_dbgain_stereo.raw
Normal file
File diff suppressed because one or more lines are too long
22
tests/test_dbgain.yml
Normal file
22
tests/test_dbgain.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
bpm: 100
|
||||||
|
rowsperbeat: 4
|
||||||
|
score:
|
||||||
|
rowsperpattern: 16
|
||||||
|
length: 1
|
||||||
|
tracks:
|
||||||
|
- numvoices: 1
|
||||||
|
order: [0]
|
||||||
|
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||||
|
patch:
|
||||||
|
- numvoices: 1
|
||||||
|
units:
|
||||||
|
- type: loadval
|
||||||
|
parameters: {stereo: 0, value: 0}
|
||||||
|
- type: dbgain
|
||||||
|
parameters: {decibels: 32, stereo: 0}
|
||||||
|
- type: loadval
|
||||||
|
parameters: {stereo: 0, value: 128}
|
||||||
|
- type: dbgain
|
||||||
|
parameters: {decibels: 32, stereo: 0}
|
||||||
|
- type: out
|
||||||
|
parameters: {gain: 128, stereo: 1}
|
20
tests/test_dbgain_stereo.yml
Normal file
20
tests/test_dbgain_stereo.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
bpm: 100
|
||||||
|
rowsperbeat: 4
|
||||||
|
score:
|
||||||
|
rowsperpattern: 16
|
||||||
|
length: 1
|
||||||
|
tracks:
|
||||||
|
- numvoices: 1
|
||||||
|
order: [0]
|
||||||
|
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||||
|
patch:
|
||||||
|
- numvoices: 1
|
||||||
|
units:
|
||||||
|
- type: loadval
|
||||||
|
parameters: {stereo: 0, value: 0}
|
||||||
|
- type: loadval
|
||||||
|
parameters: {stereo: 0, value: 128}
|
||||||
|
- type: dbgain
|
||||||
|
parameters: {decibels: 32, stereo: 1}
|
||||||
|
- type: out
|
||||||
|
parameters: {gain: 128, stereo: 1}
|
@ -49,6 +49,7 @@ var defaultUnits = map[string]sointu.Unit{
|
|||||||
"pan": {Type: "pan", Parameters: map[string]int{"stereo": 0, "panning": 64}},
|
"pan": {Type: "pan", Parameters: map[string]int{"stereo": 0, "panning": 64}},
|
||||||
"gain": {Type: "gain", Parameters: map[string]int{"stereo": 0, "gain": 64}},
|
"gain": {Type: "gain", Parameters: map[string]int{"stereo": 0, "gain": 64}},
|
||||||
"invgain": {Type: "invgain", Parameters: map[string]int{"stereo": 0, "invgain": 64}},
|
"invgain": {Type: "invgain", Parameters: map[string]int{"stereo": 0, "invgain": 64}},
|
||||||
|
"dbgain": {Type: "dbgain", Parameters: map[string]int{"stereo": 0, "decibels": 64}},
|
||||||
"crush": {Type: "crush", Parameters: map[string]int{"stereo": 0, "resolution": 64}},
|
"crush": {Type: "crush", Parameters: map[string]int{"stereo": 0, "resolution": 64}},
|
||||||
"clip": {Type: "clip", Parameters: map[string]int{"stereo": 0}},
|
"clip": {Type: "clip", Parameters: map[string]int{"stereo": 0}},
|
||||||
"hold": {Type: "hold", Parameters: map[string]int{"stereo": 0, "holdfreq": 64}},
|
"hold": {Type: "hold", Parameters: map[string]int{"stereo": 0, "holdfreq": 64}},
|
||||||
|
@ -98,6 +98,41 @@ su_op_invgain_mono:
|
|||||||
{{- end}}
|
{{- end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{- if .HasOp "dbgain"}}
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; DBGAIN opcode: apply gain on the signal, with gain given in decibels
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; Mono: x -> x*g, where g = 2**((2*d-1)*6.643856189774724) i.e. -40dB to 40dB, d=[0..1]
|
||||||
|
; Stereo: l r -> l*g r*g
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
{{.Func "su_op_dbgain" "Opcode"}}
|
||||||
|
{{- if .Stereo "dbgain"}}
|
||||||
|
fld dword [{{.Input "dbgain" "decibels"}}] ; d l r
|
||||||
|
{{- .Prepare (.Float 0.5)}}
|
||||||
|
fsub dword [{{.Use (.Float 0.5)}}] ; d-.5
|
||||||
|
fadd st0, st0 ; 2*d-1
|
||||||
|
{{- .Prepare (.Float 6.643856189774724)}}
|
||||||
|
fmul dword [{{.Use (.Float 6.643856189774724)}}] ; (2*d-1)*6.643856189774724
|
||||||
|
{{.Call "su_power"}}
|
||||||
|
{{- if .Mono "dbgain"}}
|
||||||
|
jnc su_op_dbgain_mono
|
||||||
|
{{- end}}
|
||||||
|
fmul st2, st0 ; g l r/g
|
||||||
|
su_op_dbgain_mono:
|
||||||
|
fmulp st1, st0 ; l/g (r/)
|
||||||
|
ret
|
||||||
|
{{- else}}
|
||||||
|
fld dword [{{.Input "dbgain" "decibels"}}] ; d l
|
||||||
|
{{- .Prepare (.Float 0.5)}}
|
||||||
|
fsub dword [{{.Use (.Float 0.5)}}] ; d-.5
|
||||||
|
fadd st0, st0 ; 2*d-1
|
||||||
|
{{- .Prepare (.Float 6.643856189774724)}}
|
||||||
|
fmul dword [{{.Use (.Float 6.643856189774724)}}] ; (2*d-1)*6.643856189774724
|
||||||
|
{{.Call "su_power"}}
|
||||||
|
fmulp st1, st0
|
||||||
|
ret
|
||||||
|
{{- end}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
{{- if .HasOp "filter"}}
|
{{- if .HasOp "filter"}}
|
||||||
;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
||||||
|
@ -98,6 +98,26 @@
|
|||||||
)
|
)
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
{{- if .HasOp "dbgain"}}
|
||||||
|
;;-------------------------------------------------------------------------------
|
||||||
|
;; DBGAIN opcode: apply gain on the signal, with gain given in decibels
|
||||||
|
;;-------------------------------------------------------------------------------
|
||||||
|
;; Mono: x -> x*g, where g = 2**((2*d-1)*6.643856189774724) i.e. -40dB to 40dB, d=[0..1]
|
||||||
|
;; Stereo: l r -> l*g r*g
|
||||||
|
;;-------------------------------------------------------------------------------
|
||||||
|
(func $su_op_dbgain (param $stereo i32)
|
||||||
|
{{- if .Stereo "dbgain"}}
|
||||||
|
(call $stereoHelper (local.get $stereo) (i32.const {{div (.GetOp "dbgain") 2}}))
|
||||||
|
{{- end}}
|
||||||
|
(call $input (i32.const {{.InputNumber "dbgain" "decibels"}}))
|
||||||
|
(f32.sub (f32.const 0.5))
|
||||||
|
(f32.mul (f32.const 13.287712379549449))
|
||||||
|
(call $pow2)
|
||||||
|
(f32.mul (call $pop))
|
||||||
|
(call $push)
|
||||||
|
)
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
|
||||||
{{- if .HasOp "filter"}}
|
{{- if .HasOp "filter"}}
|
||||||
;;-------------------------------------------------------------------------------
|
;;-------------------------------------------------------------------------------
|
||||||
|
@ -346,6 +346,12 @@ func (s *GoSynth) Render(buffer sointu.AudioBuffer, maxtime int) (samples int, t
|
|||||||
stack[l-2] /= params[0]
|
stack[l-2] /= params[0]
|
||||||
}
|
}
|
||||||
stack[l-1] /= params[0]
|
stack[l-1] /= params[0]
|
||||||
|
case opDbgain:
|
||||||
|
gain := float32(math.Pow(2, float64(params[0]*2-1)*6.643856189774724))
|
||||||
|
if stereo {
|
||||||
|
stack[l-2] *= gain
|
||||||
|
}
|
||||||
|
stack[l-1] *= gain
|
||||||
case opClip:
|
case opClip:
|
||||||
if stereo {
|
if stereo {
|
||||||
stack[l-2] = clip(stack[l-2])
|
stack[l-2] = clip(stack[l-2])
|
||||||
|
@ -8,30 +8,31 @@ const (
|
|||||||
opClip = 4
|
opClip = 4
|
||||||
opCompressor = 5
|
opCompressor = 5
|
||||||
opCrush = 6
|
opCrush = 6
|
||||||
opDelay = 7
|
opDbgain = 7
|
||||||
opDistort = 8
|
opDelay = 8
|
||||||
opEnvelope = 9
|
opDistort = 9
|
||||||
opFilter = 10
|
opEnvelope = 10
|
||||||
opGain = 11
|
opFilter = 11
|
||||||
opHold = 12
|
opGain = 12
|
||||||
opIn = 13
|
opHold = 13
|
||||||
opInvgain = 14
|
opIn = 14
|
||||||
opLoadnote = 15
|
opInvgain = 15
|
||||||
opLoadval = 16
|
opLoadnote = 16
|
||||||
opMul = 17
|
opLoadval = 17
|
||||||
opMulp = 18
|
opMul = 18
|
||||||
opNoise = 19
|
opMulp = 19
|
||||||
opOscillator = 20
|
opNoise = 20
|
||||||
opOut = 21
|
opOscillator = 21
|
||||||
opOutaux = 22
|
opOut = 22
|
||||||
opPan = 23
|
opOutaux = 23
|
||||||
opPop = 24
|
opPan = 24
|
||||||
opPush = 25
|
opPop = 25
|
||||||
opReceive = 26
|
opPush = 26
|
||||||
opSend = 27
|
opReceive = 27
|
||||||
opSpeed = 28
|
opSend = 28
|
||||||
opSync = 29
|
opSpeed = 29
|
||||||
opXch = 30
|
opSync = 30
|
||||||
|
opXch = 31
|
||||||
)
|
)
|
||||||
|
|
||||||
var transformCounts = [...]int{0, 0, 1, 0, 5, 1, 4, 1, 5, 2, 1, 1, 0, 1, 0, 1, 0, 0, 2, 6, 1, 2, 1, 0, 0, 0, 1, 0, 0, 0}
|
var transformCounts = [...]int{0, 0, 1, 0, 5, 1, 1, 4, 1, 5, 2, 1, 1, 0, 1, 0, 1, 0, 0, 2, 6, 1, 2, 1, 0, 0, 0, 1, 0, 0, 0}
|
||||||
|
Loading…
Reference in New Issue
Block a user