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


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


-- | 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>
--   &gt;&gt;&gt; encode_int16 0x0102 == ByteString.Lazy.pack [0x01,0x02]
--   True
--   </pre>
encode_int16 :: Int16 -> ByteString

-- | Little-endian.
--   
--   <pre>
--   &gt;&gt;&gt; encode_int16_le 0x0102 == ByteString.Lazy.pack [0x02,0x01]
--   True
--   </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>
--   &gt;&gt;&gt; encode_word16 0x0102 == ByteString.Lazy.pack [0x01,0x02]
--   True
--   </pre>
encode_word16 :: Word16 -> ByteString

-- | Little-endian.
--   
--   <pre>
--   &gt;&gt;&gt; encode_word16_le 0x0102 == ByteString.Lazy.pack [0x02,0x01]
--   True
--   </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>
--   &gt;&gt;&gt; encode_u16 0x0102 == ByteString.Lazy.pack [1,2]
--   True
--   </pre>
encode_u16 :: Int -> ByteString

-- | Little-endian.
--   
--   <pre>
--   &gt;&gt;&gt; encode_u16_le 0x0102 == ByteString.Lazy.pack [2,1]
--   True
--   </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>
--   &gt;&gt;&gt; ByteString.Lazy.unpack (encode_u32 0x01020304)
--   [1,2,3,4]
--   </pre>
encode_u32 :: Int -> ByteString

-- | Little-endian.
--   
--   <pre>
--   &gt;&gt;&gt; ByteString.Lazy.unpack (encode_u32_le 0x01020304)
--   [4,3,2,1]
--   </pre>
encode_u32_le :: Int -> ByteString

-- | Encode a 32-bit IEEE floating point number.
--   
--   <pre>
--   &gt;&gt;&gt; ByteString.Lazy.unpack (encode_f32 3.141)
--   [64,73,6,37]
--   </pre>
encode_f32 :: Float -> ByteString

-- | Little-endian variant of <a>encode_f32</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ByteString.Lazy.unpack (encode_f32_le 3.141)
--   [37,6,73,64]
--   </pre>
encode_f32_le :: Float -> ByteString

-- | Encode a 64-bit IEEE floating point number.
--   
--   <pre>
--   &gt;&gt;&gt; ByteString.Lazy.unpack (encode_f64 3.141)
--   [64,9,32,196,155,165,227,84]
--   </pre>
encode_f64 :: Double -> ByteString

-- | Little-endian variant of <a>encode_f64</a>.
--   
--   <pre>
--   &gt;&gt;&gt; ByteString.Lazy.unpack (encode_f64_le 3.141)
--   [84,227,165,155,196,32,9,64]
--   </pre>
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>
--   &gt;&gt;&gt; decode_i32 (ByteString.Lazy.pack [0x00,0x00,0x03,0xe7]) == 0x03e7
--   True
--   </pre>
decode_i32 :: ByteString -> Int

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

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

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

-- | Decode a 32-bit IEEE floating point number.
--   
--   <pre>
--   &gt;&gt;&gt; decode_f32 (ByteString.Lazy.pack [64,73,6,37])
--   3.141
--   </pre>
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>
--   &gt;&gt;&gt; ByteString.Char8.length bundleHeader_strict
--   8
--   </pre>
bundleHeader_strict :: ByteString

-- | Bundle header as a lazy ByteString.
--   
--   <pre>
--   &gt;&gt;&gt; ByteString.Lazy.length bundleHeader
--   8
--   </pre>
bundleHeader :: ByteString

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

-- | Is machine little endian?
isLittleEndian :: Bool

-- | Byte-swap byte string in four-byte segments.
byteStringSwap32BitWords :: ByteString -> ByteString

-- | If target is little-endian, swap bytes to be in network order, else
--   identity.
byteString32BitNetworkOrder :: ByteString -> ByteString


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

-- | The IEEE byte representation of a float.
--   
--   <pre>
--   &gt;&gt;&gt; f32_w32 pi
--   1078530011
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; f32_w32 (-7913907.5)
--   3404825447
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; 23 ^ 7
--   3404825447
--   </pre>
f32_w32 :: Float -> Word32

-- | Inverse of <a>f32_w32</a>.
--   
--   <pre>
--   &gt;&gt;&gt; w32_f32 1078530011
--   3.1415927
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; w32_f32 (23 ^ 7)
--   -7913907.5
--   </pre>
w32_f32 :: Word32 -> Float

-- | The IEEE byte representation of a double.
--   
--   <pre>
--   &gt;&gt;&gt; f64_w64 pi
--   4614256656552045848
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; f64_w64 1.6822072834e-314
--   3404825447
--   </pre>
f64_w64 :: Double -> Word64

