Under Debian 8.2, this command should install everything needed:
~~~
-apt-get install libgles2-mesa-dev libsdl2-dev libsdl2-image-dev inkscape mpg123
+apt-get install libgles2-mesa-dev libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev inkscape mpg123
~~~
Under Windows 64 bits, using msys2, you can install the required packages with:
~~~
-pacman -S mingw-w64-x86_64-angleproject-git mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image
+pacman -S mingw-w64-x86_64-angleproject-git mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image mingw-w64-x86_64-SDL2_mixer
~~~
# Services by submodules
module display_linux
import sdl2::image
+import sdl2::mixer
import egl # local to gamnit
intrude import display
# Setup the SDL display and lib
fun setup_sdl(window_width, window_height: Int): SDLWindow
do
- assert sdl.initialize((new SDLInitFlags).video) else
+ assert sdl.initialize((new SDLInitFlags).video.audio) else
print_error "Failed to initialize SDL2: {sdl.error}"
end
print_error "Failed to create SDL2 window: {sdl.error}"
end
+ # Audio support
+ var inited = mix.initialize(mix_init_flags)
+ assert inited != mix_init_flags else
+ print_error "Failed to load SDL2 mixer format supports: {mix.error}"
+ end
+
+ var opened = mix.open_audio(44100, mix.default_format, 2, 1024)
+ assert opened else
+ print_error "Failed to initialize SDL2 mixer: {mix.error}"
+ end
+
return sdl_window
end
+ # Initialization flags passed to SDL2 mixer
+ #
+ # Defaults to all available formats.
+ var mix_init_flags: MixInitFlags = mix.flac | mix.mod | mix.mp3 | mix.ogg is lazy, writable
+
# Close the SDL display
- fun close_sdl do sdl_window.destroy
+ fun close_sdl
+ do
+ sdl_window.destroy
+ mix.close_audio
+ mix.quit
+ sdl.finalize
+ end
end
redef class TextureAsset
# See the License for the specific language governing permissions and
# limitations under the License.
-# Linux audio implementation
+# `app::audio` implementation for GNU/Linux using SDL2 mixer
module audio
import app::audio
+import sdl2::mixer
import linux
redef class PlayableAudio
+ redef var error = null
- redef fun play do
- if path.has_suffix(".wav") then
- sys.system "aplay -q {app.assets_dir}{path} &"
- else if path.has_suffix(".mp3") then
- sys.system "mpg123 -q {app.assets_dir}{path} &"
+ # Real file system path to this asset
+ private fun fs_path: String do return app.assets_dir / path
+
+ # Does `fs_path` exist?
+ private fun fs_path_exists: Bool
+ do
+ if not fs_path.file_exists then
+ error = new Error("Failed to load audio '{path}': file not found")
+ return false
+ end
+ return true
+ end
+end
+
+redef class Sound
+
+ private var native: nullable MixChunk = null
+
+ redef fun load
+ do
+ if not fs_path_exists then return
+
+ # SDL2 mixer load
+ var native = mix.load_wav(fs_path.to_cstring)
+ if native.address_is_null then
+ error = new Error("Failed to load sound '{path}': {mix.error}")
+ return
+ end
+
+ self.native = native
+ end
+
+ redef fun play
+ do
+ var native = native
+
+ if native == null and error == null then
+ # Lazy load
+ load
+
+ # Auto print errors on lazy loading only
+ var error = error
+ if error != null then print_error error
+ end
+
+ # If there's an error, silently skip
+ if error != null then return
+ native = self.native
+ assert native != null
+
+ # Play on any available channel
+ mix.play_channel(-1, native, 0)
+ end
+end
+
+redef class Music
+
+ private var native: nullable MixMusic = null
+
+ redef fun load
+ do
+ if not fs_path_exists then return
+
+ # SDL2 mixer load
+ var native = mix.load_mus(fs_path.to_cstring)
+ if native.address_is_null then
+ error = new Error("Failed to load music '{path}': {mix.error}")
+ return
+ end
+
+ self.native = native
+ end
+
+ redef fun play
+ do
+ var native = native
+
+ if native == null and error == null then
+ # Lazy load
+ load
+
+ # Auto print errors on lazy loading only
+ var error = error
+ if error != null then print_error error
end
+
+ # If there's an error, silently skip
+ if error != null then return
+ native = self.native
+ assert native != null
+
+ # Play looping
+ mix.play_music(native, -1)
end
- redef fun load do end
- redef fun pause do end
- redef fun resume do end
+ redef fun pause do mix.pause_music
+
+ redef fun resume do mix.resume_music
end