
turpentine is an audio processor that attempts to perform audio
morphing between arbitrary soundfiles.  With some practice by
the musician, nifty interpolations between sounds, similar or
disparate may be achieved.  To many ears, the effect is quite
similar to a cross-fade.  Often it is.  However, turpentine
does perform a short-time fourier analysis of each input signal,
and it uses a input "sieve" function to exchange portions of the
spectrum of one signal with portions of the other.  The processor
doesn't have any signal intelligence:  turpentine makes no state
adjustments that are dependent upon the input signal.  Thus it can
be said that turpentine does not discriminate against non-germanic
sounds.

turpentine is a general UNIX program, but I haven't compiled it
on a machine besides a 68040 NeXT.

turpentine is a member of a family of signal processing programs
that I have developed.  Some of these programs can be found in
my package pV.tar.Z, at princeton.edu in the pub/music directory.

I use a bunch of useful UNIX "pipe-oriented" soundfile i/o programs.
This is a style of work that thrived somewhat at UCSD.  I really
like the flexibility of working very close to UNIX, so I work this way.

here is a sample UNIX command that invokes the turpentine processor:

turpentine -R44100 -N1024 -M8192 -D1024 -I1024 -fPicassoDeparture \ -FMadonnaArrival -s1. -e6. -tLinearFunction -TLinearFunction | \
tosf -R44100 -c1 theMorph.snd;

tosf is a program which receives floating-point sample data from a
pipe (all my processors are written to use floating point samples)
and it will generate a new soundfile with a NeXT style header, and a
BSD style header at the end of it such that the program is compatible
with cmix and carl programs.

Turpentine is based on a hacked up version of the phase vocoder, I
removed the phase unwrapping code, so that the program simply does
windowed short-time fourier analysis of the two input files.  Thus,
you can learn more about the innards of turpentine, by studying the
phase vocoder.

here is turpentine's "help" menu:

turpentine:  sieve-like spectral interpolation
turpentine   [flags] > floatsams
       N:      fft length [2^n]
       R:      sampling rate
       M:      window size in samples
       D:      decimation factor in samples
       I:      interpolation factor in samples
       f:      departure soundfile
       F:      arrival soundfile
       t:      interpolation mapping function
       T:      optional sieve function table
       X:      sieve table scalar
       s:      begin time of interpolation
       e:      end time of interpolation
       S:      random number seed for sieve table
       h:      this bouncy place


turpentine's analysis parameters can be controlled with these particular
flags:

N:	the fft size of the analysis.  It must be a power of two.
M:	this is a special window that is used to control the amount
	of data that the fft will analyze.  If this number is larger
	than the fft size, the remaining samples will be wrapped into
	the fft, causing time aliasing (subtle comb-filter or diffusion
	effects).  Doing this however, can speed computation by
	increasing the amount of windowing overlap.

D-I	These factors control the amount of window overlap.  I should
	have removed the interpolation (I) parameter as it really
	isn't necessary.  D controls the amount of samples that are read
	into the analysis window during a single fourier analysis.
	For the turpentine program. These values should be set to
	the same values.  If you can find an application to make them
	different (terrifying time scaling), then you can go for it.
	For test runs of turpentine you can generally use an fft size
	of 1024, a window size 8 times this (8192), and a decimation
	and interpolation of 1024.  It is normally important to use
	a decimation factor that is at least 1/8 of the window size
	such that sufficient overlapping occurs in the analysis.


The most conceptually difficult part to understand about turpentine's
architecture, is the effect of its sieve function and its index function.
The sieve function is given to turpentine as a file of floating-point
numbers. '-T' specifies this file name.  The sieve function controls
what portion of the departure spectrum is exchanged with the arrival
spectrum.  The interpolation mapping function is simply an index into
the sieve function.  The sieve function, thus, should have a number
corresponding to each possible fourier analysis frequency division.
An fft size of 1024 suggests that 512 values should be present in the
sieve function.

The interpolation mapping function is distributed over the time of the interpolation (-eTime minus -sTime).  It is also a floating point
function which, unlike the sieve function, can be of any length.  It
has range restriction of [0.0 - 1.0].  Instances of 0.0 indicate
that the departure soundfile will be wholly present, and instances
of 1.0 indicate that the arrival soundfile will be wholly present.
Values between [0.0 - 1.0] index the sieve function, and the resultant
spectrum exchanges the portions of the spectrum in the departure sound
with those of the arrival sound that lie along the length of the sieve
function from its 0th value to the currently indexed value.  As I
indicated earlier the MadonnaMorph sound, used a linear sieve function
(0-1 with equal increments).  Thus, when the index function was
approximately .5 in this example, half of the spectrum of the
departure sound was passed (11025Hz - 22050Hz), and half of the
arrival spectrum was passed (0Hz - 11025Hz).  At index value .25, 3/4
of the departure sound was passed (0Hz - 5512.5Hz) and 1/4 of the arrival
sound was passed (5512.5Hz - 22050Hz).  I have has success using "tiered"
sieve functions, I can email code to generate them.  Wild index functions
are fun to use too.

It is not necessary to specify a sieve function with turpentine.
It will generate one with a "random" number generator if you do not
specify one yourself.

If you are serious about learning about these processors, you may want
to do some reading about the phase vocoder.  F. Richard Moore's
"Elements of Computer Music" is a good place to start, as I have
built most of my processors around his phase vocoder code.  He describes
his implementation of the phase vocoder quite effectively in his book.

If you heard about turpentine via MadonnaMorph, here is some info:
MadonnaMorph was created with two soundfiles equal in duration
(7.86 seconds).  I think, as I recall, that I gave a start time
of 1. and an end time of 7. providing 6 seconds of interpolation.
I used a linear sieve function with an exponential index.

Recently, I have composed a piece that makes frequent use of this
morphing technique.  Though many of these effects are transparent,
the coda of my recent computer music piece, Manwich, is somewhat of
a cheap demo of this processor.  Well, that's one way of looking at
it!

Christopher
penrose@silvertone.princeton.edu

