-- | -- Copyright : (c) Keera Studios, 2010-2014. -- License : See LICENSE file. -- Maintainer : Ivan Perez -- -- A layer of abstraction on top of SDL audio. -- -- It plays audio soundfx asynchronously (in a new thread), which means that -- programs must be compiled with the threaded Runtime System (ghc flag is -- -threaded). module Audio ( Music(..) , Audio(..) , initAudio , loadAudio , loadMusic , playMusic , playFile , stopMusic , musicPlaying ) where -- External imports import Control.Applicative ((<$>)) import Control.Concurrent import Control.Monad import qualified Graphics.UI.SDL.Mixer.Channels as SDL.Mixer.Channels import qualified Graphics.UI.SDL.Mixer.General as SDL.Mixer import qualified Graphics.UI.SDL.Mixer.Music as SDL.Mixer.Music import qualified Graphics.UI.SDL.Mixer.Samples as SDL.Mixer.Samples import qualified Graphics.UI.SDL.Mixer.Types as SDL.Mixer.Types data Music = Music { musicName :: String, unMusic :: SDL.Mixer.Types.Music } data Audio = Audio { audioName :: String, unAudio :: SDL.Mixer.Types.Chunk } -- | Initialize the audio subsystem. -- -- Audio quality and number of channels are fixed (16). initAudio :: IO () initAudio = void $ do _result <- SDL.Mixer.openAudio 44100 SDL.Mixer.AudioS16LSB 2 4096 SDL.Mixer.Channels.allocateChannels 16 -- | Load a music file, returning a 'Music' if loaded successfully. loadMusic :: String -> IO (Maybe Music) loadMusic fp = fmap (Music fp) <$> SDL.Mixer.Music.tryLoadMUS fp -- | Play music in a loop at max volume. playMusic :: Music -> IO () playMusic m = do SDL.Mixer.Music.setMusicVolume 100 SDL.Mixer.Music.playMusic (unMusic m) (-1) -- | Stop playing music stopMusic :: IO () stopMusic = SDL.Mixer.Music.haltMusic -- | Is music playing? musicPlaying :: IO Bool musicPlaying = SDL.Mixer.Music.playingMusic -- | Load an audio file. loadAudio :: String -> IO (Maybe Audio) loadAudio fp = fmap (Audio fp) <$> SDL.Mixer.Samples.tryLoadWAV fp -- | Play an audio file for the given number of seconds. -- -- This function spawns a new OS thread. Remember to compile your program -- with the threaded RTS. playFile :: Audio -> Int -> IO () playFile wav t = void $ forkOS $ do _v <- SDL.Mixer.Channels.playChannel (-1) (unAudio wav) 0 threadDelay (t * 1000)