Pd-extended and random-data streams

Here’s a little something I wrote to take the checksums from incoming data on a network and turn these into useful data in Pd-extended. We communicate the data via the OSC (OpenSoundControl) protocol.

This is a contrived example of taking an input from /dev/anywhere and turning it into some OSC data (OpenSoundControl).

This uses:

  • tcpdump
  • Some sort of fifo
  • Perl (to build our OSC packets)
  • Pd-extended

General outline:

+------+    +--------+    +---------+    +------------+
| data | => | regexp | => | package | => |   route/   |
+------+    +--------+    |   OSC   |    | unpack OSC |
                          +---------+    +------------+

Let’s grab the data

mkdir -p /tmp/fifo
mkfifo /tmp/fifo/tcpdump
tcpdump -i en1 -U -vv > /tmp/fifo/tcpdump
  • Makes a directory for our fifo (first-in-first-out)
  • Create a fifo
  • Begin dumping data from our interface to the fifo

You’ll likely have to change ‘en1’ to the address of your wireless interface.

If the command quits after a couple of seconds at this point - that’s fine. The fifo will block until the stream is being read by another process. We’ll come back to re-start the capture/dump once we’ve got everything else lined up.

munch it, crunch it and spit it back out

Create a Perl file anywhere. I’m messy, so I stick it inside of my ~/ directory. The following script takes the checksum (as hex) and pads it in the correct format for it to be unpackaged as an OSC control.

NOTE: OSC packets must pad each argument’s length to be a multiple of 4 bytes. That’s to say, in the argument /path/to/var 1 1000 we’d have to write /path/to/var\0\0\01\0\0\01000\0\0\0\0 to the socket Read the OSC Specifications for more info

#!/bin/perl -W
use strict;
use warnings;
use IO::Socket::INET;

my ($raw, $data, $var, $socket, $append);

# flush after every write
$| = 1;

sub padOSC {
        my $xPad;
        $xPad = "\0" x (4-(length($_[0])&3));
        return($_[0] . $xPad);
}

# Set up OSC Client interface
$socket = new IO::Socket::INET (
        PeerHost => 'localhost',
        PeerPort => '8889',
        Proto => 'udp',
) or die "ERROR 0x3 $!\n";
print "UDP OK\n";

open(FIFO, "< /tmp/fifo/tcpdump")
or die $!; while (<FIFO>) {
        my $raw = $_;
        $raw =~ /(cksum )(0x.{4})(.*)(length )(\d+)/;

        $data = padOSC("/filter/frequency") . padOSC(",s") . padOSC($2);

        print "\n Length: ".length($data);
        print "\n".$data;
                        print $socket "$data";
                }
close(FIFO);
$socket->close();

Pd-time!

Now, let’s give our data to Pd and do something useful with it. Let’s put together a simple little patch to bring this together.

You can download the following patch here.

NOTE The Perl script must be executed before the tcpdump commences (due to the fifo).