-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Haskell Open Sound Control
--   
--   <tt>hosc</tt> implements a subset of the <i>Open Sound Control</i>
--   byte protocol, <a>http://opensoundcontrol.org/</a>.
--   
--   <a>Sound.OSC.Core</a> implements the actual protocol.
--   
--   <a>Sound.OSC.Transport.FD</a> implements a <i>file descriptor</i>
--   based transport layer for <tt>UDP</tt> and <tt>TCP</tt>.
--   
--   <a>Sound.OSC.Transport.Monad</a> implements a monadic interface to the
--   <tt>FD</tt> transport layer.
--   
--   Composite modules are at <a>Sound.OSC</a> and <a>Sound.OSC.FD</a>.
@package hosc
@version 0.15


-- | Waiting (for replies).
module Sound.OSC.Wait

-- | Real valued variant of <a>timeout</a>.
timeout_r :: Double -> IO a -> IO (Maybe a)

-- | Repeat action until predicate <i>f</i> is <a>True</a> when applied to
--   result.
untilPredicate :: Monad m => (a -> Bool) -> m a -> m a

-- | Repeat action until <i>f</i> does not give <a>Nothing</a> when applied
--   to result.
untilMaybe :: Monad m => (a -> Maybe b) -> m a -> m b


-- | Alegbraic data types for OSC datum and packets.
module Sound.OSC.Type

-- | <tt>NTP</tt> time in real-valued (fractional) form.
type Time = Double

-- | Constant indicating a bundle to be executed immediately.
immediately :: Time

-- | Type enumerating Datum categories.
type Datum_Type = Char

-- | Type for ASCII strings (strict <a>Char</a>8 <a>ByteString</a>).
type ASCII = ByteString

-- | Type-specialised <a>pack</a>.
ascii :: String -> ASCII

-- | Type-specialised <a>unpack</a>.
ascii_to_string :: ASCII -> String

-- | Four-byte midi message.
data MIDI
MIDI :: Word8 -> Word8 -> Word8 -> Word8 -> MIDI

-- | The basic elements of OSC messages.
data Datum
Int32 :: Int32 -> Datum
[d_int32] :: Datum -> Int32
Int64 :: Int64 -> Datum
[d_int64] :: Datum -> Int64
Float :: Float -> Datum
[d_float] :: Datum -> Float
Double :: Double -> Datum
[d_double] :: Datum -> Double
ASCII_String :: ASCII -> Datum
[d_ascii_string] :: Datum -> ASCII
Blob :: ByteString -> Datum
[d_blob] :: Datum -> ByteString
TimeStamp :: Time -> Datum
[d_timestamp] :: Datum -> Time
Midi :: MIDI -> Datum
[d_midi] :: Datum -> MIDI

-- | Single character identifier of an OSC datum.
datum_tag :: Datum -> Datum_Type

-- | <a>Datum</a> as <a>Integral</a> if <a>Int32</a> or <a>Int64</a>.
--   
--   <pre>
--   let d = [Int32 5,Int64 5,Float 5.5,Double 5.5]
--   in map datum_integral d == [Just (5::Int),Just 5,Nothing,Nothing]
--   </pre>
datum_integral :: Integral i => Datum -> Maybe i

-- | <a>Datum</a> as <a>Floating</a> if <a>Int32</a>, <a>Int64</a>,
--   <a>Float</a>, <a>Double</a> or <a>TimeStamp</a>.
--   
--   <pre>
--   let d = [Int32 5,Int64 5,Float 5,Double 5,TimeStamp 5]
--   in Data.Maybe.mapMaybe datum_floating d == replicate 5 (5::Double)
--   </pre>
datum_floating :: Floating n => Datum -> Maybe n

-- | Class for translating to and from <a>Datum</a>. There are instances
--   for the direct <a>Datum</a> field types.
--   
--   <pre>
--   d_put (1::Int32) == Int32 1
--   d_put (1::Int64) == Int64 1
--   d_put (1::Float) == Float 1
--   d_put (1::Double) == Double 1
--   d_put (C.pack "str") == ASCII_String (C.pack "str")
--   d_put (B.pack [37,37]) == Blob (B.pack [37,37])
--   d_put (MIDI 0 0 0 0) == Midi (MIDI 0 0 0 0)
--   </pre>
--   
--   There are also instances for standard Haskell types.
--   
--   <pre>
--   d_put (1::Int) == Int64 1
--   d_put (1::Integer) == Int64 1
--   </pre>
class Datem a
d_put :: Datem a => a -> Datum
d_get :: Datem a => Datum -> Maybe a

-- | Type generalised <a>Int32</a>.
--   
--   <pre>
--   int32 (1::Int32) == int32 (1::Integer)
--   d_int32 (int32 (maxBound::Int32)) == maxBound
--   int32 (((2::Int) ^ (64::Int))::Int) == Int32 0
--   </pre>
int32 :: Integral n => n -> Datum

