Resetting a buffer in filter implementation

Im a beginner and ive been checking out the filter implementation of the wolfsound tutorial about highpass and lowpass filters. So i had a question about the code in this tutorial. This processBlock is to be called every block in the processBlock of the audioprocessor class.
But ive noticed that a buffer gets resized every block and filled with zeros. Ive been trying to understand why. Because dont you need to last sample of the previous block to calculate the first sample of the current block? Or is it supposed to be calculated with a zero? It seems logical to me that you shouldnt zero the buffer every block, but since im a beginner i’d need some confirmation.

// LowpassHighpassFilter.cpp continued
//...
void LowpassHighpassFilter::processBlock(juce::AudioBuffer<float>& buffer,
                                         juce::MidiBuffer&) {
  // pi value copied from the web
  constexpr auto PI = 3.14159265359f;

  // resize the allpass buffers to the number of channels and
  // zero the new ones
  
  ////////////////////////////////HERE//////////////////////////////////
  dnBuffer.resize(buffer.getNumChannels(), 0.f);
  ////////////////////////////////HERE//////////////////////////////////

  // if we perform highpass filtering, we need to 
  // invert the output of the allpass (multiply it
  // by -1)
  const auto sign = highpass ? -1.f : 1.f;

  // helper variable
  const auto tan = std::tan(PI * cutoffFrequency / samplingRate);
  // allpass coefficient is constant while processing 
  // a block of samples
  const auto a1 = (tan - 1.f) / (tan + 1.f);

  // actual processing; each channel separately
  for (auto channel = 0; channel < buffer.getNumChannels(); ++channel) {
    // to access the sample in the channel as a C-style array
    auto channelSamples = buffer.getWritePointer(channel);

    // for each sample in the channel
    for (auto i = 0; i < buffer.getNumSamples(); ++i) {
      const auto inputSample = channelSamples[i];

      // allpass filtering
      const auto allpassFilteredSample = a1 * inputSample + 
                                            dnBuffer[channel];
      dnBuffer[channel] = inputSample - a1 * allpassFilteredSample;

      // here the final filtering occurs
      // we scale by 0.5 to stay in the [-1, 1] range
      const auto filterOutput =
          0.5f * (inputSample + sign * allpassFilteredSample);

      // assign to the output
      channelSamples[i] = filterOutput;
    }
  }
}

resize calls on vector only do something if the size actually changed, so it most likely never does anything, unless the channel layout of the track suddenly changes, in which case it might reallocate. I personally would refrain from doing this if possible. For example you could just make your channel layout only allow for mono or stereo and simply use an std::array of 2 values for this thing. if you only need 1 of them in some instances, who cares, right?

2 Likes