DOKK / manpages / debian 12 / libprotocol-osc-perl / Protocol::OSC.3pm.en
Protocol::OSC(3pm) User Contributed Perl Documentation Protocol::OSC(3pm)

Protocol::OSC - Open Sound Control v1.1 implementation

    my $osc = Protocol::OSC->new;
    my $data = $osc->message(qw(/echo isf 3 ping 3.14)); # pack
    my $packet = $osc->parse($data); # parse
    $osc->actions->{$path} = $code_ref; # add callback
    $packet->process($data, $scheduler_coderef); # parse and execute callbacks

This module implements (de)coding and processing of OSC packets according the specification. It's pure Perl implementation, yet faster than Net::LibLO and Net::OpenSoundControl (~2x). Also it provides connection agnostic interface and path matching and type tagging according OSC v1 specification <http://opensoundcontrol.org/spec-1_0> ( and v1.1 <http://opensoundcontrol.org/spec-1_1> )

Creates Protocol::Instance with optional "actions" argument which is hashref of pairs: path => coderef and optional default scheduler for "process" method - see below.

Encodes message to packet. Typetag supports these OSC-types: ifstdbht. Everything else (like TFNI) will not affect packing of @args. Alias: msg

Encodes bundle to packet. Pack several OSC messages/bundles to a bundle.

Parses OSC packet data. Returns OSC message/bundle. OSC-message is a blessed arrayref [$path, $type, @args] with corresponding methods path, type, args. OSC-bundle is a blessed arrayref [$time, @packets] with corresponding methods time, packets

Parses OSC packet/data and process messages in it. It will call matched actions through $scheduler_cb which is just "sub { $_[0]->(splice @_,1) }" by default(or specified in constructor). Arguments to scheduler are $action_coderef, $time, $action_path, $osc_msg, ?@osc_bundles.

Returns hashref of actions: path => coderef pairs. One could modify this hashref or use methods below.

Set coderef $cb to actions

Remove coderef at $path from actions at $path

Returns mathched actions in form of list of arrayrefs [$path, $coderef]

Converts (fractional) unix epoch time to NTP timestamp, which is list of ($seconds_since_1900_01_01, $int32_fraction_parts_of_second). If $unix_time is undef then (0,1) is returned which means immediate execution by OSC specs.

Reverse of previous.

Packs raw OSC data for (tcp) streaming.

Returns list of raw OSC data packets in $buf from stream buffer and residue of $buf. If $buf is incomplete - returns only $buf.

make packet

    my $data = $osc->message(my @specs = qw(/echo isf 3 ping 3.14));
    # or
    use Time::HiRes 'time';
    my $data $osc->bundle(time, [@specs], [@specs2], ...);

via UDP

    my $udp = IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => $port, Proto => 'udp', Type => SOCK_DGRAM) || die $!;
    $udp->send($data);

via TCP

    my $tcp = IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => $port, Proto => 'tcp', Type => SOCK_STREAM) || die $!;
    $tcp->syswrite($osc->to_stream($data));

UDP

    my $in = IO::Socket::INET->new( qw(LocalAddr localhost LocalPort), $port, qw(Proto udp Type), SOCK_DGRAM ) || die $!;
    $in->recv(my $packet, $in->sockopt(SO_RCVBUF));
    my $p = $osc->parse($packet);

TCP

    my $in = IO::Socket::INET->new( qw(LocalAddr localhost LocalPort), $port, qw(Proto tcp Type), SOCK_STREAM, qw(Listen 1 Reuse 1) ) || die $!;
    while (my $sock = $in->accept) {
        my $tail;
        while ($sock->sysread(my $buf, $in->sockopt(SO_RCVBUF))) {
            my @packets = $p->from_stream(length($tail) ? $tail.$buf : $buf);
            $tail = pop @packets;
            $osc->parse($_) for @packets;
        }
    }

    $osc->set_cb('/echo', sub {
        my ($at_time, $path, $msg, @maybe_bundles) = @_;
        say $at_time if $at_time; # time of parent bundle if message comes from bundle(s)
        say $path; # matched path
        say $msg->path; # path pattern of OSC message
        say $msg->type; # typetag
        say @{$msg->args}; # message arguments
        map { # all bundles from which $msg comes (from inner to outer)
            say $_->time; # time of bundle
            say $_->packets; # array of messages/bundle in bundle
        } @maybe_bundles;
    });
    ...
    $osc->process($osc->parse($data));

    use AnyEvent::Handle::UDP;
    my $udp_handle = AnyEvent::Handle::UDP->new(
        bind => [0, $port],
        on_recv => sub {
            my ($data, $handle, $client_addr) = @_;
            my $msg = $osc->parse($data);
            say $msg->path;
            $handle->push_send($osc->message(qw(/pong i), ($msg->args)[0]), $client_addr) if $msg->path eq '/ping';
        }
    );
    $udp_handle->push_send($osc->message(qw(/ping i 3)), [0, $port]);

encode

    cmpthese -1, {
        'Net::LibLO::Message' => sub { Net::LibLO::Message->new(qw(isf 3 laaaa 3.0)) },
        'Protocol::OSC' => sub { $protocol->message(qw(/echo isf 3 laaaa 3.0)) },
        'Net::OpenSoundControl' => sub { Net::OpenSoundControl::encode([qw(/echo i 3 s laaaa f 3.0)]) }
    };
    ...
                             Rate Net::LibLO::Message Net::OpenSoundControl Protocol::OSC
    Net::LibLO::Message   20479/s                  --                   -7%          -51%
    Net::OpenSoundControl 21920/s                  7%                    --          -48%
    Protocol::OSC         41754/s                104%                   90%            --

decode

    cmpthese -1, {
        'Protocol::OSC' => sub { $protocol->parse($data) },
        'Net::OpenSoundControl' => sub { Net::OpenSoundControl::decode($data) }
    };
                            Rate Net::OpenSoundControl         Protocol::OSC
    Net::OpenSoundControl 1630/s                    --                  -65%
    Protocol::OSC         4654/s                  186%                    --

NB

No validation checks performed

  • GitHub

    <http://github.com/vividsnow/Protocol-OSC>

  • Search MetaCPAN

    <https://metacpan.org/module/Protocol::OSC>

Yegor Korablev <egor@cpan.org>

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

more docs, examples and tests.. as usual )

Net::LibLO, Net::OpenSoundControl, AnyEvent::Handle::UDP

2018-12-21 perl v5.28.1