-- | Inverse of <a>f64_w64</a>.
--   
--   <pre>
--   &gt;&gt;&gt; w64_f64 4614256656552045848
--   3.141592653589793
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; w64_f64 (23 ^ 7)
--   1.6822072834e-314
--   </pre>
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


-- | 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>Int32</a>
--   length prefix.
type Blob = ByteString

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

-- | Type-specialised pack.
blob_pack_int :: [Int] -> 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 pack.
midi_pack_int :: [Int] -> 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>
--   &gt;&gt;&gt; let d = [Int32 5,Int64 5,Float 5.5,Double 5.5]
--   
--   &gt;&gt;&gt; map datum_integral d == [Just (5::Int),Just 5,Nothing,Nothing]
--   True
--   </pre>
datum_integral :: Integral i => Datum -> Maybe i

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

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

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

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

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

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

-- | Four-tuple variant of <a>Midi</a> <a>.</a> <a>MidiData</a>.
--   
--   <pre>
--   &gt;&gt;&gt; midi (0,0,0,0) == Midi (MidiData 0 0 0 0)
--   True
--   </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>
--   &gt;&gt;&gt; signatureFor [Int32 1,Float 1,string "1"]
--   ",ifs"
--   </pre>
signatureFor :: [Datum] -> String

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

-- | Descriptor tags are <tt>comma</tt> prefixed.
descriptor_tags :: Ascii -> Ascii
instance GHC.Classes.Eq Sound.Osc.Datum.Datum
instance GHC.Classes.Eq Sound.Osc.Datum.MidiData
instance GHC.Classes.Ord Sound.Osc.Datum.Datum
instance GHC.Classes.Ord Sound.Osc.Datum.MidiData
instance GHC.Internal.Read.Read Sound.Osc.Datum.Datum
instance GHC.Internal.Read.Read Sound.Osc.Datum.MidiData
instance GHC.Internal.Show.Show Sound.Osc.Datum.Datum
instance GHC.Internal.Show.Show Sound.Osc.Datum.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. The
--   type parameter specifies the element type. Ordinarily this is Message,
--   which does not allow recursion.
data BundleOf t
Bundle :: !Time -> ![t] -> BundleOf t
[bundleTime] :: BundleOf t -> !Time
[bundleMessages] :: BundleOf t -> ![t]
type Bundle = BundleOf Message

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

-- | An Osc <a>Packet</a> is either a <a>Message</a> or a 'Bundle t'.
data PacketOf t
Packet_Message :: !Message -> PacketOf t
[packetMessage] :: PacketOf t -> !Message
Packet_Bundle :: !BundleOf t -> PacketOf t
[packetBundle] :: PacketOf t -> !BundleOf t
type Packet = PacketOf Message

-- | <a>Packet_Bundle</a> of <a>bundle</a>.
p_bundle :: Time -> [t] -> PacketOf t

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

-- | Constant indicating a bundle to be executed immediately. It has the
--   Ntp64 representation of <tt>1</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; immediately == (1 / (2 ^ 32))
--   True
--   </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 :: PacketOf t -> Time

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

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

-- | 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 :: PacketOf Message -> Maybe Message

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

-- | Variant of <a>either</a> for <a>Packet</a>.
at_packet :: (Message -> a) -> (BundleOf t -> a) -> PacketOf t -> 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 'Bundle Message' have the specified
--   <a>Address_Pattern</a>.
bundle_has_address :: Address_Pattern -> BundleOf Message -> 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 -> PacketOf Message -> Bool
instance GHC.Classes.Eq t => GHC.Classes.Eq (Sound.Osc.Packet.BundleOf t)
instance GHC.Classes.Eq Sound.Osc.Packet.Message
instance GHC.Classes.Eq t => GHC.Classes.Eq (Sound.Osc.Packet.PacketOf t)
instance GHC.Classes.Eq t => GHC.Classes.Ord (Sound.Osc.Packet.BundleOf t)
instance GHC.Classes.Ord Sound.Osc.Packet.Message
instance GHC.Internal.Read.Read t => GHC.Internal.Read.Read (Sound.Osc.Packet.BundleOf t)
instance GHC.Internal.Read.Read Sound.Osc.Packet.Message
instance GHC.Internal.Read.Read t => GHC.Internal.Read.Read (Sound.Osc.Packet.PacketOf t)
instance GHC.Internal.Show.Show t => GHC.Internal.Show.Show (Sound.Osc.Packet.BundleOf t)
instance GHC.Internal.Show.Show Sound.Osc.Packet.Message
instance GHC.Internal.Show.Show t => GHC.Internal.Show.Show (Sound.Osc.Packet.PacketOf t)


