Open Sound Control (OSC) library for Golang. Implemented in pure Go.

GoOSC

Build Status GoDoc Coverage Status Go Report Card

Open Sound Control (OSC) library for Golang. Implemented in pure Go.

Features

  • OSC Bundles, including timetags
  • OSC Messages
  • OSC Client
  • OSC Server
  • Supports the following OSC argument types:
    • 'i' (Int32)
    • 'f' (Float32)
    • 's' (string)
    • 'b' (blob / binary data)
    • 'h' (Int64)
    • 't' (OSC timetag)
    • 'd' (Double/int64)
    • 'T' (True)
    • 'F' (False)
    • 'N' (Nil)
  • Support for OSC address pattern including '*', '?', '{,}' and '[]' wildcards

Install

go get github.com/hypebeast/go-osc

Usage

Client

import "github.com/hypebeast/go-osc/osc"

func main() {
    client := osc.NewClient("localhost", 8765)
    msg := osc.NewMessage("/osc/address")
    msg.Append(int32(111))
    msg.Append(true)
    msg.Append("hello")
    client.Send(msg)
}

Server

package main

import "github.com/hypebeast/go-osc/osc"

func main() {
    addr := "127.0.0.1:8765"
    d := osc.NewStandardDispatcher()
    d.AddMsgHandler("/message/address", func(msg *osc.Message) {
        osc.PrintMessage(msg)
    })

    server := &osc.Server{
        Addr: addr,
        Dispatcher:d,
    }
    server.ListenAndServe()
}

Tests

