[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