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


-- | Haskell Open Sound Control
--   
--   Haskell library implementing the Open Sound Control protocol
@package hosc
@version 0.20


-- | Type conversion.
module Sound.Osc.Coding.Convert

-- | Type specialised <a>fromIntegral</a>
int_to_word8 :: Int -> Word8

-- | Type specialised <a>fromIntegral</a>
int_to_word32 :: Int -> Word32

-- | Type specialised <a>fromIntegral</a>.
int_to_word16 :: Int -> Word16

-- | Type specialised <a>fromIntegral</a>
int_to_int8 :: Int -> Int8

-- | Type specialised <a>fromIntegral</a>
int_to_int16 :: Int -> Int16

-- | Type specialised <a>fromIntegral</a>
int_to_int32 :: Int -> Int32

-- | Type specialised <a>fromIntegral</a>
int_to_int64 :: Int -> Int64

-- | Type specialised <a>fromIntegral</a>
int8_to_int :: Int8 -> Int

-- | Type specialised <a>fromIntegral</a>
int16_to_int :: Int16 -> Int

-- | Type specialised <a>fromIntegral</a>
int32_to_int :: Int32 -> Int

-- | Type specialised <a>fromIntegral</a>
int64_to_int :: Int64 -> Int

-- | Type specialised <a>fromIntegral</a>
word8_to_int :: Word8 -> Int

-- | Type specialised <a>fromIntegral</a>
word16_to_int :: Word16 -> Int

-- | Type specialised <a>fromIntegral</a>
word32_to_int :: Word32 -> Int

-- | Type specialised <a>fromIntegral</a>
word16_to_word32 :: Word16 -> Word32

-- | Type specialised <a>fromIntegral</a>
word32_to_word16 :: Word32 -> Word16

-- | Type specialised <a>fromIntegral</a>
word32_to_int32 :: Word32 -> Int32

-- | Type specialised <a>fromIntegral</a>
word32_to_int64 :: Word32 -> Int64

-- | Type specialised <a>fromIntegral</a>
word64_to_int64 :: Word64 -> Int64

-- | Type specialised <a>fromIntegral</a>
int64_to_int32 :: Int64 -> Int32

-- | Type specialised <a>fromIntegral</a>
int64_to_word32 :: Int64 -> Word32

-- | Type specialised <a>fromIntegral</a>
word64_to_double :: Word64 -> Double

-- | Type-specialised <a>toEnum</a> of <a>fromIntegral</a>
word8_to_enum :: Enum e => Word8 -> e

-- | Type-specialised <a>toEnum</a> of <a>fromIntegral</a>
word16_to_enum :: Enum e => Word16 -> e

-- | Type-specialised <a>fromIntegral</a> of <a>fromEnum</a>.
enum_to_word8 :: Enum e => e -> Word8

-- | Type-specialised <a>fromIntegral</a> of <a>fromEnum</a>.
enum_to_word16 :: Enum e => e -> Word16

-- | Type-specialised <a>word8_to_enum</a>.
word8_to_char :: Word8 -> Char

-- | Type-specialised <a>enum_to_word8</a>.
char_to_word8 :: Char -> 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. Plain forms are big-endian,
--   little-endian forms have <tt>_le</tt> suffix.
module Sound.Osc.Coding.Byte

-- | Type specialised <a>encode</a> (big-endian).
encode_int8 :: Int8 -> ByteString

-- | Type specialised <a>encode</a> (big-endian).
--   
--   <pre>
--   encode_int16 0x0102 == L.pack [0x01,0x02]
--   </pre>
encode_int16 :: Int16 -> ByteString

-- | Little-endian.
--   
--   <pre>
--   encode_int16_le 0x0102 == L.pack [0x02,0x01]
--   </pre>
encode_int16_le :: Int16 -> ByteString

-- | Encode a signed 64-bit integer (big-endian).
encode_int64 :: Int64 -> ByteString

-- | Type specialised <a>encode</a> (big-endian).
encode_word8 :: Word8 -> ByteString

-- | Type specialised <a>encode</a> (big-endian).
--   
--   <pre>
--   encode_word16 0x0102 == L.pack [0x01,0x02]
--   </pre>
encode_word16 :: Word16 -> ByteString

-- | Little-endian.
--   
--   <pre>
--   encode_word16_le 0x0102 == L.pack [0x02,0x01]
--   </pre>
encode_word16_le :: Word16 -> ByteString

-- | Type specialised <a>encode</a>.
encode_word32 :: Word32 -> ByteString

-- | Little-endian variant of <a>encode_word32</a>.
encode_word32_le :: Word32 -> ByteString

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

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

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

-- | Encode an un-signed 16-bit integer.
--   
--   <pre>
--   encode_u16 0x0102 == L.pack [1,2]
--   </pre>
encode_u16 :: Int -> ByteString

-- | Little-endian.
--   
--   <pre>
--   encode_u16_le 0x0102 == L.pack [2,1]
--   </pre>
encode_u16_le :: 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 32-bit integer.
--   
--   <pre>
--   encode_u32 0x01020304 == L.pack [1,2,3,4]
--   </pre>
encode_u32 :: Int -> ByteString

-- | Little-endian.
--   
--   <pre>
--   encode_u32_le 0x01020304 == L.pack [4,3,2,1]
--   </pre>
encode_u32_le :: Int -> ByteString

-- | Encode a 32-bit IEEE floating point number.
--   
--   <pre>
--   encode_f32 1.0 == L.pack [63, 128, 0, 0]
--   </pre>
encode_f32 :: Float -> ByteString

-- | Little-endian variant of <a>encode_f32</a>.
encode_f32_le :: Float -> ByteString

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

-- | Little-endian variant of <a>encode_f64</a>.
encode_f64_le :: Double -> ByteString

-- | Encode an Ascii string (Ascii at Datum is an alias for a Char8
--   Bytetring).
encode_ascii :: ByteString -> ByteString

-- | Type specialised <a>decode</a>.
decode_word16 :: ByteString -> Word16

-- | Little-endian variant of <a>decode_word16</a>.
decode_word16_le :: ByteString -> Word16

-- | Type specialised <a>decode</a>.
decode_int16 :: ByteString -> Int16

-- | Type specialised <a>decode</a>.
decode_word32 :: ByteString -> Word32

-- | Little-endian variant of <a>decode_word32</a>.
decode_word32_le :: ByteString -> Word32

-- | Type specialised <a>decode</a>.
decode_int64 :: ByteString -> Int64

-- | Type specialised <a>decode</a>.
decode_word64 :: ByteString -> Word64

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

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

