mirror of
https://github.com/vsariola/sointu.git
synced 2026-04-01 03:33:12 -04:00
feat: envelopexp ported to go synth
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/vsariola/sointu/cmd"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -14,7 +15,6 @@ import (
|
|||||||
"github.com/vsariola/sointu"
|
"github.com/vsariola/sointu"
|
||||||
"github.com/vsariola/sointu/oto"
|
"github.com/vsariola/sointu/oto"
|
||||||
"github.com/vsariola/sointu/version"
|
"github.com/vsariola/sointu/version"
|
||||||
"github.com/vsariola/sointu/vm/compiler/bridge"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -93,7 +93,7 @@ func main() {
|
|||||||
return fmt.Errorf("the song could not be parsed as .json (%v) or .yml (%v)", errJSON, errYaml)
|
return fmt.Errorf("the song could not be parsed as .json (%v) or .yml (%v)", errJSON, errYaml)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer, err := sointu.Play(bridge.NativeSynther{}, song, nil) // render the song to calculate its length
|
buffer, err := sointu.Play(cmd.MainSynther, song, nil) // render the song to calculate its length
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("sointu.Play failed: %v", err)
|
return fmt.Errorf("sointu.Play failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -330,25 +330,27 @@ func (s *GoSynth) Render(buffer sointu.AudioBuffer, maxtime int) (samples int, t
|
|||||||
stack = append(stack, output)
|
stack = append(stack, output)
|
||||||
}
|
}
|
||||||
case opEnvelopexp:
|
case opEnvelopexp:
|
||||||
// TODO @qm210 - for now, this just clones the envelope so everything is wired up, but IT IS NOT IMPLEMENTED YET
|
|
||||||
// is ignoring for now
|
|
||||||
// - params[1] - attack shape parameter (center value should mean "linear")
|
|
||||||
// - params[3] - decay shape parameter (center value should mean "linear")
|
|
||||||
if !voices[0].sustain {
|
if !voices[0].sustain {
|
||||||
unit.state[0] = envStateRelease // set state to release
|
unit.state[0] = envStateRelease // set state to release
|
||||||
}
|
}
|
||||||
state := unit.state[0]
|
state := unit.state[0]
|
||||||
level := unit.state[1]
|
level := unit.state[1]
|
||||||
|
exponent := float64(1)
|
||||||
|
baseline := float32(0)
|
||||||
switch state {
|
switch state {
|
||||||
case envStateAttack:
|
case envStateAttack:
|
||||||
|
exponent = scaledEnvelopExponent(params[1])
|
||||||
level += nonLinearMap(params[0])
|
level += nonLinearMap(params[0])
|
||||||
if level >= 1 {
|
if level >= 1 {
|
||||||
level = 1
|
level = 1
|
||||||
state = envStateDecay
|
state = envStateDecay
|
||||||
}
|
}
|
||||||
case envStateDecay:
|
case envStateDecay:
|
||||||
|
exponent = scaledEnvelopExponent(params[3])
|
||||||
|
sustain := params[4]
|
||||||
|
baseline = sustain
|
||||||
level -= nonLinearMap(params[2])
|
level -= nonLinearMap(params[2])
|
||||||
if sustain := params[4]; level <= sustain {
|
if level <= sustain {
|
||||||
level = sustain
|
level = sustain
|
||||||
}
|
}
|
||||||
case envStateRelease:
|
case envStateRelease:
|
||||||
@ -359,7 +361,8 @@ func (s *GoSynth) Render(buffer sointu.AudioBuffer, maxtime int) (samples int, t
|
|||||||
}
|
}
|
||||||
unit.state[0] = state
|
unit.state[0] = state
|
||||||
unit.state[1] = level
|
unit.state[1] = level
|
||||||
output := level * params[6]
|
expLevel := float32(math.Pow(float64(level), exponent))
|
||||||
|
output := (baseline + (1-baseline)*expLevel) * params[6]
|
||||||
stack = append(stack, output)
|
stack = append(stack, output)
|
||||||
if stereo {
|
if stereo {
|
||||||
stack = append(stack, output)
|
stack = append(stack, output)
|
||||||
@ -646,6 +649,10 @@ func nonLinearMap(value float32) float32 {
|
|||||||
return float32(math.Exp2(float64(-24 * value)))
|
return float32(math.Exp2(float64(-24 * value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func scaledEnvelopExponent(value float32) float64 {
|
||||||
|
return math.Pow(2, 6*(0.5-float64(value)))
|
||||||
|
}
|
||||||
|
|
||||||
func clip(value float32) float32 {
|
func clip(value float32) float32 {
|
||||||
if value < -1 {
|
if value < -1 {
|
||||||
return -1
|
return -1
|
||||||
|
|||||||
Reference in New Issue
Block a user