-- | Type generalised <a>Int64</a>.
--   
--   <pre>
--   int64 (1::Int32) == int64 (1::Integer)
--   d_int64 (int64 (maxBound::Int64)) == maxBound
--   </pre>
int64 :: Integral n => n -> Datum

-- | Type generalised <a>Float</a>.
--   
--   <pre>
--   float (1::Int) == float (1::Double)
--   floatRange (undefined::Float) == (-125,128)
--   isInfinite (d_float (float (encodeFloat 1 256 :: Double))) == True
--   </pre>
float :: Real n => n -> Datum

-- | Type generalised <a>Double</a>.
--   
--   <pre>
--   double (1::Int) == double (1::Double)
--   double (encodeFloat 1 256 :: Double) == Double 1.157920892373162e77
--   </pre>
double :: Real n => n -> Datum

-- | <a>ASCII_String</a> of <a>pack</a>.
--   
--   <pre>
--   string "string" == ASCII_String (C.pack "string")
--   </pre>
string :: String -> Datum

-- | Four-tuple variant of <a>Midi</a> <a>.</a> <a>MIDI</a>.
--   
--   <pre>
--   midi (0,0,0,0) == Midi (MIDI 0 0 0 0)
--   </pre>
midi :: (Word8, Word8, Word8, Word8) -> Datum

-- | OSC address pattern. This is strictly an ASCII value, but it is very
--   common to pattern match on addresses and matching on <a>ByteString</a>
--   requires <tt>OverloadedStrings</tt>.
type Address_Pattern = String

-- | An OSC message.
data Message
Message :: Address_Pattern -> [Datum] -> Message
[messageAddress] :: Message -> Address_Pattern
[messageDatum] :: Message -> [Datum]

-- | <a>Message</a> constructor. It is an <a>error</a> if the
--   <a>Address_Pattern</a> doesn't conform to the OSC specification.
message :: Address_Pattern -> [Datum] -> Message

-- | Message argument types are given by a descriptor.
--   
--   <pre>
--   C.unpack (descriptor [Int32 1,Float 1,string "1"]) == ",ifs"
--   </pre>
descriptor :: [Datum] -> ASCII

-- | Descriptor tags are <tt>comma</tt> prefixed.
descriptor_tags :: ASCII -> ASCII

-- | An OSC bundle.
data Bundle
Bundle :: Time -> [Message] -> Bundle
[bundleTime] :: Bundle -> Time
[bundleMessages] :: Bundle -> [Message]

-- | OSC <a>Bundle</a>s can be ordered (time ascending).

-- | <a>Bundle</a> constructor. It is an <a>error</a> if the <a>Message</a>
--   list is empty.
bundle :: Time -> [Message] -> Bundle

-- | An OSC <a>Packet</a> is either a <a>Message</a> or a <a>Bundle</a>.
data Packet
Packet_Message :: Message -> Packet
[packetMessage] :: Packet -> Message
Packet_Bundle :: Bundle -> Packet
[packetBundle] :: Packet -> Bundle

-- | <a>Packet_Bundle</a> <a>.</a> <a>bundle</a>.
p_bundle :: Time -> [Message] -> Packet

-- | <a>Packet_Message</a> <a>.</a> <a>message</a>.
p_message :: Address_Pattern -> [Datum] -> Packet

-- | The <a>Time</a> of <a>Packet</a>, if the <a>Packet</a> is a
--   <a>Message</a> this is <a>immediately</a>.
packetTime :: Packet -> Time

-- | Retrieve the set of <a>Message</a>s from a <a>Packet</a>.
packetMessages :: Packet -> [Message]

-- | If <a>Packet</a> is a <a>Message</a> add <a>immediately</a> timestamp,
--   else <a>id</a>.
packet_to_bundle :: Packet -> Bundle

-- | If <a>Packet</a> is a <a>Message</a> or a <a>Bundle</a> with an
--   <i>immediate</i> time tag and with one element, return the
--   <a>Message</a>, else <a>Nothing</a>.
packet_to_message :: Packet -> Maybe Message

-- | Is <a>Packet</a> immediate, ie. a <a>Bundle</a> with timestamp
--   <a>immediately</a>, or a plain Message.
packet_is_immediate :: Packet -> Bool

-- | Variant of <a>either</a> for <a>Packet</a>.
at_packet :: (Message -> a) -> (Bundle -> a) -> Packet -> a

-- | Does <a>Message</a> have the specified <a>Address_Pattern</a>.
message_has_address :: Address_Pattern -> Message -> Bool

-- | Do any of the <a>Message</a>s at <a>Bundle</a> have the specified
--   <a>Address_Pattern</a>.
bundle_has_address :: Address_Pattern -> Bundle -> Bool

