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================= 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. =================aiffblk.c================= 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 instrument[.qualifiers].range.aiff 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================= 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================= 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. ===============gusread.c=========== 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.