-- High level api for playing sounds (and background music) module Sound.SFML ( PolySound, newPolySound, freePolySound, triggerPolySound, ) where import Data.IORef import Control.Monad import Foreign.Ptr import Sound.SFML.LowLevel -- * Sounds -- | A PolySound allows you to trigger one sound multiple times (the sounds overlap) data PolySound = PolySound FilePath (Ptr SoundBuffer) [Ptr Sound] (IORef Int) instance Show PolySound where show (PolySound file _ _ _) = "PolySound " ++ show file newPolySound :: FilePath -> Int -> IO PolySound newPolySound path numberOfVoices = do buffer <- sfSoundBuffer_CreateFromFile path sounds <- forM [1 .. numberOfVoices] $ \ _ -> do sound <- sfSound_Create sfSound_SetBuffer sound buffer return sound ref <- newIORef 0 return $ PolySound path buffer sounds ref freePolySound :: PolySound -> IO () freePolySound (PolySound _ buffer sounds _) = do sfSoundBuffer_Destroy buffer mapM_ sfSound_Destroy sounds triggerPolySound :: PolySound -> IO () triggerPolySound (PolySound _ _ sounds ref) = do i <- readIORef ref let i' = (i + 1) `mod` length sounds writeIORef ref i' sfSound_Play (sounds !! i) -- * Music -- There is always only one music lpaying at a single time. -- | Loads and plays a music file once. -- playMusic :: FilePath -> IO () -- playMusic = error "playMusic" -- | Loads and plays a music file in a loop. -- Stops if the program ends or 'stopMusic' is called. -- playMusicLooped :: FilePath -> IO () -- playMusicLooped = error "playMusicLooped" -- | Stops any background music that is playing. -- stopMusic :: IO () -- stopMusic = error "stopMusic"