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 -- | Create a new music and load it from a file. -- -- This function doesn't start playing the music (call -- 'play' to do so). -- -- Here is a complete list of all the supported audio formats: -- ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, -- w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. 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 -- \return A new sfMusic object (NULL if failed) -- CSFML_AUDIO_API sfMusic* sfMusic_createFromFile(const char* filename); -- | Create a new music and load it from a file in memory. -- -- This function doesn't start playing the music (call -- 'play' to do so). -- -- Here is a complete list of all the supported audio formats: -- ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, -- w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. musicFromMemory :: Ptr a -- ^ Pointer to the file data in memory -> Int -- ^ Size of the data to load, in bytes -> 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 -- \return A new sfMusic object (NULL if failed) -- CSFML_AUDIO_API sfMusic* sfMusic_createFromMemory(const void* data, size_t sizeInBytes); -- | Create a new music and load it from a custom stream. -- -- This function doesn't start playing the music (call -- 'play' to do so). -- -- Here is a complete list of all the supported audio formats: -- ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, -- w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64. 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 -- \return A new sfMusic object (NULL if failed) -- CSFML_AUDIO_API sfMusic* sfMusic_createFromStream(sfInputStream* stream); instance SFResource Music where {-# INLINABLE destroy #-} destroy = sfMusic_destroy foreign import ccall unsafe "sfMusic_destroy" sfMusic_destroy :: Music -> IO () -- CSFML_AUDIO_API void sfMusic_destroy(sfMusic* music); instance SFSoundBuffer Music where {-# INLINABLE getChannelCount #-} getChannelCount = sfMusic_getChannelCount >=> return . fromIntegral {-# INLINABLE getDuration #-} 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 () -- CSFML_AUDIO_API sfTime sfMusic_getDuration(const sfMusic* music); foreign import ccall unsafe "sfMusic_getChannelCount" sfMusic_getChannelCount :: Music -> IO CUInt -- CSFML_AUDIO_API unsigned int sfMusic_getChannelCount(const sfMusic* music); instance SFSampled Music where {-# INLINABLE getSampleRate #-} getSampleRate = sfMusic_getSampleRate foreign import ccall unsafe "sfMusic_getSampleRate" sfMusic_getSampleRate :: Music -> IO Int -- CSFML_AUDIO_API unsigned int sfMusic_getSampleRate(const sfMusic* music); instance SFSound Music where {-# INLINABLE play #-} play = sfMusic_play {-# INLINABLE pause #-} pause = sfMusic_pause {-# INLINABLE stop #-} stop = sfMusic_stop {-# INLINABLE getAttenuation #-} getAttenuation = sfMusic_getAttenuation >=> return . realToFrac {-# INLINABLE getLoop #-} getLoop music = fmap (toEnum . fromIntegral) $ sfMusic_getLoop music {-# INLINABLE getMinDistance #-} getMinDistance = sfMusic_getMinDistance >=> return . realToFrac {-# INLINABLE getPitch #-} getPitch = sfMusic_getPitch >=> return . realToFrac {-# INLINABLE getPlayingOffset #-} getPlayingOffset music = alloca $ \ptr -> sfMusic_getPlayingOffset_helper music ptr >> peek ptr {-# INLINABLE getPosition #-} getPosition music = alloca $ \ptr -> sfMusic_getPosition_helper music ptr >> peek ptr {-# INLINABLE getStatus #-} getStatus = sfMusic_getStatus >=> return . toEnum . fromIntegral {-# INLINABLE getVolume #-} getVolume = sfMusic_getVolume >=> return . realToFrac {-# INLINABLE isRelativeToListener #-} isRelativeToListener = sfMusic_isRelativeToListener >=> return . toEnum . fromIntegral {-# INLINABLE setAttenuation #-} setAttenuation m a = sfMusic_setAttenuation m $ realToFrac a {-# INLINABLE setLoop #-} setLoop music val = sfMusic_setLoop music (fromIntegral . fromEnum $ val) {-# INLINABLE setMinDistance #-} setMinDistance m d = sfMusic_setMinDistance m $ realToFrac d {-# INLINABLE setPitch #-} setPitch m p = sfMusic_setPitch m $ realToFrac p {-# INLINABLE setPlayingOffset #-} setPlayingOffset = sfMusic_setPlayingOffset {-# INLINABLE setPosition #-} setPosition music pos = with pos $ sfMusic_setPosition_helper music {-# INLINABLE setRelativeToListener #-} setRelativeToListener music val = sfMusic_setRelativeToListener music (fromIntegral . fromEnum $ val) {-# INLINABLE setVolume #-} setVolume m v = sfMusic_setVolume m $ realToFrac v foreign import ccall unsafe "sfMusic_play" sfMusic_play :: Music -> IO () -- CSFML_AUDIO_API void sfMusic_play(sfMusic* music); foreign import ccall unsafe "sfMusic_pause" sfMusic_pause :: Music -> IO () -- CSFML_AUDIO_API void sfMusic_pause(sfMusic* music); foreign import ccall unsafe "sfMusic_stop" sfMusic_stop :: Music -> IO () -- CSFML_AUDIO_API void sfMusic_stop(sfMusic* music); foreign import ccall unsafe "sfMusic_getAttenuation" sfMusic_getAttenuation :: Music -> IO CFloat -- CSFML_AUDIO_API float sfMusic_getAttenuation(const sfMusic* music); foreign import ccall unsafe "sfMusic_getLoop" sfMusic_getLoop :: Music -> IO CInt -- CSFML_AUDIO_API sfBool sfMusic_getLoop(const sfMusic* music); foreign import ccall unsafe "sfMusic_getMinDistance" sfMusic_getMinDistance :: Music -> IO CFloat -- CSFML_AUDIO_API float sfMusic_getMinDistance(const sfMusic* music); foreign import ccall unsafe "sfMusic_getPitch" sfMusic_getPitch :: Music -> IO CFloat -- CSFML_AUDIO_API float sfMusic_getPitch(const sfMusic* music); foreign import ccall unsafe "sfMusic_getPlayingOffset_helper" sfMusic_getPlayingOffset_helper :: Music -> Ptr Time -> IO () -- CSFML_AUDIO_API sfTime sfMusic_getPlayingOffset(const sfMusic* music); foreign import ccall unsafe "sfMusic_getPosition_helper" sfMusic_getPosition_helper :: Music -> Ptr Vec3f -> IO () -- CSFML_AUDIO_API sfVector3f sfMusic_getPosition(const sfMusic* music); foreign import ccall unsafe "sfMusic_getStatus" sfMusic_getStatus :: Music -> IO CInt -- CSFML_AUDIO_API sfSoundStatus sfMusic_getStatus(const sfMusic* music); foreign import ccall unsafe "sfMusic_getVolume" sfMusic_getVolume :: Music -> IO CFloat -- CSFML_AUDIO_API float sfMusic_getVolume(const sfMusic* music); foreign import ccall unsafe "sfMusic_isRelativeToListener" sfMusic_isRelativeToListener :: Music -> IO CInt -- CSFML_AUDIO_API sfBool sfMusic_isRelativeToListener(const sfMusic* music); foreign import ccall unsafe "sfMusic_setAttenuation" sfMusic_setAttenuation :: Music -> CFloat -> IO () -- CSFML_AUDIO_API void sfMusic_setAttenuation(sfMusic* music, float attenuation); foreign import ccall unsafe "sfMusic_setLoop" sfMusic_setLoop :: Music -> CInt -> IO () -- CSFML_AUDIO_API void sfMusic_setLoop(sfMusic* music, sfBool loop); foreign import ccall unsafe "sfMusic_setMinDistance" sfMusic_setMinDistance :: Music -> CFloat -> IO () -- CSFML_AUDIO_API void sfMusic_setMinDistance(sfMusic* music, float distance); foreign import ccall unsafe "sfMusic_setPitch" sfMusic_setPitch :: Music -> CFloat -> IO () -- CSFML_AUDIO_API void sfMusic_setPitch(sfMusic* music, float pitch); foreign import ccall unsafe "sfMusic_setPlayingOffset" sfMusic_setPlayingOffset :: Music -> Time -> IO () -- CSFML_AUDIO_API void sfMusic_setPlayingOffset(sfMusic* music, sfTime timeOffset); foreign import ccall unsafe "sfMusic_setPosition_helper" sfMusic_setPosition_helper :: Music -> Ptr Vec3f -> IO () -- CSFML_AUDIO_API void sfMusic_setPosition(sfMusic* music, sfVector3f position); foreign import ccall unsafe "sfMusic_setRelativeToListener" sfMusic_setRelativeToListener :: Music -> CInt -> IO () -- CSFML_AUDIO_API void sfMusic_setRelativeToListener(sfMusic* music, sfBool relative); foreign import ccall unsafe "sfMusic_setVolume" sfMusic_setVolume :: Music -> CFloat -> IO () -- CSFML_AUDIO_API void sfMusic_setVolume(sfMusic* music, float volume);