-- | 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>
--   &gt;&gt;&gt; ntpr_to_ntpi 0
--   0
--   </pre>
--   
--   <pre>
--   fmap ntpr_to_ntpi time
--   </pre>
ntpr_to_ntpi :: NtpReal -> Ntp64

-- | Convert an <a>Ntp64</a> timestamp to a real-valued Ntp timestamp.
--   
--   <pre>
--   &gt;&gt;&gt; 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>
--   &gt;&gt;&gt; ntp_posix_epoch_diff / (24 * 60 * 60)
--   25567.0
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; 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>
--   &gt;&gt;&gt; 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>
--   &gt;&gt;&gt; showBytes [0, 15, 16, 144, 255]
--   "000f1090ff"
--   </pre>
showBytes :: [Int] -> String

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

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

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

-- | Printer for Bundle
--   
--   <pre>
--   &gt;&gt;&gt; let aBundle = Bundle 1 [Message "/c_set" [Int32 1, Float 2.3, Int64 4, Double 5.6], Message "/memset" [string "addr", blob [7, 8]]]
--   
--   &gt;&gt;&gt; showBundle (Just 4) aBundle
--   "#bundle 4294967296 2 /c_set ,ifhd 1 2.3 4 5.6 /memset ,sb addr 0708"
--   </pre>
showBundle :: FpPrecision -> BundleOf Message -> String

-- | Printer for Packet.
showPacket :: FpPrecision -> PacketOf Message -> 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 (BundleOf Message)

-- | Packet parser.
packetP :: P (PacketOf Message)

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

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

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

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

-- | Run packet parser.
--   
--   <pre>
--   &gt;&gt;&gt; let 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]]])
--   
--   &gt;&gt;&gt; parsePacket (showPacket (Just 4) aPacket) == aPacket
--   True
--   </pre>
parsePacket :: String -> PacketOf Message


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

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

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

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

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

-- | Encode an Osc <a>Packet</a> to a strict <a>ByteString</a>.
encodePacket_strict :: PacketOf Message -> 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>
--   &gt;&gt;&gt; encode_datum (blob [1, 2, 3, 4]) == B.pack [0, 0, 0, 4, 1, 2, 3, 4]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Float 1) == B.pack [63, 128, 0, 0]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Float 2) == B.pack [64, 0, 0, 0]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Float 3) == B.pack [64, 64, 0, 0]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Float 4) == B.pack [64, 128, 0, 0]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Float 5) == B.pack [64, 160, 0, 0]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Int32 65536) == B.pack [0, 1, 0, 0]
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; encode_datum (Int32 (-65536)) == B.pack [255, 255, 0, 0]
--   True
--   </pre>
encode_datum :: Datum -> ByteString

-- | Encode Osc <a>Message</a>.
--   
--   <pre>
--   &gt;&gt;&gt; blob_unpack (encodeMessage (Message "/x" []))
--   [47,120,0,0,44,0,0,0]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; blob_unpack (encodeMessage (Message "/y" [float 3.141]))
--   [47,121,0,0,44,102,0,0,64,73,6,37]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let m = Message "/n_set" [int32 (-1), string "freq", float 440, string "amp", float 0.1]
--   
--   &gt;&gt;&gt; let e = blob_unpack (encodeMessage m)
--   
--   &gt;&gt;&gt; length e
--   40
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; take 20 e
--   [47,110,95,115,101,116,0,0,44,105,115,102,115,102,0,0,255,255,255,255]
--   </pre>
encodeMessage :: Message -> ByteString

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

-- | Encode Osc <a>Bundle</a>.
--   
--   <pre>
--   &gt;&gt;&gt; blob_unpack (encodeBundle (Bundle immediately [Message "/x" []]))
--   [35,98,117,110,100,108,101,0,0,0,0,0,0,0,0,1,0,0,0,8,47,120,0,0,44,0,0,0]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let m = Message "/n_set" [int32 (-1), string "freq", float 440, string "amp", float 0.1]
--   
--   &gt;&gt;&gt; let b = Bundle 0.0 [m]
--   
--   &gt;&gt;&gt; let e = blob_unpack (encodeBundle b)
--   
--   &gt;&gt;&gt; length e
--   60
--   </pre>
--   
--   <pre>
--   &gt; take 20 e
--   </pre>
--   
--   <ul>
--   <li><i>35,98,117,110,100,108,101,0,0,0,0,0,0,0,0,0,0,0,0,40</i></li>
--   </ul>
encodeBundle :: BundleOf Message -> ByteString

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


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

-- | Get an Osc <a>Packet</a>.
get_packet :: Get (PacketOf Message)

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

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

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

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

