void ParamEq::Process(float *pOutL, float *pOutR, uint32 numFrames) //----------------------------------------------------------------- { if(m_param[kEqGain] == 1.0f || !m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; for(uint32 i = numFrames; i != 0; i--) { for(uint8 channel = 0; channel < 2; channel++) { float x = *(in[channel])++; float y = b0DIVa0 * x + b1DIVa0 * x1[channel] + b2DIVa0 * x2[channel] - a1DIVa0 * y1[channel] - a2DIVa0 * y2[channel]; x2[channel] = x1[channel]; x1[channel] = x; y2[channel] = y1[channel]; y1[channel] = y; *(out[channel])++ = y; } } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); }
void Echo::Process(float *pOutL, float *pOutR, uint32 numFrames) //-------------------------------------------------------------- { if(!m_bufferSize || !m_mixBuffer.Ok()) return; const float wetMix = m_param[kEchoWetDry], dryMix = 1 - wetMix; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; for(uint32 i = numFrames; i != 0; i--) { for(uint8 channel = 0; channel < 2; channel++) { const uint8 readChannel = (m_crossEcho ? (1 - channel) : channel); int readPos = m_writePos - m_delayTime[readChannel]; if(readPos < 0) readPos += m_bufferSize; float chnInput = *(in[channel])++; float chnDelay = m_delayLine[readPos * 2 + readChannel]; // Calculate the delay float chnOutput = chnInput * m_initialFeedback; chnOutput += chnDelay * m_param[kEchoFeedback]; // Prevent denormals if(mpt::abs(chnOutput) < 1e-24f) chnOutput = 0.0f; m_delayLine[m_writePos * 2 + channel] = chnOutput; // Output samples now *(out[channel])++ = (chnInput * dryMix + chnDelay * wetMix); } m_writePos++; if(m_writePos == m_bufferSize) m_writePos = 0; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); }
void WavesReverb::Process(float *pOutL, float *pOutR, uint32 numFrames) //--------------------------------------------------------------------- { if(!m_mixBuffer.Ok()) return; const float *in[2] = { m_mixBuffer.GetInputBuffer(0), m_mixBuffer.GetInputBuffer(1) }; float *out[2] = { m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1) }; uint32 delay0 = (m_delay[0] + m_state.combPos + 4) & 0x3FFF; uint32 delay1 = (m_delay[1] + m_state.combPos + 4) & 0x3FFF; uint32 delay2 = (m_delay[2] + m_state.combPos + 4) & 0x3FFF; uint32 delay3 = (m_delay[3] + m_state.combPos + 4) & 0x3FFF; float delay0old = m_state.comb[delay0 ]; float delay1old = m_state.comb[delay1 + 1]; float delay2old = m_state.comb[delay2 + 2]; float delay3old = m_state.comb[delay3 + 3]; for(uint32 i = numFrames; i != 0; i--) { const float leftIn = *(in[0])++ + 1e-30f; // Prevent denormals const float rightIn = *(in[1])++ + 1e-30f; // Prevent denormals // Advance buffer index for the four comb filters delay0 = (delay0 - 4) & 0x3FFF; delay1 = (delay1 - 4) & 0x3FFF; delay2 = (delay2 - 4) & 0x3FFF; delay3 = (delay3 - 4) & 0x3FFF; float &delay0new = m_state.comb[delay0 ]; float &delay1new = m_state.comb[delay1 + 1]; float &delay2new = m_state.comb[delay2 + 2]; float &delay3new = m_state.comb[delay3 + 3]; uint32 pos; float r1, r2; pos = (m_state.allpassPos + m_delay[4]) & 0x7FF; r1 = delay1new * 0.61803401f + m_state.allpass1[pos] * m_coeffs[0]; r2 = m_state.allpass1[pos + 1] * m_coeffs[0] - delay0new * 0.61803401f; m_state.allpass1[m_state.allpassPos ] = r2 * 0.61803401f + delay0new; m_state.allpass1[m_state.allpassPos + 1] = delay1new - r1 * 0.61803401f; delay0new = r1; delay1new = r2; pos = (m_state.allpassPos + m_delay[5]) & 0x7FF; r1 = delay3new * 0.61803401f + m_state.allpass2[pos] * m_coeffs[1]; r2 = m_state.allpass2[pos + 1] * m_coeffs[1] - delay2new * 0.61803401f; m_state.allpass2[m_state.allpassPos ] = r2 * 0.61803401f + delay2new; m_state.allpass2[m_state.allpassPos + 1] = delay3new - r1 * 0.61803401f; delay2new = r1; delay3new = r2; *(out[0])++ = (leftIn * m_dryFactor) + delay0new + delay2new; *(out[1])++ = (rightIn * m_dryFactor) + delay1new + delay3new; const float leftWet = leftIn * m_wetFactor; const float rightWet = rightIn * m_wetFactor; m_state.comb[m_state.combPos ] = (delay0new * m_coeffs[2]) + (delay0old * m_coeffs[3]) + leftWet; m_state.comb[m_state.combPos + 1] = (delay1new * m_coeffs[4]) + (delay1old * m_coeffs[5]) + rightWet; m_state.comb[m_state.combPos + 2] = (delay2new * m_coeffs[6]) + (delay2old * m_coeffs[7]) - rightWet; m_state.comb[m_state.combPos + 3] = (delay3new * m_coeffs[8]) + (delay3old * m_coeffs[9]) + leftWet; delay0old = delay0new; delay1old = delay1new; delay2old = delay2new; delay3old = delay3new; // Advance buffer index m_state.combPos = (m_state.combPos - 4) & 0x3FFF; m_state.allpassPos = (m_state.allpassPos - 2) & 0x7FF; } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); }
void Gargle::Process(float *pOutL, float *pOutR, uint32 numFrames) //---------------------------------------------------------------- { if(!m_mixBuffer.Ok()) return; const float *inL = m_mixBuffer.GetInputBuffer(0), *inR = m_mixBuffer.GetInputBuffer(1); float *outL = m_mixBuffer.GetOutputBuffer(0), *outR = m_mixBuffer.GetOutputBuffer(1); const bool triangle = m_param[kGargleWaveShape] < 1.0f; for(uint32 frame = numFrames; frame != 0;) { if(m_counter < m_periodHalf) { // First half of gargle period const uint32 remain = std::min(frame, m_periodHalf - m_counter); if(triangle) { const uint32 stop = m_counter + remain; const float factor = 1.0f / m_periodHalf; for(uint32 i = m_counter; i < stop; i++) { *outL++ = *inL++ * i * factor; *outR++ = *inR++ * i * factor; } } else { for(uint32 i = 0; i < remain; i++) { *outL++ = *inL++; *outR++ = *inR++; } } frame -= remain; m_counter += remain; } else { // Second half of gargle period const uint32 remain = std::min(frame, m_period - m_counter); if(triangle) { const uint32 stop = m_period - m_counter - remain; const float factor = 1.0f / m_periodHalf; for(uint32 i = m_period - m_counter; i > stop; i--) { *outL++ = *inL++ * i * factor; *outR++ = *inR++ * i * factor; } } else { for(uint32 i = 0; i < remain; i++) { *outL++ = 0; *outR++ = 0; } inL += remain; inR += remain; } frame -= remain; m_counter += remain; if(m_counter >= m_period) m_counter = 0; } } ProcessMixOps(pOutL, pOutR, m_mixBuffer.GetOutputBuffer(0), m_mixBuffer.GetOutputBuffer(1), numFrames); }