mirror of
https://github.com/bloeys/wavy.git
synced 2025-12-29 09:28:19 +00:00
Many sounds from one data buffer+volume control
This commit is contained in:
@ -58,12 +58,12 @@ func (sb *SoundBuffer) Seek(offset int64, whence int) (int64, error) {
|
|||||||
return sb.Pos, nil
|
return sb.Pos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clone returns a new SoundBuffer that uses the same `Data` but with an independent ReadSeeker.
|
//Copy returns a new SoundBuffer that uses the same `Data` but with an independent ReadSeeker.
|
||||||
//This allows you to have many readers all reading from different positions of the same buffer.
|
//This allows you to have many readers all reading from different positions of the same buffer.
|
||||||
//
|
//
|
||||||
//The new buffer will have its starting position set to io.SeekStart (`Pos=0`)
|
//The new buffer will have its starting position set to io.SeekStart (`Pos=0`)
|
||||||
func (sb *SoundBuffer) Clone() SoundBuffer {
|
func (sb *SoundBuffer) Copy() *SoundBuffer {
|
||||||
return SoundBuffer{
|
return &SoundBuffer{
|
||||||
Data: sb.Data,
|
Data: sb.Data,
|
||||||
Pos: 0,
|
Pos: 0,
|
||||||
}
|
}
|
||||||
|
|||||||
43
wavy.go
43
wavy.go
@ -26,9 +26,9 @@ type SoundInfo struct {
|
|||||||
type Sound struct {
|
type Sound struct {
|
||||||
Player oto.Player
|
Player oto.Player
|
||||||
|
|
||||||
//FileDesc is the file descriptor of the sound file being streamed.
|
//File is the file descriptor of the sound file being streamed.
|
||||||
//This is only set if sound is streamed, and is kept to ensure GC doesn't hit it
|
//This is only set if sound is streamed, and is kept to ensure GC doesn't hit it
|
||||||
FileDesc *os.File
|
File *os.File
|
||||||
|
|
||||||
//Data is an io.ReadSeeker over an open file or over a buffer containing the uncompressed sound file.
|
//Data is an io.ReadSeeker over an open file or over a buffer containing the uncompressed sound file.
|
||||||
//Becomes nil after close
|
//Becomes nil after close
|
||||||
@ -110,6 +110,17 @@ func (s *Sound) RemainingTime() time.Duration {
|
|||||||
return time.Duration(lenInMS) * time.Millisecond
|
return time.Duration(lenInMS) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SetVolume must be between 0 and 1 (both inclusive). Other values will panic.
|
||||||
|
//The default volume is 1.
|
||||||
|
func (s *Sound) SetVolume(newVol float64) {
|
||||||
|
|
||||||
|
if newVol < 0 || newVol > 1 {
|
||||||
|
panic("sound volume can not be less than zero or bigger than one")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Player.SetVolume(newVol)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Sound) IsClosed() bool {
|
func (s *Sound) IsClosed() bool {
|
||||||
return s.Data == nil
|
return s.Data == nil
|
||||||
}
|
}
|
||||||
@ -123,8 +134,8 @@ func (s *Sound) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fdErr error = nil
|
var fdErr error = nil
|
||||||
if s.FileDesc != nil {
|
if s.File != nil {
|
||||||
fdErr = s.FileDesc.Close()
|
fdErr = s.File.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Data = nil
|
s.Data = nil
|
||||||
@ -145,7 +156,27 @@ func (s *Sound) Close() error {
|
|||||||
return fdErr
|
return fdErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//CopyInMemSound returns a new sound object that has identitcal info but uses the same underlying data.
|
||||||
|
//Since the sound data is not copied this function is very fast.
|
||||||
|
//
|
||||||
|
//The returned sound can be used independently of the original one (e.g. use it to play the same gunshot sound many times).
|
||||||
|
func CopyInMemSound(s *Sound) *Sound {
|
||||||
|
|
||||||
|
if s.Info.Mode == SoundMode_Streaming {
|
||||||
|
panic("streaming sounds can not be copied. Please use NewSoundStreaming instead")
|
||||||
|
}
|
||||||
|
|
||||||
|
d := s.Data.(*SoundBuffer).Copy()
|
||||||
|
return &Sound{
|
||||||
|
Player: Ctx.NewPlayer(d),
|
||||||
|
File: nil,
|
||||||
|
Data: d,
|
||||||
|
Info: s.Info,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//NewSoundStreaming plays sound by streaming from a file, so no need to load the entire file into memory.
|
//NewSoundStreaming plays sound by streaming from a file, so no need to load the entire file into memory.
|
||||||
|
//Good for large sound files
|
||||||
func NewSoundStreaming(fpath string) (s *Sound, err error) {
|
func NewSoundStreaming(fpath string) (s *Sound, err error) {
|
||||||
|
|
||||||
//Error checking filetype
|
//Error checking filetype
|
||||||
@ -165,7 +196,7 @@ func NewSoundStreaming(fpath string) (s *Sound, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = &Sound{
|
s = &Sound{
|
||||||
FileDesc: file,
|
File: file,
|
||||||
Info: SoundInfo{
|
Info: SoundInfo{
|
||||||
Type: soundType,
|
Type: soundType,
|
||||||
Mode: SoundMode_Streaming,
|
Mode: SoundMode_Streaming,
|
||||||
@ -188,7 +219,7 @@ func NewSoundStreaming(fpath string) (s *Sound, err error) {
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewSoundMem loads the entire sound file into memory and plays from that
|
//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
|
//Error checking filetype
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package wavy_test
|
package wavy_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -85,7 +84,9 @@ func TestSound(t *testing.T) {
|
|||||||
s.PlaySync()
|
s.PlaySync()
|
||||||
|
|
||||||
//Test repeat playing
|
//Test repeat playing
|
||||||
s.Player.Reset()
|
s2 := wavy.CopyInMemSound(s)
|
||||||
s.Data.Seek(0, io.SeekStart)
|
s2.SetVolume(0.25)
|
||||||
s.PlaySync()
|
|
||||||
|
s.PlaySync() //Already finished, should not play
|
||||||
|
s2.PlaySync() //Should play from beginning
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user