{-# LANGUAGE ForeignFunctionInterface #-} -------------------------------------------------------------------------------- -- | -- Module : Sound.OpenAL.ALC.Capture -- Copyright : (c) Sven Panne 2003-2013 -- License : BSD3 -- -- Maintainer : Sven Panne -- Stability : stable -- Portability : portable -- -- This module corresponds to section 6.4.2. (Capture) of the OpenAL -- Specification and Reference (version 1.1). -- -------------------------------------------------------------------------------- module Sound.OpenAL.ALC.Capture ( NumSamples, captureOpenDevice, captureStart, captureNumSamples, captureSamples, captureStop, captureCloseDevice, captureDefaultDeviceSpecifier, captureDeviceSpecifier, allCaptureDeviceSpecifiers ) where import Graphics.Rendering.OpenGL.GL.StateVar import Foreign.C.Types import Foreign.Ptr ( Ptr, nullPtr, FunPtr ) import Sound.OpenAL.AL.Buffer ( Format ) import Sound.OpenAL.AL.Format ( marshalFormat ) import Sound.OpenAL.ALC.ALCboolean ( unmarshalALCboolean ) import Sound.OpenAL.ALC.BasicTypes ( ALCchar, ALCuint, ALCenum, ALCsizei, ALCboolean ) import Sound.OpenAL.ALC.Context ( Frequency ) import Sound.OpenAL.ALC.Device ( Device ) import Sound.OpenAL.ALC.Extensions ( alcProcAddress ) import Sound.OpenAL.ALC.QueryUtils ( IntQuery(..), getInteger ) import Sound.OpenAL.ALC.QueryUtils ( StringQuery(..), getString, getStringRaw, alcIsExtensionPresent ) import Sound.OpenAL.ALC.String ( withALCString, peekALCStrings ) import Sound.OpenAL.Config ( ALCdevice(..), marshalDevice, unmarshalDevice ) -------------------------------------------------------------------------------- type NumSamples = ALCsizei -------------------------------------------------------------------------------- type Invoker a = FunPtr a -> a getCaptureFunc :: String -> IO (FunPtr a) getCaptureFunc = get . alcProcAddress Nothing -------------------------------------------------------------------------------- captureOpenDevice :: Maybe String -> Frequency -> Format -> NumSamples -> IO (Maybe Device) captureOpenDevice maybeDeviceSpec frequency format size = do funPtr <- getCaptureFunc "alcCaptureOpenDevice" let open deviceSpec = invokeCaptureOpenDevice funPtr deviceSpec (round frequency) (fromIntegral (marshalFormat format)) size fmap unmarshalDevice $ (maybe (open nullPtr) -- use preferred device (flip withALCString open) maybeDeviceSpec) foreign import ccall unsafe "dynamic" invokeCaptureOpenDevice :: Invoker (Ptr ALCchar -> ALCuint -> ALCenum -> ALCsizei -> IO ALCdevice) -------------------------------------------------------------------------------- captureStart :: Device -> IO () captureStart = captureStartStop "alcCaptureStart" captureStartStop :: String -> Device -> IO () captureStartStop funName device = do funPtr <- getCaptureFunc funName invokeCaptureStartStop funPtr (marshalDevice device) foreign import ccall unsafe "dynamic" invokeCaptureStartStop :: Invoker (ALCdevice -> IO ()) -------------------------------------------------------------------------------- captureNumSamples :: Device -> GettableStateVar NumSamples captureNumSamples device = makeGettableStateVar $ fmap fromIntegral (getInteger (Just device) CaptureSamples) -------------------------------------------------------------------------------- captureSamples :: Device -> Ptr a -> NumSamples -> IO () captureSamples device buf n = do funPtr <- getCaptureFunc "alcCaptureSamples" invokeCaptureSamples funPtr (marshalDevice device) buf n foreign import ccall unsafe "dynamic" invokeCaptureSamples :: Invoker (ALCdevice -> Ptr a -> NumSamples -> IO ()) -------------------------------------------------------------------------------- captureStop :: Device -> IO () captureStop = captureStartStop "alcCaptureStop" -------------------------------------------------------------------------------- captureCloseDevice :: Device -> IO Bool captureCloseDevice device = do funPtr <- getCaptureFunc "alcCaptureCloseDevice" fmap unmarshalALCboolean . invokeCaptureCloseDevice funPtr . marshalDevice $ device foreign import ccall unsafe "dynamic" invokeCaptureCloseDevice :: Invoker (ALCdevice -> IO ALCboolean) -------------------------------------------------------------------------------- -- | Contains the name of the default capture device. captureDefaultDeviceSpecifier :: GettableStateVar String captureDefaultDeviceSpecifier = makeGettableStateVar $ getString Nothing CaptureDefaultDeviceSpecifier -------------------------------------------------------------------------------- -- | Contains the specifier string for the given capture device. captureDeviceSpecifier :: Device -> GettableStateVar String captureDeviceSpecifier device = makeGettableStateVar $ getString (Just device) CaptureDeviceSpecifier -------------------------------------------------------------------------------- -- | Contains a list of specifiers for all available capture devices. allCaptureDeviceSpecifiers :: GettableStateVar [String] allCaptureDeviceSpecifiers = makeGettableStateVar $ do enumExtPresent <- get (alcIsExtensionPresent Nothing "ALC_ENUMERATION_EXT") if enumExtPresent then peekALCStrings =<< getStringRaw Nothing CaptureDeviceSpecifier else fmap (\s -> [s]) $ get captureDefaultDeviceSpecifier