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).