-- | Decode an unsigned 8-bit integer.
decode_u16 :: ByteString -> Int

-- | Little-endian variant of <a>decode_u16</a>.
decode_u16_le :: ByteString -> Int

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

-- | Little-endian variant of <a>decode_i16</a>.
decode_i16_le :: ByteString -> Int

-- | Decode a signed 32-bit integer.
--   
--   <pre>
--   decode_i32 (L.pack [0x00,0x00,0x03,0xe7]) == 0x03e7
--   </pre>
decode_i32 :: ByteString -> Int

-- | Little-endian variant of <a>decode_i32</a>.
--   
--   <pre>
--   decode_i32_le (L.pack [0xe7,0x03,0x00,0x00]) == 0x03e7
--   </pre>
decode_i32_le :: ByteString -> Int

-- | Decode an unsigned 32-bit integer.
--   
--   <pre>
--   decode_u32 (L.pack [1,2,3,4]) == 0x01020304
--   </pre>
decode_u32 :: ByteString -> Int

-- | Little-endian variant of decode_u32.
--   
--   <pre>
--   decode_u32_le (L.pack [1,2,3,4]) == 0x04030201
--   </pre>
decode_u32_le :: ByteString -> Int

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

-- | Little-endian variant of <a>decode_f32</a>.
decode_f32_le :: ByteString -> Float

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

-- | Decode an Ascii string, inverse of <a>encode_ascii</a>.
decode_ascii :: ByteString -> ByteString

-- | Read <i>n</i> bytes from <i>h</i> and run <i>f</i>.
read_decode :: (ByteString -> t) -> Int -> Handle -> IO t

-- | Type-specialised reader for <a>decode</a>.
read_word32 :: Handle -> IO Word32

-- | <a>read_decode</a> of <a>decode_word32_le</a>.
read_word32_le :: Handle -> IO Word32

-- | <a>hPut</a> of <a>encode_word32</a>.
write_word32 :: Handle -> Word32 -> IO ()

-- | <a>hPut</a> of <a>encode_word32_le</a>.
write_word32_le :: Handle -> Word32 -> IO ()

-- | <a>decode_i8</a> of <a>hGet</a>.
read_i8 :: Handle -> IO Int

-- | <a>decode_i16</a> of <a>hGet</a>.
read_i16 :: Handle -> IO Int

-- | <a>decode_i32</a> of <a>hGet</a>.
read_i32 :: Handle -> IO Int

-- | <a>decode_i32_le</a> of <a>hGet</a>.
read_i32_le :: Handle -> IO Int

-- | <a>decode_u32</a> of <a>hGet</a>.
read_u32 :: Handle -> IO Int

-- | <a>decode_u32_le</a> of <a>hGet</a>.
read_u32_le :: Handle -> IO Int

-- | <a>hPut</a> of <a>encode_u32</a>.
write_u32 :: Handle -> Int -> IO ()

-- | <a>hPut</a> of <a>encode_u32_le</a>.
write_u32_le :: Handle -> Int -> IO ()

-- | <a>decode_f32</a> of <a>hGet</a>.
read_f32 :: Handle -> IO Float

-- | <a>decode_f32_le</a> of <a>hGet</a>.
read_f32_le :: Handle -> IO Float

-- | Read u8 length prefixed Ascii string (pascal string).
read_pstr :: Handle -> IO ByteString

-- | Bundle header as a (strict) <a>ByteString</a>.
--   
--   <pre>
--   S.C.length bundleHeader_strict == 8
--   </pre>
bundleHeader_strict :: ByteString

-- | Bundle header as a lazy ByteString.
--   
--   <pre>
--   L.length bundleHeader == 8
--   </pre>
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]
--   map align [512::Int .. 519] == [0,3,2,1,0,3,2,1]
--   </pre>
align :: (Num i, Bits i) => i -> i


-- | Osc data types.
module Sound.Osc.Datum

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

-- | Type for Ascii strings (strict Char8 ByteString)
type Ascii = ByteString

-- | Type-specialised pack.
ascii :: String -> Ascii

-- | Type-specialised unpack.
ascii_to_string :: Ascii -> String

-- | Type for <a>Word8</a> arrays, these are stored with an <a>Datum</a>
--   length prefix.
type Blob = ByteString

-- | Type-specialised pack.
blob_pack :: [Word8] -> Blob

-- | Type-specialised unpack.
blob_unpack :: Blob -> [Word8]

-- | Type-specialised unpack.
blob_unpack_int :: Blob -> [Int]

-- | Four-byte midi message: port-id, status-byte, data, data.
data MidiData
MidiData :: !Word8 -> !Word8 -> !Word8 -> !Word8 -> MidiData
midi_pack :: [Word8] -> MidiData

-- | Type-specialised unpack.
midi_unpack_int :: MidiData -> [Int]

-- | A real-valued time stamp. For Osc proper this is an Ntp64 time in
--   real-valued (fractional) form. For SuperCollider Nrt programs this is
--   elapsed time since the start of the score. This is the primary form of
--   timestamp used by hosc.
type Time = Double

-- | 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
AsciiString :: !Ascii -> Datum
[d_ascii_string] :: Datum -> !Ascii
Blob :: !Blob -> Datum
[d_blob] :: Datum -> !Blob
TimeStamp :: !Time -> Datum
[d_timestamp] :: Datum -> !Time
Midi :: !MidiData -> Datum
[d_midi] :: Datum -> !MidiData

-- | List of required data types (tag, name).
osc_types_required :: [(DatumType, String)]

-- | List of optional data types (tag,name).
osc_types_optional :: [(DatumType, String)]

-- | List of all data types (tag,name).
osc_types :: [(DatumType, String)]

-- | Lookup name of type.
osc_type_name :: DatumType -> Maybe String

-- | Erroring variant.
osc_type_name_err :: DatumType -> String

-- | Single character identifier of an Osc datum.
datum_tag :: Datum -> DatumType

-- | Type and name of <a>Datum</a>.
datum_type_name :: Datum -> (DatumType, String)

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

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

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

-- | <a>AsciiString</a> of pack.
--   
--   <pre>
--   string "string" == AsciiString (ByteString.Char8.pack "string")
--   </pre>
string :: String -> Datum

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

-- | <a>Blob</a> of <a>blob_pack</a>.
blob :: [Word8] -> Datum

-- | Message argument types are given by a signature.
--   
--   <pre>
--   signatureFor [Int32 1,Float 1,string "1"] == ",ifs"
--   </pre>
signatureFor :: [Datum] -> String

