As I'm analysing music, it doesn't make sense to consider the whole spectrum range, am I right? I mean, based on this, I should worry to check only until the 4k range.
This is not right. What the chart does not show is the approximate energy drop per octave of each instrument. A kick drum, for example, will have strong energy in the low range (say below 120Hz), but often very little within the highs (say above 10kHz).
If you are analysing music, and say there is a kick drum and a distorted guitar (which has dominent frequencies from the fundamental all the way up the spectrum), you are unlikely to be able to detect the kick drum, as the distorted guitar 4k energy will overpower any 4k in the kick. If you however analyse 80Hz - you should 'see' the kick no problem.
So, in case the previous sentence is right, I shouldn't take all the 512 spectrum values, but only the first ones. So if my samples are at 44100Hz, and I have a spectrum with 512 values, each one should cover a range of (approximately) 86Hz. Is that correct? In that case, I should only analyse the first 47 array values and safely ignore the rest, I guess.
As explained, the previous sentence is not right.
In addition, a sample rate of 44100Hz can contain frequencies up to 22050Hz (aka the Nyquist frequency = half the sample rate). I'm not sure what KissFFT gives you back, most FFTs will give you a mirrored result, of which you take the first half, and you work out what x-value corresponds to what frequency by calculating the frequency gap. I hope that you get how this is done from this code (alternatively look at the code here):
[ iSamples, iSamplingRate, iBitDepth ] = wavread( '100Hz16b.wav' );
iNyquist = iSamplingRate / 2;
iSampleCount = length( iSamples );
iAudioDuration = iSampleCount / iSamplingRate;
iFrequencyDelta = 1 / iAudioDuration;
iFFT = fft( iSamples );
# Get half of the set
iFFT = iFFT( 1:iSampleCount/2 + 1);
iFreqRange = 0: iFrequencyDelta : iNyquist;
plot( iFreqRange, 10*log10( abs(iFFT) ) );
If I want to analyse a wider frequency, would be enough to sum the values from each frequency and calculate the mean? Is that correct?
Generally speaking this is correct, but the wider the bandwidth of your analysis is, the harder it will be to detect differences. Say we take the extreme case where you analyse the whole frequency spectrum - you would not be able to distinguish one instrument from another. More on this below.
What I'm doing is reasonable? Or I'm just making crazy random stuff?
This is a momentous challenge (PhD stuff), but with a hard effort you might be able to demonstrate some degree of success (depending on the complexity of the material being analysed).
What you have to consider is that the timbre of all sounds can be broken down into two components:
- Their spectral content (ie, what frequencies exist and how much energy in each range).
- Their dynamic envelope (how their average level changes over time).
For the latter, do some research on 'beat detection' (but try to ignore anything with DJ in the title) and envelope followers (which is a very common strategy to detect the transient nature of sounds - work better than compering RMS to peak).
While I can't share an untested strategy, you may want to consider (starting with extremely simple material, like a kick drum and a violin going slowly crescendo):
- Perform FFT.
- Perform envelope follower on each of the bands you get.
- Take it from here (think patterns and deviations).