[SCM] jack-tools/master: Imported Upstream version 20131226

raboof-guest at users.alioth.debian.org raboof-guest at users.alioth.debian.org
Sun Jan 5 21:41:04 UTC 2014


The following commit has been merged in the master branch:
commit 9de7815a316f20a32c433e5b09984017121bbe0a
Author: Arnout Engelen <arnouten at bzzt.net>
Date:   Sun Jan 5 21:33:27 2014 +0100

    Imported Upstream version 20131226

diff --git a/.boring b/.boring
index 1b76107..5b98240 100644
--- a/.boring
+++ b/.boring
@@ -1,24 +1,9 @@
-.deps
-.libs
-.*\.o$
-aclocal.m4
-autom4te.cache
-config/.*
-config.log
-config.status
-configure
-common/\.deps
-common/.*\.o
-common/Makefile
-jack\.dl$
-jack\.osc$
-jack\.play$
-jack\.plumbing$
-jack\.record$
-jack\.scope$
-jack\.transport$
-jack\.udp$
-libcommon.a
-libtool
-Makefile.in
-Makefile
+^jack-dl$
+^jack-osc$
+^jack-play$
+^jack-plumbing$
+^jack-record$
+^jack-scope$
+^jack-transport$
+^jack-udp$
+^c-common$
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..41feb23
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,39 @@
+prefix=$(HOME)/opt
+bin=jack-dl jack-osc jack-play jack-plumbing jack-record jack-scope jack-transport jack-udp
+
+CFLAGS=-Wall -D_POSIX_C_SOURCE=200112 -std=c99 -O3 -g
+LDLIBS=c-common/lib-c-common.a -ljack -lpthread -lm
+
+all: $(bin)
+
+jack-transport: jack-transport.c
+	gcc $(CFLAGS) -o jack-transport jack-transport.c $(LDLIBS) -lcurses
+
+jack-dl: jack-dl.c
+	gcc $(CFLAGS) -o jack-dl jack-dl.c $(LDLIBS) -ldl -llo
+
+jack-play: jack-play.c
+	gcc $(CFLAGS) -o jack-play jack-play.c $(LDLIBS) -lsndfile -lsamplerate
+
+jack-record: jack-record.c
+	gcc $(CFLAGS) -o jack-record jack-record.c $(LDLIBS) -lsndfile
+
+jack-scope: jack-scope.c
+	gcc $(CFLAGS) -o jack-scope jack-scope.c $(LDLIBS) -lX11 -lXext
+
+clean:
+	rm -f $(bin) *.o
+
+install:
+	cp $(bin) $(prefix)/bin
+	cp jack-dl.h $(prefix)/include
+
+uninstall:
+	(cd $(prefix)/bin ; rm -f $(bin))
+
+ln-local-c-common:
+	rm -f c-common
+	ln -s $(HOME)/sw/c-common c-common
+
+mk-local-c-common:
+	(cd c-common ; make)
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 0882c4e..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,67 +0,0 @@
-MAINTAINERCLEANFILES =	aclocal.m4	\
-			config.guess	\
-			config.log	\
-			config.status	\
-			config.sub	\
-			configure	\
-			depcomp		\
-			install-sh	\
-			ltmain.sh	\
-			Makefile.in	\
-			missing		\
-			mkinstalldirs
-
-SUBDIRS = common
-
-bin_PROGRAMS =	jack.dl \
-		jack.osc \
-		jack.play \
-		jack.plumbing \
-		jack.record \
-		jack.scope \
-		jack.transport \
-		jack.udp
-
-jack_dl_SOURCES = jack.dl.c
-jack_dl_LDADD = common/libcommon.a $(JACK_LIBS) $(LIBLO_LIBS)
-jack_dl_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) $(LIBLO_CFLAGS)
-
-jack_dl_includedir = $(includedir)
-jack_dl_include_HEADERS = jack.dl.h
-
-jack_osc_SOURCES = jack.osc.c
-jack_osc_LDADD = common/libcommon.a $(JACK_LIBS)
-jack_osc_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
-
-jack_play_SOURCES = jack.play.c
-jack_play_LDADD = common/libcommon.a $(JACK_LIBS) $(SNDFILE_LIBS) $(SRC_LIBS)
-jack_play_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) $(SNDFILE_CFLAGS) $(SRC_CFLAGS)
-
-jack_plumbing_SOURCES = jack.plumbing.c
-jack_plumbing_LDADD = common/libcommon.a $(JACK_LIBS)
-jack_plumbing_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
-
-jack_record_SOURCES = jack.record.c
-jack_record_LDADD = common/libcommon.a $(JACK_LIBS) $(SNDFILE_LIBS)
-jack_record_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) $(SNDFILE_CFLAGS) 
-
-jack_scope_SOURCES = jack.scope.c
-jack_scope_LDADD = common/libcommon.a $(JACK_LIBS) $(X11_LIBS) $(XEXT_LIBS)
-jack_scope_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) $(X11_CFLAGS) $(XEXT_CFLAGS)
-
-jack_transport_SOURCES = jack.transport.c
-jack_transport_LDADD = common/libcommon.a $(JACK_LIBS) -lncurses
-jack_transport_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
-
-jack_udp_SOURCES = jack.udp.c
-jack_udp_LDADD = common/libcommon.a $(JACK_LIBS)
-jack_udp_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
-
-docs_ASCIIDOC =	jack.osc.text \
-		jack.play.text \
-		jack.plumbing.text \
-		jack.record.text \
-		jack.scope.text \
-		jack.transport.text \
-		jack.udp.text
-EXTRA_DIST = $(docs_ASCIIDOC) help/sin.c help/sin.scm 
diff --git a/README b/README
index 8a829f1..1e9dea9 100644
--- a/README
+++ b/README
@@ -1,25 +1,55 @@
-jack.* - jackd[1] utilities
-
-jack.dl        - load dsp algorithms from shared libraries
-jack.osc       - jack <-> open sound control (osc[4]) daemon
-jack.play      - soundfile[2] playback
-jack.plumbing  - plumbing daemon
-jack.record    - soundfile recording
-jack.scope     - plain X oscilloscope
-jack.transport - minimalist ncurses jack transport
-jack.udp       - jack over udp client (obsolete, see netjack[3])
-
-Documentation is in asciidoc[5] format.  To build type:  
-  
-  for i in *.text ; do asciidoc $i; done
-
-[1] http://jackaudio.org/
-[2] http://mega-nerd.com/libsndfile/
-[3] http://netjack.org/
-[4] http://opensoundcontrol.org/
-[5] http://www.methods.co.nz/asciidoc/
-
-(c) rohan drape 2003-2010
-    gpl, http://www.gnu.org/copyleft/
-    with contributions by jeremy hall
-    see darcs history for details
+rju
+---
+
+[jackd][jackd] utilities
+
+---------------------------- --------------------------------------------------
+[jack-dl][-dl]               load dsp algorithms from shared libraries
+[jack-osc][-osc]             jack <-> open sound control ([osc][osc]) daemon
+[jack-play][-play]           [resampling][sr] [soundfile][sf] playback
+[jack-plumbing][-plumbing]   [plumbing][plumb] daemon
+[jack-record][-record]       soundfile recording
+[jack-scope][-scope]         plain [X][x] oscilloscope
+[jack-transport][-transport] minimalist [ncurses][curses] jack transport
+[jack-udp][-udp]             jack over udp client (obsolete, see [netjack][nj])
+---------------------------- --------------------------------------------------
+
+[-dl]: ?t=rju&m=jack-dl.text
+[-osc]: ?t=rju&m=jack-osc.text
+[-play]: ?t=rju&m=jack-play.text
+[-plumbing]: ?t=rju&m=jack-plumbing.text
+[-record]: ?t=rju&m=jack-record.text
+[-scope]: ?t=rju&m=jack-scope.text
+[-transport]: ?t=rju&m=jack-transport.text
+[-udp]: ?t=rju&m=jack-udp.text
+
+To build type:
+
+> make prefix=~/opt all install
+
+Documentation is in [asciidoc][ad] format, which is more or less
+interoperable with [markdown][markdown].  To build type:
+
+> for i in *.text ; do asciidoc $i; done
+
+[jackd]: http://jackaudio.org/
+[sf]: http://mega-nerd.com/libsndfile/
+[sr]: http://mega-nerd.com/libsamplerate/
+[nj]: http://netjack.sf.net/
+[osc]: http://opensoundcontrol.org/
+[ad]: http://methods.co.nz/asciidoc/
+[markdown]: http://daringfireball.net/projects/markdown/
+[x]: http://x.org
+[plumb]: http://plan9.bell-labs.com/sys/doc/plumb.html
+[curses]: http://gnu.org/software/ncurses/
+
+© [rohan drape][rd], 2003-2013, [gpl]. with contributions by:
+
+- jeremy hall
+
+see the [darcs][darcs] [history][history] for details
+
+[rd]: http://rd.slavepianos.org/
+[gpl]: http://gnu.org/copyleft/
+[darcs]: http://darcs.net/
+[history]:  http://rd.slavepianos.org/r/d/darcsweb.cgi?r=rju
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100644
index bdb5e9d..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-libtoolize --force 2>&1 | sed '/^You should/d' || {
-    echo "libtool failed, exiting..."
-    exit 1
-}
-
-aclocal $ACLOCAL_FLAGS || {
-    echo "aclocal \$ACLOCAL_FLAGS where \$ACLOCAL_FLAGS= failed, exiting..."
-    exit 1
-}
-
-automake --add-missing --foreign || {
-    echo "automake --add-missing --foreign failed, exiting..."
-    exit 1
-}
-
-autoconf || {
-    echo "autoconf failed, exiting..."
-    exit 1
-}
diff --git a/c-common/Makefile b/c-common/Makefile
new file mode 100644
index 0000000..d1471f9
--- /dev/null
+++ b/c-common/Makefile
@@ -0,0 +1,65 @@
+prefix = $(HOME)/opt
+obj =	alsa-seq-endpoint.o \
+	alsa-seq-listener.o \
+	alsa-seq-print.o \
+	alsa-seq-send.o \
+	bessel.o \
+	byte-order.o \
+	cfile.o \
+	client.o \
+	clip.o \
+	cq.o \
+	file.o \
+	gen-trapezoid.o \
+	gl-cube.o \
+	gl-sphere.o \
+	glu-screen-capture.o \
+	img.o \
+	img-ppm.o \
+	jack-client.o \
+	jack-port.o \
+	jack-ringbuffer.o \
+	jack-transport.o \
+	memory.o \
+	network.o \
+	observe-signal.o \
+	osc.o \
+	plane.o \
+	quantize.o \
+	rand.o \
+	rgba.o \
+	segment-transfer.o \
+	signal-clip.o \
+	signal-copy.o \
+	signal-interleave.o \
+	signal-interpolate.o \
+	signal-print.o \
+	sound-file.o \
+	taus88.o \
+	time-current.o \
+	time-ntp.o \
+	time-timespec.o \
+	time-timeval.o \
+	trace.o \
+	vector.o \
+	window.o \
+	ximg.o \
+	xregcomp.o
+
+%.o : %.c %.h
+	gcc -Wall -O2 -c $*.c
+
+all: $(obj)
+	ar -rcs lib-c-common.a $(obj)
+
+clean:
+	rm -f *.o *.a
+
+install:
+	cp lib-c-common.a $(prefix)/lib
+	mkdir -p $(prefix)/include/c-common
+	cp *.h $(prefix)/include/c-common
+
+uninstall:
+	rm -f $(prefix)/lib/lib-c-common.a
+	rm -Rf $(prefix)/include/c-common
diff --git a/c-common/README b/c-common/README
new file mode 100644
index 0000000..45fb213
--- /dev/null
+++ b/c-common/README
@@ -0,0 +1,14 @@
+c-common
+--------
+
+library of functions common to [c][c] projects
+
+tested-with: [gcc][gcc] 4.6.2
+
+[c]: http://www.open-std.org/jtc1/sc22/wg14/
+[gcc]: http://gcc.gnu.org/
+
+© [rohan drape][rd], 2003-2013, [gpl]
+
+[rd]: http://rd.slavepianos.org/
+[gpl]: http://gnu.org/copyleft/
diff --git a/c-common/alsa-seq-endpoint.c b/c-common/alsa-seq-endpoint.c
new file mode 100644
index 0000000..f78d543
--- /dev/null
+++ b/c-common/alsa-seq-endpoint.c
@@ -0,0 +1,220 @@
+#include <alsa/asoundlib.h>
+
+#include "alsa-seq-endpoint.h"
+#include "failure.h"
+#include "print.h"
+
+/* Write the number of source and destination endpoints to respective
+   counter locations. */
+
+void alsa_seq_endpoint_count(snd_seq_t *seq, int *source_n, int *destination_n)
+{
+  *source_n = 0;
+  *destination_n = 0;
+
+  snd_seq_client_info_t *c;
+  snd_seq_client_info_malloc(&c);
+  snd_seq_client_info_set_client(c, -1);
+
+  snd_seq_port_info_t *p;
+  snd_seq_port_info_malloc(&p);
+
+  while(snd_seq_query_next_client(seq, c) >= 0) {
+    int  client;
+    client = snd_seq_client_info_get_client(c);
+
+    snd_seq_port_info_set_client(p, client);
+    snd_seq_port_info_set_port(p, -1);
+    while(snd_seq_query_next_port(seq, p) >= 0) {
+
+      int  capability;
+      capability = snd_seq_port_info_get_capability(p);
+      if(capability & SND_SEQ_PORT_CAP_READ) {
+	*source_n += 1;
+      }
+      if(capability & SND_SEQ_PORT_CAP_WRITE) {
+	*destination_n += 1;
+      }
+    }
+  }
+
+  snd_seq_client_info_free(c);
+  snd_seq_port_info_free(p);
+
+  return;
+}
+
+/* Write the name of the endpoint `e' to `device_name' and
+   `port_name'. */
+
+void alsa_seq_endpoint_name(snd_seq_t *seq, const alsa_seq_endpoint_t *e,
+			    char *device_name, char *port_name, int size)
+{
+  snd_seq_client_info_t *c;
+  snd_seq_client_info_malloc(&c);
+  snd_seq_get_any_client_info( seq, e->client, c);
+  if(device_name) {
+    strncpy(device_name, snd_seq_client_info_get_name(c), size);
+  }
+  snd_seq_client_info_free(c);
+
+  snd_seq_port_info_t *p;
+  snd_seq_port_info_malloc(&p);
+  snd_seq_get_any_port_info( seq, e->client, e->port, p);
+  if(port_name) {
+    strncpy(port_name, snd_seq_port_info_get_name(p), size);
+  }
+  snd_seq_port_info_free(p);
+
+  return;
+}
+
+/* Print the endpoint `e' to stderr. */
+
+void alsa_seq_endpoint_print(snd_seq_t *seq, const alsa_seq_endpoint_t *e)
+{
+  const int size = 512;
+  char client_name[size];
+  char port_name[size];
+  alsa_seq_endpoint_name(seq, e, client_name, port_name, size);
+  eprintf("Endpoint:\n");
+  eprintf("  Client      : %d, '%s'\n", e->client, client_name);
+  eprintf("  Port        : %d, '%s'\n", e->port, port_name);
+  eprintf("  Source      : %s\n", e->source ? "Yes" : "No");
+  eprintf("  Destination : %s\n", e->destination ? "Yes" : "No");
+}
+
+/* Print the `e_n' endpoints at `e' to stderr. */
+
+void alsa_seq_endpoint_print_set(snd_seq_t *seq,
+				 const alsa_seq_endpoint_t *e, int e_n)
+{
+  int i;
+  for(i = 0; i < e_n; i++) {
+    alsa_seq_endpoint_print(seq, e + i);
+  }
+}
+
+/* Allocate required memory and read the set of endpoints at `seq'
+   into `source' and `destination.  This allows endpoints to be
+   addressed using zero indexed <integer> values. */
+
+void alsa_seq_endpoint_read(snd_seq_t *seq,
+			    alsa_seq_endpoint_t **source,
+			    int *source_n,
+			    alsa_seq_endpoint_t **destination,
+			    int *destination_n)
+{
+  alsa_seq_endpoint_count(seq, source_n, destination_n);
+
+  alsa_seq_endpoint_t *s;
+  s = malloc(*source_n * sizeof(alsa_seq_endpoint_t));
+
+  alsa_seq_endpoint_t *d;
+  d = malloc(*destination_n * sizeof(alsa_seq_endpoint_t));
+
+  snd_seq_client_info_t *c;
+  snd_seq_client_info_malloc(&c);
+  snd_seq_client_info_set_client(c, -1);
+
+  snd_seq_port_info_t *p;
+  snd_seq_port_info_malloc(&p);
+
+  int s_n;
+  s_n = 0;
+
+  int d_n;
+  d_n = 0;
+
+  while(snd_seq_query_next_client(seq, c) >= 0) {
+    int  client;
+    client = snd_seq_client_info_get_client(c);
+
+    snd_seq_port_info_set_client(p, client);
+    snd_seq_port_info_set_port(p, -1);
+
+    while(snd_seq_query_next_port(seq, p) >= 0) {
+      alsa_seq_endpoint_t e;
+      e.client = snd_seq_port_info_get_client(p);
+      e.port = snd_seq_port_info_get_port(p);
+
+      int  capability;
+      capability = snd_seq_port_info_get_capability(p);
+      e.source = capability & SND_SEQ_PORT_CAP_READ;
+      e.destination = capability & SND_SEQ_PORT_CAP_WRITE;
+
+      if(e.source) {
+	s[s_n] = e;
+	s_n += 1;
+	if(s_n > *source_n) {
+	  eprintf("%s: source endpoint race triggered\n", __func__);
+	  FAILURE;
+	}
+      }
+
+      if(e.destination) {
+	d[d_n] = e;
+	d_n += 1;
+	if(d_n > *destination_n) {
+	  eprintf("%s: destination endpoint race triggered\n", __func__);
+	  FAILURE;
+	}
+      }
+    }
+  }
+
+  snd_seq_client_info_free(c);
+  snd_seq_port_info_free(p);
+
+  *source = s;
+  *destination = d;
+
+  return;
+}
+
+/* Establish a connection from each of the source endpoints to
+   indicated port at `seq'. */
+
+void alsa_seq_endpoint_connect_from(snd_seq_t *seq, int port,
+				    const alsa_seq_endpoint_t *e, int e_n)
+{
+  int self;
+  self = snd_seq_client_id(seq);
+  int i;
+  for(i = 0; i < e_n; i++) {
+    if(e[i].source && e[i].client != self) {
+      snd_seq_connect_from(seq, port, e[i].client, e[i].port);
+    }
+  }
+}
+
+/* Establish a connection to each of the destination endpoints from
+   indicated port at `seq'. */
+
+void
+alsa_seq_endpoint_connect_to(snd_seq_t *seq, int port,
+			     const alsa_seq_endpoint_t *e, int e_n)
+{
+  int self;
+  self = snd_seq_client_id(seq);
+  int i;
+  for(i = 0; i < e_n; i++) {
+    if(e[i].source && e[i].client != self) {
+      snd_seq_connect_to(seq, port, e[i].client, e[i].port);
+    }
+  }
+}
+
+/* Get the index of of the endpoint for 'client' and 'port'. */
+
+int alsa_seq_endpoint_index(const alsa_seq_endpoint_t *e, int e_n,
+			    int client, int port)
+{
+  int i;
+  for(i = 0; i < e_n; i++) {
+    if(e[i].client == client && e[i].port == port) {
+      return i;
+    }
+  }
+  return -1;
+}
diff --git a/c-common/alsa-seq-endpoint.h b/c-common/alsa-seq-endpoint.h
new file mode 100644
index 0000000..607c308
--- /dev/null
+++ b/c-common/alsa-seq-endpoint.h
@@ -0,0 +1,46 @@
+#ifndef _COMMON_ALSA_SEQ_ENDPOINT_H
+#define _COMMON_ALSA_SEQ_ENDPOINT_H
+
+#include <stdbool.h>
+#include <alsa/asoundlib.h>
+
+typedef struct
+{
+  int client;
+  int port;
+  bool source;
+  bool destination;
+} alsa_seq_endpoint_t;
+
+void
+alsa_seq_endpoint_count(snd_seq_t *seq, int *source_n, int *destination_n);
+
+void
+alsa_seq_endpoint_name(snd_seq_t *seq, const alsa_seq_endpoint_t *e,
+		       char *device_name, char *port_name, int size);
+
+void
+alsa_seq_endpoint_print(snd_seq_t *seq, const alsa_seq_endpoint_t *e);
+
+void
+alsa_seq_endpoint_print_set(snd_seq_t *seq, const alsa_seq_endpoint_t *e, int e_n);
+
+void
+alsa_seq_endpoint_read(snd_seq_t *seq,
+		       alsa_seq_endpoint_t **source, int *source_n,
+		       alsa_seq_endpoint_t **destination, int *destination_n);
+
+void
+alsa_seq_endpoint_connect_from(snd_seq_t *seq, int port,
+			       const alsa_seq_endpoint_t *e, int e_n);
+
+void
+alsa_seq_endpoint_connect_to(snd_seq_t *seq, int port,
+			     const alsa_seq_endpoint_t *e, int e_n);
+
+int
+alsa_seq_endpoint_index(const alsa_seq_endpoint_t *e, int e_n,
+			int client, int port);
+
+#endif
+
diff --git a/c-common/alsa-seq-listener.c b/c-common/alsa-seq-listener.c
new file mode 100644
index 0000000..813890b
--- /dev/null
+++ b/c-common/alsa-seq-listener.c
@@ -0,0 +1,51 @@
+#include <pthread.h>
+#include <alsa/asoundlib.h>
+
+#include "alsa-seq-listener.h"
+#include "int.h"
+#include "print.h"
+
+/* ALSA provides a blocking read interface for midi data.  Create a
+   thread that will listen at an input port and pass incoming packets
+   to `reciever'. */
+
+void alsa_seq_listener_debug_receiver(void *context, const snd_seq_event_t *event,
+				      const u8 *data, int data_n)
+{
+  dprintf("%s: received packet: context=%p, event=%p, data=%p, data_n=%d\n",
+	  __func__, context, event, data, data_n);
+}
+
+void *alsa_seq_listener_thread(void *PTR)
+{
+  alsa_seq_listener_t *l = (alsa_seq_listener_t *) PTR;
+  while(true) {
+    snd_seq_event_t *e;
+    snd_seq_event_input(l->seq, &e);
+    dprintf("%s: event received: e=%p\n", __func__, e);
+    if(snd_seq_ev_is_channel_type(e) || e->type == SND_SEQ_EVENT_SYSEX) {
+      int data_extent = 512;
+      u8 data[data_extent];
+      int data_n;
+      data_n = snd_midi_event_decode(l->decoder, data, data_extent, e);
+      l->receiver(l->context, e, data, data_n);
+    }
+  }
+  return NULL;
+}
+
+pthread_t alsa_seq_listener(snd_seq_t *seq,
+			    snd_midi_event_t *decoder,
+			    alsa_seq_listener_recv_t receiver,
+			    void *context)
+{
+  pthread_t thread;
+  alsa_seq_listener_t *l;
+  l = malloc(sizeof(alsa_seq_listener_t));
+  l->seq = seq;
+  l->decoder = decoder;
+  l->receiver = receiver;
+  l->context = context;
+  pthread_create(&(thread), NULL, alsa_seq_listener_thread, l);
+  return thread;
+}
diff --git a/c-common/alsa-seq-listener.h b/c-common/alsa-seq-listener.h
new file mode 100644
index 0000000..03dd6bb
--- /dev/null
+++ b/c-common/alsa-seq-listener.h
@@ -0,0 +1,29 @@
+#ifndef _COMMON_ALSA_SEQ_LISTENER_H
+#define _COMMON_ALSA_SEQ_LISTENER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <alsa/asoundlib.h>
+
+typedef void (*alsa_seq_listener_recv_t) (void *,const snd_seq_event_t *,const unsigned char *, int);
+
+typedef struct
+{
+  snd_seq_t *seq;
+  snd_midi_event_t *decoder;
+  alsa_seq_listener_recv_t receiver;
+  void *context;
+} alsa_seq_listener_t;
+
+
+void alsa_seq_listener_debug_receiver(void *context, const snd_seq_event_t *event,
+				      const unsigned char *data, int data_n);
+
+void *alsa_seq_listener_thread(void *PTR);
+
+pthread_t alsa_seq_listener(snd_seq_t *seq, snd_midi_event_t *decoder,
+			    alsa_seq_listener_recv_t receiver, void *context);
+
+#endif
diff --git a/c-common/alsa-seq-print.c b/c-common/alsa-seq-print.c
new file mode 100644
index 0000000..109c030
--- /dev/null
+++ b/c-common/alsa-seq-print.c
@@ -0,0 +1,28 @@
+#include <alsa/asoundlib.h>
+
+#include "alsa-seq-print.h"
+#include "print.h"
+
+/* Print some basic system information to stderr. */
+
+void alsa_seq_print_system_info(snd_seq_t *seq)
+{
+  snd_seq_system_info_t *info;
+  snd_seq_system_info_malloc(&info);
+  snd_seq_system_info(seq, info);
+  eprintf("System Information:\n");
+  eprintf("Number of queues          : %d\n",
+	  snd_seq_system_info_get_queues(info));
+  eprintf("Number of clients         : %d\n",
+	  snd_seq_system_info_get_clients(info));
+  eprintf("Number of ports           : %d\n",
+	  snd_seq_system_info_get_ports(info));
+  eprintf("Number of channels        : %d\n",
+	  snd_seq_system_info_get_channels(info));
+  eprintf("Number of current clients : %d\n",
+	  snd_seq_system_info_get_cur_clients(info));
+  eprintf("Number of current queues  : %d\n",
+	  snd_seq_system_info_get_cur_queues(info));
+  snd_seq_system_info_free(info);
+  return;
+}
diff --git a/c-common/alsa-seq-print.h b/c-common/alsa-seq-print.h
new file mode 100644
index 0000000..5c3ba2f
--- /dev/null
+++ b/c-common/alsa-seq-print.h
@@ -0,0 +1,8 @@
+#ifndef _COMMON_ALSA_SEQ_PRINT_H
+#define _COMMON_ALSA_SEQ_PRINT_H
+
+#include <alsa/asoundlib.h>
+
+void alsa_seq_print_system_info(snd_seq_t *seq);
+
+#endif
diff --git a/c-common/alsa-seq-send.c b/c-common/alsa-seq-send.c
new file mode 100644
index 0000000..1b5ef76
--- /dev/null
+++ b/c-common/alsa-seq-send.c
@@ -0,0 +1,72 @@
+#include <alsa/asoundlib.h>
+
+#include "alsa-seq-send.h"
+#include "int.h"
+#include "print.h"
+
+/* Make a basic seq queue. */
+int alsa_seq_make_default_queue(snd_seq_t *seq)
+{
+  int queue;
+  queue = snd_seq_alloc_queue(seq);
+  snd_seq_start_queue(seq, queue, 0);
+  snd_seq_drain_output(seq);
+  return queue;
+}
+
+/* Apart from setting the event destination, all the code for _send
+   and _send_to is shared. */
+static void alsa_seq_send_common(snd_seq_t *seq, int queue,
+				 int src_port,
+				 snd_midi_event_t *encoder,
+				 u8 *c, int n,
+				 snd_seq_event_t e)
+{
+  if(n <= 0) {
+    eprintf("%s: empty packet\n", __func__);
+    return;
+  }
+  snd_seq_real_time_t time;
+  int err;
+  snd_seq_ev_set_source(&e, src_port);
+  snd_midi_event_reset_encode(encoder);
+  err = snd_midi_event_encode(encoder, c, n, &e);
+  if(err < 0 || e.type == SND_SEQ_EVENT_NONE) {
+    eprintf("%s: encoding failed: %s\n", __func__, snd_strerror(errno));
+    return;
+  }
+  time.tv_sec = time.tv_nsec = 0;
+  snd_seq_ev_schedule_real( &e, queue, 1, &time);
+  err = snd_seq_event_output_direct(seq, &e);
+  if(err < 0) {
+    eprintf("%s: output failed: %s\n", __func__, snd_strerror(errno));
+    return;
+  }
+}
+
+/* Encode the MIDI data at `c' as an ALSA sequencer event and send it
+   to the registered subscribers. */
+void alsa_seq_send(snd_seq_t *seq, int queue,
+		   int src_port,
+		   snd_midi_event_t *encoder,
+		   u8 *c, int n)
+{
+  snd_seq_event_t e;
+  snd_seq_ev_clear(&e);
+  snd_seq_ev_set_subs(&e);
+  alsa_seq_send_common(seq, queue, src_port, encoder, c, n , e);
+}
+
+/* Encode the MIDI data at `c' as an ALSA sequencer event and send it
+   to indicated destination port. */
+void alsa_seq_send_to(snd_seq_t *seq, int queue,
+		      int src_port,
+		      int dst_client, int dst_port,
+		      snd_midi_event_t *encoder,
+		      u8 *c, int n)
+{
+  snd_seq_event_t e;
+  snd_seq_ev_clear(&e);
+  snd_seq_ev_set_dest(&e, dst_client, dst_port);
+  alsa_seq_send_common(seq, queue, src_port, encoder, c, n , e);
+}
diff --git a/c-common/alsa-seq-send.h b/c-common/alsa-seq-send.h
new file mode 100644
index 0000000..3803009
--- /dev/null
+++ b/c-common/alsa-seq-send.h
@@ -0,0 +1,20 @@
+#ifndef _COMMON_ALSA_SEQ_SEND_H
+#define _COMMON_ALSA_SEQ_SEND_H
+
+#include <alsa/asoundlib.h>
+#include "int.h"
+
+int alsa_seq_make_default_queue(snd_seq_t *seq);
+
+void alsa_seq_send(snd_seq_t *seq, int queue,
+		   int port,
+		   snd_midi_event_t *encoder,
+		   u8 *c, int n ) ;
+
+void alsa_seq_send_to(snd_seq_t *seq, int queue,
+		      int src_port,
+		      int dst_client, int dst_port,
+		      snd_midi_event_t *encoder,
+		      u8 *c, int n);
+
+#endif
diff --git a/c-common/bessel.c b/c-common/bessel.c
new file mode 100644
index 0000000..600c8f7
--- /dev/null
+++ b/c-common/bessel.c
@@ -0,0 +1,35 @@
+#include <math.h>
+#include "bessel.h"
+
+float bessi0(float x)
+{
+    if (x == 0.0 || fabs(x) > 15.0)
+	return 1.0;
+    float z = x * x;
+    float numerator =
+	(z *
+	 (z *
+	  (z *
+	   (z *
+	    (z *
+	     (z *
+	      (z *
+	       (z *
+		(z *
+		 (z *
+		  (z *
+		   (z *
+		    (z *
+		     (z * 0.210580722890567e-22 + 0.380715242345326e-19) +
+		     0.479440257548300e-16) + 0.435125971262668e-13) +
+		   0.300931127112960e-10) + 0.160224679395361e-7) +
+		 0.654858370096785e-5) + 0.202591084143397e-2) +
+	       0.463076284721000e0) + 0.754337328948189e2) +
+	     0.830792541809429e4) + 0.571661130563785e6) +
+	   0.216415572361227e8) + 0.356644482244025e9) +
+	 0.144048298227235e10);
+    float denominator =
+	(z * (z * (z - 0.307646912682801e4) + 0.347626332405882e7) -
+	 0.144048298227235e10);
+    return -numerator / denominator;
+}
diff --git a/c-common/bessel.h b/c-common/bessel.h
new file mode 100644
index 0000000..03b86c4
--- /dev/null
+++ b/c-common/bessel.h
@@ -0,0 +1,6 @@
+#ifndef _COMMON_BESSEL_H
+#define _COMMON_BESSEL_H
+
+float bessi0(float x);
+
+#endif
diff --git a/common/byte-order.c b/c-common/byte-order.c
similarity index 94%
rename from common/byte-order.c
rename to c-common/byte-order.c
index 9b2535b..8f5b055 100644
--- a/common/byte-order.c
+++ b/c-common/byte-order.c
@@ -1,5 +1,3 @@
-/*  byte-order.c - (c) rohan drape, 2005-2006 */
-
 #include <string.h>
 
 #include "byte-order.h"
