void DelayDSPKernel::process(const float* source, float* destination, size_t framesToProcess) { size_t bufferLength = m_buffer.size(); float* buffer = m_buffer.data(); ASSERT(bufferLength); if (!bufferLength) return; ASSERT(source && destination); if (!source || !destination) return; double sampleRate = this->sampleRate(); double delayTime = delayProcessor() ? delayProcessor()->delayTime()->value() : m_desiredDelayFrames / sampleRate; // Make sure the delay time is in a valid range. delayTime = min(maxDelayTime(), delayTime); delayTime = max(0.0, delayTime); if (m_firstTime) { m_currentDelayTime = delayTime; m_firstTime = false; } int n = framesToProcess; while (n--) { // Approach desired delay time. m_currentDelayTime += (delayTime - m_currentDelayTime) * m_smoothingRate; double desiredDelayFrames = m_currentDelayTime * sampleRate; double readPosition = m_writeIndex + bufferLength - desiredDelayFrames; if (readPosition > bufferLength) readPosition -= bufferLength; // Linearly interpolate in-between delay times. int readIndex1 = static_cast<int>(readPosition); int readIndex2 = (readIndex1 + 1) % bufferLength; double interpolationFactor = readPosition - readIndex1; double input = static_cast<float>(*source++); buffer[m_writeIndex] = static_cast<float>(input); m_writeIndex = (m_writeIndex + 1) % bufferLength; double sample1 = buffer[readIndex1]; double sample2 = buffer[readIndex2]; double output = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2; *destination++ = static_cast<float>(output); } }
void DelayDSPKernel::process(const float* source, float* destination, size_t framesToProcess) { size_t bufferLength = m_buffer.size(); float* buffer = m_buffer.data(); ASSERT(bufferLength); if (!bufferLength) return; ASSERT(source && destination); if (!source || !destination) return; float sampleRate = this->sampleRate(); double delayTime = 0; float* delayTimes = m_delayTimes.data(); double maxTime = maxDelayTime(); bool sampleAccurate = delayProcessor() && delayProcessor()->delayTime()->hasSampleAccurateValues(); if (sampleAccurate) delayProcessor()->delayTime()->calculateSampleAccurateValues(delayTimes, framesToProcess); else { delayTime = delayProcessor() ? delayProcessor()->delayTime()->finalValue() : m_desiredDelayFrames / sampleRate; // Make sure the delay time is in a valid range. delayTime = min(maxTime, delayTime); delayTime = max(0.0, delayTime); if (m_firstTime) { m_currentDelayTime = delayTime; m_firstTime = false; } } for (unsigned i = 0; i < framesToProcess; ++i) { if (sampleAccurate) { delayTime = delayTimes[i]; delayTime = std::min(maxTime, delayTime); delayTime = std::max(0.0, delayTime); m_currentDelayTime = delayTime; } else { // Approach desired delay time. m_currentDelayTime += (delayTime - m_currentDelayTime) * m_smoothingRate; } double desiredDelayFrames = m_currentDelayTime * sampleRate; double readPosition = m_writeIndex + bufferLength - desiredDelayFrames; if (readPosition >= bufferLength) readPosition -= bufferLength; // Linearly interpolate in-between delay times. int readIndex1 = static_cast<int>(readPosition); int readIndex2 = (readIndex1 + 1) % bufferLength; double interpolationFactor = readPosition - readIndex1; double input = static_cast<float>(*source++); buffer[m_writeIndex] = static_cast<float>(input); m_writeIndex = (m_writeIndex + 1) % bufferLength; double sample1 = buffer[readIndex1]; double sample2 = buffer[readIndex2]; double output = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2; *destination++ = static_cast<float>(output); } }