Spectral Tools


Description of the OM workspace SpectRes

    My process begins in Audiosculpt, where I do a partial tracking analysis of the sound; the resultant analysis is exported as an SDIF file with the extension .trc.  There are ways of analyzing soundfiles directly in OM, but I prefer to take advantage of Audiosculpt's nice display (you can see the partials superimposed on the FFT) and it's ability to fine-tune the analysis parameters.  Also, I find it useful to be able to filter the soundfile before doing partial tracking, for example to remove a bunch of low noise that I'm not interested in, or to emphasize the high partials I am interested in. 

    In my workspace you'll find six folders containing patches that I've used for handling spectral data, as well as a folder of components (sub-patches) and a folder of patches containing examples of the materials I've generated.

SDIF tools

        In OM, I import the SDIF files into one of the patches contained in the folder "sdif tools."  The patch sdif_midicvel has two routines that convert the frequency and amplitude data in each frame into midics and velocities, as described in the patch.  I also put in a routine for examining the SDIF file.  The .trc files are structured as 3D matrices; each file contains a certain number of frames, each of which represents a "vertical slice" of the FFT.  Each frame has one n by 4 matrix, where n represents the number of partials that are found in that frame.   The four columns represent the partial number, frequency, amplitude, and phase.  So, if you evaluate the getrow object for a given row you'll get all the data for one of the partials, whereas if you evaluate the getcol object for a given column you'll get all of the data of a particular type, such as a list of all of the frequencies or all of the amplitudes.

    In order to visualize the contents of a particular frame I wrote the patch "sdif project," which projects the pitches into a measure such that the stronger partials appear closer to the left while the weaker ones lie to the right.  The patches in the folder "chordseqs" contain projections of various sdif frames; looking at a series of sequential frame projections gives me an idea of the evolution of the partials.

    There are three other patches in this folder that interpolate between individual frames of SDIF files and manually created chords, so that I can create a sequences of chords where pitches fade in and out.  In my documentation of these patches and others, I make reference to a concept I call an "HV" or "hierarchy vector."   An HV is simply a set of weighting values attached to a set of pitches, just as velocity values are attached to midi notes.  In my music I abstract the weighting found within a spectrum into other ways of expressing relative importance, such as the prevalence of a particular note in a given time frame.  "FHV" stands for "full hierarchy vector", and is a re-formatting of an HV so that it can be expressed as a single list of numbers; each MIDI note value is given a weighting, with zeros holding the places of notes that don't appear in the set.  Hence, the 60th number in the list represents the weighting for middle C.  


    Two patches in the folder "partialextract" can be used to isolate the data for a particular partial over multiple frames.  "partfrondur" shows the onsets and durations of all partials in an SDIF, and "partdisplay" can be used to view the evolutions of selected partials. 

Chord-Seq tools

    The patches in chord-seq tools can be helpful for manipulating chord-seq objects that have been generated from sdif files; use chord-seq trim to crop a sequence, or chord-seq thin to remove all but every nth chord.  Chordseq project does the same thing as sdif project, but starting with a chord-seq.  Use chord-seq gain within other patches to adjust the velocity values in a chord seq (without exceeding 127). 

FHV filters

    FHV filters contains patches that modify and sort elements according to HV and register.  "fhvlowlimit" and "fhvlowlimit-cseq" remove pitches below a particular velocity, as set by a bpf curve.  In my music I have used this patch to control processes of accretion in which pitches are added in an order relative to their weighting. "fhvlowhighlimit" adds another bpf to control the high velocity limit.  

    The patch "contourfilter2" also applies two bpfs to an FHV list, but here the curves represent registral limits.  (The patch is currently set up to be used as a "bpatcher" within another patch - use the "hv to fhv" patch found in the components folder to supply the FHV list to the input.)

     The patches "hv slicer" and "lincountourslicer" divide chord-seqs into a number of "slices"; in the former the pitches are sorted according to hv values, whereas the latter uses register.  

    "fhvfilter-mult" adjusts FHV values according to a curve, analogous to an EQ filter; "fhvfilter-mult" does the same thing but allows for dynamic control of this filter, interpolating between two bpfs.

 Rhythm tools

     The folder "Rhythm Tools" contains patches that apply HV values to aspects of rhythm, some of which are incorporated into the larger patches found in the folder "Projectors."  These patches can of course be used in other contexts, but I have more work to do in this area and so the contents of this folder have not been fully refined.  I eventually want to apply the concept of HV to rhythmic aspects, so that a pitch's weighting value can be expressed in its placement relative to strong beats in a measure, or its duration, etc.


    Once I have used the above tools to generate chord sequences, I can use the patches in "Projectors" to create measures containing notes and rests.  "melodyproject" creates a monophonic line from the notes in each chord, in which the prevalence of a particular pitch is relative to its HV value.  The density of the passage can be controlled by adjusting the resolution and porosity values.  "textureproject" can be used to create a polyphonic texture, the overall characteristics of which reflect the HV values.  A chord-seq is first sliced by lincontourslicer, then the individual lines are projected into measures.  "textureproject2" substitutes the hv slicer for the lincontourslicer found in "textureproject".


© David Litke 2018