-- | The descriptor is an Ascii encoded signature.
--   
--   <pre>
--   descriptor [Int32 1,Float 1,string "1"] == ascii ",ifs"
--   </pre>
descriptor :: [Datum] -> Ascii

-- | Descriptor tags are <tt>comma</tt> prefixed.
descriptor_tags :: Ascii -> Ascii
instance GHC.Read.Read Sound.Osc.Datum.MidiData
instance GHC.Show.Show Sound.Osc.Datum.MidiData
instance GHC.Classes.Eq Sound.Osc.Datum.MidiData
instance GHC.Classes.Ord Sound.Osc.Datum.MidiData
instance GHC.Show.Show Sound.Osc.Datum.Datum
instance GHC.Read.Read Sound.Osc.Datum.Datum
instance GHC.Classes.Eq Sound.Osc.Datum.Datum
instance GHC.Classes.Ord Sound.Osc.Datum.Datum


-- | Some backwards compatability, not really...
module Sound.Osc.Alias
type Datum_Type = DatumType
type BLOB = Blob
type ASCII = Ascii
type MIDI = MidiData


-- | Data types for Osc messages, bundles and packets.
module Sound.Osc.Packet

-- | Osc address pattern. This is strictly an Ascii value, however it is
--   very common to pattern match on addresses and matching on
--   Data.ByteString.Char8 requires <tt>OverloadedStrings</tt>.
type Address_Pattern = String

-- | An Osc message, an <a>Address_Pattern</a> and a sequence of
--   <a>Datum</a>.
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
messageSignature :: Message -> String
messageDescriptor :: Message -> Ascii

-- | An Osc bundle, a <a>Time</a> and a sequence of <a>Message</a>s. Do not
--   allow recursion, all contents must be messages.
data Bundle
Bundle :: !Time -> ![Message] -> Bundle
[bundleTime] :: Bundle -> !Time
[bundleMessages] :: Bundle -> ![Message]

-- | <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> of <a>bundle</a>.
p_bundle :: Time -> [Message] -> Packet

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

-- | Constant indicating a bundle to be executed immediately. It has the
--   Ntp64 representation of <tt>1</tt>.
--   
--   <pre>
--   ntpr_to_ntpi immediately == 1
--   </pre>
immediately :: Time

-- | 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
instance GHC.Show.Show Sound.Osc.Packet.Message
instance GHC.Read.Read Sound.Osc.Packet.Message
instance GHC.Classes.Eq Sound.Osc.Packet.Message
instance GHC.Classes.Ord Sound.Osc.Packet.Message
instance GHC.Show.Show Sound.Osc.Packet.Bundle
instance GHC.Read.Read Sound.Osc.Packet.Bundle
instance GHC.Classes.Eq Sound.Osc.Packet.Bundle
instance GHC.Show.Show Sound.Osc.Packet.Packet
instance GHC.Read.Read Sound.Osc.Packet.Packet
instance GHC.Classes.Eq Sound.Osc.Packet.Packet
instance GHC.Classes.Ord Sound.Osc.Packet.Bundle


-- | Osc related timing functions. Osc timestamps are 64-bit <tt>Ntp</tt>
--   values, <a>http://ntp.org/</a>.
module Sound.Osc.Time

-- | Type for binary (integeral) representation of a 64-bit Ntp timestamp
--   (ie. ntpi). The Ntp epoch is January 1, 1900. Ntp v4 also includes a
--   128-bit format, which is not used by Osc.
type Ntp64 = Word64

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

-- | <tt>Unix/Posix</tt> time in real-valued (fractional) form. The
--   Unix/Posix epoch is January 1, 1970.
type PosixReal = Double

-- | Convert an NtpReal timestamp to an Ntp64 timestamp.
--   
--   <pre>
--   ntpr_to_ntpi 0 == 0
--   fmap ntpr_to_ntpi time
--   </pre>
ntpr_to_ntpi :: NtpReal -> Ntp64

-- | Convert an <a>Ntp64</a> timestamp to a real-valued Ntp timestamp.
--   
--   <pre>
--   ntpi_to_ntpr 0 == 0.0
--   </pre>
ntpi_to_ntpr :: Ntp64 -> NtpReal

-- | Difference (in seconds) between <i>Ntp</i> and <i>Posix</i> epochs.
--   
--   <pre>
--   ntp_posix_epoch_diff / (24 * 60 * 60) == 25567
--   25567 `div` 365 == 70
--   </pre>
ntp_posix_epoch_diff :: Num n => n

-- | Convert a PosixReal timestamp to an Ntp64 timestamp.
posix_to_ntpi :: PosixReal -> Ntp64

-- | Convert <tt>Unix/Posix</tt> to <tt>Ntp</tt>.
posix_to_ntpr :: Num n => n -> n

-- | Convert <tt>Ntp</tt> to <tt>Unix/Posix</tt>.
ntpr_to_posix :: Num n => n -> n

-- | Convert <a>Ntp64</a> to <tt>Unix/Posix</tt>.
ntpi_to_posix :: Ntp64 -> PosixReal

-- | Convert <tt>Time</tt> to <a>POSIXTime</a>.
ntpr_to_posixtime :: NtpReal -> POSIXTime

-- | Convert <a>POSIXTime</a> to <tt>Time</tt>.
posixtime_to_ntpr :: POSIXTime -> NtpReal

-- | The time at 1970-01-01:00:00:00 which is the Unix/Posix epoch.
posix_epoch :: UTCTime

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

-- | utc_to_posix of Clock.getCurrentTime.
getCurrentTimeAsPosix :: IO PosixReal

-- | realToFrac of Clock.Posix.getPOSIXTime
--   
--   <pre>
--   get_ct = getCurrentTimeAsPosix
--   get_pt = getPosixTimeAsPosix
--   (ct,pt) &lt;- get_ct &gt;&gt;= \t0 -&gt; get_pt &gt;&gt;= \t1 -&gt; return (t0,t1)
--   print (pt - ct,pt - ct &lt; 1e-5)
--   </pre>
getPosixTimeAsPosix :: IO PosixReal

-- | Read current real-valued <tt>Ntp</tt> timestamp.
currentTime :: IO NtpReal


-- | A simple and unambigous text encoding for Osc.
module Sound.Osc.Text

-- | Precision value for floating point numbers.
type FpPrecision = Maybe Int

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

-- | Hex encoded byte sequence.
--   
--   <pre>
--   showBytes [0, 15, 16, 144, 255] == "000f1090ff"
--   </pre>
showBytes :: [Int] -> String

