Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic reflect types for package consumers to use #19

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions audio.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package audio

import (
"errors"
"reflect"
)

var (
Expand Down Expand Up @@ -32,4 +33,7 @@ type Buffer interface {
// Clone creates a clean clone that can be modified without
// changing the source buffer.
Clone() Buffer
// Type returns a reflect value for determining the type
// for on the fly conversions
Type() reflect.Kind
}
12 changes: 12 additions & 0 deletions float_buffer.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package audio

import "reflect"

var _ Buffer = (*FloatBuffer)(nil)
var _ Buffer = (*Float32Buffer)(nil)

Expand Down Expand Up @@ -74,6 +76,11 @@ func (buf *FloatBuffer) NumFrames() int {
return len(buf.Data) / numChannels
}

// Type returns the type of this buffer
func (buf *FloatBuffer) Type() reflect.Kind {
return reflect.Float64
}

// Float32Buffer is an audio buffer with its PCM data formatted as float32.
type Float32Buffer struct {
// Format is the representation of the underlying data format
Expand Down Expand Up @@ -154,3 +161,8 @@ func (buf *Float32Buffer) NumFrames() int {

return len(buf.Data) / numChannels
}

// Type returns the type of this buffer
func (buf *Float32Buffer) Type() reflect.Kind {
return reflect.Float32
}
6 changes: 6 additions & 0 deletions float_buffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,16 @@ func TestFloat32Buffer(t *testing.T) {
if !reflect.DeepEqual(fb64.Data, tt.f64) {
t.Errorf("Expected %+v got %+v", tt.f64, fb64.Data)
}
if fb64.Type() != reflect.Float64 {
t.Errorf("buffer was improperly typed: %v", fb64.Type())
}
integer := fb.AsIntBuffer()
if !reflect.DeepEqual(integer.Data, tt.integer) {
t.Errorf("Expected %+v got %+v", tt.integer, integer.Data)
}
if integer.Type() != reflect.Int {
t.Errorf("buffer was improperly typed: %v", integer.Type())
}
})
}
}
10 changes: 9 additions & 1 deletion int_buffer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package audio

import "math"
import (
"math"
"reflect"
)

var _ Buffer = (*IntBuffer)(nil)

Expand Down Expand Up @@ -104,3 +107,8 @@ func (buf *IntBuffer) Clone() Buffer {
}
return newB
}

// Type returns the type of this buffer
func (buf *IntBuffer) Type() reflect.Kind {
return reflect.Int
}
15 changes: 15 additions & 0 deletions int_buffer_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package audio

import (
"reflect"
"testing"
)

Expand Down Expand Up @@ -36,6 +37,20 @@ func TestIntBuffer_AsFloat32Buffer(t *testing.T) {
t.Errorf("%d was converted out of range to %f", intData[i], f)
}
}
if got.Type() != reflect.Float32 {
t.Errorf("buffer was improperly typed: %v", got.Type())
}

gotb := got.Clone()
got64 := gotb.AsFloatBuffer()
for i, f := range got64.Data {
if f < -1.0 || f > 1.0 {
t.Errorf("%d was converted out of range to %f", intData[i], f)
}
}
if got64.Type() != reflect.Float64 {
t.Errorf("buffer was improperly typed: %v", got64.Type())
}
})
}
}
28 changes: 27 additions & 1 deletion pcm_buffer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package audio

import "math"
import (
"math"
"reflect"
)

// PCMDataFormat is an enum type to indicate the underlying data format used.
type PCMDataFormat uint8
Expand Down Expand Up @@ -459,3 +462,26 @@ func (b *PCMBuffer) calculateIntBitDepth() uint8 {

return bitDepth
}

// Type returns the type of this buffer
func (b *PCMBuffer) Type() reflect.Kind {
if b == nil {
return reflect.Invalid
}

switch b.DataType {
case DataTypeI8:
return reflect.Int8
case DataTypeI16:
return reflect.Int16
case DataTypeI32:
return reflect.Int32
case DataTypeF32:
return reflect.Float32
case DataTypeF64:
return reflect.Float64
default:
return reflect.Invalid
}

}
60 changes: 60 additions & 0 deletions pcm_buffer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package audio

import (
"reflect"
"testing"
)

func TestPCMBuffer_AsFloatBuffer(t *testing.T) {
tests := []struct {
name string
datatype PCMDataFormat
bd uint8
i8 []int8
i16 []int16
i32 []int32
f32 []float32
f64 []float64
}{
{"int8 conversion", DataTypeI8, 1, []int8{1, 2, 3}, []int16{1, 2, 3}, []int32{1, 2, 3}, []float32{2, 4, 6}, []float64{2, 4, 6}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pcmb := PCMBuffer{
Format: FormatMono22500,
I8: tt.i8,
SourceBitDepth: tt.bd,
DataType: tt.datatype,
}

// I'm unsure if the actual behavior is for int8 individual
// data to double the way it did
// 1,2,3 => 2,4,6
pcmb32 := pcmb.AsFloat32Buffer()
if !reflect.DeepEqual(pcmb32.Data, tt.f32) {
t.Errorf("Expected %+v got %+v", tt.f32, pcmb32.Data)
}
pcmb64 := pcmb.AsFloatBuffer()
if !reflect.DeepEqual(pcmb64.Data, tt.f64) {
t.Errorf("Expected %+v got %+v", tt.f64, pcmb64.Data)
}

if !reflect.DeepEqual(pcmb.AsI16(), tt.i16) {
t.Errorf("Expected %+v got %+v", tt.i8, pcmb.AsI16())
}
if !reflect.DeepEqual(pcmb.AsI32(), tt.i32) {
t.Errorf("Expected %+v got %+v", tt.i32, pcmb.AsI32())
}
if pcmb.Type() != reflect.Int8 {
t.Errorf("buffer was improperly typed: %v", pcmb.Type())
}
if pcmb32.Type() != reflect.Float32 {
t.Errorf("buffer was improperly typed: %v", pcmb32.Type())
}
if pcmb64.Type() != reflect.Float64 {
t.Errorf("buffer was improperly typed: %v", pcmb64.Type())
}
})
}

}