Pitch detection algorithm
An algorithm that attempts to detect the pitch (inverse of frequency) of a periodic signal, usually digitized sound. This can be done in the time domain or the frequency domain. In the time domain, a simple approach would be to measure the distance between zero-crossing points of the signal. However, this does not work well with complex waveforms. A better way is to compare parts of the signal with other parts of it to find a match. AMDF (Average Magnitude Difference Function), or the similar Autocorrelation work this way. These algorithms can give quite accurate results, however they have false detection problems and don't tolerate well to noisy signals. Also, they don't work with polyphonic sounds (which involve more than one pitch). In the frequency domain, polyphonic detection is possible, usually utilizing the Fast Fourier Transformation (FFT) to convert sound to frequency spectrum, however this requires more processing power as the desired accuracy increases. Below is an implementation of a modified AMDF algorithm in pascal programming language: (* XAMDF pitch detection algorithm *)
const
Sample_Size = 128;
Half_Size = Sample_Size div 2;
Sample_Rate = 5000;
var
Samples : array [1..Sample_Size] of byte;
function Detect_Frequency:real;
var
Period, Time : integer;
ErrPer1, ErrPerX : longint;
begin
ErrPer1:=0;
for Time:=1 to Half_Size do
ErrPer1:=ErrPer1+abs(Samples[Time]-Samples[Time+1]);
for Period:=2 to Half_Size do
begin
ErrPerX:=0;
for Time:=1 to Half_Size do
ErrPerX:=ErrPerX+abs(Samples[Time]-Samples[Time+Period]);
if (ErrPerX < ErrPer1) then
begin
Detect_Frequency:=Sample_Rate/(Period+(ErrPerX/ErrPer1));
Exit;
end;
end;
Detect_Frequency:=0;
end;
|