//---------------------------------------------------------------------
// name: mfcc-mean.ck
// desc: mel-frequency cepstral coefficients
// this example aggregates multiple MFCC frames; compute mean
//
// version: need chuck version 1.5.0.0 or higher
// sorting: part of ChAI (ChucK for AI)
//
// to see API, uncomment:
// MFCC.help();
//
// author: Yikai Li and Ge Wang
// date: Spring 2023
//---------------------------------------------------------------------
// analysis patch
adc => FFT fft =^ MFCC mfcc => blackhole;
// FFT size
2048 => fft.size;
// FFT hop size
512 => int hopSize;
// number of filters in MEL space
10 => mfcc.numFilters;
// number of MFCC coefficients to compute per frame
13 => mfcc.numCoeffs => int nCoeffs;
// used to compute the frame size
.1::second => dur aggregateTime;
// set FFT window
Windowing.hamming(fft.size()) => fft.window;
// current sample sample
second / samp => float sampleRate;
// this should already be set to the current chuck srate
// but could be overridden, if desired
// sampleRate => mfcc.sampleRate;
// calculate the number of frames
(aggregateTime/second * sampleRate / hopSize + .5) $ int => int nFrames;
// print out
chout <= IO.newline(); <<< "--------------------------------------------", "">>>;
<<< "num filters:", mfcc.numFilters()>>>;
<<< "num MFCC coefficients:", mfcc.numCoeffs()>>>;
<<< "agregrateTime:", aggregateTime/second, "seconds">>>;
<<< "num frames:", nFrames>>>;
<<< "--------------------------------------------", "">>>;
chout <= IO.newline(); // per-frame MFCC coefficients float mfccs[nFrames][nCoeffs]; // average of MFCC coefficients across all frames float mfccMean [nCoeffs]; // let one FFTsize of time pass fft.size()::samp => now;
// analysis loop
while( true )
{
// aggregate mfcc features
for( 0 => int fi; fi < nFrames; fi++ ) { // triggers MFCC and its dependencies (e.g., FFT) mfcc.upchuck(); // get contents for( 0 => int i; i < nCoeffs; i++ ) { // copy the resulting coeffs mfcc.fval(i) => mfccs[fi][i];
}
// advance time by one hop
hopSize::samp => now;
}
// compute mean
for( 0 => int i; i < nCoeffs; i++ ) { // zero out 0.0 => mfccMean[i];
// sum
for (0 => int j; j < nFrames; j++) { mfccs[j][i] +=> mfccMean[i];
}
// divide by frames
nFrames /=> mfccMean[i];
// print
chout <= mfccMean[i] <= " ";
}
// new line
chout <= IO.newline();
}