Wav file loading

This commit is contained in:
bloeys
2022-06-26 02:33:48 +04:00
parent 974c94008d
commit 4a5270129a
7 changed files with 89 additions and 40 deletions

7
go.mod
View File

@ -7,4 +7,9 @@ require (
github.com/hajimehoshi/oto/v2 v2.1.0 github.com/hajimehoshi/oto/v2 v2.1.0
) )
require golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect require (
github.com/go-audio/audio v1.0.0 // indirect
github.com/go-audio/riff v1.0.0 // indirect
github.com/go-audio/wav v1.1.0 // indirect
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect
)

6
go.sum
View File

@ -1,3 +1,9 @@
github.com/go-audio/audio v1.0.0 h1:zS9vebldgbQqktK4H0lUqWrG8P0NxCJVqcj7ZpNnwd4=
github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs=
github.com/go-audio/riff v1.0.0 h1:d8iCGbDvox9BfLagY94fBynxSPHO80LmZCaOsmKxokA=
github.com/go-audio/riff v1.0.0/go.mod h1:l3cQwc85y79NQFCRB7TiPoNiaijp6q8Z0Uv38rVG498=
github.com/go-audio/wav v1.1.0 h1:jQgLtbqBzY7G+BM8fXF7AHUk1uHUviWS4X39d5rsL2g=
github.com/go-audio/wav v1.1.0/go.mod h1:mpe9qfwbScEbkd8uybLuIpTgHyrISw/OTuvjUW2iGtE=
github.com/hajimehoshi/go-mp3 v0.3.3 h1:cWnfRdpye2m9ElSoVqneYRcpt/l3ijttgjMeQh+r+FE= github.com/hajimehoshi/go-mp3 v0.3.3 h1:cWnfRdpye2m9ElSoVqneYRcpt/l3ijttgjMeQh+r+FE=
github.com/hajimehoshi/go-mp3 v0.3.3/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= github.com/hajimehoshi/go-mp3 v0.3.3/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=

View File

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

BIN
test_audio_files/camera.wav Executable file

Binary file not shown.

11
test_audio_files/license.txt Executable file
View File

@ -0,0 +1,11 @@
"Free Sounds Library"
Free Sound Effects Site.
Licence: License: Attribution 4.0 International (CC BY 4.0). You are allowed to use sound effects free of charge and royalty free in your multimedia projects for commercial or non-commercial purposes.
http://www.freesoundslibrary.com

87
wavy.go
View File