-- | Does <a>Packet</a> have the specified <a>Address_Pattern</a>, ie.
--   <a>message_has_address</a> or <a>bundle_has_address</a>.
packet_has_address :: Address_Pattern -> Packet -> Bool

-- | Perhaps a precision value for floating point numbers.
type FP_Precision = Maybe Int

-- | Variant of <a>showFFloat</a> that deletes trailing zeros.
--   
--   <pre>
--   map (floatPP (Just 4)) [1,pi] == ["1.0","3.1416"]
--   </pre>
floatPP :: RealFloat n => Maybe Int -> n -> String

-- | Pretty printer for <a>Time</a>.
--   
--   <pre>
--   timePP (Just 4) (1/3) == "0.3333"
--   </pre>
timePP :: FP_Precision -> Time -> String

-- | Pretty printer for vectors.
--   
--   <pre>
--   vecPP [1::Int,2,3] == "&lt;1,2,3&gt;"
--   </pre>
vecPP :: Show a => [a] -> String

-- | Pretty printer for <a>Datum</a>.
--   
--   <pre>
--   let d = [Int32 1,Float 1.2,string "str",midi (0,0x90,0x40,0x60)]
--   in map datumPP d ==  ["1","1.2","\"str\"","&lt;0,144,64,96&gt;"]
--   </pre>
datumPP :: FP_Precision -> Datum -> String

-- | Pretty printer for <a>Message</a>.
messagePP :: FP_Precision -> Message -> String

-- | Pretty printer for <a>Bundle</a>.
bundlePP :: FP_Precision -> Bundle -> String

-- | Pretty printer for <a>Packet</a>.
packetPP :: FP_Precision -> Packet -> String

-- | Variant of <a>read</a>.
readMaybe :: (Read a) => String -> Maybe a

-- | Given <a>Datum_Type</a> attempt to parse <a>Datum</a> at
--   <a>String</a>.
--   
--   <pre>
--   parse_datum 'i' "42" == Just (Int32 42)
--   parse_datum 'h' "42" == Just (Int64 42)
--   parse_datum 'f' "3.14159" == Just (Float 3.14159)
--   parse_datum 'd' "3.14159" == Just (Double 3.14159)
--   parse_datum 's' "\"pi\"" == Just (string "pi")
--   parse_datum 'b' "[112,105]" == Just (Blob (B.pack [112,105]))
--   parse_datum 'm' "(0,144,60,90)" == Just (midi (0,144,60,90))
--   </pre>
parse_datum :: Datum_Type -> String -> Maybe Datum
instance GHC.Show.Show Sound.OSC.Type.Packet
instance GHC.Read.Read Sound.OSC.Type.Packet
instance GHC.Classes.Eq Sound.OSC.Type.Packet
instance GHC.Show.Show Sound.OSC.Type.Bundle
instance GHC.Read.Read Sound.OSC.Type.Bundle
instance GHC.Classes.Eq Sound.OSC.Type.Bundle
instance GHC.Show.Show Sound.OSC.Type.Message
instance GHC.Read.Read Sound.OSC.Type.Message
instance GHC.Classes.Eq Sound.OSC.Type.Message
instance GHC.Show.Show Sound.OSC.Type.Datum
instance GHC.Read.Read Sound.OSC.Type.Datum
instance GHC.Classes.Eq Sound.OSC.Type.Datum
instance GHC.Read.Read Sound.OSC.Type.MIDI
instance GHC.Show.Show Sound.OSC.Type.MIDI
instance GHC.Classes.Eq Sound.OSC.Type.MIDI
instance Sound.OSC.Type.Datem GHC.Int.Int32
instance Sound.OSC.Type.Datem GHC.Int.Int64
instance Sound.OSC.Type.Datem GHC.Types.Int
instance Sound.OSC.Type.Datem GHC.Integer.Type.Integer
instance Sound.OSC.Type.Datem GHC.Types.Float
instance Sound.OSC.Type.Datem GHC.Types.Double
instance Sound.OSC.Type.Datem Data.ByteString.Internal.ByteString
instance Sound.OSC.Type.Datem Data.ByteString.Lazy.Internal.ByteString
instance Sound.OSC.Type.Datem Sound.OSC.Type.MIDI
instance GHC.Classes.Ord Sound.OSC.Type.Bundle


-- | OSC related timing functions. OSC timestamps are <tt>NTP</tt> values,
--   <a>http://ntp.org/</a>.
module Sound.OSC.Time

-- | Type for integer (binary) representation of <tt>NTP</tt> time.
type NTPi = Word64

-- | <tt>Unix/Posix</tt> epoch time in real-valued (fractional) form.
type UT = Double

-- | Convert a real-valued NTP timestamp to an <a>NTPi</a> timestamp.
ntpr_to_ntpi :: RealFrac n => n -> NTPi

-- | Convert an <a>NTPi</a> timestamp to a real-valued NTP timestamp.
ntpi_to_ntpr :: Fractional n => NTPi -> n

