Skip to content

Commit

Permalink
Change TCP packet length in header to 32-bit
Browse files Browse the repository at this point in the history
  • Loading branch information
haubie committed Oct 31, 2023
1 parent 95a3e25 commit 10a2c07
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ Below is a summary of key OSC concepts:

See `OSCx.Encoder.time/1` and [Time tags and synchronisation](time_tags.md).

## Examples
For some simple examples of using this library, see [Examples](examples.md) or the [OSCx Livebook tour](livebook/oscx_tour.livemd).

## Installation

### Adding it to your Elixir project
Expand Down
36 changes: 33 additions & 3 deletions lib/oscx.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ defmodule OSCx do
Note that this library is deliberately minimilistic and no network transport or process logic is included.
# Concepts, messages and bundles
## Concepts, messages and bundles
You can learn more about OSC and it's concepts and how to use this library by:
- accessing the [README file](README.md)
- taking the [Livebook tour](livebook/oscx_tour.livemd)
- browsing the simple [Examples](examples.md)
- reading the `OSCx.Message` or `OSCx.Bundle` module documentation
- reading about OSC [arguments and types](arguments_and_types.md)
## Example
### Example
To encode a basic message:
```
iex> my_message = %OSCx.Message{address: "/my_synth/volume", arguments: [0.25]}
Expand All @@ -34,18 +35,27 @@ defmodule OSCx do
iex> decoded_message = OSCx.decode(binary_message)
%OSCx.Message{address: "/my_synth/volume", arguments: [0.25]}
```
## TCP
If using TCP as the transport mechanism, append the `:tcp` atom to the encode function:
```
OSCx.encode(my_message_or_bundle, :tcp)
```
This frames the OSC packet with the message length in the header. This isn't required by UDP. See `encode/2` for more information.
"""

@doc """
Encodes an `%OSCx.Message{}` or `%OSCx.Bundle{}` struct as OSC binary data.
Takes as `%OSCx.Message{}` or `%OSCx.Bundle{}` as the first parameter.
## Example
```
# Encode a message
iex> %OSCx.Message{address: "/status", arguments: [1]} |> OSCx.encode()
<<47, 115, 116, 97, 116, 117, 115, 0, 44, 105, 0, 0, 0, 0, 0, 1>>
# Encode a bundle with a essage
# Encode a bundle with a message
iex> OSCx.Bundle.new(
elements: [OSCx.Message.new()],
time: %{seconds: 1, fraction: 100}
Expand All @@ -57,7 +67,22 @@ defmodule OSCx do
[<<0, 0, 0, 8, 47, 0, 0, 0, 44, 0, 0, 0>>]
]
```
## TCP
If using TCP as the transport mechansim, pass the `:tcp` atom as the second parameter:
```
OSCx.encode(my_message_or_bundle, :tcp)
```
This will prefix the length (byte size) of the OSC binary data in 32-bits.
This is because in stream-based protocols such as TCP, the outgoing OSC packets are required to be framed using the packet's length in the header.
This isn't needed if using UDP.
"""
def encode(message_or_bundle, :tcp), do: encode(message_or_bundle) |> prefix_size_for_tcp()
@spec encode(map()) :: binary()
def encode(message_or_bundle) when is_struct(message_or_bundle, OSCx.Message), do: OSCx.Message.encode(message_or_bundle)
def encode(message_or_bundle) when is_struct(message_or_bundle, OSCx.Bundle), do: OSCx.Bundle.encode(message_or_bundle)
def encode(_message_or_bundle), do: raise("Not a Message or Bundle. Only %OSCx.Messages{} and %OSCx.Bundles{} can be encoded.")
Expand All @@ -77,4 +102,9 @@ defmodule OSCx do
"""
def decode(<<35, 98, 117, 110, 100, 108, 101, 0, _rest::binary>>=message_or_bundle) when is_binary(message_or_bundle), do: OSCx.Bundle.decode(message_or_bundle)
def decode(message_or_bundle) when is_binary(message_or_bundle), do: OSCx.Message.decode(message_or_bundle)

# Helper method for TCP, prepends the size of the data as a 32-bit value

defp prefix_size_for_tcp(encoded_data), do: OSCx.Encoder.prefix_size(encoded_data, 32)

end
2 changes: 1 addition & 1 deletion lib/oscx/message.ex
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ defmodule OSCx.Message do
address <> tag_type_string <> arguments
end

@spec decode(any()) :: Message
@spec decode(binary()) :: %OSCx.Message{address: binary(), arguments: list()}
@doc """
Decodes a binary OSC message.
Expand Down

0 comments on commit 10a2c07

Please sign in to comment.