-- | Escape whites space (space, tab, newline) and the escape character
--   (backslash).
--   
--   <pre>
--   mapM_ (putStrLn .  escapeString) ["str", "str ", "st r", "s\tr", "s\\tr", "\nstr"]
--   </pre>
escapeString :: String -> String

-- | Printer for Datum.
--   
--   <pre>
--   aDatumSeq = [Int32 1,Float 1.2,string "str",midi (0,0x90,0x40,0x60),blob [12,16], TimeStamp 100.0]
--   map (showDatum (Just 5)) aDatumSeq == ["1","1.2","str","00904060","0c10","429496729600"]
--   </pre>
showDatum :: FpPrecision -> Datum -> String

-- | Printer for Message.
--   
--   <pre>
--   aMessage = Message "/addr" [Int32 1, Int64 2, Float 3, Double 4, string "five", blob [6, 7], midi (8, 9, 10, 11)]
--   showMessage (Just 4) aMessage
--   </pre>
--   
--   <pre>
--   aMessageSeq = [Message "/c_set" [Int32 1, Float 2.3], Message "/s_new" [string "sine", Int32 (-1), Int32 1, Int32 1]]
--   map (showMessage (Just 4)) aMessageSeq
--   </pre>
showMessage :: FpPrecision -> Message -> String

-- | Printer for Bundle
--   
--   <pre>
--   aBundle = Bundle 1 [Message "/c_set" [Int32 1, Float 2.3, Int64 4, Double 5.6], Message "/memset" [string "addr", blob [7, 8]]]
--   showBundle (Just 4) aBundle
--   </pre>
showBundle :: FpPrecision -> Bundle -> String

-- | Printer for Packet.
showPacket :: FpPrecision -> Packet -> String

-- | A character parser with no user state.
type P a = GenParser Char () a

-- | Run p then q, returning result of p.
(>>~) :: Monad m => m t -> m u -> m t

-- | <i>p</i> as lexeme, i.e. consuming any trailing white space.
lexemeP :: P t -> P t

-- | Any non-space character. Allow escaped space.
stringCharP :: P Char

-- | Parser for string.
stringP :: P String

-- | Parser for Osc address.
oscAddressP :: P String

-- | Parser for Osc signature.
oscSignatureP :: P String

-- | Parser for decimal digit.
digitP :: P Char
allowNegativeP :: Num n => P n -> P n

-- | Parser for non-negative integer.
nonNegativeIntegerP :: (Integral n, Read n) => P n

-- | Parser for integer.
integerP :: (Integral n, Read n) => P n

-- | Parser for non-negative float.
nonNegativeFloatP :: (Fractional n, Read n) => P n

-- | Parser for non-negative float.
floatP :: (Fractional n, Read n) => P n

-- | Parser for hexadecimal digit.
hexdigitP :: P Char

-- | Byte parser.
byteP :: (Integral n, Read n) => P n

-- | Byte sequence parser.
byteSeqP :: (Integral n, Read n) => P [n]

-- | Datum parser.
datumP :: Char -> P Datum

-- | Message parser.
messageP :: P Message

-- | Bundle tag parser.
bundleTagP :: P String

-- | Bundle parser.
bundleP :: P Bundle

-- | Packet parser.
packetP :: P Packet

-- | Run parser.
runP :: P t -> String -> t

-- | Run datum parser.
--   
--   <pre>
--   parseDatum 'i' "-1" == Int32 (-1)
--   parseDatum 'f' "-2.3" == Float (-2.3)
--   </pre>
parseDatum :: Char -> String -> Datum

-- | Run message parser.
--   
--   <pre>
--   aMessageSeq = [Message "/c_set" [Int32 1, Float 2.3, Int64 4, Double 5.6], Message "/memset" [string "addr", blob [7, 8]]]
--   map (parseMessage . showMessage (Just 4)) aMessageSeq  == aMessageSeq
--   </pre>
parseMessage :: String -> Message

-- | Run bundle parser.
--   
--   <pre>
--   aBundle = Bundle 1 [Message "/c_set" [Int32 1, Float 2.3, Int64 4, Double 5.6], Message "/memset" [string "addr", blob [7, 8]]]
--   parseBundle (showBundle (Just 4) aBundle) == aBundle
--   </pre>
parseBundle :: String -> Bundle

-- | Run packet parser.
--   
--   <pre>
--   aPacket = Packet_Bundle (Bundle 1 [Message "/c_set" [Int32 1, Float 2.3, Int64 4, Double 5.6], Message "/memset" [string "addr", blob [7, 8]]])
--   parsePacket (showPacket (Just 4) aPacket) == aPacket
--   </pre>
parsePacket :: String -> Packet


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

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

