Recent Posts ¶

See all posts ordered by date

Pd-extended and random-data streams

Ronald MacDonald <> v1.0, Thu Oct 20 14:28:13 EST 2011

Edit, November 05, 2011: Come from Slashdot? Read this.

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 uses:
+------+    +--------+    +---------+    +------------+
| data | => | regexp | => | package | => |   route/   |
+------+    +--------+    |   OSC   |    | unpack OSC |
                          +---------+    +------------+

1. Let’s grab the data

mkdir -p /tmp/fifo
mkfifo /tmp/fifo/tcpdump
tcpdump -i en1 -U -vv > /tmp/fifo/tcpdump

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.

2. Let’s 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.


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 guide for more information.

(Download the source here)

#!/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";

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

Pd Patch: Receive UDP

You can download the above patch here: Bright orange is, obviously, amplitude. Mod is dividing the output. Moses gives us an option to limit the input.

4. Getting it all working

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