h-raylib-5.6.0.0: src/Raylib/Core/Audio.hs
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE TemplateHaskell #-}
-- | Bindings to @raudio@
module Raylib.Core.Audio
( -- * High level
initAudioDevice,
closeAudioDevice,
isAudioDeviceReady,
setMasterVolume,
getMasterVolume,
loadWave,
loadWaveFromMemory,
loadSound,
loadSoundFromWave,
loadSoundAlias,
unloadSoundAlias,
updateSound,
unloadSound,
isWaveValid,
isSoundValid,
exportWave,
exportWaveAsCode,
playSound,
stopSound,
pauseSound,
resumeSound,
isSoundPlaying,
setSoundVolume,
setSoundPitch,
setSoundPan,
waveCopy,
waveCrop,
waveFormat,
loadWaveSamples,
loadMusicStream,
loadMusicStreamFromMemory,
unloadMusicStream,
isMusicValid,
playMusicStream,
isMusicStreamPlaying,
updateMusicStream,
stopMusicStream,
pauseMusicStream,
resumeMusicStream,
seekMusicStream,
setMusicVolume,
setMusicPitch,
setMusicPan,
getMusicTimeLength,
getMusicTimePlayed,
loadAudioStream,
unloadAudioStream,
isAudioStreamValid,
updateAudioStream,
isAudioStreamProcessed,
playAudioStream,
pauseAudioStream,
resumeAudioStream,
isAudioStreamPlaying,
stopAudioStream,
setAudioStreamVolume,
setAudioStreamPitch,
setAudioStreamPan,
setAudioStreamBufferSizeDefault,
setAudioStreamCallback,
attachAudioStreamProcessor,
detachAudioStreamProcessor,
attachAudioMixedProcessor,
detachAudioMixedProcessor,
-- * Native
c'initAudioDevice,
c'closeAudioDevice,
c'isAudioDeviceReady,
c'setMasterVolume,
c'getMasterVolume,
c'loadWave,
c'loadWaveFromMemory,
c'loadSound,
c'loadSoundFromWave,
c'loadSoundAlias,
c'updateSound,
c'isWaveValid,
c'unloadWave,
c'isSoundValid,
c'unloadSound,
c'unloadSoundAlias,
c'exportWave,
c'exportWaveAsCode,
c'playSound,
c'stopSound,
c'pauseSound,
c'resumeSound,
c'isSoundPlaying,
c'setSoundVolume,
c'setSoundPitch,
c'setSoundPan,
c'waveCopy,
c'waveCrop,
c'waveFormat,
c'loadWaveSamples,
c'unloadWaveSamples,
c'loadMusicStream,
c'loadMusicStreamFromMemory,
c'isMusicValid,
c'unloadMusicStream,
c'playMusicStream,
c'isMusicStreamPlaying,
c'updateMusicStream,
c'stopMusicStream,
c'pauseMusicStream,
c'resumeMusicStream,
c'seekMusicStream,
c'setMusicVolume,
c'setMusicPitch,
c'setMusicPan,
c'getMusicTimeLength,
c'getMusicTimePlayed,
c'loadAudioStream,
c'isAudioStreamValid,
c'unloadAudioStream,
c'updateAudioStream,
c'isAudioStreamProcessed,
c'playAudioStream,
c'pauseAudioStream,
c'resumeAudioStream,
c'isAudioStreamPlaying,
c'stopAudioStream,
c'setAudioStreamVolume,
c'setAudioStreamPitch,
c'setAudioStreamPan,
c'setAudioStreamBufferSizeDefault,
c'setAudioStreamCallback,
c'attachAudioStreamProcessor,
c'detachAudioStreamProcessor,
c'attachAudioMixedProcessor,
c'detachAudioMixedProcessor,
-- * Callbacks
mk'audioCallback,
createAudioCallback,
)
where
import Foreign (Ptr, Storable (peek, sizeOf), castPtr, toBool, castFunPtr)
import Foreign.C
( CBool (..),
CFloat (..),
CInt (..),
CString,
CUChar (..),
CUInt (..),
withCString,
)
import Raylib.Internal (WindowResources, unloadSingleAudioBuffer, unloadSingleAudioBufferAlias, unloadSingleCtxDataPtr, addFunPtr, unloadSingleFunPtr, releaseAudioWindowResources)
import Raylib.Internal.Foreign
( pop,
popCArray,
withFreeable,
withFreeableArrayLen,
)
import Raylib.Internal.TH (genNative)
import Raylib.Types
( AudioCallback,
AudioStream (audioStream'buffer),
C'AudioCallback,
Music (music'ctxData, music'ctxType),
Sound (sound'stream),
Wave (wave'channels, wave'frameCount),
)
$( genNative
[ ("c'initAudioDevice", "InitAudioDevice_", "rl_bindings.h", [t|IO ()|]),
("c'closeAudioDevice", "CloseAudioDevice_", "rl_bindings.h", [t|IO ()|]),
("c'isAudioDeviceReady", "IsAudioDeviceReady_", "rl_bindings.h", [t|IO CBool|]),
("c'setMasterVolume", "SetMasterVolume_", "rl_bindings.h", [t|CFloat -> IO ()|]),
("c'getMasterVolume", "GetMasterVolume_", "rl_bindings.h", [t|IO CFloat|]),
("c'loadWave", "LoadWave_", "rl_bindings.h", [t|CString -> IO (Ptr Wave)|]),
("c'loadWaveFromMemory", "LoadWaveFromMemory_", "rl_bindings.h", [t|CString -> Ptr CUChar -> CInt -> IO (Ptr Wave)|]),
("c'loadSound", "LoadSound_", "rl_bindings.h", [t|CString -> IO (Ptr Sound)|]),
("c'loadSoundFromWave", "LoadSoundFromWave_", "rl_bindings.h", [t|Ptr Wave -> IO (Ptr Sound)|]),
("c'loadSoundAlias", "LoadSoundAlias_", "rl_bindings.h", [t|Ptr Sound -> IO (Ptr Sound)|]),
("c'updateSound", "UpdateSound_", "rl_bindings.h", [t|Ptr Sound -> Ptr () -> CInt -> IO ()|]),
("c'isWaveValid", "IsWaveValid_", "rl_bindings.h", [t|Ptr Wave -> IO CBool|]),
("c'unloadWave", "UnloadWave_", "rl_bindings.h", [t|Ptr Wave -> IO ()|]),
("c'isSoundValid", "IsSoundValid_", "rl_bindings.h", [t|Ptr Sound -> IO CBool|]),
("c'unloadSound", "UnloadSound_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),
("c'unloadSoundAlias", "UnloadSoundAlias_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),
("c'exportWave", "ExportWave_", "rl_bindings.h", [t|Ptr Wave -> CString -> IO CBool|]),
("c'exportWaveAsCode", "ExportWaveAsCode_", "rl_bindings.h", [t|Ptr Wave -> CString -> IO CBool|]),
("c'playSound", "PlaySound_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),
("c'stopSound", "StopSound_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),
("c'pauseSound", "PauseSound_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),
("c'resumeSound", "ResumeSound_", "rl_bindings.h", [t|Ptr Sound -> IO ()|]),
("c'isSoundPlaying", "IsSoundPlaying_", "rl_bindings.h", [t|Ptr Sound -> IO CBool|]),
("c'setSoundVolume", "SetSoundVolume_", "rl_bindings.h", [t|Ptr Sound -> CFloat -> IO ()|]),
("c'setSoundPitch", "SetSoundPitch_", "rl_bindings.h", [t|Ptr Sound -> CFloat -> IO ()|]),
("c'setSoundPan", "SetSoundPan_", "rl_bindings.h", [t|Ptr Sound -> CFloat -> IO ()|]),
("c'waveCopy", "WaveCopy_", "rl_bindings.h", [t|Ptr Wave -> IO (Ptr Wave)|]),
("c'waveCrop", "WaveCrop_", "rl_bindings.h", [t|Ptr Wave -> CInt -> CInt -> IO ()|]),
("c'waveFormat", "WaveFormat_", "rl_bindings.h", [t|Ptr Wave -> CInt -> CInt -> CInt -> IO ()|]),
("c'loadWaveSamples", "LoadWaveSamples_", "rl_bindings.h", [t|Ptr Wave -> IO (Ptr CFloat)|]),
("c'unloadWaveSamples", "UnloadWaveSamples_", "rl_bindings.h", [t|Ptr CFloat -> IO ()|]),
("c'loadMusicStream", "LoadMusicStream_", "rl_bindings.h", [t|CString -> IO (Ptr Music)|]),
("c'loadMusicStreamFromMemory", "LoadMusicStreamFromMemory_", "rl_bindings.h", [t|CString -> Ptr CUChar -> CInt -> IO (Ptr Music)|]),
("c'isMusicValid", "IsMusicValid_", "rl_bindings.h", [t|Ptr Music -> IO CBool|]),
("c'unloadMusicStream", "UnloadMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),
("c'playMusicStream", "PlayMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),
("c'isMusicStreamPlaying", "IsMusicStreamPlaying_", "rl_bindings.h", [t|Ptr Music -> IO CBool|]),
("c'updateMusicStream", "UpdateMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),
("c'stopMusicStream", "StopMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),
("c'pauseMusicStream", "PauseMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),
("c'resumeMusicStream", "ResumeMusicStream_", "rl_bindings.h", [t|Ptr Music -> IO ()|]),
("c'seekMusicStream", "SeekMusicStream_", "rl_bindings.h", [t|Ptr Music -> CFloat -> IO ()|]),
("c'setMusicVolume", "SetMusicVolume_", "rl_bindings.h", [t|Ptr Music -> CFloat -> IO ()|]),
("c'setMusicPitch", "SetMusicPitch_", "rl_bindings.h", [t|Ptr Music -> CFloat -> IO ()|]),
("c'setMusicPan", "SetMusicPan_", "rl_bindings.h", [t|Ptr Music -> CFloat -> IO ()|]),
("c'getMusicTimeLength", "GetMusicTimeLength_", "rl_bindings.h", [t|Ptr Music -> IO CFloat|]),
("c'getMusicTimePlayed", "GetMusicTimePlayed_", "rl_bindings.h", [t|Ptr Music -> IO CFloat|]),
("c'loadAudioStream", "LoadAudioStream_", "rl_bindings.h", [t|CUInt -> CUInt -> CUInt -> IO (Ptr AudioStream)|]),
("c'isAudioStreamValid", "IsAudioStreamValid_", "rl_bindings.h", [t|Ptr AudioStream -> IO CBool|]),
("c'unloadAudioStream", "UnloadAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> IO ()|]),
("c'updateAudioStream", "UpdateAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> Ptr () -> CInt -> IO ()|]),
("c'isAudioStreamProcessed", "IsAudioStreamProcessed_", "rl_bindings.h", [t|Ptr AudioStream -> IO CBool|]),
("c'playAudioStream", "PlayAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> IO ()|]),
("c'pauseAudioStream", "PauseAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> IO ()|]),
("c'resumeAudioStream", "ResumeAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> IO ()|]),
("c'isAudioStreamPlaying", "IsAudioStreamPlaying_", "rl_bindings.h", [t|Ptr AudioStream -> IO CBool|]),
("c'stopAudioStream", "StopAudioStream_", "rl_bindings.h", [t|Ptr AudioStream -> IO ()|]),
("c'setAudioStreamVolume", "SetAudioStreamVolume_", "rl_bindings.h", [t|Ptr AudioStream -> CFloat -> IO ()|]),
("c'setAudioStreamPitch", "SetAudioStreamPitch_", "rl_bindings.h", [t|Ptr AudioStream -> CFloat -> IO ()|]),
("c'setAudioStreamPan", "SetAudioStreamPan_", "rl_bindings.h", [t|Ptr AudioStream -> CFloat -> IO ()|]),
("c'setAudioStreamBufferSizeDefault", "SetAudioStreamBufferSizeDefault_", "rl_bindings.h", [t|CInt -> IO ()|]),
("c'setAudioStreamCallback", "SetAudioStreamCallback_", "rl_bindings.h", [t|Ptr AudioStream -> C'AudioCallback -> IO ()|]),
("c'attachAudioStreamProcessor", "AttachAudioStreamProcessor_", "rl_bindings.h", [t|Ptr AudioStream -> C'AudioCallback -> IO ()|]),
("c'detachAudioStreamProcessor", "DetachAudioStreamProcessor_", "rl_bindings.h", [t|Ptr AudioStream -> C'AudioCallback -> IO ()|]),
("c'attachAudioMixedProcessor", "AttachAudioMixedProcessor_", "rl_bindings.h", [t|C'AudioCallback -> IO ()|]),
("c'detachAudioMixedProcessor", "DetachAudioMixedProcessor_", "rl_bindings.h", [t|C'AudioCallback -> IO ()|])
]
)
initAudioDevice :: IO ()
initAudioDevice = c'initAudioDevice
closeAudioDevice :: Maybe WindowResources -> IO ()
closeAudioDevice wr = do
mapM_ releaseAudioWindowResources wr
c'closeAudioDevice
isAudioDeviceReady :: IO Bool
isAudioDeviceReady = toBool <$> c'isAudioDeviceReady
setMasterVolume :: Float -> IO ()
setMasterVolume volume = c'setMasterVolume (realToFrac volume)
getMasterVolume :: IO Float
getMasterVolume = realToFrac <$> c'getMasterVolume
loadWave :: String -> IO Wave
loadWave fileName = withCString fileName c'loadWave >>= pop
loadWaveFromMemory :: String -> [Integer] -> IO Wave
loadWaveFromMemory fileType fileData = withCString fileType (\f -> withFreeableArrayLen (map fromIntegral fileData) (\size d -> c'loadWaveFromMemory f d (fromIntegral $ size * sizeOf (0 :: CUChar)))) >>= pop
loadSound :: String -> IO Sound
loadSound fileName = withCString fileName c'loadSound >>= pop
loadSoundFromWave :: Wave -> IO Sound
loadSoundFromWave wave = withFreeable wave c'loadSoundFromWave >>= pop
loadSoundAlias :: Sound -> IO Sound
loadSoundAlias source = withFreeable source c'loadSoundAlias >>= pop
-- | Unloads a `managed` sound alias from RAM
unloadSoundAlias :: Sound -> WindowResources -> IO ()
unloadSoundAlias sound = unloadSingleAudioBufferAlias (castPtr (audioStream'buffer (sound'stream sound)))
updateSound :: Sound -> Ptr () -> Int -> IO ()
updateSound sound dataValue sampleCount = withFreeable sound (\s -> c'updateSound s dataValue (fromIntegral sampleCount))
-- | Unloads a `managed` sound from RAM
unloadSound :: Sound -> WindowResources -> IO ()
unloadSound sound = unloadAudioStream (sound'stream sound)
isWaveValid :: Wave -> IO Bool
isWaveValid wave = toBool <$> withFreeable wave c'isWaveValid
isSoundValid :: Sound -> IO Bool
isSoundValid sound = toBool <$> withFreeable sound c'isSoundValid
exportWave :: Wave -> String -> IO Bool
exportWave wave fileName = toBool <$> withFreeable wave (withCString fileName . c'exportWave)
exportWaveAsCode :: Wave -> String -> IO Bool
exportWaveAsCode wave fileName = toBool <$> withFreeable wave (withCString fileName . c'exportWaveAsCode)
playSound :: Sound -> IO ()
playSound sound = withFreeable sound c'playSound
stopSound :: Sound -> IO ()
stopSound sound = withFreeable sound c'stopSound
pauseSound :: Sound -> IO ()
pauseSound sound = withFreeable sound c'pauseSound
resumeSound :: Sound -> IO ()
resumeSound sound = withFreeable sound c'resumeSound
isSoundPlaying :: Sound -> IO Bool
isSoundPlaying sound = toBool <$> withFreeable sound c'isSoundPlaying
setSoundVolume :: Sound -> Float -> IO ()
setSoundVolume sound volume = withFreeable sound (\s -> c'setSoundVolume s (realToFrac volume))
setSoundPitch :: Sound -> Float -> IO ()
setSoundPitch sound pitch = withFreeable sound (\s -> c'setSoundPitch s (realToFrac pitch))
setSoundPan :: Sound -> Float -> IO ()
setSoundPan sound pan = withFreeable sound (\s -> c'setSoundPan s (realToFrac pan))
waveCopy :: Wave -> IO Wave
waveCopy wave = withFreeable wave c'waveCopy >>= pop
waveCrop :: Wave -> Int -> Int -> IO Wave
waveCrop wave initFrame finalFrame = do
new <- waveCopy wave
withFreeable new (\w -> c'waveCrop w (fromIntegral initFrame) (fromIntegral finalFrame) >> peek w)
waveFormat :: Wave -> Int -> Int -> Int -> IO ()
waveFormat wave sampleRate sampleSize channels = do
new <- waveCopy wave
withFreeable new (\n -> c'waveFormat n (fromIntegral sampleRate) (fromIntegral sampleSize) (fromIntegral channels))
loadWaveSamples :: Wave -> IO [Float]
loadWaveSamples wave =
withFreeable
wave
(\w -> map realToFrac <$> (popCArray (fromIntegral $ wave'frameCount wave * wave'channels wave) =<< c'loadWaveSamples w))
loadMusicStream :: String -> IO Music
loadMusicStream fileName = withCString fileName c'loadMusicStream >>= pop
loadMusicStreamFromMemory :: String -> [Integer] -> IO Music
loadMusicStreamFromMemory fileType streamData =
withCString fileType (\t -> withFreeableArrayLen (map fromIntegral streamData) (\size d -> c'loadMusicStreamFromMemory t d (fromIntegral $ size * sizeOf (0 :: CUChar)))) >>= pop
-- | Unloads a `managed` music stream from RAM
unloadMusicStream :: Music -> WindowResources -> IO ()
unloadMusicStream music = unloadSingleCtxDataPtr (fromEnum (music'ctxType music)) (music'ctxData music)
isMusicValid :: Music -> IO Bool
isMusicValid music = toBool <$> withFreeable music c'isMusicValid
playMusicStream :: Music -> IO ()
playMusicStream music = withFreeable music c'playMusicStream
isMusicStreamPlaying :: Music -> IO Bool
isMusicStreamPlaying music = toBool <$> withFreeable music c'isMusicStreamPlaying
updateMusicStream :: Music -> IO ()
updateMusicStream music = withFreeable music c'updateMusicStream
stopMusicStream :: Music -> IO ()
stopMusicStream music = withFreeable music c'stopMusicStream
pauseMusicStream :: Music -> IO ()
pauseMusicStream music = withFreeable music c'pauseMusicStream
resumeMusicStream :: Music -> IO ()
resumeMusicStream music = withFreeable music c'resumeMusicStream
seekMusicStream :: Music -> Float -> IO ()
seekMusicStream music position = withFreeable music (\m -> c'seekMusicStream m (realToFrac position))
setMusicVolume :: Music -> Float -> IO ()
setMusicVolume music volume = withFreeable music (\m -> c'setMusicVolume m (realToFrac volume))
setMusicPitch :: Music -> Float -> IO ()
setMusicPitch music pitch = withFreeable music (\m -> c'setMusicPitch m (realToFrac pitch))
setMusicPan :: Music -> Float -> IO ()
setMusicPan music pan = withFreeable music (\m -> c'setMusicPan m (realToFrac pan))
getMusicTimeLength :: Music -> IO Float
getMusicTimeLength music = realToFrac <$> withFreeable music c'getMusicTimeLength
getMusicTimePlayed :: Music -> IO Float
getMusicTimePlayed music = realToFrac <$> withFreeable music c'getMusicTimePlayed
loadAudioStream :: Integer -> Integer -> Integer -> IO AudioStream
loadAudioStream sampleRate sampleSize channels = c'loadAudioStream (fromIntegral sampleRate) (fromIntegral sampleSize) (fromIntegral channels) >>= pop
-- | Unloads a `managed` audio stream from RAM
unloadAudioStream :: AudioStream -> WindowResources -> IO ()
unloadAudioStream stream = unloadSingleAudioBuffer (castPtr $ audioStream'buffer stream)
isAudioStreamValid :: AudioStream -> IO Bool
isAudioStreamValid stream = toBool <$> withFreeable stream c'isAudioStreamValid
updateAudioStream :: AudioStream -> Ptr () -> Int -> IO ()
updateAudioStream stream value frameCount = withFreeable stream (\s -> c'updateAudioStream s value (fromIntegral frameCount))
isAudioStreamProcessed :: AudioStream -> IO Bool
isAudioStreamProcessed stream = toBool <$> withFreeable stream c'isAudioStreamProcessed
playAudioStream :: AudioStream -> IO ()
playAudioStream stream = withFreeable stream c'playAudioStream
pauseAudioStream :: AudioStream -> IO ()
pauseAudioStream stream = withFreeable stream c'pauseAudioStream
resumeAudioStream :: AudioStream -> IO ()
resumeAudioStream stream = withFreeable stream c'resumeAudioStream
isAudioStreamPlaying :: AudioStream -> IO Bool
isAudioStreamPlaying stream = toBool <$> withFreeable stream c'isAudioStreamPlaying
stopAudioStream :: AudioStream -> IO ()
stopAudioStream stream = withFreeable stream c'stopAudioStream
setAudioStreamVolume :: AudioStream -> Float -> IO ()
setAudioStreamVolume stream volume = withFreeable stream (\s -> c'setAudioStreamVolume s (realToFrac volume))
setAudioStreamPitch :: AudioStream -> Float -> IO ()
setAudioStreamPitch stream pitch = withFreeable stream (\s -> c'setAudioStreamPitch s (realToFrac pitch))
setAudioStreamPan :: AudioStream -> Float -> IO ()
setAudioStreamPan stream pan = withFreeable stream (\s -> c'setAudioStreamPan s (realToFrac pan))
setAudioStreamBufferSizeDefault :: Int -> IO ()
setAudioStreamBufferSizeDefault = c'setAudioStreamBufferSizeDefault . fromIntegral
setAudioStreamCallback :: AudioStream -> AudioCallback -> WindowResources -> IO C'AudioCallback
setAudioStreamCallback stream callback window =
withFreeable
stream
( \s ->
do
c <- createAudioCallback callback
addFunPtr (castFunPtr c) window
c'setAudioStreamCallback s c
return c
)
attachAudioStreamProcessor :: AudioStream -> AudioCallback -> WindowResources -> IO C'AudioCallback
attachAudioStreamProcessor stream callback window =
withFreeable
stream
( \s ->
do
c <- createAudioCallback callback
addFunPtr (castFunPtr c) window
c'attachAudioStreamProcessor s c
return c
)
detachAudioStreamProcessor :: AudioStream -> C'AudioCallback -> WindowResources -> IO ()
detachAudioStreamProcessor stream callback window =
withFreeable stream (`c'detachAudioStreamProcessor` callback) >> unloadSingleFunPtr (castFunPtr callback) window
attachAudioMixedProcessor :: AudioCallback -> WindowResources -> IO C'AudioCallback
attachAudioMixedProcessor callback window =
do
c <- createAudioCallback callback
addFunPtr (castFunPtr c) window
c'attachAudioMixedProcessor c
return c
detachAudioMixedProcessor :: C'AudioCallback -> WindowResources -> IO ()
detachAudioMixedProcessor callback window = c'detachAudioMixedProcessor callback >> unloadSingleFunPtr (castFunPtr callback) window
foreign import ccall unsafe "wrapper"
mk'audioCallback ::
(Ptr () -> CUInt -> IO ()) -> IO C'AudioCallback
-- foreign import ccall unsafe "dynamic"
-- mK'audioCallback ::
-- C'AudioCallback -> (Ptr () -> CUInt -> IO ())
createAudioCallback :: AudioCallback -> IO C'AudioCallback
createAudioCallback callback =
mk'audioCallback
(\bufferData frames -> callback bufferData (fromIntegral frames))