sc/spectra [ Modules ]

[ Top ] [ Modules ]



 File:             spectra.lsp

 Class Hierarchy:  none (no classes defined)

 Version:          1.1.0

 Project:          slippery chicken (algorithmic composition)

 Purpose:          Definition of the spectral data for piano and other
                   instruments' notes. We'll use this data for
                   the calculation of chord dissonance values in the chord
                   class's calculate-dissonance method. 

 Author:           Michael Edwards:

 Creation date:    July 27th 2015

 $$ Last modified:  12:49:39 Thu Apr 18 2024 CEST

 SVN ID: $Id: spectra.lsp 5359 2015-07-24 20:53:22Z medward2 $

spectra/get-spectra-al [ Functions ]

[ Top ] [ spectra ] [ Functions ]


 August 6th 2015, Edinburgh


 Create an assoc-list of spectral data by doing spectral analysis of all the
 sound files contained in a given directory. The aim is to extract the
 spectral data for harmonic partials, so we specifically look for ascending
 partials as close as possible to integer multiples of the sample sound
 file's fundamental frequency, as detected from the file name (see below).

 By default we average spectra over three separate readings at 300, 400, and
 500 milliseconds. We do this in order to avoid spectral anomalies at any
 fixed point in any of the sound files, and of course to skip the onset
 transient and any inharmonicities therein.

 As the extensive analysis and processing here will take some computation
 time, in order to create our default spectral data for calculating a
 chord's dissonance or spectral centroid, I've performed the analysis on
 some of my local sample libraries. By then using the assoc-list method
 print-for-init I've copied the data into separate text files for reading
 into the +slippery-chicken-spectra+ global assoc-list and thus making these
 available to all slippery-chicken users. By modifying the examples at the
 bottom of this file, similar sample directories' spectral data could be
 added to this global.


 - the path to the samples directory. This should be something suitable for
 passing to the (directory) function so we'll need the extension of the sound
 files (see "*.wav" in the example below).
 - a function for processing the filenames (as a string, with no directory
 or extension e.g. "Stein-R(A0)-V(085)-dB(3478)-T(ML)-M(28)-P(2126-03-01)")
 in order to return the MIDI note number of the sample in that file. This
 whole approach is predicated on the assumption that sample file names will
 contain such pitch data. If that is not the case then get-spectra-al will
 be of no use. See the akoustik-piano-name and violin-ensemble-name
 functions below for examples.


  Keyword arguments:
 - :force-harmonics: whether to look for harmonic partials or not. If this
    is nil then the returned spectra will be the strongest by amplitude
    irrespective of their harmonicity. Default = t
 - :harmonic-tolerance: the maximum deviation from the exact integer
    partial. Default = 0.15 
 - :fftsize: The FFT window size for spectral analysis. Default = 4096
 - :num-partials: the number of partials to identify and return.
    Default = 12
 - :id: The default ID for the resultant assoc-list. Default = 'spectra
 - :analysis-points: The times in milliseconds at which to do the spectral
    analysis and extract averages. If no averaging is necessary simply pass
    one starting value as a list. Default = '(300 400 500)


 An assoc-list object whose keys are the MIDI note numbers associated with
 the spectral information of sample sound files. Each of these is in the
 form of a two element list: a list of fundamental scalers and a list of
 their amplitudes (normalised to 1.0).


(get-spectra-al "/path/to/samples/*.wav"
                #'violin-ensemble-name :id 'violin-ensemble)
ASSOC-LIST: warn-not-found T
SCLIST: sclist-length: 21, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
data: (
NAMED-OBJECT: id: 56, tag: NIL, 
data: ((0.9889743194880222d0 2.0263850081954717d0 2.9990610385449314d0
        4.024036707283989d0 5.032546599880615d0 6.013292183763263d0
        7.0551329128964655d0 8.049590274637817d0 9.032029362954297d0
        10.017427921485291d0 11.0461040956976d0 12.028523416637086d0)
       (0.1748299156810844d0 0.6666103041159978d0 0.740572572283973d0
        0.37090168062541756d0 0.2529382535743205d0 0.19313279338531672d0
        0.290088638695093d0 0.20008736984066355d0 0.12280861470679348d0
        0.15534581915388804d0 0.11772253740784348d0 0.11703054477270619d0))


(defun get-spectra-al (sample-dir name-fun
                       &key (force-harmonics t) (harmonic-tolerance 0.15)
                         (fftsize 4096) (num-partials 12) (id 'spectra)
                         ;; millisec times of fft analysis
                         (analysis-points '(300 400 500)))