alsa-0.4: Sound/Alsa/Sequencer/Event.hs
--------------------------------------------------------------------------------
-- |
-- Module : Sound.Alsa.Sequencer.Event
-- Copyright : (c) Iavor S. Diatchki, 2007
-- License : BSD3
--
-- Maintainer: Iavor S. Diatchki
-- Stability : provisional
--
-- This module contains functions for working with events.
-- Reference:
-- <http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html>
--------------------------------------------------------------------------------
module Sound.Alsa.Sequencer.Event
( sync_output_queue -- :: SndSeq -> IO ()
, event_input -- :: SndSeq -> IO Event
, event_input_pending -- :: SndSeq -> Bool -> IO Word
, event_output -- :: SndSeq -> Event -> IO Word
, event_output_buffer -- :: SndSeq -> Event -> IO Word
, event_output_direct -- :: SndSeq -> Event -> IO Word
, event_output_pending -- :: SndSeq -> IO Word
, extract_output -- :: SndSeq -> IO Event
, remove_output -- :: SndSeq -> IO ()
, drain_output -- :: SndSeq -> IO Word
, drop_output -- :: SndSeq -> IO ()
, drop_output_buffer -- :: SndSeq -> IO ()
, drop_input -- :: SndSeq -> IO ()
, drop_input_buffer -- :: SndSeq -> IO ()
) where
import Foreign.C.Types(CInt)
import Foreign.Ptr(Ptr,nullPtr)
import Foreign.Marshal.Alloc(alloca)
import Foreign.Storable
import Data.Word
import Data.Int
import Sound.Alsa.Sequencer.Marshal
import Sound.Alsa.Sequencer.Errors
-- | Wait until all events of the client are processed.
sync_output_queue :: SndSeq -> IO ()
sync_output_queue (SndSeq h) =
check_error_ =<< snd_seq_sync_output_queue h
foreign import ccall "alsa/asoundlib.h snd_seq_sync_output_queue"
snd_seq_sync_output_queue :: Ptr SndSeq_ -> IO CInt
-- | Get an event from the input buffer.
-- If the input buffer is empty, then it is filled with data from the
-- sequencer queue. If there is no data in the sequencer queue,
-- then the process is either put to sleep (if the sequencer is operating
-- in blocking mode), or we throw @EAGAIN@ (if the sequence is operating
-- in non-blocking mode).
--
-- We may also throw @ENOSPC@, which means that the sequencer queue
-- over-run and some events were lost (this clears the input buffer).
--
event_input :: SndSeq -> IO Event
event_input (SndSeq h) = alloca $ \p ->
do check_error =<< snd_seq_event_input h p
peek =<< peek p
foreign import ccall "alsa/asoundlib.h snd_seq_event_input"
snd_seq_event_input :: Ptr SndSeq_ -> Ptr (Ptr Event) -> IO CInt
-- | Returns the number of events in the input buffer.
-- If the input buffer is empty and the boolean argument is true,
-- then try to fill the input buffer with data from the sequencer queue.
-- See also: 'snd_seq_event_input'.
event_input_pending
:: SndSeq
-> Bool -- ^ refill if empty?
-> IO Word -- ^ number of events in buffer
event_input_pending (SndSeq h) fill =
check_error =<< snd_seq_event_input_pending h (if fill then 1 else 0)
foreign import ccall "alsa/asoundlib.h snd_seq_event_input_pending"
snd_seq_event_input_pending :: Ptr SndSeq_ -> Int -> IO CInt
-- | Output an event and drain the buffer, if it became full.
-- Throws exceptions.
-- See also: 'event_output_direct', 'event_output_buffer',
-- 'event_output_pending', 'drain_output', 'drop_output',
-- 'extract_output', 'remove_events'
event_output :: SndSeq
-> Event
-> IO Word -- ^ the number of remaining events (or bytes?)
event_output (SndSeq h) e =
alloca_ev e $ \p -> check_error =<< snd_seq_event_output h p
foreign import ccall "alsa/asoundlib.h snd_seq_event_output"
snd_seq_event_output :: Ptr SndSeq_ -> Ptr Event -> IO CInt
-- | Output an event without draining the buffer.
-- Throws @-EAGAIN@ if the buffer becomes full.
-- See also 'event_output'.
event_output_buffer :: SndSeq
-> Event
-> IO Word -- ^ the byte size of remaining events
event_output_buffer (SndSeq h) e =
alloca_ev e $ \p -> check_error =<< snd_seq_event_output_buffer h p
foreign import ccall "alsa/asoundlib.h snd_seq_event_output_buffer"
snd_seq_event_output_buffer :: Ptr SndSeq_ -> Ptr Event -> IO CInt
-- | Output an event directly to the sequencer, NOT through the output buffer.
-- If an error occurs, then we throw an exception.
-- See also 'event_output'.
event_output_direct
:: SndSeq
-> Event
-> IO Word -- ^ number of bytes sent to the sequencer
event_output_direct (SndSeq h) e =
alloca_ev e $ \p -> check_error =<< snd_seq_event_output_direct h p
foreign import ccall "alsa/asoundlib.h snd_seq_event_output_direct"
snd_seq_event_output_direct :: Ptr SndSeq_ -> Ptr Event -> IO CInt
-- | Return the size (in bytes) of pending events on output buffer.
-- See also 'snd_seq_event_output'.
event_output_pending
:: SndSeq
-> IO Word -- ^ size of pending events (in bytes)
event_output_pending (SndSeq h) =
fromIntegral `fmap` snd_seq_event_output_pending h
foreign import ccall "alsa/asoundlib.h snd_seq_event_output_pending"
snd_seq_event_output_pending :: Ptr SndSeq_ -> IO CInt
-- | Extract the first event in output buffer.
-- Throws an exception on error.
-- See also 'snd_seq_event_output'.
extract_output
:: SndSeq
-> IO Event -- ^ the first event in the buffer (if one was present)
extract_output (SndSeq h) =
alloca $ \p -> do check_error =<< snd_seq_extract_output h p
peek =<< peek p
-- | Remove the first event in output buffer.
-- Throws an exception on error.
-- See also 'snd_seq_event_output'.
remove_output :: SndSeq -> IO ()
remove_output (SndSeq h) = check_error_ =<< snd_seq_extract_output h nullPtr
foreign import ccall "alsa/asoundlib.h snd_seq_extract_output"
snd_seq_extract_output :: Ptr SndSeq_ -> Ptr (Ptr Event) -> IO CInt
-- | Drain output buffer to sequencer.
-- This function drains all pending events on the output buffer.
-- The function returns immediately after the events are sent to the queues
-- regardless whether the events are processed or not.
-- To get synchronization with the all event processes,
-- use 'sync_output_queue' after calling this function.
-- Throws an exception on error.
-- See also: 'event_output', 'sync_output_queue'.
drain_output
:: SndSeq
-> IO Word -- ^ byte size of events remaining in the buffer.
drain_output (SndSeq h) = check_error =<< snd_seq_drain_output h
foreign import ccall "alsa/asoundlib.h snd_seq_drain_output"
snd_seq_drain_output :: Ptr SndSeq_ -> IO CInt
-- | Remove events from both the user-space output buffer,
-- and the kernel-space sequencer queue.
-- See also: 'drain_output', 'drop_output_buffer', 'remove_events'.
drop_output :: SndSeq -> IO ()
drop_output (SndSeq h) = check_error_ =<< snd_seq_drop_output h
foreign import ccall "alsa/asoundlib.h snd_seq_drop_output"
snd_seq_drop_output :: Ptr SndSeq_ -> IO CInt
-- | Remove events from the user-space output buffer.
-- See also: 'drop_output'.
drop_output_buffer :: SndSeq -> IO ()
drop_output_buffer (SndSeq h) = check_error_ =<< snd_seq_drop_output_buffer h
foreign import ccall "alsa/asoundlib.h snd_seq_drop_output_buffer"
snd_seq_drop_output_buffer :: Ptr SndSeq_ -> IO CInt
-- | Remove events from both the user-space input buffer,
-- and the kernel-space sequencer queue.
-- See also: 'drop_input_buffer', 'remove_events'.
drop_input :: SndSeq -> IO ()
drop_input (SndSeq h) = check_error_ =<< snd_seq_drop_input h
foreign import ccall "alsa/asoundlib.h snd_seq_drop_input"
snd_seq_drop_input :: Ptr SndSeq_ -> IO CInt
-- | Remove events from the user-space input buffer.
-- See also: 'drop_input'.
drop_input_buffer :: SndSeq -> IO ()
drop_input_buffer (SndSeq h) = check_error_ =<< snd_seq_drop_input_buffer h
foreign import ccall "alsa/asoundlib.h snd_seq_drop_input_buffer"
snd_seq_drop_input_buffer :: Ptr SndSeq_ -> IO CInt