ClipInMemSoundPercent + WaitLoop + bugs

This commit is contained in:
bloeys
2022-06-26 00:38:29 +04:00
parent 6afd1b7ac2
commit 974c94008d
2 changed files with 76 additions and 11 deletions

83
wavy.go
View File

@ -78,7 +78,9 @@ func Init(sr SampleRate, chanCount SoundChannelCount, bitDepth SoundBitDepth) er
//Wait blocks until sound finishes playing. If the sound is not playing Wait returns immediately. //Wait blocks until sound finishes playing. If the sound is not playing Wait returns immediately.
//In the worst case (Wait sleeping then sound immediately paused), Wait will block ~4% of the total play time. //In the worst case (Wait sleeping then sound immediately paused), Wait will block ~4% of the total play time.
//In most other cases Wait should be accurate to ~1ms //In most other cases Wait should be accurate to ~1ms.
//
//If you want to wait for all loops to finish then use WaitLoop
func (s *Sound) Wait() { func (s *Sound) Wait() {
if !s.IsPlaying() { if !s.IsPlaying() {
@ -97,6 +99,14 @@ func (s *Sound) Wait() {
} }
} }
//WaitLoop waits until the sound is no longer looping
func (s *Sound) WaitLoop() {
for s.IsLooping {
s.Wait()
}
}
//PlayAsync plays the sound in the background and returns. //PlayAsync plays the sound in the background and returns.
func (s *Sound) PlayAsync() { func (s *Sound) PlayAsync() {
s.Player.Play() s.Player.Play()
@ -120,10 +130,16 @@ func (s *Sound) LoopAsync(timesToPlay int) {
if s.IsPlaying() { if s.IsPlaying() {
s.Pause() s.Pause()
s.Wait()
if s.IsLooping {
s.WaitLoop()
} else {
s.Wait()
}
} }
s.PlayAsync() s.PlayAsync()
timesToPlay--
s.IsLooping = true s.IsLooping = true
go func() { go func() {
@ -158,6 +174,8 @@ func (s *Sound) LoopAsync(timesToPlay int) {
s.PlayAsync() s.PlayAsync()
} }
} }
s.IsLooping = false
}() }()
} }
@ -218,12 +236,7 @@ func (s *Sound) SeekToPercent(percent float64) {
s.Player.Reset() s.Player.Reset()
} }
if percent < 0 { percent = clamp01F64(percent)
percent = 0
} else if percent > 1 {
percent = 1
}
s.Data.Seek(int64(float64(s.Info.Size)*percent), io.SeekStart) s.Data.Seek(int64(float64(s.Info.Size)*percent), io.SeekStart)
} }
@ -280,17 +293,51 @@ func (s *Sound) Close() error {
//CopyInMemSound returns a new sound object that has identitcal info and uses the same underlying data, but with independent play controls (e.g. one playing at the start while one is in the middle). //CopyInMemSound returns a new sound object that has identitcal info and uses the same underlying data, but with independent play controls (e.g. one playing at the start while one is in the middle).
//Since the sound data is not copied this function is very fast. //Since the sound data is not copied this function is very fast.
//
//Panics if the sound is not in-memory
func CopyInMemSound(s *Sound) *Sound { func CopyInMemSound(s *Sound) *Sound {
if s.Info.Mode != SoundMode_Memory { if s.Info.Mode != SoundMode_Memory {
panic("only in-memory sounds can be copied. Please use NewSoundStreaming if you want to have multiple sound objects of a streaming sound") panic("only in-memory sounds can be copied. Please use NewSoundStreaming if you want to have multiple sound objects of a streaming sound")
} }
d := s.Data.(*SoundBuffer).Copy() sb := s.Data.(*SoundBuffer).Copy()
p := Ctx.NewPlayer(sb)
p.SetVolume(s.Volume())
return &Sound{ return &Sound{
Player: Ctx.NewPlayer(d), Player: p,
File: nil, File: nil,
Data: d, Data: sb,
Info: s.Info,
}
}
//ClipInMemSoundPercent is like CopyInMemSound but produces a sound that plays only between from and to.
//fromPercent and toPercent must be between 0 and 1
func ClipInMemSoundPercent(s *Sound, fromPercent, toPercent float64) *Sound {
if s.Info.Mode != SoundMode_Memory {
panic("only in-memory sounds can be used in ClipInMemSoundPercent")
}
fromPercent = clamp01F64(fromPercent)
toPercent = clamp01F64(toPercent)
sb := s.Data.(*SoundBuffer).Copy()
start := int64(float64(len(sb.Data)) * fromPercent)
end := int64(float64(len(sb.Data)) * toPercent)
sb.Data = sb.Data[start:end]
p := Ctx.NewPlayer(sb)
p.SetVolume(s.Volume())
return &Sound{
Player: p,
File: nil,
Data: sb,
Info: s.Info, Info: s.Info,
} }
} }
@ -450,3 +497,17 @@ func PlayTimeFromByteCount(byteCount int64) time.Duration {
func ByteCountFromPlayTime(t time.Duration) int64 { func ByteCountFromPlayTime(t time.Duration) int64 {
return t.Milliseconds() * BytesPerSecond / 1000 return t.Milliseconds() * BytesPerSecond / 1000
} }
//clampF64 [min,max]
func clamp01F64(x float64) float64 {
if x < 0 {
return 0
}
if x > 1 {
return 1
}
return x
}

View File

@ -99,6 +99,10 @@ func TestSound(t *testing.T) {
s2.SeekToTime(400 * time.Millisecond) s2.SeekToTime(400 * time.Millisecond)
s2.PlaySync() s2.PlaySync()
s3 := wavy.ClipInMemSoundPercent(s2, 0, 0.25)
s3.LoopAsync(3)
s3.WaitLoop()
} }
func TestByteCountFromPlayTime(t *testing.T) { func TestByteCountFromPlayTime(t *testing.T) {