GUS patches from Univ. of Iowa samples in .aiff format
  -- Stan Swanson, 30 April 2004

These notes summarize several utilities written to transform
 samples  from the University of Iowa Electronic Music Studios 
into GUS patches.  The samples are made available for music projects
without any restrictions.  I have licensed my GUS patches under the
Creative Commons license with the restrictions "attribute" and "share alike",
in the general spirt of the GNU GPL to make the material freely available,
but to control possible commercial restrictions by third
parties.  There should be no legal issues regarding public performance
or making CD's from these samples except for copyrights on the music
itself [disclaimer: this is not legal advice because the lawyers have 
made it illegal for anybody but a lawyer to dispense legal advice 
(a blatant example of non GPL type thinking)].

There are presently four aiff programs, and a utility dump program:

aiffparse.c  which sketches the framework for decoding aiff audio files,

aiffblk.c    which finds the beginning and end of each tone in
             the uiowa samples and writes the .loc file for

aiffsamp.c   which further analyses the samples as to actual frequency
             and envelope shape and determines sample loop points,
	     writing a .gus file containing this info for each sample

aiff2gus.c   which extracts the WAV data from the samples, modifies
             the attack envelope, and writes a GUS patch file.
gusread.c    a utility which dumps GUS patch files

All of the programs are interactive with keyboard or file inputs,
and some mouse inputs for graphics.  Some utilize my simple X Windows
graphing utilities in xplot.c.  None at present take additional 
arguments from the command line.


aiffparse.c is an sample program which decodes the chunk structure of
.aiff files.  One of the stumbling points is that .aiff files come from
the Macintosh world and have byte order reversal for short and long integers
relative to the usual PC world of Linux.  Appropriate code and utilities
are included.  ... web link to file structure...

Prompts for input (in approximate order)

input aiff file:    give the file name and path

nominal first frequency:   give a floating point frequency in Hz for the
                           first sample.  This will be multiplied by
			   2^(1/12) for each subsequent sample, presuming
			   rising semitones as in the uiowa samples.

    The program will then read chunks, determining the sample rate and
various other parameters.  Various attempts at determing the non-silent
stretches of the file are made, along with amplitude averaging for 
10 millisecond intervals.  Attempts at Fourier and autocorrelation of
frequency are made.  You will see portions of this code in the other
three programs.  At the end, you can see amplitude and frequency information
graphically for 10 second intervals, after starting xplot by answering

 graphics options: x[windows], p[ostscript], b[oth], n[one]: x

Once the xgraf window comes up, you can advance to the next frame
by clicking the right mouse button within that window.


This program starts with a uiowa .aiff sample file and produces a .loc
file which has the starting and ending byte positions and the nominal
frequency for each sample in the file.

The general file name format for the samples is 


e.g. Violin.arco.ff.sulG.C4B4.aiff, BbClarinet.ff.C5B5.aiff

The full path and instrument...range should be given and will have
.aiff appended.  This information will be saved in the .loc file
and used by subsequent programs.  If the nominal frequency of the
first sample is not given, an attempt will be made to compute this
from the first characters of the "range" (e.g. A4 == 440.000)

input path and aiff file : /home/stan/uiowa/Violin.arco.ff.sulG.C4B4

[old] input aiff file infix: [path and instrument...loudness supplied]

The sample amplitude is determined in 10 msec intevals and a histogram
printed out.  Then the number of samples found with threshholds of
500.0 and 10.0 is printed.  If the wrong number of samples is found,
you may modify the threshholds at the prompt

new limits?[hi lo]:     { a carriage return accepts the current result}

Then you can look at the results graphically

 graphics options: x[windows], p[ostscript], b[oth], n[one]: x

with right mouse button clicks to advance.  Finally you are asked
for an output .loc file name and a nominal initial frequency.

output file (locations):

nominal initial frequency:


