[CLAM] how to use the SpectrumAnalysis object in pitch detection?

Xavier Amatriain xamat at iua.upf.es
Wed Mar 24 06:09:16 PST 2004


Ok, now that I see the code, I can see what the problem is. The 
assertion that is failing is not very informative I must say, but your 
code should never work because there is a problem with the configuration 
or the way that you are using the SpectralAnalysis.

It is a bit difficult to explain it all here because I would have to 
refer you to some literature, bu let's try.

When you do a STFT on a piece of audio, you will not get a single 
spectrum but rather a sequence of spectrums, the size of which is 
determined by the size of the audio you input to the FFT. This input 
audio is, in our case, the WindowSize*(2^zeropaddingfactor) (where 
WindowSize is in fact the nearest power of two as the Spectral Analysis 
only works with powers of two for the moment). So your spectrum will be 
of size inputFFTSize/2+1. And you will be getting as many spectrums as 
AudioSize/inputFFTSize.

In your code you are trying to analyze an audio that is chunk_size (what 
is that exactly?) using an inputFFTSize of 513, but I suspect you are 
expecting to get a single spectrum!

Now you have two options:

a) If you really want to get the whole spectrum of a musical note (I 
don't think that will be that much informative BTW) don't use the 
SpectralAnalysis, this class is intended to work as explained before 
(sort of stream-like and on a continuous manner, like a regular STFT). 
Just do a regular FFT maybe adding the Window and zero padding if you 
want your peak detection to work better.

b) What you are really trying to do is to get an average descriptor over 
a note. Then do a regular STFT that will return a sequence of spectrums, 
compute the peaks for each spectrum, compute the pitch for each spectrum 
and finally take the average of all pitches as the note pitch.

BTW. Have you done the tutorial? I know it is a bit long to do but this 
kind of questions are supposed to be answered in there.

Oh, and I will try to see why the error is not caught on a higher layer, 
giving a more informative message. Well, the reason is that 
configurations are not as exhaustively checked as they should but I will 
see if this particular one has a quick fix.

Martijn Bosma wrote:

>Hello,
>
>I have some problems with finding the fundamental frequency of an audio 
>object.
>The code of my function can be found below.
>As its input it uses an audio object called chunk.
>chunk contains one note of a melody.  (more or less one second in length)
>My main problem is to go from an audio object to its spectrum
>
>- Is it possible for the SpectrumAnalysis object to analyse the spectrum 
>  of this chunk at once?
>
>- How do I configure the spectrum analysis object for this task?
>  (zeropadding, hopsize, windowsize, windowtype and circularshift?)
>
>- when I run the program and the program reaches the do method of the
>  SpectralAnalysis object in my code, I get the following exception 
>  breakpoint:
>	ASSERTION FAILED
>	spectrum.cxx line 647:
>	Spectrum::GetSize(): Complex size and Size mismatch.
>  this is probably because of a wrong configuration of the 
>  spectralAnalysis object or because of the size of the audio chunk.
>
>
>- for the configuration of the FundFreqDetect and the SpectralPeakDetect 
>  objects I use the default values of their configuration classes.
>  (e.g. ffdConfig.DefaultValues();)
>  is this correct, or necessary?
>
>
>I have sent this problem before to the clamlist, but then I 
>was not clear about what I would like to know.
>I think now I have sent the code as well it is easier for people to see
>where I go wrong here.
>
>Thanks in advance for helping
>Martijn
>
>*************************************************************
>//THE CODE:
>
>// chunk is an audio object containing one note of the melody
>// this method gets the  fundamental frequency of chunk. 
>// It stores the resulting fundamental object in 
>// the "vector<Fundamental> pitches"
>void MyCLAMApp::DoFunfreq(Audio chunk)
>{
>
>	// make spectrum object
>	SpectrumConfig cfg;
>	cfg.SetSize(chunk_size / 2  + 1);
>
>	Spectrum spec;
>	spec.Configure(cfg);
>	spec.ToDB();
>
>
>	// spectrum analyzer
>	// sampleRate = samplerate of the audio object chunk
>	SpectralAnalysisConfig sac;
>	sac.AddAll();
>	sac.UpdateData();
>    	sac.SetSamplingRate(sampleRate);
>	sac.SetZeroPadding(0);
>	sac.SetHopSize(0);
>	sac.SetWindowSize(513);   
>	sac.SetWindowType(EWindowType::eHamming);
>    	sac.SetHopSize((sac.GetWindowSize()-1)/2);
>	sac.GetCircularShift().SetAmount(-256);
>
>	SpectralAnalysis sa;
>	sa.Configure(sac);
>	sa.Start();
>	sa.Do(chunk, spec);	// this line of code causes the exception 
>breakpoint
>	sa.Stop();
>
>	
>	// get the spectralpeak array from spectrum
>	SpectralPeakDetectConfig detectPeaksConfig;
>	detectPeaksConfig.DefaultValues();
>
>	SpectralPeakDetect	detectPeaks;
>	detectPeaks.Configure(detectPeaksConfig);
>
>	SpectralPeakArray peaks;
>	peaks.SetScale(EScale(EScale::eLog));
>
>	detectPeaks.Start();
>	detectPeaks.Do(spec, peaks);
>	detectPeaks.Stop();
>
>
>	// fundamental frequency detection
>	Fundamental fund;
>	fund.AddCandidatesFreq();
>    	fund.AddCandidatesErr();
>    	fund.UpdateData();
>	fund.SetnCandidates(0);
>	fund.SetnMaxCandidates(60);
>
>	FundFreqDetectConfig ffdConfig;
>	ffdConfig.DefaultValues();
>
>	FundFreqDetect ffd;
>	ffd.Configure(ffdConfig);
>	
>	ffd.Start();
>	ffd.Do(peaks, fund);
>	ffd.Stop();
>
>
>	// store the fundamental object
>	pitches.push_back(fund);
>
>}
>
>
>_______________________________________________
>CLAM mailing list
>CLAM at iua.upf.es
>http://www.iua.upf.es/mtg/clam
>
>
>  
>

-- 
/**
*     Xavier Amatriain
*   Music Technology Group
*  Universitat Pompeu Fabra
* http://iua.upf.es/mtg/~xamat
*
*/






More information about the clam-users mailing list