audiosignal-processingsdlconvolutionaudioeffect

Audio Convolution output is longer than input, how can i get around this when feeding data back to a stream of fixed length?


After taking audio data from a stream of length x, the data is then convolved with an impulse response of length 256. This gives the output vector a length of (x + 256 - 1). When the data is then fed back into a stream of length x there are 255 samples of overshoot that then causes popping and clicking.

Is there a work around for this? Im not 100% on how to merge the larger than original buffer into the output again without losing random samples or causing this issue.

I left out the larger irrelevent parts of the code, it all works its just this issue i need fixed. Its just here to give an insight into the problem.

Code:

    void ConvolveEffect(int chan, void* stream, int len, void* udata)
{
////...A bunch of settings etc

    //Pointer to stream
    short* p = (short*)stream;                       //Using short to rep 16 bit ints as the stream is in 16bits.
    int length = len / sizeof(short);

    //Processing buffer (float)
    float* audioData[2];
    audioData[0] = new float[length / 2];
    audioData[1] = new float[length / 2];

    //Demux to L and R
    for (int i = 0; i < length; i++)
    {           
        bool even = i % 2 == 0 ? true : false;
        audioData[!even][((i - !even) / 2)] = map(p[i], -32767, 32767, -1.0, 1.0);
    }
   
  ////....Convolution occurs outputting OUT
        std::vector<fftconvolver::Sample> outL = Convolve(audioData[0], IRL, length / 2, 256, 128, 256, 256);


    std::vector<fftconvolver::Sample> outR = Convolve(audioData[1], IRR, length / 2, 256, 128, 256, 256);


  //Remux
    for (int i = 0; i < length; i++)
    {
        bool even = i % 2 == 0 ? true : false;
        p[i] = map(Out[!even][(i - !even) / 2], -1.0, 1.0, -32768, 32767);
    }

Solution

  • You remember the 255 extra samples and add their values to the 255 samples at the beginning of the next output block.

    For example:

    [1, 2, 1, 3]  produces [2, 3, 4, 3, 2, 1]  you output [2, 3, 4, 3], remember [2,1]
    

    Next block:

     [3, 2, 1, 3] produces [4, 3, 4, 5, 5, 2]
    
     you output:
    
         [4, 3, 4 ,5]
       + [2, 1]
      -----------------
         [6, 4, 4, 5]
    
     remember [5,2]
    

    This is referred to as the "overlap-add" method of convolution. It's usually used with FFT convolution in blocks.

    The Wikipedia page is here, but it's not awesome: https://en.wikipedia.org/wiki/Overlap%E2%80%93add_method