@@ -8,24 +6,24 @@
 #include "int.h"
 #include "print.h"
 
-u16 hton16(u16 n) 
-{ 
-  return htons(n); 
+u16 hton16(u16 n)
+{
+  return htons(n);
 }
 
-u16 ntoh16(u16 n) 
-{ 
-  return ntohs(n); 
+u16 ntoh16(u16 n)
+{
+  return ntohs(n);
 }
 
-u32 hton32(u32 n) 
-{ 
-  return htonl(n); 
+u32 hton32(u32 n)
+{
+  return htonl(n);
 }
 
-u32 ntoh32(u32 n) 
-{ 
-  return ntohl(n); 
+u32 ntoh32(u32 n)
+{
+  return ntohl(n);
 }
 
 u64 hton64(u64 n)
@@ -149,7 +147,7 @@ GENERATE_TNC_FROM_BUF(ntoh,f,64);
   {						\
     proc##_##tag##_to_buf((u8 *)&a,a);		\
     return a;					\
-  }  
+  }
 
 GENERATE_TNC(hton,u16);
 GENERATE_TNC(hton,i16);
diff --git a/common/byte-order.h b/c-common/byte-order.h
similarity index 97%
rename from common/byte-order.h
rename to c-common/byte-order.h
index f66ee17..fc31a0c 100644
--- a/common/byte-order.h
+++ b/c-common/byte-order.h
@@ -7,27 +7,27 @@
 #include "float.h"
 #include "int.h"
 
-typedef union 
-{ 
+typedef union
+{
   u16 u;
   i16 i;
-} 
+}
 n16_t;
 
-typedef union 
-{ 
+typedef union
+{
   u32 u;
   i32 i;
   f32 f;
-} 
+}
 n32_t;
 
-typedef union 
-{ 
+typedef union
+{
   u64 u;
   i64 i;
   f64 f;
-} 
+}
 n64_t;
 
 void byte_order_confirm(void);
diff --git a/c-common/cfile.c b/c-common/cfile.c
new file mode 100644
index 0000000..643ecaf
--- /dev/null
+++ b/c-common/cfile.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <stdint.h>
+#include "byte-order.h"
+#include "failure.h"
+#include "memory.h"
+
+FILE *xfopen(const char *filename, const char *opentype)
+{
+    FILE *fp = fopen(filename, opentype);
+    if (!fp) {
+	perror("fopen() failed");
+	FAILURE;
+    }
+    return fp;
+}
+
+size_t xfread(void *data, size_t size, size_t count, FILE * stream)
+{
+    size_t err = fread(data, size, count, stream);
+    if (err != count) {
+	fprintf(stderr, "fread() failed\n");
+	FAILURE;
+    }
+    return err;
+}
+
+#define GENERATE_NC_READ(tag)			\
+tag fread_##tag ( FILE *fp )			\
+{						\
+  tag n;					\
+  xfread(&n, 4, 1, fp);                         \
+  return ntoh_##tag (n);			\
+}
+
+GENERATE_NC_READ(u16);
+GENERATE_NC_READ(u32);
+GENERATE_NC_READ(u64);
+GENERATE_NC_READ(i16);
+GENERATE_NC_READ(i32);
+GENERATE_NC_READ(i64);
+GENERATE_NC_READ(f32);
+GENERATE_NC_READ(f64);
+
+char *fread_byte_string(FILE * fp, int n)
+{
+    char *s = xmalloc(n + 1);
+    s[n] = '\0';
+    xfread(s, 1, n, fp);
+    return s;
+}
diff --git a/c-common/cfile.h b/c-common/cfile.h
new file mode 100644
index 0000000..4825258
--- /dev/null
+++ b/c-common/cfile.h
@@ -0,0 +1,22 @@
+#ifndef _COMMON_CFILE_H
+#define _COMMON_CFILE_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include "byte-order.h"
+#include "failure.h"
+
+FILE *xfopen(const char *filename, const char *opentype);
+size_t xfread(void *data, size_t size, size_t count, FILE * stream);
+char *fread_byte_string(FILE * fp, int n);
+
+u16 fread_u16(FILE *fp);
+u32 fread_u32(FILE *fp);
+u64 fread_u64(FILE *fp);
+i16 fread_i16(FILE *fp);
+i32 fread_i32(FILE *fp);
+i64 fread_i64(FILE *fp);
+f32 fread_f32(FILE *fp);
+f64 fread_f64(FILE *fp);
+
+#endif
diff --git a/common/client.c b/c-common/client.c
similarity index 88%
rename from common/client.c
rename to c-common/client.c
index 0c58def..144ce75 100644
--- a/common/client.c
+++ b/c-common/client.c
@@ -1,5 +1,3 @@
-/*  client.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -43,8 +41,8 @@ void free_client_register(client_register_t *r)
   free(r);
 }
 
-void edit_client_register(client_register_t *r, 
-			  struct sockaddr_in addr, 
+void edit_client_register(client_register_t *r,
+			  struct sockaddr_in addr,
 			  i32 mask)
 {
   dprintf("edit_client_register: mask=%d\n", mask);
@@ -75,9 +73,9 @@ void edit_client_register(client_register_t *r,
   eprintf("edit_client_register: Client dropped.\n");
 }
 
-void sendto_client_register(int fd, 
-			    const client_register_t *r, 
-			    const u8 *packet, i32 packet_sz, 
+void sendto_client_register(int fd,
+			    const client_register_t *r,
+			    const u8 *packet, i32 packet_sz,
 			    i32 mask)
 {
   if(packet_sz) {
diff --git a/common/client.h b/c-common/client.h
similarity index 94%
rename from common/client.h
rename to c-common/client.h
index fe6b3f8..7efb03e 100644
--- a/common/client.h
+++ b/c-common/client.h
@@ -3,14 +3,14 @@
 
 #include "int.h"
 
-typedef struct 
+typedef struct
 {
   struct sockaddr_in address ;
   i32 mask ;
   i8 in_use ;
 } client_t ;
 
-typedef struct 
+typedef struct
 {
   client_t *c ;
   i32 n ;
diff --git a/c-common/clip.c b/c-common/clip.c
new file mode 100644
index 0000000..f0c54d9
--- /dev/null
+++ b/c-common/clip.c
@@ -0,0 +1,21 @@
+#include "clip.h"
+#include "int.h"
+#include "float.h"
+#include "vector.h"
+
+i32 clipi32(i32 n, i32 l, i32 r)
+{
+  if(n < l) return l; else if(n > r) return r; return n;
+}
+
+f32 clipf32(f32 n, f32 l, f32 r)
+{
+  if(n < l) return l; else if(n > r) return r; return n;
+}
+
+v32 clipv32(v32 v, f32 l, f32 r)
+{
+  return make_v32(clipf32(v.x, l, r),
+		  clipf32(v.y, l, r),
+		  clipf32(v.z, l, r));
+}
diff --git a/c-common/clip.h b/c-common/clip.h
new file mode 100644
index 0000000..a9781fc
--- /dev/null
+++ b/c-common/clip.h
@@ -0,0 +1,12 @@
+#ifndef _COMMON_CLIP_H
+#define _COMMON_CLIP_H
+
+#include "int.h"
+#include "float.h"
+#include "vector.h"
+
+i32 clipi32(i32 n, i32 l, i32 r);
+f32 clipf32(f32 n, f32 l, f32 r);
+v32 clipv32(v32 v, f32 l, f32 r);
+
+#endif
diff --git a/c-common/cq.c b/c-common/cq.c
new file mode 100644
index 0000000..a6d3750
--- /dev/null
+++ b/c-common/cq.c
@@ -0,0 +1,55 @@
+#include "cq.h"
+#include "signal-interpolate.h"
+
+/* cq = circular queue
+   n = buffer length
+   ri = read index
+   wi = write index
+   ai = absolute index
+   s = buffer */
+
+float cq_index(int n,float ri,int wi)
+{
+  float ai = ((float)wi - 1.0) - ri;
+  if(ai < 0.0) {
+    ai += (float)n;
+  }
+  return ai ;
+}
+
+int cq_index_i(int n,int ri,int wi)
+{
+  int ai = (wi - 1) - ri;
+  if(ai < 0) {
+    ai += n;
+  }
+  return ai;
+}
+
+float cq_access_i(float *s,int n,int ri,int wi)
+{
+  int i = cq_index_i(n,ri,wi);
+  return s[i];
+}
+
+float cq_access(float *s,int n,float ri,int wi)
+{
+  int i = cq_index(n,ri,wi);
+  return signal_interpolate(s,n,i);
+}
+
+void cq_increment_write_index(int n,int *wi)
+{
+  *wi += 1;
+  if(*wi >= n) {
+    *wi = 0;
+  }
+}
+
+float cq_update(float *s,int n,float i,int *wi)
+{
+  float j = s[*wi];
+  s[*wi] = i;
+  cq_increment_write_index(n,wi);
+  return j;
+}
diff --git a/c-common/cq.h b/c-common/cq.h
new file mode 100644
index 0000000..20313e5
--- /dev/null
+++ b/c-common/cq.h
@@ -0,0 +1,11 @@
+#ifndef _COMMON_CQ_H
+#define _COMMON_CQ_H
+
+float cq_index(int n,float ri,int wi);
+int cq_index_i(int n,int ri,int wi);
+float cq_access_i(float *s,int n,int ri,int wi);
+float cq_access(float *s,int n,float ri,int wi);
+void cq_increment_write_index(int n,int *wi);
+float cq_update(float *s,int n,float i,int *wi);
+
+#endif
diff --git a/common/failure.h b/c-common/failure.h
similarity index 100%
rename from common/failure.h
rename to c-common/failure.h
diff --git a/common/file.c b/c-common/file.c
similarity index 92%
rename from common/file.c
rename to c-common/file.c
index 95ac0d3..789c911 100644
--- a/common/file.c
+++ b/c-common/file.c
@@ -1,12 +1,10 @@
-/*  file.c - (c) rohan drape, 2005-2006 */
-
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
 #include <sys/stat.h>
 #include <stdint.h>
-#include <netinet/in.h> 
+#include <netinet/in.h>
 
 #include "memory.h"
 #include "failure.h"
@@ -49,7 +47,7 @@ ssize_t xwrite(int filedes, const void *buffer, size_t size)
   ssize_t err = write(filedes, buffer, size);
   if(err == -1) {
     perror("write() failed");
-    FAILURE; 
+    FAILURE;
   }
   return err;
 }
@@ -59,7 +57,7 @@ ssize_t xread(int filedes, void *buffer, size_t size)
   ssize_t err = read(filedes, buffer, size);
   if(err == -1) {
     perror("read() failed");
-    FAILURE; 
+    FAILURE;
   }
   return err;
 }
diff --git a/common/file.h b/c-common/file.h
similarity index 100%
rename from common/file.h
rename to c-common/file.h
diff --git a/common/float.h b/c-common/float.h
similarity index 100%
rename from common/float.h
rename to c-common/float.h
diff --git a/c-common/gen-trapezoid.c b/c-common/gen-trapezoid.c
new file mode 100644
index 0000000..ace00bf
--- /dev/null
+++ b/c-common/gen-trapezoid.c
@@ -0,0 +1,40 @@
+#include "float.h"
+#include "gen-trapezoid.h"
+
+/* Design a standard trapezoidal envelope.  `shape' determines the
+   sustain time as a proportion of the duration, zero is a triangular
+   envelope, one a rectangular envelope.  `skew' determines the
+   attack/decay ratio, zero is an immediate attack and a slow decay,
+   one a slow attack and an immediate decay.  */
+
+void
+gen_trapezoid (f32 *s,int n,f32 gain,f32 shape,f32 skew)
+{
+#if DEBUG
+  if (n != 8) {
+    return;
+  }
+#endif
+
+  /* x0,y0 */
+  s[0] = 0.0;
+  s[1] = 0.0;
+  if (skew + 1.0 <= 1.0) {
+    s[1] = gain;
+  }
+
+  /* x1,y1 */
+  s[2] = skew * (1.0 - shape);
+  s[3] = gain;
+
+  /* x2,y2 */
+  s[4] = shape + s[2];
+  s[5] = gain;
+
+  /* x3,y3 */
+  s[6] = 1.0;
+  s[7] = 0.0;
+  if (skew - 1.0 >= 0.0) {
+    s[7] = gain;
+  }
+}
diff --git a/c-common/gen-trapezoid.h b/c-common/gen-trapezoid.h
new file mode 100644
index 0000000..0e21041
--- /dev/null
+++ b/c-common/gen-trapezoid.h
@@ -0,0 +1,8 @@
+#ifndef _COMMON_GEN_TRAPEZOID_H
+#define _COMMON_GEN_TRAPEZOID_H
+
+#include "float.h"
+
+void gen_trapezoid(f32 *signal,int signal_n,f32 gain,f32 shape,f32 skew);
+
+#endif
diff --git a/c-common/gl-cube.c b/c-common/gl-cube.c
new file mode 100644
index 0000000..8bf1761
--- /dev/null
+++ b/c-common/gl-cube.c
@@ -0,0 +1,62 @@
+#include <GL/gl.h>
+#include "gl-cube.h"
+
+void cubel(void)
+{
+  glBegin(GL_LINES);
+  glVertex3f(-1.0, -1.0, -1.0);
+  glVertex3f(1.0, -1.0, -1.0);
+  glVertex3f(1.0, -1.0, -1.0);
+  glVertex3f(1.0, 1.0, -1.0);
+  glVertex3f(1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, -1.0);
+  glVertex3f(-1.0, -1.0, -1.0);
+  glVertex3f(-1.0, -1.0, 1.0);
+  glVertex3f(1.0, -1.0, 1.0);
+  glVertex3f(1.0, -1.0, 1.0);
+  glVertex3f(1.0, 1.0, 1.0);
+  glVertex3f(1.0, 1.0, 1.0);
+  glVertex3f(-1.0, 1.0, 1.0);
+  glVertex3f(-1.0, 1.0, 1.0);
+  glVertex3f(-1.0, -1.0, 1.0);
+  glVertex3f(-1.0, -1.0, -1.0);
+  glVertex3f(-1.0, -1.0, 1.0);
+  glVertex3f(1.0, -1.0, -1.0);
+  glVertex3f(1.0, -1.0, 1.0);
+  glVertex3f(1.0, 1.0, -1.0);
+  glVertex3f(1.0, 1.0, 1.0);
+  glVertex3f(-1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, 1.0);
+  glEnd();
+}
+
+void cubeq(void)
+{
+  glBegin(GL_QUADS);
+  glVertex3f(-1.0, -1.0, -1.0);
+  glVertex3f(-1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, 1.0);
+  glVertex3f(-1.0, -1.0, 1.0);
+  glVertex3f(1.0, -1.0, 1.0);
+  glVertex3f(1.0, 1.0, 1.0);
+  glVertex3f(1.0, 1.0, -1.0);
+  glVertex3f(1.0, -1.0, -1.0);
+  glVertex3f(-1.0, -1.0, -1.0);
+  glVertex3f(1.0, -1.0, -1.0);
+  glVertex3f(1.0, -1.0, 1.0);
+  glVertex3f(-1.0, -1.0, 1.0);
+  glVertex3f(-1.0, 1.0, 1.0);
+  glVertex3f(1.0, 1.0, 1.0);
+  glVertex3f(1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, -1.0);
+  glVertex3f(-1.0, -1.0, -1.0);
+  glVertex3f(1.0, -1.0, -1.0);
+  glVertex3f(1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, -1.0);
+  glVertex3f(-1.0, 1.0, 1.0);
+  glVertex3f(1.0, 1.0, 1.0);
+  glVertex3f(1.0, -1.0, 1.0);
+  glVertex3f(-1.0, -1.0, 1.0);
+  glEnd();
+}
diff --git a/c-common/gl-cube.h b/c-common/gl-cube.h
new file mode 100644
index 0000000..2f953f4
--- /dev/null
+++ b/c-common/gl-cube.h
@@ -0,0 +1,7 @@
+#ifndef _GL_CUBE_H
+#define _GL_CUBE_H
+
+void cubel(void);
+void cubeq(void);
+
+#endif
diff --git a/c-common/gl-sphere.c b/c-common/gl-sphere.c
new file mode 100644
index 0000000..dfaed7b
--- /dev/null
+++ b/c-common/gl-sphere.c
@@ -0,0 +1,13 @@
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include "gl-sphere.h"
+
+void spherel(void)
+{
+  int n = 16;
+  GLUquadric *q = gluNewQuadric();
+  gluQuadricDrawStyle(q, GLU_LINE);
+  gluQuadricNormals(q, GLU_SMOOTH);
+  gluSphere(q, 1.0, n, n);
+  gluDeleteQuadric(q);
+}
diff --git a/c-common/gl-sphere.h b/c-common/gl-sphere.h
new file mode 100644
index 0000000..48cf231
--- /dev/null
+++ b/c-common/gl-sphere.h
@@ -0,0 +1,6 @@
+#ifndef _GL_SPHERE_H
+#define _GL_SPHERE_H
+
+void spherel(void);
+
+#endif
diff --git a/c-common/glu-screen-capture.c b/c-common/glu-screen-capture.c
new file mode 100644
index 0000000..fb875ea
--- /dev/null
+++ b/c-common/glu-screen-capture.c
@@ -0,0 +1,19 @@
+#include <GL/glut.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "img-ppm.h"
+#include "memory.h"
+
+void glu_screen_capture(char *fn)
+{
+  int w = glutGet(GLUT_WINDOW_WIDTH);
+  int h = glutGet(GLUT_WINDOW_HEIGHT);
+  u8 *d = malloc(w * h * 3);
+  glPixelStorei(GL_PACK_ALIGNMENT, 1);
+  glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, d);
+  img_write_ppm_file(d, w, h, fn);
+  free(d);
+}
diff --git a/c-common/glu-screen-capture.h b/c-common/glu-screen-capture.h
new file mode 100644
index 0000000..9efb72d
--- /dev/null
+++ b/c-common/glu-screen-capture.h
@@ -0,0 +1,6 @@
+#ifndef _GLU_SCREEN_CAPTURE_H
+#define _GLU_SCREEN_CAPTURE_H
+
+void glu_screen_capture(char *fn);
+
+#endif
diff --git a/common/img-ppm.c b/c-common/img-ppm.c
similarity index 94%
rename from common/img-ppm.c
rename to c-common/img-ppm.c
index d943d20..9939202 100644
--- a/common/img-ppm.c
+++ b/c-common/img-ppm.c
@@ -1,5 +1,3 @@
-/*  img-ppm.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
@@ -24,7 +22,7 @@ i32 img_write_ppm_file(u8 *data, i32 w, i32 h, const char *name)
   }
   img_write_ppm(data, w, h, fp);
   fclose(fp);
-  return 0; 
+  return 0;
 }
 
 u8 *img_read_ppm(i32 *w, i32 *h, FILE *fp)
diff --git a/common/img-ppm.h b/c-common/img-ppm.h
similarity index 100%
rename from common/img-ppm.h
rename to c-common/img-ppm.h
diff --git a/common/img.c b/c-common/img.c
similarity index 94%
rename from common/img.c
rename to c-common/img.c
index 46db83f..1d506bc 100644
--- a/common/img.c
+++ b/c-common/img.c
@@ -1,5 +1,3 @@
-/*  img.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <string.h>
 #include <math.h>
diff --git a/common/img.h b/c-common/img.h
similarity index 100%
rename from common/img.h
rename to c-common/img.h
diff --git a/common/int.h b/c-common/int.h
similarity index 100%
rename from common/int.h
rename to c-common/int.h
diff --git a/common/jack-client.c b/c-common/jack-client.c
similarity index 95%
rename from common/jack-client.c
rename to c-common/jack-client.c
index 982ea47..728ce40 100644
--- a/common/jack-client.c
+++ b/c-common/jack-client.c
@@ -1,5 +1,3 @@
-/*  jack-client.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/common/jack-client.h b/c-common/jack-client.h
similarity index 100%
rename from common/jack-client.h
rename to c-common/jack-client.h
diff --git a/common/jack-port.c b/c-common/jack-port.c
similarity index 73%
rename from common/jack-port.c
rename to c-common/jack-port.c
index 23d630c..1b4620f 100644
--- a/common/jack-port.c
+++ b/c-common/jack-port.c
@@ -1,5 +1,3 @@
-/*  jack-port.c - (c) rohan drape, 2005-2010 */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -89,13 +87,35 @@ void jack_port_clear_all_connections(jack_client_t *j, const char *l)
   }
 }
 
-void jack_port_connect_pattern(jack_client_t *client, int n, char *src, char *dst)
+void jack_port_connect_pattern(jack_client_t *client, int n, int k, char *src, char *dst)
 {
   int i;
   for(i = 0; i < n; i++) {
     char src_name[64],dst_name[64];
-    snprintf(src_name, 64, src, i + 1);
+    snprintf(src_name, 64, src, i + k + 1);
     snprintf(dst_name, 64, dst, i + 1);
     jack_port_connect_named(client,src_name,dst_name);
   }
 }
+
+void jack_port_connect_to_env(jack_client_t *c, int n, int k, char *env)
+{
+  char *dst_pattern = getenv(env);
+  if (dst_pattern) {
+    char src_pattern[128];
+    char *c_name = jack_get_client_name(c);
+    snprintf(src_pattern, 128, "%s:out_%%d", c_name);
+    jack_port_connect_pattern(c, n, k, src_pattern, dst_pattern);
+  }
+}
+
+void jack_port_connect_from_env(jack_client_t *c, int n, int k, char *env)
+{
+  char *src_pattern = getenv(env);
+  if (src_pattern) {
+    char dst_pattern[128];
+    char *c_name = jack_get_client_name(c);
+    snprintf(dst_pattern, 128, "%s:in_%%d", c_name);
+    jack_port_connect_pattern(c, n, k, src_pattern, dst_pattern);
+  }
+}
diff --git a/common/jack-port.h b/c-common/jack-port.h
similarity index 68%
rename from common/jack-port.h
rename to c-common/jack-port.h
index e158433..a87f4d0 100644
--- a/common/jack-port.h
+++ b/c-common/jack-port.h
@@ -9,6 +9,8 @@ int jack_port_connect_named(jack_client_t *client, const char *src, const char *
 int jack_port_disconnect_named(jack_client_t *client, const char *src, const char *dst);
 int jack_port_is_connected_p(jack_client_t *j, const char *l, const char *r);
 void jack_port_clear_all_connections(jack_client_t *j, const char *l);
-void jack_port_connect_pattern(jack_client_t *client, int n, char *src, char *dst);
+void jack_port_connect_pattern(jack_client_t *client, int n, int k, char *src, char *dst);
+void jack_port_connect_to_env(jack_client_t *c, int n, int k, char *env);
+void jack_port_connect_from_env(jack_client_t *c, int n, int k, char *env);
 
 #endif
diff --git a/common/jack-ringbuffer.c b/c-common/jack-ringbuffer.c
similarity index 86%
rename from common/jack-ringbuffer.c
rename to c-common/jack-ringbuffer.c
index c00b04a..fe83d58 100644
--- a/common/jack-ringbuffer.c
+++ b/c-common/jack-ringbuffer.c
@@ -1,5 +1,3 @@
-/*  jack-ringbuffer.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -15,11 +13,11 @@
 void jack_ringbuffer_print_debug(const jack_ringbuffer_t *r, const char *s)
 {
   eprintf("%s: read_ptr=%d,write_ptr=%d,size=%d,size_mask=%d\n",
-	  s, (int)r->read_ptr, (int)r->write_ptr, 
+	  s, (int)r->read_ptr, (int)r->write_ptr,
 	  (int)r->size, (int)r->size_mask);
 }
 
-int jack_ringbuffer_wait_for_read(const jack_ringbuffer_t *r, 
+int jack_ringbuffer_wait_for_read(const jack_ringbuffer_t *r,
 				  int nbytes, int fd)
 {
   int space = (int) jack_ringbuffer_read_space(r);
@@ -52,7 +50,7 @@ void jack_ringbuffer_read_exactly(jack_ringbuffer_t *r, char *buf, int n)
 {
   int err = jack_ringbuffer_read(r, buf, n);
   if(err != n) {
-    eprintf("%s: error reading ring buffer (%d != %d)\n", 
+    eprintf("%s: error reading ring buffer (%d != %d)\n",
 	    __func__, err, n);
     FAILURE;
   }
diff --git a/common/jack-ringbuffer.h b/c-common/jack-ringbuffer.h
similarity index 100%
rename from common/jack-ringbuffer.h
rename to c-common/jack-ringbuffer.h
diff --git a/common/jack-transport.c b/c-common/jack-transport.c
similarity index 85%
rename from common/jack-transport.c
rename to c-common/jack-transport.c
index 68c3723..a5a1e8b 100644
--- a/common/jack-transport.c
+++ b/c-common/jack-transport.c
@@ -1,5 +1,3 @@
-/*  jack-transport.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -16,4 +14,4 @@ bool jack_transport_is_rolling(jack_client_t *client)
 {
   jack_transport_state_t s = jack_transport_query(client , NULL);
   return s & JackTransportRolling;
-}  
+}
diff --git a/common/jack-transport.h b/c-common/jack-transport.h
similarity index 100%
rename from common/jack-transport.h
rename to c-common/jack-transport.h
diff --git a/common/memory.c b/c-common/memory.c
similarity index 82%
rename from common/memory.c
rename to c-common/memory.c
index b30e9d7..2085d58 100644
--- a/common/memory.c
+++ b/c-common/memory.c
@@ -1,5 +1,3 @@
-/*  memory.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 #include <stdio.h>
 #include "failure.h"
@@ -9,7 +7,7 @@ void *xmalloc(size_t size)
 {
   void *p = malloc(size);
   if(p == NULL) {
-    fprintf(stderr, "malloc() failed: %ld\n", (long)size);  
+    fprintf(stderr, "malloc() failed: %ld\n", (long)size);
     FAILURE;
   }
   return p;
@@ -19,7 +17,7 @@ void *xcalloc(size_t count, size_t eltsize)
 {
   void *p = calloc(count, eltsize);
   if(p == NULL) {
-    perror("calloc() failed");  
+    perror("calloc() failed");
     FAILURE;
   }
   return p;
@@ -44,7 +42,7 @@ float *fmalloc(size_t n)
   }
   return d;
 }
-        
+
 void fmemset(float *data, int n, float value)
 {
   int i;
diff --git a/common/memory.h b/c-common/memory.h
similarity index 100%
rename from common/memory.h
rename to c-common/memory.h
diff --git a/common/network.c b/c-common/network.c
similarity index 98%
rename from common/network.c
rename to c-common/network.c
index d24661e..1a35db0 100644
--- a/common/network.c
+++ b/c-common/network.c
@@ -1,5 +1,3 @@
-/*  network.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -152,13 +150,13 @@ int fd_wait(int fd, unsigned long timeout)
   fd_set set;
   FD_ZERO(&set);
   FD_SET(fd, &set);
-  
+
   struct timeval t;
   t = usec_to_timeval(timeout);
-  
+
   int err;
   err = select(FD_SETSIZE, &set, NULL, NULL, &t);
-  
+
   if(err == -1) {
     fprintf(stderr, "fd_wait: select failed, %d\n", err);
     FAILURE;
diff --git a/common/network.h b/c-common/network.h
similarity index 100%
rename from common/network.h
rename to c-common/network.h
diff --git a/common/observe-signal.c b/c-common/observe-signal.c
similarity index 88%
rename from common/observe-signal.c
rename to c-common/observe-signal.c
index 31db6b3..d1575c8 100644
--- a/common/observe-signal.c
+++ b/c-common/observe-signal.c
@@ -1,5 +1,3 @@
-/*  observe-signal.c - (c) rohan drape, 2005-2006 */
-
 #define _XOPEN_SOURCE 600 /* To use SA_RESTART and SA_RESETHAND */
 
 #include <stdio.h>
@@ -22,7 +20,7 @@ static void signal_management_handler(int s)
 static void *signal_management_thread(void *PTR)
 {
   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
-  sigset_t blocked;  
+  sigset_t blocked;
   sigprocmask(SIG_SETMASK, 0, &blocked);
   int s;
   sigwait(&blocked, &s);
@@ -55,7 +53,7 @@ int observe_signals(void)
 	return -1;
       }
     }
