module Sound.JACK.FFI where
import Foreign.Ptr (Ptr, FunPtr)
import Foreign.C.String (CString)
import qualified Foreign.C.Error as E
import qualified Foreign.C.Types as C
import qualified Data.EnumSet as ES
import Data.Word (Word, Word32, Word64, )
import Data.Ix (Ix(range, inRange, rangeSize, index))
import Data.Monoid (Monoid, mempty, mappend, )
import Numeric.NonNegative.Class as NonNeg
data Client = Client
data Port typ = Port
data Input = Input
data Output = Output
foreign import ccall "static jack/jack.h jack_client_open"
client_open :: CString -> OpenOptionSet -> Ptr StatusSet -> CString -> IO (Ptr Client)
foreign import ccall "static jack/jack.h jack_client_new"
client_new :: CString -> IO (Ptr Client)
foreign import ccall "static jack/jack.h jack_get_sample_rate"
get_sample_rate :: Ptr Client -> IO C.CInt
type OpenOptionSet = ES.T C.CULong OpenOptions
data OpenOptions =
NoStartServer
| UseExactName
| ServerName
deriving (Enum, Eq, Ord, Show, Ix)
wordNullOption, wordNoStartServer, wordUseExactName, wordServerName :: OpenOptionSet
wordNullOption = ES.empty
wordNoStartServer = ES.fromEnum NoStartServer
wordUseExactName = ES.fromEnum UseExactName
wordServerName = ES.fromEnum ServerName
type StatusSet = ES.T C.CULong Status
data Status =
Failure
| InvalidOption
| NameNotUnique
| ServerStarted
| ServerFailed
| ServerError
| NoSuchClient
| LoadFailure
| InitFailure
| ShmFailure
| VersionError
deriving (Enum, Eq, Ord, Show, Ix)
wordFailure, wordInvalidOption, wordNameNotUnique, wordServerStarted,
wordServerFailed, wordServerError, wordNoSuchClient, wordLoadFailure,
wordInitFailure, wordShmFailure, wordVersionError :: StatusSet
wordFailure = ES.fromEnum Failure
wordInvalidOption = ES.fromEnum InvalidOption
wordNameNotUnique = ES.fromEnum NameNotUnique
wordServerStarted = ES.fromEnum ServerStarted
wordServerFailed = ES.fromEnum ServerFailed
wordServerError = ES.fromEnum ServerError
wordNoSuchClient = ES.fromEnum NoSuchClient
wordLoadFailure = ES.fromEnum LoadFailure
wordInitFailure = ES.fromEnum InitFailure
wordShmFailure = ES.fromEnum ShmFailure
wordVersionError = ES.fromEnum VersionError
type PortFlagSet = ES.T C.CULong PortFlag
data PortFlag =
PortIsInput
| PortIsOutput
| PortIsPhysical
| PortCanMonitor
| PortIsTerminal
deriving (Enum, Eq, Ord, Show, Ix)
newtype PortName = PortName {deconsPortName :: CString}
newtype PortType = PortType {deconsPortType :: CString}
portIsInput, portIsOutput :: PortFlagSet
portIsInput = ES.fromEnum PortIsInput
portIsOutput = ES.fromEnum PortIsOutput
foreign import ccall "static jack/jack.h jack_port_register"
port_register :: Ptr Client -> PortName -> PortType ->
PortFlagSet -> C.CULong -> IO (Ptr (Port a))
newtype NFrames = NFrames Word32
deriving (Show, Eq, Ord)
nframesToWord :: NFrames -> Word
nframesToWord (NFrames n) = fromIntegral n
instance Ix NFrames where
range (a,b) =
map (NFrames . fromIntegral) $
range (nframesToWord a, nframesToWord b)
index (a,b) i =
index (nframesToWord a, nframesToWord b) (nframesToWord i)
inRange (a,b) i =
inRange (nframesToWord a, nframesToWord b) (nframesToWord i)
rangeSize (a,b) =
rangeSize (nframesToWord a, nframesToWord b)
instance Monoid NFrames where
mempty = NFrames 0
mappend (NFrames x) (NFrames y) = NFrames (x+y)
instance NonNeg.C NFrames where
split = NonNeg.splitDefault (\(NFrames n) -> n) NFrames
nframesIndices :: NFrames -> [NFrames]
nframesIndices (NFrames n) =
take (fromIntegral n) $ map NFrames $ iterate (1+) 0
nframesBounds :: NFrames -> (NFrames,NFrames)
nframesBounds (NFrames n) =
(NFrames 0, NFrames $ n 1)
type Process arg = NFrames -> Ptr arg -> IO E.Errno
foreign import ccall "static jack/jack.h jack_set_process_callback"
set_process_callback ::
Ptr Client -> FunPtr (Process arg) -> Ptr arg -> IO E.Errno
type ClientRegistration arg = CString -> C.CInt -> Ptr arg -> IO ()
foreign import ccall "static jack/jack.h jack_set_client_registration_callback"
set_client_registration_callback ::
Ptr Client -> FunPtr (ClientRegistration arg) -> Ptr arg -> IO E.Errno
newtype PortId = PortId Word32 deriving (Eq, Ord, Show)
data UnknownType = UnknownType
type PortRegistration arg = PortId -> C.CInt -> Ptr arg -> IO ()
foreign import ccall "static jack/jack.h jack_set_port_registration_callback"
set_port_registration_callback ::
Ptr Client -> FunPtr (PortRegistration arg) -> Ptr arg -> IO E.Errno
type PortConnect arg = PortId -> PortId -> C.CInt -> Ptr arg -> IO ()
foreign import ccall "static jack/jack.h jack_set_port_connect_callback"
set_port_connect_callback ::
Ptr Client -> FunPtr (PortConnect arg) -> Ptr arg -> IO E.Errno
foreign import ccall "static jack/jack.h jack_port_by_id"
port_by_id ::
Ptr Client -> PortId -> IO (Ptr (Port UnknownType))
foreign import ccall "static jack/jack.h jack_port_by_name"
port_by_name ::
Ptr Client -> PortName -> IO (Ptr (Port UnknownType))
foreign import ccall "static jack/jack.h jack_port_name"
port_name ::
Ptr (Port typ) -> IO PortName
foreign import ccall "static jack/jack.h jack_port_name_size"
port_name_size ::
IO C.CInt
foreign import ccall "static jack/jack.h jack_port_get_aliases"
port_get_aliases ::
Ptr (Port typ) -> Ptr CString -> IO C.CInt
foreign import ccall "static jack/jack.h jack_port_short_name"
port_short_name ::
Ptr (Port typ) -> IO CString
foreign import ccall "static jack/jack.h jack_port_flags"
port_flags ::
Ptr (Port typ) -> IO PortFlagSet
foreign import ccall "static jack/jack.h jack_port_type"
port_type ::
Ptr (Port UnknownType) -> IO PortType
foreign import ccall "static jack/jack.h jack_get_ports"
get_ports :: Ptr Client -> CString -> CString -> C.CULong -> IO (Ptr CString)
foreign import ccall "static jack/jack.h jack_port_get_all_connections"
port_get_all_connections ::
Ptr Client -> Ptr (Port typ) -> IO (Ptr CString)
foreign import ccall "static jack/jack.h jack_last_frame_time"
last_frame_time :: Ptr Client -> IO NFrames
foreign import ccall "static jack/jack.h jack_port_get_buffer"
port_get_buffer :: Ptr (Port a) -> NFrames -> IO (Ptr a)
foreign import ccall "static jack/jack.h jack_get_buffer_size"
get_buffer_size :: Ptr Client -> IO (C.CUInt)
foreign import ccall "static jack/jack.h jack_activate"
activate :: Ptr Client -> IO E.Errno
foreign import ccall "static jack/jack.h jack_client_close"
client_close :: Ptr Client -> IO E.Errno
foreign import ccall "static jack/jack.h jack_connect"
connect :: Ptr Client -> PortName -> PortName -> IO E.Errno
foreign import ccall "static jack/jack.h jack_disconnect"
disconnect :: Ptr Client -> PortName -> PortName -> IO E.Errno
foreign import ccall "static jack/jack.h jack_port_unregister"
port_unregister :: Ptr Client -> Ptr (Port a) -> IO E.Errno
foreign import ccall "static jack/jack.h jack_deactivate"
deactivate :: Ptr Client -> IO E.Errno
_dummy :: (Word32, Word64)
_dummy = undefined