From d7e886a76b5fd7ffee85cc139fd174efebd816c1 Mon Sep 17 00:00:00 2001 From: Hraban Luyat Date: Sun, 12 Jul 2015 10:22:25 +0000 Subject: [PATCH] Refactoring the tests, wip (but passing) --- errors.go | 79 +++++++++++++++++++++++++++++++++++--------------- stream.go | 6 ++-- stream_test.go | 54 ++++++++++++++++++++++------------ 3 files changed, 94 insertions(+), 45 deletions(-) diff --git a/errors.go b/errors.go index 3ddfab3..4514ae0 100644 --- a/errors.go +++ b/errors.go @@ -1,7 +1,6 @@ package opus import ( - "errors" "fmt" ) @@ -11,31 +10,63 @@ import ( */ import "C" -var opusfileErrcodes = map[C.int]error{ - -1: errors.New("OP_FALSE"), - -2: errors.New("OP_EOF"), - -3: errors.New("OP_HOLE"), - -128: errors.New("OP_EREAD"), - -129: errors.New("OP_EFAULT"), - -130: errors.New("OP_EIMPL"), - -131: errors.New("OP_EINVAL"), - -132: errors.New("OP_ENOTFORMAT"), - -133: errors.New("OP_EBADHEADER"), - -134: errors.New("OP_EVERSION"), - -135: errors.New("OP_ENOTAUDIO"), - -136: errors.New("OP_EBADPACKET"), - -137: errors.New("OP_EBADLINK"), - -138: errors.New("OP_ENOSEEK"), - -139: errors.New("OP_EBADTIMESTAMP"), -} +type opusFileError int + +var opusfileErrcodes = map[C.int]error{} + +const ( + ERR_OP_FALSE opusFileError = -1 + ERR_OP_EOF = -2 + ERR_OP_HOLE = -3 + ERR_OP_EREAD = -128 + ERR_OP_EFAULT = -129 + ERR_OP_EIMPL = -130 + ERR_OP_EINVAL = -131 + ERR_OP_ENOTFORMAT = -132 + ERR_OP_EBADHEADER = -133 + ERR_OP_EVERSION = -134 + ERR_OP_ENOTAUDIO = -135 + ERR_OP_EBADPACKET = -136 + ERR_OP_EBADLINK = -137 + ERR_OP_ENOSEEK = -138 + ERR_OP_EBADTIMESTAMP = -139 +) -// opusfileerr maps libopusfile error codes to human readable strings -func opusfileerr(code C.int) error { - err, ok := opusfileErrcodes[code] - if ok { - return err +func (i opusFileError) Error() string { + switch i { + case ERR_OP_FALSE: + return "OP_FALSE" + case ERR_OP_EOF: + return "OP_EOF" + case ERR_OP_HOLE: + return "OP_HOLE" + case ERR_OP_EREAD: + return "OP_EREAD" + case ERR_OP_EFAULT: + return "OP_EFAULT" + case ERR_OP_EIMPL: + return "OP_EIMPL" + case ERR_OP_EINVAL: + return "OP_EINVAL" + case ERR_OP_ENOTFORMAT: + return "OP_ENOTFORMAT" + case ERR_OP_EBADHEADER: + return "OP_EBADHEADER" + case ERR_OP_EVERSION: + return "OP_EVERSION" + case ERR_OP_ENOTAUDIO: + return "OP_ENOTAUDIO" + case ERR_OP_EBADPACKET: + return "OP_EBADPACKET" + case ERR_OP_EBADLINK: + return "OP_EBADLINK" + case ERR_OP_ENOSEEK: + return "OP_ENOSEEK" + case ERR_OP_EBADTIMESTAMP: + return "OP_EBADTIMESTAMP" + default: + return "libopus error: %d (unknown code)" } - return fmt.Errorf("libopus error: %d (unknown code)", int(code)) } // opuserr translates libopus (not libopusfile) error codes to human readable diff --git a/stream.go b/stream.go index c73916f..37a039e 100644 --- a/stream.go +++ b/stream.go @@ -75,7 +75,7 @@ func (s *Stream) Init(read io.Reader) error { 0, &errno) if errno != 0 { - return opusfileerr(errno) + return opusFileError(errno) } s.oggfile = oggfile return nil @@ -104,7 +104,7 @@ func (s *Stream) Read(pcm []int16) (int, error) { C.int(len(pcm)), nil) if n < 0 { - return 0, opusfileerr(n) + return 0, opusFileError(n) } if n == 0 { return 0, io.EOF @@ -125,7 +125,7 @@ func (s *Stream) ReadFloat32(pcm []float32) (int, error) { C.int(len(pcm)), nil) if n < 0 { - return 0, opusfileerr(n) + return 0, opusFileError(n) } if n == 0 { return 0, io.EOF diff --git a/stream_test.go b/stream_test.go index ee4edea..8badc69 100644 --- a/stream_test.go +++ b/stream_test.go @@ -5,10 +5,11 @@ package opus import ( - "bytes" "fmt" "io" + "io/ioutil" "os" + "reflect" "strings" "testing" ) @@ -22,14 +23,14 @@ func TestStreamIllegal(t *testing.T) { } } -func readStreamWav(t *testing.T, stream *Stream, buffersize int) []byte { - var buf bytes.Buffer - pcm := make([]int16, buffersize) +func readStreamPcm(t *testing.T, stream *Stream, buffersize int) []int16 { + var pcm []int16 + pcmbuf := make([]int16, buffersize) for { - n, err := stream.Read(pcm) + n, err := stream.Read(pcmbuf) switch err { case io.EOF: - return buf.Bytes() + return pcm case nil: break default: @@ -38,10 +39,7 @@ func readStreamWav(t *testing.T, stream *Stream, buffersize int) []byte { if n == 0 { t.Fatal("Nil-error Read() must not return 0") } - for i := 0; i < n; i++ { - buf.WriteByte(byte(pcm[i] & 0xff)) - buf.WriteByte(byte(pcm[i] >> 8)) - } + pcm = append(pcm, pcmbuf[:n]...) } } @@ -63,26 +61,46 @@ func mustOpenStream(t *testing.T, r io.Reader) *Stream { return stream } -func readFileWav(t *testing.T, fname string, buffersize int) []byte { +func opus2pcm(t *testing.T, fname string, buffersize int) []int16 { reader := mustOpenFile(t, fname) stream, err := NewStream(reader) if err != nil { t.Fatalf("Error while creating opus stream: %v", err) } - return readStreamWav(t, stream, buffersize) + return readStreamPcm(t, stream, buffersize) +} + +// Extract raw pcm data from .wav file +func exctractWavPcm(t *testing.T, fname string) []int16 { + bytes, err := ioutil.ReadFile(fname) + if err != nil { + t.Fatalf("Error reading file data from %s: %v", fname, err) + } + const wavHeaderSize = 44 + if (len(bytes)-wavHeaderSize)%2 == 1 { + t.Fatalf("Illegal wav data: payload must be encoded in byte pairs") + } + numSamples := (len(bytes) - wavHeaderSize) / 2 + samples := make([]int16, numSamples) + for i := 0; i < numSamples; i++ { + samples[i] += int16(bytes[wavHeaderSize+i*2]) + samples[i] += int16(bytes[wavHeaderSize+i*2+1]) << 8 + } + return samples } func TestStream(t *testing.T) { - wav := readFileWav(t, "testdata/speech_8.opus", 10000) - if len(wav) != 1036800 { - t.Fatalf("Unexpected length of WAV file: %d", len(wav)) + pcm := opus2pcm(t, "testdata/speech_8.opus", 10000) + if len(pcm) != 518400 { + t.Fatalf("Unexpected length of decoded opus file: %d", len(pcm)) } + } func TestStreamSmallBuffer(t *testing.T) { - smallbuf := readFileWav(t, "testdata/speech_8.opus", 1) - bigbuf := readFileWav(t, "testdata/speech_8.opus", 10000) - if !bytes.Equal(smallbuf, bigbuf) { + smallbuf := opus2pcm(t, "testdata/speech_8.opus", 1) + bigbuf := opus2pcm(t, "testdata/speech_8.opus", 10000) + if !reflect.DeepEqual(smallbuf, bigbuf) { t.Errorf("Reading with 1-sample buffer size yields different audio data") } } -- 2.48.1