diff --git a/go.mod b/go.mod index 1489baa..e788cff 100755 --- a/go.mod +++ b/go.mod @@ -6,10 +6,12 @@ require ( github.com/go-audio/wav v1.1.0 github.com/hajimehoshi/go-mp3 v0.3.3 github.com/hajimehoshi/oto/v2 v2.1.0 + github.com/jfreymuth/oggvorbis v1.0.3 ) require ( github.com/go-audio/audio v1.0.0 // indirect github.com/go-audio/riff v1.0.0 // indirect + github.com/jfreymuth/vorbis v1.0.2 // indirect golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect ) diff --git a/go.sum b/go.sum index ec8ba10..2f8fad4 100755 --- a/go.sum +++ b/go.sum @@ -9,6 +9,10 @@ github.com/hajimehoshi/go-mp3 v0.3.3/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0Ubt github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= github.com/hajimehoshi/oto/v2 v2.1.0 h1:/h+UkbKzhD7xBHOQlWgKUplBPZ+J4DK3P2Y7g2UF1X4= github.com/hajimehoshi/oto/v2 v2.1.0/go.mod h1:9i0oYbpJ8BhVGkXDKdXKfFthX1JUNfXjeTp944W8TGM= +github.com/jfreymuth/oggvorbis v1.0.3 h1:MLNGGyhOMiVcvea9Dp5+gbs2SAwqwQbtrWnonYa0M0Y= +github.com/jfreymuth/oggvorbis v1.0.3/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII= +github.com/jfreymuth/vorbis v1.0.2 h1:m1xH6+ZI4thH927pgKD8JOH4eaGRm18rEE9/0WKjvNE= +github.com/jfreymuth/vorbis v1.0.2/go.mod h1:DoftRo4AznKnShRl1GxiTFCseHr4zR9BN3TWXyuzrqQ= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= diff --git a/sound_enums.go b/sound_enums.go index ed407c5..b06de3d 100755 --- a/sound_enums.go +++ b/sound_enums.go @@ -6,6 +6,7 @@ const ( SoundType_Unknown SoundType = iota SoundType_MP3 SoundType_WAV + SoundType_OGG ) type SampleRate int diff --git a/test_audio_files/camera.ogg b/test_audio_files/camera.ogg new file mode 100755 index 0000000..1bb6c28 Binary files /dev/null and b/test_audio_files/camera.ogg differ diff --git a/wavy.go b/wavy.go index 450205b..5fbdd7a 100644 --- a/wavy.go +++ b/wavy.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "math" "os" "path" "time" @@ -12,6 +13,7 @@ import ( "github.com/go-audio/wav" "github.com/hajimehoshi/go-mp3" "github.com/hajimehoshi/oto/v2" + "github.com/jfreymuth/oggvorbis" ) //SoundInfo contains static info about a loaded sound file @@ -438,8 +440,6 @@ func soundFromReaderSeeker(r io.ReadSeeker, s *Sound) error { s.Data = sb s.Player = Ctx.NewPlayer(sb) s.Info.Size = int64(len(sb.Data)) - return nil - } else if s.Info.Type == SoundType_WAV { wavDec := wav.NewDecoder(r) @@ -457,10 +457,24 @@ func soundFromReaderSeeker(r io.ReadSeeker, s *Sound) error { s.Data = sb s.Player = Ctx.NewPlayer(sb) s.Info.Size = int64(len(sb.Data)) - return nil + } else if s.Info.Type == SoundType_OGG { + + soundData, _, err := oggvorbis.ReadAll(r) + if err != nil { + return err + } + + sb := &SoundBuffer{Data: F32ToUnsignedPCM16(soundData)} + s.Data = sb + s.Player = Ctx.NewPlayer(sb) + s.Info.Size = int64(len(sb.Data)) } - panic("invalid sound type") + if s.Data == nil { + panic("invalid sound type. This is probably a bug!") + } + + return nil } func GetSoundFileType(fpath string) SoundType { @@ -471,6 +485,8 @@ func GetSoundFileType(fpath string) SoundType { return SoundType_MP3 case ".wav", ".wave": return SoundType_WAV + case ".ogg": + return SoundType_OGG default: return SoundType_Unknown } @@ -534,3 +550,23 @@ func clamp01F64(x float64) float64 { return x } + +//F32ToUnsignedPCM16 takes PCM data stored as float32 between [-1, 1] +//and returns a byte array of uint16, where each two subsequent bytes represent one uint16. +func F32ToUnsignedPCM16(fs []float32) []byte { + + outBuf := make([]byte, len(fs)*2) + for i := 0; i < len(fs); i++ { + + //Remap [-1,1]->[-32768, 32767], then re-interprets the int16 as a uint16. + //With this, the negative values are mapped into the higher half of the uint16 range, + //while positive values remain unchanged + x16 := uint16(fs[i] * math.MaxInt16) + + baseIndex := i * 2 + outBuf[baseIndex] = byte(x16 >> 0) + outBuf[baseIndex+1] = byte(x16 >> 8) + } + + return outBuf +} diff --git a/wavy_test.go b/wavy_test.go index fb43839..8519528 100755 --- a/wavy_test.go +++ b/wavy_test.go @@ -112,6 +112,15 @@ func TestSound(t *testing.T) { return } s.PlaySync() + + //Ogg + const oggFPath = "./test_audio_files/camera.ogg" + s, err = wavy.NewSoundMem(oggFPath) + if err != nil { + t.Errorf("Failed to load memory sound with path '%s'. Err: %s\n", oggFPath, err) + return + } + s.PlaySync() } func TestByteCountFromPlayTime(t *testing.T) {