-- | Difference (in seconds) between <i>NTP</i> and <i>UT</i> epochs.
--   
--   <pre>
--   ntp_ut_epoch_diff / (24 * 60 * 60) == 25567
--   </pre>
ntp_ut_epoch_diff :: Num n => n

-- | Convert a <a>UT</a> timestamp to an <a>NTPi</a> timestamp.
ut_to_ntpi :: UT -> NTPi

-- | Convert <tt>Unix/Posix</tt> to <tt>NTP</tt>.
ut_to_ntpr :: Num n => n -> n

-- | Convert <tt>NTP</tt> to <tt>Unix/Posix</tt>.
ntpr_to_ut :: Num n => n -> n

-- | Convert <a>NTPi</a> to <tt>Unix/Posix</tt>.
ntpi_to_ut :: NTPi -> UT

-- | The time at 1970-01-01:00:00:00.
ut_epoch :: UTCTime

-- | Convert <a>UTCTime</a> to <tt>Unix/Posix</tt>.
utc_to_ut :: Fractional n => UTCTime -> n

-- | Read current real-valued <tt>NTP</tt> timestamp.
--   
--   <pre>
--   do {ct &lt;- fmap utc_to_ut T.getCurrentTime
--      ;pt &lt;- fmap realToFrac T.getPOSIXTime
--      ;print (pt - ct,pt - ct &lt; 1e-5)}
--   </pre>
time :: MonadIO m => m Time

-- | The <a>pauseThread</a> limit (in seconds). Values larger than this
--   require a different thread delay mechanism, see <a>sleepThread</a>.
--   The value is the number of microseconds in <tt>maxBound::Int</tt>.
pauseThreadLimit :: Fractional n => n

-- | Pause current thread for the indicated duration (in seconds), see
--   <a>pauseThreadLimit</a>.
pauseThread :: (MonadIO m, Ord n, RealFrac n) => n -> m ()

-- | Type restricted <a>pauseThread</a>.
wait :: MonadIO m => Double -> m ()

-- | Pause current thread until the given <a>Time</a>, see
--   <a>pauseThreadLimit</a>.
pauseThreadUntil :: MonadIO m => Time -> m ()

-- | Sleep current thread for the indicated duration (in seconds). Divides
--   long sleeps into parts smaller than <a>pauseThreadLimit</a>.
sleepThread :: (RealFrac n, MonadIO m) => n -> m ()

-- | Sleep current thread until the given <a>Time</a>. Divides long sleeps
--   into parts smaller than <a>pauseThreadLimit</a>.
sleepThreadUntil :: MonadIO m => Time -> m ()


-- | Datum normalisation.
module Sound.OSC.Normalise

-- | Lift <a>Int32</a> to <a>Int64</a> and <a>Float</a> to <a>Double</a>.
--   
--   <pre>
--   map normalise_datum [Int32 1,Float 1] == [Int64 1,Double 1]
--   </pre>
normalise_datum :: Datum -> Datum

-- | A normalised <a>Message</a> has only <a>Int64</a> and <a>Double</a>
--   numerical values.
--   
--   <pre>
--   let m = message "/m" [Int32 0,Float 0]
--   in normalise_message m == message "/m" [Int64 0,Double 0]
--   </pre>
normalise_message :: Message -> Message

-- | A normalised <a>Bundle</a> has only <a>Int64</a> and <a>Double</a>
--   numerical values.
normalise_bundle :: Bundle -> Bundle

-- | Map a normalising function over datum at an OSC <a>Message</a>.
message_coerce :: (Datum -> Datum) -> Message -> Message

-- | Map a normalising function over datum at an OSC <a>Bundle</a>.
bundle_coerce :: (Datum -> Datum) -> Bundle -> Bundle

-- | Coerce <a>Int32</a>, <a>Int64</a> and <a>Float</a> to <a>Double</a>.
--   
--   <pre>
--   map datum_promote [Int32 5,Float 5] == [Double 5,Double 5]
--   </pre>
datum_promote :: Datum -> Datum

-- | <a>Datum</a> as <a>Int64</a> if <a>Int32</a>, <a>Int64</a>,
--   <a>Float</a> or <a>Double</a>.
--   
--   <pre>
--   let d = [Int32 5,Int64 5,Float 5.5,Double 5.5,string "5"]
--   in map datum_floor d == [Int64 5,Int64 5,Int64 5,Int64 5,string "5"]
--   </pre>
datum_floor :: Datum -> Datum


-- | <a>Datum</a> related functions.
module Sound.OSC.Datum

-- | Type specialised <a>d_get</a>.
--   
--   <pre>
--   map datum_int32 [Int32 1,Float 1] == [Just 1,Nothing]
--   </pre>
datum_int32 :: Datum -> Maybe Int32

-- | Type specialised <a>d_get</a>.
datum_int64 :: Datum -> Maybe Int64

