module Sound.SFML (
PolySound,
newPolySound,
freePolySound,
triggerPolySound,
LoopedSound,
newLoopedSound,
freeLoopedSound,
startLoopedSound,
stopLoopedSound,
) where
import Data.Maybe
import Data.IORef
import Control.Monad
import Foreign.Ptr
import Sound.SFML.LowLevel
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 -> Maybe Float -> IO ()
triggerPolySound (PolySound _ _ sounds ref) volume = do
i <- readIORef ref
let sound = sounds !! i
status <- getStatus sound
when (status == Stopped) $ do
writeIORef ref ((i + 1) `mod` length sounds)
sfSound_SetVolume sound ((fromMaybe 1 volume) * 100)
sfSound_Play sound
newtype LoopedSound = LoopedSound (Ptr Sound)
deriving Show
newLoopedSound :: FilePath -> IO LoopedSound
newLoopedSound path = do
buffer <- sfSoundBuffer_CreateFromFile path
sound <- sfSound_Create
sfSound_SetBuffer sound buffer
sfSound_SetLoop sound True
return $ LoopedSound sound
freeLoopedSound :: LoopedSound -> IO ()
freeLoopedSound (LoopedSound ptr) =
sfSound_Destroy ptr
startLoopedSound :: LoopedSound -> IO ()
startLoopedSound (LoopedSound ptr) =
sfSound_Play ptr
stopLoopedSound :: LoopedSound -> IO ()
stopLoopedSound (LoopedSound ptr) =
sfSound_Stop ptr