osc-crystal
osc-crystal
Open Sound Control implementation in Crystal.
This implementation is based on the The Open Sound Control 1.0 Specification and including some extensions (extra type-tag and dispatching).
Features
- Encode/Decode OSC message
- Support extra type-tags associated with the tyeps in Crystal
- On receiving message, matching the address patterns and callback concurrently
Arguments and Type Tags
This supports basic type tags and some additional ones that be shown below:
OSC Type Tag | Type in Crystal |
---|---|
i | Int32 |
f | Float32 |
s | String |
b | OSC::Type::Blob (alias of Array(UIn8) ) |
h | Int64 |
d | Float64 |
t | Time |
c | Char |
r | OSC::Type::RGBA |
m | OSC::Type::Midi |
T | OSC::Type::True |
F | OSC::Type::False |
N | Nil |
I | OSC::Type::Inf |
The type tags are determined by the type of each argument. See Usage.
Installation
-
Add the dependency to your
shard.yml
:dependencies: osc-crystal: github: astellon/osc-crystal
-
Run
shards install
Usage
Getting started, let's send an OSC Message via UDP soket to localhost.
require "osc-crystal"
# make message
m1 = OSC::Message.new("/addr", 0_i32)
# set up UDP server/client
server = UDPSocket.new
server.bind "localhost", 8000
client = UDPSocket.new
client.connect "localhost", 8000
# send message
client.send m1
# receive massage
message, client_addr = server.receive
# decode from bytes
m2 = OSC::Message.new(message.bytes)
# get argumanent
m2.arg(0) # => 0
The type tags are determined by the type of each argument like:
m = OSC::Message.new(
"/foo",
0_i32,
0_f32,
"String",
[0_u8, 0_u8, 0_u8, 0_u8],
0_i64,
0_f64,
Time.utc,
'0',
OSC::Type::RGBA.new(0_u8, 0_u8, 0_u8, 0_u8),
OSC::Type::Midi.new(0_u8, 0_u8, 0_u8, 0_u8),
OSC::Type::True,
OSC::Type::False,
Nil,
OSC::Type::Inf
)
m.address # => "/foo"
m.tag # => ifsbhdtcrmTFNI
m.arg(0) # => 0
The best way to handle the messages is to use OSC::Server
and OSC::Client
. You can specify the address and the process that will be involked when the given socket receives OSC messages. Example:
require "socket"
require "osc-crystal"
# set up UDP server/client and wrap sockets with OSC classes
server = UDPSocket.new
server.bind "localhost", 8000
osc_server = OSC::Server.new(server)
client = UDPSocket.new
client.connect "localhost", 8000
osc_client = OSC::Client.new(client)
# initialize `OSC::Message`s
m1 = OSC::Message.new(
"/*/*",
1_i32
)
m2 = OSC::Message.new(
"/*/hoge",
1_i32
)
# add methods for specific address
osc_server.dispatch("/foo/hoge") do |m|
puts "dispatched: /foo/hoge for #{m.address}"
end
osc_server.dispatch("/foo/fuga") do |m|
puts "dispatched: /foo/fuga for #{m.address}"
end
# run the server concurrently (return immediately)
osc_server.run
# send messages
osc_client.send m1
# => dispatched: /foo/hoge for /*/*
# dispatched: /foo/fuga for /*/*
osc_client.send m2
# => dispatched: /foo/hoge for /*/hoge
# Sleep a second
sleep(1)
client.close
server.close
Contributing
- Fork it (https://github.com/astellon/osc-crystal/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Astellon - creator and maintainer
- Tobaloidee - logo
osc-crystal
- 5
- 2
- 2
- 0
- 0
- about 2 years ago
- March 16, 2019
MIT License
Thu, 07 Nov 2024 12:33:40 GMT