Ogg file support

This commit is contained in:
bloeys
2022-06-26 06:19:58 +04:00
parent 2d0f00175a
commit 989547c14e
6 changed files with 56 additions and 4 deletions

2
go.mod
View File

@ -6,10 +6,12 @@ require (
github.com/go-audio/wav v1.1.0 github.com/go-audio/wav v1.1.0
github.com/hajimehoshi/go-mp3 v0.3.3 github.com/hajimehoshi/go-mp3 v0.3.3
github.com/hajimehoshi/oto/v2 v2.1.0 github.com/hajimehoshi/oto/v2 v2.1.0
github.com/jfreymuth/oggvorbis v1.0.3
) )
require ( require (
github.com/go-audio/audio v1.0.0 // indirect github.com/go-audio/audio v1.0.0 // indirect
github.com/go-audio/riff 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 golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect
) )

4
go.sum
View File

@ -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 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 h1:/h+UkbKzhD7xBHOQlWgKUplBPZ+J4DK3P2Y7g2UF1X4=
github.com/hajimehoshi/oto/v2 v2.1.0/go.mod h1:9i0oYbpJ8BhVGkXDKdXKfFthX1JUNfXjeTp944W8TGM= 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/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/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= golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=

View File

@ -6,6 +6,7 @@ const (
SoundType_Unknown SoundType = iota SoundType_Unknown SoundType = iota
SoundType_MP3 SoundType_MP3
SoundType_WAV SoundType_WAV
SoundType_OGG
) )
type SampleRate int type SampleRate int

BIN
test_audio_files/camera.ogg Executable file

Binary file not shown.

44
wavy.go
View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math"
"os" "os"
"path" "path"
"time" "time"
@ -12,6 +13,7 @@ import (
"github.com/go-audio/wav" "github.com/go-audio/wav"
"github.com/hajimehoshi/go-mp3" "github.com/hajimehoshi/go-mp3"
"github.com/hajimehoshi/oto/v2" "github.com/hajimehoshi/oto/v2"
"github.com/jfreymuth/oggvorbis"
) )
//SoundInfo contains static info about a loaded sound file //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.Data = sb
s.Player = Ctx.NewPlayer(sb) s.Player = Ctx.NewPlayer(sb)
s.Info.Size = int64(len(sb.Data)) s.Info.Size = int64(len(sb.Data))
return nil
} else if s.Info.Type == SoundType_WAV { } else if s.Info.Type == SoundType_WAV {
wavDec := wav.NewDecoder(r) wavDec := wav.NewDecoder(r)
@ -457,10 +457,24 @@ func soundFromReaderSeeker(r io.ReadSeeker, s *Sound) error {
s.Data = sb s.Data = sb
s.Player = Ctx.NewPlayer(sb) s.Player = Ctx.NewPlayer(sb)
s.Info.Size = int64(len(sb.Data)) 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 { func GetSoundFileType(fpath string) SoundType {
@ -471,6 +485,8 @@ func GetSoundFileType(fpath string) SoundType {
return SoundType_MP3 return SoundType_MP3
case ".wav", ".wave": case ".wav", ".wave":
return SoundType_WAV return SoundType_WAV
case ".ogg":
return SoundType_OGG
default: default:
return SoundType_Unknown return SoundType_Unknown
} }
@ -534,3 +550,23 @@ func clamp01F64(x float64) float64 {
return x 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
}

View File

@ -112,6 +112,15 @@ func TestSound(t *testing.T) {
return return
} }
s.PlaySync() 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) { func TestByteCountFromPlayTime(t *testing.T) {