2 * Copyright (C) 2010, Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "DelayDSPKernel.h"
31 #include "AudioUtilities.h"
36 const double DefaultMaxDelayTime = 1.0;
37 const double SmoothingTimeConstant = 0.020; // 20ms
41 DelayDSPKernel::DelayDSPKernel(DelayProcessor* processor)
42 : AudioDSPKernel(processor)
43 , m_maxDelayTime(DefaultMaxDelayTime)
47 ASSERT(processor && processor->sampleRate() > 0);
51 m_buffer.allocate(static_cast<size_t>(processor->sampleRate() * DefaultMaxDelayTime));
54 m_smoothingRate = AudioUtilities::discreteTimeConstantForSampleRate(SmoothingTimeConstant, processor->sampleRate());
57 DelayDSPKernel::DelayDSPKernel(double maxDelayTime, double sampleRate)
58 : AudioDSPKernel(sampleRate)
59 , m_maxDelayTime(maxDelayTime)
63 ASSERT(maxDelayTime > 0.0);
64 if (maxDelayTime <= 0.0)
67 size_t bufferLength = static_cast<size_t>(sampleRate * maxDelayTime);
72 m_buffer.allocate(bufferLength);
75 m_smoothingRate = AudioUtilities::discreteTimeConstantForSampleRate(SmoothingTimeConstant, sampleRate);
78 void DelayDSPKernel::process(const float* source, float* destination, size_t framesToProcess)
80 size_t bufferLength = m_buffer.size();
81 float* buffer = m_buffer.data();
87 ASSERT(source && destination);
88 if (!source || !destination)
91 double sampleRate = this->sampleRate();
92 double delayTime = delayProcessor() ? delayProcessor()->delayTime()->value() : m_desiredDelayFrames / sampleRate;
94 // Make sure the delay time is in a valid range.
95 delayTime = min(maxDelayTime(), delayTime);
96 delayTime = max(0.0, delayTime);
99 m_currentDelayTime = delayTime;
103 int n = framesToProcess;
105 // Approach desired delay time.
106 m_currentDelayTime += (delayTime - m_currentDelayTime) * m_smoothingRate;
108 double desiredDelayFrames = m_currentDelayTime * sampleRate;
110 double readPosition = m_writeIndex + bufferLength - desiredDelayFrames;
111 if (readPosition >= bufferLength)
112 readPosition -= bufferLength;
114 // Linearly interpolate in-between delay times.
115 int readIndex1 = static_cast<int>(readPosition);
116 int readIndex2 = (readIndex1 + 1) % bufferLength;
117 double interpolationFactor = readPosition - readIndex1;
119 double input = static_cast<float>(*source++);
120 buffer[m_writeIndex] = static_cast<float>(input);
121 m_writeIndex = (m_writeIndex + 1) % bufferLength;
123 double sample1 = buffer[readIndex1];
124 double sample2 = buffer[readIndex2];
126 double output = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2;
128 *destination++ = static_cast<float>(output);
132 void DelayDSPKernel::reset()
138 } // namespace WebCore
140 #endif // ENABLE(WEB_AUDIO)