Files
mediadevices/pkg/wave/buffer_test.go
Lukas Herman db5d8f23bd Fix unstored audio
* Add unit test to check internal buffer integrity
* Fix unstored audio in internal buffer
2020-10-05 22:20:12 -04:00

130 lines
3.6 KiB
Go

package wave
import (
"errors"
"fmt"
"reflect"
"testing"
)
var (
errIdenticalAddress = errors.New("Cloned audio has the same memory address with the original audio")
)
func TestBufferStoreCopyAndLoad(t *testing.T) {
chunkInfo := ChunkInfo{
Len: 4,
Channels: 2,
SamplingRate: 48000,
}
testCases := map[string]struct {
New func() EditableAudio
Update func(EditableAudio)
Validate func(*testing.T, Audio, Audio)
}{
"Float32Interleaved": {
New: func() EditableAudio {
return NewFloat32Interleaved(chunkInfo)
},
Update: func(src EditableAudio) {
src.Set(0, 0, Float32Sample(1))
},
Validate: func(t *testing.T, original Audio, clone Audio) {
ok := reflect.ValueOf(original.(*Float32Interleaved).Data).Pointer() != reflect.ValueOf(clone.(*Float32Interleaved).Data).Pointer()
if !ok {
t.Error(errIdenticalAddress)
}
},
},
"Float32NonInterleaved": {
New: func() EditableAudio {
return NewFloat32NonInterleaved(chunkInfo)
},
Update: func(src EditableAudio) {
src.Set(0, 0, Float32Sample(1))
},
Validate: func(t *testing.T, original Audio, clone Audio) {
originalReal := original.(*Float32NonInterleaved)
cloneReal := clone.(*Float32NonInterleaved)
if reflect.ValueOf(originalReal.Data).Pointer() == reflect.ValueOf(cloneReal.Data).Pointer() {
t.Error(errIdenticalAddress)
}
for i := range cloneReal.Data {
if reflect.ValueOf(originalReal.Data[i]).Pointer() == reflect.ValueOf(cloneReal.Data[i]).Pointer() {
err := fmt.Errorf("Channel %d memory address should be different", i)
t.Errorf("%v: %w", errIdenticalAddress, err)
}
}
},
},
"Int16Interleaved": {
New: func() EditableAudio {
return NewInt16Interleaved(chunkInfo)
},
Update: func(src EditableAudio) {
src.Set(1, 1, Int16Sample(2))
},
Validate: func(t *testing.T, original Audio, clone Audio) {
ok := reflect.ValueOf(original.(*Int16Interleaved).Data).Pointer() != reflect.ValueOf(clone.(*Int16Interleaved).Data).Pointer()
if !ok {
t.Error(errIdenticalAddress)
}
},
},
"Int16NonInterleaved": {
New: func() EditableAudio {
return NewInt16NonInterleaved(chunkInfo)
},
Update: func(src EditableAudio) {
src.Set(1, 1, Int16Sample(2))
},
Validate: func(t *testing.T, original Audio, clone Audio) {
originalReal := original.(*Int16NonInterleaved)
cloneReal := clone.(*Int16NonInterleaved)
if reflect.ValueOf(originalReal.Data).Pointer() == reflect.ValueOf(cloneReal.Data).Pointer() {
t.Error(errIdenticalAddress)
}
for i := range cloneReal.Data {
if reflect.ValueOf(originalReal.Data[i]).Pointer() == reflect.ValueOf(cloneReal.Data[i]).Pointer() {
err := fmt.Errorf("Channel %d memory address should be different", i)
t.Errorf("%v: %w", errIdenticalAddress, err)
}
}
},
},
}
buffer := NewBuffer()
for name, testCase := range testCases {
// Since the test also wants to make sure that Copier can convert from 1 type to another,
// t.Run is not ideal since it'll run the tests separately
t.Log("Testing", name)
src := testCase.New()
src.Set(0, 0, Int16Sample(1))
buffer.StoreCopy(src)
testCase.Validate(t, src, buffer.Load())
if !reflect.DeepEqual(buffer.Load(), src) {
t.Fatalf(`Expected the copied audio chunk to be identical with the source
Expected:
%v
Actual:
%v
`, src, buffer.Load())
}
testCase.Update(src)
buffer.StoreCopy(src)
if !reflect.DeepEqual(buffer.Load(), src) {
t.Fatal("Expected the copied audio chunk to be identical with the source after an update in source")
}
}
}