-- | Encode an Osc <a>Message</a>, ie. <a>encodePacket</a> of
--   <a>Packet_Message</a>.
--   
--   <pre>
--   let m = [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   encodeMessage (Message "/g_free" [Int32 0]) == L.pack m
--   </pre>
encodeMessage :: Message -> ByteString

-- | Encode an Osc <a>Bundle</a>, ie. <a>encodePacket</a> of
--   <a>Packet_Bundle</a>.
--   
--   <pre>
--   let m = [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   let b = [35,98,117,110,100,108,101,0,0,0,0,0,0,0,0,1,0,0,0,16] ++ m
--   encodeBundle (Bundle immediately [Message "/g_free" [Int32 0]]) == L.pack b
--   </pre>
encodeBundle :: Bundle -> ByteString

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

-- | Encode an Osc <a>Packet</a> to a strict <a>ByteString</a>.
encodePacket_strict :: Packet -> ByteString


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

-- | Align byte string, if required.
extend :: Word8 -> ByteString -> ByteString

-- | Encode Osc <a>Datum</a>.
--   
--   MidiData: Bytes from MSB to LSB are: port id, status byte, data1,
--   data2.
--   
--   <pre>
--   encode_datum (blob [1, 2, 3, 4]) == B.pack [0, 0, 0, 4, 1, 2, 3, 4]
--   </pre>
encode_datum :: Datum -> ByteString

-- | Encode Osc <a>Message</a>.
--   
--   <pre>
--   m = Message "/n_set" [int32 (-1), string "freq", float 440, string "amp", float 0.1]
--   e = blob_unpack (encodeMessage m)
--   length e == 40
--   e == [47,110,95,115,101,116,0,0,44,105,115,102,115,102,0,0,255,255,255,255,102,114,101,113,0,0,0,0,67,220,0,0,97,109,112,0,61,204,204,205]
--   </pre>
encodeMessage :: Message -> ByteString

-- | Encode Osc <a>Message</a> as an Osc blob.
encode_message_blob :: Message -> Datum

-- | Encode Osc <a>Bundle</a>.
--   
--   b = Bundle 0.0 [m] e = blob_unpack (encodeBundle b) length e == 60 e
--   ==
--   [35,98,117,110,100,108,101,0,0,0,0,0,0,0,0,0,0,0,0,40,47,110,95,115,101,116,0,0,44,105,115,102,115,102,0,0,255,255,255,255,102,114,101,113,0,0,0,0,67,220,0,0,97,109,112,0,61,204,204,205]
encodeBundle :: Bundle -> ByteString

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


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

-- | Get an Osc <a>Packet</a>.
get_packet :: Get Packet

-- | Decode an Osc <a>Message</a> from a lazy ByteString.
--   
--   <pre>
--   let b = ByteString.Lazy.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   decodeMessage b == Message "/g_free" [Int32 0]
--   </pre>
decodeMessage :: ByteString -> Message

-- | Decode an Osc <a>Bundle</a> from a lazy ByteString.
decodeBundle :: ByteString -> Bundle

-- | Decode an Osc packet from a lazy ByteString.
--   
--   <pre>
--   let b = ByteString.Lazy.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   decodePacket b == Packet_Message (Message "/g_free" [Int32 0])
--   </pre>
decodePacket :: ByteString -> Packet

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


-- | Base-level decode function for Osc packets. 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]
--   decodePacket b == Packet_Message (Message "/g_free" [Int32 0])
--   </pre>
decodePacket :: ByteString -> Packet


-- | System time
module Sound.Osc.Time.System

-- | Get the system time, epoch start of 1970 UTC, leap-seconds ignored.
--   getSystemTime is typically much faster than getCurrentTime, however it
--   is not available in Hugs.
getSystemTimeAsNtpReal :: IO NtpReal

-- | System time with fractional part in microseconds (us) instead of
--   nanoseconds (ns).
getSystemTimeInMicroseconds :: IO (Int64, Word32)


-- | Thread operations.
module Sound.Osc.Time.Thread

-- | The <tt>pauseThread</tt> limit (in seconds). Values larger than this
--   require a different thread delay mechanism, see <tt>sleepThread</tt>.
--   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>.
pauseThreadFor :: RealFrac n => n -> IO ()

-- | Pause current thread until the given time, see
--   <a>pauseThreadLimit</a>.
pauseThreadUntilTime :: RealFrac n => n -> IO ()

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

-- | Sleep current thread until the given time. Divides long sleeps into
--   parts smaller than <a>pauseThreadLimit</a>.
sleepThreadUntilTime :: RealFrac n => n -> IO ()


-- | MonadIO lifted forms of Sound.Osc.Time.Thread functions
module Sound.Osc.Time.Thread.MonadIO
time :: MonadIO m => m NtpReal
pauseThread :: (MonadIO m, RealFrac n) => n -> m ()
wait :: MonadIO m => Double -> m ()
pauseThreadUntil :: (MonadIO m, RealFrac n) => n -> m ()
sleepThread :: (RealFrac n, MonadIO m) => n -> m ()
sleepThreadUntil :: (RealFrac n, MonadIO m) => n -> m ()


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

-- | 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


-- | 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.
sendPacket :: Transport t => t -> Packet -> 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

-- | <a>sendPacket</a> of <a>Packet_Message</a>.
sendMessage :: Transport t => t -> Message -> IO ()

-- | <a>sendPacket</a> of <a>Packet_Bundle</a>.
sendBundle :: Transport t => t -> Bundle -> IO ()

-- | 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]

-- | 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]


-- | 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.
sendPacket :: SendOsc m => Packet -> 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 r -> IO r

-- | <a>void</a> of <a>withTransport</a>.
withTransport_ :: Transport t => IO t -> Connection t r -> IO ()

-- | Type restricted synonym for <tt>sendOsc</tt>.
sendMessage :: SendOsc m => Message -> m ()

-- | Type restricted synonym for <tt>sendOsc</tt>.
sendBundle :: SendOsc m => Bundle -> m ()

-- | Variant of <a>recvPacket</a> that runs <tt>packet_to_bundle</tt>.
recvBundle :: RecvOsc m => m Bundle

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

-- | Erroring variant.
recvMessage_err :: RecvOsc m => m Message

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

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

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

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

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

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

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

-- | Variant of <a>waitReply</a> that runs <tt>messageDatum</tt>.
waitDatum :: RecvOsc m => Address_Pattern -> m [Datum]
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)
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.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.SendOsc (Control.Monad.Trans.Reader.ReaderT t io)


-- | Osc over Udp implementation.
module Sound.Osc.Transport.Fd.Udp

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

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

-- | Send data over Udp using <a>send</a>.
udp_send_data :: Udp -> ByteString -> IO ()

-- | Send data over Udp using <a>sendAll</a>.
udp_sendAll_data :: Udp -> ByteString -> IO ()

-- | Send packet over Udp.
udp_send_packet :: Udp -> Packet -> IO ()

-- | Receive packet over Udp.
udp_recv_packet :: Udp -> IO Packet

-- | Close Udp.
udp_close :: Udp -> IO ()

-- | Bracket Udp communication.
with_udp :: IO Udp -> (Udp -> IO t) -> IO t

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

-- | Set option, ie. <a>Broadcast</a> or <a>RecvTimeOut</a>.
set_udp_opt :: SocketOption -> Int -> Udp -> IO ()

-- | Get option.
get_udp_opt :: SocketOption -> Udp -> IO Int

-- | Make a <a>Udp</a> connection.
openUdp :: String -> Int -> IO Udp

-- | Trivial <a>Udp</a> server socket.
--   
--   <pre>
--   import Control.Concurrent {- base -}
--   </pre>
--   
--   <pre>
--   let u0 = udpServer "127.0.0.1" 57300
--   t0 &lt;- forkIO (Fd.withTransport u0 (\fd -&gt; forever (Fd.recvMessage fd &gt;&gt;= print &gt;&gt; print "Received message, continuing")))
--   killThread t0
--   </pre>
--   
--   <pre>
--   let u1 = openUdp "127.0.0.1" 57300
--   Fd.withTransport u1 (\fd -&gt; Fd.sendMessage fd (Packet.message "/n" []))
--   </pre>
udpServer :: String -> Int -> IO Udp

-- | Variant of <a>udpServer</a> that doesn't require the host address.
udp_server :: Int -> IO Udp

