package assetstore import ( "log" "os" "github.com/hajimehoshi/ebiten/v2/audio" "github.com/hajimehoshi/ebiten/v2/audio/vorbis" ) type Sound struct { Name string filename string } func (a *AssetStore) Sound(name string) (*Sound, error) { name = canonical(name) if sound, ok := a.sounds[name]; ok { return sound, nil } // TODO: Data/Sounds.dat + Sounds/wh40k.ds seem to operate together to allow // attributes and a .wav file to be attached to event names, which could be // what we use here instead. For now, we're just using the .wav files! log.Printf("Loading sound %v", name) // FIXME: a preprocessing script is used to create these files from the // original ADPCM .wav files. Instead, use the original .wav files. filename, err := a.lookup(name, "wav.ogg", "Wav") if err != nil { return nil, err } sound := &Sound{ Name: name, filename: filename, } a.sounds[name] = sound return sound, nil } func (s *Sound) Player() (*audio.Player, error) { decoder, err := s.decoder() if err != nil { return nil, err } return audio.NewPlayer(audio.CurrentContext(), decoder) } func (s *Sound) InfinitePlayer() (*audio.Player, error) { decoder, err := s.decoder() if err != nil { return nil, err } infinite := audio.NewInfiniteLoop(decoder, decoder.Length()) return audio.NewPlayer(audio.CurrentContext(), infinite) } func (s *Sound) decoder() (*vorbis.Stream, error) { f, err := os.Open(s.filename) if err != nil { return nil, err } decoder, err := vorbis.Decode(audio.CurrentContext(), f) if err != nil { _ = f.Close() return nil, err } return decoder, nil }