Minim |
|
freqToIndex |
Description Returns the index of the frequency band that contains the requested frequency.Signature int freqToIndex(float freq) Parameters freq — float: the frequency you want the index for (in Hz)Returns int: the index of the frequency band that contains freq Related FFTExample /** * An FFT object is used to convert an audio signal into its frequency domain representation. This representation * lets you see how much of each frequency is contained in an audio signal. Sometimes you might not want to * work with the entire spectrum, so it's possible to have the FFT object calculate average frequency bands by * simply averaging the values of adjacent frequency bands in the full spectrum. There are two different ways * these can be calculated: <b>Linearly</b>, by grouping equal numbers of adjacent frequency bands, or * <b>Logarithmically</b>, by grouping frequency bands by <i>octave</i>, which is more akin to how humans hear sound. * <br/> * This sketch illustrates the difference between viewing the full spectrum, * linearly spaced averaged bands, and logarithmically spaced averaged bands. * <p> * From top to bottom: * <ul> * <li>The full spectrum.</li> * <li>The spectrum grouped into 30 linearly spaced averages.</li> * <li>The spectrum grouped logarithmically into 10 octaves, each split into 3 bands.</li> * </ul> * * Moving the mouse across the sketch will highlight a band in each spectrum and display what the center * frequency of that band is. The averaged bands are drawn so that they line up with full spectrum bands they * are averages of. In this way, you can clearly see how logarithmic averages differ from linear averages. * <p> * For more information about Minim and additional features, visit http://code.compartmental.net/minim/ */ import ddf.minim.analysis.*; import ddf.minim.*; Minim minim; AudioPlayer jingle; FFT fftLin; FFT fftLog; float height3; float height23; float spectrumScale = 4; PFont font; void setup() { size(512, 480); height3 = height/3; height23 = 2*height/3; minim = new Minim(this); jingle = minim.loadFile("jingle.mp3", 1024); // loop the file jingle.loop(); // create an FFT object that has a time-domain buffer the same size as jingle's sample buffer // note that this needs to be a power of two // and that it means the size of the spectrum will be 1024. // see the online tutorial for more info. fftLin = new FFT( jingle.bufferSize(), jingle.sampleRate() ); // calculate the averages by grouping frequency bands linearly. use 30 averages. fftLin.linAverages( 30 ); // create an FFT object for calculating logarithmically spaced averages fftLog = new FFT( jingle.bufferSize(), jingle.sampleRate() ); // calculate averages based on a miminum octave width of 22 Hz // split each octave into three bands // this should result in 30 averages fftLog.logAverages( 22, 3 ); rectMode(CORNERS); font = loadFont("ArialMT-12.vlw"); } void draw() { background(0); textFont(font); textSize( 18 ); float centerFrequency = 0; // perform a forward FFT on the samples in jingle's mix buffer // note that if jingle were a MONO file, this would be the same as using jingle.left or jingle.right fftLin.forward( jingle.mix ); fftLog.forward( jingle.mix ); // draw the full spectrum { noFill(); for(int i = 0; i < fftLin.specSize(); i++) { // if the mouse is over the spectrum value we're about to draw // set the stroke color to red if ( i == mouseX ) { centerFrequency = fftLin.indexToFreq(i); stroke(255, 0, 0); } else { stroke(255); } line(i, height3, i, height3 - fftLin.getBand(i)*spectrumScale); } fill(255, 128); text("Spectrum Center Frequency: " + centerFrequency, 5, height3 - 25); } // no more outline, we'll be doing filled rectangles from now noStroke(); // draw the linear averages { // since linear averages group equal numbers of adjacent frequency bands // we can simply precalculate how many pixel wide each average's // rectangle should be. int w = int( width/fftLin.avgSize() ); for(int i = 0; i < fftLin.avgSize(); i++) { // if the mouse is inside the bounds of this average, // print the center frequency and fill in the rectangle with red if ( mouseX >= i*w && mouseX < i*w + w ) { centerFrequency = fftLin.getAverageCenterFrequency(i); fill(255, 128); text("Linear Average Center Frequency: " + centerFrequency, 5, height23 - 25); fill(255, 0, 0); } else { fill(255); } // draw a rectangle for each average, multiply the value by spectrumScale so we can see it better rect(i*w, height23, i*w + w, height23 - fftLin.getAvg(i)*spectrumScale); } } // draw the logarithmic averages { // since logarithmically spaced averages are not equally spaced // we can't precompute the width for all averages for(int i = 0; i < fftLog.avgSize(); i++) { centerFrequency = fftLog.getAverageCenterFrequency(i); // how wide is this average in Hz? float averageWidth = fftLog.getAverageBandWidth(i); // we calculate the lowest and highest frequencies // contained in this average using the center frequency // and bandwidth of this average. float lowFreq = centerFrequency - averageWidth/2; float highFreq = centerFrequency + averageWidth/2; // freqToIndex converts a frequency in Hz to a spectrum band index // that can be passed to getBand. in this case, we simply use the // index as coordinates for the rectangle we draw to represent // the average. int xl = (int)fftLog.freqToIndex(lowFreq); int xr = (int)fftLog.freqToIndex(highFreq); // if the mouse is inside of this average's rectangle // print the center frequency and set the fill color to red if ( mouseX >= xl && mouseX < xr ) { fill(255, 128); text("Logarithmic Average Center Frequency: " + centerFrequency, 5, height - 25); fill(255, 0, 0); } else { fill(255); } // draw a rectangle for each average, multiply the value by spectrumScale so we can see it better rect( xl, height, xr, height - fftLog.getAvg(i)*spectrumScale ); } } } Usage Web & Application |