Documentation ¶
Overview ¶
Package osc implements Open Sound Control 1.0
For more info about OSC, go to http://opensoundcontrol.org
Example (CustomDispatcher) ¶
package main import ( "fmt" "log" "net" "time" ) func main() { laddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") if err != nil { log.Fatal(err) } server, err := ListenUDP("udp", laddr) if err != nil { log.Fatal(err) } defer server.Close() var ( doneChan = make(chan struct{}) dispatcher = customDispatcher{done: doneChan} errChan = make(chan error) ) go func() { errChan <- server.Serve(1, dispatcher) }() // Send a message from the client. raddr, err := net.ResolveUDPAddr("udp", server.LocalAddr().String()) if err != nil { log.Fatal(err) } client, err := DialUDP("udp", nil, raddr) if err != nil { log.Fatal(err) } if err := client.Send(Message{Address: "/foo"}); err != nil { log.Fatal(err) } select { case <-doneChan: case err := <-errChan: log.Fatal(err) case <-time.After(5 * time.Second): panic("timeout waiting for custom dispatcher example to finish") } } type customDispatcher struct { done chan struct{} } func (d customDispatcher) Dispatch(bundle Bundle, exactMatch bool) error { fmt.Println("bundle received by custom dispatcher") close(d.done) return nil } func (d customDispatcher) Invoke(msg Message, exactMatch bool) error { fmt.Printf("method %s received by custom dispatcher\n", msg.Address) close(d.done) return nil }
Output: method /foo received by custom dispatcher
Example (PingPong) ¶
package main import ( "errors" "fmt" "log" "net" "time" ) func main() { errChan := make(chan error) // Setup the server. laddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") if err != nil { log.Fatal(err) } server, err := ListenUDP("udp", laddr) if err != nil { log.Fatal(err) } // Run the server in a new goroutine. go serverDispatch(server, errChan) // Setup the client. raddr, err := net.ResolveUDPAddr("udp", server.LocalAddr().String()) if err != nil { log.Fatal(err) } client, err := DialUDP("udp", nil, raddr) if err != nil { log.Fatal(err) } var ( pongChan = make(chan struct{}) clientCloseChan = make(chan struct{}) ) // Clients are also servers! go clientDispatch(client, errChan, pongChan, clientCloseChan) // Send the ping message, wait for the pong, then close both connections. if err := client.Send(Message{Address: "/ping"}); err != nil { log.Fatal(err) } if err := waitPong(pongChan, errChan); err != nil { log.Fatal(err) } if err := client.Send(Message{Address: "/close"}); err != nil { log.Fatal(err) } if err := waitErr(errChan); err != nil { log.Fatal(err) } if err := waitClose(clientCloseChan, errChan); err != nil { log.Fatal(err) } } func serverDispatch(server *UDPConn, errChan chan error) { errChan <- server.Serve(1, PatternMatching{ "/ping": Method(func(msg Message) error { fmt.Println("Server received ping.") return server.SendTo(msg.Sender, Message{Address: "/pong"}) }), "/close": Method(func(msg Message) error { if err := server.SendTo(msg.Sender, Message{Address: "/close"}); err != nil { _ = server.Close() return err } fmt.Println("Server closing.") return server.Close() }), }) } func clientDispatch(client Conn, errChan chan error, pongChan chan struct{}, closeChan chan struct{}) { errChan <- client.Serve(1, PatternMatching{ "/pong": Method(func(msg Message) error { fmt.Println("Client received pong.") close(pongChan) return nil }), "/close": Method(func(msg Message) error { fmt.Println("Client closing.") close(closeChan) return client.Close() }), }) } func waitPong(pongChan chan struct{}, errChan chan error) error { select { case <-time.After(2 * time.Second): return errors.New("timeout") case err := <-errChan: if err != nil { return err } case <-pongChan: } return nil } func waitErr(errChan chan error) error { select { case <-time.After(2 * time.Second): return errors.New("timeout") case err := <-errChan: return err } } func waitClose(closeChan chan struct{}, errChan chan error) error { select { case <-time.After(2 * time.Second): return errors.New("timeout") case <-closeChan: } return nil }
Output: Server received ping. Client received pong. Server closing. Client closing.
Index ¶
- Constants
- Variables
- func GetRegex(pattern string) (*regexp.Regexp, error)
- func Pad(b []byte) []byte
- func ReadBlob(length int32, data []byte) ([]byte, int64)
- func ReadString(data []byte) (string, int64)
- func TempSocket() string
- func ToBytes(s string) []byte
- func ValidateAddress(addr string) error
- func VerifyParts(m1, m2 string) bool
- type Argument
- type Arguments
- type Blob
- func (b Blob) Bytes() []byte
- func (b Blob) Equal(other Argument) bool
- func (b Blob) ReadBlob() ([]byte, error)
- func (b Blob) ReadBool() (bool, error)
- func (b Blob) ReadFloat32() (float32, error)
- func (b Blob) ReadInt32() (int32, error)
- func (b Blob) ReadString() (string, error)
- func (b Blob) String() string
- func (b Blob) Typetag() byte
- func (b Blob) WriteTo(w io.Writer) (int64, error)
- type Bool
- func (b Bool) Bytes() []byte
- func (b Bool) Equal(other Argument) bool
- func (b Bool) ReadBlob() ([]byte, error)
- func (b Bool) ReadBool() (bool, error)
- func (b Bool) ReadFloat32() (float32, error)
- func (b Bool) ReadInt32() (int32, error)
- func (b Bool) ReadString() (string, error)
- func (b Bool) String() string
- func (b Bool) Typetag() byte
- func (b Bool) WriteTo(w io.Writer) (int64, error)
- type Bundle
- type Conn
- type Dispatcher
- type Float
- func (f Float) Bytes() []byte
- func (f Float) Equal(other Argument) bool
- func (f Float) ReadBlob() ([]byte, error)
- func (f Float) ReadBool() (bool, error)
- func (f Float) ReadFloat32() (float32, error)
- func (f Float) ReadInt32() (int32, error)
- func (f Float) ReadString() (string, error)
- func (f Float) String() string
- func (f Float) Typetag() byte
- func (f Float) WriteTo(w io.Writer) (int64, error)
- type Incoming
- type Int
- func (i Int) Bytes() []byte
- func (i Int) Equal(other Argument) bool
- func (i Int) ReadBlob() ([]byte, error)
- func (i Int) ReadBool() (bool, error)
- func (i Int) ReadFloat32() (float32, error)
- func (i Int) ReadInt32() (int32, error)
- func (i Int) ReadString() (string, error)
- func (i Int) String() string
- func (i Int) Typetag() byte
- func (i Int) WriteTo(w io.Writer) (int64, error)
- type Message
- type MessageHandler
- type Method
- type Packet
- type PatternMatching
- type String
- func (s String) Bytes() []byte
- func (s String) Equal(other Argument) bool
- func (s String) ReadBlob() ([]byte, error)
- func (s String) ReadBool() (bool, error)
- func (s String) ReadFloat32() (float32, error)
- func (s String) ReadInt32() (int32, error)
- func (s String) ReadString() (string, error)
- func (s String) String() string
- func (s String) Typetag() byte
- func (s String) WriteTo(w io.Writer) (int64, error)
- type Timetag
- type UDPConn
- func (conn *UDPConn) Close() error
- func (conn *UDPConn) CloseChan() <-chan struct{}
- func (conn *UDPConn) Context() context.Context
- func (conn *UDPConn) Send(p Packet) error
- func (conn *UDPConn) SendTo(addr net.Addr, p Packet) error
- func (conn *UDPConn) Serve(numWorkers int, dispatcher Dispatcher) error
- func (conn *UDPConn) SetContext(ctx context.Context)
- func (conn *UDPConn) SetExactMatch(value bool)
- type UnixConn
- func DialUnix(network string, laddr, raddr *net.UnixAddr) (*UnixConn, error)
- func DialUnixContext(ctx context.Context, network string, laddr, raddr *net.UnixAddr) (*UnixConn, error)
- func ListenUnix(network string, laddr *net.UnixAddr) (*UnixConn, error)
- func ListenUnixContext(ctx context.Context, network string, laddr *net.UnixAddr) (*UnixConn, error)
- func (conn *UnixConn) Close() error
- func (conn *UnixConn) CloseChan() <-chan struct{}
- func (conn *UnixConn) Context() context.Context
- func (conn *UnixConn) Send(p Packet) error
- func (conn *UnixConn) SendTo(addr net.Addr, p Packet) error
- func (conn *UnixConn) Serve(numWorkers int, dispatcher Dispatcher) error
- func (conn *UnixConn) SetExactMatch(value bool)
Examples ¶
Constants ¶
const ( TypetagPrefix byte = ',' TypetagInt byte = 'i' TypetagFloat byte = 'f' TypetagString byte = 's' TypetagBlob byte = 'b' TypetagFalse byte = 'F' TypetagTrue byte = 'T' )
Typetag constants.
const ( // SecondsFrom1900To1970 is exactly what it sounds like. SecondsFrom1900To1970 = 2208988800 // Source: RFC 868 // TimetagSize is the number of 8-bit bytes in an OSC timetag. TimetagSize = 8 // Immediately is a special timetag value that means "immediately". Immediately = Timetag(1) )
const (
// BundleTag is the tag on an OSC bundle message.
BundleTag = "#bundle"
)
const (
// MessageChar is the first character of any valid OSC message.
MessageChar = '/'
)
Variables ¶
var ( ErrEarlyTimetag = errors.New("enclosing bundle's timetag was later than the nested bundle's") ErrEndOfPackets = errors.New("end of packets") )
Common errors.
var ( ErrNilDispatcher = errors.New("nil dispatcher") ErrPrematureClose = errors.New("server cannot be closed before calling Listen") )
Common errors.
var ( ErrIndexOutOfBounds = errors.New("index out of bounds") ErrInvalidTypeTag = errors.New("invalid type tag") ErrNilWriter = errors.New("writer must not be nil") ErrParse = errors.New("error parsing message") )
Common errors.
var (
ErrInvalidAddress = errors.New("invalid OSC address")
)
Common errors.
Functions ¶
func GetRegex ¶
GetRegex compiles and returns a regular expression object for the given address pattern.
func ReadString ¶
ReadString reads a string from a byte slice. If the byte slice does not have any null bytes, then one is appended to the end. If the length of the byte slice is not a multiple of 4 we append as many null bytes as we need to make this true before converting to a string. What this means is that the second return value, which is the number of bytes that are consumed to create the string is always a multiple of 4. We also strip off any trailing null bytes in the returned string.
func TempSocket ¶
func TempSocket() string
TempSocket creates an absolute path to a temporary socket file.
func ToBytes ¶
ToBytes returns an OSC representation of the given string. This means that the returned byte slice is padded with null bytes so that it's length is a multiple of 4.
func ValidateAddress ¶
ValidateAddress returns an error if addr contains characters that are disallowed by the OSC spec.
func VerifyParts ¶
VerifyParts verifies that m1 and m2 have the same number of parts, where a part is a nonempty string between pairs of '/' or a nonempty string at the end.
Types ¶
type Argument ¶
type Argument interface { io.WriterTo Bytes() []byte Equal(Argument) bool ReadInt32() (int32, error) ReadFloat32() (float32, error) ReadBool() (bool, error) ReadString() (string, error) ReadBlob() ([]byte, error) String() string Typetag() byte }
Argument represents an OSC argument. An OSC argument can have many different types, which is why we choose to represent them with an interface.
func ReadArgument ¶
ReadArgument parses an OSC message argument given a type tag and some data.
func ReadArguments ¶
ReadArguments reads all arguments from the reader and adds it to the OSC message.
func ReadBlobFrom ¶
ReadBlobFrom reads a binary blob from the provided data.
func ReadFloatFrom ¶
ReadFloatFrom reads a 32-bit float from a byte slice.
type Blob ¶
type Blob []byte
Blob is a slice of bytes.
func (Blob) Bytes ¶
Bytes converts the arg to a byte slice suitable for adding to the binary representation of an OSC message.
func (Blob) ReadFloat32 ¶
ReadFloat32 reads a 32-bit float from the arg.
func (Blob) ReadString ¶
ReadString string reads a string from the arg.
type Bool ¶
type Bool bool
Bool represents a boolean value.
func (Bool) Bytes ¶
Bytes converts the arg to a byte slice suitable for adding to the binary representation of an OSC message.
func (Bool) ReadFloat32 ¶
ReadFloat32 reads a 32-bit float from the arg.
func (Bool) ReadString ¶
ReadString string reads a string from the arg.
type Bundle ¶
Bundle is an OSC bundle. An OSC Bundle consists of the OSC-string "#bundle" followed by an OSC Time Tag, followed by zero or more bundle elements. The OSC-timetag is a 64-bit fixed point time tag. See http://opensoundcontrol.org/spec-1_0 for more information.
func ParseBundle ¶
ParseBundle parses a bundle from a byte slice.
type Conn ¶
type Conn interface { net.Conn Context() context.Context Serve(int, Dispatcher) error Send(Packet) error SendTo(net.Addr, Packet) error SetExactMatch(bool) }
Conn defines the methods
type Dispatcher ¶
type Dispatcher interface { Dispatch(bundle Bundle, exactMatch bool) error Invoke(msg Message, exactMatch bool) error }
Dispatcher dispatches OSC packets.
type Float ¶
type Float float32
Float represents a 32-bit float.
func (Float) Bytes ¶
Bytes converts the arg to a byte slice suitable for adding to the binary representation of an OSC message.
func (Float) ReadFloat32 ¶
ReadFloat32 reads a 32-bit float from the arg.
func (Float) ReadString ¶
ReadString string reads a string from the arg.
type Int ¶
type Int int32
Int represents a 32-bit integer.
func (Int) Bytes ¶
Bytes converts the arg to a byte slice suitable for adding to the binary representation of an OSC message.
func (Int) ReadFloat32 ¶
ReadFloat32 reads a 32-bit float from the arg.
func (Int) ReadString ¶
ReadString string reads a string from the arg.
type Message ¶
Message is an OSC message. An OSC message consists of an OSC address pattern and zero or more arguments.
func ParseMessage ¶
ParseMessage parses an OSC message from a slice of bytes.
func (Message) Match ¶
Match returns true if the address of the OSC Message matches the given address.
type MessageHandler ¶
MessageHandler is any type that can handle an OSC message.
type Packet ¶
Packet is an OSC packet. An OSC packet consists of its contents, a contiguous block of binary data, and its size, the number of 8-bit bytes that comprise the contents. The size of an OSC packet is always a multiple of 4.
type PatternMatching ¶
type PatternMatching map[string]MessageHandler
PatternMatching is a dispatcher that implements OSC 1.0 pattern matching. See http://opensoundcontrol.org/spec-1_0 "OSC Message Dispatching and Pattern Matching"
type String ¶
type String string
String is a string.
func (String) Bytes ¶
Bytes converts the arg to a byte slice suitable for adding to the binary representation of an OSC message.
func (String) ReadFloat32 ¶
ReadFloat32 reads a 32-bit float from the arg.
func (String) ReadString ¶
ReadString string reads a string from the arg.
type Timetag ¶
type Timetag uint64
Timetag represents an OSC Time Tag. An OSC Time Tag is defined as follows: Time tags are represented by a 64 bit fixed point number. The first 32 bits specify the number of seconds since midnight on January 1, 1900, and the last 32 bits specify fractional parts of a second to a precision of about 200 picoseconds. This is the representation used by Internet NTP timestamps. The time tag value consisting of 63 zero bits followed by a one in the least significant bit is a special case meaning "immediately."
func ReadTimetag ¶
ReadTimetag parses a timetag from a byte slice.
type UDPConn ¶
type UDPConn struct {
// contains filtered or unexported fields
}
UDPConn is an OSC connection over UDP.
func DialUDPContext ¶
func DialUDPContext(ctx context.Context, network string, laddr, raddr *net.UDPAddr) (*UDPConn, error)
DialUDPContext returns a new OSC connection over UDP that can be canceled with the provided context.
func ListenUDPContext ¶
ListenUDPContext creates a UDP listener that can be canceled with the provided context.
func (*UDPConn) CloseChan ¶
func (conn *UDPConn) CloseChan() <-chan struct{}
CloseChan returns a channel that is closed when the connection gets closed.
func (*UDPConn) Serve ¶
func (conn *UDPConn) Serve(numWorkers int, dispatcher Dispatcher) error
Serve starts dispatching OSC. Any errors returned from a dispatched method will be returned. Note that this means that errors returned from a dispatcher method will kill your server. If context.Canceled or context.DeadlineExceeded are encountered they will be returned directly.
func (*UDPConn) SetContext ¶
SetContext sets the context associated with the conn.
func (*UDPConn) SetExactMatch ¶
SetExactMatch changes the behavior of the Serve method so that messages will only be dispatched to methods whose addresses match the message's address exactly. This should provide some performance improvement.
type UnixConn ¶
type UnixConn struct {
// contains filtered or unexported fields
}
UnixConn handles OSC over a unix socket.
func DialUnixContext ¶
func DialUnixContext(ctx context.Context, network string, laddr, raddr *net.UnixAddr) (*UnixConn, error)
DialUnixContext creates a new UnixConn.
func ListenUnix ¶
ListenUnix creates a Unix listener that can be canceled with the provided context.
func ListenUnixContext ¶
ListenUnixContext creates a Unix listener that can be canceled with the provided context.
func (*UnixConn) CloseChan ¶
func (conn *UnixConn) CloseChan() <-chan struct{}
CloseChan returns a channel that is closed when the connection gets closed.
func (*UnixConn) Serve ¶
func (conn *UnixConn) Serve(numWorkers int, dispatcher Dispatcher) error
Serve starts dispatching OSC. Any errors returned from a dispatched method will be returned. Note that this means that errors returned from a dispatcher method will kill your server. If context.Canceled or context.DeadlineExceeded are encountered they will be returned directly.
func (*UnixConn) SetExactMatch ¶
SetExactMatch changes the behavior of the Serve method so that messages will only be dispatched to methods whose addresses match the message's address exactly. This should provide some performance improvement.