public bool Run(float[] data, float deltaTime) { syllableDetected = false; float sumIntensity = 0; if (!SinglePolaity(data)) // Here to easily take out artifacts found on my poor desktop mic { sumIntensity = SumAbsIntensity(data); level = sumIntensity / data.Length; float mean = SumIntensity(data) / data.Length; int sampleOffsetHigh; int sampleOffsetLow; FrequencyBandToSampleOffsets(data.Length, sampleRate, 80, 300, out sampleOffsetHigh, out sampleOffsetLow); // was 80,900 float newNPA = DoNormalisedPeakAutocorrelation(data, mean, sampleOffsetHigh, sampleOffsetLow); normalisedPeakAutocorrelation += (newNPA - normalisedPeakAutocorrelation) * deltaTime * 10; DipTracking(); // If we're using the periodicity, check that the normalised value is high before // considering it if (normalisedPeakAutocorrelation > npaThreshold) { peak = Math.Max(peak, level); PeakPicking(); } } else { level = 0; } if (syllableDetected) { totalSyllables++; } LogMT.SendStreamValue("MTdt", deltaTime); LogMT.SendStreamValue("MTnpa", normalisedPeakAutocorrelation); LogMT.SendStreamValue("MTlvl", level); LogMT.SendStreamValue("MTpek", peak); LogMT.SendStreamValue("MTdip", dip); LogMT.SendStreamValue("MTdpd", Convert.ToInt32(dipped)); LogMT.SendStreamValue("MTsbs", totalSyllables); return(syllableDetected); }
/// <summary> /// Calculates the peak of the normalised autocorrelation of a window of samples, /// with an offset within a given band. /// </summary> private static float DoNormalisedPeakAutocorrelation(float[] window, float mean, int sampleOffsetHigh, int sampleOffsetLow) { float highest = 0; float[] gammaA = new float[sampleOffsetHigh - sampleOffsetLow + 1]; float sumZero = 0; for (int t = 0; t < window.Length - 0; t++) { sumZero += window[t + 0] * window[t]; } float gammaZero = sumZero / window.Length; for (int h = sampleOffsetHigh; h >= sampleOffsetLow; h--) { float sum = 0; for (int t = 0; t < window.Length - h; t++) { sum += (window[t + h] - mean) * (window[t] - mean); } float gamma = (sum / window.Length) / (window.Length - h); if (gamma > highest) { highest = gamma; } float norm = highest / (gammaZero / window.Length); gammaA[h - sampleOffsetLow] = norm; } // Here we normalise the peak value so it is between 0 and 1 float normalised = highest / (gammaZero / window.Length); LogMT.SendStreamValue("MTsoL", sampleOffsetLow); LogMT.SendStreamValue("MTsoH", sampleOffsetHigh); LogMT.SendStreamValueBlock("MTatc", gammaA); return(normalised); }