Phase 6
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package synthetic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/uopi/uopi/internal/dsp"
|
||||
)
|
||||
|
||||
// floatParam extracts a float64 from params; returns 0 if missing or wrong type.
|
||||
func floatParam(params map[string]any, key string) float64 {
|
||||
if params == nil {
|
||||
return 0
|
||||
}
|
||||
v, ok := params[key]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
f, ok := v.(float64)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// stringParam extracts a string from params; returns "" if missing or wrong type.
|
||||
func stringParam(params map[string]any, key string) string {
|
||||
if params == nil {
|
||||
return ""
|
||||
}
|
||||
v, ok := params[key]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
s, ok := v.(string)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// BuildPipeline converts a []NodeDef (from JSON) into a []dsp.Node ready for
|
||||
// execution. JSON numbers are float64, so all numeric params are handled as
|
||||
// float64 regardless of the final type needed.
|
||||
func BuildPipeline(defs []NodeDef) ([]dsp.Node, error) {
|
||||
nodes := make([]dsp.Node, 0, len(defs))
|
||||
for i, d := range defs {
|
||||
n, err := buildNode(d)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("pipeline node %d (%q): %w", i, d.Type, err)
|
||||
}
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func buildNode(d NodeDef) (dsp.Node, error) {
|
||||
p := d.Params
|
||||
switch d.Type {
|
||||
case "gain":
|
||||
return &dsp.GainNode{Gain: floatParam(p, "gain")}, nil
|
||||
|
||||
case "offset":
|
||||
return &dsp.OffsetNode{Offset: floatParam(p, "offset")}, nil
|
||||
|
||||
case "add":
|
||||
return &dsp.AddNode{}, nil
|
||||
|
||||
case "subtract":
|
||||
return &dsp.SubtractNode{}, nil
|
||||
|
||||
case "multiply":
|
||||
return &dsp.MultiplyNode{}, nil
|
||||
|
||||
case "divide":
|
||||
return &dsp.DivideNode{}, nil
|
||||
|
||||
case "moving_average":
|
||||
return &dsp.MovingAverageNode{Window: max(1, int(floatParam(p, "window")))}, nil
|
||||
|
||||
case "rms":
|
||||
return &dsp.RMSNode{Window: max(1, int(floatParam(p, "window")))}, nil
|
||||
|
||||
case "derivative":
|
||||
return &dsp.DerivativeNode{}, nil
|
||||
|
||||
case "clamp":
|
||||
return &dsp.ClampNode{
|
||||
Min: floatParam(p, "min"),
|
||||
Max: floatParam(p, "max"),
|
||||
}, nil
|
||||
|
||||
case "threshold":
|
||||
return &dsp.ThresholdNode{
|
||||
Threshold: floatParam(p, "threshold"),
|
||||
High: floatParam(p, "high"),
|
||||
Low: floatParam(p, "low"),
|
||||
}, nil
|
||||
|
||||
case "expr":
|
||||
return &dsp.ExprNode{Expr: stringParam(p, "expr")}, nil
|
||||
|
||||
case "lua":
|
||||
return &dsp.LuaNode{Script: stringParam(p, "script")}, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown node type %q", d.Type)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user