DSPRelated.com
Forums

Using the convolution of two rectangular signals to test a block convolver.

Started by Les Cargill March 19, 2017
> > Exactly- the block convolution seems to just provide the ... > illusion of not being circular, or of a "circle" with a... > different ( smaller? larger? ) "radius". Interesting. >
Yes, FFT->multiply->IFFT is equivalent to a circular convolution, not a linear one. This is why you have to pad out with zeros in the overlap-add method -- it makes sure the result of the single-block convolution is short enough to fit in the buffer without looping around the end.
> > For a 64 sample FFT, with 18 signal-samples per processing iteration, > 46 zeros behaves badly, 45 produces the expected result. >
I don't understand what you mean here. If you're using a 64 sample FFT, you need to provide an array of 64 numbers as input. If 18 of them are signal samples, aren't there then going to be exactly 46 zeros? How could you have a different number of zeros? -Ethan
ethan@polyspectral.com wrote:
>> >> Exactly- the block convolution seems to just provide the ... >> illusion of not being circular, or of a "circle" with a... >> different ( smaller? larger? ) "radius". Interesting. >> > > Yes, FFT->multiply->IFFT is equivalent to a circular convolution, not a linear one.
Right! We knew that; I knew that. What was not clear was the relationship ( which holds ) between block and a "you have all of both sample-sets in memory and convolve them" case.
> This is why you have to pad out with zeros in the overlap-add method > -- it makes sure the result of the single-block convolution is short > enough to fit in the buffer without looping around the end. >
You only have to pad out FFTSIZE-SIGNAL_QUANTUM[1] samples, at the end, for a block convolution, and only for the case where you're convolving a fixed quantity of samples. I hope that last thing becomes clearer down the page. [1] say SIGNAL_QUANTUM=89 ( for 2msec @ 44100 ksamples/sec ) and FFTSIZE = 1024 - leaving 935 or 936.
>> >> For a 64 sample FFT, with 18 signal-samples per processing iteration, >> 46 zeros behaves badly, 45 produces the expected result. >> > > I don't understand what you mean here. If you're using a 64 sample
> FFT, you need to provide an array of 64 numbers as input. If 18 of > them are signal samples, aren't there then going to be exactly 46 > zeros? How could you have a different number of zeros?
>
Neat question! This is for a VST plugin that uses block convolution of a continuous stream of input. But part of it is a generic block convolver, implemented as a C++ class with a minimal API. I needed to test the convolver seperate from the VST plugin stuff. It's difficult to create a test case using a DAW because samples written to a .wav file are constrained to the range -1...1. I actually did this with samples where 1 => 0.01 or 0.001 , and got the correct output. Still, I wanted the classic test. So the test case was to convolve a fixed buffer of all-ones ( a rectangular pulse ) with another fixed block of the same number of all ones - because that was easy to test for. You expect a triangular pulse as output. A small state machines checks for a triangular pulse well. So I chose: - A variable number of samples in the rectangular pulse. The C program used accepted as a command line argument the number of samples. - An FFT size of 64. - An "input quantum" - how many new, signal-to-be-convolved samples per iteration through the block convolver. - A buffer size, >= the number of samples in the rectangular pulse. This means I could drive the program with a script. It would basically print "BAD" or "GOOD". The script could salami-slice the parameters until we found the edge case between good and bad. What I found was - regardless of all the other parameters, if I added the right number of zeros[1], it did not go circular. If I didn't, it did. [1] to both the signal *and the impulse*, because they are constrained as being the same for this test. For a 64 sized FFT with 19 input samples per block, the dividing line was between 46 and 45. 45 zeros bad, 46 good. The conclusion is that for block convolutions, you must add enough zeros ( to the impulse ) or it'll become a circular convolution. Which makes perfect sense. I am sure I messed this up, and please, ask again if you have questions.
> -Ethan >
-- Les Cargill