diff --git a/ebitengine/audio.go b/ebitengine/audio.go index 973db4d..6c16151 100644 --- a/ebitengine/audio.go +++ b/ebitengine/audio.go @@ -121,7 +121,7 @@ func (e *ebitenPlayerSource) Read(p []byte) (int, error) { bytesRead := 0 - e.audioSystem.ReadSamples(e.floatBuffer[:samples]) + e.ReadSamples(e.floatBuffer[:samples]) for i := 0; i < samples; i++ { floatSample := pi.Mid(e.floatBuffer[i], -1, 1) sample := int16(floatSample * 0x7FFF) // actually the full int16 range is -0x8000 to 0x7FFF (therefore -0x8000 will never be returned) diff --git a/ebitengine/audio_test.go b/ebitengine/audio_test.go index 2f22d9c..8a1be93 100644 --- a/ebitengine/audio_test.go +++ b/ebitengine/audio_test.go @@ -4,6 +4,7 @@ package ebitengine //nolint import ( + "sync" "testing" "github.com/stretchr/testify/assert" @@ -119,6 +120,40 @@ func TestEbitenPlayerSource_Read(t *testing.T) { }) } +func TestEbitenPlayerSource_ThreadSafety(t *testing.T) { + t.Run("should not fail when run with -race flag", func(t *testing.T) { + reader := &ebitenPlayerSource{ + audioSystem: &audio.Synthesizer{}, + } + + const goroutines = 100 + + var group sync.WaitGroup + group.Add(goroutines) + + for i := 0; i < goroutines; i++ { + go func() { + defer group.Done() + + _, err := reader.Read(make([]byte, 128)) + require.NoError(t, err) + reader.Sfx(0, 0, 0, 0) + reader.Music(0, 0, 0) + reader.Stat() + reader.SetSfx(0, audio.SoundEffect{}) + reader.GetSfx(0) + reader.SetMusic(0, audio.Pattern{}) + reader.GetMusic(0) + _, err = reader.Save() + require.NoError(t, err) + _ = reader.Load(make([]byte, 128)) + }() + } + + group.Wait() + }) +} + type audioSystemMock struct { buffer []float64 }