-- | Type specialised <a>d_get</a>.
datum_float :: Datum -> Maybe Float

-- | Type specialised <a>d_get</a>.
datum_double :: Datum -> Maybe Double

-- | Type specialised <a>d_get</a>.
--   
--   <pre>
--   datum_ascii (d_put (C.pack "string")) == Just (C.pack "string")
--   </pre>
datum_ascii :: Datum -> Maybe ASCII

-- | <a>unpack</a> of <a>d_get</a>.
--   
--   <pre>
--   datum_string (d_put (C.pack "string")) == Just "string"
--   map datum_string [string "string",Int32 5] == [Just "string",Nothing]
--   </pre>
datum_string :: Datum -> Maybe String

-- | Type specialised <a>d_get</a>.
datum_blob :: Datum -> Maybe ByteString

-- | <a>Maybe</a> variant of <a>d_timestamp</a>.
datum_timestamp :: Datum -> Maybe Time

-- | Type specialised <a>d_get</a>.
datum_midi :: Datum -> Maybe MIDI

-- | <a>Datum</a> as sequence of <a>Word8</a> if <a>ASCII_String</a>,
--   <a>Blob</a> or <a>Midi</a>.
--   
--   <pre>
--   let d = [string "5",Blob (B.pack [53]),midi (0x00,0x90,0x40,0x60)]
--   in Data.Maybe.mapMaybe datum_sequence d == [[53],[53],[0,144,64,96]]
--   </pre>
datum_sequence :: Datum -> Maybe [Word8]


-- | Bit-level type casts and byte layout string typecasts.
module Sound.OSC.Coding.Cast

-- | The IEEE byte representation of a float.
f32_w32 :: Float -> Word32

-- | Inverse of <a>f32_w32</a>.
w32_f32 :: Word32 -> Float

-- | The IEEE byte representation of a double.
f64_w64 :: Double -> Word64

-- | Inverse of <tt>f64_i64</tt>.
w64_f64 :: Word64 -> Double

-- | Transform a haskell string into a C string (a null suffixed byte
--   string).
str_cstr :: String -> [Word8]

-- | Inverse of <a>str_cstr</a>.
cstr_str :: [Word8] -> String

-- | Transform a haskell string to a pascal string (a length prefixed byte
--   string).
str_pstr :: String -> [Word8]

-- | Inverse of <a>str_pstr</a>.
pstr_str :: [Word8] -> String


-- | Byte-level coding utility functions.
module Sound.OSC.Coding.Byte

-- | Encode a signed 8-bit integer.
encode_i8 :: Int -> ByteString

-- | Encode an un-signed 8-bit integer.
encode_u8 :: Int -> ByteString

-- | Encode a signed 16-bit integer.
encode_i16 :: Int -> ByteString

-- | Encode a signed 32-bit integer.
encode_i32 :: Int -> ByteString

-- | Encode an unsigned 16-bit integer.
encode_u32 :: Int -> ByteString

-- | Encode a signed 64-bit integer.
encode_i64 :: Int64 -> ByteString

-- | Encode an unsigned 64-bit integer.
encode_u64 :: Word64 -> ByteString

-- | Encode a 32-bit IEEE floating point number.
encode_f32 :: Float -> ByteString

-- | Encode a 64-bit IEEE floating point number.
encode_f64 :: Double -> ByteString

-- | Encode an ASCII string.
encode_str :: ASCII -> ByteString

-- | Decode an un-signed 8-bit integer.
decode_u8 :: ByteString -> Int

-- | Decode a signed 8-bit integer.
decode_i8 :: ByteString -> Int

-- | Decode a signed 16-bit integer.
decode_i16 :: ByteString -> Int

-- | Decode a signed 32-bit integer.
decode_i32 :: ByteString -> Int

-- | Decode an unsigned 32-bit integer.
decode_u32 :: ByteString -> Int

-- | Decode a signed 64-bit integer.
decode_i64 :: ByteString -> Int64

-- | Decode an unsigned 64-bit integer.
decode_u64 :: ByteString -> Word64

-- | Decode a 32-bit IEEE floating point number.
decode_f32 :: ByteString -> Float

-- | Decode a 64-bit IEEE floating point number.
decode_f64 :: ByteString -> Double

-- | Decode an ASCII string.
decode_str :: ByteString -> ASCII

-- | Bundle header as a (strict) <a>ByteString</a>.
bundleHeader_strict :: ByteString

-- | Bundle header as a lazy ByteString.
bundleHeader :: ByteString

-- | The number of bytes required to align an OSC value to the next 4-byte
--   boundary.
--   
--   <pre>
--   map align [0::Int .. 7] == [0,3,2,1,0,3,2,1]
--   </pre>
align :: (Num i, Bits i) => i -> i


-- | Base-level decode function for OSC packets (slow). For ordinary use
--   see <a>Binary</a>.
module Sound.OSC.Coding.Decode.Base