-  } 
+  }
   if(pthread_sigmask(SIG_SETMASK, &signals, 0)) {
     fprintf(stderr, "pthread_sigmask() failed: %s\n", strerror(errno));
     return -1;
@@ -71,9 +69,9 @@ int observe_signals(void)
 
 bool observe_end_of_process(void)
 {
-  return(signal_received & 1<<SIGHUP || 
-	 signal_received & 1<<SIGINT || 
-	 signal_received & 1<<SIGQUIT || 
-	 signal_received & 1<<SIGPIPE || 
+  return(signal_received & 1<<SIGHUP ||
+	 signal_received & 1<<SIGINT ||
+	 signal_received & 1<<SIGQUIT ||
+	 signal_received & 1<<SIGPIPE ||
 	 signal_received & 1<<SIGTERM);
 }
diff --git a/common/observe-signal.h b/c-common/observe-signal.h
similarity index 100%
rename from common/observe-signal.h
rename to c-common/observe-signal.h
diff --git a/common/osc.c b/c-common/osc.c
similarity index 87%
rename from common/osc.c
rename to c-common/osc.c
index 00cc176..543b1d5 100644
--- a/common/osc.c
+++ b/c-common/osc.c
@@ -1,5 +1,3 @@
-/*  osc.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
@@ -9,6 +7,11 @@
 #include "byte-order.h"
 #include "failure.h"
 #include "osc.h"
+#include "print.h"
+
+i32 osc_align(i32 n) {return (((n + 3) & (~3)) - n);}
+i32 osc_cstr_bound(i32 n) {return n + 1 + osc_align(n + 1);}
+i32 osc_blob_bound(i32 n) {return n + osc_align(n);}
 
 void osc_print_packet(const u8 *packet, i32 packet_sz)
 {
@@ -21,11 +24,6 @@ void osc_print_packet(const u8 *packet, i32 packet_sz)
   }
 }
 
-i32 osc_str_bound(i32 n)
-{
-  return n +(4 -(n % 4));
-}
-
 bool osc_is_numerical_type(u8 c)
 {
   return c == 'i' || c == 'h' || c == 't' || c == 'f' || c == 'd';
@@ -134,25 +132,25 @@ i32 osc_collect_arguments(const char *dsc, const u8 *p, osc_data_t *data)
       p += 8;
     } else if(c == 'f') {
       data[i].f = ntoh_f32_from_buf(p);
-      p += 4; 
+      p += 4;
     } else if(c == 'd') {
       data[i].d = ntoh_f64_from_buf(p);
-      p += 8; 
+      p += 8;
     } else if(c == 's') {
       data[i].s = (char*)p;
-      p += osc_str_bound(u8strlen(p));
+      p += osc_cstr_bound(u8strlen(p));
     } else if(c == 'S') {
       data[i].S = (char*)p;
-      p += osc_str_bound(u8strlen(p));
+      p += osc_cstr_bound(u8strlen(p));
     } else if(c == 'c') {
       data[i].c = ntoh_u32_from_buf(p);
-      p += 4; 
+      p += 4;
     } else if(c == 'm') {
       data[i].m = ntoh_u32_from_buf(p);
-      p += 4; 
+      p += 4;
     } else if(c == 'r') {
       data[i].r = ntoh_u32_from_buf(p);
-      p += 4; 
+      p += 4;
     } else if(c == 'b') {
       data[i].b.data = p + 4;
       data[i].b.size = ntoh_i32_from_buf(p);
@@ -183,31 +181,31 @@ i32 osc_pack_arguments(const char *dsc, const osc_data_t *data, u8 *p)
       p += 8;
     } else if(c == 'f') {
       ntoh_f32_to_buf(p, data[i].f);
-      p += 4; 
+      p += 4;
     } else if(c == 'd') {
       ntoh_f64_to_buf(p, data[i].d);
-      p += 8; 
+      p += 8;
     } else if(c == 's') {
       i32 n = strlen(data[i].s);
-      memcpy(p, data[i].s, n+1);
-      p += osc_str_bound(n);
+      memcpy(p, data[i].s, n + 1);
+      p += osc_cstr_bound(n);
     } else if(c == 'S') {
       i32 n = strlen(data[i].s);
-      memcpy(p, data[i].S, n+1);
-      p += osc_str_bound(n);
+      memcpy(p, data[i].S, n + 1);
+      p += osc_cstr_bound(n);
     } else if(c == 'c') {
       ntoh_u32_to_buf(p, data[i].c);
-      p += 4; 
+      p += 4;
     } else if(c == 'm') {
       ntoh_u32_to_buf(p, data[i].m);
-      p += 4; 
+      p += 4;
     } else if(c == 'r') {
       ntoh_u32_to_buf(p, data[i].r);
-      p += 4; 
+      p += 4;
     } else if(c == 'b') {
       ntoh_i32_to_buf(p, data[i].b.size);
       memcpy(p + 4, data[i].b.data, data[i].b.size);
-      p += osc_str_bound(data[i].b.size)+ 4;
+      p += osc_blob_bound(data[i].b.size) + 4;
     } else {
       return -1;
     }
@@ -227,13 +225,13 @@ i32 osc_dsc_read_arg_len(const char *dsc, const u8 *p)
   while(*dsc != '\0') {
     u8 c = *dsc;
     if(c == 'i' || c == 'f' || c == 'c' || c == 'm' || c == 'r') {
-      n += 4; 
+      n += 4;
     } else if(c == 'd' || c == 'h' || c == 't') {
       n += 8;
     } else if(c == 's' || c == 'S') {
-      n += osc_str_bound(u8strlen(p + n));
+      n += osc_cstr_bound(u8strlen(p + n));
     } else if(c == 'b') {
-      n += osc_str_bound(ntoh_i32_from_buf(p + n)) + 4;
+      n += osc_blob_bound(ntoh_i32_from_buf(p + n)) + 4;
     } else {
       return -1;
     }
@@ -253,15 +251,15 @@ osc_dsc_calculate_arg_len(const char *dsc, const osc_data_t *data)
   while(*dsc != '\0') {
     u8 c = *dsc;
     if(c == 'i' || c == 'f' || c == 'c' || c == 'm' || c == 'r') {
-      n += 4; 
+      n += 4;
     } else if(c == 'd' || c == 'h' || c == 't') {
       n += 8;
     } else if(c == 's') {
-      n += osc_str_bound(strlen(data->s));
+      n += osc_cstr_bound(strlen(data->s));
     } else if(c == 'S') {
-      n += osc_str_bound(strlen(data->S));
+      n += osc_cstr_bound(strlen(data->S));
     } else if(c == 'b') {
-      n += osc_str_bound(data->b.size)+ 4;
+      n += osc_cstr_bound(data->b.size)+ 4;
     } else {
       return -1;
     }
@@ -277,7 +275,7 @@ i32 osc_match_address(const char *addr, const u8 *packet)
   if(strncmp(addr, (char*)packet, addr_n)!= 0) {
     return 0;
   } else {
-    return osc_str_bound(addr_n);
+    return osc_cstr_bound(addr_n);
   }
 }
 
@@ -292,27 +290,31 @@ i32 osc_match_dsc(const char *u_dsc, const char *p_dsc)
       return 0;
     }
   }
-  return osc_str_bound(u_dsc_n);
+  return osc_cstr_bound(u_dsc_n);
 }
 
 i32 osc_parse_message(const char *addr, const char *dsc, const u8 *packet, i32 packet_sz, osc_data_t *data)
 {
   i32 addr_len = osc_match_address(addr, packet);
-  if(! addr_len) {
+  if(addr_len == 0) {
     return 0;
   }
   const char *p_dsc = (char*)packet + addr_len;
   i32 dsc_len = osc_match_dsc(dsc, p_dsc);
-  if(! dsc_len) {
+  if(dsc_len == 0) {
     return 0;
   }
   const u8 *p_arg = (u8*)p_dsc + dsc_len;
   i32 arg_len = osc_dsc_read_arg_len(p_dsc, p_arg);
   if(packet_sz < addr_len + dsc_len + arg_len) {
+    eprintf("%s: packet_sz: (%d,%d,%d,%d)\n"
+            ,__func__,packet_sz
+            ,addr_len,dsc_len,arg_len);
     return 0;
   }
   i32 err = osc_collect_arguments(p_dsc, p_arg, data);
   if(err) {
+    eprintf("%s: osc_collect_arguments\n",__func__);
     return 0;
   }
   osc_coerce_arguments(dsc, p_dsc, data);
@@ -322,9 +324,9 @@ i32 osc_parse_message(const char *addr, const char *dsc, const u8 *packet, i32 p
 i32 osc_construct_message(const char *addr, const char *dsc, const osc_data_t *data, u8 *packet, i32 packet_sz)
 {
   i32 addr_n = strlen(addr);
-  i32 addr_len = osc_str_bound(addr_n);
+  i32 addr_len = osc_cstr_bound(addr_n);
   i32 dsc_n = strlen(dsc);
-  i32 dsc_len = osc_str_bound(dsc_n);
+  i32 dsc_len = osc_cstr_bound(dsc_n);
   i32 arg_len = osc_dsc_calculate_arg_len(dsc, data);
   memset(packet, 0, addr_len + dsc_len + arg_len);
   memcpy(packet, addr, addr_n);
@@ -343,7 +345,7 @@ i32 osc_build_message(u8 *packet, i32 packet_sz,
 		      const char *addr, const char *dsc, ...)
 {
   osc_data_t data[256];
-  
+
   va_list ap;
   va_start(ap, dsc);
 
@@ -391,6 +393,6 @@ i32 osc_build_message(u8 *packet, i32 packet_sz,
     index++;
   }
   va_end(ap);
-  
+
   return osc_construct_message(addr, dsc, data, packet, packet_sz);
 }
diff --git a/common/osc.h b/c-common/osc.h
similarity index 72%
rename from common/osc.h
rename to c-common/osc.h
index 0ddf87f..1fd5520 100644
--- a/common/osc.h
+++ b/c-common/osc.h
@@ -9,33 +9,35 @@
 
 typedef struct
 {
-  const u8 *data; 
-  i32 size; 
+  const u8 *data;
+  i32 size;
 } osc_blob_t;
 
 typedef union
 {
-  i32 i;
-  i64 h;
-  u64 t;
-  f32 f;
-  f64 d;
-  const char *s;
-  const char *S;
-  u32 c;
-  u32 m;
-  u32 r;
-  osc_blob_t b;
+  i32 i; /* Signed Integer (32 bits) */
+  i64 h; /* Signed Integer (64 bits) */
+  u64 t; /* NTP TimeStamp */
+  f32 f; /* IEEE Float (32 bits) */
+  f64 d; /* IEEE Float (64 bits) */
+  const char *s; /* ASCII String (NULL suffix) */
+  const char *S; /* Symbol */
+  u32 c; /* ASCII Character */
+  u32 m; /* MIDI message (4 bytes) */
+  u32 r; /* RGBA Colour (4 bytes) */
+  osc_blob_t b; /* Blob (bytestring) */
 } osc_data_t;
-  
+
 typedef struct
 {
   u8 type;
   osc_data_t value;
 } osc_arg_t;
 
+i32 osc_align(i32 n);
+i32 osc_cstr_bound(i32 n);
+i32 osc_blob_bound(i32 n);
 void osc_print_packet(const u8 *packet, i32 packet_sz);
-i32 osc_str_bound(i32 n);
 bool osc_is_numerical_type(u8 c);
 bool osc_is_string_type(u8 c);
 bool osc_can_coerce(u8 u, u8 d);
diff --git a/c-common/plane.c b/c-common/plane.c
new file mode 100644
index 0000000..6cadcab
--- /dev/null
+++ b/c-common/plane.c
@@ -0,0 +1,91 @@
+/* A plane in 'Hessian normal form' can be given by a normal (a unit
+  vector perpendicular to the plane) and a scalar distance from the
+  origin. */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <math.h>
+#include "vector.h"
+#include "plane.h"
+
+plane make_plane(v32 n, f32 d)
+{
+  plane p;
+  p.n = n;
+  p.d = d;
+  return p;
+}
+
+f32 point_plane_distance(plane p, v32 v)
+{
+  return vdot(p.n, v) + p.d;
+}
+
+/* Determing if a point lies on, in front of or behind a plane. */
+
+enum side half_space(plane p, v32 v)
+{
+  f32 d = point_plane_distance(p, v);
+  if(d == 0.0) {
+    return coincide;
+  } else if(d > 0.0) {
+    return front;
+  } else if(d < 0.0) {
+    return back;
+  } else if(isnan(d)) {
+    fprintf(stderr, "half_space: nan: %f\n", d);
+    return coincide;
+  } else {
+    fprintf(stderr, "half_space: impossible condition: %f\n", d);
+    return coincide;
+   }
+}
+
+/* Returns #t iff p0 and p1 are not on the same side of plane. */
+
+bool intersect (plane p, v32 v0, v32 v1)
+{
+  enum side t0 = half_space(p, v0);
+  enum side t1 = half_space(p, v1);
+  return t0 != t1;
+}
+
+/* Given that the line from v0 to v1 intersects the plane return the
+   point at which it does so. -- NOTE: If n is zero t is NAN. */
+
+v32 intersection(plane p, v32 v0, v32 v1)
+{
+  v32 r = vsub(v1, v0);
+  f32 n = vdot(p.n, r);
+  f32 t = -(vdot(p.n, v0) + p.d) / n;
+  return vadd(v0, vmul(t, r));
+}
+
+/*  i = unit incidence vector, n = unit surface normal, result = unit
+    reflection vector */
+
+v32 in_to_r(v32 i, v32 n)
+{
+  return vadd(vmul(vdot(vmul(-1.0, i), n) * 2.0, n), i);
+}
+
+/*
+;; (p0,p1) is a line that intersects the plane (n,d).  returns the
+;; reflection of p0 about the point of intersection p*.  this is not
+;; the same as the reflection of p0 about the point of intersection -
+;; the magnitude of the reflected vector r is determined by the
+;; magnitude of (p1 - p*) not the vector (p* - p0) i.
+
+
+;; \
+;;  \ /
+;; --~---------------
+;;    \
+*/
+
+v32 reflect(plane p, v32 v0, v32 v1)
+{
+  v32 v = intersection(p, v0, v1);
+  v32 w = vunitise(vsub(v, v0));
+  return vadd(v, vmul(vlength(vsub(v1, v)), in_to_r(w, p.n)));
+}
diff --git a/c-common/plane.h b/c-common/plane.h
new file mode 100644
index 0000000..68e8a1f
--- /dev/null
+++ b/c-common/plane.h
@@ -0,0 +1,18 @@
+#ifndef _PLANE_H
+#define _PLANE_H
+
+#include <stdbool.h>
+#include "vector.h"
+
+typedef struct {v32 n; f32 d;} plane;
+enum side {front, back, coincide};
+
+plane make_plane(v32 n, f32 d);
+f32 point_plane_distance(plane p, v32 v);
+enum side half_space(plane p, v32 v);
+bool intersect (plane p, v32 v0, v32 v1);
+v32 intersection(plane p, v32 v0, v32 v1);
+v32 in_to_r(v32 i, v32 n);
+v32 reflect(plane p, v32 v0, v32 v1);
+
+#endif
diff --git a/common/print.h b/c-common/print.h
similarity index 89%
rename from common/print.h
rename to c-common/print.h
index cc75e8e..4d570da 100644
--- a/common/print.h
+++ b/c-common/print.h
@@ -8,7 +8,7 @@
 #ifdef DEBUG
   #define dprintf(...) fprintf(stderr,__VA_ARGS__)
 #else
-  #define dprintf(...) 
+  #define dprintf(...)
 #endif
 
 #endif
diff --git a/c-common/quantize.c b/c-common/quantize.c
new file mode 100644
index 0000000..2830f03
--- /dev/null
+++ b/c-common/quantize.c
@@ -0,0 +1,10 @@
+#include <math.h>
+#include "float.h"
+#include "quantize.h"
+
+/* Return the multiple of `quanta' nearest to `value'. */
+f32
+quantize(f32 quanta,f32 value)
+{
+  return quanta * roundf(value/quanta);
+}
diff --git a/c-common/quantize.h b/c-common/quantize.h
new file mode 100644
index 0000000..40fa799
--- /dev/null
+++ b/c-common/quantize.h
@@ -0,0 +1,8 @@
+#ifndef _COMMON_QUANTIZE_C
+#define _COMMON_QUANTIZE_C
+
+#include "float.h"
+
+f32 quantize(f32 quanta,f32 value);
+
+#endif
diff --git a/c-common/rand.c b/c-common/rand.c
new file mode 100644
index 0000000..736ec73
--- /dev/null
+++ b/c-common/rand.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+
+#include "float.h"
+#include "taus88.h"
+#include "rand.h"
+#include "rgba.h"
+#include "vector.h"
+
+static taus88_t taus88_std = {1243598713U, 3093459404U, 1821928721U};
+
+f32 randf32(f32 l, f32 r)
+{
+  f32 n = taus88f32(&taus88_std);
+  return (n * (r - l)) + l;
+}
+
+v32 randv32(f32 l, f32 r)
+{
+  v32 v;
+  v.x = randf32(l,r);
+  v.y = randf32(l,r);
+  v.z = randf32(l,r);
+  return v;
+}
+
+rgba randc32(f32 l, f32 r)
+{
+  rgba c;
+  c.r = randf32(l,r);
+  c.g = randf32(l,r);
+  c.b = randf32(l,r);
+  c.a = randf32(l,r);
+  return c;
+}
diff --git a/c-common/rand.h b/c-common/rand.h
new file mode 100644
index 0000000..13148db
--- /dev/null
+++ b/c-common/rand.h
@@ -0,0 +1,12 @@
+#ifndef _COMMON_RAND_H
+#define _COMMON_RAND_H
+
+#include "float.h"
+#include "vector.h"
+#include "rgba.h"
+
+f32 randf32(f32 l, f32 r);
+v32 randv32(f32 l, f32 r);
+rgba randc32(f32 l, f32 r);
+
+#endif
diff --git a/c-common/rgba.c b/c-common/rgba.c
new file mode 100644
index 0000000..de2f045
--- /dev/null
+++ b/c-common/rgba.c
@@ -0,0 +1,12 @@
+#include "float.h"
+#include "rgba.h"
+
+rgba make_rgba(f32 r, f32 g, f32 b, f32 a)
+{
+  rgba c;
+  c.r = r;
+  c.g = g;
+  c.b = b;
+  c.a = a;
+  return c;
+}
diff --git a/c-common/rgba.h b/c-common/rgba.h
new file mode 100644
index 0000000..74f043c
--- /dev/null
+++ b/c-common/rgba.h
@@ -0,0 +1,10 @@
+#ifndef _RGBA_H
+#define _RGBA_H
+
+#include "float.h"
+
+typedef struct {f32 r, g, b, a;} rgba;
+
+rgba make_rgba(f32 r, f32 g, f32 b, f32 a);
+
+#endif
diff --git a/c-common/segment-transfer.c b/c-common/segment-transfer.c
new file mode 100644
index 0000000..ea6c335
--- /dev/null
+++ b/c-common/segment-transfer.c
@@ -0,0 +1,62 @@
+#include <math.h>
+#include "float.h"
+#include "segment-transfer.h"
+
+/* Straight line interpolation (zero <= index <= one). */
+f32
+segment_transfer_interpolate_linear (f32 left,f32 right,f32 index)
+{
+  return ((index * (right - left)) + left);
+}
+
+/* Logarithmic interpolation function (zero <= index <= one).  This
+   works by translating `index' into a logarithmic space and making a
+   linear interpolation with the translated index.*/
+f32
+segment_transfer_interpolate_logarithmic (f32 left,f32 right,f32 index)
+{
+  return ((log10 ((index * 9) + 1.0)) * (right - left)) + left;
+}
+
+/* `data' is a pointer to a `size' samples that define a valid
+   transfer function.  `x' is a normalized lookup index between zero
+   and one. `size' must be a multiple of two, and `data' is
+   interpreted as a series of x/y co-ordinates. `data' is searched
+   left to right for two x co-ordinates that span `x', these are then
+   interpolated to calculate the corresponding y value.  A single data
+   point covers all possible x values. Out of range indexes are
+   truncated left and right. Other cases are looked up in left to
+   right order. */
+
+#define SEGMENT_TRANSFER_X(index) (data[((index)*2)])
+#define SEGMENT_TRANSFER_Y(index) (data[((index)*2)+1])
+
+f32
+segment_transfer_lookup_linear (f32 *data,int size,f32 x)
+{
+  int size_2 = size / 2;
+  if (size_2 == 1) {
+    return SEGMENT_TRANSFER_Y (0);
+  } else if (x <= 0.0) {
+    return SEGMENT_TRANSFER_Y (0);
+  } else if (x >= 1.0) {
+    return SEGMENT_TRANSFER_Y (size_2 - 1);
+  } else {
+    f32 x_left = SEGMENT_TRANSFER_X (0);
+    f32 x_right;
+    f32 z;
+    int i;
+    for (i = 1; i < size_2; i++) {
+      x_right = SEGMENT_TRANSFER_X (i);
+      if (x >= x_left && x <= x_right) {
+	f32 y_left = SEGMENT_TRANSFER_Y (i - 1);
+	f32 y_right = SEGMENT_TRANSFER_Y (i);
+	z = (x - x_left) / (x_right - x_left);
+	return segment_transfer_interpolate_linear (y_left,y_right,z);
+      }
+      x_left = x_right;
+    }
+  }
+  /* If the transfer function is corrupt return zero. */
+  return 0.0;
+}
diff --git a/c-common/segment-transfer.h b/c-common/segment-transfer.h
new file mode 100644
index 0000000..830a3dc
--- /dev/null
+++ b/c-common/segment-transfer.h
@@ -0,0 +1,10 @@
+#ifndef _COMMON_SEGMENT_TRANSFER_H
+#define _COMMON_SEGMENT_TRANSFER_H
+
+#include "float.h"
+
+f32 segment_transfer_interpolate_linear(f32 left,f32 right,f32 index);
+f32 segment_transfer_interpolate_logarithmic(f32 left,f32 right,f32 index);
+f32 segment_transfer_lookup_linear(f32 *data,int size,f32 x);
+
+#endif
diff --git a/common/signal-clip.c b/c-common/signal-clip.c
similarity index 83%
rename from common/signal-clip.c
rename to c-common/signal-clip.c
index 621058a..1736713 100644
--- a/common/signal-clip.c
+++ b/c-common/signal-clip.c
@@ -1,5 +1,3 @@
-/*  signal-clip.c - (c) rohan drape, 2005-2006 */
-
 #include "signal-clip.h"
 
 /* l = left, r = right, n = length of signal */
diff --git a/common/signal-clip.h b/c-common/signal-clip.h
similarity index 100%
rename from common/signal-clip.h
rename to c-common/signal-clip.h
diff --git a/common/signal-copy.c b/c-common/signal-copy.c
similarity index 79%
rename from common/signal-copy.c
rename to c-common/signal-copy.c
index 7ccf889..c3ebe03 100644
--- a/common/signal-copy.c
+++ b/c-common/signal-copy.c
@@ -1,11 +1,9 @@
-/*  signal-copy.c - (c) rohan drape, 2005-2006 */
-
 #include <math.h>
 #include <string.h>
 
 #include "signal-copy.h"
 
-void signal_copy_circular ( float *dst , const float *src , int n , int s ) 
+void signal_copy_circular ( float *dst , const float *src , int n , int s )
 {
   memcpy ( dst , src + s , ( n - s ) * sizeof(float) ) ;
   memcpy ( dst + ( n - s ) , src , s * sizeof(float) ) ;
diff --git a/common/signal-copy.h b/c-common/signal-copy.h
similarity index 100%
rename from common/signal-copy.h
rename to c-common/signal-copy.h
diff --git a/common/signal-interleave.c b/c-common/signal-interleave.c
similarity index 93%
rename from common/signal-interleave.c
rename to c-common/signal-interleave.c
index 4a17572..3c360f2 100644
--- a/common/signal-interleave.c
+++ b/c-common/signal-interleave.c
@@ -1,5 +1,3 @@
-/*  signal-interleave.c - (c) rohan drape, 2005-2006 */
-
 #include "float.h"
 #include "signal-interleave.h"
 
diff --git a/common/signal-interleave.h b/c-common/signal-interleave.h
similarity index 100%
rename from common/signal-interleave.h
rename to c-common/signal-interleave.h
diff --git a/common/signal-interpolate.c b/c-common/signal-interpolate.c
similarity index 91%
rename from common/signal-interpolate.c
rename to c-common/signal-interpolate.c
index 96c9451..10bae44 100644
--- a/common/signal-interpolate.c
+++ b/c-common/signal-interpolate.c
@@ -1,5 +1,3 @@
-/*  signal-interpolate.c - (c) rohan drape, 2005-2006 */
-
 #include <math.h>
 
 #include "int.h"
diff --git a/common/signal-interpolate.h b/c-common/signal-interpolate.h
similarity index 100%
rename from common/signal-interpolate.h
rename to c-common/signal-interpolate.h
diff --git a/common/signal-print.c b/c-common/signal-print.c
similarity index 84%
rename from common/signal-print.c
rename to c-common/signal-print.c
index ccd24aa..bf22e75 100644
--- a/common/signal-print.c
+++ b/c-common/signal-print.c
@@ -1,5 +1,3 @@
-/*  signal-print.c - (c) rohan drape, 2005 */
-
 #include <stdio.h>
 
 #include "float.h"
diff --git a/common/signal-print.h b/c-common/signal-print.h
similarity index 100%
rename from common/signal-print.h
rename to c-common/signal-print.h
diff --git a/common/sound-file.c b/c-common/sound-file.c
similarity index 91%
rename from common/sound-file.c
rename to c-common/sound-file.c
index af8e54e..f05d244 100644
--- a/common/sound-file.c
+++ b/c-common/sound-file.c
@@ -1,5 +1,3 @@
-/*  sound-file.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 
 #include "failure.h"
@@ -45,7 +43,7 @@ sf_count_t xsf_write_float(SNDFILE *sndfile, float *ptr, sf_count_t items)
 /* Read the single channel sound file at `name' to a newly allocated
    array and store the size at `n'. */
 
-float *read_signal_file(const char *name, int *n)
+float *read_signal_file(const char *name, int nc, int *n)
 {
   SF_INFO sfi;
   SNDFILE *sfp = sf_open(name, SFM_READ, &sfi);
@@ -54,11 +52,11 @@ float *read_signal_file(const char *name, int *n)
     sf_perror(sfp);
     FAILURE;
   }
-  if(sfi.channels != 1) {
+  if(sfi.channels != nc) {
     fprintf(stderr, "illegal channel count: %d\n", sfi.channels);
     FAILURE;
   }
-  *n = sfi.frames;
+  *n = sfi.frames * sfi.channels;
   float *data = xmalloc(*n * sizeof(float));
   int err = sf_read_float(sfp, data, *n);
   if(err == -1) {
@@ -66,7 +64,7 @@ float *read_signal_file(const char *name, int *n)
     sf_perror(sfp);
     FAILURE;
   }
-  return data;  
+  return data;
 }
 
 void write_signal_file(const char *name, const float *data, int n)
@@ -87,5 +85,5 @@ void write_signal_file(const char *name, const float *data, int n)
     sf_perror(sfp);
     FAILURE;
   }
-  sf_close(sfp);  
+  sf_close(sfp);
 }
