alure-0.1: source/Sound/UI/ALURE/Raw.hs
module Sound.UI.ALURE.Raw
(
-- * Main and Miscellanious
getVersion,
getErrorString,
getDeviceNames,
initDevice,
shutdownDevice,
-- * File Loading
createBufferFromFile,
bufferDataFromFile,
-- * Streaming
) where
import Sound.UI.ALURE.Internal
import Sound.UI.ALURE.Marshal
import Foreign.Marshal.Alloc
import Foreign.C.String
import Foreign.Ptr
import Foreign.Storable
import Foreign.Marshal.Array
import Control.Monad
import Sound.OpenAL.ALC.Device()
import Sound.OpenAL.ALC.Context
import Sound.OpenAL.AL.Buffer
--------------------------------------------------------------------------------
-- Main and Miscellanious
-- | Gets major and minor version of ALURE C library, if provided.
getVersion :: IO (Maybe Int, Maybe Int)
getVersion = do
alloca $ \pMajor -> do
alloca $ \pMinor -> do
c_alureGetVersion pMajor pMinor
a <- if pMajor == nullPtr then return Nothing
else liftM (Just . fromIntegral) (peek pMajor)
b <- if pMinor == nullPtr then return Nothing
else liftM (Just . fromIntegral) (peek pMinor)
return (a, b)
-- | Returns a string describing the last error encountered.
getErrorString :: IO String
getErrorString = do
c_alureGetErrorString >>= peekCString
-- | Gets a list of device names from OpenAL. This encapsulates AL_ENUMERATE_ALL_EXT
-- (if supported and 'allExt' is true).
getDeviceNames :: Bool -> IO (Maybe [String])
getDeviceNames allExt = do
alloca $ \pCount -> do
pStr <- c_alureGetDeviceNames (marshalBool allExt) pCount
res <- if pStr == nullPtr then return Nothing
else do
count <- peek pCount
liftM Just $ peekStrings (fromIntegral count) pStr
c_alureFreeDeviceNames pStr
return res
where
peekStrings len pStr =
forM [0..len-1] $ \i -> do
p <- peekElemOff pStr i
peekCString p
-- | Opens the named device, creates a context with the given attributes, and sets that
-- context as current. 'name' and 'attrs' would be the same as what's passed to 'openDevice'
-- and 'createContext' respectively.
initDevice :: Maybe String -> [ContextAttribute] -> IO Bool
initDevice name attrs = do
withCStringFromMaybe name $ \p -> do
withArray0 0 (fromContextAttributes attrs) $ \array -> do
liftM unmarshalBool $ c_alureInitDevice p array
where withCStringFromMaybe Nothing f = f nullPtr
withCStringFromMaybe (Just str) f = withCString str f
-- | Destroys the current context and closes its associated device.
shutdownDevice :: IO Bool
shutdownDevice = do
liftM unmarshalBool c_alureShutdownDevice
--------------------------------------------------------------------------------
-- File Loading
-- | Loads the given file into a new OpenAL buffer object. The formats supported depend
-- on the options the C library was compiled with, what libraries available at runtime,
-- and the installed decode callbacks. Requieres an active context.
createBufferFromFile :: String -> IO (Maybe Buffer)
createBufferFromFile fname = do
withCString fname $ \p -> do
liftM unmarshalBuffer $ c_alureCreateBufferFromFile p
-- | Loads the given file into an existing OpenAL buffer object. The previous contents of
-- the buffer are replaced. Requires an active context.
bufferDataFromFile :: Buffer -> String -> IO Bool
bufferDataFromFile buffer fname = do
withCString fname $ \p -> do
liftM unmarshalBool $ c_alureBufferDataFromFile p (marshalBuffer . Just $ buffer)
--------------------------------------------------------------------------------
-- Streaming