-- 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 fromIntegral int_to_word8 :: Int -> Word8 -- | Type specialised fromIntegral int_to_word32 :: Int -> Word32 -- | Type specialised fromIntegral. int_to_word16 :: Int -> Word16 -- | Type specialised fromIntegral int_to_int8 :: Int -> Int8 -- | Type specialised fromIntegral int_to_int16 :: Int -> Int16 -- | Type specialised fromIntegral int_to_int32 :: Int -> Int32 -- | Type specialised fromIntegral int_to_int64 :: Int -> Int64 -- | Type specialised fromIntegral int8_to_int :: Int8 -> Int -- | Type specialised fromIntegral int16_to_int :: Int16 -> Int -- | Type specialised fromIntegral int32_to_int :: Int32 -> Int -- | Type specialised fromIntegral int64_to_int :: Int64 -> Int -- | Type specialised fromIntegral word8_to_int :: Word8 -> Int -- | Type specialised fromIntegral word16_to_int :: Word16 -> Int -- | Type specialised fromIntegral word32_to_int :: Word32 -> Int -- | Type specialised fromIntegral word16_to_word32 :: Word16 -> Word32 -- | Type specialised fromIntegral word32_to_word16 :: Word32 -> Word16 -- | Type specialised fromIntegral word32_to_int32 :: Word32 -> Int32 -- | Type specialised fromIntegral word32_to_int64 :: Word32 -> Int64 -- | Type specialised fromIntegral word64_to_int64 :: Word64 -> Int64 -- | Type specialised fromIntegral int64_to_int32 :: Int64 -> Int32 -- | Type specialised fromIntegral int64_to_word32 :: Int64 -> Word32 -- | Type specialised fromIntegral word64_to_double :: Word64 -> Double -- | Type-specialised toEnum of fromIntegral word8_to_enum :: Enum e => Word8 -> e -- | Type-specialised toEnum of fromIntegral word16_to_enum :: Enum e => Word16 -> e -- | Type-specialised fromIntegral of fromEnum. enum_to_word8 :: Enum e => e -> Word8 -- | Type-specialised fromIntegral of fromEnum. enum_to_word16 :: Enum e => e -> Word16 -- | Type-specialised word8_to_enum. word8_to_char :: Word8 -> Char -- | Type-specialised enum_to_word8. 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 f32_w32. w32_f32 :: Word32 -> Float -- | The IEEE byte representation of a double. f64_w64 :: Double -> Word64 -- | Inverse of f64_i64. w64_f64 :: Word64 -> Double -- | Transform a haskell string into a C string (a null suffixed byte -- string). str_cstr :: String -> [Word8] -- | Inverse of str_cstr. cstr_str :: [Word8] -> String -- | Transform a haskell string to a pascal string (a length prefixed byte -- string). str_pstr :: String -> [Word8] -- | Inverse of str_pstr. pstr_str :: [Word8] -> String -- | Byte-level coding utility functions. Plain forms are big-endian, -- little-endian forms have _le suffix. module Sound.Osc.Coding.Byte -- | Type specialised encode (big-endian). encode_int8 :: Int8 -> ByteString -- | Type specialised encode (big-endian). -- --
-- encode_int16 0x0102 == L.pack [0x01,0x02] --encode_int16 :: Int16 -> ByteString -- | Little-endian. -- --
-- encode_int16_le 0x0102 == L.pack [0x02,0x01] --encode_int16_le :: Int16 -> ByteString -- | Encode a signed 64-bit integer (big-endian). encode_int64 :: Int64 -> ByteString -- | Type specialised encode (big-endian). encode_word8 :: Word8 -> ByteString -- | Type specialised encode (big-endian). -- --
-- encode_word16 0x0102 == L.pack [0x01,0x02] --encode_word16 :: Word16 -> ByteString -- | Little-endian. -- --
-- encode_word16_le 0x0102 == L.pack [0x02,0x01] --encode_word16_le :: Word16 -> ByteString -- | Type specialised encode. encode_word32 :: Word32 -> ByteString -- | Little-endian variant of encode_word32. 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. -- --
-- encode_u16 0x0102 == L.pack [1,2] --encode_u16 :: Int -> ByteString -- | Little-endian. -- --
-- encode_u16_le 0x0102 == L.pack [2,1] --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. -- --
-- encode_u32 0x01020304 == L.pack [1,2,3,4] --encode_u32 :: Int -> ByteString -- | Little-endian. -- --
-- encode_u32_le 0x01020304 == L.pack [4,3,2,1] --encode_u32_le :: Int -> ByteString -- | Encode a 32-bit IEEE floating point number. -- --
-- encode_f32 1.0 == L.pack [63, 128, 0, 0] --encode_f32 :: Float -> ByteString -- | Little-endian variant of encode_f32. encode_f32_le :: Float -> ByteString -- | Encode a 64-bit IEEE floating point number. encode_f64 :: Double -> ByteString -- | Little-endian variant of encode_f64. 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 decode. decode_word16 :: ByteString -> Word16 -- | Little-endian variant of decode_word16. decode_word16_le :: ByteString -> Word16 -- | Type specialised decode. decode_int16 :: ByteString -> Int16 -- | Type specialised decode. decode_word32 :: ByteString -> Word32 -- | Little-endian variant of decode_word32. decode_word32_le :: ByteString -> Word32 -- | Type specialised decode. decode_int64 :: ByteString -> Int64 -- | Type specialised decode. 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 decode_u16. decode_u16_le :: ByteString -> Int -- | Decode a signed 16-bit integer. decode_i16 :: ByteString -> Int -- | Little-endian variant of decode_i16. decode_i16_le :: ByteString -> Int -- | Decode a signed 32-bit integer. -- --
-- decode_i32 (L.pack [0x00,0x00,0x03,0xe7]) == 0x03e7 --decode_i32 :: ByteString -> Int -- | Little-endian variant of decode_i32. -- --
-- decode_i32_le (L.pack [0xe7,0x03,0x00,0x00]) == 0x03e7 --decode_i32_le :: ByteString -> Int -- | Decode an unsigned 32-bit integer. -- --
-- decode_u32 (L.pack [1,2,3,4]) == 0x01020304 --decode_u32 :: ByteString -> Int -- | Little-endian variant of decode_u32. -- --
-- decode_u32_le (L.pack [1,2,3,4]) == 0x04030201 --decode_u32_le :: ByteString -> Int -- | Decode a 32-bit IEEE floating point number. decode_f32 :: ByteString -> Float -- | Little-endian variant of decode_f32. decode_f32_le :: ByteString -> Float -- | Decode a 64-bit IEEE floating point number. decode_f64 :: ByteString -> Double -- | Decode an Ascii string, inverse of encode_ascii. decode_ascii :: ByteString -> ByteString -- | Read n bytes from h and run f. read_decode :: (ByteString -> t) -> Int -> Handle -> IO t -- | Type-specialised reader for decode. read_word32 :: Handle -> IO Word32 -- | read_decode of decode_word32_le. read_word32_le :: Handle -> IO Word32 -- | hPut of encode_word32. write_word32 :: Handle -> Word32 -> IO () -- | hPut of encode_word32_le. write_word32_le :: Handle -> Word32 -> IO () -- | decode_i8 of hGet. read_i8 :: Handle -> IO Int -- | decode_i16 of hGet. read_i16 :: Handle -> IO Int -- | decode_i32 of hGet. read_i32 :: Handle -> IO Int -- | decode_i32_le of hGet. read_i32_le :: Handle -> IO Int -- | decode_u32 of hGet. read_u32 :: Handle -> IO Int -- | decode_u32_le of hGet. read_u32_le :: Handle -> IO Int -- | hPut of encode_u32. write_u32 :: Handle -> Int -> IO () -- | hPut of encode_u32_le. write_u32_le :: Handle -> Int -> IO () -- | decode_f32 of hGet. read_f32 :: Handle -> IO Float -- | decode_f32_le of hGet. read_f32_le :: Handle -> IO Float -- | Read u8 length prefixed Ascii string (pascal string). read_pstr :: Handle -> IO ByteString -- | Bundle header as a (strict) ByteString. -- --
-- S.C.length bundleHeader_strict == 8 --bundleHeader_strict :: ByteString -- | Bundle header as a lazy ByteString. -- --
-- L.length bundleHeader == 8 --bundleHeader :: ByteString -- | The number of bytes required to align an Osc value to the next 4-byte -- boundary. -- --
-- 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] --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 Word8 arrays, these are stored with an Datum -- 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 Datum. datum_type_name :: Datum -> (DatumType, String) -- | Datum as Integral if Int32 or Int64. -- --
-- let d = [Int32 5,Int64 5,Float 5.5,Double 5.5] -- map datum_integral d == [Just (5::Int),Just 5,Nothing,Nothing] --datum_integral :: Integral i => Datum -> Maybe i -- | Datum as Floating if Int32, Int64, Float, Double or -- TimeStamp. -- --
-- let d = [Int32 5,Int64 5,Float 5,Double 5,TimeStamp 5] -- mapMaybe datum_floating d == replicate 5 (5::Double) --datum_floating :: Floating n => Datum -> Maybe n -- | Type generalised Datum. -- --
-- int32 (1::Int32) == int32 (1::Integer) -- d_int32 (int32 (maxBound::Int32)) == maxBound -- int32 (((2::Int) ^ (64::Int))::Int) == Int32 0 --int32 :: Integral n => n -> Datum -- | Type generalised Int64. -- --
-- int64 (1::Int32) == int64 (1::Integer) -- d_int64 (int64 (maxBound::Int64)) == maxBound --int64 :: Integral n => n -> Datum -- | Type generalised Float. -- --
-- float (1::Int) == float (1::Double) -- floatRange (undefined::Float) == (-125,128) -- isInfinite (d_float (float (encodeFloat 1 256 :: Double))) == True --float :: Real n => n -> Datum -- | Type generalised Double. -- --
-- double (1::Int) == double (1::Double) -- double (encodeFloat 1 256 :: Double) == Double 1.157920892373162e77 --double :: Real n => n -> Datum -- | AsciiString of pack. -- --
-- string "string" == AsciiString (ByteString.Char8.pack "string") --string :: String -> Datum -- | Four-tuple variant of Midi . MidiData. -- --
-- midi (0,0,0,0) == Midi (MidiData 0 0 0 0) --midi :: (Word8, Word8, Word8, Word8) -> Datum -- | Blob of blob_pack. blob :: [Word8] -> Datum -- | Message argument types are given by a signature. -- --
-- signatureFor [Int32 1,Float 1,string "1"] == ",ifs" --signatureFor :: [Datum] -> String -- | The descriptor is an Ascii encoded signature. -- --
-- descriptor [Int32 1,Float 1,string "1"] == ascii ",ifs" --descriptor :: [Datum] -> Ascii -- | Descriptor tags are comma 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 OverloadedStrings. type Address_Pattern = String -- | An Osc message, an Address_Pattern and a sequence of -- Datum. data Message Message :: !Address_Pattern -> ![Datum] -> Message [messageAddress] :: Message -> !Address_Pattern [messageDatum] :: Message -> ![Datum] -- | Message constructor. It is an error if the -- Address_Pattern doesn't conform to the Osc specification. message :: Address_Pattern -> [Datum] -> Message messageSignature :: Message -> String messageDescriptor :: Message -> Ascii -- | An Osc bundle, a Time and a sequence of Messages. Do not -- allow recursion, all contents must be messages. data Bundle Bundle :: !Time -> ![Message] -> Bundle [bundleTime] :: Bundle -> !Time [bundleMessages] :: Bundle -> ![Message] -- | Bundle constructor. It is an error if the Message -- list is empty. bundle :: Time -> [Message] -> Bundle -- | An Osc Packet is either a Message or a Bundle. data Packet Packet_Message :: !Message -> Packet [packetMessage] :: Packet -> !Message Packet_Bundle :: !Bundle -> Packet [packetBundle] :: Packet -> !Bundle -- | Packet_Bundle of bundle. p_bundle :: Time -> [Message] -> Packet -- | Packet_Message of message. p_message :: Address_Pattern -> [Datum] -> Packet -- | Constant indicating a bundle to be executed immediately. It has the -- Ntp64 representation of 1. -- --
-- ntpr_to_ntpi immediately == 1 --immediately :: Time -- | The Time of Packet, if the Packet is a -- Message this is immediately. packetTime :: Packet -> Time -- | Retrieve the set of Messages from a Packet. packetMessages :: Packet -> [Message] -- | If Packet is a Message add immediately timestamp, -- else id. packet_to_bundle :: Packet -> Bundle -- | If Packet is a Message or a Bundle with an -- immediate time tag and with one element, return the -- Message, else Nothing. packet_to_message :: Packet -> Maybe Message -- | Is Packet immediate, ie. a Bundle with timestamp -- immediately, or a plain Message. packet_is_immediate :: Packet -> Bool -- | Variant of either for Packet. at_packet :: (Message -> a) -> (Bundle -> a) -> Packet -> a -- | Does Message have the specified Address_Pattern. message_has_address :: Address_Pattern -> Message -> Bool -- | Do any of the Messages at Bundle have the specified -- Address_Pattern. bundle_has_address :: Address_Pattern -> Bundle -> Bool -- | Does Packet have the specified Address_Pattern, ie. -- message_has_address or bundle_has_address. 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 Ntp -- values, http://ntp.org/. 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 -- | Ntp time in real-valued (fractional) form. type NtpReal = Double -- | Unix/Posix 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. -- --
-- ntpr_to_ntpi 0 == 0 -- fmap ntpr_to_ntpi time --ntpr_to_ntpi :: NtpReal -> Ntp64 -- | Convert an Ntp64 timestamp to a real-valued Ntp timestamp. -- --
-- ntpi_to_ntpr 0 == 0.0 --ntpi_to_ntpr :: Ntp64 -> NtpReal -- | Difference (in seconds) between Ntp and Posix epochs. -- --
-- ntp_posix_epoch_diff / (24 * 60 * 60) == 25567 -- 25567 `div` 365 == 70 --ntp_posix_epoch_diff :: Num n => n -- | Convert a PosixReal timestamp to an Ntp64 timestamp. posix_to_ntpi :: PosixReal -> Ntp64 -- | Convert Unix/Posix to Ntp. posix_to_ntpr :: Num n => n -> n -- | Convert Ntp to Unix/Posix. ntpr_to_posix :: Num n => n -> n -- | Convert Ntp64 to Unix/Posix. ntpi_to_posix :: Ntp64 -> PosixReal -- | Convert Time to POSIXTime. ntpr_to_posixtime :: NtpReal -> POSIXTime -- | Convert POSIXTime to Time. posixtime_to_ntpr :: POSIXTime -> NtpReal -- | The time at 1970-01-01:00:00:00 which is the Unix/Posix epoch. posix_epoch :: UTCTime -- | Convert UTCTime to Unix/Posix. utc_to_posix :: Fractional n => UTCTime -> n -- | utc_to_posix of Clock.getCurrentTime. getCurrentTimeAsPosix :: IO PosixReal -- | realToFrac of Clock.Posix.getPOSIXTime -- --
-- get_ct = getCurrentTimeAsPosix -- get_pt = getPosixTimeAsPosix -- (ct,pt) <- get_ct >>= \t0 -> get_pt >>= \t1 -> return (t0,t1) -- print (pt - ct,pt - ct < 1e-5) --getPosixTimeAsPosix :: IO PosixReal -- | Read current real-valued Ntp 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 showFFloat that deletes trailing zeros. -- --
-- map (showFloatWithPrecision (Just 4)) [1, 2.0, pi] == ["1.0", "2.0", "3.1416"] --showFloatWithPrecision :: RealFloat n => FpPrecision -> n -> String -- | Hex encoded byte sequence. -- --
-- showBytes [0, 15, 16, 144, 255] == "000f1090ff" --showBytes :: [Int] -> String -- | Escape whites space (space, tab, newline) and the escape character -- (backslash). -- --
-- mapM_ (putStrLn . escapeString) ["str", "str ", "st r", "s\tr", "s\\tr", "\nstr"] --escapeString :: String -> String -- | Printer for Datum. -- --
-- 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"] --showDatum :: FpPrecision -> Datum -> String -- | Printer for Message. -- --
-- 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 ---- --
-- 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 --showMessage :: FpPrecision -> Message -> String -- | Printer for Bundle -- --
-- 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 --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 -- | p 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. -- --
-- parseDatum 'i' "-1" == Int32 (-1) -- parseDatum 'f' "-2.3" == Float (-2.3) --parseDatum :: Char -> String -> Datum -- | Run message parser. -- --
-- 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 --parseMessage :: String -> Message -- | Run bundle parser. -- --
-- 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 --parseBundle :: String -> Bundle -- | Run packet parser. -- --
-- 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 --parsePacket :: String -> Packet -- | Optimised encode function for Osc packets. module Sound.Osc.Coding.Encode.Builder -- | Builder for an Osc Packet. build_packet :: Packet -> Builder -- | Encode an Osc Message, ie. encodePacket of -- Packet_Message. -- --
-- 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 --encodeMessage :: Message -> ByteString -- | Encode an Osc Bundle, ie. encodePacket of -- Packet_Bundle. -- --
-- 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 --encodeBundle :: Bundle -> ByteString -- | Encode an Osc Packet. encodePacket :: Packet -> ByteString -- | Encode an Osc Packet to a strict ByteString. encodePacket_strict :: Packet -> ByteString -- | Base-level encode function for Osc packets (slow). For ordinary use -- see Builder. module Sound.Osc.Coding.Encode.Base -- | Align byte string, if required. extend :: Word8 -> ByteString -> ByteString -- | Encode Osc Datum. -- -- MidiData: Bytes from MSB to LSB are: port id, status byte, data1, -- data2. -- --
-- encode_datum (blob [1, 2, 3, 4]) == B.pack [0, 0, 0, 4, 1, 2, 3, 4] --encode_datum :: Datum -> ByteString -- | Encode Osc Message. -- --
-- 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] --encodeMessage :: Message -> ByteString -- | Encode Osc Message as an Osc blob. encode_message_blob :: Message -> Datum -- | Encode Osc Bundle. -- -- 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 Packet. encodePacket :: Packet -> ByteString -- | Optimised decode function for Osc packets. module Sound.Osc.Coding.Decode.Binary -- | Get an Osc Packet. get_packet :: Get Packet -- | Decode an Osc Message from a lazy ByteString. -- --
-- 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] --decodeMessage :: ByteString -> Message -- | Decode an Osc Bundle from a lazy ByteString. decodeBundle :: ByteString -> Bundle -- | Decode an Osc packet from a lazy ByteString. -- --
-- 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]) --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 -- Binary. module Sound.Osc.Coding.Decode.Base -- | Decode an Osc Message. decodeMessage :: ByteString -> Message -- | Decode an Osc Bundle. decodeBundle :: ByteString -> Bundle -- | Decode an Osc Packet. -- --
-- 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]) --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 pauseThread limit (in seconds). Values larger than this -- require a different thread delay mechanism, see sleepThread. -- The value is the number of microseconds in maxBound::Int. pauseThreadLimit :: Fractional n => n -- | Pause current thread for the indicated duration (in seconds), see -- pauseThreadLimit. pauseThreadFor :: RealFrac n => n -> IO () -- | Pause current thread until the given time, see -- pauseThreadLimit. pauseThreadUntilTime :: RealFrac n => n -> IO () -- | Sleep current thread for the indicated duration (in seconds). Divides -- long sleeps into parts smaller than pauseThreadLimit. sleepThreadFor :: RealFrac n => n -> IO () -- | Sleep current thread until the given time. Divides long sleeps into -- parts smaller than pauseThreadLimit. 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 f is True when applied to -- result. untilPredicate :: Monad m => (a -> Bool) -> m a -> m a -- | Repeat action until f does not give Nothing when applied -- to result. untilMaybe :: Monad m => (a -> Maybe b) -> m a -> m b -- | An abstract transport layer with implementations for Udp and -- Tcp 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 -- | sendPacket of Packet_Message. sendMessage :: Transport t => t -> Message -> IO () -- | sendPacket of Packet_Bundle. sendBundle :: Transport t => t -> Bundle -> IO () -- | Variant of recvPacket that runs packet_to_bundle. recvBundle :: Transport t => t -> IO Bundle -- | Variant of recvPacket that runs packet_to_message. recvMessage :: Transport t => t -> IO (Maybe Message) -- | Variant of recvPacket that runs packetMessages. recvMessages :: Transport t => t -> IO [Message] -- | Wait for a Packet where the supplied predicate is True, -- discarding intervening packets. waitUntil :: Transport t => t -> (Packet -> Bool) -> IO Packet -- | Wait for a Packet where the supplied function does not give -- Nothing, discarding intervening packets. waitFor :: Transport t => t -> (Packet -> Maybe a) -> IO a -- | waitUntil packet_is_immediate. waitImmediate :: Transport t => t -> IO Packet -- | waitFor packet_to_message, ie. an incoming -- Message or immediate mode Bundle with one element. waitMessage :: Transport t => t -> IO Message -- | A waitFor for variant using packet_has_address to match -- on the Address_Pattern of incoming Packets. waitAddress :: Transport t => t -> Address_Pattern -> IO Packet -- | Variant on waitAddress that returns matching Message. waitReply :: Transport t => t -> Address_Pattern -> IO Message -- | Variant of waitReply that runs messageDatum. 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 -- | DuplexOsc is the union of SendOsc and RecvOsc. class (SendOsc m, RecvOsc m) => DuplexOsc m -- | Transport is DuplexOsc with a MonadIO 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 -- | void of withTransport. withTransport_ :: Transport t => IO t -> Connection t r -> IO () -- | Type restricted synonym for sendOsc. sendMessage :: SendOsc m => Message -> m () -- | Type restricted synonym for sendOsc. sendBundle :: SendOsc m => Bundle -> m () -- | Variant of recvPacket that runs packet_to_bundle. recvBundle :: RecvOsc m => m Bundle -- | Variant of recvPacket that runs packet_to_message. recvMessage :: RecvOsc m => m (Maybe Message) -- | Erroring variant. recvMessage_err :: RecvOsc m => m Message -- | Variant of recvPacket that runs packetMessages. recvMessages :: RecvOsc m => m [Message] -- | Wait for a Packet where the supplied predicate is -- True, discarding intervening packets. waitUntil :: RecvOsc m => (Packet -> Bool) -> m Packet -- | Wait for a Packet where the supplied function does not give -- Nothing, discarding intervening packets. waitFor :: RecvOsc m => (Packet -> Maybe a) -> m a -- | waitUntil packet_is_immediate. waitImmediate :: RecvOsc m => m Packet -- | waitFor packet_to_message, ie. an incoming -- Message or immediate mode Bundle with one element. waitMessage :: RecvOsc m => m Message -- | A waitFor for variant using packet_has_address to -- match on the Address_Pattern of incoming Packets. waitAddress :: RecvOsc m => Address_Pattern -> m Packet -- | Variant on waitAddress that returns matching Message. waitReply :: RecvOsc m => Address_Pattern -> m Message -- | Variant of waitReply that runs messageDatum. 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 send. udp_send_data :: Udp -> ByteString -> IO () -- | Send data over Udp using sendAll. 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. Broadcast or RecvTimeOut. set_udp_opt :: SocketOption -> Int -> Udp -> IO () -- | Get option. get_udp_opt :: SocketOption -> Udp -> IO Int -- | Make a Udp connection. openUdp :: String -> Int -> IO Udp -- | Trivial Udp server socket. -- --
-- import Control.Concurrent ---- --
-- let u0 = udpServer "127.0.0.1" 57300 -- t0 <- forkIO (Fd.withTransport u0 (\fd -> forever (Fd.recvMessage fd >>= print >> print "Received message, continuing"))) -- killThread t0 ---- --
-- let u1 = openUdp "127.0.0.1" 57300 -- Fd.withTransport u1 (\fd -> Fd.sendMessage fd (Packet.message "/n" [])) --udpServer :: String -> Int -> IO Udp -- | Variant of udpServer 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 Socket to Tcp. socket_to_tcp :: Socket -> IO Tcp -- | Create and initialise Tcp. tcp_handle :: (Socket -> SockAddr -> IO ()) -> String -> Int -> IO Tcp -- | Make a Tcp connection. -- --
-- 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 -> let f = Fd.sendMessage fd in f m1 >> pauseThread 0.25 >> f m2) --openTcp :: String -> Int -> IO Tcp -- | accept connection at s and run f. tcp_server_f :: Socket -> (Tcp -> IO ()) -> IO () -- | A trivial Tcp Osc 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 timeout where time is given in fractional seconds. timeout_r :: Double -> IO a -> IO (Maybe a) -- | Variant of recvPacket that implements an n second -- timeout. recvPacketTimeout :: Transport t => Double -> t -> IO (Maybe Packet) -- | Composite of non-transport related modules. -- -- Provides the Datum, Message, Time, Bundle -- and Packet types and the coding functions encodePacket -- and decodePacket. -- --
-- import Sound.Osc.Core -- -- let o = bundle immediately [message "/g_free" [Int32 0]] -- let e = encodeBundle o -- decodePacket e == Packet_Bundle o --module Sound.Osc.Core -- | Composite of Sound.Osc.Core and Sound.Osc.Transport.Fd. module Sound.Osc.Fd -- | Composite of Sound.Osc.Core and -- Sound.Osc.Transport.Monad. module Sound.Osc -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. This allows us to run IO -- computations in any monadic stack, so long as it supports these kinds -- of operations (i.e. IO is the base monad for the stack). -- --
-- import Control.Monad.Trans.State -- from the "transformers" library -- -- printState :: Show s => StateT s IO () -- printState = do -- state <- get -- liftIO $ print state ---- -- Had we omitted liftIO, we would have ended up with -- this error: -- --
-- • Couldn't match type ‘IO’ with ‘StateT s IO’ -- Expected type: StateT s IO () -- Actual type: IO () ---- -- The important part here is the mismatch between StateT s IO -- () and IO (). -- -- Luckily, we know of a function that takes an IO a and -- returns an (m a): liftIO, enabling us to run -- the program and see the expected results: -- --
-- > evalStateT printState "hello" -- "hello" -- -- > evalStateT printState 3 -- 3 --liftIO :: MonadIO m => IO a -> m a -- | 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 -- | 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 -- | Four-byte midi message: port-id, status-byte, data, data. data MidiData MidiData :: !Word8 -> !Word8 -> !Word8 -> !Word8 -> MidiData -- | Type for Word8 arrays, these are stored with an Datum -- length prefix. type Blob = ByteString -- | Type for Ascii strings (strict Char8 ByteString) type Ascii = ByteString -- | Type enumerating Datum categories. type DatumType = Char -- | Type-specialised pack. ascii :: String -> Ascii -- | 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 Datum. datum_type_name :: Datum -> (DatumType, String) -- | Datum as Integral if Int32 or Int64. -- --
-- let d = [Int32 5,Int64 5,Float 5.5,Double 5.5] -- map datum_integral d == [Just (5::Int),Just 5,Nothing,Nothing] --datum_integral :: Integral i => Datum -> Maybe i -- | Datum as Floating if Int32, Int64, Float, Double or -- TimeStamp. -- --
-- let d = [Int32 5,Int64 5,Float 5,Double 5,TimeStamp 5] -- mapMaybe datum_floating d == replicate 5 (5::Double) --datum_floating :: Floating n => Datum -> Maybe n -- | Type generalised Datum. -- --
-- int32 (1::Int32) == int32 (1::Integer) -- d_int32 (int32 (maxBound::Int32)) == maxBound -- int32 (((2::Int) ^ (64::Int))::Int) == Int32 0 --int32 :: Integral n => n -> Datum -- | Type generalised Int64. -- --
-- int64 (1::Int32) == int64 (1::Integer) -- d_int64 (int64 (maxBound::Int64)) == maxBound --int64 :: Integral n => n -> Datum -- | Type generalised Float. -- --
-- float (1::Int) == float (1::Double) -- floatRange (undefined::Float) == (-125,128) -- isInfinite (d_float (float (encodeFloat 1 256 :: Double))) == True --float :: Real n => n -> Datum -- | Type generalised Double. -- --
-- double (1::Int) == double (1::Double) -- double (encodeFloat 1 256 :: Double) == Double 1.157920892373162e77 --double :: Real n => n -> Datum -- | AsciiString of pack. -- --
-- string "string" == AsciiString (ByteString.Char8.pack "string") --string :: String -> Datum -- | Four-tuple variant of Midi . MidiData. -- --
-- midi (0,0,0,0) == Midi (MidiData 0 0 0 0) --midi :: (Word8, Word8, Word8, Word8) -> Datum -- | Blob of blob_pack. blob :: [Word8] -> Datum -- | Message argument types are given by a signature. -- --
-- signatureFor [Int32 1,Float 1,string "1"] == ",ifs" --signatureFor :: [Datum] -> String -- | The descriptor is an Ascii encoded signature. -- --
-- descriptor [Int32 1,Float 1,string "1"] == ascii ",ifs" --descriptor :: [Datum] -> Ascii -- | Descriptor tags are comma prefixed. descriptor_tags :: Ascii -> Ascii -- | An Osc Packet is either a Message or a Bundle. data Packet Packet_Message :: !Message -> Packet [packetMessage] :: Packet -> !Message Packet_Bundle :: !Bundle -> Packet [packetBundle] :: Packet -> !Bundle -- | An Osc bundle, a Time and a sequence of Messages. Do not -- allow recursion, all contents must be messages. data Bundle Bundle :: !Time -> ![Message] -> Bundle [bundleTime] :: Bundle -> !Time [bundleMessages] :: Bundle -> ![Message] -- | An Osc message, an Address_Pattern and a sequence of -- Datum. data Message Message :: !Address_Pattern -> ![Datum] -> Message [messageAddress] :: Message -> !Address_Pattern [messageDatum] :: Message -> ![Datum] -- | 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 OverloadedStrings. type Address_Pattern = String -- | Message constructor. It is an error if the -- Address_Pattern doesn't conform to the Osc specification. message :: Address_Pattern -> [Datum] -> Message messageSignature :: Message -> String messageDescriptor :: Message -> Ascii -- | Bundle constructor. It is an error if the Message -- list is empty. bundle :: Time -> [Message] -> Bundle -- | Packet_Bundle of bundle. p_bundle :: Time -> [Message] -> Packet -- | Packet_Message of message. p_message :: Address_Pattern -> [Datum] -> Packet -- | Constant indicating a bundle to be executed immediately. It has the -- Ntp64 representation of 1. -- --
-- ntpr_to_ntpi immediately == 1 --immediately :: Time -- | The Time of Packet, if the Packet is a -- Message this is immediately. packetTime :: Packet -> Time -- | Retrieve the set of Messages from a Packet. packetMessages :: Packet -> [Message] -- | If Packet is a Message add immediately timestamp, -- else id. packet_to_bundle :: Packet -> Bundle -- | If Packet is a Message or a Bundle with an -- immediate time tag and with one element, return the -- Message, else Nothing. packet_to_message :: Packet -> Maybe Message -- | Is Packet immediate, ie. a Bundle with timestamp -- immediately, or a plain Message. packet_is_immediate :: Packet -> Bool -- | Variant of either for Packet. at_packet :: (Message -> a) -> (Bundle -> a) -> Packet -> a -- | Does Message have the specified Address_Pattern. message_has_address :: Address_Pattern -> Message -> Bool -- | Do any of the Messages at Bundle have the specified -- Address_Pattern. bundle_has_address :: Address_Pattern -> Bundle -> Bool -- | Does Packet have the specified Address_Pattern, ie. -- message_has_address or bundle_has_address. packet_has_address :: Address_Pattern -> Packet -> Bool -- | Unix/Posix time in real-valued (fractional) form. The -- Unix/Posix epoch is January 1, 1970. type PosixReal = Double -- | Ntp time in real-valued (fractional) form. type NtpReal = Double -- | 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 -- | Convert an NtpReal timestamp to an Ntp64 timestamp. -- --
-- ntpr_to_ntpi 0 == 0 -- fmap ntpr_to_ntpi time --ntpr_to_ntpi :: NtpReal -> Ntp64 -- | Convert an Ntp64 timestamp to a real-valued Ntp timestamp. -- --
-- ntpi_to_ntpr 0 == 0.0 --ntpi_to_ntpr :: Ntp64 -> NtpReal -- | Difference (in seconds) between Ntp and Posix epochs. -- --
-- ntp_posix_epoch_diff / (24 * 60 * 60) == 25567 -- 25567 `div` 365 == 70 --ntp_posix_epoch_diff :: Num n => n -- | Convert a PosixReal timestamp to an Ntp64 timestamp. posix_to_ntpi :: PosixReal -> Ntp64 -- | Convert Unix/Posix to Ntp. posix_to_ntpr :: Num n => n -> n -- | Convert Ntp to Unix/Posix. ntpr_to_posix :: Num n => n -> n -- | Convert Ntp64 to Unix/Posix. ntpi_to_posix :: Ntp64 -> PosixReal -- | Convert Time to POSIXTime. ntpr_to_posixtime :: NtpReal -> POSIXTime -- | Convert POSIXTime to Time. posixtime_to_ntpr :: POSIXTime -> NtpReal -- | The time at 1970-01-01:00:00:00 which is the Unix/Posix epoch. posix_epoch :: UTCTime -- | Convert UTCTime to Unix/Posix. utc_to_posix :: Fractional n => UTCTime -> n -- | utc_to_posix of Clock.getCurrentTime. getCurrentTimeAsPosix :: IO PosixReal -- | realToFrac of Clock.Posix.getPOSIXTime -- --
-- get_ct = getCurrentTimeAsPosix -- get_pt = getPosixTimeAsPosix -- (ct,pt) <- get_ct >>= \t0 -> get_pt >>= \t1 -> return (t0,t1) -- print (pt - ct,pt - ct < 1e-5) --getPosixTimeAsPosix :: IO PosixReal -- | Read current real-valued Ntp timestamp. currentTime :: IO NtpReal -- | Builder for an Osc Packet. build_packet :: Packet -> Builder -- | Encode an Osc Packet. encodePacket :: Packet -> ByteString -- | Encode an Osc Message, ie. encodePacket of -- Packet_Message. -- --
-- 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 --encodeMessage :: Message -> ByteString -- | Encode an Osc Bundle, ie. encodePacket of -- Packet_Bundle. -- --
-- 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 --encodeBundle :: Bundle -> ByteString -- | Encode an Osc Packet to a strict ByteString. encodePacket_strict :: Packet -> ByteString -- | Get an Osc Packet. get_packet :: Get Packet -- | Decode an Osc Message from a lazy ByteString. -- --
-- 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] --decodeMessage :: ByteString -> Message -- | Decode an Osc Bundle from a lazy ByteString. decodeBundle :: ByteString -> Bundle -- | Decode an Osc packet from a lazy ByteString. -- --
-- 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]) --decodePacket :: ByteString -> Packet -- | Decode an Osc packet from a strict Char8 ByteString. decodePacket_strict :: ByteString -> Packet -- | 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) -- | The pauseThread limit (in seconds). Values larger than this -- require a different thread delay mechanism, see sleepThread. -- The value is the number of microseconds in maxBound::Int. pauseThreadLimit :: Fractional n => n -- | Pause current thread for the indicated duration (in seconds), see -- pauseThreadLimit. pauseThreadFor :: RealFrac n => n -> IO () -- | Pause current thread until the given time, see -- pauseThreadLimit. pauseThreadUntilTime :: RealFrac n => n -> IO () -- | Sleep current thread for the indicated duration (in seconds). Divides -- long sleeps into parts smaller than pauseThreadLimit. sleepThreadFor :: RealFrac n => n -> IO () -- | Sleep current thread until the given time. Divides long sleeps into -- parts smaller than pauseThreadLimit. sleepThreadUntilTime :: RealFrac n => n -> IO () 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 () -- | Repeat action until predicate f is True when applied to -- result. untilPredicate :: Monad m => (a -> Bool) -> m a -> m a -- | Repeat action until f does not give Nothing when applied -- to result. untilMaybe :: Monad m => (a -> Maybe b) -> m a -> m b -- | Transport connection. type Connection t a = ReaderT t IO a -- | Transport is DuplexOsc with a MonadIO constraint. class (DuplexOsc m, MonadIO m) => Transport m -- | DuplexOsc is the union of SendOsc and RecvOsc. class (SendOsc m, RecvOsc m) => DuplexOsc m -- | Receiver monad. class Monad m => RecvOsc m -- | Receive and decode an Osc packet. recvPacket :: RecvOsc m => m Packet -- | Sender monad. class Monad m => SendOsc m -- | Encode and send an Osc packet. sendPacket :: SendOsc m => Packet -> m () -- | Bracket Open Sound Control communication. withTransport :: Transport t => IO t -> Connection t r -> IO r -- | void of withTransport. withTransport_ :: Transport t => IO t -> Connection t r -> IO () -- | Type restricted synonym for sendOsc. sendMessage :: SendOsc m => Message -> m () -- | Type restricted synonym for sendOsc. sendBundle :: SendOsc m => Bundle -> m () -- | Variant of recvPacket that runs packet_to_bundle. recvBundle :: RecvOsc m => m Bundle -- | Variant of recvPacket that runs packet_to_message. recvMessage :: RecvOsc m => m (Maybe Message) -- | Erroring variant. recvMessage_err :: RecvOsc m => m Message -- | Variant of recvPacket that runs packetMessages. recvMessages :: RecvOsc m => m [Message] -- | Wait for a Packet where the supplied predicate is -- True, discarding intervening packets. waitUntil :: RecvOsc m => (Packet -> Bool) -> m Packet -- | Wait for a Packet where the supplied function does not give -- Nothing, discarding intervening packets. waitFor :: RecvOsc m => (Packet -> Maybe a) -> m a -- | waitUntil packet_is_immediate. waitImmediate :: RecvOsc m => m Packet -- | waitFor packet_to_message, ie. an incoming -- Message or immediate mode Bundle with one element. waitMessage :: RecvOsc m => m Message -- | A waitFor for variant using packet_has_address to -- match on the Address_Pattern of incoming Packets. waitAddress :: RecvOsc m => Address_Pattern -> m Packet -- | Variant on waitAddress that returns matching Message. waitReply :: RecvOsc m => Address_Pattern -> m Message -- | Variant of waitReply that runs messageDatum. waitDatum :: RecvOsc m => Address_Pattern -> m [Datum] -- | 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 send. udp_send_data :: Udp -> ByteString -> IO () -- | Send data over Udp using sendAll. 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. Broadcast or RecvTimeOut. set_udp_opt :: SocketOption -> Int -> Udp -> IO () -- | Get option. get_udp_opt :: SocketOption -> Udp -> IO Int -- | Make a Udp connection. openUdp :: String -> Int -> IO Udp -- | Trivial Udp server socket. -- --
-- import Control.Concurrent ---- --
-- let u0 = udpServer "127.0.0.1" 57300 -- t0 <- forkIO (Fd.withTransport u0 (\fd -> forever (Fd.recvMessage fd >>= print >> print "Received message, continuing"))) -- killThread t0 ---- --
-- let u1 = openUdp "127.0.0.1" 57300 -- Fd.withTransport u1 (\fd -> Fd.sendMessage fd (Packet.message "/n" [])) --udpServer :: String -> Int -> IO Udp -- | Variant of udpServer 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) -- | 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 Socket to Tcp. socket_to_tcp :: Socket -> IO Tcp -- | Create and initialise Tcp. tcp_handle :: (Socket -> SockAddr -> IO ()) -> String -> Int -> IO Tcp -- | Make a Tcp connection. -- --
-- 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 -> let f = Fd.sendMessage fd in f m1 >> pauseThread 0.25 >> f m2) --openTcp :: String -> Int -> IO Tcp -- | accept connection at s and run f. tcp_server_f :: Socket -> (Tcp -> IO ()) -> IO () -- | A trivial Tcp Osc server. tcp_server :: Int -> (Tcp -> IO ()) -> IO ()