-- | Send to specified address using 'C.sendAllTo.
sendTo :: Udp -> Packet -> 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


-- | Osc over Tcp implementation.
module Sound.Osc.Transport.Fd.Tcp

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

-- | Send data over Tcp.
tcp_send_data :: Tcp -> ByteString -> IO ()

-- | Send packet over Tcp.
tcp_send_packet :: Tcp -> Packet -> IO ()

-- | Receive packet over Tcp.
tcp_recv_packet :: Tcp -> IO Packet

-- | Close Tcp.
tcp_close :: Tcp -> IO ()

-- | Bracket UDP communication.
with_tcp :: IO Tcp -> (Tcp -> IO t) -> IO t

-- | Create and initialise Tcp socket.
tcp_socket :: (Socket -> SockAddr -> IO ()) -> Maybe String -> Int -> IO Socket

-- | Convert <a>Socket</a> to <a>Tcp</a>.
socket_to_tcp :: Socket -> IO Tcp

-- | Create and initialise Tcp.
tcp_handle :: (Socket -> SockAddr -> IO ()) -> String -> Int -> IO Tcp

-- | Make a <a>Tcp</a> connection.
--   
--   <pre>
--   import Sound.Osc.Datum {- hosc -}
--   import Sound.Osc.Time {- hosc -}
--   let t = openTcp "127.0.0.1" 57110
--   let m1 = Packet.message "/dumpOsc" [Int32 1]
--   let m2 = Packet.message "/g_new" [Int32 1]
--   Fd.withTransport t (\fd -&gt; let f = Fd.sendMessage fd in f m1 &gt;&gt; pauseThread 0.25 &gt;&gt; f m2)
--   </pre>
openTcp :: String -> Int -> IO Tcp

-- | <a>accept</a> connection at <i>s</i> and run <i>f</i>.
tcp_server_f :: Socket -> (Tcp -> IO ()) -> IO ()

-- | A trivial <a>Tcp</a> <i>Osc</i> server.
tcp_server :: Int -> (Tcp -> IO ()) -> IO ()
instance Sound.Osc.Transport.Fd.Transport Sound.Osc.Transport.Fd.Tcp.Tcp


-- | Timeout, implemented independently of socket timeout setting.
module Sound.Osc.Time.Timeout

-- | Variant of <a>timeout</a> where time is given in fractional seconds.
timeout_r :: Double -> IO a -> IO (Maybe a)

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


-- | Composite of non-transport related modules.
--   
--   Provides the <a>Datum</a>, <a>Message</a>, <a>Time</a>, <a>Bundle</a>
--   and <a>Packet</a> types and the coding functions <a>encodePacket</a>
--   and <a>decodePacket</a>.
--   
--   <pre>
--   import Sound.Osc.Core {- hosc -}
--   
--   let o = bundle immediately [message "/g_free" [Int32 0]]
--   let e = encodeBundle o
--   decodePacket e == Packet_Bundle o
--   </pre>
module Sound.Osc.Core


-- | Composite of <a>Sound.Osc.Core</a> and <a>Sound.Osc.Transport.Fd</a>.
module Sound.Osc.Fd


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

-- | Monads in which <a>IO</a> computations may be embedded. Any monad
--   built by applying a sequence of monad transformers to the <a>IO</a>
--   monad will be an instance of this class.
--   
--   Instances should satisfy the following laws, which state that
--   <a>liftIO</a> is a transformer of monads:
--   
--   <ul>
--   <li><pre><a>liftIO</a> . <a>return</a> = <a>return</a></pre></li>
--   <li><pre><a>liftIO</a> (m &gt;&gt;= f) = <a>liftIO</a> m &gt;&gt;=
--   (<a>liftIO</a> . f)</pre></li>
--   </ul>
class Monad m => MonadIO (m :: Type -> Type)

-- | Lift a computation from the <a>IO</a> monad. This allows us to run IO
--   computations in any monadic stack, so long as it supports these kinds
--   of operations (i.e. <a>IO</a> is the base monad for the stack).
--   
--   <h3><b>Example</b></h3>
--   
--   <pre>
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s =&gt; StateT s IO ()
--   printState = do
--     state &lt;- get
--     liftIO $ print state
--   </pre>
--   
--   Had we omitted <tt><a>liftIO</a></tt>, we would have ended up with
--   this error:
--   
--   <pre>
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   </pre>
--   
--   The important part here is the mismatch between <tt>StateT s IO
--   ()</tt> and <tt><a>IO</a> ()</tt>.
--   
--   Luckily, we know of a function that takes an <tt><a>IO</a> a</tt> and
--   returns an <tt>(m a)</tt>: <tt><a>liftIO</a></tt>, enabling us to run
--   the program and see the expected results:
--   
--   <pre>
--   &gt; evalStateT printState "hello"
--   "hello"
--   
--   &gt; evalStateT printState 3
--   3
--   </pre>
liftIO :: MonadIO m => IO a -> m a

-- | An Osc message, an <a>Address_Pattern</a> and a sequence of
--   <a>Datum</a>.
data Message
Message :: !Address_Pattern -> ![Datum] -> Message
[messageAddress] :: Message -> !Address_Pattern
[messageDatum] :: Message -> ![Datum]

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

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

-- | 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
AsciiString :: !Ascii -> Datum
[d_ascii_string] :: Datum -> !Ascii
Blob :: !Blob -> Datum
[d_blob] :: Datum -> !Blob
TimeStamp :: !Time -> Datum
[d_timestamp] :: Datum -> !Time
Midi :: !MidiData -> Datum
[d_midi] :: Datum -> !MidiData

-- | 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 real-valued time stamp. For Osc proper this is an Ntp64 time in
--   real-valued (fractional) form. For SuperCollider Nrt programs this is
--   elapsed time since the start of the score. This is the primary form of
--   timestamp used by hosc.
type Time = Double

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

-- | Osc address pattern. This is strictly an Ascii value, however it is
--   very common to pattern match on addresses and matching on
--   Data.ByteString.Char8 requires <tt>OverloadedStrings</tt>.
type Address_Pattern = String

-- | Type for binary (integeral) representation of a 64-bit Ntp timestamp
--   (ie. ntpi). The Ntp epoch is January 1, 1900. Ntp v4 also includes a
--   128-bit format, which is not used by Osc.
type Ntp64 = Word64

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

-- | Type for Ascii strings (strict Char8 ByteString)
type Ascii = ByteString

-- | Type for <a>Word8</a> arrays, these are stored with an <a>Datum</a>
--   length prefix.
type Blob = ByteString