aiffsamp.c reads the .loc file produced by aiffblk.c and does further
preparatory work needed to produce the GUS patch.  You can edit out
noise entries in the .loc file or otherwise change it to modify
which samples are treated.

input .loc file:

output .gus infofile:

Then you can look at the results graphically

 graphics options: x[windows], p[ostscript], b[oth], n[one]: x

with right mouse button clicks to advance. You will see a frame for
each sample, with the volume envelope indicated at the bottom in red
with tick marks showing where the 0.25, 0.50, and 0.75 levels on envelope
amplitude are reached.  The byte position of the 0.75 level is output
to be used for attack envelope modification in aiff2gus.  Also a
renormalization factor is given so that the samples can be made approximately
equiamplitude, leaving the MIDI velocity to control notes uniformly.

Frequency analysis is done both by an autocorrelation routine and an
Fourier sum;  especially in the case of the violin, the actual frequencies
differ from the nominal frequencies by up to a quarter tone.  The results
of the frequency analysis are plotted in white.

Loop points are determined at the end of an approximately 1 second piece
of the sample (possible problems with short samples will need to be
dealt with in the future).  Timidity uses the loop to extend the sample
for long notes and sustains.  I have chosen a two period loop, but that
could be reprogrammed or made an input choice.  Waveforms at the loop
point, offset by one period,  are plotted in red and green... they should
coincide well. If not there are problems.

The initial wave form and envelope are plotted in yellow and cyan at the
top.  Some samples (especially violin) rise too slowly to make good tones
for fast contra music, so the attack envelope is artificially modified
in aiff2gus.


aiff2gus.c takes an input file which is a merge-edit
from the .gus output files of aiffsamp.c.  A clarinet
is relatively simple, only omitting noise samples. 
With a violin, one must decide which from which string
to take the sample (I chose the most open strings:
G from G3 to D_4, D from D4 to A_4, etc.)  Also one
may not want to include a lot of high frequency samples,
relying on Timidity to generate them from lower frequencey
samples.  I found that the frequency determination was
unreliable for the violin above about C6.  aiff2gus is
presently set up to assume all semitones are given,
and computes the frequency transition point by taking
the geometric mean (sqrt(f1*f2)) between the nominal
frequencies.  This works for all semitones, and for
some choices of larger tone intervals, but will not work
for all choices-> reprogram or specify.

output GUS pat: desired name of patch file

aiff_gus_in: edit/merge of outputs from aiffsamp

The sample information is read in and the frequency limits
are computed and printed.  Samples must be in ascending order
of nominal frequency.  Default envelope parameters are assigned.
(mostly Timidity expects the attack and sustain to be modelled
in the waveform, so most envelope parameters are set so as
not to distort the waveform.  These could be further studied
and tweaked.  One is given a chance to specify the artificial
attack time (rise from 0.00 to 0.75 of full amplitude in
a specified number of milliseconds.  The violin/fiddle
samples rose too slowly and were modified to 30 or 15 ms
to work for 1/16 notes at 120 beats per second.  Another
option (in an attempt to capture initial bowing noise for
the violin is to enter a negative attack duration (e.g -30).
whereupon the program determines the 0.10 envelope level
and renormalizes the initial slope and then applies the
specifed attack shape.  This works unless the initial
waveshape is very ragged and one has amplitude dips
after the renormalized stretch.  Timidity has provision
for vibrato but I have not explored this option, relying
on the default 0.0 (no vibrato).  Vibrato will only
be important for notes longer than a fifth of a second
or so, corresponding to a typical vibrato frequency
of 5 Hz (currently hard coded in the program.

attack [30.0ms]   vibrato depth [0.0 cents]:

The program is hard coded to insert copyright and
license information into various text and unused
reserved byte stretches in the patch file.


The resulting file (and other GUS) patches can be dumped
both numerically (for parameters) and graphically for
waveforms with the utility gusread.c.  This program
provides insight into/ access to the GUS file format--
which can also be extracted from Timidity: instrum.c.