make test
Comments
  • TCP support

    TCP support

    This implements TCP support in the way I described in #34.

    Brief summary:

    • I've done this in a backwards-compatible way, with UDP as the default network protocol.
    • To use TCP, call client.SetNetworkProtocol(osc.TCP) or server.SetNetworkProtocol(osc.TCP).
    • Incidental: I added a server.CloseConnection function to facilitate testing and give users the ability to forcibly stop a running server.
      • ListenAndServe includes defer server.CloseConnection(), ensuring that the connection it creates is closed in the event of an interruption or error.

    I also made some adjustments and improvements to the tests and examples. I did some thorough testing involving this branch of go-osc and a similar branch of JavaOSC where I've just finished implementing TCP support. I tested all the permutations of TCP vs. UDP, Go client vs. Java client, Go server vs. Java server, and everything is looking great, as far as I can tell.

    Feedback welcome, of course. I realize this is a big change set! Let me know if there's anything I can do to make reviewing it easier.

    Thanks for all the excellent work on go-osc!

  • Can't build shuttle-go

    Can't build shuttle-go

    Hi, after this commit https://github.com/hypebeast/go-osc/commit/edff003c8de14fd0897d4c881c1683b88b01729f I am unable to build shuttle-go https://github.com/abourget/shuttle-go, is there a way to revert it or could you provide a fix/workaround?

    thanks

  • Invalid blobs generated

    Invalid blobs generated

    I'm working on an application that sends blobs for controlling some other software, and ran into an issue in which this library generates invalid blobs. Sample code to recreate issue:

    package main
    
    import (
    	"fmt"
    	"github.com/hypebeast/go-osc/osc"
    )
    
    func main() {
    	ip := "localhost"
    	port := 7770
    	client := osc.NewClient(ip, port)
    	message := osc.NewMessage("/dmx/universe/0")
    	b := make([]byte, 512)
    	for i := 0; i < 512; i++ {
    		b[i] = byte(i / 2)
    	}
    	message.Append(b)
    	err := client.Send(message)
    	fmt.Println(err)
    	fmt.Println(message.Address)
    	fmt.Println(message.Arguments)
    }
    

    OSCDump reports the following error: liblo server error 9911 in path /dmx/universe/0: Invalid message received

    If, however, I change the size of slice b to 511, everything works as intended:

    package main
    
    import (
    	"fmt"
    	"github.com/hypebeast/go-osc/osc"
    )
    
    func main() {
    	ip := "localhost"
    	port := 7770
    	client := osc.NewClient(ip, port)
    	message := osc.NewMessage("/dmx/universe/0")
    	b := make([]byte, 511)
    	for i := 0; i < 511; i++ {
    		b[i] = byte(i / 2)
    	}
    	message.Append(b)
    	err := client.Send(message)
    	fmt.Println(err)
    	fmt.Println(message.Address)
    	fmt.Println(message.Arguments)
    }
    

    e3691c7e.717f8444 /dmx/universe/0 b [511 byte blob]

    If there's any other useful information I can provide, let me know.

  • Error in timetag to time.Time conversion

    Error in timetag to time.Time conversion

    Extract from the code:

    // timetagToTime converts the given timetag to a time object.
    func timetagToTime(timetag uint64) (t time.Time) {
    	return time.Unix(int64((timetag>>32)-secondsFrom1900To1970), int64(timetag&0xffffffff))
    }
    

    This function is used on bundle reception (readBundle called by readPacket called by a few functions) to parse received timetags. It takes the lower 32 bits from the timetag and gives them as the second argument of time.Unix, that has the following signature and doc:

    // Unix returns the local Time corresponding to the given Unix time,
    // sec seconds and nsec nanoseconds since January 1, 1970 UTC.
    // It is valid to pass nsec outside the range [0, 999999999].
    // Not all sec values have a corresponding time value. One such
    // value is 1<<63-1 (the largest int64 value).
    func Unix(sec int64, nsec int64) Time
    

    However, the OSC 1.0 spec describes time tags as:

    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 signifigant bit is a special case meaning “immediately.” — https://ccrma.stanford.edu/groups/osc/spec-1_0.html#timetags

    As such, the lower 32 bits should be used as fractions of a second (1 second / 2^32 ~= 0.233 nano second per fraction) rather than whole nanoseconds.

    If this analysis is right, this bug affects every bundle received by this library by a big amount: between 0s at the start of the second up to, at the end of a second, 2^32-1 nanoseconds - 1 second, or ~3.295 seconds! I have not run the code, but I assume people using the bundle feature would notice such big delays in dispatch?

  • Pull concrete dispatcher logic out of server

    Pull concrete dispatcher logic out of server

    This allows the use of custom Dispatchers, making the Server more flexible.

    Previously, the * handler could be used but this would still mean that the logic of the OscDispatcher would have to be gone through before being routed to the defaultHandler.

  • Use Dispatcher interface in Server

    Use Dispatcher interface in Server

    This PR makes Server use the Dispatcher interface, rather than using OscDispatcher directly.

    This change allows users of this library to switch out OscDispatcher for other implementations as/where needed (perhaps for one which trades-off full OSC compliance for extra performance, e.g. "exact" lookups on message addresses rather than pattern lookups).

  • Fix Server.Handle() with address pattern

    Fix Server.Handle() with address pattern

    The address in the osc.Message was being treated as a pattern, and matched against the handler address. That doesn't make any sense, the handler address should be a pattern, and the address in the osc.Message should be matched against that handler pattern?

  • Kopf idiomatic go

    Kopf idiomatic go

    This CL is a noop CL from a functionality standpoint. The focus of the changes are to make the code more Go idiomatic.

    • Shorter variable names (https://github.com/golang/go/wiki/CodeReviewComments#variable-names)
    • Indent error flow (https://github.com/golang/go/wiki/CodeReviewComments#indent-error-flow)
    • Handle errors (https://github.com/golang/go/wiki/CodeReviewComments#handle-errors)
    • Minimize named result parameters (https://github.com/golang/go/wiki/CodeReviewComments#named-result-parameters)
  • Simplify and improve server.

    Simplify and improve server.

    • Remove "close" member which had a race condition.
    • Behave more like a standard Go server, eg: net/http
    • Implement read deadlines correctly, add a test.
  • fixtests: alter formatting to fix tests

    fixtests: alter formatting to fix tests

    Prior to this change, go test would fail because of the formatting of some of the t.Errorf calls had used the wrong formatting type or a value missing.

    This change alters the formatting calls so that the test all pass.

    No logic has been changed in this commit.

  • Add Message unit tests

    Add Message unit tests

    Add TypeTags() and String() unit tests for the Message struct. Also move the server examples into separate directories so that unit tests pass consistently with Travis.

    The majority of commits listed on this CL are for my own branch, and are not relevant to this change. Please look at the 'Files changed' to see exactly what is changing.

  • match osc message based on address and types

    match osc message based on address and types

    In the liblo c/c++ osc library, one can specify a method which matches a osc message based on address and types:

    /* add method that will match the path /foo/bar, with two numbers, coerced
     * to float and int */
    lo_server_thread_add_method(st, "/foo/bar", "fi", foo_handler, NULL);
    

    So "/error", "sis" matches a other message then "/error", "f"

    Is this possible with go-osc?

    I see there references to a 'OSC Type Tag String' in the code, but not sure if or how this can be used for pattern matching: https://github.com/hypebeast/go-osc/blob/cec5a8a1e5f5/osc/osc.go#L220 https://github.com/hypebeast/go-osc/blob/cec5a8a1e5f5/osc/osc.go#L282

    Liblo:

    https://github.com/radarsat1/liblo/blob/master/examples/example_server.c https://github.com/radarsat1/liblo/blob/master/lo/lo_types.h

  • [question] Osc support for Go

    [question] Osc support for Go

    Is Go a good language when one wants to use OSC?

    How good is this OSC library for Go? How does this library compare to those in Python for instance (python-liblo)?

    Go seems to be interesting language and faster then Python, but I need a good OSC library.

  • Receiving of osc bundles is broken

    Receiving of osc bundles is broken

    Adding the following test-case

    func TestReadBundle(t *testing.T) {
    	b := NewBundle(time.Now())
    	b.Append(NewMessage("/a", "test"))
    	b.Append(NewMessage("/b", "test2"))
    
    	d, err := b.MarshalBinary()
    	if err != nil {
    		t.Errorf("bundle marshal error: %v", err)
    		return
    	}
    
    	d = append(d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
    
    	io := bufio.NewReader(bytes.NewReader(d))
    	start := 0
    	bundle, err := readBundle(io, &start, len(d))
    	if err != nil {
    		t.Errorf("bundle read error: %v", err)
    		return
    	}
    
    	if len(bundle.Messages) != 2 {
    		t.Error("incorrect message count on decode")
    		return
    	}
    }
    

    resultst in:

    --- FAIL: TestReadBundle (0.00s)
        osc_test.go:302: bundle read error: unsupported OSC packet type: only Bundle and Message are supported
    

    During the decoding of osc bundles the appending of messages to the bundle fails.

  • Why is a new client connection created for each send?

    Why is a new client connection created for each send?

    I'm not a networking expoert but I wondered why for each send a new client connection (Dial) is created. I thought the connection could be created once per client and reuse it for sending. Wouldn't this be more efficient?

  • Added server SendTo method

    Added server SendTo method

    This pull request allows bidirectional communication. To enabled this a SendTo (analogue to PacketConn.WriteTo) was added to the Server struct. Now it is possible to both send messages to a server and receive its answers on the same port.

    Further changes:

    • Store current connection in Server and use it. Therefor a SetConnection method was added as well and net.PacketConn parameters were removed.
    • Added Server.Listen(): enable the listening port, but do not start the Serve() loop yet. Useful if you send a message before listening for responses.
    • Packet.SenderAddress(): returns sender address (or nil) for the current message or bundle. This is necessary so a server can send responses to the correct address.
  • Answer from server

    Answer from server

    I have an remote OSC-Server which cends state information back to a client. I cannot seem to find a way to listen for a reply for a msg sent by a client.

    oscC := osc.NewClient("127.0.0.1", 9000)
    if err := oscC.Send(osc.NewMessage("/system/server-info")); err != nil {
        fmt.Println(err)
    }
    
    // How to receive the servers reply?
    
Go library for hardware I/O control, in the programming style of Arduino

hwio Introduction hwio is a Go library for interfacing with hardware I/O, particularly on SoC-based boards such as BeagleBone Black, Raspberry Pi and

Dec 9, 2022
Library for interacting with LLVM IR in pure Go.

llvm Library for interacting with LLVM IR in pure Go. Introduction Introductory blog post "LLVM IR and Go" Our Document Installation go get -u github.

Dec 28, 2022
simple bank which is implemented using Golang

Banker The service that we’re going to build is a simple bank. It will provide APIs for the frontend to do following things: Create and manage bank ac

Nov 15, 2021
Let's Go is task sharing app implemented in golang.

Let's Go - A sample GO app Overview Let's Go is an HTTP server. It has various apis to play with. It is a small app that can group users of a company

Dec 13, 2021
Seekable ZSTD compression format implemented in Golang.

ZSTD seekable compression format implementation in Go Seekable ZSTD compression format implemented in Golang. This library provides a random access re

Jan 7, 2023
Control external Fan to cool down your raspi cluster
Control external Fan to cool down your raspi cluster

Fan control for Raspberry Pi This is a small project that I build in order to cool down my raspi home cluster The case I use have some external fans t

Dec 11, 2021
Configuration agent for BFE control plane

conf-agent conf-agent 说明 conf-agent 从 api-server 获取最新的配置并触发bfe热加载。 获取方式 获取 conf-agent 工具。获取 conf-agent 有多种方式: 在 releases 页面下载对应平台的可执行文件 通过 go get 工具本地

Oct 28, 2022
Joy2Mouse is a program that allows you to control your computer mouse with a joystick.
Joy2Mouse is a program that allows you to control your computer mouse with a joystick.

Joy2Mouse Joy2Mouse is a program that allows you to control your computer mouse with a joystick. Features Control your mouse with a joystick Mouse dow

Dec 26, 2021
Control QEMU like magic!
Control QEMU like magic!

Qemantra Qemantra is a command-line tool for creating and managing QEMU Virtual Machines. QEMU is better and sometimes faster than VirtualBox , but do

Dec 26, 2022
FreeDesktop.org (xdg) Specs implemented in Go

xdg Package xdg provides access to the FreeDesktop.org (XDG) specs. Documentation Documentation is available via godoc. Here are direct links to the d

Nov 11, 2022
Go specs implemented as a scripting language in Rust.

Goscript A script language like Python or Lua written in Rust, with exactly the same syntax as Go's. The Goal Runs most pure Go code, probably add som

Jan 8, 2023
A Simple Bank Web Service implemented in Go, HTTP & GRPC, PostgreSQL, Docker, Kubernetes, GitHub Actions CI

simple-bank Based on this Backend Master Class by TECH SCHOOL: https://youtube.com/playlist?list=PLy_6D98if3ULEtXtNSY_2qN21VCKgoQAE Requirements Insta

Dec 9, 2021
QuickAbeHiroshi - The golang program to open a web site which is the fastest in the world
QuickAbeHiroshi - The golang program to open a web site which is the fastest in the world

The golang program to open a web site which is the fastest in the world.

Jan 2, 2022
An open source gitlab linting utility

gitlab-lint API and collector An open source gitlab linting utility Frontend https://github.com/globocom/gitlab-lint-react How to install Install depe

Oct 31, 2022
OTS: Open Terraforming Server
 OTS: Open Terraforming Server

OTS: Open Terraforming Server A prototype open source alternative to terraform enterprise

Jan 2, 2023
Neko is a cross-platform open-source animated cursor-chasing cat. This is the reimplementation write in Go.

Neko Neko is a cat that chases the mouse cursor across the screen, an app written in the late 1980s and ported for many platforms. This code is a re-i

Nov 21, 2022
A bin which will keep screen open by moving a mouse

Stay Awake This is a small program which will move mouse up and down to keep screen on. This stimulates like user is doing something. Motivation I had

Oct 21, 2021
Code snippets by first time open source contributors

Introduction Golang code snippets by first time open source contributors Rules How to contribute Add a folder and create your desired code snippet fil

Oct 6, 2021
Tidb - An open-source NewSQL database that supports Hybrid Transactional and Analytical Processing (HTAP) workloads
Tidb - An open-source NewSQL database that supports Hybrid Transactional and Analytical Processing (HTAP) workloads

What is TiDB? TiDB ("Ti" stands for Titanium) is an open-source NewSQL database

Jan 5, 2022