-- | Four-byte midi message: port-id, status-byte, data, data.
data MidiData
MidiData :: !Word8 -> !Word8 -> !Word8 -> !Word8 -> MidiData

-- | An Osc bundle, a <a>Time</a> and a sequence of <a>Message</a>s. Do not
--   allow recursion, all contents must be messages.
data Bundle
Bundle :: !Time -> ![Message] -> Bundle
[bundleTime] :: Bundle -> !Time
[bundleMessages] :: Bundle -> ![Message]

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

-- | <tt>Unix/Posix</tt> time in real-valued (fractional) form. The
--   Unix/Posix epoch is January 1, 1970.
type PosixReal = Double

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

-- | Encode and send an Osc packet.
sendPacket :: SendOsc m => Packet -> 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

-- | Transport connection.
type Connection t a = ReaderT t IO a
time :: MonadIO m => m NtpReal

-- | <a>AsciiString</a> of pack.
--   
--   <pre>
--   string "string" == AsciiString (ByteString.Char8.pack "string")
--   </pre>
string :: String -> Datum

-- | Type-specialised pack.
ascii :: String -> Ascii

-- | Send to specified address using 'C.sendAllTo.
sendTo :: Udp -> Packet -> SockAddr -> IO ()

-- | Recv variant to collect message source address.
recvFrom :: Udp -> IO (Packet, SockAddr)

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

-- | Decode an Osc <a>Message</a> from a lazy ByteString.
--   
--   <pre>
--   let b = ByteString.Lazy.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   decodeMessage b == Message "/g_free" [Int32 0]
--   </pre>
decodeMessage :: ByteString -> Message

-- | Decode an Osc <a>Bundle</a> from a lazy ByteString.
decodeBundle :: ByteString -> Bundle

-- | Decode an Osc packet from a lazy ByteString.
--   
--   <pre>
--   let b = ByteString.Lazy.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   decodePacket b == Packet_Message (Message "/g_free" [Int32 0])
--   </pre>
decodePacket :: ByteString -> Packet

-- | Get an Osc <a>Packet</a>.
get_packet :: Get Packet

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

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