-- | Either decode Osc message or return an error message. Prevents
--   application halt for non-valid message<i>bundle</i>packet arrives.
--   
--   <pre>
--   &gt;&gt;&gt; let b = ByteString.Lazy.pack [1,2,3,2,1]
--   
--   &gt;&gt;&gt; decodePacketOr b
--   Left "not enough bytes"
--   </pre>
decodeMessageOr :: ByteString -> Either String Message
decodeBundleOr :: ByteString -> Either String Bundle
decodePacketOr :: ByteString -> Either String 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 -> BundleOf Message

-- | Decode an Osc <a>Packet</a>.
--   
--   <pre>
--   &gt;&gt;&gt; let b = B.pack [47,103,95,102,114,101,101,0,44,105,0,0,0,0,0,0]
--   
--   &gt;&gt;&gt; decodePacket b == Packet_Message (Message "/g_free" [Int32 0])
--   True
--   </pre>
decodePacket :: ByteString -> PacketOf Message


-- | 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 -> PacketOf Message -> IO ()

-- | Receive and decode an Osc packet.
recvPacket :: Transport t => t -> IO (PacketOf Message)

-- | Receive and either decode an Osc packet.
recvPacketOr :: Transport t => t -> IO (Either String 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 -> BundleOf Message -> IO ()

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

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

-- | Erroring variant.
recvMessage_err :: Transport t => t -> IO 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 -> (PacketOf Message -> Bool) -> IO (PacketOf Message)

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

-- | <a>waitUntil</a> <a>packet_is_immediate</a>.
waitImmediate :: Transport t => t -> IO (PacketOf Message)

-- | <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 (PacketOf Message)

-- | 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 :: Type -> Type)

-- | Encode and send an Osc packet.
sendPacket :: SendOsc m => PacketOf Message -> m ()

-- | Receiver monad.
class Monad m => RecvOsc (m :: Type -> Type)

-- | Receive and decode an Osc packet.
recvPacket :: RecvOsc m => m (PacketOf Message)

-- | <a>DuplexOsc</a> is the union of <a>SendOsc</a> and <a>RecvOsc</a>.
class (SendOsc m, RecvOsc m) => DuplexOsc (m :: Type -> Type)

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

-- | 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 => BundleOf Message -> m ()

-- | Variant of <a>recvPacket</a> that runs <tt>packet_to_bundle</tt>.
recvBundle :: RecvOsc m => m (BundleOf Message)

-- | 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 => (PacketOf Message -> Bool) -> m (PacketOf Message)

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

-- | <a>waitUntil</a> <tt>packet_is_immediate</tt>.
waitImmediate :: RecvOsc m => m (PacketOf Message)

-- | <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 (PacketOf Message)

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


-- | 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 -> PacketOf Message -> IO ()

-- | Receive packet over Udp.
udp_recv_packet :: Udp -> IO (PacketOf Message)
udp_recv_packet_or :: Udp -> IO (Either String 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
--   </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 -> PacketOf Message -> SockAddr -> IO ()

-- | Recv variant to collect message source address.
recvFrom :: Udp -> IO (PacketOf Message, 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 -> PacketOf Message -> IO ()

-- | Receive packet over Tcp.
tcp_recv_packet :: Tcp -> IO (PacketOf Message)
tcp_recv_packet_or :: Tcp -> IO (Either String Packet)

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

-- | Bracket Tcp 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
--   import Sound.Osc.Time
--   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


-- | Osc over Udp/Tcp implementation.
module Sound.Osc.Transport.Fd.Socket

-- | Protocol, either Udp or Tcp
data OscProtocol
Udp :: OscProtocol
Tcp :: OscProtocol

-- | Hostname
type OscHostname = String

-- | Port number
type OscPort = Int

-- | Socket address
type OscSocketAddress = (OscProtocol, OscHostname, OscPort)

-- | Socket
data OscSocket
OscUdpSocket :: Udp -> OscSocket
OscTcpSocket :: Tcp -> OscSocket

-- | Open socket at address
openOscSocket :: OscSocketAddress -> IO OscSocket
instance GHC.Classes.Eq Sound.Osc.Transport.Fd.Socket.OscProtocol
instance GHC.Internal.Read.Read Sound.Osc.Transport.Fd.Socket.OscProtocol
instance GHC.Internal.Show.Show Sound.Osc.Transport.Fd.Socket.OscProtocol
instance Sound.Osc.Transport.Fd.Transport Sound.Osc.Transport.Fd.Socket.OscSocket


-- | 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 (PacketOf Message))


-- | 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>
--   &gt;&gt;&gt; let o = bundle immediately [message "/g_free" [Int32 0]]
--   
--   &gt;&gt;&gt; let e = encodeBundle o
--   
--   &gt;&gt;&gt; decodePacket e == Packet_Bundle o
--   True
--   </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
