-- Copyright (c) 2010 Philipp Balzarek (p.balzarek@googlemail.com) -- -- License: MIT; See LICENSE file {-# LANGUAGE ForeignFunctionInterface #-} -- | Low level bindings to the JACK \ functionality -- -- This is a faithfull representation of the C api. -- For now please refer to the JACK api documentation for a complete -- description of the functionality -- -- -- -- A somewhat safer interface can be found at "Sound.Jack.JackMonad" module Sound.Jack.Bindings ( withOpenClient , withOpenClientDefaultServer , Raw.clientOpenWithDefaultServer , Raw.clientOpenWithServerName , Raw.clientClose , Raw.clientNameSize , Raw.getClientName , Raw.internalClientNew , Raw.internalClientClose , Raw.activate , Raw.deactivate , Raw.clientThreadId , Raw.isRealtime , Raw.cycleWait , Raw.cycleSignal , setProcessThread , setThreadInitCallback , setProcessCallback , setFreewheelCallback , setBufferSizeCallback , setSampleRateCallback , setClientRegistrationCallback , setPortRegistrationCallback , setPortConnectCallback , setGraphOrderCallback , setXrunCallback , Raw.setFreewheel , Raw.setBufferSize , Raw.getSampleRate , Raw.getBufferSize , Raw.engineTakeoverTimebase , Raw.cpuLoad , Raw.portRegister , Raw.portUnregister , Raw.portGetBuffer , Raw.portName , Raw.portShortName , Raw.portFlags , Raw.portType , Raw.portIsMine , Raw.portConnected , Raw.portGetConnections , Raw.portGetAllConnections , Raw.jackPortGetLatency , Raw.jackPortGetTotalLatency , Raw.portSetLatency , Raw.recomputeTotalLatencies , Raw.portSetName , Raw.portSetAlias , Raw.portUnsetAlias , Raw.portRequestMonitor , Raw.portRequestMonitorByName , Raw.portEnsureMonitor , Raw.portMonitoringInput , Raw.connect , Raw.disconnect , Raw.portDisconnect , Raw.portNameSize , Raw.portTypeSize , Raw.getPorts , Raw.portByName , Raw.portById , Raw.framesSinceCycleStart , Raw.frameTime , Raw.framesToTime , Raw.timeToFrames , Raw.getTime , Raw.Port , Raw.PortFlags(..) , Raw.AudioSample , BufferSizeCallback , ClientRegistrationCallback , FreewheelCallback , GraphOrderCallback , PortConnectCallback , PortRegistrationCallback , ProcessCallback , SampleRateCallback , ThreadCallback , ThreadInitCallback , XRunCallback , Raw.Options(..) , Raw.Client -- opaque , Raw.Status(..) , Raw.PortID -- opaque , Raw.defaultAudioType , Raw.defaultMidiType , Raw.fromThread , Raw.NFrames , Raw.Thread , Raw.Time ) where import qualified Sound.Jack.RawBindings as Raw import Control.Monad import Control.Exception import Foreign import Foreign.C ignore = (>> return ()) -- | Open a Jack client and run the supplied action, handling errors and closing the client withOpenClient :: String -- ^ server name -> [Raw.Options] -- ^ client options -> String -- ^ client name -> (Raw.Client -> [Raw.Status] -> IO a) -- ^ action to be run with the open client -> ([Raw.Status] -> IO a) -- ^ action to be run on error -> IO a -- ^ withOpenClient serverName options clientName action errorHandler = bracket (Raw.clientOpenWithServerName clientName options serverName ) (\(client,flags) -> unless (Raw.Failure `elem` flags) (ignore $ Raw.clientClose client )) (\(client, flags) -> if (Raw.Failure `elem` flags) then errorHandler flags else action client flags) -- | Open a Jack client on the default server and run the supplied action, -- handling errors and closing the client withOpenClientDefaultServer :: [Raw.Options] -- ^ client options -> String -- ^ The client name -> (Raw.Client -> [Raw.Status] -> IO a) -- ^ action to be run with the open client -> ([Raw.Status] -> IO a) -- ^ action to be run at error -> IO a -- ^ withOpenClientDefaultServer options clientName action errorHandler = bracket (Raw.clientOpenWithDefaultServer clientName options) (\(client,flags) -> unless (Raw.Failure `elem` flags) (ignore $ Raw.clientClose client )) (\(client, flags) -> if Raw.Failure `elem` flags then errorHandler flags else action client flags ) type ThreadCallback = Ptr () -> IO (Ptr ()) type BufferSizeCallback = CUInt -> Ptr () -> IO CInt type ClientRegistrationCallback = Ptr CChar -> CInt -> Ptr () -> IO () type FreewheelCallback = CInt -> Ptr () -> IO () type GraphOrderCallback = Ptr () -> IO CInt type PortConnectCallback = CUInt -> CUInt -> CInt -> Ptr () -> IO () type PortRegistrationCallback = CUInt -> CInt -> Ptr () -> IO () type ProcessCallback = CUInt -- ^ Number of Frames to Process -> Ptr () -- ^ User Data -> IO CInt type SampleRateCallback = CUInt -> Ptr () -> IO CInt type ThreadInitCallback = Ptr () -> IO () type XRunCallback = Ptr () -> IO CInt foreign import ccall safe "wrapper" mkThreadCallback :: ThreadCallback -> IO Raw.ThreadCallbackPtr foreign import ccall safe "wrapper" mkBufferSizeCallback :: BufferSizeCallback -> IO Raw.BufferSizeCallbackPtr foreign import ccall safe "wrapper" mkClientRegistrationCallback :: ClientRegistrationCallback-> IO Raw.ClientRegistrationCallbackPtr foreign import ccall safe "wrapper" mkFreewheelCallback :: FreewheelCallback -> IO Raw.FreewheelCallbackPtr foreign import ccall safe "wrapper" mkGraphOrderCallback :: GraphOrderCallback -> IO Raw.GraphOrderCallbackPtr foreign import ccall safe "wrapper" mkPortConnectCallback :: PortConnectCallback -> IO Raw.PortConnectCallbackPtr foreign import ccall safe "wrapper" mkPortRegistrationCallback :: PortRegistrationCallback -> IO Raw.PortRegistrationCallbackPtr foreign import ccall safe "wrapper" mkProcessCallback :: ProcessCallback -> IO Raw.ProcessCallbackPtr foreign import ccall safe "wrapper" mkSampleRateCallback :: SampleRateCallback -> IO Raw.SampleRateCallbackPtr foreign import ccall safe "wrapper" mkThreadInitCallback :: ThreadInitCallback -> IO Raw.ThreadInitCallbackPtr foreign import ccall safe "wrapper" mkXRunCallback :: XRunCallback -> IO Raw.XRunCallbackPtr withFunPtr :: (Monad m) => (t1 -> m a) -> (t -> a -> t2 -> m b) -> t -> t1 -> t2 -> m b withFunPtr mkPtr setCallback client callbackFun userData = mkPtr callbackFun >>= \fPtr -> setCallback client fPtr userData setProcessThread :: Raw.Client -> ThreadCallback -> Ptr () -> IO Int setProcessThread = withFunPtr mkThreadCallback Raw.setProcessThread setThreadInitCallback :: Raw.Client -> ThreadInitCallback -> Ptr () -> IO Int setThreadInitCallback = withFunPtr mkThreadInitCallback Raw.setThreadInitCallback setProcessCallback :: Raw.Client -> ProcessCallback -> Ptr () -> IO Int setProcessCallback = withFunPtr mkProcessCallback Raw.setProcessCallback setFreewheelCallback :: Raw.Client -> FreewheelCallback -> Ptr () -> IO Int setFreewheelCallback = withFunPtr mkFreewheelCallback Raw.setFreewheelCallback setBufferSizeCallback :: Raw.Client -> BufferSizeCallback -> Ptr () -> IO Int setBufferSizeCallback = withFunPtr mkBufferSizeCallback Raw.setBufferSizeCallback setSampleRateCallback :: Raw.Client -> SampleRateCallback -> Ptr () -> IO Int setSampleRateCallback = withFunPtr mkSampleRateCallback Raw.setSampleRateCallback setClientRegistrationCallback :: Raw.Client -> ClientRegistrationCallback -> Ptr () -> IO Int setClientRegistrationCallback = withFunPtr mkClientRegistrationCallback Raw.setClientRegistrationCallback setPortRegistrationCallback :: Raw.Client -> PortRegistrationCallback -> Ptr () -> IO Int setPortRegistrationCallback = withFunPtr mkPortRegistrationCallback Raw.setPortRegistrationCallback setPortConnectCallback :: Raw.Client -> PortConnectCallback -> Ptr () -> IO Int setPortConnectCallback = withFunPtr mkPortConnectCallback Raw.setPortConnectCallback setGraphOrderCallback :: Raw.Client -> GraphOrderCallback -> Ptr () -> IO Int setGraphOrderCallback = withFunPtr mkGraphOrderCallback Raw.setGraphOrderCallback setXrunCallback :: Raw.Client -> XRunCallback -> Ptr () -> IO Int setXrunCallback = withFunPtr mkXRunCallback Raw.setXrunCallback