module SFML.Audio.Music
(
module SFML.Utils
, musicFromFile
, musicFromMemory
, musicFromStream
, destroy
, setLoop
, getLoop
, getDuration
, play
, pause
, stop
, getChannelCount
, getSampleRate
, getStatus
, getPlayingOffset
, setPitch
, setVolume
, setPosition
, setRelativeToListener
, setMinDistance
, setAttenuation
, setPlayingOffset
, getPitch
, getVolume
, getPosition
, isRelativeToListener
, getMinDistance
, getAttenuation
)
where
import SFML.Audio.SFSampled
import SFML.Audio.SFSound
import SFML.Audio.SFSoundBuffer
import SFML.Audio.SoundStatus
import SFML.Audio.Types
import SFML.SFException
import SFML.SFResource
import SFML.System.InputStream
import SFML.System.Time
import SFML.System.Vector3
import SFML.Utils
import Control.Monad ((>=>))
import Foreign.Marshal.Utils (with)
import Foreign.Marshal.Alloc (alloca)
import Foreign.C.String
import Foreign.C.Types
import Foreign.Ptr (Ptr, nullPtr)
import Foreign.Storable (peek)
checkNull :: Music -> Maybe Music
checkNull music@(Music ptr) = if ptr == nullPtr then Nothing else Just music
musicFromFile :: FilePath -> IO (Either SFException Music)
musicFromFile path =
let err = SFException $ "Failed loading music from file " ++ path
in withCAString path $ \cstr -> sfMusic_createFromFile cstr >>= return . tagErr err . checkNull
foreign import ccall unsafe "sfMusic_createFromFile"
sfMusic_createFromFile :: CString -> IO Music
musicFromMemory
:: Ptr a
-> Int
-> IO (Either SFException Music)
musicFromMemory ptr size =
let err = SFException $ "Failed loading music from memory address " ++ show ptr
in fmap (tagErr err . checkNull) $ sfMusic_createFromMemory ptr (fromIntegral size)
foreign import ccall unsafe "sfMusic_createFromMemory"
sfMusic_createFromMemory :: Ptr a -> CUInt -> IO Music
musicFromStream :: InputStream -> IO (Either SFException Music)
musicFromStream is =
let err = SFException $ "Failed loading music from input stream " ++ show is
in with is $ \ptr -> sfMusic_createFromStream ptr >>= return . tagErr err . checkNull
foreign import ccall unsafe "sfMusic_createFromStream"
sfMusic_createFromStream :: Ptr InputStream -> IO Music
instance SFResource Music where
destroy = sfMusic_destroy
foreign import ccall unsafe "sfMusic_destroy"
sfMusic_destroy :: Music -> IO ()
instance SFSoundBuffer Music where
getChannelCount = sfMusic_getChannelCount >=> return . fromIntegral
getDuration music = alloca $ \ptr -> sfMusic_getDuration_helper music ptr >> peek ptr
foreign import ccall unsafe "sfMusic_getDuration_helper"
sfMusic_getDuration_helper :: Music -> Ptr Time -> IO ()
foreign import ccall unsafe "sfMusic_getChannelCount"
sfMusic_getChannelCount :: Music -> IO CUInt
instance SFSampled Music where
getSampleRate = sfMusic_getSampleRate
foreign import ccall unsafe "sfMusic_getSampleRate"
sfMusic_getSampleRate :: Music -> IO Int
instance SFSound Music where
play = sfMusic_play
pause = sfMusic_pause
stop = sfMusic_stop
getAttenuation = sfMusic_getAttenuation >=> return . realToFrac
getLoop music = fmap (toEnum . fromIntegral) $ sfMusic_getLoop music
getMinDistance = sfMusic_getMinDistance >=> return . realToFrac
getPitch = sfMusic_getPitch >=> return . realToFrac
getPlayingOffset music = alloca $ \ptr -> sfMusic_getPlayingOffset_helper music ptr >> peek ptr
getPosition music = alloca $ \ptr -> sfMusic_getPosition_helper music ptr >> peek ptr
getStatus = sfMusic_getStatus >=> return . toEnum . fromIntegral
getVolume = sfMusic_getVolume >=> return . realToFrac
isRelativeToListener = sfMusic_isRelativeToListener >=> return . toEnum . fromIntegral
setAttenuation m a = sfMusic_setAttenuation m $ realToFrac a
setLoop music val = sfMusic_setLoop music (fromIntegral . fromEnum $ val)
setMinDistance m d = sfMusic_setMinDistance m $ realToFrac d
setPitch m p = sfMusic_setPitch m $ realToFrac p
setPlayingOffset = sfMusic_setPlayingOffset
setPosition music pos = with pos $ sfMusic_setPosition_helper music
setRelativeToListener music val = sfMusic_setRelativeToListener music (fromIntegral . fromEnum $ val)
setVolume m v = sfMusic_setVolume m $ realToFrac v
foreign import ccall unsafe "sfMusic_play"
sfMusic_play :: Music -> IO ()
foreign import ccall unsafe "sfMusic_pause"
sfMusic_pause :: Music -> IO ()
foreign import ccall unsafe "sfMusic_stop"
sfMusic_stop :: Music -> IO ()
foreign import ccall unsafe "sfMusic_getAttenuation"
sfMusic_getAttenuation :: Music -> IO CFloat
foreign import ccall unsafe "sfMusic_getLoop"
sfMusic_getLoop :: Music -> IO CInt
foreign import ccall unsafe "sfMusic_getMinDistance"
sfMusic_getMinDistance :: Music -> IO CFloat
foreign import ccall unsafe "sfMusic_getPitch"
sfMusic_getPitch :: Music -> IO CFloat
foreign import ccall unsafe "sfMusic_getPlayingOffset_helper"
sfMusic_getPlayingOffset_helper :: Music -> Ptr Time -> IO ()
foreign import ccall unsafe "sfMusic_getPosition_helper"
sfMusic_getPosition_helper :: Music -> Ptr Vec3f -> IO ()
foreign import ccall unsafe "sfMusic_getStatus"
sfMusic_getStatus :: Music -> IO CInt
foreign import ccall unsafe "sfMusic_getVolume"
sfMusic_getVolume :: Music -> IO CFloat
foreign import ccall unsafe "sfMusic_isRelativeToListener"
sfMusic_isRelativeToListener :: Music -> IO CInt
foreign import ccall unsafe "sfMusic_setAttenuation"
sfMusic_setAttenuation :: Music -> CFloat -> IO ()
foreign import ccall unsafe "sfMusic_setLoop"
sfMusic_setLoop :: Music -> CInt -> IO ()
foreign import ccall unsafe "sfMusic_setMinDistance"
sfMusic_setMinDistance :: Music -> CFloat -> IO ()
foreign import ccall unsafe "sfMusic_setPitch"
sfMusic_setPitch :: Music -> CFloat -> IO ()
foreign import ccall unsafe "sfMusic_setPlayingOffset"
sfMusic_setPlayingOffset :: Music -> Time -> IO ()
foreign import ccall unsafe "sfMusic_setPosition_helper"
sfMusic_setPosition_helper :: Music -> Ptr Vec3f -> IO ()
foreign import ccall unsafe "sfMusic_setRelativeToListener"
sfMusic_setRelativeToListener :: Music -> CInt -> IO ()
foreign import ccall unsafe "sfMusic_setVolume"
sfMusic_setVolume :: Music -> CFloat -> IO ()