-- | Decode an OSC <a>Message</a>.
decodeMessage :: ByteString -> Message

-- | Decode an OSC <a>Bundle</a>.
decodeBundle :: ByteString -> Bundle

-- | Decode an OSC <a>Packet</a>.
--   
--   <pre>
--   let b = B.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   in decodePacket b == Message "/g_free" [Int 0]
--   </pre>
decodePacket :: ByteString -> Packet


-- | Optimised decode function for OSC packets.
module Sound.OSC.Coding.Decode.Binary

-- | Get an OSC <a>Packet</a>.
getPacket :: Get Packet

-- | Decode an OSC packet from a lazy ByteString.
--   
--   <pre>
--   let b = B.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   in decodeOSC b == Message "/g_free" [Int 0]
--   </pre>
decodePacket :: ByteString -> Packet

-- | Decode an OSC packet from a strict ByteString.
decodePacket_strict :: ByteString -> Packet


-- | Base-level encode function for OSC packets (slow). For ordinary use
--   see <a>Builder</a>.
module Sound.OSC.Coding.Encode.Base

-- | Encode an OSC <a>Message</a>.
encodeMessage :: Message -> ByteString

-- | Encode an OSC <a>Bundle</a>.
encodeBundle :: Bundle -> ByteString

-- | Encode an OSC <a>Packet</a>.
encodePacket :: Packet -> ByteString


-- | Optimised encode function for OSC packets.
module Sound.OSC.Coding.Encode.Builder

-- | Builder monoid for an OSC <a>Packet</a>.
build_packet :: Packet -> Builder

-- | Encode an OSC <a>Message</a>.
encodeMessage :: Message -> ByteString

-- | Encode an OSC <a>Bundle</a>.
encodeBundle :: Bundle -> ByteString

-- | Encode an OSC <a>Packet</a> to a lazy <a>ByteString</a>.
--   
--   <pre>
--   let b = L.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   in encodeOSC (Message "/g_free" [Int 0]) == b
--   </pre>
encodePacket :: Packet -> ByteString

-- | Encode an Packet packet to a strict ByteString.
encodePacket_strict :: Packet -> ByteString


-- | A type-class to provide coding operations to different data types
--   using the same function names.
module Sound.OSC.Coding

-- | Converting from and to binary packet representations.
class Coding a
encodePacket :: Coding a => Packet -> a
decodePacket :: Coding a => a -> Packet

-- | An <a>encodePacket</a> and <a>decodePacket</a> pair over
--   <a>ByteString</a>.
type Coder = (Packet -> ByteString, ByteString -> Packet)

-- | <a>encodePacket</a> <a>.</a> <a>Packet_Message</a>.
encodeMessage :: Coding c => Message -> c

-- | <a>encodePacket</a> <a>.</a> <a>Packet_Bundle</a>.
encodeBundle :: Coding c => Bundle -> c

-- | <a>packet_to_message</a> <a>.</a> <a>decodePacket</a>.
decodeMessage :: Coding c => c -> Maybe Message

-- | <a>packet_to_bundle</a> <a>.</a> <a>decodePacket</a>.
decodeBundle :: Coding c => c -> Bundle
instance Sound.OSC.Coding.Coding Data.ByteString.Internal.ByteString
instance Sound.OSC.Coding.Coding Data.ByteString.Lazy.Internal.ByteString
instance Sound.OSC.Coding.Coding GHC.Base.String


-- | Typeclass for encoding and decoding OSC packets.
module Sound.OSC.Class

-- | A type-class for values that can be translated to and from OSC
--   <a>Packet</a>s.
class OSC o
toPacket :: OSC o => o -> Packet
fromPacket :: OSC o => Packet -> Maybe o

-- | <a>encodePacket</a> <a>.</a> <a>toPacket</a>.
encodeOSC :: (Coding c, OSC o) => o -> c

-- | <a>fromPacket</a> <a>.</a> <a>decodePacket</a>.
decodeOSC :: (Coding c, OSC o) => c -> Maybe o
instance Sound.OSC.Class.OSC Sound.OSC.Type.Message
instance Sound.OSC.Class.OSC Sound.OSC.Type.Bundle
instance Sound.OSC.Class.OSC Sound.OSC.Type.Packet


-- | Composite of non-transport related modules.
--   
--   Provides the <a>Datum</a>, <a>Message</a>, <a>Bundle</a> and
--   <a>Packet</a> types and the <a>Datem</a>, <a>OSC</a> and <a>Coding</a>
--   type-classes.
--   
--   The basic constructors are <a>message</a> and <a>bundle</a>, the basic
--   coding functions are <a>encodePacket</a> and <a>decodePacket</a>.
--   
--   <pre>
--   import Sound.OSC.Core
--   
--   let {o = bundle immediately [message "/g_free" [Int32 0]]
--       ;e = encodeBundle o :: String}
--   in decodeBundle e == o
--   </pre>
module Sound.OSC.Core


