| Index: Source/modules/webaudio/RealtimeAnalyser.cpp
|
| diff --git a/Source/modules/webaudio/RealtimeAnalyser.cpp b/Source/modules/webaudio/RealtimeAnalyser.cpp
|
| index c8a700ed79ecb18db725f6bd5aee6aa9aa793b96..8ec324350535a54379623706c978b4db62321592 100644
|
| --- a/Source/modules/webaudio/RealtimeAnalyser.cpp
|
| +++ b/Source/modules/webaudio/RealtimeAnalyser.cpp
|
| @@ -105,13 +105,13 @@ void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess)
|
| ASSERT(isBusGood);
|
| if (!isBusGood)
|
| return;
|
| -
|
| +
|
| // FIXME : allow to work with non-FFTSize divisible chunking
|
| bool isDestinationGood = m_writeIndex < m_inputBuffer.size() && m_writeIndex + framesToProcess <= m_inputBuffer.size();
|
| ASSERT(isDestinationGood);
|
| if (!isDestinationGood)
|
| - return;
|
| -
|
| + return;
|
| +
|
| // Perform real-time analysis
|
| const float* source = bus->channel(0)->data();
|
| float* dest = m_inputBuffer.data() + m_writeIndex;
|
| @@ -140,13 +140,13 @@ namespace {
|
| void applyWindow(float* p, size_t n)
|
| {
|
| ASSERT(isMainThread());
|
| -
|
| +
|
| // Blackman window
|
| double alpha = 0.16;
|
| double a0 = 0.5 * (1 - alpha);
|
| double a1 = 0.5;
|
| double a2 = 0.5 * alpha;
|
| -
|
| +
|
| for (unsigned i = 0; i < n; ++i) {
|
| double x = static_cast<double>(i) / static_cast<double>(n);
|
| double window = a0 - a1 * cos(2 * piDouble * x) + a2 * cos(4 * piDouble * x);
|
| @@ -157,12 +157,12 @@ void applyWindow(float* p, size_t n)
|
| } // namespace
|
|
|
| void RealtimeAnalyser::doFFTAnalysis()
|
| -{
|
| +{
|
| ASSERT(isMainThread());
|
|
|
| // Unroll the input buffer into a temporary buffer, where we'll apply an analysis window followed by an FFT.
|
| size_t fftSize = this->fftSize();
|
| -
|
| +
|
| AudioFloatArray temporaryBuffer(fftSize);
|
| float* inputBuffer = m_inputBuffer.data();
|
| float* tempP = temporaryBuffer.data();
|
| @@ -172,13 +172,13 @@ void RealtimeAnalyser::doFFTAnalysis()
|
| if (writeIndex < fftSize) {
|
| memcpy(tempP, inputBuffer + writeIndex - fftSize + InputBufferSize, sizeof(*tempP) * (fftSize - writeIndex));
|
| memcpy(tempP + fftSize - writeIndex, inputBuffer, sizeof(*tempP) * writeIndex);
|
| - } else
|
| + } else
|
| memcpy(tempP, inputBuffer + writeIndex - fftSize, sizeof(*tempP) * fftSize);
|
|
|
| -
|
| +
|
| // Window the input samples.
|
| applyWindow(tempP, fftSize);
|
| -
|
| +
|
| // Do the analysis.
|
| m_analysisFrame->doFFT(tempP);
|
|
|
| @@ -187,21 +187,21 @@ void RealtimeAnalyser::doFFTAnalysis()
|
|
|
| // Blow away the packed nyquist component.
|
| imagP[0] = 0;
|
| -
|
| +
|
| // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor).
|
| const double magnitudeScale = 1.0 / DefaultFFTSize;
|
|
|
| // A value of 0 does no averaging with the previous result. Larger values produce slower, but smoother changes.
|
| double k = m_smoothingTimeConstant;
|
| k = max(0.0, k);
|
| - k = min(1.0, k);
|
| -
|
| + k = min(1.0, k);
|
| +
|
| // Convert the analysis data from complex to magnitude and average with the previous result.
|
| float* destination = magnitudeBuffer().data();
|
| size_t n = magnitudeBuffer().size();
|
| for (size_t i = 0; i < n; ++i) {
|
| Complex c(realP[i], imagP[i]);
|
| - double scalarMagnitude = abs(c) * magnitudeScale;
|
| + double scalarMagnitude = abs(c) * magnitudeScale;
|
| destination[i] = float(k * destination[i] + (1 - k) * scalarMagnitude);
|
| }
|
| }
|
| @@ -212,9 +212,9 @@ void RealtimeAnalyser::getFloatFrequencyData(Float32Array* destinationArray)
|
|
|
| if (!destinationArray)
|
| return;
|
| -
|
| +
|
| doFFTAnalysis();
|
| -
|
| +
|
| // Convert from linear magnitude to floating-point decibels.
|
| const double minDecibels = m_minDecibels;
|
| unsigned sourceLength = magnitudeBuffer().size();
|
| @@ -222,7 +222,7 @@ void RealtimeAnalyser::getFloatFrequencyData(Float32Array* destinationArray)
|
| if (len > 0) {
|
| const float* source = magnitudeBuffer().data();
|
| float* destination = destinationArray->data();
|
| -
|
| +
|
| for (unsigned i = 0; i < len; ++i) {
|
| float linearValue = source[i];
|
| double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue);
|
| @@ -237,9 +237,9 @@ void RealtimeAnalyser::getByteFrequencyData(Uint8Array* destinationArray)
|
|
|
| if (!destinationArray)
|
| return;
|
| -
|
| +
|
| doFFTAnalysis();
|
| -
|
| +
|
| // Convert from linear magnitude to unsigned-byte decibels.
|
| unsigned sourceLength = magnitudeBuffer().size();
|
| size_t len = min(sourceLength, destinationArray->length());
|
| @@ -248,12 +248,12 @@ void RealtimeAnalyser::getByteFrequencyData(Uint8Array* destinationArray)
|
| const double minDecibels = m_minDecibels;
|
|
|
| const float* source = magnitudeBuffer().data();
|
| - unsigned char* destination = destinationArray->data();
|
| -
|
| + unsigned char* destination = destinationArray->data();
|
| +
|
| for (unsigned i = 0; i < len; ++i) {
|
| float linearValue = source[i];
|
| double dbMag = !linearValue ? minDecibels : AudioUtilities::linearToDecibels(linearValue);
|
| -
|
| +
|
| // The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX.
|
| double scaledValue = UCHAR_MAX * (dbMag - minDecibels) * rangeScaleFactor;
|
|
|
| @@ -262,7 +262,7 @@ void RealtimeAnalyser::getByteFrequencyData(Uint8Array* destinationArray)
|
| scaledValue = 0;
|
| if (scaledValue > UCHAR_MAX)
|
| scaledValue = UCHAR_MAX;
|
| -
|
| +
|
| destination[i] = static_cast<unsigned char>(scaledValue);
|
| }
|
| }
|
| @@ -274,7 +274,7 @@ void RealtimeAnalyser::getByteTimeDomainData(Uint8Array* destinationArray)
|
|
|
| if (!destinationArray)
|
| return;
|
| -
|
| +
|
| unsigned fftSize = this->fftSize();
|
| size_t len = min(fftSize, destinationArray->length());
|
| if (len > 0) {
|
| @@ -283,9 +283,9 @@ void RealtimeAnalyser::getByteTimeDomainData(Uint8Array* destinationArray)
|
| if (!isInputBufferGood)
|
| return;
|
|
|
| - float* inputBuffer = m_inputBuffer.data();
|
| + float* inputBuffer = m_inputBuffer.data();
|
| unsigned char* destination = destinationArray->data();
|
| -
|
| +
|
| unsigned writeIndex = m_writeIndex;
|
|
|
| for (unsigned i = 0; i < len; ++i) {
|
| @@ -300,7 +300,7 @@ void RealtimeAnalyser::getByteTimeDomainData(Uint8Array* destinationArray)
|
| scaledValue = 0;
|
| if (scaledValue > UCHAR_MAX)
|
| scaledValue = UCHAR_MAX;
|
| -
|
| +
|
| destination[i] = static_cast<unsigned char>(scaledValue);
|
| }
|
| }
|
|
|