Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1371)

Unified Diff: Source/modules/webaudio/WaveTable.cpp

Issue 18182009: WaveTable name has changed to PeriodicWave (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: fix global constructors test Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/webaudio/WaveTable.h ('k') | Source/modules/webaudio/WaveTable.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/webaudio/WaveTable.cpp
diff --git a/Source/modules/webaudio/WaveTable.cpp b/Source/modules/webaudio/WaveTable.cpp
deleted file mode 100644
index cd322bb94e5aa747bc592629592485bed7f54cfb..0000000000000000000000000000000000000000
--- a/Source/modules/webaudio/WaveTable.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(WEB_AUDIO)
-
-#include "modules/webaudio/WaveTable.h"
-
-#include "core/platform/audio/FFTFrame.h"
-#include "core/platform/audio/VectorMath.h"
-#include "modules/webaudio/OscillatorNode.h"
-#include <algorithm>
-#include "wtf/OwnPtr.h"
-
-const unsigned WaveTableSize = 4096; // This must be a power of two.
-const unsigned NumberOfRanges = 36; // There should be 3 * log2(WaveTableSize) 1/3 octave ranges.
-const float CentsPerRange = 1200 / 3; // 1/3 Octave.
-
-namespace WebCore {
-
-using namespace VectorMath;
-
-PassRefPtr<WaveTable> WaveTable::create(float sampleRate, Float32Array* real, Float32Array* imag)
-{
- bool isGood = real && imag && real->length() == imag->length();
- ASSERT(isGood);
- if (isGood) {
- RefPtr<WaveTable> waveTable = adoptRef(new WaveTable(sampleRate));
- size_t numberOfComponents = real->length();
- waveTable->createBandLimitedTables(real->data(), imag->data(), numberOfComponents);
- return waveTable;
- }
- return 0;
-}
-
-PassRefPtr<WaveTable> WaveTable::createSine(float sampleRate)
-{
- RefPtr<WaveTable> waveTable = adoptRef(new WaveTable(sampleRate));
- waveTable->generateBasicWaveform(OscillatorNode::SINE);
- return waveTable;
-}
-
-PassRefPtr<WaveTable> WaveTable::createSquare(float sampleRate)
-{
- RefPtr<WaveTable> waveTable = adoptRef(new WaveTable(sampleRate));
- waveTable->generateBasicWaveform(OscillatorNode::SQUARE);
- return waveTable;
-}
-
-PassRefPtr<WaveTable> WaveTable::createSawtooth(float sampleRate)
-{
- RefPtr<WaveTable> waveTable = adoptRef(new WaveTable(sampleRate));
- waveTable->generateBasicWaveform(OscillatorNode::SAWTOOTH);
- return waveTable;
-}
-
-PassRefPtr<WaveTable> WaveTable::createTriangle(float sampleRate)
-{
- RefPtr<WaveTable> waveTable = adoptRef(new WaveTable(sampleRate));
- waveTable->generateBasicWaveform(OscillatorNode::TRIANGLE);
- return waveTable;
-}
-
-WaveTable::WaveTable(float sampleRate)
- : m_sampleRate(sampleRate)
- , m_waveTableSize(WaveTableSize)
- , m_numberOfRanges(NumberOfRanges)
- , m_centsPerRange(CentsPerRange)
-{
- ScriptWrappable::init(this);
- float nyquist = 0.5 * m_sampleRate;
- m_lowestFundamentalFrequency = nyquist / maxNumberOfPartials();
- m_rateScale = m_waveTableSize / m_sampleRate;
-}
-
-void WaveTable::waveDataForFundamentalFrequency(float fundamentalFrequency, float* &lowerWaveData, float* &higherWaveData, float& tableInterpolationFactor)
-{
- // Negative frequencies are allowed, in which case we alias to the positive frequency.
- fundamentalFrequency = fabsf(fundamentalFrequency);
-
- // Calculate the pitch range.
- float ratio = fundamentalFrequency > 0 ? fundamentalFrequency / m_lowestFundamentalFrequency : 0.5;
- float centsAboveLowestFrequency = log2f(ratio) * 1200;
-
- // Add one to round-up to the next range just in time to truncate partials before aliasing occurs.
- float pitchRange = 1 + centsAboveLowestFrequency / m_centsPerRange;
-
- pitchRange = std::max(pitchRange, 0.0f);
- pitchRange = std::min(pitchRange, static_cast<float>(m_numberOfRanges - 1));
-
- // The words "lower" and "higher" refer to the table data having the lower and higher numbers of partials.
- // It's a little confusing since the range index gets larger the more partials we cull out.
- // So the lower table data will have a larger range index.
- unsigned rangeIndex1 = static_cast<unsigned>(pitchRange);
- unsigned rangeIndex2 = rangeIndex1 < m_numberOfRanges - 1 ? rangeIndex1 + 1 : rangeIndex1;
-
- lowerWaveData = m_bandLimitedTables[rangeIndex2]->data();
- higherWaveData = m_bandLimitedTables[rangeIndex1]->data();
-
- // Ranges from 0 -> 1 to interpolate between lower -> higher.
- tableInterpolationFactor = pitchRange - rangeIndex1;
-}
-
-unsigned WaveTable::maxNumberOfPartials() const
-{
- return m_waveTableSize / 2;
-}
-
-unsigned WaveTable::numberOfPartialsForRange(unsigned rangeIndex) const
-{
- // Number of cents below nyquist where we cull partials.
- float centsToCull = rangeIndex * m_centsPerRange;
-
- // A value from 0 -> 1 representing what fraction of the partials to keep.
- float cullingScale = pow(2, -centsToCull / 1200);
-
- // The very top range will have all the partials culled.
- unsigned numberOfPartials = cullingScale * maxNumberOfPartials();
-
- return numberOfPartials;
-}
-
-// Convert into time-domain wave tables.
-// One table is created for each range for non-aliasing playback at different playback rates.
-// Thus, higher ranges have more high-frequency partials culled out.
-void WaveTable::createBandLimitedTables(const float* realData, const float* imagData, unsigned numberOfComponents)
-{
- float normalizationScale = 1;
-
- unsigned fftSize = m_waveTableSize;
- unsigned halfSize = fftSize / 2;
- unsigned i;
-
- numberOfComponents = std::min(numberOfComponents, halfSize);
-
- m_bandLimitedTables.reserveCapacity(m_numberOfRanges);
-
- for (unsigned rangeIndex = 0; rangeIndex < m_numberOfRanges; ++rangeIndex) {
- // This FFTFrame is used to cull partials (represented by frequency bins).
- FFTFrame frame(fftSize);
- float* realP = frame.realData();
- float* imagP = frame.imagData();
-
- // Copy from loaded frequency data and scale.
- float scale = fftSize;
- vsmul(realData, 1, &scale, realP, 1, numberOfComponents);
- vsmul(imagData, 1, &scale, imagP, 1, numberOfComponents);
-
- // If fewer components were provided than 1/2 FFT size, then clear the remaining bins.
- for (i = numberOfComponents; i < halfSize; ++i) {
- realP[i] = 0;
- imagP[i] = 0;
- }
-
- // Generate complex conjugate because of the way the inverse FFT is defined.
- float minusOne = -1;
- vsmul(imagP, 1, &minusOne, imagP, 1, halfSize);
-
- // Find the starting bin where we should start culling.
- // We need to clear out the highest frequencies to band-limit the waveform.
- unsigned numberOfPartials = numberOfPartialsForRange(rangeIndex);
-
- // Cull the aliasing partials for this pitch range.
- for (i = numberOfPartials + 1; i < halfSize; ++i) {
- realP[i] = 0;
- imagP[i] = 0;
- }
- // Clear packed-nyquist if necessary.
- if (numberOfPartials < halfSize)
- imagP[0] = 0;
-
- // Clear any DC-offset.
- realP[0] = 0;
-
- // Create the band-limited table.
- OwnPtr<AudioFloatArray> table = adoptPtr(new AudioFloatArray(m_waveTableSize));
- m_bandLimitedTables.append(table.release());
-
- // Apply an inverse FFT to generate the time-domain table data.
- float* data = m_bandLimitedTables[rangeIndex]->data();
- frame.doInverseFFT(data);
-
- // For the first range (which has the highest power), calculate its peak value then compute normalization scale.
- if (!rangeIndex) {
- float maxValue;
- vmaxmgv(data, 1, &maxValue, m_waveTableSize);
-
- if (maxValue)
- normalizationScale = 1.0f / maxValue;
- }
-
- // Apply normalization scale.
- vsmul(data, 1, &normalizationScale, data, 1, m_waveTableSize);
- }
-}
-
-void WaveTable::generateBasicWaveform(int shape)
-{
- unsigned fftSize = waveTableSize();
- unsigned halfSize = fftSize / 2;
-
- AudioFloatArray real(halfSize);
- AudioFloatArray imag(halfSize);
- float* realP = real.data();
- float* imagP = imag.data();
-
- // Clear DC and Nyquist.
- realP[0] = 0;
- imagP[0] = 0;
-
- for (unsigned n = 1; n < halfSize; ++n) {
- float omega = 2 * piFloat * n;
- float invOmega = 1 / omega;
-
- // Fourier coefficients according to standard definition.
- float a; // Coefficient for cos().
- float b; // Coefficient for sin().
-
- // Calculate Fourier coefficients depending on the shape.
- // Note that the overall scaling (magnitude) of the waveforms is normalized in createBandLimitedTables().
- switch (shape) {
- case OscillatorNode::SINE:
- // Standard sine wave function.
- a = 0;
- b = (n == 1) ? 1 : 0;
- break;
- case OscillatorNode::SQUARE:
- // Square-shaped waveform with the first half its maximum value and the second half its minimum value.
- a = 0;
- b = invOmega * ((n & 1) ? 2 : 0);
- break;
- case OscillatorNode::SAWTOOTH:
- // Sawtooth-shaped waveform with the first half ramping from zero to maximum and the second half from minimum to zero.
- a = 0;
- b = -invOmega * cos(0.5 * omega);
- break;
- case OscillatorNode::TRIANGLE:
- // Triangle-shaped waveform going from its maximum value to its minimum value then back to the maximum value.
- a = (4 - 4 * cos(0.5 * omega)) / (n * n * piFloat * piFloat);
- b = 0;
- break;
- default:
- ASSERT_NOT_REACHED();
- a = 0;
- b = 0;
- break;
- }
-
- realP[n] = a;
- imagP[n] = b;
- }
-
- createBandLimitedTables(realP, imagP, halfSize);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEB_AUDIO)
« no previous file with comments | « Source/modules/webaudio/WaveTable.h ('k') | Source/modules/webaudio/WaveTable.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698