-- | An abstract transport layer with implementations for <tt>UDP</tt> and
--   <tt>TCP</tt> transport.
module Sound.OSC.Transport.FD

-- | Abstract over the underlying transport protocol.
class Transport t

-- | Encode and send an OSC packet.
sendOSC :: (Transport t, OSC o) => t -> o -> IO ()

-- | Receive and decode an OSC packet.
recvPacket :: Transport t => t -> IO Packet

-- | Close an existing connection.
close :: Transport t => t -> IO ()

-- | Bracket OSC communication.
withTransport :: Transport t => IO t -> (t -> IO a) -> IO a

-- | Type restricted synonym for <a>sendOSC</a>.
sendMessage :: Transport t => t -> Message -> IO ()

-- | Type restricted synonym for <a>sendOSC</a>.
sendBundle :: Transport t => t -> Bundle -> IO ()

-- | Variant of <a>recvPacket</a> that runs <a>fromPacket</a>.
recvOSC :: (Transport t, OSC o) => t -> IO (Maybe o)

-- | Variant of <a>recvPacket</a> that runs <a>packet_to_bundle</a>.
recvBundle :: (Transport t) => t -> IO Bundle

-- | Variant of <a>recvPacket</a> that runs <a>packet_to_message</a>.
recvMessage :: (Transport t) => t -> IO (Maybe Message)

-- | Variant of <a>recvPacket</a> that runs <a>packetMessages</a>.
recvMessages :: (Transport t) => t -> IO [Message]

-- | Variant of <a>recvPacket</a> that implements an <i>n</i> second
--   <tt>timeout</tt>.
recvPacketTimeout :: (Transport t) => Double -> t -> IO (Maybe Packet)

-- | Wait for a <a>Packet</a> where the supplied predicate is <a>True</a>,
--   discarding intervening packets.
waitUntil :: (Transport t) => t -> (Packet -> Bool) -> IO Packet

-- | Wait for a <a>Packet</a> where the supplied function does not give
--   <a>Nothing</a>, discarding intervening packets.
waitFor :: (Transport t) => t -> (Packet -> Maybe a) -> IO a

-- | <a>waitUntil</a> <a>packet_is_immediate</a>.
waitImmediate :: Transport t => t -> IO Packet

-- | <a>waitFor</a> <a>packet_to_message</a>, ie. an incoming
--   <a>Message</a> or immediate mode <a>Bundle</a> with one element.
waitMessage :: Transport t => t -> IO Message

-- | A <a>waitFor</a> for variant using <a>packet_has_address</a> to match
--   on the <a>Address_Pattern</a> of incoming <tt>Packets</tt>.
waitAddress :: Transport t => t -> Address_Pattern -> IO Packet

-- | Variant on <a>waitAddress</a> that returns matching <a>Message</a>.
waitReply :: Transport t => t -> Address_Pattern -> IO Message

-- | Variant of <a>waitReply</a> that runs <a>messageDatum</a>.
waitDatum :: Transport t => t -> Address_Pattern -> IO [Datum]


-- | OSC over TCP implementation.
module Sound.OSC.Transport.FD.TCP

-- | The TCP transport handle data type.
data TCP
TCP :: Handle -> TCP
[tcpHandle] :: TCP -> Handle

-- | Make a <a>TCP</a> connection.
openTCP :: String -> Int -> IO TCP

-- | A trivial <a>TCP</a> <i>OSC</i> server.
tcpServer' :: Int -> (TCP -> IO ()) -> IO ()
instance Sound.OSC.Transport.FD.Transport Sound.OSC.Transport.FD.TCP.TCP


-- | OSC over UDP implementation.
module Sound.OSC.Transport.FD.UDP

-- | The UDP transport handle data type.
data UDP
UDP :: Socket -> UDP
[udpSocket] :: UDP -> Socket

-- | Return the port number associated with the UDP socket.
udpPort :: Integral n => UDP -> IO n

-- | Create and initialise UDP socket.
udp_socket :: (Socket -> SockAddr -> IO ()) -> String -> Int -> IO UDP

-- | Make a <a>UDP</a> connection.
--   
--   <pre>
--   let t = openUDP "127.0.0.1" 57110
--   in withTransport t (\fd -&gt; recvT 0.5 fd &gt;&gt;= print)
--   </pre>
openUDP :: String -> Int -> IO UDP

-- | Trivial <a>UDP</a> server socket.
--   
--   <pre>
--   import Control.Concurrent
--   </pre>
--   
--   <pre>
--   let {f fd = forever (recvMessage fd &gt;&gt;= print)
--       ;t = udpServer "127.0.0.1" 57300}
--   in void (forkIO (withTransport t f))
--   </pre>
--   
--   <pre>
--   let t = openUDP "127.0.0.1" 57300
--   in withTransport t (\fd -&gt; sendMessage fd (message "/n" []))
--   </pre>
udpServer :: String -> Int -> IO UDP