diff --git a/common/sound-file.h b/c-common/sound-file.h
similarity index 87%
rename from common/sound-file.h
rename to c-common/sound-file.h
index 4592a47..4399eb2 100644
--- a/common/sound-file.h
+++ b/c-common/sound-file.h
@@ -7,7 +7,7 @@ SNDFILE *xsf_open(const char *path, int mode, SF_INFO *sfinfo);
 void xsf_handle_error(SNDFILE *sndfile);
 sf_count_t xsf_read_float(SNDFILE *sndfile, float *ptr, sf_count_t items);
 sf_count_t xsf_write_float(SNDFILE *sndfile, float *ptr, sf_count_t items);
-float *read_signal_file(const char *name, int *n);
+float *read_signal_file(const char *name, int nc, int *n);
 void write_signal_file(const char *name, const float *data, int n);
 
 #endif
diff --git a/c-common/taus88.c b/c-common/taus88.c
new file mode 100644
index 0000000..800989a
--- /dev/null
+++ b/c-common/taus88.c
@@ -0,0 +1,26 @@
+#include <stdint.h>
+#include "taus88.h"
+
+taus88_t make_taus88(u32 seed)
+{
+  taus88_t t;
+  t.s1 = 1243598713U ^ seed; if (t.s1 <  2) t.s1 = 1243598713U;
+  t.s2 = 3093459404U ^ seed; if (t.s2 <  8) t.s2 = 3093459404U;
+  t.s3 = 1821928721U ^ seed; if (t.s3 < 16) t.s3 = 1821928721U;
+  return t;
+}
+
+u32 taus88u32(taus88_t *t)
+{
+  t->s1 = ((t->s1 &  -2) << 12) ^ (((t->s1 << 13) ^  t->s1) >> 19);
+  t->s2 = ((t->s2 &  -8) <<  4) ^ (((t->s2 <<  2) ^  t->s2) >> 25);
+  t->s3 = ((t->s3 & -16) << 17) ^ (((t->s3 <<  3) ^  t->s3) >> 11);
+  return t->s1 ^ t->s2 ^ t->s3;
+}
+
+f32 taus88f32(taus88_t *t)
+{
+  union {u32 i ; f32 f ;} u;
+  u.i = 0x3F800000 | (taus88u32(t) >> 9);
+  return u.f - 1.0;
+}
diff --git a/c-common/taus88.h b/c-common/taus88.h
new file mode 100644
index 0000000..0d69fdc
--- /dev/null
+++ b/c-common/taus88.h
@@ -0,0 +1,14 @@
+#ifndef _COMMON_TAUS88_H
+#define _COMMON_TAUS88_H
+
+#include <stdint.h>
+#include "int.h"
+#include "float.h"
+
+typedef struct {u32 s1, s2, s3;} taus88_t;
+
+taus88_t make_taus88(u32 seed);
+u32 taus88u32(taus88_t *t);
+f32 taus88f32(taus88_t *t);
+
+#endif
diff --git a/common/time-current.c b/c-common/time-current.c
similarity index 74%
rename from common/time-current.c
rename to c-common/time-current.c
index aa9d768..a67ca5d 100644
--- a/common/time-current.c
+++ b/c-common/time-current.c
@@ -1,5 +1,3 @@
-/*  time-current.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 
 #include <sys/time.h>
@@ -10,13 +8,13 @@
 
 /* Get the current time as a UTC double precision value. */
 
-f64 current_time_as_utc_real(void) 
+f64 current_time_as_utc_real(void)
 {
   struct timeval current;
-  gettimeofday(&current, NULL); 
+  gettimeofday(&current, NULL);
   return timeval_to_real(current);
 }
-  
+
 struct timeval current_time_as_utc_timeval(void)
 {
   struct timeval tv;
diff --git a/common/time-current.h b/c-common/time-current.h
similarity index 100%
rename from common/time-current.h
rename to c-common/time-current.h
diff --git a/common/time-ntp.c b/c-common/time-ntp.c
similarity index 90%
rename from common/time-ntp.c
rename to c-common/time-ntp.c
index 03bcdc8..fd34c8a 100644
--- a/common/time-ntp.c
+++ b/c-common/time-ntp.c
@@ -1,5 +1,3 @@
-/*  time-ntp.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 #include <stdint.h>
 
@@ -34,7 +32,7 @@ u32 utc_usec_to_ntp_approx(u32 usec)
   return (usec << 12) + (usec << 8) - t;
 }
 
-u64 utc_timeval_to_ntp_approx(struct timeval tv) 
+u64 utc_timeval_to_ntp_approx(struct timeval tv)
 {
   const u64 secdif = (u64)2208988800UL; /* seconds from 1900 to 1970 */
   return ((u64)tv.tv_sec + (secdif << 32)) + ((u64)utc_usec_to_ntp_approx (tv.tv_usec));
diff --git a/common/time-ntp.h b/c-common/time-ntp.h
similarity index 100%
rename from common/time-ntp.h
rename to c-common/time-ntp.h
diff --git a/common/time-timespec.c b/c-common/time-timespec.c
similarity index 82%
rename from common/time-timespec.c
rename to c-common/time-timespec.c
index 4c375d7..c4213fd 100644
--- a/common/time-timespec.c
+++ b/c-common/time-timespec.c
@@ -1,5 +1,3 @@
-/*  time-timespec.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 
 #include "time-timespec.h"
diff --git a/common/time-timespec.h b/c-common/time-timespec.h
similarity index 100%
rename from common/time-timespec.h
rename to c-common/time-timespec.h
diff --git a/common/time-timeval.c b/c-common/time-timeval.c
similarity index 88%
rename from common/time-timeval.c
rename to c-common/time-timeval.c
index 6c55a3f..0f1ac92 100644
--- a/common/time-timeval.c
+++ b/c-common/time-timeval.c
@@ -1,5 +1,3 @@
-/*  time-timeval.c - (c) rohan drape, 2005-2006 */
-
 #include <stdlib.h>
 #include <math.h>
 
@@ -29,8 +27,8 @@ struct timeval real_to_timeval(f64 d)
   return t;
 }
 
