Fix unstored audio

* Add unit test to check internal buffer integrity
* Fix unstored audio in internal buffer
This commit is contained in:
Lukas Herman
2020-10-01 23:09:25 -07:00
parent d6ba28af8c
commit db5d8f23bd
2 changed files with 65 additions and 3 deletions

View File

@@ -51,6 +51,7 @@ func (buff *Buffer) StoreCopy(src Audio) {
} }
copy(buff.bufferFloat32Interleaved, src.Data) copy(buff.bufferFloat32Interleaved, src.Data)
clone.Data = buff.bufferFloat32Interleaved
buff.tmp = clone buff.tmp = clone
case *Float32NonInterleaved: case *Float32NonInterleaved:
@@ -83,6 +84,7 @@ func (buff *Buffer) StoreCopy(src Audio) {
copy(buff.bufferFloat32NonInterleaved[i], src.Data[i]) copy(buff.bufferFloat32NonInterleaved[i], src.Data[i])
} }
clone.Data = buff.bufferFloat32NonInterleaved
buff.tmp = clone buff.tmp = clone
case *Int16Interleaved: case *Int16Interleaved:
@@ -104,6 +106,7 @@ func (buff *Buffer) StoreCopy(src Audio) {
} }
copy(buff.bufferInt16Interleaved, src.Data) copy(buff.bufferInt16Interleaved, src.Data)
clone.Data = buff.bufferInt16Interleaved
buff.tmp = clone buff.tmp = clone
case *Int16NonInterleaved: case *Int16NonInterleaved:
@@ -136,6 +139,7 @@ func (buff *Buffer) StoreCopy(src Audio) {
copy(buff.bufferInt16NonInterleaved[i], src.Data[i]) copy(buff.bufferInt16NonInterleaved[i], src.Data[i])
} }
clone.Data = buff.bufferInt16NonInterleaved
buff.tmp = clone buff.tmp = clone
default: default:

View File

@@ -1,10 +1,16 @@
package wave package wave
import ( import (
"errors"
"fmt"
"reflect" "reflect"
"testing" "testing"
) )
var (
errIdenticalAddress = errors.New("Cloned audio has the same memory address with the original audio")
)
func TestBufferStoreCopyAndLoad(t *testing.T) { func TestBufferStoreCopyAndLoad(t *testing.T) {
chunkInfo := ChunkInfo{ chunkInfo := ChunkInfo{
Len: 4, Len: 4,
@@ -14,6 +20,7 @@ func TestBufferStoreCopyAndLoad(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
New func() EditableAudio New func() EditableAudio
Update func(EditableAudio) Update func(EditableAudio)
Validate func(*testing.T, Audio, Audio)
}{ }{
"Float32Interleaved": { "Float32Interleaved": {
New: func() EditableAudio { New: func() EditableAudio {
@@ -22,6 +29,12 @@ func TestBufferStoreCopyAndLoad(t *testing.T) {
Update: func(src EditableAudio) { Update: func(src EditableAudio) {
src.Set(0, 0, Float32Sample(1)) 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": { "Float32NonInterleaved": {
New: func() EditableAudio { New: func() EditableAudio {
@@ -30,6 +43,20 @@ func TestBufferStoreCopyAndLoad(t *testing.T) {
Update: func(src EditableAudio) { Update: func(src EditableAudio) {
src.Set(0, 0, Float32Sample(1)) 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": { "Int16Interleaved": {
New: func() EditableAudio { New: func() EditableAudio {
@@ -38,6 +65,12 @@ func TestBufferStoreCopyAndLoad(t *testing.T) {
Update: func(src EditableAudio) { Update: func(src EditableAudio) {
src.Set(1, 1, Int16Sample(2)) 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": { "Int16NonInterleaved": {
New: func() EditableAudio { New: func() EditableAudio {
@@ -46,6 +79,20 @@ func TestBufferStoreCopyAndLoad(t *testing.T) {
Update: func(src EditableAudio) { Update: func(src EditableAudio) {
src.Set(1, 1, Int16Sample(2)) 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)
}
}
},
}, },
} }
@@ -57,9 +104,20 @@ func TestBufferStoreCopyAndLoad(t *testing.T) {
t.Log("Testing", name) t.Log("Testing", name)
src := testCase.New() src := testCase.New()
src.Set(0, 0, Int16Sample(1))
buffer.StoreCopy(src) buffer.StoreCopy(src)
testCase.Validate(t, src, buffer.Load())
if !reflect.DeepEqual(buffer.Load(), src) { if !reflect.DeepEqual(buffer.Load(), src) {
t.Fatal("Expected the copied audio chunk to be identical with the source") t.Fatalf(`Expected the copied audio chunk to be identical with the source
Expected:
%v
Actual:
%v
`, src, buffer.Load())
} }
testCase.Update(src) testCase.Update(src)