{-| PRIVATE MODULE Reference: -} module Sound.Alsa.Sequencer.Sequencer where import Foreign.C.Types(CInt,CSize) import Foreign.C.String(CString,withCAString,peekCString) import Foreign.Ptr(Ptr) import Foreign.Marshal.Alloc(alloca) import Foreign.Storable import Data.Word import Sound.Alsa.Sequencer.Marshal import Sound.Alsa.Sequencer.Errors -- | Creates a new handle and opens a connection to the kernel sequencer -- interface. After a client is created successfully, -- a 'ClientStart' event is broadcast to the announce port. -- May throw an exception. -- See also: 'open_lconf', 'close', 'get_seq_type', -- 'get_seq_name', 'set_blocking', 'get_client_id'. open :: String -- ^ The sequencer's \"name\". This is not a name that you -- make up for your own purposes; it has special significance -- to the ALSA library. Usually you need to pass 'default_name' -- here. -> OpenMode -- Read\/Write permissions -> BlockMode -- Blocking behavior -> IO SndSeq -- Handle to the sequencer. open t om bm = alloca $ \p -> withCAString t $ \s -> do check_error_ =<< snd_seq_open p s (exp_OpenMode om) (exp_BlockMode bm) SndSeq `fmap` peek p foreign import ccall "alsa/asoundlib.h snd_seq_open" snd_seq_open :: Ptr (Ptr SndSeq_) -> CString -> CInt -> CInt -> IO CInt -- | Close the sequencer. Closes the sequencer client and releases its -- resources. After a client is closed, an event with 'ClientExit' is -- broadcast to announce port. The connection between other clients are -- disconnected. Call this just before exiting your program. -- NOTE: we could put this in a finalizer for the handle? close :: SndSeq -- ^ handle to the sequencer -> IO () close (SndSeq s) = check_error_ =<< snd_seq_close s foreign import ccall "alsa/asoundlib.h snd_seq_close" snd_seq_close :: Ptr SndSeq_ -> IO CInt -- | Get identifier of a sequencer handle. -- It is the same identifier specified in the call to 'open'. get_seq_name :: SndSeq -- ^ sequencer handle -> IO String -- ^ ALSA identifier for the handel get_seq_name (SndSeq h) = peekCString =<< snd_seq_name h foreign import ccall "alsa/asoundlib.h snd_seq_name" snd_seq_name :: Ptr SndSeq_ -> IO CString -- | Change the blocking mode of the given client. -- In block mode, the client falls into sleep when it fills the output -- pool with events, or when it demands events from an empty input pool. -- memory pool with full events. Clients that are sleeping due to -- loack of space in the output pool are woken when a certain -- amount of free space becomes available (see 'set_output_room'). set_blocking :: SndSeq -- ^ sequencer handle -> BlockMode -- ^ blocking mode -> IO () set_blocking (SndSeq h) m = check_error_ =<< snd_seq_nonblock h(exp_BlockMode m) foreign import ccall "alsa/asoundlib.h snd_seq_nonblock" snd_seq_nonblock :: Ptr SndSeq_ -> CInt -> IO CInt -- Buffers --------------------------------------------------------------------- -- | Return the byte size of the output buffer. get_output_buffer_size :: SndSeq -- ^ Sequencer handle. -> IO Word -- ^ Size of output buffer in bytes. get_output_buffer_size (SndSeq h) = fromIntegral `fmap` snd_seq_get_output_buffer_size h foreign import ccall "alsa/asoundlib.h snd_seq_get_output_buffer_size" snd_seq_get_output_buffer_size :: Ptr SndSeq_ -> IO CSize -- | Resize of the output buffer. -- This function clears all output events (see 'drop_output'). set_output_buffer_size :: SndSeq -- ^ Sequencer handle. -> Word -- ^ New buffer size in bytes. -> IO () set_output_buffer_size (SndSeq h) x = check_error_ =<< snd_seq_set_output_buffer_size h (fromIntegral x) foreign import ccall "alsa/asoundlib.h snd_seq_set_output_buffer_size" snd_seq_set_output_buffer_size :: Ptr SndSeq_ -> CSize -> IO CInt -- | Return the byte size of input buffer. get_input_buffer_size :: SndSeq -- ^ Sequencer handle. -> IO Word -- ^ Size of input buffer in bytes. get_input_buffer_size (SndSeq h) = fromIntegral `fmap` snd_seq_get_input_buffer_size h foreign import ccall "alsa/asoundlib.h snd_seq_get_input_buffer_size" snd_seq_get_input_buffer_size :: Ptr SndSeq_ -> IO CSize -- | Resize the input buffer. -- This function clears all input events (see 'drop_input'). set_input_buffer_size :: SndSeq -- ^ Sequencer handle. -> Word -- ^ New byffer size in bytes. -> IO () set_input_buffer_size (SndSeq h) x = check_error_ =<< snd_seq_set_input_buffer_size h (fromIntegral x) foreign import ccall "alsa/asoundlib.h snd_seq_set_input_buffer_size" snd_seq_set_input_buffer_size :: Ptr SndSeq_ -> CSize -> IO CInt -- Pool management ------------------------------------------------------------- -- | Resize the output memory pool. set_pool_output :: SndSeq -- ^ Sequencer handle. -> Word -- ^ New size in bytes. -> IO () set_pool_output (SndSeq h) x = check_error_ =<< snd_seq_set_client_pool_output h (fromIntegral x) foreign import ccall "alsa/asoundlib.h snd_seq_set_client_pool_output" snd_seq_set_client_pool_output :: Ptr SndSeq_ -> CSize -> IO CInt -- | Specify how much space should become free before waking clients -- that are blocked due to a lack of space in the output pool. set_pool_output_room :: SndSeq -- ^ Sequencer handle. -> Word -- ^ Number of bytes need to wake up. -> IO () set_pool_output_room (SndSeq h) x = check_error_ =<< snd_seq_set_client_pool_output_room h (fromIntegral x) foreign import ccall "alsa/asoundlib.h snd_seq_set_client_pool_output_room" snd_seq_set_client_pool_output_room :: Ptr SndSeq_ -> CSize -> IO CInt -- | Reset the output pool. reset_pool_output :: SndSeq -- ^ Sequencer handle. -> IO () reset_pool_output (SndSeq h) = check_error_ =<< snd_seq_reset_pool_output h foreign import ccall "alsa/asoundlib.h snd_seq_reset_pool_output" snd_seq_reset_pool_output :: Ptr SndSeq_ -> IO CInt -- | Resize the input memory pool. set_pool_input :: SndSeq -- ^ Sequencer handle. -> Word -- ^ New size in bytes. -> IO () set_pool_input (SndSeq h) x = check_error_ =<< snd_seq_set_client_pool_input h (fromIntegral x) foreign import ccall "alsa/asoundlib.h snd_seq_set_client_pool_input" snd_seq_set_client_pool_input :: Ptr SndSeq_ -> CSize -> IO CInt -- | Reset the input pool. reset_pool_input :: SndSeq -- ^ Sequencer handle. -> IO () reset_pool_input (SndSeq h) = check_error_ =<< snd_seq_reset_pool_input h foreign import ccall "alsa/asoundlib.h snd_seq_reset_pool_input" snd_seq_reset_pool_input :: Ptr SndSeq_ -> IO CInt --Middle Level Interface ------------------------------------------------------- -- | Simple subscription (w\/o exclusive & time conversion). connect_from :: SndSeq -> Port -> Addr -> IO () connect_from (SndSeq h) me a = check_error_ =<< snd_seq_connect_from h (exp_Port me) c p where (c,p) = exp_Addr a foreign import ccall "alsa/asoundlib.h snd_seq_connect_from" snd_seq_connect_from :: Ptr SndSeq_ -> CInt -> CInt -> CInt -> IO CInt -- | Simple subscription (w\/o exclusive & time conversion). connect_to :: SndSeq -> Port -> Addr -> IO () connect_to (SndSeq h) me a = check_error_ =<< snd_seq_connect_to h (exp_Port me) c p where (c,p) = exp_Addr a foreign import ccall "alsa/asoundlib.h snd_seq_connect_to" snd_seq_connect_to :: Ptr SndSeq_ -> CInt -> CInt -> CInt -> IO CInt -- | Simple disconnection. disconnect_from :: SndSeq -> Port -> Addr -> IO () disconnect_from (SndSeq h) me a = check_error_ =<< snd_seq_disconnect_from h (exp_Port me) c p where (c,p) = exp_Addr a foreign import ccall "alsa/asoundlib.h snd_seq_disconnect_from" snd_seq_disconnect_from :: Ptr SndSeq_ -> CInt -> CInt -> CInt -> IO CInt -- | Simple disconnection. disconnect_to :: SndSeq -> Port -> Addr -> IO () disconnect_to (SndSeq h) me a = check_error_ =<< snd_seq_disconnect_to h (exp_Port me) c p where (c,p) = exp_Addr a foreign import ccall "alsa/asoundlib.h snd_seq_disconnect_to" snd_seq_disconnect_to :: Ptr SndSeq_ -> CInt -> CInt -> CInt -> IO CInt -- | Parse the given string into sequencer address. -- The client and port are separated by either colon or period, e.g. 128:1. -- The function also accepts client names. parse_address :: SndSeq -- ^ Sequencer handle. -> String -- ^ String to be parsed. -> IO Addr -- ^ The parsed address. parse_address (SndSeq h) s = alloca $ \pa -> withCAString s $ \ps -> do check_error =<< snd_seq_parse_address h pa ps peek pa foreign import ccall "alsa/asoundlib.h snd_seq_parse_address" snd_seq_parse_address :: Ptr SndSeq_ -> Ptr Addr -> CString -> IO CInt