-- | Send variant to send to specified address.
sendTo :: OSC o => UDP -> o -> SockAddr -> IO ()

-- | Recv variant to collect message source address.
recvFrom :: UDP -> IO (Packet, SockAddr)
instance Sound.OSC.Transport.FD.Transport Sound.OSC.Transport.FD.UDP.UDP


-- | Composite of <a>Sound.OSC.Core</a> and <a>Sound.OSC.Transport.FD</a>.
module Sound.OSC.FD


-- | Monad class implementing an Open Sound Control transport.
module Sound.OSC.Transport.Monad

-- | Sender monad.
class Monad m => SendOSC m

-- | Encode and send an OSC packet.
sendOSC :: (SendOSC m, OSC o) => o -> m ()

-- | Receiver monad.
class Monad m => RecvOSC m

-- | Receive and decode an OSC packet.
recvPacket :: RecvOSC m => m Packet

-- | <a>DuplexOSC</a> is the union of <a>SendOSC</a> and <a>RecvOSC</a>.
class (SendOSC m, RecvOSC m) => DuplexOSC m

-- | <a>Transport</a> is <a>DuplexOSC</a> with a <a>MonadIO</a> constraint.
class (DuplexOSC m, MonadIO m) => Transport m

-- | Transport connection.
type Connection t a = ReaderT t IO a

-- | Bracket Open Sound Control communication.
withTransport :: Transport t => IO t -> Connection t a -> IO a

-- | Type restricted synonym for <a>sendOSC</a>.
sendMessage :: SendOSC m => Message -> m ()

-- | Type restricted synonym for <a>sendOSC</a>.
sendBundle :: SendOSC m => Bundle -> m ()

-- | Variant of <a>recvPacket</a> that runs <a>fromPacket</a>.
recvOSC :: (RecvOSC m, OSC o) => m (Maybe o)

-- | Variant of <a>recvPacket</a> that runs <a>packet_to_bundle</a>.
recvBundle :: (RecvOSC m) => m Bundle

-- | Variant of <a>recvPacket</a> that runs <a>packet_to_message</a>.
recvMessage :: (RecvOSC m) => m (Maybe Message)

-- | Variant of <a>recvPacket</a> that runs <a>packetMessages</a>.
recvMessages :: (RecvOSC m) => m [Message]

-- | Wait for a <a>Packet</a> where the supplied predicate is <a>True</a>,
--   discarding intervening packets.
waitUntil :: (RecvOSC m) => (Packet -> Bool) -> m Packet

-- | Wait for a <a>Packet</a> where the supplied function does not give
--   <a>Nothing</a>, discarding intervening packets.
waitFor :: (RecvOSC m) => (Packet -> Maybe a) -> m a

-- | <a>waitUntil</a> <a>packet_is_immediate</a>.
waitImmediate :: RecvOSC m => m Packet

-- | <a>waitFor</a> <a>packet_to_message</a>, ie. an incoming
--   <a>Message</a> or immediate mode <a>Bundle</a> with one element.
waitMessage :: RecvOSC m => m Message

-- | A <a>waitFor</a> for variant using <a>packet_has_address</a> to match
--   on the <a>Address_Pattern</a> of incoming <tt>Packets</tt>.
waitAddress :: RecvOSC m => Address_Pattern -> m Packet

-- | Variant on <a>waitAddress</a> that returns matching <a>Message</a>.
waitReply :: RecvOSC m => Address_Pattern -> m Message

-- | Variant of <a>waitReply</a> that runs <a>messageDatum</a>.
waitDatum :: RecvOSC m => Address_Pattern -> m [Datum]
instance (Sound.OSC.Transport.FD.Transport t, Control.Monad.IO.Class.MonadIO io) => Sound.OSC.Transport.Monad.SendOSC (Control.Monad.Trans.Reader.ReaderT t io)
instance (Sound.OSC.Transport.FD.Transport t, Control.Monad.IO.Class.MonadIO io) => Sound.OSC.Transport.Monad.RecvOSC (Control.Monad.Trans.Reader.ReaderT t io)
instance (Sound.OSC.Transport.FD.Transport t, Control.Monad.IO.Class.MonadIO io) => Sound.OSC.Transport.Monad.DuplexOSC (Control.Monad.Trans.Reader.ReaderT t io)
instance (Sound.OSC.Transport.FD.Transport t, Control.Monad.IO.Class.MonadIO io) => Sound.OSC.Transport.Monad.Transport (Control.Monad.Trans.Reader.ReaderT t io)


-- | Composite of <a>Sound.OSC.Core</a> and
--   <a>Sound.OSC.Transport.Monad</a>.
module Sound.OSC
