# osc

*Erlang support for the Open Sound Control protocol*

[![Build Status][gh-actions-badge]][gh-actions]
[![Erlang Versions][erlang-badge]][versions]

[![Project Logo][logo]][logo-large]

This is an implementation of the Open Sound Control (OSC) protocol written
in Erlang with OTP. The project provides the following:

* `osc_lib`: an API for encoding and decoding OSC messages
* `osc_client`: a manageed UDP client for OSC servers
* `osc`: an OTP application (release-baseed) for creeating custom OSC servers

For more information about OSC, see the links below in the 
[Resources](#resources) section.

## Setup

Include one of the following in your project's `rebar.config`: 

``` erlang
%% Latest Release
{deps, [
    {osc, {git, "", {tag, "2.1.0"}}}

%% Unstable
{deps, [
    {osc, {git, "", {branch, "release/2.2.x"}}}

## Encoding / Decoding OSC Messagees


## Connecting to OSC Servers

The following is a demonstration using the Erlang OSC server, but first we need
to add the default addresses to the server:

``` erlang
1> osc:add_addresses().

Now we can create a client connection manager and send a message to the default

``` erlang
2> osc_client:start().
3> {ok, Pid} = osc_client:connect("localhost", 2357).
4> osc_client:cast_msg(Pid, "/debug/log_message").

No value is expected from the server, so `cast_msg` is used.

The Erlang OSC server will then log the output:

``` erlang
=INFO REPORT==== 27-Nov-2020::14:02:22.687276 ===
Received message: []

Here's an example of connecting to a SuperCollider server:

``` erlang
1> osc_client:start().
2> {ok, Pid} = osc_client:connect("localhost", 57110).
3> osc_client:call_msg(Pid, "/status").

`call_msg` was used here since we expect a value back from the server.

For more example usage, you may be interested in viewing the source for the
LFE project [undertone]( While written in
LFE, it make extensive use of `osc_client` and might offer the curious coder
significant insights.

## Running Project Tests

    rebar3 as test check

## Running the Default Server

Start an interactive Erlang shell:

    rebar3 shell

Note: that will automatically start all the release dependency applications as
well as `osc` itself.

Then you can use the simple API for adding OSC addresses to the default server:

``` erlang
1> osc:get_addresses().
2> osc:add_addresses().
3> osc:get_addresses().
4> osc:remove_addresses().
5> osc:get_addresses().
See the `osc` module for example payloads in adding and removing OSC addresses.

## Using `erlsci/osc` Fork as Custom Server

Update the code in `apps/osc/src/osc.erl` to add the OSC addresses you want to
support (which will require creating the callback code those addreessese will
need). Update `osc_server:init` to call `osc:add_addresses/0` upon startup.

Create and run a release:

    rebar3 release
    cp -r _build/default/rel/osc INSTALL_DIR
    INSTALL_DIR/osc/bin/osc start
You can confirm `osc` is running with:

    INSTALL_DIR/osc/bin/osc ping
That should return `pong`.

To connect to the running release and get an interactive Erlang shell:

    INSTALL_DIR/osc/bin/osc attach
    Attaching to /tmp/erl_pipes/osc@MM-MAC-7744/erlang.pipe.1 (^D to exit)


## Resources

* [OSC]( on WikiPedia
* [Intro to OSC](
* Open Sound Control's [original home](
* [Controlling Ardour with OSC](
* [SuperCollider OSC Communication](
* [Overtone OSC source code](
* [OSC 1.0 Specification](

[//]: ---Named-Links---

[logo]: priv/images/logo-v2.png
[logo-large]: priv/images/logo-v2-large.png