-- | Encode an Osc <a>Message</a>, ie. <a>encodePacket</a> of
--   <a>Packet_Message</a>.
--   
--   <pre>
--   let m = [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   encodeMessage (Message "/g_free" [Int32 0]) == L.pack m
--   </pre>
encodeMessage :: Message -> ByteString

-- | Encode an Osc <a>Bundle</a>, ie. <a>encodePacket</a> of
--   <a>Packet_Bundle</a>.
--   
--   <pre>
--   let m = [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   let b = [35,98,117,110,100,108,101,0,0,0,0,0,0,0,0,1,0,0,0,16] ++ m
--   encodeBundle (Bundle immediately [Message "/g_free" [Int32 0]]) == L.pack b
--   </pre>
encodeBundle :: Bundle -> ByteString

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

-- | Encode an Osc <a>Packet</a> to a strict <a>ByteString</a>.
encodePacket_strict :: Packet -> ByteString

-- | Get the system time, epoch start of 1970 UTC, leap-seconds ignored.
--   getSystemTime is typically much faster than getCurrentTime, however it
--   is not available in Hugs.
getSystemTimeAsNtpReal :: IO NtpReal

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

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

-- | Type-specialised unpack.
ascii_to_string :: Ascii -> String

-- | Type-specialised pack.
blob_pack :: [Word8] -> Blob

-- | Type-specialised unpack.
blob_unpack :: Blob -> [Word8]

-- | Type-specialised unpack.
blob_unpack_int :: Blob -> [Int]
midi_pack :: [Word8] -> MidiData

-- | Type-specialised unpack.
midi_unpack_int :: MidiData -> [Int]

-- | List of required data types (tag, name).
osc_types_required :: [(DatumType, String)]

-- | List of optional data types (tag,name).
osc_types_optional :: [(DatumType, String)]

-- | List of all data types (tag,name).
osc_types :: [(DatumType, String)]

-- | Lookup name of type.
osc_type_name :: DatumType -> Maybe String

-- | Erroring variant.
osc_type_name_err :: DatumType -> String

-- | Single character identifier of an Osc datum.
datum_tag :: Datum -> DatumType

-- | Type and name of <a>Datum</a>.
datum_type_name :: Datum -> (DatumType, String)

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

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

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

-- | <a>Blob</a> of <a>blob_pack</a>.
blob :: [Word8] -> Datum

-- | Message argument types are given by a signature.
--   
--   <pre>
--   signatureFor [Int32 1,Float 1,string "1"] == ",ifs"
--   </pre>
signatureFor :: [Datum] -> String

-- | The descriptor is an Ascii encoded signature.
--   
--   <pre>
--   descriptor [Int32 1,Float 1,string "1"] == ascii ",ifs"
--   </pre>
descriptor :: [Datum] -> Ascii

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

-- | <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
messageSignature :: Message -> String
messageDescriptor :: Message -> Ascii

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

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

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

-- | Constant indicating a bundle to be executed immediately. It has the
--   Ntp64 representation of <tt>1</tt>.
--   
--   <pre>
--   ntpr_to_ntpi immediately == 1
--   </pre>
immediately :: Time

-- | 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

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

-- | 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

-- | 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

-- | Convert an NtpReal timestamp to an Ntp64 timestamp.
--   
--   <pre>
--   ntpr_to_ntpi 0 == 0
--   fmap ntpr_to_ntpi time
--   </pre>
ntpr_to_ntpi :: NtpReal -> Ntp64

-- | Convert an <a>Ntp64</a> timestamp to a real-valued Ntp timestamp.
--   
--   <pre>
--   ntpi_to_ntpr 0 == 0.0
--   </pre>
ntpi_to_ntpr :: Ntp64 -> NtpReal

-- | Difference (in seconds) between <i>Ntp</i> and <i>Posix</i> epochs.
--   
--   <pre>
--   ntp_posix_epoch_diff / (24 * 60 * 60) == 25567
--   25567 `div` 365 == 70
--   </pre>
ntp_posix_epoch_diff :: Num n => n

-- | Convert a PosixReal timestamp to an Ntp64 timestamp.
posix_to_ntpi :: PosixReal -> Ntp64

-- | Convert <tt>Unix/Posix</tt> to <tt>Ntp</tt>.
posix_to_ntpr :: Num n => n -> n

-- | Convert <tt>Ntp</tt> to <tt>Unix/Posix</tt>.
ntpr_to_posix :: Num n => n -> n

-- | Convert <a>Ntp64</a> to <tt>Unix/Posix</tt>.
ntpi_to_posix :: Ntp64 -> PosixReal

-- | Convert <tt>Time</tt> to <a>POSIXTime</a>.
ntpr_to_posixtime :: NtpReal -> POSIXTime

-- | Convert <a>POSIXTime</a> to <tt>Time</tt>.
posixtime_to_ntpr :: POSIXTime -> NtpReal

-- | The time at 1970-01-01:00:00:00 which is the Unix/Posix epoch.
posix_epoch :: UTCTime

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

-- | utc_to_posix of Clock.getCurrentTime.
getCurrentTimeAsPosix :: IO PosixReal

-- | realToFrac of Clock.Posix.getPOSIXTime
--   
--   <pre>
--   get_ct = getCurrentTimeAsPosix
--   get_pt = getPosixTimeAsPosix
--   (ct,pt) &lt;- get_ct &gt;&gt;= \t0 -&gt; get_pt &gt;&gt;= \t1 -&gt; return (t0,t1)
--   print (pt - ct,pt - ct &lt; 1e-5)
--   </pre>
getPosixTimeAsPosix :: IO PosixReal

-- | Read current real-valued <tt>Ntp</tt> timestamp.
currentTime :: IO NtpReal

-- | System time with fractional part in microseconds (us) instead of
--   nanoseconds (ns).
getSystemTimeInMicroseconds :: IO (Int64, Word32)

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

-- | Pause current thread until the given time, see
--   <a>pauseThreadLimit</a>.
pauseThreadUntilTime :: RealFrac n => n -> IO ()

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

-- | Sleep current thread until the given time. Divides long sleeps into
--   parts smaller than <a>pauseThreadLimit</a>.
sleepThreadUntilTime :: RealFrac n => n -> IO ()
wait :: MonadIO m => Double -> m ()
pauseThread :: (MonadIO m, RealFrac n) => n -> m ()
sleepThread :: (RealFrac n, MonadIO m) => n -> m ()
pauseThreadUntil :: (MonadIO m, RealFrac n) => n -> m ()
sleepThreadUntil :: (RealFrac n, MonadIO m) => n -> m ()

-- | 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

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

-- | Type restricted synonym for <tt>sendOsc</tt>.
sendMessage :: SendOsc m => Message -> m ()

-- | Type restricted synonym for <tt>sendOsc</tt>.
sendBundle :: SendOsc m => Bundle -> m ()

-- | Variant of <a>recvPacket</a> that runs <tt>packet_to_bundle</tt>.
recvBundle :: RecvOsc m => m Bundle

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

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

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

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

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

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

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

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

-- | Variant of <a>waitReply</a> that runs <tt>messageDatum</tt>.
waitDatum :: RecvOsc m => Address_Pattern -> m [Datum]

-- | <a>void</a> of <a>withTransport</a>.
withTransport_ :: Transport t => IO t -> Connection t r -> IO ()

-- | Erroring variant.
recvMessage_err :: RecvOsc m => m Message

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

-- | Send data over Udp using <a>send</a>.
udp_send_data :: Udp -> ByteString -> IO ()

-- | Send data over Udp using <a>sendAll</a>.
udp_sendAll_data :: Udp -> ByteString -> IO ()

-- | Send packet over Udp.
udp_send_packet :: Udp -> Packet -> IO ()

-- | Receive packet over Udp.
udp_recv_packet :: Udp -> IO Packet

-- | Close Udp.
udp_close :: Udp -> IO ()

-- | Bracket Udp communication.
with_udp :: IO Udp -> (Udp -> IO t) -> IO t

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

-- | Set option, ie. <a>Broadcast</a> or <a>RecvTimeOut</a>.
set_udp_opt :: SocketOption -> Int -> Udp -> IO ()

-- | Get option.
get_udp_opt :: SocketOption -> Udp -> IO Int

-- | Make a <a>Udp</a> connection.
openUdp :: String -> Int -> IO Udp

-- | Trivial <a>Udp</a> server socket.
--   
--   <pre>
--   import Control.Concurrent {- base -}
--   </pre>
--   
--   <pre>
--   let u0 = udpServer "127.0.0.1" 57300
--   t0 &lt;- forkIO (Fd.withTransport u0 (\fd -&gt; forever (Fd.recvMessage fd &gt;&gt;= print &gt;&gt; print "Received message, continuing")))
--   killThread t0
--   </pre>
--   
--   <pre>
--   let u1 = openUdp "127.0.0.1" 57300
--   Fd.withTransport u1 (\fd -&gt; Fd.sendMessage fd (Packet.message "/n" []))
--   </pre>
udpServer :: String -> Int -> IO Udp

-- | Variant of <a>udpServer</a> that doesn't require the host address.
udp_server :: Int -> IO Udp

-- | Send data over Tcp.
tcp_send_data :: Tcp -> ByteString -> IO ()

-- | Send packet over Tcp.
tcp_send_packet :: Tcp -> Packet -> IO ()

-- | Receive packet over Tcp.
tcp_recv_packet :: Tcp -> IO Packet

-- | Close Tcp.
tcp_close :: Tcp -> IO ()

-- | Bracket UDP communication.
with_tcp :: IO Tcp -> (Tcp -> IO t) -> IO t

-- | Create and initialise Tcp socket.
tcp_socket :: (Socket -> SockAddr -> IO ()) -> Maybe String -> Int -> IO Socket

-- | Convert <a>Socket</a> to <a>Tcp</a>.
socket_to_tcp :: Socket -> IO Tcp

-- | Create and initialise Tcp.
tcp_handle :: (Socket -> SockAddr -> IO ()) -> String -> Int -> IO Tcp

-- | Make a <a>Tcp</a> connection.
--   
--   <pre>
--   import Sound.Osc.Datum {- hosc -}
--   import Sound.Osc.Time {- hosc -}
--   let t = openTcp "127.0.0.1" 57110
--   let m1 = Packet.message "/dumpOsc" [Int32 1]
--   let m2 = Packet.message "/g_new" [Int32 1]
--   Fd.withTransport t (\fd -&gt; let f = Fd.sendMessage fd in f m1 &gt;&gt; pauseThread 0.25 &gt;&gt; f m2)
--   </pre>
openTcp :: String -> Int -> IO Tcp

-- | <a>accept</a> connection at <i>s</i> and run <i>f</i>.
tcp_server_f :: Socket -> (Tcp -> IO ()) -> IO ()

-- | A trivial <a>Tcp</a> <i>Osc</i> server.
tcp_server :: Int -> (Tcp -> IO ()) -> IO ()
