// Takes the input audio channel |impulseP| as an input impulse response and calculates the average group delay. // This represents the initial delay before the most energetic part of the impulse response. // The sample-frame delay is removed from the |impulseP| impulse response, and this value is returned. // The |length| of the passed in |impulseP| must be must be a power of 2. static float extractAverageGroupDelay(float* impulseP, size_t length) { // Check for power-of-2. MOZ_ASSERT(length && (length & (length - 1)) == 0); FFTBlock estimationFrame(length); estimationFrame.PerformFFT(impulseP); float frameDelay = static_cast<float>(estimationFrame.ExtractAverageGroupDelay()); estimationFrame.GetInverse(impulseP); return frameDelay; }
// Takes the input AudioChannel as an input impulse response and calculates the average group delay. // This represents the initial delay before the most energetic part of the impulse response. // The sample-frame delay is removed from the impulseP impulse response, and this value is returned. // the length of the passed in AudioChannel must be a power of 2. static float extractAverageGroupDelay(AudioChannel* channel, size_t analysisFFTSize) { ASSERT(channel); float* impulseP = channel->mutableData(); bool isSizeGood = channel->length() >= analysisFFTSize; ASSERT(isSizeGood); if (!isSizeGood) return 0; // Check for power-of-2. ASSERT(1UL << static_cast<unsigned>(log2(analysisFFTSize)) == analysisFFTSize); FFTFrame estimationFrame(analysisFFTSize); estimationFrame.doFFT(impulseP); float frameDelay = narrowPrecisionToFloat(estimationFrame.extractAverageGroupDelay()); estimationFrame.doInverseFFT(impulseP); return frameDelay; }