-int timeval_subtract(struct timeval *result, 
-		     struct timeval x, 
+int timeval_subtract(struct timeval *result,
+		     struct timeval x,
 		     struct timeval y)
 {
   if (x.tv_usec < y.tv_usec) {
diff --git a/common/time-timeval.h b/c-common/time-timeval.h
similarity index 100%
rename from common/time-timeval.h
rename to c-common/time-timeval.h
diff --git a/c-common/trace.c b/c-common/trace.c
new file mode 100644
index 0000000..5ca3497
--- /dev/null
+++ b/c-common/trace.c
@@ -0,0 +1,63 @@
+#include <string.h>
+#include "int.h"
+#include "float.h"
+#include "print.h"
+#include "trace.h"
+
+#define TRACE_CPY(r,d,m) memcpy(r,d,m*sizeof(f32))
+#define TRACE_PTR(d,m,i) (d + ((i)*(m)))
+#define TRACE_READ(d,m,n,i) d[((n)*(m))+(i)]
+#define TRACE_T(d,m,n) d[(n)*(m)]
+
+void trace_interpolate(const f32 * d, i32 m, f32 t, f32 z, f32 * r)
+{
+    i32 i;
+    r[0] = t;
+    for (i = 1; i < m; i++) {
+	f32 p = d[i];
+	f32 q = d[i + m];
+	r[i] = (z * (q - p)) + p;
+    }
+    return;
+}
+
+/* d = data, n = data length, m = trace degree (including t), r = result */
+int trace_lookup(const f32 * d, i32 n, i32 m, f32 time, f32 * r)
+{
+    i32 trace_n = n / m;
+    if (n == m || time <= 0.0) {
+	TRACE_CPY(r, d, m);
+	return 0;
+    } else if (time >= 1.0) {
+	TRACE_CPY(r, TRACE_PTR(d, m, trace_n - 1), m);
+	return 0;
+    } else {
+	f32 t_left = TRACE_T(d, m, 0);
+	i32 i;
+	for (i = 1; i < trace_n; i++) {
+	    f32 t_right = TRACE_T(d, m, i);
+	    if (time >= t_left && time <= t_right) {
+		f32 z = (time - t_left) / (t_right - t_left);
+		trace_interpolate(TRACE_PTR(d, m, i - 1), m, time, z, r);
+                dprintf("(%f,%f) %f = %f\n",t_left,t_right,time,r[1]);
+		return 0;
+	    }
+	    t_left = t_right;
+	}
+    }
+    TRACE_CPY(r, TRACE_PTR(d, m, trace_n - 1), m);
+    return -1;
+}
+
+/*
+main () {
+  f32 tr[10] = {0,-1,0.25,0,0.5,1,0.75,0,1,-1};
+  i32 i;
+  for (i = 0; i < 20; i++) {
+    f32 r[2];
+    f32 tm = (f32)i / 20.0;
+    trace_lookup(tr,10,2,tm,r);
+    printf("main: %f = %f\n",tm,r[1]);
+  }
+}
+*/
diff --git a/c-common/trace.h b/c-common/trace.h
new file mode 100644
index 0000000..9cfaf0f
--- /dev/null
+++ b/c-common/trace.h
@@ -0,0 +1,10 @@
+#ifndef _COMMON_TRACE_H
+#define _COMMON_TRACE_H
+
+#include "int.h"
+#include "float.h"
+
+void trace_interpolate(const f32 * d, i32 m, f32 t, f32 z, f32 * r);
+int trace_lookup(const f32 * d, i32 n, i32 m, f32 time, f32 * r);
+
+#endif
diff --git a/c-common/vector.c b/c-common/vector.c
new file mode 100644
index 0000000..5af92dc
--- /dev/null
+++ b/c-common/vector.c
@@ -0,0 +1,51 @@
+#include <math.h>
+#include <stdio.h>
+#include "vector.h"
+
+v32 make_v32(f32 x, f32 y, f32 z)
+{
+  v32 v;
+  v.x = x;
+  v.y = y;
+  v.z = z;
+  return v;
+}
+
+v32 vmul(f32 s, v32 v)
+{
+  v32 r = { s * v.x, s * v.y, s * v.z};
+  return r;
+}
+
+v32 vadd(v32 a, v32 b)
+{
+  v32 v = { a.x + b.x, a.y + b.y, a.z + b.z};
+  return v;
+}
+
+v32 vsub(v32 a, v32 b)
+{
+  v32 v = { a.x - b.x, a.y - b.y, a.z - b.z};
+  return v;
+}
+
+f32 vdot(v32 a, v32 b)
+{
+  return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+
+f32 vlength(v32 v)
+{
+  return sqrtf(vdot(v, v));
+}
+
+v32 vunitise(v32 v)
+{
+  f32 l = vlength(v);
+  if(l == 0.0) {
+    fprintf(stderr, "vunitise: vlength==0\n");
+    return v;
+  } else {
+    return vmul(1.0 / l, v);
+  }
+}
diff --git a/c-common/vector.h b/c-common/vector.h
new file mode 100644
index 0000000..fc13d42
--- /dev/null
+++ b/c-common/vector.h
@@ -0,0 +1,16 @@
+#ifndef _VECTOR_H
+#define _VECTOR_H
+
+#include "float.h"
+
+typedef struct { f32 x, y, z;} v32;
+
+v32 make_v32(f32 x, f32 y, f32 z);
+v32 vmul(f32 s, v32 v);
+v32 vadd(v32 a, v32 b);
+v32 vsub(v32 a, v32 b);
+f32 vdot(v32 a, v32 b);
+f32 vlength(v32 v);
+v32 vunitise(v32 v);
+
+#endif
diff --git a/c-common/window.c b/c-common/window.c
new file mode 100644
index 0000000..ef138a5
--- /dev/null
+++ b/c-common/window.c
@@ -0,0 +1,412 @@
+#include <ctype.h>
+#include <math.h>
+#include "bessel.h"
+#include "memory.h"
+#include "window.h"
+
+#define PI (3.14159265358979323846)
+#define TWO_PI (2*PI)
+
+float fsquare(float a)
+{
+    return a * a;
+}
+
+#define GENERATE_WINDOW_AT(name,body)		\
+float					        \
+name##_window_at ( float angle )		\
+{						\
+  body ;					\
+}
+
+#define GENERATE_WINDOW_AT_BETA(name,body)	\
+float    					\
+name##_window_at ( float angle , float beta )	\
+{						\
+  body ;					\
+}
+
+#define APPLY_SCALAR				\
+    data[i] *= scalar ;				\
+    data[j] *= scalar ;
+
+#define GENERATE_APPLY_WINDOW(name,setup)	\
+void			        		\
+apply_##name##_window ( float * data , int n )	\
+{						\
+  setup {					\
+    float scalar = name##_window_at ( angle ) ;	\
+    APPLY_SCALAR				\
+  }						\
+}
+
+#define GENERATE_APPLY_WINDOW_BETA(name,setup)			\
+void						        	\
+apply_##name##_window ( float * data , int n , float beta )	\
+{								\
+  setup {							\
+    float scalar = name##_window_at ( angle , beta ) ;		\
+    APPLY_SCALAR						\
+  }								\
+}
+
+#define GENERATE_APPLY_WINDOW_B(name,setup,body)	\
+void                                                    \
+apply_##name##_window ( float * data , int n )		\
+{							\
+  setup {						\
+    body						\
+    APPLY_SCALAR					\
+  }							\
+}
+
+#define GENERATE_APPLY_WINDOW_BETA_B(name,setup,body)		\
+void							        \
+apply_##name##_window ( float * data , int n , float beta )	\
+{								\
+  setup {							\
+    body							\
+    APPLY_SCALAR						\
+  }								\
+}
+
+#define GENERATE_MAKE_WINDOW(name)		\
+void					\
+make_##name##_window ( float * data , int n )	\
+{						\
+  fmemset ( data , n , 1.0) ;			\
+  apply_##name##_window ( data , n ) ;		\
+}
+
+#define GENERATE_MAKE_WINDOW_BETA(name)				\
+void     							\
+make_##name##_window ( float * data , int n , float beta )	\
+{								\
+  fmemset ( data , n , 1.0 ) ;					\
+  apply_##name##_window ( data , n , beta ) ;			\
+}
+
+#define FREQ_BASE_SETUP									\
+  int i , j ;										\
+  float angle ;										\
+  int midn = n >> 1 ;									\
+  float freq = TWO_PI / (float)n ;							\
+  for ( i = 0 , j = n - 1 , angle = 0.0 ; i <= midn ; i++ , j-- , angle += freq )
+
+GENERATE_WINDOW_AT(rectangular, return 1.0;);
+GENERATE_APPLY_WINDOW(rectangular, FREQ_BASE_SETUP);
+GENERATE_MAKE_WINDOW(rectangular);
+
+GENERATE_WINDOW_AT(hanning, return 0.5 - 0.5 * cosf(angle););
+GENERATE_APPLY_WINDOW(hanning, FREQ_BASE_SETUP);
+GENERATE_MAKE_WINDOW(hanning);
+
+GENERATE_WINDOW_AT(hamming, return 0.54 - 0.46 * cosf(angle););
+GENERATE_APPLY_WINDOW(hamming, FREQ_BASE_SETUP);
+GENERATE_MAKE_WINDOW(hamming);
+
+GENERATE_WINDOW_AT(blackman2,
+		   float c = cosf(angle);
+		   return 0.34401 + (c * (-0.49755 + (c * 0.15844))););
+GENERATE_APPLY_WINDOW(blackman2, FREQ_BASE_SETUP);
+GENERATE_MAKE_WINDOW(blackman2);
+
+GENERATE_WINDOW_AT(blackman3,
+		   float c = cosf(angle);
+		   return 0.21747 +
+		   (c * (-0.45325 + (c * (0.28256 - (c * 0.04672))))););
+GENERATE_APPLY_WINDOW(blackman3, FREQ_BASE_SETUP);
+GENERATE_MAKE_WINDOW(blackman3);
+
+
+GENERATE_WINDOW_AT(blackman4,
+		   float c = cosf(angle);
+		   return 0.084037 +
+		   (c *
+		    (-0.29145 +
+		     (c *
+		      (0.375696 + (c * (-0.20762 + (c * 0.041194))))))););
+GENERATE_APPLY_WINDOW(blackman4, FREQ_BASE_SETUP);
+GENERATE_MAKE_WINDOW(blackman4);
+
+#define RATE_BASE_SETUP									\
+  int i , j ;										\
+  float angle ;										\
+  int midn = n >> 1 ;									\
+  float rate = 1.0 / (float)midn ;							\
+  for ( i = 0 , j = n - 1 , angle = 1.0 ; i <= midn ; i++ , j-- , angle -= rate )
+
+GENERATE_WINDOW_AT(bartlett, return angle;);
+GENERATE_APPLY_WINDOW(bartlett, RATE_BASE_SETUP);
+GENERATE_MAKE_WINDOW(bartlett);
+
+
+GENERATE_WINDOW_AT_BETA(kaiser,
+			float I0beta = bessi0(beta);
+			return bessi0(beta * sqrt(1.0 - fsquare(angle))) /
+			I0beta;);
+GENERATE_APPLY_WINDOW_BETA(kaiser, RATE_BASE_SETUP);
+GENERATE_MAKE_WINDOW_BETA(kaiser);
+
+GENERATE_WINDOW_AT_BETA(cauchy,
+			return 1.0 / (1.0 + fsquare(beta * angle)););
+GENERATE_APPLY_WINDOW_BETA(cauchy, RATE_BASE_SETUP);
+GENERATE_MAKE_WINDOW_BETA(cauchy);
+
+GENERATE_WINDOW_AT_BETA(poisson, return exp((-beta) * angle););
+GENERATE_APPLY_WINDOW_BETA(poisson, RATE_BASE_SETUP);
+GENERATE_MAKE_WINDOW_BETA(poisson);
+
+GENERATE_WINDOW_AT_BETA(gaussian,
+			return exp(-0.5 * fsquare(beta * angle)););
+GENERATE_APPLY_WINDOW_BETA(gaussian, RATE_BASE_SETUP);
+GENERATE_MAKE_WINDOW_BETA(gaussian);
+
+#define MID_BASE_SETUP					\
+  int i , j ;						\
+  int midn = n >> 1 ;					\
+  int midp1 = ( n + 1 ) / 2 ;				\
+  int midm1 = ( n - 1 ) / 2 ;				\
+  for ( i = 0 , j = n - 1 ; i <= midn ; i++ , j-- )
+
+GENERATE_APPLY_WINDOW_B(welch,
+			MID_BASE_SETUP,
+			float scalar =
+			1.0 - fsquare((float)(i - midm1) / (float)midp1););
+GENERATE_MAKE_WINDOW(welch);
+
+GENERATE_APPLY_WINDOW_B(parzen,
+			MID_BASE_SETUP,
+			float scalar =
+			1.0 - fabs((float) (i - midm1) / (float) midp1););
+GENERATE_MAKE_WINDOW(parzen);
+
+#define COUNTER_BASE_SETUP				\
+  int i , j ;						\
+  int midn = n >> 1 ;					\
+  for ( i = 0 , j = n - 1 ; i <= midn ; i++ , j-- )
+
+GENERATE_APPLY_WINDOW_B(riemann,
+			float sr = TWO_PI / (float) n;
+			COUNTER_BASE_SETUP,
+			float scalar =
+			(i ==
+			 midn) ? 1.0 : sinf(sr * (midn -
+						  i)) / (sr * (midn -
+							       i)););
+GENERATE_MAKE_WINDOW(riemann);
+
+GENERATE_APPLY_WINDOW_B(exponential,
+			float expsum = 1.0;
+			float expn = log(2) / (float) ((n >> 1) + 1.0);
+			COUNTER_BASE_SETUP, float scalar = expsum - 1.0;
+			expsum *= expn;);
+GENERATE_MAKE_WINDOW(exponential);
+
+GENERATE_APPLY_WINDOW_BETA_B(tukey,
+			     COUNTER_BASE_SETUP,
+			     float c = midn * (1.0 - beta);
+			     float scalar =
+			     (i >=
+			      c) ? 1.0 : 0.5 * (1.0 - cosf(PI * i / c)););
+GENERATE_MAKE_WINDOW_BETA(tukey);
+
+#define EOS(c) (c == '\0')
+
+int streq_ci(const char *a, const char *b)
+{
+    while (1) {
+	if (*a == '\0' && *b == '\0')
+	    return 1;
+	if (toupper(*a++) != toupper(*b++))
+	    return 0;
+    }
+}
+
+#define TEST_TYPE(name,intern)			\
+  if ( streq_ci ( type , name ) ) {		\
+    return intern ;				\
+  }
+
+int parse_window_type(const char *type)
+{
+    TEST_TYPE("RECTANGULAR", RECTANGULAR_WINDOW);
+    TEST_TYPE("HANNING", HANNING_WINDOW);
+    TEST_TYPE("HAMMING", HAMMING_WINDOW);
+    TEST_TYPE("BLACKMAN2", BLACKMAN2_WINDOW);
+    TEST_TYPE("BLACKMAN3", BLACKMAN3_WINDOW);
+    TEST_TYPE("BLACKMAN4", BLACKMAN4_WINDOW);
+    TEST_TYPE("BARTLETT", BARTLETT_WINDOW);
+    TEST_TYPE("KAISER", KAISER_WINDOW);
+    TEST_TYPE("CAUCHY", CAUCHY_WINDOW);
+    TEST_TYPE("POISSON", POISSON_WINDOW);
+    TEST_TYPE("GAUSSIAN", GAUSSIAN_WINDOW);
+    TEST_TYPE("WELCH", WELCH_WINDOW);
+    TEST_TYPE("PARZEN", PARZEN_WINDOW);
+    TEST_TYPE("RIEMANN", RIEMANN_WINDOW);
+    TEST_TYPE("EXPONENTIAL", EXPONENTIAL_WINDOW);
+    TEST_TYPE("TUKEY", TUKEY_WINDOW);
+    return -1;
+}
+
+window_f_t *get_apply_window_f(enum WINDOW_TYPE type)
+{
+    switch (type) {
+    case RECTANGULAR_WINDOW:
+	return apply_rectangular_window;
+    case HANNING_WINDOW:
+	return apply_hanning_window;
+    case HAMMING_WINDOW:
+	return apply_hamming_window;
+    case BLACKMAN2_WINDOW:
+	return apply_blackman2_window;
+    case BLACKMAN3_WINDOW:
+	return apply_blackman3_window;
+    case BLACKMAN4_WINDOW:
+	return apply_blackman4_window;
+    case BARTLETT_WINDOW:
+	return apply_bartlett_window;
+    case WELCH_WINDOW:
+	return apply_welch_window;
+    case PARZEN_WINDOW:
+	return apply_parzen_window;
+    case RIEMANN_WINDOW:
+	return apply_riemann_window;
+    case EXPONENTIAL_WINDOW:
+	return apply_exponential_window;
+    default:
+	return apply_rectangular_window;
+    }
+}
+
+beta_window_f_t *get_apply_beta_window_f(enum WINDOW_TYPE type)
+{
+    switch (type) {
+    case KAISER_WINDOW:
+	return apply_kaiser_window;
+    case CAUCHY_WINDOW:
+	return apply_cauchy_window;
+    case POISSON_WINDOW:
+	return apply_poisson_window;
+    case GAUSSIAN_WINDOW:
+	return apply_gaussian_window;
+    case TUKEY_WINDOW:
+	return apply_tukey_window;
+    default:
+	return apply_kaiser_window;
+    }
+}
+
+void
+apply_typed_window(enum WINDOW_TYPE type, float *data, int n, float beta)
+{
+    switch (type) {
+    case RECTANGULAR_WINDOW:
+	apply_rectangular_window(data, n);
+	break;
+    case HANNING_WINDOW:
+	apply_hanning_window(data, n);
+	break;
+    case HAMMING_WINDOW:
+	apply_hamming_window(data, n);
+	break;
+    case BLACKMAN2_WINDOW:
+	apply_blackman2_window(data, n);
+	break;
+    case BLACKMAN3_WINDOW:
+	apply_blackman3_window(data, n);
+	break;
+    case BLACKMAN4_WINDOW:
+	apply_blackman4_window(data, n);
+	break;
+    case BARTLETT_WINDOW:
+	apply_bartlett_window(data, n);
+	break;
+    case KAISER_WINDOW:
+	apply_kaiser_window(data, n, beta);
+	break;
+    case CAUCHY_WINDOW:
+	apply_cauchy_window(data, n, beta);
+	break;
+    case POISSON_WINDOW:
+	apply_poisson_window(data, n, beta);
+	break;
+    case GAUSSIAN_WINDOW:
+	apply_gaussian_window(data, n, beta);
+	break;
+    case WELCH_WINDOW:
+	apply_welch_window(data, n);
+	break;
+    case PARZEN_WINDOW:
+	apply_parzen_window(data, n);
+	break;
+    case RIEMANN_WINDOW:
+	apply_riemann_window(data, n);
+	break;
+    case EXPONENTIAL_WINDOW:
+	apply_exponential_window(data, n);
+	break;
+    case TUKEY_WINDOW:
+	apply_tukey_window(data, n, beta);
+	break;
+    default:
+	fmemset(data, n, 1.0);
+    }
+}
+
+void
+make_typed_window(enum WINDOW_TYPE type, float *data, int n, float beta)
+{
+    switch (type) {
+    case RECTANGULAR_WINDOW:
+	make_rectangular_window(data, n);
+	break;
+    case HANNING_WINDOW:
+	make_hanning_window(data, n);
+	break;
+    case HAMMING_WINDOW:
+	make_hamming_window(data, n);
+	break;
+    case BLACKMAN2_WINDOW:
+	make_blackman2_window(data, n);
+	break;
+    case BLACKMAN3_WINDOW:
+	make_blackman3_window(data, n);
+	break;
+    case BLACKMAN4_WINDOW:
+	make_blackman4_window(data, n);
+	break;
+    case BARTLETT_WINDOW:
+	make_bartlett_window(data, n);
+	break;
+    case KAISER_WINDOW:
+	make_kaiser_window(data, n, beta);
+	break;
+    case CAUCHY_WINDOW:
+	make_cauchy_window(data, n, beta);
+	break;
+    case POISSON_WINDOW:
+	make_poisson_window(data, n, beta);
+	break;
+    case GAUSSIAN_WINDOW:
+	make_gaussian_window(data, n, beta);
+	break;
+    case WELCH_WINDOW:
+	make_welch_window(data, n);
+	break;
+    case PARZEN_WINDOW:
+	make_parzen_window(data, n);
+	break;
+    case RIEMANN_WINDOW:
+	make_riemann_window(data, n);
+	break;
+    case EXPONENTIAL_WINDOW:
+	make_exponential_window(data, n);
+	break;
+    case TUKEY_WINDOW:
+	make_tukey_window(data, n, beta);
+	break;
+    default:
+	fmemset(data, n, 1.0);
+    }
+}
diff --git a/c-common/window.h b/c-common/window.h
new file mode 100644
index 0000000..a5978e1
--- /dev/null
+++ b/c-common/window.h
@@ -0,0 +1,32 @@
+#ifndef _COMMON_WINDOW_H
+#define _COMMON_WINDOW_H
+
+typedef void (window_f_t) (float *, int);
+typedef void (beta_window_f_t) (float *, int, float);
+
+enum WINDOW_TYPE {
+    RECTANGULAR_WINDOW,
+    HANNING_WINDOW,
+    HAMMING_WINDOW,
+    BLACKMAN2_WINDOW,
+    BLACKMAN3_WINDOW,
+    BLACKMAN4_WINDOW,
+    BARTLETT_WINDOW,
+    KAISER_WINDOW,
+    CAUCHY_WINDOW,
+    POISSON_WINDOW,
+    GAUSSIAN_WINDOW,
+    WELCH_WINDOW,
+    PARZEN_WINDOW,
+    RIEMANN_WINDOW,
+    EXPONENTIAL_WINDOW,
+    TUKEY_WINDOW,
+};
+
+int parse_window_type(const char *type);
+window_f_t *get_apply_window_f(enum WINDOW_TYPE type);
+beta_window_f_t *get_apply_beta_window_f(enum WINDOW_TYPE type);
+void apply_typed_window(enum WINDOW_TYPE type, float *data, int n, float beta);
+void make_typed_window(enum WINDOW_TYPE type, float *data, int n, float beta);
+
+#endif
diff --git a/common/ximg.c b/c-common/ximg.c
similarity index 91%
rename from common/ximg.c
rename to c-common/ximg.c
index 5f4ea72..2ed70fc 100644
--- a/common/ximg.c
+++ b/c-common/ximg.c
@@ -1,5 +1,3 @@
-/*  ximg.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -8,7 +6,7 @@
 #include "memory.h"
 #include "ximg.h"
 
-static int 
+static int
 ximg_handle_error(Display *d, XErrorEvent *e)
 {
   char message[128];
@@ -18,7 +16,7 @@ ximg_handle_error(Display *d, XErrorEvent *e)
   return 1;
 }
 
-static int 
+static int
 ximg_handle_io_error(Display *d)
 {
   fprintf(stderr, "X IO error\n");
@@ -59,12 +57,12 @@ ximg_open(int width, int height, char *name)
     fprintf(stderr, "ximg_open(): Non true color visual");
     FAILURE;
   }
-  x->image = XCreateImage(x->d, x->v, 
-			    DisplayPlanes(x->d, DefaultScreen( x->d)), 
-			    ZPixmap, 0, NULL, 
-			    x->width, x->height, BitmapPad(x->d), 0);  
+  x->image = XCreateImage(x->d, x->v,
+			    DisplayPlanes(x->d, DefaultScreen( x->d)),
+			    ZPixmap, 0, NULL,
+			    x->width, x->height, BitmapPad(x->d), 0);
   if(! x->image){
-    fprintf(stderr, "XCreateImage() failed");  
+    fprintf(stderr, "XCreateImage() failed");
     FAILURE;
   }
   x->image->data = xmalloc(x->height * x->image->bytes_per_line);
@@ -78,7 +76,7 @@ ximg_open(int width, int height, char *name)
    one byte, in row major order.  The pixmap is the same size as the
    window.  Modified from work by John Bradley in xv(1).  */
 
-static inline int 
+static inline int
 highbit(u32 ul)
 {
   i32 i;
@@ -87,7 +85,7 @@ highbit(u32 ul)
   return i;
 }
 
-void 
+void
 ximg_blit(Ximg_t *x, u8 *data)
 {
   u32 rmask = x->v->red_mask;
@@ -107,15 +105,15 @@ ximg_blit(Ximg_t *x, u8 *data)
     fprintf(stderr, "ximg_blit() : domain error : bperpix");
     abort ();
   }
-  u8 *lip = (u8*)x->image->data;  
+  u8 *lip = (u8*)x->image->data;
   u8 *pp = data;
   int i;
   for (i=0; i<x->height; i++, lip+=bperline) {
     int j;
     u8 *ip = lip;
     for (j=0; j<x->width; j++) {
-      u32 r = *pp++;  
-      u32 g = *pp++;  
+      u32 r = *pp++;
+      u32 g = *pp++;
       u32 b = *pp++;
       r = (rshift<0) ? r << (-rshift) : r >> rshift;
       g = (gshift<0) ? g << (-gshift) : g >> gshift;
@@ -173,7 +171,7 @@ ximg_blit(Ximg_t *x, u8 *data)
 }
 
 void
-ximg_mouse(Ximg_t *x, int *dx, int *dy, int *b) 
+ximg_mouse(Ximg_t *x, int *dx, int *dy, int *b)
 {
   int rootx, rooty;
   Window root, child;
@@ -182,7 +180,7 @@ ximg_mouse(Ximg_t *x, int *dx, int *dy, int *b)
   *b = (int)mask;
 }
 
-void 
+void
 ximg_close(Ximg_t *x)
 {
   XdbeDeallocateBackBufferName(x->d, x->b);
diff --git a/common/ximg.h b/c-common/ximg.h
similarity index 100%
rename from common/ximg.h
rename to c-common/ximg.h
diff --git a/common/xregcomp.c b/c-common/xregcomp.c
similarity index 72%
rename from common/xregcomp.c
rename to c-common/xregcomp.c
index 7ffc107..54d4fcb 100644
--- a/common/xregcomp.c
+++ b/c-common/xregcomp.c
@@ -1,5 +1,3 @@
-/*  xregcomp.c - (c) rohan drape, 2005-2006 */
-
 #include <stdio.h>
 
 #include "failure.h"
@@ -11,7 +9,7 @@ int xregcomp(regex_t *preg, const char *regex, int cflags)
   if(err) {
     char str[64];
     regerror(err, preg, str, 64);
-    fprintf(stderr, "regcomp() failed on `%s' with `%d': %s\n", 
+    fprintf(stderr, "regcomp() failed on `%s' with `%d': %s\n",
 	      regex, cflags, str);
     FAILURE;
   }
diff --git a/common/xregcomp.h b/c-common/xregcomp.h
similarity index 100%
rename from common/xregcomp.h
rename to c-common/xregcomp.h
diff --git a/common/Makefile.am b/common/Makefile.am
deleted file mode 100644
index 3c64a1f..0000000
--- a/common/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-
-MAINTAINERCLEANFILES =	Makefile.in
-
-noinst_LIBRARIES = libcommon.a
-
-libcommon_a_SOURCES =	byte-order.c byte-order.h \
-			client.c client.h \
-			failure.h \
-			file.c file.h \
-			float.h \
-			img.c img.h \
-			img-ppm.c img-ppm.h \
-			int.h \
-			jack-client.c jack-client.h \
-			jack-port.c jack-port.h \
-			jack-ringbuffer.c jack-ringbuffer.h \
-			jack-transport.c jack-transport.h \
-			memory.c memory.h \
-			network.c network.h \
-			observe-signal.c observe-signal.h \
-			osc.c osc.h \
-			print.h \
-			signal-clip.c signal-clip.h \
-			signal-copy.c signal-copy.h \
-			signal-interleave.c signal-interleave.h \
-			signal-interpolate.c signal-interpolate.h \
-			signal-print.c signal-print.h \
-			sound-file.c sound-file.h \
-			time-current.c time-current.h \
-			time-ntp.c time-ntp.h \
-			time-timespec.c time-timespec.h \
-			time-timeval.c time-timeval.h \
-			ximg.c ximg.h \
-			xregcomp.c xregcomp.h
-libcommon_a_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 2974a4f..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,56 +0,0 @@
-# configure.ac                            -*-autoconf-*-
-
-# Initialize autoconf and autmake
-
-AC_INIT(jack.*,0.5)
-AC_CONFIG_AUX_DIR(config)
-AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE
-PKG_PROG_PKG_CONFIG
-
-# Check for programs. These macros set and export variables that are
-# used in the make process.
-
-AC_PROG_CC
-AC_PROG_CPP
-AC_PROG_INSTALL
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-AC_PROG_AWK
-AC_PROG_LD
-AM_PROG_LIBTOOL
-
-# Require JACK library.
-
-PKG_CHECK_MODULES(JACK, jack, , AC_MSG_ERROR("jack required"))
-
-# Require sndfile library.
-
-PKG_CHECK_MODULES(SNDFILE, sndfile, , AC_MSG_ERROR("libsndfile required"))
-
-# Require samplerate library.
-
-PKG_CHECK_MODULES(SRC, samplerate, , AC_MSG_ERROR("libssamplerate required"))
-
-# Require liblo library.
-
-PKG_CHECK_MODULES(LIBLO, liblo, , AC_MSG_ERROR("liblo required"))
-
-# Require X11
-
-PKG_CHECK_MODULES(X11, x11, , AC_MSG_ERROR("x11 required"))
-PKG_CHECK_MODULES(XEXT, xext, , AC_MSG_ERROR("xext required"))
-PKG_CHECK_MODULES(Xt, xt, , AC_MSG_ERROR("xt required"))
-
-# Require inotify
-
-AC_CHECK_HEADERS(sys/inotify.h, AC_DEFINE(HAVE_INOTIFY, 1, inotify))
-
-# Set compiler flags.
-
-AC_SUBST(AM_CFLAGS)
-AM_CFLAGS="-D_POSIX_C_SOURCE=200112 -std=c99 -O3 -funroll-loops -Wall"
-
-# Write Makefile.
-
-AC_OUTPUT(Makefile common/Makefile)
diff --git a/help/Makefile b/help/Makefile
new file mode 100644
index 0000000..ae55fdd
--- /dev/null
+++ b/help/Makefile
@@ -0,0 +1,5 @@
+sin:
+	gcc -shared -I ~/opt/include sin.c -o sin.so
+
+clean:
+	rm -f *.so
diff --git a/help/scope.scm b/help/scope.scm
index 57bfd12..de219be 100644
--- a/help/scope.scm
+++ b/help/scope.scm
@@ -7,7 +7,7 @@
   (lambda (cmd arg)
     (send fd (list cmd arg))))
 
-(set-scope "/frames" 1024)
+(set-scope "/frames" (* 512 2))
 (set-scope "/delay" (/ 1000.0 24.0))
 
 (set-scope "/mode" "signal")
@@ -19,4 +19,6 @@
 (set-scope "/incr" 0.1)
 (set-scope "/embed" 64)
 
+(set-scope "/input-gain" 2.0)
+
 (udp:close fd)
diff --git a/help/sin.c b/help/sin.c
index 306dbfd..9c83a15 100644
--- a/help/sin.c
+++ b/help/sin.c
@@ -1,15 +1,15 @@
-/* gcc -shared -I ~/include sin.c -o sin.so */
+/* gcc -shared -I ~/opt/include sin.c -o sin.so */
 
 #include <stdlib.h>
 #include <math.h>
-#include <jack.dl.h>
+#include <jack-dl.h>
 
 struct sinosc {
   float f;                      /* frequency */
   float a;                      /* amplitude */
   float p;                      /* pan */
   float phase;                  /* oscillator phase */
-}; 
+};
 
 #define TWO_PI (2 * M_PI)
 
@@ -27,35 +27,36 @@ float step_phasor(float *phase, float incr)
     *phase -= TWO_PI;
   }
 }
-  
-/* allocate state data and initialize private control data */
-void *dsp_init(struct world *w, int g)
+
+size_t dsp_memreq()
+{
+  return sizeof(struct sinosc);
+}
+
+/* allocate state data and initialize control data */
+void dsp_init(void *p)
 {
-  struct sinosc *s = malloc(sizeof(struct sinosc));
+  struct sinosc *s = p;
   s->phase = 0.0;
   s->f = 440.0;
   s->a = 0.1;
   s->p = 0.5;
-  w_p_set1(w, g, 0, s->f);
-  w_p_set1(w, g, 1, s->a);
-  w_p_set1(w, g, 2, s->p);
-  return (void*)s;
 }
 
 /* process nf frames of data */
-void dsp_step(struct world *w, int g, void *ptr, int nf)
+void dsp_step(struct world *w, int g, int nf)
 {
   int i;
-  struct sinosc *s = (struct sinosc *)ptr;
+  struct sinosc *s = w_state(w,g);
   /* load state */
   float f = s->f;
   float a = s->a;
   float p = s->p;
   float phase = s->phase;
   /* read control values */
-  float fe = w_p_get1(w, g, 0);
-  float ae = w_p_get1(w, g, 1);
-  float pe = w_p_get1(w, g, 2);
+  float fe = w_c_get1(w, (g * 3) + 0);
+  float ae = w_c_get1(w, (g * 3) + 1);
+  float pe = w_c_get1(w, (g * 3) + 2);
   /* calculate control increments */
   float fi = (fe - f) / (float)nf;
   float ai = (ae - a) / (float)nf;
diff --git a/help/sin.scm b/help/sin.scm
index d7d4c63..ae51697 100644
--- a/help/sin.scm
+++ b/help/sin.scm
@@ -1,3 +1,6 @@
+(import (sosc)
+        (rsc3))
+
 (define with-jackdl
   (lambda (f)
     (let* ((fd (udp:open "127.0.0.1" 57190))
@@ -9,23 +12,27 @@
   (lambda (i s)
     (message "/g_load" (list i s))))
 
-(define p-set1
-  (lambda (g i n)
-    (message "/p_set1" (list g i n))))
+(define c-set1
+  (lambda (i n)
+    (message "/c_set" (list i n))))
+
+(define g-ctl
+  (lambda (g i)
+    (+ (* g 3) i)))
 
 (define set-sin
   (lambda (g f a p)
     (with-jackdl
      (lambda (fd)
-       (send fd (p-set1 g 0 f))
-       (send fd (p-set1 g 1 a))
-       (send fd (p-set1 g 2 p))))))
+       (send fd (c-set1 (g-ctl g 0) f))
+       (send fd (c-set1 (g-ctl g 1) a))
+       (send fd (c-set1 (g-ctl g 2) p))))))
 
 (with-jackdl
   (lambda (fd)
     (for-each
      (lambda (g)
-       (send fd (g-load g "/home/rohan/sw/jack.*/help/sin.so")))
+       (send fd (g-load g "/home/rohan/sw/rju/help/sin.so")))
      (list 0 1 2))))
 
 (set-sin (i-random 0 3)
diff --git a/jack-dl.c b/jack-dl.c
new file mode 100644
index 0000000..d8e8eef
--- /dev/null
+++ b/jack-dl.c
@@ -0,0 +1,185 @@
+#include <dlfcn.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <jack/jack.h>
+#include <jack/thread.h>
+#include <lo/lo.h>
+
+#include "c-common/jack-port.h"
+#include "c-common/print.h"
+#include "jack-dl.h"
+
+void fail(char *s)
+{
+  fprintf(stderr, "%s", s);
+  exit(EXIT_FAILURE);
+}
+
+int dsp_run(jack_nframes_t nf, void *ptr)
+{
+  struct world *w = (struct world *)ptr;
+  if(w->ga) {
+    for(int i = 0; i < w->nc; i++) {
+      w->in[i] = (float *)jack_port_get_buffer(w->ip[i], nf);
+      w->out[i] = (float *)jack_port_get_buffer(w->op[i], nf);
+      memset(w->out[i],0,nf * sizeof(float));
+    }
+    w->dsp_step(w, nf);
+  }
+  return 0;
+}
+
+void osc_error(int n, const char *m, const char *p)
+{
+  fprintf(stderr,"jack-dl: error %d in path %s: %s\n", n, p, m);
+}
+
+#define break_on(x,s)                                                   \
+  if(x){                                                                \
+    fprintf(stderr,"jack-dl: %s: %s, %d\n", s, __FILE__, __LINE__);     \
+    return 0;                                                           \
+  }
+
+int osc_g_load(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
+{
+  struct world *w = (struct world *)u;
+  w->ga = false;
+  char *s = &a[0]->s;
+  if(w->gh) break_on(dlclose(w->gh), dlerror());
+  w->gh = dlopen(s, RTLD_LAZY);
+  break_on(!w->gh, dlerror());
+  w->dsp_memreq = dlsym(w->gh, "dsp_memreq");
+  w->dsp_init = dlsym(w->gh, "dsp_init");
+  w->dsp_step = dlsym(w->gh, "dsp_step");
+  size_t k = w->dsp_memreq();
+  w->st = malloc(k);
+  w->dsp_init(w->st);
+  w->ga = true;
+  fprintf(stderr,"g_load: %s\n", s);
+  return 0;
+}
+
+int osc_g_unload(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
+{
+  struct world *w = (struct world *)u;
+  w->ga = false;
+  if(w->gh) break_on(dlclose(w->gh), dlerror());
+  w->gh = NULL;
+  if(w->st) free(w->st);
+  fprintf(stderr,"g_unload\n");
+  return 0;
+}
+
+int osc_c_set(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
+{
+  struct world *w = (struct world *)u;
+  int i = a[0]->i;
+  break_on(i >= w->nk, "control index");
+  w_c_set1(w, i, a[1]->f);
+  fprintf(stderr,"c_set: %d, %f\n", i, a[1]->f);
+  return 0;
+}
+
+int osc_b_alloc(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
+{
+  struct world *w = (struct world *)u;
+  int i = a[0]->i;
+  break_on(i >= w->nb, "buffer index");
+  /*if(w->bd[i]) free(w->bd[i]);*/
+  int l = a[1]->i;
+  int c = a[2]->i;
+  break_on(c != 1, "buffer not single channel...");
+  w->bl[i] = 0;
+  if(w->bd[i]) {
+    w->bd[i] = realloc(w->bd[i],l * sizeof(float));
+  } else {
+    w->bd[i] = calloc(l, sizeof(float));
+  }
+  w->bl[i] = l;
+  fprintf(stderr,"b_alloc: %d, %d, %d\n", i, l, c);
+  return 0;
+}
+
+int osc_quit(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
+{
+  struct world *w = (struct world *)u;
+  w->ef = true;
+  return 0;
+}
+
+void world_init(struct world *w, int nc, int nk, int nb)
+{
+  w->nc = nc;
+  w->nk = nk;
+  w->nb = nb;
+  w->dsp_memreq = NULL;
+  w->dsp_init = NULL;
+  w->dsp_step = NULL;
+  w->st = NULL;
+  w->ga = false;
+  w->gh = NULL;
+  w->ip = malloc(w->nc * sizeof(jack_port_t *));
+  w->op = malloc(w->nc * sizeof(jack_port_t *));
+  w->in = malloc(w->nc * sizeof(float *));
+  w->out = malloc(w->nc * sizeof(float *));
+  w->ctl = calloc(w->nk, sizeof(float));
+  w->bl = calloc(w->nb, sizeof(int));
+  w->bd = calloc(w->nb, sizeof(float*));
+  w->ef = false;
+  strncpy(w->cn,"jack-dl",64);
+  w->c = jack_client_open(w->cn,JackNullOption,NULL);
+  if(!w->c) fail("could not create jack client\n");
+  jack_set_process_callback(w->c, dsp_run, w);
+  w->sr = (float)jack_get_sample_rate(w->c);
+  jack_port_make_standard(w->c, w->ip, w->nc, false);
+  jack_port_make_standard(w->c, w->op, w->nc, true);
+}
+
+void usage(void)
+{
+  eprintf("Usage: jack-dl [ options ]\n");
+  eprintf("    -b N : Number of buffers (default=8).\n");
+  eprintf("    -c N : Number of channels (default=8).\n");
+  eprintf("    -k N : Number of controls (default=64).\n");
+  exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+  struct world w;
+  lo_server_thread osc;
+  int c;
+  int nb = 8, nc = 8, nk = 64;
+  while((c = getopt(argc, argv, "b:c:hk:")) != -1) {
+    switch(c) {
+    case 'b': nb = (int)strtol(optarg, NULL, 0); break;
+    case 'c': nc = (int)strtol(optarg, NULL, 0); break;
+    case 'h': usage(); break;
+    case 'k': nk = (int)strtol(optarg, NULL, 0); break;
+    }
+  }
+  world_init(&w, nc, nk, nb);
+  osc = lo_server_thread_new("57190", osc_error);
+  lo_server_thread_add_method(osc, "/c_set", "if", osc_c_set, &w);
+  lo_server_thread_add_method(osc, "/g_load", "s", osc_g_load, &w);
+  lo_server_thread_add_method(osc, "/g_unload", "", osc_g_unload, &w);
+  lo_server_thread_add_method(osc, "/b_alloc", "iii", osc_b_alloc, &w);
+  lo_server_thread_add_method(osc, "/quit", NULL, osc_quit, &w);
+  lo_server_thread_start(osc);
+  if(jack_activate(w.c)) fail("jack-dl: jack_activate() failed\n");
+  jack_port_connect_to_env(w.c, w.nc, 0, "JACK_DL_CONNECT_TO");
+  jack_port_connect_from_env(w.c, w.nc, 0, "JACK_DL_CONNECT_FROM");
+  while(!w.ef) {
+    struct timespec t = {0, 100000000};
+    nanosleep(&t, NULL);
+  }
+  jack_client_close(w.c);
+  lo_server_thread_free(osc);
+  return EXIT_SUCCESS;
+}
diff --git a/jack-dl.h b/jack-dl.h
new file mode 100644
index 0000000..685b105
--- /dev/null
+++ b/jack-dl.h
@@ -0,0 +1,37 @@
+#include <stdbool.h>
+#include <jack/jack.h>
+
+struct world {
+  size_t (*dsp_memreq)();
+  void (*dsp_init)(void *);
+  void (*dsp_step)(struct world *, int);
+  void *st;                    /* graph state */
+  bool ga;                     /* graph active */
+  void *gh;                    /* graph shared library handle */
+  jack_client_t *c;            /* client */
+  char cn[64];                 /* client name */
+  jack_port_t **ip;            /* input ports */
+  jack_port_t **op;            /* output ports */
+  int nc;                      /* number of channels */
+  int nk;                      /* number of controls */
+  int nb;                      /* number of buffers */
+  float sr;                    /* sample rate */
+  float **in;                  /* input data */
+  float **out;                 /* output data */
+  float *ctl;                  /* (shared) control data */
+  float **bd;                  /* buffer data */
+  int *bl;                     /* buffer sizes (0 == not-ready) */
+  bool ef;                     /* exit flag */
+};
+
+#define df_world struct world
+#define w_state(w) (w)->st
+#define w_sr(w) (w)->sr
+#define w_c_get1(w,i) (w)->ctl[(i)]
+#define w_c_set1(w,i,n) (w)->ctl[(i)]=(n)
+#define w_in1(w,i) (w)->in[0][(i)]
+#define w_out1(w,i,n) (w)->out[0][(i)]=(n)
+#define w_out2(w,i,n1,n2) {(w)->out[0][(i)]=(n1);(w)->out[1][(i)]=(n2);}
+/* run-time check... */
+#define w_b_read1(w,b,i) (w)->bl[(b)] > (i) ? (w)->bd[(b)][(i)] : 0.0
+#define w_b_write1(w,b,i,n) if((w)->bl[(b)] > (i)) {(w)->bd[(b)][(i)]=(n);}
diff --git a/jack-dl.text b/jack-dl.text
new file mode 100644
index 0000000..d8a56fd
--- /dev/null
+++ b/jack-dl.text
@@ -0,0 +1,59 @@
+JACK-DL(1)
+==========
+Rohan Drape <rd at slavepianos.org>
+
+NAME
+----
+jack-dl - JACK shared library dsp loader
+
+SYNOPSIS
+--------
+jack-dl [options]
+
+OPTIONS
+-------
+*-b*
+:   Set the number of buffers (default=8).
+*-c*
+:   Set the number of input and output channels (default=8).
+*-k*
+:   Set the number of control buses (default=64).
+*-p*
+:   Set the udp port number (default=57190).
+
+DESCRIPTION
+-----------
+jack-dl loads dsp algorithms from shared libraries and allows user
+interaction with the executing graph.  Commands are sent as OSC
+packets over a UDP connection.
+
+The dsp graph code must provide three functions:
+
+    size_t (*dsp_memreq)();
+    void (*dsp_init)(void *);
+    void (*dsp_step)(void *,int);
+
+jack-dl accepts the OSC commands:
+
+Command   Arguments                             Description
+-------   ---------                             -----------
+/b_alloc  id::int frames::int channels::int     buffer allocate
+/c_set    index::int value::float               control set
+/g_load   object-file::file-path                graph load
+
+jack-dl consults the `JACK_DL_CONNECT_TO` and `JACK_DL_CONNECT_FROM`
+environment variables.
+
+jack-dl implements only a subset of the OSC protocol.  In particular
+it does not implement the patten matching rules and does not implement
+a scheduler for incoming messages.
+
+jack-dl drops all unrecognized incoming packets.
+
+AUTHOR
+------
+Rohan Drape <http://rd.slavepianos.org/>
+
+SEE ALSO
+--------
+jackd(1), OSC(7) <http://opensoundcontrol.org/>
diff --git a/jack.osc.c b/jack-osc.c
similarity index 83%
rename from jack.osc.c
rename to jack-osc.c
index 64a214e..d64e4b1 100644
--- a/jack.osc.c
+++ b/jack-osc.c
@@ -1,5 +1,3 @@
-/***** jack.osc.c - (c) rohan drape, 2004-2006 *****/
-
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -9,19 +7,19 @@
 #include <pthread.h>
 #include <sys/time.h>
 
-#include "common/byte-order.h"
-#include "common/client.h"
-#include "common/failure.h"
-#include "common/jack-client.h"
-#include "common/jack-port.h"
-#include "common/memory.h"
-#include "common/network.h"
-#include "common/observe-signal.h"
-#include "common/osc.h"
-#include "common/print.h"
-#include "common/time-current.h"
-#include "common/time-ntp.h"
-#include "common/time-timeval.h"
+#include "c-common/byte-order.h"
+#include "c-common/client.h"
+#include "c-common/failure.h"
+#include "c-common/jack-client.h"
+#include "c-common/jack-port.h"
+#include "c-common/memory.h"
+#include "c-common/network.h"
+#include "c-common/observe-signal.h"
+#include "c-common/osc.h"
+#include "c-common/print.h"
+#include "c-common/time-current.h"
+#include "c-common/time-ntp.h"
+#include "c-common/time-timeval.h"
 
 #define REQUEST_TICK        0x00000001
 #define REQUEST_PULSE       0x00000002
@@ -39,12 +37,12 @@ struct jackosc
   f64 ppf;			/* Pulses per frame */
   f64 tpf;			/* Ticks per frame */
   f64 pulse;			/* Pulse clock */
-  i64 frm;			/* Frame clock (jack.osc) */
+  i64 frm;			/* Frame clock (jack-osc) */
   i64 j_frm;			/* Frame clock (jackd) */
   u64 ntp;			/* NTP clock */
   f64 utc;			/* UTC clock */
   i8 roll;
-  i32 correct_interval; 
+  i32 correct_interval;
   i32 correct_n;
   i8 fps_alt;
   jack_client_t *client;
@@ -63,10 +61,10 @@ struct jackosc
 #define COMMON_SEND(addr,dsc,incl)					\
   int packet_sz;							\
   packet_sz = osc_construct_message(addr, dsc, o, packet, 256);		\
-  sendto_client_register(d->fd, d->cr, packet, packet_sz, incl); 
+  sendto_client_register(d->fd, d->cr, packet, packet_sz, incl);
 
-void send_jck_drift(struct jackosc *d, 
-		    u64 ntp, f64 utc, i64 frm, 
+void send_jck_drift(struct jackosc *d,
+		    u64 ntp, f64 utc, i64 frm,
 		    i64 ntp_dif, f64 utc_dif)
 {
   COMMON_SETUP(5);
@@ -75,8 +73,8 @@ void send_jck_drift(struct jackosc *d,
   COMMON_SEND("/drift", ",tdhhd", REQUEST_CORRECTION);
 }
 
-void send_jck_tick(struct jackosc *d, 
-		   u64 ntp, f64 utc, i64 frm, 
+void send_jck_tick(struct jackosc *d,
+		   u64 ntp, f64 utc, i64 frm,
 		   i64 frame, f64 pulse)
 {
   COMMON_SETUP(5);
@@ -85,23 +83,23 @@ void send_jck_tick(struct jackosc *d,
   COMMON_SEND("/tick", ",tdhhd", REQUEST_TICK);
 }
 
-void send_jck_current(int fd, struct sockaddr_in address, 
-		      u64 ntp, f64 utc, i64 frm, 
+void send_jck_current(int fd, struct sockaddr_in address,
+		      u64 ntp, f64 utc, i64 frm,
 		      i64 frame, f64 pulse)
 {
   COMMON_SETUP(5);
   o[3].h = frame;
   o[4].d = pulse;
   int packet_sz;
-  packet_sz = osc_construct_message("/current.reply", ",tdhhd", 
+  packet_sz = osc_construct_message("/current.reply", ",tdhhd",
 				    o, packet, 256);
   if(packet_sz) {
     sendto_exactly(fd, packet, packet_sz, address);
   }
 }
 
-void send_jck_pulse(struct jackosc *d, 
-		    u64 ntp, f64 utc, i64 frm, 
+void send_jck_pulse(struct jackosc *d,
+		    u64 ntp, f64 utc, i64 frm,
 		    u64 p_ntp, f64 p_utc, i64 p_frm, i32 pulse)
 {
   COMMON_SETUP(7);
@@ -112,9 +110,9 @@ void send_jck_pulse(struct jackosc *d,
   COMMON_SEND("/pulse", ",tdhtdhi", REQUEST_PULSE);
 }
 
-void send_jck_transport(struct jackosc *d, 
-			u64 ntp, f64 utc, i64 frm, 
-			f64 fps, f64 ppm, f64 ppc, f64 pt, 
+void send_jck_transport(struct jackosc *d,
+			u64 ntp, f64 utc, i64 frm,
+			f64 fps, f64 ppm, f64 ppc, f64 pt,
 			i32 rolling)
 {
   COMMON_SETUP(8);
@@ -126,8 +124,8 @@ void send_jck_transport(struct jackosc *d,
   COMMON_SEND("/transport", ",tdhddddi", REQUEST_TRANSPORT);
 }
 
-void send_jck_status(int fd, struct sockaddr_in address, 
-		     f64 fps, f64 ppm, f64 ppc, f64 pt, 
+void send_jck_status(int fd, struct sockaddr_in address,
+		     f64 fps, f64 ppm, f64 ppc, f64 pt,
 		     i32 rolling)
 {
   u8 packet[256];
@@ -138,7 +136,7 @@ void send_jck_status(int fd, struct sockaddr_in address,
   o[2].d = ppc;
   o[3].d = pt;
   o[4].i = rolling;
-  packet_sz = osc_construct_message("/status.reply", ",ddddi", 
+  packet_sz = osc_construct_message("/status.reply", ",ddddi",
 				    o, packet, 256);
   if(packet_sz) {
     sendto_exactly(fd, packet, packet_sz, address);
@@ -157,7 +155,7 @@ void *jackosc_osc_thread_procedure(void *PTR)
       socklen_t addr_len = sizeof(addr);
       const int packet_extent = 64;
       u8 packet[packet_extent];
-      i32 packet_sz = xrecvfrom(d->fd, packet, 64, 0, 
+      i32 packet_sz = xrecvfrom(d->fd, packet, 64, 0,
 				(struct sockaddr *)&addr, &addr_len);
       osc_data_t o[4];
       if(OSC_PARSE_MSG("/receive", ",i")) {
@@ -167,10 +165,10 @@ void *jackosc_osc_thread_procedure(void *PTR)
 	init_sockaddr_in(&ra_addr, o[2].s, (i16)o[1].i);
 	edit_client_register(d->cr, ra_addr, o[0].i);
       } else if(OSC_PARSE_MSG("/status", ",")) {
-	send_jck_status(d->fd, addr, 
+	send_jck_status(d->fd, addr,
 			d->fps, d->ppm, d->ppc, d->pt, d->roll);
       } else if(OSC_PARSE_MSG("/current", ",")) {
-	send_jck_current(d->fd, addr, 
+	send_jck_current(d->fd, addr,
 			 d->ntp, d->utc, d->frm, d->j_frm, d->pulse);
       } else if(OSC_PARSE_MSG("/start", ",")) {
 	jack_transport_start(d->client);
@@ -190,20 +188,20 @@ void *jackosc_osc_thread_procedure(void *PTR)
   return NULL;
 }
 
-inline f64 get_ticks_per_frame(f64 ticks_per_pulse, 
-			       f64 pulses_per_minute, 
+inline f64 get_ticks_per_frame(f64 ticks_per_pulse,
+			       f64 pulses_per_minute,
 			       f64 frames_per_second)
 {
   f64 pulses_per_second = pulses_per_minute / 60.0;
   f64 ticks_per_second = ticks_per_pulse * pulses_per_second;
-  return ticks_per_second / frames_per_second; 
+  return ticks_per_second / frames_per_second;
 }
 
-inline f64 get_pulses_per_frame(f64 pulses_per_minute, 
+inline f64 get_pulses_per_frame(f64 pulses_per_minute,
 				f64 frames_per_second)
 {
   f64 pulses_per_second = pulses_per_minute / 60.0;
-  return pulses_per_second / frames_per_second; 
+  return pulses_per_second / frames_per_second;
 }
 
 int jackosc_process(jack_nframes_t nframes, void *PTR)
@@ -248,8 +246,8 @@ int jackosc_process(jack_nframes_t nframes, void *PTR)
       send_jck_transport(d, d->ntp, d->utc, d->frm,
 			 d->fps, d->ppm, d->ppc, d->pt, d->roll);
     }
-    if(d->roll && 
-       (p.tick == 0 || 
+    if(d->roll &&
+       (p.tick == 0 ||
 	((f64)p.tick +(floorf((f64)nframes * d->tpf)))> (f64)p.ticks_per_beat)) {
       i32 p_tick_off =(p.tick == 0)? 0 : p.ticks_per_beat - p.tick;
       f64 p_frm_off = (f64)p_tick_off * d->tpf;
@@ -292,7 +290,7 @@ int jackosc_fps_handler(jack_nframes_t fps, void *PTR)
 
 void jackosc_usage(void)
 {
-  eprintf("Usage: jack.osc [ options ]\n");
+  eprintf("Usage: jack-osc [ options ]\n");
   eprintf("   -c  Drift correction interval in periods (default=64).\n");
   eprintf("   -p  Port number (default=57130).\n");
   FAILURE;
@@ -338,7 +336,7 @@ int main(int argc, char *argv[])
   }
   d.fd = socket_udp(0);
   bind_inet(d.fd, NULL, port_n);
-  d.client = jack_client_unique("jack.osc");
+  d.client = jack_client_unique("jack-osc");
   jack_set_error_function(jack_client_minimal_error_handler);
   jack_set_sample_rate_callback(d.client, jackosc_fps_handler, &d);
   jack_on_shutdown(d.client, jack_client_minimal_shutdown_handler, 0);
@@ -353,4 +351,4 @@ int main(int argc, char *argv[])
   free_client_register(d.cr);
   exit(0);
   return 0;
-}  
+}
diff --git a/jack.osc.text b/jack-osc.text
similarity index 87%
rename from jack.osc.text
rename to jack-osc.text
index 3799ebc..e37d9dc 100644
--- a/jack.osc.text
+++ b/jack-osc.text
@@ -1,15 +1,14 @@
-JACK.OSC(1)
+JACK-OSC(1)
 ===========
 Rohan Drape <rd at slavepianos.org>
 
-
 NAME
 ----
-jack.osc - JACK Transport Publication Daemon
+jack-osc - JACK Transport Publication Daemon
 
 SYNOPSIS
 --------
-jack.osc [options]
+jack-osc [options]
 
 OPTIONS
 -------
@@ -20,14 +19,14 @@ OPTIONS
 
 DESCRIPTION
 -----------
-jack.osc publishes the transport state of the local JACK server as OSC
-packets over a UDP connection.  jack.osc allows any OSC enabled
+jack-osc publishes the transport state of the local JACK server as OSC
+packets over a UDP connection.  jack-osc allows any OSC enabled
 application to act as a JACK transport client, receiving sample
 accurate pulse stream timing data, and monitoring and initiating
 transport state change.
 
 Clients request to receive timing and change notification packets by
-sending a "request notification" packet, '/receive', to the jack.osc
+sending a "request notification" packet, '/receive', to the jack-osc
 server.  This packet has the form
 
     /receive category
@@ -59,7 +58,7 @@ client from the register send a request with a category value of
 negative one.
 
 After requesting notification the client will receive all relevant
-timing packets sent by the server.  All jack.osc timing packets are
+timing packets sent by the server.  All jack-osc timing packets are
 sent at the start of a JACK period as OSC message and have the same
 shape:
 
@@ -73,7 +72,7 @@ is a signed 64bit integer frame counter the absolute value of which is
 not defined but which increments synchronously with the ntp and utc
 time stamps.  arg...  is the set of tag specific arguments.
 
-The timing packets sent by jack.osc are:
+The timing packets sent by jack-osc are:
 
 /pulse ntp utc frm p-ntp p-utc p-frm pulse
 :   Pulse Location.  This packet indicates that the nearest frame to
@@ -95,11 +94,11 @@ The timing packets sent by jack.osc are:
 /drift ntp utc frm ntp-dif utc-dif
 :   Drift Correction.  This packet is sent whenever the clock drift
     correction is run.  The frequency of this is set by the *-c*
-    option to the jack.osc server.  The integer value ntp-dif is the
+    option to the jack-osc server.  The integer value ntp-dif is the
     NTP form of the corrected drift value and utc-dif the UTC form.
     Since JACK is a sample clock there is no frame drift value.
 
-The state change packets sent by jack.osc are:
+The state change packets sent by jack-osc are:
 
 /transport ntp utc frm fps ppm ppc pt state
 :   Transport state change.  This packet is sent whenever the JACK
@@ -131,10 +130,10 @@ changes.
 
 Clients initiate a change in transport roll state by sending a
 "request transport operation" packet, '/start' or '/stop' to the
-jack.osc server.  Neither requires an argument.
+jack-osc server.  Neither requires an argument.
 
 Clients initiate a change in transport location by sending a "request
-locate operation" packet, '/locate', to the jack.osc server.  It has
+locate operation" packet, '/locate', to the jack-osc server.  It has
 the shape:
 
     /locate location
@@ -143,19 +142,19 @@ where the single precision real value location is the requested
 transport location in seconds.
 
 Clients can connect and disconnect ports by sending '/connect' and
-'/disconnect' messages to the jack.osc server.  Both have the shape:
+'/disconnect' messages to the jack-osc server.  Both have the shape:
 
    /[dis]connect left right
 
-jack.osc implements only a subset of the OSC protocol.  In particular
+jack-osc implements only a subset of the OSC protocol.  In particular
 it does not implement the patten matching rules and does not implement
 a scheduler for incoming messages.
 
-jack.osc drops all unrecognized incoming packets.
+jack-osc drops all unrecognized incoming packets.
 
 AUTHOR
 ------
-Rohan Drape <http://slavepianos.org/rd/>
+Rohan Drape <http://rd.slavepianos.org/>
 
 SEE ALSO
 --------
diff --git a/jack.play.c b/jack-play.c
similarity index 87%
rename from jack.play.c
rename to jack-play.c
index c448b11..70b09eb 100644
--- a/jack.play.c
+++ b/jack-play.c
@@ -1,29 +1,27 @@
-/***** jack.play.c - (c) rohan drape, 2003-2010 *****/
-
-#include <unistd.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <string.h>
-#include <stdbool.h>
-#include <pthread.h>
+#include <unistd.h>
 
 #include <jack/jack.h>
 #include <jack/thread.h>
 
 #include <samplerate.h>
 
-#include "common/failure.h"
-#include "common/file.h"
-#include "common/int.h"
-#include "common/jack-client.h"
-#include "common/jack-ringbuffer.h"
-#include "common/jack-port.h"
-#include "common/jack-transport.h"
-#include "common/memory.h"
-#include "common/observe-signal.h"
-#include "common/print.h"
-#include "common/sound-file.h"
+#include "c-common/failure.h"
+#include "c-common/file.h"
+#include "c-common/int.h"
+#include "c-common/jack-client.h"
+#include "c-common/jack-ringbuffer.h"
+#include "c-common/jack-port.h"
+#include "c-common/jack-transport.h"
+#include "c-common/memory.h"
+#include "c-common/observe-signal.h"
+#include "c-common/print.h"
+#include "c-common/sound-file.h"
 
 struct player_opt
 {
@@ -59,38 +57,33 @@ struct player
 
 /* Read the sound file from disk and write to the ring buffer until
    the end of file, at which point return. */
-
 void *disk_proc(void *PTR)
 {
   struct player *d = (struct player *)PTR;
   while(!observe_end_of_process()) {
 
     /* Handle seek request. */
-
     if(d->o.seek_request >= 0) {
       sf_count_t err = sf_seek(d->sound_file,
 			       (sf_count_t)d->o.seek_request, SEEK_SET);
       if(err == -1) {
-	eprintf("jack.play: seek request failed, %ld\n",
+	eprintf("jack-play: seek request failed, %ld\n",
 		(long)d->o.seek_request);
       }
       d->o.seek_request = -1;
     }
 
     /* Wait for write space at the ring buffer. */
-
     int nbytes = d->o.minimal_frames * sizeof(float) * d->channels;
     nbytes = jack_ringbuffer_wait_for_write(d->rb, nbytes, d->pipe[0]);
 
     /* Do not overflow the local buffer. */
-
     if(nbytes > d->buffer_bytes) {
-      eprintf("jack.play: impossible condition, write space.\n");
+      eprintf("jack-play: impossible condition, write space.\n");
       nbytes = d->buffer_bytes;
     }
 
     /* Read sound file data, which *must* be frame aligned. */
-
     int nframes =(nbytes / sizeof(float))/ d->channels;
     int nsamples = nframes * d->channels;
     sf_count_t err = xsf_read_float(d->sound_file,
@@ -106,7 +99,6 @@ void *disk_proc(void *PTR)
     }
 
     /* Write data to ring buffer. */
-
     jack_ringbuffer_write(d->rb,
 			  (char *)d->d_buffer,
 			  (size_t)err * sizeof(float));
@@ -138,7 +130,6 @@ void signal_set(float **s, int n, int c, float z)
 /* Write data from the ring buffer to the JACK output ports.  If the
    disk thread is late, ie. the ring buffer is empty print a warning
    and zero the output ports.  */
-
 int signal_proc(jack_nframes_t nframes, void *PTR)
 {
   struct player *d = (struct player *)PTR;
@@ -146,15 +137,13 @@ int signal_proc(jack_nframes_t nframes, void *PTR)
   int nbytes = nsamples * sizeof(float);
 
   /* Ensure the period size is workable. */
-
   if(nbytes >= d->buffer_bytes) {
-    eprintf("jack.play: period size exceeds limit\n");
+    eprintf("jack-play: period size exceeds limit\n");
     FAILURE;
     return 1;
   }
 
   /* Get port data buffers. */
-
   int i,j;
   for(i = 0; i < d->channels; i++) {
     d->out[i] = (float *)jack_port_get_buffer(d->output_port[i], nframes);
@@ -163,7 +152,6 @@ int signal_proc(jack_nframes_t nframes, void *PTR)
   /* Write silence if the transport is stopped.  If stopped the disk
      thread will sleep and signals will be ignored, so check here
      also. */
-
   if(d->o.transport_aware && !jack_transport_is_rolling(d->client)) {
     if(observe_end_of_process ()) {
       FAILURE;
@@ -176,19 +164,17 @@ int signal_proc(jack_nframes_t nframes, void *PTR)
 
   /* Get data from sample rate converter, this returns the number of
      frames acquired. */
-
   long err = src_callback_read (d->src,
 				d->o.src_ratio,
 				(long)nframes,
 				d->j_buffer);
   if(err==0) {
-    eprintf("jack.play: sample rate converter failed: %s\n",
+    eprintf("jack-play: sample rate converter failed: %s\n",
 	    src_strerror(src_error(d->src)));
     FAILURE;
   }
 
   /* Uninterleave available data to the output buffers. */
-
   for(i = 0; i < err; i++) {
     for(j = 0; j < d->channels; j++) {
       d->out[j][i] = d->j_buffer[(i*d->channels)+j];
@@ -199,9 +185,8 @@ int signal_proc(jack_nframes_t nframes, void *PTR)
      output buffers.  The print statement is not correct, a this
      should set a flag and have another thread take appropriate
      action. */
-
   if(err < nframes) {
-    eprintf("jack.play: disk thread late (%ld < %d)\n", err, nframes);
+    eprintf("jack-play: disk thread late (%ld < %d)\n", err, nframes);
     for(i = err; i < nframes; i++) {
       for(j = 0; j < d->channels; j++) {
 	d->out[j][i] = 0.0;
@@ -218,16 +203,14 @@ int signal_proc(jack_nframes_t nframes, void *PTR)
      will not block.  The number of bytes that can accumulate in the
      pipe is a factor of the relative sizes of the ring buffer and the
      process callback, but should in no case be very large. */
-
   char b = 1;
   xwrite(d->pipe[1], &b, 1);
-
   return 0;
 }
 
 void usage(void)
 {
-  eprintf("Usage: jack.play [ options ] sound-file...\n");
+  eprintf("Usage: jack-play [ options ] sound-file...\n");
   eprintf("    -b N : Ring buffer size in frames (default=4096).\n");
   eprintf("    -c N : ID of conversion algorithm (default=2, SRC_SINC_FASTEST).\n");
   eprintf("    -i N : Initial disk seek in frames (default=0).\n");
@@ -243,7 +226,6 @@ void usage(void)
    the actual result size, and therefore have two error cases.  Since
    there is no alternative but to drop sample data in any case it does
    not matter much. */
-
 long read_input_from_rb(void *PTR, float **buf)
 {
   struct player *d = PTR;
@@ -258,7 +240,7 @@ long read_input_from_rb(void *PTR, float **buf)
 
   /* SRC locks up if we return zero here, return a silent frame */
   if(err==0) {
-    eprintf("jack.play: ringbuffer empty... zeroing data\n");
+    eprintf("jack-play: ringbuffer empty... zeroing data\n");
     memset(d->k_buffer, 0, (size_t)nsamples * sizeof(float));
     err = d->o.rb_request_frames;
   }
@@ -274,15 +256,13 @@ int jackplay(const char *file_name,
   observe_signals ();
 
   /* Open sound file. */
-
   SF_INFO sfinfo;
   d.sound_file = xsf_open(file_name, SFM_READ, &sfinfo);
   d.channels = sfinfo.channels;
 
   /* Allocate channel based data. */
-
   if(d.channels < 1) {
-    eprintf("jack.play: illegal number of channels in file: %d\n",
+    eprintf("jack-play: illegal number of channels in file: %d\n",
 	    d.channels);
     FAILURE;
   }
@@ -290,7 +270,6 @@ int jackplay(const char *file_name,
   d.output_port = xmalloc(d.channels * sizeof(jack_port_t *));
 
   /* Allocate buffers. */
-
   d.buffer_samples = d.o.buffer_frames * d.channels;
   d.buffer_bytes = d.buffer_samples * sizeof(float);
   d.d_buffer = xmalloc(d.buffer_bytes);
@@ -306,30 +285,26 @@ int jackplay(const char *file_name,
 			    &err,
 			    &d);
   if(!d.src) {
-    eprintf("jack.play: sample rate conversion setup failed: %s\n",
+    eprintf("jack-play: sample rate conversion setup failed: %s\n",
 	    src_strerror(err));
     FAILURE;
   }
 
   /* Create communication pipe. */
-
   xpipe(d.pipe);
 
   /* Become a client of the JACK server.  */
-
   if(d.o.unique_name) {
     d.client = jack_client_unique_store(d.o.client_name);
   } else {
     d.client = jack_client_open(d.o.client_name,JackNullOption,NULL);
   }
   if(!d.client) {
-    eprintf("jack.play: could not create jack client: %s", d.o.client_name);
+    eprintf("jack-play: could not create jack client: %s", d.o.client_name);
     FAILURE;
   }
 
-
   /* Start disk thread, the priority number is a random guess.... */
-
   jack_client_create_thread (d.client,
 			     &(d.disk_thread),
 			     50,
@@ -338,7 +313,6 @@ int jackplay(const char *file_name,
 			     &d);
 
   /* Set error, process and shutdown handlers. */
-
   jack_set_error_function(jack_client_minimal_error_handler);
   jack_on_shutdown(d.client, jack_client_minimal_shutdown_handler, 0);
   if(d.o.transport_aware) {
@@ -346,37 +320,34 @@ int jackplay(const char *file_name,
   }
   jack_set_process_callback(d.client, signal_proc, &d);
 
-  /* Inform the user of sample-rate mismatch. */
-
-  int osr = jack_get_sample_rate(d.client);
-  int isr = sfinfo.samplerate;
+  /* Inform the user of sample-rate mismatch and set SRC ratio. */
+  double osr = (double) jack_get_sample_rate(d.client);
+  double isr = (double) sfinfo.samplerate;
   if(osr != isr) {
     d.o.src_ratio *= (osr / isr);
-    eprintf("jack.play: resampling, sample rate of file != server, %d != %d\n",
+    eprintf("jack-play: resampling, sample rate of file != server, %G != %G (%G)\n",
 	    isr,
-	    osr);
+	    osr,
+            d.o.src_ratio);
   }
 
   /* Create output ports, connect if env variable set and activate
      client. */
-
   jack_port_make_standard(d.client, d.output_port, d.channels, true);
   jack_client_activate(d.client);
   char *dst_pattern = getenv("JACK_PLAY_CONNECT_TO");
   if (dst_pattern) {
     char src_pattern[128];
     snprintf(src_pattern,128,"%s:out_%%d",d.o.client_name);
-    jack_port_connect_pattern(d.client,d.channels,src_pattern,dst_pattern);
+    jack_port_connect_pattern(d.client,d.channels,0,src_pattern,dst_pattern);
   }
 
   /* Wait for disk thread to end, which it does when it reaches the
      end of the file or is interrupted. */
-
   pthread_join(d.disk_thread, NULL);
 
   /* Close sound file, free ring buffer, close JACK connection, close
      pipe, free data buffers, indicate success. */
-
   jack_client_close(d.client);
   sf_close(d.sound_file);
   jack_ringbuffer_free(d.rb);
@@ -404,7 +375,7 @@ int main(int argc, char *argv[])
   o.src_ratio = 1.0;
   o.rb_request_frames = 64;
   o.converter = SRC_SINC_FASTEST;
-  strncpy(o.client_name, "jack.play", 64);
+  strncpy(o.client_name, "jack-play", 64);
 
   while((c = getopt(argc, argv, "b:c:hi:m:n:q:r:tu")) != -1) {
     switch(c) {
@@ -439,7 +410,7 @@ int main(int argc, char *argv[])
       o.unique_name = false;
       break;
     default:
-      eprintf("jack.play: illegal option, %c\n", c);
+      eprintf("jack-play: illegal option, %c\n", c);
       usage ();
       break;
     }
@@ -449,7 +420,7 @@ int main(int argc, char *argv[])
   }
   int i;
   for(i = optind; i < argc; i++) {
-    printf("jack.play: %s\n", argv[i]);
+    printf("jack-play: %s\n", argv[i]);
     jackplay(argv[i], o);
   }
   return EXIT_SUCCESS;
diff --git a/jack.play.text b/jack-play.text
similarity index 71%
rename from jack.play.text
rename to jack-play.text
index 893dcbb..7d8545b 100644
--- a/jack.play.text
+++ b/jack-play.text
@@ -1,15 +1,14 @@
-JACK.PLAY(1)
+JACK-PLAY(1)
 ============
 Rohan Drape <rd at slavepianos.org>
 
-
 NAME
 ----
-jack.play - JACK Sound File Player
+jack-play - JACK Sound File Player
 
 SYNOPSIS
 --------
-jack.play [options] sound-file...
+jack-play [options] sound-file...
 
 OPTIONS
 -------
@@ -20,8 +19,8 @@ OPTIONS
 
 *-c*
 :   Set the sample rate conversion algorithm (default=2).  Values are:
-    SRC_SINC_BEST_QUALITY = 0, SRC_SINC_MEDIUM_QUALITY = 1,
-    SRC_SINC_FASTEST = 2, SRC_ZERO_ORDER_HOLD = 3 and SRC_LINEAR = 4.
+    `SRC_SINC_BEST_QUALITY` = 0, `SRC_SINC_MEDIUM_QUALITY` = 1,
+    `SRC_SINC_FASTEST` = 2, `SRC_ZERO_ORDER_HOLD` = 3 and `SRC_LINEAR` = 4.
 
 *-i*
 :   Set the initial disk seek in frames (default=0).
@@ -31,7 +30,7 @@ OPTIONS
     is an optimization switch.
 
 *-n*
-:   Set the client name (default=jack.play).
+:   Set the client name (default=jack-play).
 
 *-q*
 :   Set the frame size to request data from the ringbuffer
@@ -48,18 +47,18 @@ OPTIONS
 
 DESCRIPTION
 -----------
-jack.play is a light-weight JACK sound file player. It creates as many
+jack-play is a light-weight JACK sound file player. It creates as many
 output ports as there are channels in the input file.  It will connect
 to ports mentioned in the environment variable JACK_PLAY_CONNECT_TO
 which must include a %d pattern to indicate port number, otherwise it
-implements no connection logic, use jack.plumbing(1) instead.
+implements no connection logic, use jack-plumbing(1) instead.
 
-jack.play will read files in any format supported by libsndfile, and
+jack-play will read files in any format supported by libsndfile, and
 will resample to match the server sample rate using libsamplerate.
 
 AUTHOR
 ------
-Written by Rohan Drape <http://slavepianos.org/rd/>
+Written by Rohan Drape <http://rd.slavepianos.org/>
 
 SEE ALSO
 --------
diff --git a/jack.plumbing.c b/jack-plumbing.c
similarity index 97%
rename from jack.plumbing.c
rename to jack-plumbing.c
index 203e5dc..fa9b5a0 100644
--- a/jack.plumbing.c
+++ b/jack-plumbing.c
@@ -1,5 +1,3 @@
-/***** jack.plumbing.c - (c) rohan drape, 2003-2010 *****/
-
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -13,19 +11,19 @@
 #include <pthread.h>
 #include <pthread.h>
 
-#include "common/file.h"
-#include "common/jack-client.h"
-#include "common/jack-port.h"
-#include "common/print.h"
-#include "common/xregcomp.h"
-#include "common/time-timespec.h"
+#include "c-common/file.h"
+#include "c-common/jack-client.h"
+#include "c-common/jack-port.h"
+#include "c-common/print.h"
+#include "c-common/xregcomp.h"
+#include "c-common/time-timespec.h"
 
 #define MAX_SETS      8
 #define MAX_RULES     512
 #define MAX_STR       512
 #define MAX_SUBEXP    4
 #define DEFAULT_DELAY 30000
-#define SYS_RULESET   "/etc/jack.plumbing"
+#define SYS_RULESET   "/etc/jack-plumbing"
 
 enum action {
   ignore,
@@ -42,7 +40,7 @@ struct rule
   regex_t left_c;
   char right[MAX_STR];
 };
- 
+
 struct plumber
 {
   struct rule r[MAX_RULES];     /* The rule set. */
@@ -211,7 +209,7 @@ static void
 append_ordinary_rule_files(struct plumber *p)
 {
   append_rule_file(p, SYS_RULESET);
-  append_rule_file(p, "%s/.jack.plumbing", getenv("HOME"));
+  append_rule_file(p, "%s/.jack-plumbing", getenv("HOME"));
 }
 
 /* Add implicit connect rules at `p'.  */
@@ -338,7 +336,7 @@ right_applies_p(const char *p_l, const char *r, const char *p_r,
   regex_t rr;
   xregcomp(&rr, rhs, REG_NOSUB | REG_EXTENDED);
   int err = regexec(&rr, p_r, 0, NULL, 0);
-  regfree(&rr); 
+  regfree(&rr);
   return  err == 0;
 }
 
@@ -464,7 +462,7 @@ wait_on_connection_set(struct plumber *p)
     struct timespec t;
     t = usec_to_timespec(p-> u);
     p->w = 0;
-    nanosleep(&t, NULL); 
+    nanosleep(&t, NULL);
     eprintf("sleeping %d\n",p->w);
   }
   eprintf ("out of while loop\n");
@@ -529,7 +527,7 @@ init_plumber_defaults(struct plumber *p)
 static void
 init_plumber_connection(struct plumber *p)
 {
-  p->j = jack_client_unique("jack.plumbing");
+  p->j = jack_client_unique("jack-plumbing");
 }
 
 static void
@@ -538,7 +536,7 @@ finalize_plumber(struct plumber *p)
   jack_client_close(p->j);
   pthread_cond_destroy(&p->cond);
   pthread_mutex_destroy(&p->lock);
-} 
+}
 
 #ifdef HAVE_SYS_INOTIFY_H
 
@@ -598,7 +596,7 @@ as_daemon(struct plumber *p)
 static void
 plumber_usage(void)
 {
-  eprintf("Usage: jack.plumbing [ options ] [ rule-files ]\n");
+  eprintf("Usage: jack-plumbing [ options ] [ rule-files ]\n");
   eprintf("    -d   : Do not start as daemon.\n");
   eprintf("    -o   : Do not acquire ordinary rule files.\n");
   eprintf("    -q   : Quiet operation.\n");
diff --git a/jack.plumbing.text b/jack-plumbing.text
similarity index 82%
rename from jack.plumbing.text
rename to jack-plumbing.text
index 629e718..9355979 100644
--- a/jack.plumbing.text
+++ b/jack-plumbing.text
@@ -1,15 +1,15 @@
-JACK.PLUMBING(1)
+JACK-PLUMBING(1)
 ===============
 Rohan Drape <rd at slavepianos.org>
 
 
 NAME
 ----
-jack.plumbing - JACK Plumbing Daemon
+jack-plumbing - JACK Plumbing Daemon
 
 SYNOPSIS
 --------
-jack.plumbing [options] [rule-files]
+jack-plumbing [options] [rule-files]
 
 OPTIONS
 -------
@@ -29,8 +29,8 @@ OPTIONS
 
 DESCRIPTION
 -----------
-jack.plumbing maintains a set of port connection rules and manages
-these as clients register ports with JACK.  Port names are implicitly
+jack-plumbing maintains a set of port connection rules and manages
+these as clients register ports with JACK-  Port names are implicitly
 bounded regular expressions and support sub-expression patterns.
 
 There are four rules: connect, disconnect, also-connect and
@@ -44,9 +44,9 @@ output ports it registers are connected to appropriate ALSA playback
 ports.  The connect rule only makes a connection if none already
 exist.
 
-    (also-connect "system:playback_1" "jack.udp-[0-9]*:in_1")
+    (also-connect "system:playback_1" "jack-udp-[0-9]*:in_1")
 
-This also-connect rule ensures that when jack.udp(1) is running in
+This also-connect rule ensures that when jack-udp(1) is running in
 send mode all signals that are ordinarily sent to the local audio
 interface will also be sent to the network destination.  The
 also-connect aliasing applies to both the left and right hand side of
@@ -72,8 +72,8 @@ empty it is a no-op, it does not write any files, it does not require
 any modification to clients or to how clients are started.
 
 When a set of port registrations is made it checks the modification
-time of the rule set files, '/etc/jack.plumbing' and
-'~/.jack.plumbing', and any files specified by the user, rereads the
+time of the rule set files, '/etc/jack-plumbing' and
+'~/.jack-plumbing', and any files specified by the user, rereads the
 rule set if it has been updated, then makes the JACK graph obey the
 rules.
 
@@ -84,8 +84,8 @@ connect rules, then connect-exclusive rules.
 
 FILES
 -----
-* /etc/jack.plumbing
-* ~/.jack.plumbing
+* /etc/jack-plumbing
+* ~/.jack-plumbing
 
 AUTHOR
 ------
diff --git a/jack.record.c b/jack-record.c
similarity index 75%
rename from jack.record.c
rename to jack-record.c
index 3cea3d4..52fd95c 100644
--- a/jack.record.c
+++ b/jack-record.c
@@ -1,5 +1,3 @@
-/***** jack.record.c - (c) rohan drape, 2003-2006 *****/
-
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -7,16 +5,16 @@
 #include <string.h>
 #include <pthread.h>
 
-#include "common/failure.h"
-#include "common/file.h"
-#include "common/jack-client.h"
-#include "common/jack-port.h"
-#include "common/jack-ringbuffer.h"
-#include "common/memory.h"
-#include "common/observe-signal.h"
-#include "common/print.h"
-#include "common/signal-interleave.h"
-#include "common/sound-file.h"
+#include "c-common/failure.h"
+#include "c-common/file.h"
+#include "c-common/jack-client.h"
+#include "c-common/jack-port.h"
+#include "c-common/jack-ringbuffer.h"
+#include "c-common/memory.h"
+#include "c-common/observe-signal.h"
+#include "c-common/print.h"
+#include "c-common/signal-interleave.h"
+#include "c-common/sound-file.h"
 
 struct recorder
 {
@@ -53,7 +51,7 @@ void write_to_disk(struct recorder *d, int nframes)
 		      p,
 		      (sf_count_t)nframes);
       p += nframes;
-    }  
+    }
   } else {
     int nsamples = nframes * d->channels;
     xsf_write_float(d->sound_file[0],
@@ -68,32 +66,27 @@ void *disk_thread_procedure(void *PTR)
   while(!observe_end_of_process()) {
 
     /* Wait for data at the ring buffer. */
-
     int nbytes = d->minimal_frames * sizeof(float) * d->channels;
-    nbytes = jack_ringbuffer_wait_for_read(d->ring_buffer, nbytes, 
+    nbytes = jack_ringbuffer_wait_for_read(d->ring_buffer, nbytes,
 					   d->pipe[0]);
 
     /* Drop excessive data to not overflow the local buffer. */
-
     if(nbytes > d->buffer_bytes) {
-      eprintf("jack.record: impossible condition, read space.\n");
+      eprintf("jack-record: impossible condition, read space.\n");
       nbytes = d->buffer_bytes;
     }
 
     /* Read data from the ring buffer. */
-
     jack_ringbuffer_read(d->ring_buffer,
-			 (char *) d->d_buffer, 
+			 (char *) d->d_buffer,
 			 nbytes);
-    
+
     /* Do write operation.  The sample count *must* be an integral
        number of frames. */
-
     int nframes = (nbytes / sizeof(float))/ d->channels;
     write_to_disk(d, nframes);
 
     /* Handle timer */
-
     d->timer_counter += nframes;
     if(d->timer_frames > 0 && d->timer_counter >= d->timer_frames) {
       return NULL;
@@ -105,7 +98,6 @@ void *disk_thread_procedure(void *PTR)
 /* Write data from the JACK input ports to the ring buffer.  If the
    disk thread is late, ie. the ring buffer is full, print an error
    and halt the client.  */
-
 int process(jack_nframes_t nframes, void *PTR)
 {
   struct recorder *d = (struct recorder *) PTR;
@@ -113,7 +105,6 @@ int process(jack_nframes_t nframes, void *PTR)
   int nbytes = nsamples * sizeof(float);
 
   /* Get port data buffers. */
-
   int i;
   for(i = 0; i < d->channels; i++) {
     d->in[i] = (float *) jack_port_get_buffer(d->input_port[i], nframes);
@@ -121,40 +112,36 @@ int process(jack_nframes_t nframes, void *PTR)
 
   /* Check period size is workable. If the buffer is large, ie 4096
      frames, this should never be of practical concern. */
-
   if(nbytes >= d->buffer_bytes) {
-    eprintf("jack.record: period size exceeds limit\n");
+    eprintf("jack-record: period size exceeds limit\n");
     FAILURE;
     return 1;
   }
 
   /* Check that there is adequate space in the ringbuffer. */
-
   int space = (int) jack_ringbuffer_write_space(d->ring_buffer);
   if(space < nbytes) {
-    eprintf("jack.record: overflow error, %d > %d\n", nbytes, space);
+    eprintf("jack-record: overflow error, %d > %d\n", nbytes, space);
     FAILURE;
     return 1;
   }
-    
-  /* Interleave input to buffer and copy into ringbuffer. */
 
-  signal_interleave_to(d->j_buffer, 
-		       (const float **)d->in, 
-		       nframes, 
+  /* Interleave input to buffer and copy into ringbuffer. */
+  signal_interleave_to(d->j_buffer,
+		       (const float **)d->in,
+		       nframes,
 		       d->channels);
   int err = jack_ringbuffer_write(d->ring_buffer,
 				  (char *) d->j_buffer,
 				  (size_t) nbytes);
   if(err != nbytes) {
-    eprintf("jack.record: error writing to ringbuffer, %d != %d\n", 
+    eprintf("jack-record: error writing to ringbuffer, %d != %d\n",
 	    err, nbytes);
     FAILURE;
     return 1;
   }
-  
-  /* Poke the disk thread to indicate data is on the ring buffer. */
 
+  /* Poke the disk thread to indicate data is on the ring buffer. */
   char b = 1;
   xwrite(d->pipe[1], &b, 1);
 
@@ -163,13 +150,15 @@ int process(jack_nframes_t nframes, void *PTR)
 
 void usage(void)
 {
-  eprintf("Usage: jack.record [ options ] sound-file\n");
-  eprintf("    -b N : Ring buffer size in frames (default=4096).\n");
-  eprintf("    -f N : File format (default=0x10006).\n");
-  eprintf("    -m N : Minimal disk read size in frames (default=32).\n");
-  eprintf("    -n N : Number of channels (default=2).\n");
-  eprintf("    -s   : Write to multiple single channel sound files.\n");
-  eprintf("    -t N : Set a timer to record for N seconds (default=-1).\n");
+  eprintf("Usage: jack-record [options] sound-file\n");
+  eprintf("  -b N : Ring buffer size in frames (default=4096).\n");
+  eprintf("  -f N : File format (default=0x10006).\n");
+  eprintf("  -m N : Minimal disk transfer size in frames (default=32).\n");
+  eprintf("  -n N : Number of channels (default=2).\n");
+  eprintf("  -o N : Jack port source offset (default=0).\n");
+  eprintf("  -p S : Jack port pattern to connect to (default=nil).\n");
+  eprintf("  -s   : Write to multiple single channel sound files.\n");
+  eprintf("  -t N : Set a timer to record for N seconds (default=-1).\n");
   FAILURE;
 }
 
@@ -185,7 +174,9 @@ int main(int argc, char *argv[])
   d.file_format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
   d.multiple_sound_files = 0;
   int c;
-  while((c = getopt(argc, argv, "b:f:hm:n:st:")) != -1) {
+  char *p = NULL;
+  int o = 0;
+  while((c = getopt(argc, argv, "b:f:hm:n:o:p:st:")) != -1) {
     switch(c) {
     case 'b':
       d.buffer_frames = (int) strtol(optarg, NULL, 0);
@@ -202,6 +193,13 @@ int main(int argc, char *argv[])
     case 'n':
       d.channels = (int) strtol(optarg, NULL, 0);
       break;
+    case 'o':
+      o = (int) strtol(optarg, NULL, 0);
+      break;
+    case 'p':
+      p = malloc(128);
+      strncpy(p,optarg,128);
+      break;
     case 's':
       d.multiple_sound_files = 1;
       break;
@@ -209,7 +207,7 @@ int main(int argc, char *argv[])
       d.timer_seconds = (float) strtod(optarg, NULL);
       break;
     default:
-      eprintf("jack.record: illegal option, %c\n", c);
+      eprintf("jack-record: illegal option, %c\n", c);
       usage ();
       break;
     }
@@ -219,9 +217,8 @@ int main(int argc, char *argv[])
   }
 
   /* Allocate channel based data. */
-
   if(d.channels < 1) {
-    eprintf("jack.record: illegal number of channels: %d\n", d.channels);
+    eprintf("jack-record: illegal number of channels: %d\n", d.channels);
     FAILURE;
   }
   d.in = xmalloc(d.channels * sizeof(float *));
@@ -229,15 +226,14 @@ int main(int argc, char *argv[])
   d.input_port = xmalloc(d.channels * sizeof(jack_port_t *));
 
   /* Connect to JACK. */
-  
-  jack_client_t *client = jack_client_unique("jack.record");
+  char client_name[64] = "jack-record";
+  jack_client_t *client = jack_client_unique_store(client_name);
   jack_set_error_function(jack_client_minimal_error_handler);
   jack_on_shutdown(client, jack_client_minimal_shutdown_handler, 0);
   jack_set_process_callback(client, process, &d);
   d.sample_rate = jack_get_sample_rate(client);
 
   /* Setup timer. */
-
   if(d.timer_seconds < 0.0) {
     d.timer_frames = -1;
   } else {
@@ -245,16 +241,15 @@ int main(int argc, char *argv[])
   }
 
   /* Create sound file. */
-
-  SF_INFO sfinfo; 
+  SF_INFO sfinfo;
   sfinfo.samplerate = (int) d.sample_rate;
   sfinfo.frames = 0;
   sfinfo.format = d.file_format;
   if(d.multiple_sound_files) {
     if(!strstr(argv[optind], "%d")) {
-      eprintf("jack.record: illegal template, '%s'\n", argv[optind]);
+      eprintf("jack-record: illegal template, '%s'\n", argv[optind]);
       usage ();
-    }      
+    }
     sfinfo.channels = 1;
     int i;
     for(i = 0; i < d.channels; i++) {
@@ -268,38 +263,37 @@ int main(int argc, char *argv[])
   }
 
   /* Allocate buffers. */
-  
   d.buffer_samples = d.buffer_frames * d.channels;
   d.buffer_bytes = d.buffer_samples * sizeof(float);
   d.d_buffer = xmalloc(d.buffer_bytes);
-  d.j_buffer = xmalloc(d.buffer_bytes);  
+  d.j_buffer = xmalloc(d.buffer_bytes);
   d.u_buffer = xmalloc(d.buffer_bytes);
   d.ring_buffer = jack_ringbuffer_create(d.buffer_bytes);
 
   /* Create communication pipe. */
-
   xpipe(d.pipe);
 
   /* Start disk thread. */
-
   pthread_create (&(d.disk_thread),
-		  NULL, 
-		  disk_thread_procedure, 
+		  NULL,
+		  disk_thread_procedure,
 		  &d);
 
-  /* Create input ports and activate client. */
-
+  /* Create ports, connect to if given, activate client. */
   jack_port_make_standard(client, d.input_port, d.channels, false);
   jack_client_activate(client);
+  if (p) {
+    char q[128];
+    snprintf(q,128,"%s:in_%%d",client_name);
+    jack_port_connect_pattern(client,d.channels,o,p,q);
+  }
 
   /* Wait for disk thread to end, which it does when it reaches the
      end of the file or is interrupted. */
-
   pthread_join(d.disk_thread, NULL);
 
   /* Close sound file, free ring buffer, close JACK connection, close
      pipe, free data buffers, indicate success. */
-
   jack_client_close(client);
   if(d.multiple_sound_files) {
     int i;
diff --git a/jack.record.text b/jack-record.text
similarity index 77%
rename from jack.record.text
rename to jack-record.text
index e42c382..be8faec 100644
--- a/jack.record.text
+++ b/jack-record.text
@@ -1,15 +1,14 @@
-JACK.RECORD(1)
+JACK-RECORD(1)
 ==============
 Rohan Drape <rd at slavepianos.org>
 
-
 NAME
 ----
-jack.record - JACK Capture Client
+jack-record - JACK Capture Client
 
 SYNOPSIS
 --------
-jack.record [options] sound-file
+jack-record [options] sound-file
 
 OPTIONS
 -------
@@ -22,7 +21,7 @@ OPTIONS
 :   Set the file format (default=0x10006).  The number is a bitwise-or
     of two values, the first describes the file type, the second
     the data type.  The default value of 0x10000 | 0x00006 describes a
-    thirty-two bit floating point WAV file.
+    thirty-two bit floating point WAV file.  0x2 is 16-bit and 0x3 24-bit.
 
 *-m*
 :   Set the minimal disk transfer size in frames (default=32).  This
@@ -31,6 +30,13 @@ OPTIONS
 *-n*
 :   Set the number of input channels to create (default=2).
 
+*-o*
+:   Integer offset for port connection pattern (default=0).
+
+*-p*
+:   A pattern describing the JACK ports to connect to,
+    ie. SuperCollider:out_%d (default=nil).
+
 *-s*
 :   Capture to a set of single channel sound files.  The sound file
     name must be a valid template.
@@ -41,9 +47,9 @@ OPTIONS
 
 DESCRIPTION
 -----------
-jack.record is a light-weight JACK capture client to write an
+jack-record is a light-weight JACK capture client to write an
 arbitrary number of channels to disk.  It implements no connection
-logic, use jack.plumbing(1) instead.
+logic, use jack-plumbing(1) instead.
 
 If the default mode a single multiple channel sound file is written.
 If the *-s* option is given a set of single channel sound files are
@@ -51,7 +57,7 @@ written.  In this case the sound file name must be a valid template,
 the substring %d is replaced with the channel number counting from
 zero.
 
-jack.record will write files in any format supported by libsndfile.
+jack-record will write files in any format supported by libsndfile.
 The table below shows the most common file format masks.  For other
 values see the file 'sndfile.h'.
 
@@ -66,7 +72,7 @@ SF_FORMAT_FLOAT    0x00006   32 bit float data
 
 AUTHOR
 ------
-Rohan Drape <http://slavepianos.org/rd/>
+Rohan Drape <http://rd.slavepianos.org/>
 
 SEE ALSO
 --------
diff --git a/jack.scope.c b/jack-scope.c
similarity index 75%
rename from jack.scope.c
rename to jack-scope.c
index 3f0757c..4538ccd 100644
--- a/jack.scope.c
+++ b/jack-scope.c
@@ -1,5 +1,3 @@
-/***** jack.scope.c - (c) rohan drape, 1998-2006 *****/
-
 #include <stdio.h>
 #include <errno.h>
 #include <sys/types.h>
@@ -12,26 +10,26 @@
 #include <getopt.h>
 #include <math.h>
 
-#include "common/byte-order.h"
-#include "common/failure.h"
-#include "common/file.h"
-#include "common/img.h"
-#include "common/img-ppm.h"
-#include "common/jack-client.h"
-#include "common/jack-port.h"
-#include "common/memory.h"
-#include "common/network.h"
-#include "common/observe-signal.h"
-#include "common/osc.h"
-#include "common/print.h"
-#include "common/signal-copy.h"
-#include "common/signal-clip.h"
-#include "common/signal-interleave.h"
-#include "common/signal-interpolate.h"
-#include "common/ximg.h"
+#include "c-common/byte-order.h"
+#include "c-common/failure.h"
+#include "c-common/file.h"
+#include "c-common/img.h"
+#include "c-common/img-ppm.h"
+#include "c-common/jack-client.h"
+#include "c-common/jack-port.h"
+#include "c-common/memory.h"
+#include "c-common/network.h"
+#include "c-common/observe-signal.h"
+#include "c-common/osc.h"
+#include "c-common/print.h"
+#include "c-common/signal-copy.h"
+#include "c-common/signal-clip.h"
+#include "c-common/signal-interleave.h"
+#include "c-common/signal-interpolate.h"
+#include "c-common/ximg.h"
 
-typedef void (*draw_fn_t) (u8 *, i32, 
-			   const f32 *, i32, i32, i32, 
+typedef void (*draw_fn_t) (u8 *, i32,
+			   const f32 *, i32, i32, i32,
 			   void *);
 
 typedef bool (*control_fn_t) (const u8 *, i32, void *);
@@ -60,6 +58,7 @@ struct scope
   int delay_frames;
   int delay_location;
   int mode;
+  float input_gain;
   int pipe[2];
   char *image_directory;
   int image_cnt;
@@ -83,6 +82,7 @@ jackscope_print(struct scope *d)
   eprintf("DelayFrames     : %d\n", d->delay_frames);
   eprintf("DelayLocation   : %d\n", d->delay_location);
   eprintf("Mode            : %d\n", d->mode);
+  eprintf("InputGain       : %f\n", d->input_gain);
 }
 
 #define OSC_PARSE_MSG(command,types)				\
@@ -113,10 +113,10 @@ embed_draw_grid(u8 *image, i32 size)
 }
 
 static void
-embed_draw_data(u8 *image, i32 size, 
-		const f32 *signal, 
-		i32 n, 
-		const u8 *color, 
+embed_draw_data(u8 *image, i32 size,
+		const f32 *signal,
+		i32 n,
+		const u8 *color,
 		i32 embed, f32 incr)
 {
   if(incr <= 0.0) {
@@ -125,13 +125,13 @@ embed_draw_data(u8 *image, i32 size,
   f32 xindex = 0.0;
   f32 yindex = (f32) embed;
   while(yindex < n) {
-    i32 x = signal_x_to_screen_x(signal_interpolate_safe(signal, 
-							 n, 
+    i32 x = signal_x_to_screen_x(signal_interpolate_safe(signal,
+							 n,
 							 xindex),
 				 size);
-    i32 y = signal_y_to_screen_y(signal_interpolate_safe(signal, 
+    i32 y = signal_y_to_screen_y(signal_interpolate_safe(signal,
 							 n,
-							 yindex), 
+							 yindex),
 				 size);
     xindex += incr;
     yindex += incr;
@@ -149,20 +149,20 @@ embed_init(void)
 }
 
 void
-embed_draw(u8 *image, i32 size, 
-	   const f32 *signal, i32 f, i32 d, i32 c, 
+embed_draw(u8 *image, i32 size,
+	   const f32 *signal, i32 f, i32 d, i32 c,
 	   void *PTR)
 {
   struct embed *e = (struct embed *) PTR;
   embed_draw_grid(image, size);
   i32 i;
   for(i = 0; i < c; i++) {
-    u8 color[12] = {128, 32, 32, 
-		    32, 32, 128, 
-		    128, 224, 224, 
+    u8 color[12] = {128, 32, 32,
+		    32, 32, 128,
+		    128, 224, 224,
 		    224, 224, 128};
-    embed_draw_data(image, size, signal +(i * f), d, 
-		    color +(i * 3), 
+    embed_draw_data(image, size, signal +(i * f), d,
+		    color +(i * 3),
 		    e->embed, e->incr);
   }
 }
@@ -205,8 +205,8 @@ signal_draw_grid(u8 *image, i32 size)
 }
 
 static void
-signal_draw_data(u8 *image, i32 size, 
-		 const f32 *signal, i32 n, 
+signal_draw_data(u8 *image, i32 size,
+		 const f32 *signal, i32 n,
 		 const u8 *color, i32 style)
 {
   i32 i;
@@ -236,7 +236,7 @@ signal_draw_data(u8 *image, i32 size,
       for(j = l; j < r; j++) {
 	img_set_pixel(image, size, i, j, color);
       }
-    }  
+    }
   }
 }
 
@@ -263,21 +263,21 @@ signal_init(void)
 }
 
 void
-signal_draw(u8 *image, i32 size, 
-	    const f32 *signal, i32 f, i32 d, i32 c, 
+signal_draw(u8 *image, i32 size,
+	    const f32 *signal, i32 f, i32 d, i32 c,
 	    void *PTR)
 {
   struct signal *s = (struct signal *) PTR;
   signal_draw_grid(image, size);
   i32 i;
   for(i = 0; i < c; i++) {
-    u8 color[12] = {128, 32, 32, 
-		    32, 32, 128, 
-		    128, 224, 224, 
+    u8 color[12] = {128, 32, 32,
+		    32, 32, 128,
+		    128, 224, 224,
 		    224, 224, 128};
-    signal_draw_data(image, size, 
-		     signal +(i * f), d, 
-		     color +(i * 3), 
+    signal_draw_data(image, size,
+		     signal +(i * f), d,
+		     color +(i * 3),
 		     s->style);
   }
 }
@@ -302,7 +302,7 @@ set_mode(struct scope *d, const char *mode)
   } else if(strncmp("embed", mode, 5)== 0) {
     d->mode = EMBED_MODE;
   } else {
-    eprintf("jack.scope: illegal mode, %s\n", mode);
+    eprintf("jack-scope: illegal mode, %s\n", mode);
   }
 }
 
@@ -315,23 +315,25 @@ jackscope_osc_thread_procedure(void *PTR)
     uint8_t packet[packet_extent];
     int packet_sz = xrecv(d->fd, packet, 32, 0);
     osc_data_t o[1];
-    if(!(d->child_control[0](packet, packet_sz, d->child_data[0])|| 
+    if(!(d->child_control[0](packet, packet_sz, d->child_data[0])||
 	 d->child_control[1](packet, packet_sz, d->child_data[1]))) {
       if(OSC_PARSE_MSG("/frames", ",i")) {
 	d->draw_frames = o[0].i > d->data_frames ? d->data_frames : o[0].i;
       } else if(OSC_PARSE_MSG("/mode", ",s")) {
 	set_mode(d, o[0].s);
+      } else if(OSC_PARSE_MSG("/input-gain", ",f")) {
+	d->input_gain = o[0].f;
       } else if(OSC_PARSE_MSG("/delay", ",f")) {
 	d->delay_msec = o[0].f;
 	d->delay_frames = floorf(( d->delay_msec / 1000.0)* d->fps);
       } else {
-	eprintf("jack.scope: dropped packet: %8s\n", packet); 
+	eprintf("jack-scope: dropped packet: %8s\n", packet);
       }
     }
   }
   return NULL;
 }
-    
+
 /* The data is channel separated into a local buffer, 'local'.  The
    image data 'image' is cleared and a user selected drawing procedure
    is invoked.  The draw procedure must accept any combination of
@@ -341,7 +343,7 @@ void *
 jackscope_draw_thread_procedure(void *PTR)
 {
   struct scope *d = (struct scope *) PTR;
-  Ximg_t *x = ximg_open(d->window_size, d->window_size, "jack.scope");
+  Ximg_t *x = ximg_open(d->window_size, d->window_size, "jack-scope");
   int image_n = d->window_size * d->window_size * 3;
   uint8_t *image = xmalloc(image_n);
   float *local = xmalloc(d->data_samples * sizeof(float));
@@ -351,15 +353,15 @@ jackscope_draw_thread_procedure(void *PTR)
     signal_uninterleave(local, d->share, d->data_frames, d->channels);
     signal_clip(local, d->data_frames * d->channels, -1.0, 1.0);
     memset(image, 255, image_n);
-    d->child_draw[d->mode](image, d->window_size, 
-			   local, d->data_frames, 
-			   d->draw_frames, d->channels, 
+    d->child_draw[d->mode](image, d->window_size,
+			   local, d->data_frames,
+			   d->draw_frames, d->channels,
 			   d->child_data[d->mode]);
     ximg_blit(x, image);
     if(d->image_directory) {
       char name[256];
-      snprintf(name, 256, 
-	       "%s/jack.scope.%06d.ppm", 
+      snprintf(name, 256,
+	       "%s/jack-scope.%06d.ppm",
 	       d->image_directory, d->image_cnt);
       img_write_ppm_file(image, d->window_size, d->window_size, name);
     }
@@ -389,7 +391,7 @@ jackscope_process(jack_nframes_t nframes, void *PTR)
   for(i = 0; i < nframes; i++) {
     int j;
     for(j = 0; j < d->channels; j++) {
-      d->data[k++] = (float) in[j][i];
+      d->data[k++] = (float) in[j][i] * d->input_gain;
       if(k >= d->data_samples) {
 	k = 0;
       }
@@ -410,14 +412,15 @@ jackscope_process(jack_nframes_t nframes, void *PTR)
 void
 jackscope_usage (void)
 {
-  eprintf("Usage: jack.scope [ options ] sound-file\n");
-  eprintf("   -b  Scope size in frames (default=512).\n");
-  eprintf("   -d  Delay time in ms between scope udpates (default=100.0).\n");
-  eprintf("   -f  Request images be stored at location (default=NULL).\n");
-  eprintf("   -m  Scope operating mode (default=signal).\n");
-  eprintf("   -n  Number of channels (default=1).\n");
-  eprintf("   -p  Port number to listen for OSC packets (default=57140).\n");
-  eprintf("   -w  Scope size in pixels (default=512).\n");
+  eprintf("Usage: jack-scope [options] sound-file\n");
+  eprintf(" -b I : Scope size in frames (default=512)\n");
+  eprintf(" -d R : Delay time in ms between scope udpates (default=100)\n");
+  eprintf(" -f S : Request images be stored at location (default=NULL)\n");
+  eprintf(" -m S : Scope operating mode (default=signal)\n");
+  eprintf(" -n I : Number of channels (default=1)\n");
+  eprintf(" -p S : Jack port pattern to connect to (default=nil)\n");
+  eprintf(" -u I : UDP port number for OSC packets (default=57140)\n");
+  eprintf(" -w I : Scope size in pixels (default=512)\n");
   FAILURE;
 }
 
@@ -435,6 +438,7 @@ main(int argc, char **argv)
   d.delay_location = 0;
   d.channels = 1;
   d.mode = SIGNAL_MODE;
+  d.input_gain = 1.0;
   d.child_data[0] = signal_init ();
   d.child_draw[0] = signal_draw;
   d.child_control[0] = signal_control;
@@ -444,9 +448,10 @@ main(int argc, char **argv)
   d.image_directory = NULL;
   d.image_cnt = 0;
   int port_n = 57140;
-  int c;
-  while ((c = getopt (argc, argv, "b:d:e:f:hi:m:n:s:w:")) != -1) {
-    switch (c) {
+  int o;
+  char *p = NULL;
+  while ((o = getopt (argc, argv, "b:d:e:f:hi:m:n:p:s:u:w:")) != -1) {
+    switch (o) {
     case 'b':
       d.data_frames = strtol(optarg, NULL, 0);
       break;
@@ -470,13 +475,17 @@ main(int argc, char **argv)
       }
       break;
     case 'p':
+      p = malloc(128);
+      strncpy(p,optarg,128);
+      break;
+    case 'u':
       port_n = strtol(optarg, NULL, 0);
       break;
     case 'w':
       d.window_size = strtol(optarg, NULL, 0);
       break;
     default:
-      eprintf("jack.scope: illegal option, %c\n", (char)c);
+      eprintf("jack-scope: illegal option, %c\n", (char)o);
       jackscope_usage ();
       break;
     }
@@ -488,20 +497,30 @@ main(int argc, char **argv)
   d.fd = socket_udp(0);
   bind_inet(d.fd, NULL, port_n);
   xpipe(d.pipe);
-  pthread_create(&(d.osc_thread), NULL, 
+  pthread_create(&(d.osc_thread), NULL,
 		 jackscope_osc_thread_procedure, &d);
-  pthread_create(&(d.draw_thread), NULL, 
+  pthread_create(&(d.draw_thread), NULL,
 		 jackscope_draw_thread_procedure, &d);
-  jack_client_t *client = jack_client_unique("jack.scope");
-  jack_set_process_callback(client, jackscope_process, &d);
+  char nm[64] = "jack-scope";
+  jack_client_t *c = jack_client_unique_store(nm);
   jack_set_error_function(jack_client_minimal_error_handler);
-  jack_on_shutdown(client, jack_client_minimal_shutdown_handler, 0);
-  d.fps = (float) jack_get_sample_rate(client);
+  jack_on_shutdown(c, jack_client_minimal_shutdown_handler, 0);
+  jack_set_process_callback(c, jackscope_process, &d);
+  d.fps = (float) jack_get_sample_rate(c);
   d.delay_frames = floorf(( d.delay_msec / 1000.0)* d.fps);
-  jack_port_make_standard(client, d.port, d.channels, 0);
-  jack_client_activate(client);
+  jack_port_make_standard(c, d.port, d.channels, 0);
+  if(jack_client_activate(c)) {
+    eprintf("jack-scope: jack_activate() failed\n");
+    FAILURE;
+  }
+  if (!p) p = getenv("JACK_SCOPE_CONNECT_TO");
+  if (p) {
+    char q[128];
+    snprintf(q,128,"%s:in_%%d",nm);
+    jack_port_connect_pattern(c,d.channels,0,p,q);
+  }
   pthread_join(d.draw_thread, NULL);
-  jack_client_close (client);
+  jack_client_close (c);
   close(d.pipe[0]);
   close(d.pipe[1]);
   free(d.data);
diff --git a/jack.scope.text b/jack-scope.text
similarity index 71%
rename from jack.scope.text
rename to jack-scope.text
index e6b0374..8ae65d0 100644
--- a/jack.scope.text
+++ b/jack-scope.text
@@ -1,15 +1,15 @@
-JACK.SCOPE(1)
+JACK-SCOPE(1)
 =============
 Rohan Drape <rd at slavepianos.org>
 
 
 NAME
 ----
-jack.scope - JACK Oscilloscope
+jack-scope - JACK Oscilloscope
 
 SYNOPSIS
 --------
-jack.scope [options]
+jack-scope [options]
 
 OPTIONS
 -------
@@ -36,7 +36,12 @@ OPTIONS
     channel limit.
 
 *-p*
-:   Set the port number to listen for OSC packets on (default=57140).
+:   A pattern describing the JACK ports to connect to,
+    ie. `SuperCollider:out_%d` (default=nil).  If this is not set
+    consults the environment variable `JACK_SCOPE_CONNECT_TO`.
+
+*-u*
+:   Set the UDP port number to listen for OSC packets on (default=57140).
 
 *-w*
 :   Set the scope size in pixels (default=512).  The scope window is
@@ -44,17 +49,17 @@ OPTIONS
 
 DESCRIPTION
 -----------
-jack.scope is an oscilloscope for JACK under X11.  jack.scope draws
+jack-scope is an oscilloscope for JACK under X11.  jack-scope draws
 either a time domain signal trace or a self correlation trace.
 Multiple input channels are superimposed, each channel is drawn in a
-different color.  jack.scope accepts OSC packets for interactive
+different color.  jack-scope accepts OSC packets for interactive
 control of drawing parameters.
 
-The operating mode of jack.scope is set using *-m*.  In signal mode
-jack.scope draws a time domain signal trace, in embed mode jack.scope
+The operating mode of jack-scope is set using *-m*.  In signal mode
+jack-scope draws a time domain signal trace, in embed mode jack-scope
 draws a self correlation trace.
 
-The size of the jack.scope window is set using *-w*, the scope window
+The size of the jack-scope window is set using *-w*, the scope window
 is square.  The window is of fixed size and has centered gravity.  The
 time interval that is displayed is determined by the frame size, set
 using *-b*.  The image refresh rate is determined by the delay
@@ -62,26 +67,26 @@ interval, set using *-d*.  Note that the interval is truncated to the
 nearest frame boundary and that the time taken to compose the image
 and blit to the screen is indeterminate.
 
-The number of JACK input ports that jack.scope creates and monitors is
+The number of JACK input ports that jack-scope creates and monitors is
 set using *-n*.  Multiple channels are drawn in superimposition, each
 channel is drawn in a distinct color.
 
-In signal mode the trace is drawn in a style set using '/style'.  In
+In signal mode the trace is drawn in a style set using `/style`.  In
 dot mode only the sample pixel in each column is drawn.  In fill mode
 all pixels between the sample pixel and the zero pixel of each column
 are drawn.  In line mode all pixels between the adjacent sample pixels
 of each column are drawn.
 
 In embed mode the trace is a self correlation signal with a sample
-delay set using '/embed'.  The delayed sample is on the x-axis.  The
-interpolation increment is set using '/incr', increment values less
+delay set using `/embed`.  The delayed sample is on the x-axis.  The
+interpolation increment is set using `/incr`, increment values less
 than one result in increasingly continuous trace paths.
 
-jack.scope can store the animation as a sequence of uncompressed
+jack-scope can store the animation as a sequence of uncompressed
 ppm(5) image files.  To request this use the *-f* option with the
 directory files should be written to as the argument.
 
-The OSC messages understood by jack.scope are given in the table
+The OSC messages understood by jack-scope are given in the table
 below.  Each command requires one argument of the indicated type.  The
 last column gives the option that sets the same parameter.
 
@@ -94,7 +99,7 @@ Command   Description        Argument    Option
 /embed    embedding          integer     N/A
 /incr     increment          float       N/A
 
-jack.scope implements no connection logic, use jack.plumbing(1)
+jack-scope implements no connection logic, use jack-plumbing(1)
 instead.
 
 REFERENCES
@@ -104,7 +109,7 @@ Art and Science of Auditory Autocorrelation’’ CMJ, 22/2, 1998.
 
 AUTHOR
 ------
-Rohan Drape <http://slavepianos.org/rd/>
+Rohan Drape <http://rd.slavepianos.org/>
 
 SEE ALSO
 --------
diff --git a/jack.transport.c b/jack-transport.c
similarity index 73%
rename from jack.transport.c
rename to jack-transport.c
index f88312e..7afc78a 100644
--- a/jack.transport.c
+++ b/jack-transport.c
@@ -1,15 +1,17 @@
-/*****  jack.transport.c - (c) rohan drape, 2006-2008 *****/
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <math.h>
-#include <time.h>
 #include <curses.h>
+#include <math.h>
 #include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
 #include <jack/jack.h>
 #include <jack/transport.h>
 
+#include "c-common/jack-client.h"
+
 struct transport {
+  bool verbose;
   bool rolling;
   double time;
   double incr;
@@ -19,15 +21,11 @@ struct transport {
 
 void finish(int sig)
 {
+  fprintf(stderr, "jack-transport: finish\n");
   endwin();
   exit(0);
 }
 
-void shutdown(void *PTR)
-{
-  exit(1);
-}
-
 void getcmd(const char *prompt, char *result, int n)
 {
   move(2,0);
@@ -71,29 +69,49 @@ void offset(struct transport *t, double o)
   locate(t);
 }
 
+void usage(void)
+{
+  printf("Usage: jack-transport [options]\n");
+  printf("   -h: print usage\n");
+  exit(0);
+}
+
 int main(int argc, char **argv)
 {
   struct transport t;
+  int c;
+
+  t.verbose = false;
   t.rolling = false;
   t.time = 0.0;
   t.incr = 5.0;
   t.skip = 60.0;
-  t.jk = jack_client_open("jack.transport", JackNullOption, NULL);
+
+  while((c = getopt(argc, argv, "hv")) != -1) {
+    switch(c) {
+    case 'h': usage(); break;
+    case 'v': t.verbose = true; break;
+    }
+  }
+
+  t.jk = jack_client_open("jack-transport", JackNullOption, NULL);
   if(t.jk) {
-    jack_on_shutdown(t.jk, shutdown, 0);
+    jack_set_error_function(jack_client_minimal_error_handler);
+    jack_on_shutdown(t.jk, jack_client_minimal_shutdown_handler, 0);
     jack_activate(t.jk);
   } else {
-    fprintf(stderr, "jack.transport: could not connect to jack.\n");
+    fprintf(stderr, "jack-transport: could not connect to jack\n");
     exit(1);
   }
-  
+
+  if(t.verbose) fprintf(stderr, "jack-transport: init curses\n");
   signal(SIGINT, finish);
   initscr();
   keypad(stdscr, TRUE);
   nonl();
   halfdelay(1);
   noecho();
-  
+
   while (1) {
     int c;
     jack_transport_state_t s;
@@ -109,27 +127,31 @@ int main(int argc, char **argv)
       erase();
       refresh();
       break;
-    case ' ': 
+    case ' ':
       if(t.rolling) {
 	jack_transport_stop(t.jk);
       } else {
 	jack_transport_start(t.jk);
       }
       break;
+    case 'f':
     case '>':
     case KEY_RIGHT:
       offset(&t, t.incr);
       break;
+    case 'F':
     case '.':
     case KEY_UP:
       offset(&t, t.skip);
       break;
+    case 'b':
     case '<':
     case KEY_LEFT:
       offset(&t, -t.incr);
       break;
-    case KEY_DOWN:
+    case 'B':
     case ',':
+    case KEY_DOWN:
       offset(&t, -t.skip);
       break;
     case 'z':
@@ -162,12 +184,13 @@ int main(int argc, char **argv)
     case ERR:
       break;
     }
-      
-    mvaddstr(0, 0, "jack.transport - (c) rohan drape, 2006-2008");
+
+    mvaddstr(0, 0, "jack-transport");
+    mvaddstr(2, 0, "[s]tart,[s]top,[f]orward,[b]ack,[l]ocate,[i]ncrement,[z]ero,[q]uit");
     mvaddch(1, 0, t.rolling ? ACS_RARROW : ACS_BLOCK);
-    mvaddtime(1, 4, t.time);
+    mvaddtime(1, 6, t.time);
   }
-  
+
   jack_client_close(t.jk);
   endwin();
   return 0;
diff --git a/jack-transport.text b/jack-transport.text
new file mode 100644
index 0000000..ef121a0
--- /dev/null
+++ b/jack-transport.text
@@ -0,0 +1,48 @@
+JACK-TRANSPORT(1)
+=================
+Rohan Drape <rd at slavepianos.org>
+
+
+NAME
+----
+jack-transport - Minimalist Jack Transport Interface
+
+SYNOPSIS
+--------
+jack-transport
+
+DESCRIPTION
+-----------
+jack-transport is a minimalist Jack transport control interface using
+ncurses.  It displays the transport state and current time, and
+provides standard operating keys.
+
+COMMANDS
+--------
+*s*
+:   Start and stop transport.  Aliased to [space].
+*l*
+:   Locate  to  entered  time.   Starting to type a number will also
+    enter locate mode.
+*i*
+:   Set forward & backward increment to entered interval (default = 5 seconds).
+*z*
+:   Locate to start (zero).
+*r*
+:   Erase and refresh screen.
+*f*
+:   Move forwards by increment.  Aliased to [>] and [right-arrow].
+*b*
+:   Move backwards by increment.  Aliased to [<] and [left-arrow].
+*F*
+:   Move forwards one minute.  Aliased to [.] and [up-arrow].
+*B*
+:   Skip backwards one minute.  Aliased to [,] and [down-arrow].
+
+AUTHOR
+------
+Rohan Drape <http://rd.slavepianos.org/>
+
+SEE ALSO
+--------
+jackd(1), jack-play(1)
diff --git a/jack.udp.c b/jack-udp.c
similarity index 81%
rename from jack.udp.c
rename to jack-udp.c
index 95b6286..e41d3eb 100644
--- a/jack.udp.c
+++ b/jack-udp.c
@@ -1,5 +1,3 @@
-/***** jack.udp.c - (c) rohan drape, 2003-2010 *****/
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
@@ -9,21 +7,21 @@
 #include <unistd.h>
 #include <pthread.h>
 
-#include "common/byte-order.h"
-#include "common/failure.h"
-#include "common/file.h"
-#include "common/jack-client.h"
-#include "common/jack-port.h"
-#include "common/jack-ringbuffer.h"
-#include "common/memory.h"
-#include "common/network.h"
-#include "common/print.h"
+#include "c-common/byte-order.h"
+#include "c-common/failure.h"
+#include "c-common/file.h"
+#include "c-common/jack-client.h"
+#include "c-common/jack-port.h"
+#include "c-common/jack-ringbuffer.h"
+#include "c-common/memory.h"
+#include "c-common/network.h"
+#include "c-common/print.h"
 
 #define MAX_CHANNELS      32
 #define PAYLOAD_SAMPLES   256
 #define PAYLOAD_BYTES     (PAYLOAD_SAMPLES*sizeof(f32))
 
-typedef struct 
+typedef struct
 {
   int buffer_size;
   f32 *j_buffer;
@@ -100,27 +98,27 @@ void *jackudp_recv_thread(void *PTR)
   while(1) {
     packet_recv(d->fd, &p, 0);
     if(p.index != next_packet && next_packet != -1) {
-      eprintf("jack.udp recv: out of order packet arrival (%d, %d)\n", 
+      eprintf("jack-udp recv: out of order packet arrival (%d, %d)\n",
 	      next_packet, (int)p.index);
       FAILURE;
     }
     if(p.channels != d->channels) {
-      eprintf("jack.udp recv: channel mismatch packet arrival (%d != %d)\n", 
+      eprintf("jack-udp recv: channel mismatch packet arrival (%d != %d)\n",
 	      p.channels, d->channels);
       FAILURE;
     }
     int bytes_available = (int) jack_ringbuffer_write_space(d->rb);
     if(PAYLOAD_BYTES > bytes_available) {
-      eprintf("jack.udp recv: buffer overflow (%d > %d)\n", 
+      eprintf("jack-udp recv: buffer overflow (%d > %d)\n",
 	      (int) PAYLOAD_BYTES, bytes_available);
     } else {
       jack_ringbuffer_write_exactly(d->rb,
-				    (char *) p.data, 
+				    (char *) p.data,
 				    (size_t) PAYLOAD_BYTES);
     }
     next_packet = p.index + 1;
     next_packet %= INT32_MAX;
-  }  
+  }
   return NULL;
 }
 
@@ -130,7 +128,7 @@ int jackudp_recv (jack_nframes_t nframes, void *PTR)
 {
   jackudp_t *d = (jackudp_t *) PTR;
   if(nframes >= d->buffer_size) {
-    eprintf("jack.udp recv: JACK buffer size exceeds limit\n");
+    eprintf("jack-udp recv: JACK buffer size exceeds limit\n");
     return -1;
   }
 
@@ -144,7 +142,7 @@ int jackudp_recv (jack_nframes_t nframes, void *PTR)
   int nbytes = nsamples * sizeof(f32);
   int bytes_available = (int) jack_ringbuffer_read_space(d->rb);
   if(nbytes > bytes_available) {
-    eprintf("jack.udp recv: buffer underflow (%d > %d)\n", 
+    eprintf("jack-udp recv: buffer underflow (%d > %d)\n",
 	    nbytes, bytes_available);
     for(i = 0; i < nframes; i++) {
       for(j = 0; j < d->channels; j++) {
@@ -201,15 +199,15 @@ int jackudp_send(jack_nframes_t n, void *PTR )
   int bytes_available = (int) jack_ringbuffer_write_space(d->rb);
   int bytes_to_write = n * sizeof(f32) * d->channels;
   if(bytes_to_write > bytes_available) {
-    eprintf ("jack.udp send: buffer overflow error (UDP thread late)\n");
+    eprintf ("jack-udp send: buffer overflow error (UDP thread late)\n");
   } else {
-    jack_ringbuffer_write_exactly(d->rb, 
+    jack_ringbuffer_write_exactly(d->rb,
 				    (char *) d->j_buffer, bytes_to_write );
   }
 
   char b = 1;
   if(write(d->pipe[1], &b, 1)== -1) {
-    eprintf ("jack.udp send: error writing communication pipe.\n");
+    eprintf ("jack-udp send: error writing communication pipe.\n");
     FAILURE;
   }
   return 0;
@@ -217,9 +215,9 @@ int jackudp_send(jack_nframes_t n, void *PTR )
 
 void jackudp_usage (void)
 {
-  eprintf("Usage: jack.udp [ options ] mode\n");
+  eprintf("Usage: jack-udp [ options ] mode\n");
   eprintf("   -b  Set the ring buffer size in frames (default=4096).\n");
-  eprintf("   -c  Set the client name (default=\"jack.udp-PID\").\n");
+  eprintf("   -c  Set the client name (default=\"jack-udp-PID\").\n");
   eprintf("   -p  Set the port number (default=57160).\n");
   eprintf("   -n  Set the number of channels (default=2).\n");
   eprintf("   -r  Set the remote addrress to send to (default=\"127.0.0.1\").\n");
@@ -254,7 +252,7 @@ int main (int argc, char **argv)
       hostname = optarg;
       break;
     default:
-      eprintf ("jack.udp: Illegal option %c.\n", c);
+      eprintf ("jack-udp: Illegal option %c.\n", c);
       jackudp_usage ();
       break;
     }
@@ -263,7 +261,7 @@ int main (int argc, char **argv)
     jackudp_usage ();
   }
   if(d.channels < 1 || d.channels > MAX_CHANNELS) {
-    eprintf("jack.udp: illegal number of channels: %d\n", d.channels);
+    eprintf("jack-udp: illegal number of channels: %d\n", d.channels);
     FAILURE;
   }
   int recv_mode = (strcmp(argv[optind], "recv") == 0);
@@ -271,10 +269,10 @@ int main (int argc, char **argv)
   if(recv_mode) {
     bind_inet(d.fd, NULL, port_n);
   } else {
-    init_sockaddr_in(&(d.address), 
-		     hostname ? hostname : "127.0.0.1", 
+    init_sockaddr_in(&(d.address),
+		     hostname ? hostname : "127.0.0.1",
 		     port_n);
-  }  
+  }
   d.buffer_size *= d.channels * sizeof(f32);
   d.j_buffer = xmalloc(d.buffer_size);
   d.rb = jack_ringbuffer_create(d.buffer_size);
@@ -283,18 +281,18 @@ int main (int argc, char **argv)
   if(d.name) {
     client = jack_client_open(d.name,JackNullOption,NULL);
   } else {
-    client = jack_client_unique("jack.udp");
+    client = jack_client_unique("jack-udp");
   }
   jack_set_error_function(jack_client_minimal_error_handler);
   jack_on_shutdown(client, jack_client_minimal_shutdown_handler, 0);
-  jack_set_process_callback(client, 
-			    recv_mode ? jackudp_recv : jackudp_send, 
+  jack_set_process_callback(client,
+			    recv_mode ? jackudp_recv : jackudp_send,
 			    &d);
   jack_port_make_standard(client, d.j_port, d.channels, recv_mode);
   jack_client_activate(client);
-  pthread_create(&(d.c_thread), 
-		 NULL, 
-		 recv_mode ? jackudp_recv_thread : jackudp_send_thread, 
+  pthread_create(&(d.c_thread),
+		 NULL,
+		 recv_mode ? jackudp_recv_thread : jackudp_send_thread,
 		 &d);
   pthread_join(d.c_thread, NULL);
   close(d.fd);
diff --git a/jack.udp.text b/jack-udp.text
similarity index 75%
rename from jack.udp.text
rename to jack-udp.text
index f87a71f..298ebe1 100644
--- a/jack.udp.text
+++ b/jack-udp.text
@@ -1,22 +1,22 @@
-JACK.UDP(1)
+JACK-UDP(1)
 ===========
 Rohan Drape <rd at slavepianos.org>
 
 
 NAME
 ----
-jack.udp - JACK UDP Transport Client
+jack-udp - JACK UDP Transport Client
 
 SYNOPSIS
 --------
-jack.udp [options] send|recv
+jack-udp [options] send|recv
 
 OPTIONS
 -------
 *-b*
 :   Set the ring buffer size in frames (default=4096).
 *-c*
-:   Set the client name (default=jack.udp-PID).
+:   Set the client name (default=jack-udp-PID).
 *-n*
 :   Set the number of channels, and therefore the number of JACK ports
     (default=2).
@@ -27,7 +27,7 @@ OPTIONS
 
 DESCRIPTION
 -----------
-jack.udp is a UDP audio transport mechansim for JACK.  The send mode
+jack-udp is a UDP audio transport mechansim for JACK.  The send mode
 reads signals from a set of JACK input ports and sends UDP packets to
 the indicated port at the indicated host at a rate determined by the
 local JACK daemon.  The recv mode reads incoming packets at the indi-
@@ -40,17 +40,17 @@ will report dropped and out-of-order packets, and shutdown on channel
 mismatch packets.  In practice this mechanism can be made highly reli-
 able over local networks.
 
-jack.udp implements no connection logic, use jack.plumbing(1) instead.
+jack-udp implements no connection logic, use jack-plumbing(1) instead.
 
 EXAMPLE
 -------
 
-    192.0.0.1:~$ jack.udp -r 192.0.0.2 send
-    192.0.0.2:~$ jack.udp recv
+    192.0.0.1:~$ jack-udp -r 192.0.0.2 send
+    192.0.0.2:~$ jack-udp recv
 
 AUTHOR
 ------
-Rohan Drape <http://slavepianos.org/rd/>
+Rohan Drape <http://rd.slavepianos.org/>
 
 SEE ALSO
 --------
diff --git a/jack.dl.c b/jack.dl.c
deleted file mode 100644
index a8fd677..0000000
--- a/jack.dl.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/***** jack.dl.c - (c) rohan drape, 2003-2008 *****/
-
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <time.h>
-#include <dlfcn.h>
-
-#include <jack/jack.h>
-#include <jack/thread.h>
-#include <lo/lo.h>
-
-#include "common/jack-port.h"
-#include "jack.dl.h"
-
-void fail(char *s)
-{
-  fprintf(stderr, s);
-  exit(EXIT_FAILURE);
-}
-
-int dsp_run(jack_nframes_t nf, void *ptr)
-{
-  struct world *w = (struct world *)ptr;
-  for(int i = 0; i < w->nc; i++) {
-    w->in[i] = (float *)jack_port_get_buffer(w->ip[i], nf);
-  }
-  for(int i = 0; i < w->nc; i++) {
-    w->out[i] = (float *)jack_port_get_buffer(w->op[i], nf);
-    memset(w->out[i], 0, nf * sizeof(float));
-  }
-  for(int i = 0; i < w->ng; i++) {
-    if(w->ga[i]) {
-      w->dsp_step[i](w, i, w->st[i], nf);
-    }
-  }
-  return 0;
-}
-
-void osc_error(int n, const char *m, const char *p)
-{
-  fprintf(stderr,"jack.dl: error %d in path %s: %s\n", n, p, m);
-}
-
-#define break_on(x,s)                                                   \
-  if(x){                                                                \
-    fprintf(stderr,"jack.dl: %s: %s, %d\n", s, __FILE__, __LINE__);     \
-    return 0;                                                           \
-  }
-
-int osc_g_load(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
-{
-  struct world *w = (struct world *)u;
-  int g = a[0]->i;
-  break_on(g >= w->ng, "graph index");
-  w->ga[g] = false;
-  char *s = &a[1]->s;
-  if(w->gh[g]) break_on(dlclose(w->gh[g]), dlerror());
-  w->gh[g] = dlopen(s, RTLD_LAZY);
-  break_on(!w->gh[g], dlerror());
-  w->dsp_init[g] = dlsym(w->gh[g], "dsp_init");
-  w->dsp_step[g] = dlsym(w->gh[g], "dsp_step");
-  w->st[g] = w->dsp_init[g](w, g);
-  w->ga[g] = true;
-  fprintf(stderr,"g_load: %d, %s\n", g, s);
-  return 0;
-}
-
-int osc_g_unload(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
-{
-  struct world *w = (struct world *)u;
-  int g = a[0]->i;
-  break_on(g >= w->ng, "graph index");
-  w->ga[g] = false;
-  if(w->gh[g]) break_on(dlclose(w->gh[g]), dlerror());
-  w->gh[g] = NULL;
-  if(w->st[g]) free(w->st[g]);
-  fprintf(stderr,"g_unload: %d\n", g);
-  return 0;
-}
-
-int osc_c_set1(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
-{
-  struct world *w = (struct world *)u;
-  int i = a[0]->i;
-  break_on(i >= w->nk, "control index");
-  w_c_set1(w, i, a[1]->f);
-  fprintf(stderr,"c_set1: %d, %f\n", i, a[1]->f);
-  return 0;
-}
-
-int osc_b_alloc(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
-{
-  struct world *w = (struct world *)u;
-  int i = a[0]->i;
-  break_on(i >= w->nb, "buffer index");
-  /*if(w->bd[i]) free(w->bd[i]);*/
-  int l = a[1]->i;
-  w->bl[i] = 0;
-  w->bd[i] = calloc(l, sizeof(float));
-  w->bl[i] = l;
-  fprintf(stderr,"b_alloc: %d, %d\n", i, l);
-  return 0;
-}
-
-int osc_p_set1(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
-{
-  struct world *w = (struct world *)u;
-  int g = a[0]->i;
-  break_on(g >= w->ng, "graph index");
-  int i = a[1]->i;
-  break_on(i >= w->nk, "control index");
-  w_p_set1(w, g, i, a[2]->f);
-  fprintf(stderr,"p_set1: %d, %d, %f\n", g, i, a[2]->f);
-  return 0;
-}
-
-int osc_quit(const char *p, const char *t, lo_arg **a, int n, void *d, void *u)
-{
-  struct world *w = (struct world *)u;
-  w->ef = true;
-  return 0;
-}
-
-void world_init(struct world *w, int ng, int nc, int nk, int nb)
-{
-  w->ng = ng;
-  w->nc = nc;
-  w->nk = nk;
-  w->nb = nb;
-  w->dsp_init = calloc(w->ng, sizeof(void *));
-  w->dsp_step = calloc(w->ng, sizeof(void *));
-  w->st = calloc(w->ng, sizeof(void *));
-  w->p_ctl = malloc(w->ng * sizeof(float *));
-  for(int i = 0; i < w->ng; i++) {
-    w->p_ctl[i] = calloc(w->nk, sizeof(float));
-  }
-  w->ga = calloc(w->ng, sizeof(bool));
-  w->gh = calloc(w->ng, sizeof(void *));
-  w->ip = malloc(w->nc * sizeof(jack_port_t *));
-  w->op = malloc(w->nc * sizeof(jack_port_t *));
-  w->in = malloc(w->nc * sizeof(float *));
-  w->out = malloc(w->nc * sizeof(float *));
-  w->ctl = calloc(w->nk, sizeof(float));
-  w->bl = calloc(w->nb, sizeof(int));
-  w->bd = calloc(w->ng, sizeof(float*));
-  w->ef = false;
-  w->c = jack_client_open("jack.dl",JackNullOption,NULL);
-  if(!w->c) fail("could not create jack client\n");
-  jack_set_process_callback(w->c, dsp_run, w);
-  w->sr = (float)jack_get_sample_rate(w->c);
-  jack_port_make_standard(w->c, w->ip, w->nc, false);
-  jack_port_make_standard(w->c, w->op, w->nc, true);
-}
-
-int main(int argc, char **argv)
-{
-  struct world w;
-  lo_server_thread osc;
-  world_init(&w, 8, 8, 64, 8);
-  osc = lo_server_thread_new("57190", osc_error);
-  lo_server_thread_add_method(osc, "/c_set1", "if", osc_c_set1, &w);
-  lo_server_thread_add_method(osc, "/p_set1", "iif", osc_p_set1, &w);
-  lo_server_thread_add_method(osc, "/g_load", "is", osc_g_load, &w);
-  lo_server_thread_add_method(osc, "/g_unload", "i", osc_g_unload, &w);
-  lo_server_thread_add_method(osc, "/b_alloc", "ii", osc_b_alloc, &w);
-  lo_server_thread_add_method(osc, "/quit", NULL, osc_quit, &w);
-  lo_server_thread_start(osc);
-  if(jack_activate(w.c)) fail("jack.dl: jack_activate() failed\n");
-  while(!w.ef) {
-    struct timespec t = {0, 100000000};
-    nanosleep(&t, NULL);
-  }
-  jack_client_close(w.c);
-  lo_server_thread_free(osc);
-  return EXIT_SUCCESS;
-}
diff --git a/jack.dl.h b/jack.dl.h
deleted file mode 100644
index c808c10..0000000
--- a/jack.dl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <stdbool.h>
-#include <jack/jack.h>
-
-struct world {
-  void* (**dsp_init)(struct world *, int);
-  void (**dsp_step)(struct world *, int, void *, int);
-  void **st;                    /* graph state */
-  bool *ga;                     /* graph active */
-  void **gh;                    /* graph shared library handle */
-  jack_client_t *c;             /* client */
-  jack_port_t **ip;             /* input ports */
-  jack_port_t **op;             /* output ports */
-  int nc;                       /* number of channels */
-  int ng;                       /* number of graphs */
-  int nk;                       /* number of controls */
-  int nb;                       /* number of buffers */
-  float sr;                     /* sample rate */
-  float **in;                   /* input data */
-  float **out;                  /* output data */
-  float *ctl;                   /* shared control data */
-  float **bd;                   /* buffer data */
-  int *bl;                      /* buffer sizes */
-  float **p_ctl;                /* private control data */
-  bool ef;                      /* exit flag */
-};
-
-#define w_sr(w) (w)->sr
-#define w_c_get1(w,i) (w)->ctl[(i)]
-#define w_c_set1(w,i,n) (w)->ctl[(i)]=(n)
-#define w_p_get1(w,g,i) (w)->p_ctl[(g)][(i)]
-#define w_p_set1(w,g,i,n) (w)->p_ctl[(g)][(i)]=(n)
-#define w_out1(w,i,n) (w)->out[0][(i)]+=(n)
-#define w_out2(w,i,n1,n2) {(w)->out[0][(i)]+=(n1);(w)->out[1][(i)]+=(n2);}
-#define w_b_read1(w,b,i) (w)->bd[(b)][(i)]
-#define w_b_write1(w,b,i,n) (w)->bd[(b)][(i)]=(n)
diff --git a/jack.dl.text b/jack.dl.text
deleted file mode 100644
index 0369866..0000000
--- a/jack.dl.text
+++ /dev/null
@@ -1,49 +0,0 @@
-JACK.DL(1)
-==========
-Rohan Drape <rd at slavepianos.org>
-
-
-NAME
-----
-jack.dl - JACK shared library dsp loader
-
-SYNOPSIS
---------
-jack.dl [options]
-
-OPTIONS
--------
-*-c*
-:   Set the number of input and output channels (default=8).
-*-g*
-:   Set the number of graph slots (default=8).
-*-k*
-:   Set the number of control buses (default=64).
-*-p*
-:   Set the udp port number (default=57190).
-
-DESCRIPTION
------------
-jack.dl loads dsp algorithms from shared libraries.  Commands are sent
-as OSC packets over a UDP connection.  jack.dl allows data flow code
-generators to be used as interactively.
-
-Clients load dsp graphs by sending a "graph load" packet:
-
-    /g_load index object-file
-
-where index is an integer and object-file a file name.
-
-jack.dl implements only a subset of the OSC protocol.  In particular
-it does not implement the patten matching rules and does not implement
-a scheduler for incoming messages.
-
-jack.dl drops all unrecognized incoming packets.
-
-AUTHOR
-------
-Rohan Drape <http://slavepianos.org/rd/>
-
-SEE ALSO
---------
-jackd(1), OSC(7) <http://opensoundcontrol.org/>
diff --git a/jack.transport.text b/jack.transport.text
deleted file mode 100644
index 566b340..0000000
--- a/jack.transport.text
+++ /dev/null
@@ -1,44 +0,0 @@
-JACK.TRANSPORT(1)
-=================
-Rohan Drape <rd at slavepianos.org>
-
-
-NAME
-----
-jack.transport - Minimalist Jack Transport Interface
-
-SYNOPSIS
---------
-jack.transport
-
-DESCRIPTION
------------
-jack.transport is a minimalist Jack transport control interface using
-ncurses.  It displays the transport state and current time, and pro-
-vides standard operating keys.
-
-COMMANDS
---------
-*s*
-:   Start and stop transport.  Aliased to [space].
-*l*
-:   Locate  to  entered  time.   Starting to type a number will also
-    enter locate mode.
-*i*
-:   Set skip increment to entered interval.
-*z*
-:   Locate to start (zero).
-*r*
-:   Erase and refresh screen.
-*>*
-:   Skip forwards.  Aliased to . and [right-arrow].
-*<*
-:   Skip backwards.  Aliased to , and [left-arrow].
-
-AUTHOR
-------
-Rohan Drape <http://slavepianos.org/rd/>
-
-SEE ALSO
---------
-jackd(1), jack.play(1)

-- 
jack-tools packaging



More information about the pkg-multimedia-commits mailing list