Esempio n. 1
0
void RealtimeAnalyser::convertToByteData(DOMUint8Array* destinationArray) {
  // Convert from linear magnitude to unsigned-byte decibels.
  unsigned sourceLength = magnitudeBuffer().size();
  size_t len = std::min(sourceLength, destinationArray->length());
  if (len > 0) {
    const double rangeScaleFactor = m_maxDecibels == m_minDecibels
                                        ? 1
                                        : 1 / (m_maxDecibels - m_minDecibels);
    const double minDecibels = m_minDecibels;

    const float* source = magnitudeBuffer().data();
    unsigned char* destination = destinationArray->data();

    for (unsigned i = 0; i < len; ++i) {
      float linearValue = source[i];
      double dbMag = 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;

      // Clip to valid range.
      if (scaledValue < 0)
        scaledValue = 0;
      if (scaledValue > UCHAR_MAX)
        scaledValue = UCHAR_MAX;

      destination[i] = static_cast<unsigned char>(scaledValue);
    }
  }
}
Esempio n. 2
0
void RealtimeAnalyser::getByteFrequencyData(Uint8Array* destinationArray)
{
    ASSERT(isMainThread());

    if (!destinationArray)
        return;
        
    doFFTAnalysis();
    
    // Convert from linear magnitude to unsigned-byte decibels.
    unsigned sourceLength = magnitudeBuffer().size();
    size_t len = min(sourceLength, destinationArray->length());
    if (len > 0) {
        const double RangeScaleFactor = m_maxDecibels == m_minDecibels ? 1.0 : 1.0 / (m_maxDecibels - m_minDecibels);

        const float* source = magnitudeBuffer().data();
        unsigned char* destination = destinationArray->data();        
        
        for (unsigned i = 0; i < len; ++i) {
            float linearValue = source[i];
            double dbMag = !linearValue ? m_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 - m_minDecibels) * RangeScaleFactor;

            // Clip to valid range.
            if (scaledValue < 0.0)
                scaledValue = 0.0;
            if (scaledValue > UCHAR_MAX)
                scaledValue = UCHAR_MAX;
            
            destination[i] = static_cast<unsigned char>(scaledValue);
        }
    }
}
Esempio n. 3
0
void RealtimeAnalyser::doFFTAnalysis() {
  DCHECK(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();

  // Take the previous fftSize values from the input buffer and copy into the
  // temporary buffer.
  unsigned writeIndex = m_writeIndex;
  if (writeIndex < fftSize) {
    memcpy(tempP, inputBuffer + writeIndex - fftSize + InputBufferSize,
           sizeof(*tempP) * (fftSize - writeIndex));
    memcpy(tempP + fftSize - writeIndex, inputBuffer,
           sizeof(*tempP) * writeIndex);
  } else {
    memcpy(tempP, inputBuffer + writeIndex - fftSize, sizeof(*tempP) * fftSize);
  }

  // Window the input samples.
  applyWindow(tempP, fftSize);

  // Do the analysis.
  m_analysisFrame->doFFT(tempP);

  float* realP = m_analysisFrame->realData();
  float* imagP = m_analysisFrame->imagData();

  // 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 / fftSize;

  // A value of 0 does no averaging with the previous result.  Larger values
  // produce slower, but smoother changes.
  double k = m_smoothingTimeConstant;
  k = std::max(0.0, k);
  k = std::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) {
    std::complex<double> c(realP[i], imagP[i]);
    double scalarMagnitude = abs(c) * magnitudeScale;
    destination[i] = float(k * destination[i] + (1 - k) * scalarMagnitude);
  }
}
Esempio n. 4
0
void RealtimeAnalyser::convertFloatToDb(DOMFloat32Array* destinationArray) {
  // Convert from linear magnitude to floating-point decibels.
  unsigned sourceLength = magnitudeBuffer().size();
  size_t len = std::min(sourceLength, destinationArray->length());
  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 = AudioUtilities::linearToDecibels(linearValue);
      destination[i] = float(dbMag);
    }
  }
}
Esempio n. 5
0
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();

    // Take the previous fftSize values from the input buffer and copy into the temporary buffer.
    // FIXME : optimize with memcpy().
    unsigned writeIndex = m_writeIndex;
    for (unsigned i = 0; i < fftSize; ++i)
        tempP[i] = inputBuffer[(i + writeIndex - fftSize + InputBufferSize) % InputBufferSize];
    
    // Window the input samples.
    applyWindow(tempP, fftSize);
    
    // Do the analysis.
    m_analysisFrame->doFFT(tempP);

    float* realP = m_analysisFrame->realData();
    float* imagP = m_analysisFrame->imagData();

    // Blow away the packed nyquist component.
    imagP[0] = 0.0f;
    
    // 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);    
    
    // 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;        
        destination[i] = float(k * destination[i] + (1.0 - k) * scalarMagnitude);
    }
}
void RealtimeAnalyser::getFloatFrequencyData(DOMFloat32Array* destinationArray)
{
    ASSERT(isMainThread());
    ASSERT(destinationArray);

    doFFTAnalysis();

    // Convert from linear magnitude to floating-point decibels.
    const double minDecibels = m_minDecibels;
    unsigned sourceLength = magnitudeBuffer().size();
    size_t len = std::min(sourceLength, destinationArray->length());
    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);
            destination[i] = float(dbMag);
        }
    }
}