@ -7,9 +7,9 @@ import (
"io" "io"
"os" "os"
"path" "path"
"strings"
"time" "time"
"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"
) )
@ -52,7 +52,7 @@ var (
//Pre-defined errors //Pre-defined errors
var ( var (
ErrunknownSoundType = errors.New("unknown sound type. Sound file extension must be one of: .mp3") errUnknownSoundType = errors.New("unknown sound type. Sound file extension must be one of: .mp3")
) )
//Init prepares the default audio device and does any required setup. //Init prepares the default audio device and does any required setup.
@ -354,14 +354,9 @@ func ResumeAllSounds() {
//Good for large sound files //Good for large sound files
func NewSoundStreaming(fpath string) (s *Sound, err error) { func NewSoundStreaming(fpath string) (s *Sound, err error) {
//Error checking filetype soundType := GetSoundFileType(fpath)
soundType := SoundType_Unknown
if strings.HasSuffix(fpath, ".mp3") {
soundType = SoundType_MP3
}
if soundType == SoundType_Unknown { if soundType == SoundType_Unknown {
return nil, ErrunknownSoundType return nil, errUnknownSoundType
} }
//We read file but don't close so the player can stream the file any time later //We read file but don't close so the player can stream the file any time later
@ -378,17 +373,9 @@ func NewSoundStreaming(fpath string) (s *Sound, err error) {
}, },
} }
//Load file depending on type err = soundFromReaderSeeker(file, s)
if soundType == SoundType_MP3 { if err != nil {
return nil, getLoadingErr(fpath, err)
dec, err := mp3.NewDecoder(file)
if err != nil {
return nil, err
}
s.Info.Size = dec.Length()
s.Player = Ctx.NewPlayer(dec)
s.Data = dec
} }
return s, nil return s, nil
@ -397,19 +384,14 @@ func NewSoundStreaming(fpath string) (s *Sound, err error) {
//NewSoundMem loads the entire sound file into memory //NewSoundMem loads the entire sound file into memory
func NewSoundMem(fpath string) (s *Sound, err error) { func NewSoundMem(fpath string) (s *Sound, err error) {
//Error checking filetype soundType := GetSoundFileType(fpath)
soundType := SoundType_Unknown
if strings.HasSuffix(fpath, ".mp3") {
soundType = SoundType_MP3
}
if soundType == SoundType_Unknown { if soundType == SoundType_Unknown {
return nil, ErrunknownSoundType return nil, getLoadingErr(fpath, errUnknownSoundType)
} }
fileBytes, err := os.ReadFile(fpath) fileBytes, err := os.ReadFile(fpath)
if err != nil { if err != nil {
return nil, err return nil, getLoadingErr(fpath, err)
} }
bytesReader := bytes.NewReader(fileBytes) bytesReader := bytes.NewReader(fileBytes)
@ -420,34 +402,69 @@ func NewSoundMem(fpath string) (s *Sound, err error) {
}, },
} }
//Load file depending on type err = soundFromReaderSeeker(bytesReader, s)
if soundType == SoundType_MP3 { if err != nil {
return nil, getLoadingErr(fpath, err)
}
dec, err := mp3.NewDecoder(bytesReader) return s, nil
}
func getLoadingErr(fpath string, err error) error {
return fmt.Errorf("failed to load '%s' with err '%s'", fpath, err.Error())
}
func soundFromReaderSeeker(r io.ReadSeeker, s *Sound) error {
if s.Info.Type == SoundType_MP3 {
dec, err := mp3.NewDecoder(r)
if err != nil { if err != nil {
return nil, err return err
} }
finalBuf, err := ReadAllFromReader(dec, 0, uint64(dec.Length())) finalBuf, err := ReadAllFromReader(dec, 0, uint64(dec.Length()))
if err != nil { if err != nil {
return nil, err return err
} }
sb := &SoundBuffer{Data: finalBuf} sb := &SoundBuffer{Data: finalBuf}
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 {
wavDec := wav.NewDecoder(r)
err := wavDec.FwdToPCM()
if err != nil {
return err
}
finalBuf, err := ReadAllFromReader(wavDec.PCMChunk, 0, uint64(wavDec.PCMSize))
if err != nil {
return err
}
sb := &SoundBuffer{Data: finalBuf}
s.Data = sb
s.Player = Ctx.NewPlayer(sb)
s.Info.Size = int64(len(sb.Data))
return nil
} }
return s, nil panic("invalid sound type")
} }
func GetSoundFileType(fpath string) SoundType { func GetSoundFileType(fpath string) SoundType {
ext := path.Ext(fpath) ext := path.Ext(fpath)
switch ext { switch ext {
case "mp3": case ".mp3":
return SoundType_MP3 return SoundType_MP3
case ".wav", ".wave":
return SoundType_WAV
default: default:
return SoundType_Unknown return SoundType_Unknown
} }

View File

@ -9,16 +9,16 @@ import (
func TestSound(t *testing.T) { func TestSound(t *testing.T) {
fatihaFilepath := "./test_audio_files/Fatiha.mp3"
tadaFilepath := "./test_audio_files/tada.mp3"
const fatihaLenMS = 55484
err := wavy.Init(wavy.SampleRate_44100, wavy.SoundChannelCount_2, wavy.SoundBitDepth_2) err := wavy.Init(wavy.SampleRate_44100, wavy.SoundChannelCount_2, wavy.SoundBitDepth_2)
if err != nil { if err != nil {
t.Errorf("Failed to init wavy. Err: %s\n", err) t.Errorf("Failed to init wavy. Err: %s\n", err)
return return
} }
const fatihaFilepath = "./test_audio_files/Fatiha.mp3"
const tadaFilepath = "./test_audio_files/tada.mp3"
const fatihaLenMS = 55484
//Streaming //Streaming
s, err := wavy.NewSoundStreaming(fatihaFilepath) s, err := wavy.NewSoundStreaming(fatihaFilepath)
if err != nil { if err != nil {
@ -103,6 +103,15 @@ func TestSound(t *testing.T) {
s3 := wavy.ClipInMemSoundPercent(s2, 0, 0.25) s3 := wavy.ClipInMemSoundPercent(s2, 0, 0.25)
s3.LoopAsync(3) s3.LoopAsync(3)
s3.WaitLoop() s3.WaitLoop()
//Wav
const wavFPath = "./test_audio_files/camera.wav"
s, err = wavy.NewSoundMem(wavFPath)
if err != nil {
t.Errorf("Failed to load memory sound with path '%s'. Err: %s\n", wavFPath, err)
return
}
s.PlaySync()
} }
func TestByteCountFromPlayTime(t *testing.T) { func TestByteCountFromPlayTime(t *testing.T) {