mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
feat(bridge): Return sensible error messages from bridge and test that patches that should fail actually do.
This commit is contained in:
parent
cd95c5ae37
commit
50ca02442d
@ -3,6 +3,7 @@ package bridge
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/vsariola/sointu/go4k"
|
||||
)
|
||||
@ -49,6 +50,27 @@ var opcodeTable = map[string]opTableEntry{
|
||||
"in": opTableEntry{C.su_in_id, []string{"channel"}},
|
||||
}
|
||||
|
||||
type RenderError struct {
|
||||
errcode int
|
||||
}
|
||||
|
||||
func (e *RenderError) Error() string {
|
||||
var reasons []string
|
||||
if e.errcode&0x40 != 0 {
|
||||
reasons = append(reasons, "FPU stack over/underflow")
|
||||
}
|
||||
if e.errcode&0x04 != 0 {
|
||||
reasons = append(reasons, "FPU divide by zero")
|
||||
}
|
||||
if e.errcode&0x01 != 0 {
|
||||
reasons = append(reasons, "FPU invalid operation")
|
||||
}
|
||||
if e.errcode&0x3800 != 0 {
|
||||
reasons = append(reasons, "FPU stack push/pops are not balanced")
|
||||
}
|
||||
return "RenderError: " + strings.Join(reasons, ", ")
|
||||
}
|
||||
|
||||
// Render renders until the buffer is full or the modulated time is reached, whichever
|
||||
// happens first.
|
||||
// Parameters:
|
||||
@ -74,7 +96,7 @@ func (synth *C.Synth) Render(buffer []float32, maxtime int) (int, int, error) {
|
||||
time := C.int(maxtime)
|
||||
errcode := int(C.su_render(synth, (*C.float)(&buffer[0]), &samples, &time))
|
||||
if errcode > 0 {
|
||||
return -1, -1, errors.New("RenderTime failed")
|
||||
return int(samples), int(time), &RenderError{errcode: errcode}
|
||||
}
|
||||
return int(samples), int(time), nil
|
||||
}
|
||||
|
@ -67,3 +67,98 @@ func TestBridge(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackUnderflow(t *testing.T) {
|
||||
patch := go4k.Patch{
|
||||
Instruments: []go4k.Instrument{
|
||||
go4k.Instrument{1, []go4k.Unit{
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
}}},
|
||||
SampleOffsets: []go4k.SampleOffset{},
|
||||
DelayTimes: []int{}}
|
||||
synth, err := bridge.Synth(patch)
|
||||
if err != nil {
|
||||
t.Fatalf("bridge compile error: %v", err)
|
||||
}
|
||||
buffer := make([]float32, 2)
|
||||
err = go4k.Render(synth, buffer)
|
||||
if err == nil {
|
||||
t.Fatalf("rendering should have failed due to stack underflow")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackBalancing(t *testing.T) {
|
||||
patch := go4k.Patch{
|
||||
Instruments: []go4k.Instrument{
|
||||
go4k.Instrument{1, []go4k.Unit{
|
||||
go4k.Unit{"push", map[string]int{}},
|
||||
}}},
|
||||
SampleOffsets: []go4k.SampleOffset{},
|
||||
DelayTimes: []int{}}
|
||||
synth, err := bridge.Synth(patch)
|
||||
if err != nil {
|
||||
t.Fatalf("bridge compile error: %v", err)
|
||||
}
|
||||
buffer := make([]float32, 2)
|
||||
err = go4k.Render(synth, buffer)
|
||||
if err == nil {
|
||||
t.Fatalf("rendering should have failed due to unbalanced stack push/pop")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStackOverflow(t *testing.T) {
|
||||
patch := go4k.Patch{
|
||||
Instruments: []go4k.Instrument{
|
||||
go4k.Instrument{1, []go4k.Unit{
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
}}},
|
||||
SampleOffsets: []go4k.SampleOffset{},
|
||||
DelayTimes: []int{}}
|
||||
synth, err := bridge.Synth(patch)
|
||||
if err != nil {
|
||||
t.Fatalf("bridge compile error: %v", err)
|
||||
}
|
||||
buffer := make([]float32, 2)
|
||||
err = go4k.Render(synth, buffer)
|
||||
if err == nil {
|
||||
t.Fatalf("rendering should have failed due to stack overflow, despite balanced push/pops")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDivideByZero(t *testing.T) {
|
||||
patch := go4k.Patch{
|
||||
Instruments: []go4k.Instrument{
|
||||
go4k.Instrument{1, []go4k.Unit{
|
||||
go4k.Unit{"loadval", map[string]int{"value": 128}},
|
||||
go4k.Unit{"invgain", map[string]int{"invgain": 0}},
|
||||
go4k.Unit{"pop", map[string]int{}},
|
||||
}}},
|
||||
SampleOffsets: []go4k.SampleOffset{},
|
||||
DelayTimes: []int{}}
|
||||
synth, err := bridge.Synth(patch)
|
||||
if err != nil {
|
||||
t.Fatalf("bridge compile error: %v", err)
|
||||
}
|
||||
buffer := make([]float32, 2)
|
||||
err = go4k.Render(synth, buffer)
|
||||
if err == nil {
|
||||
t.Fatalf("rendering should have failed due to divide by zero")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user