# [music-dsp] Transient elimination in filtering

Dave Gamble signalzerodb at yahoo.co.uk
Mon Apr 28 09:07:01 EDT 2003

```> Hello All,
>
Hey man.

> I understand the generic convolution equation for
> filtering, but I don't
> understand the logistic of parts of the code that
> achieved this transient
> reduction.  I commented the code which I don't
> understand with ??.  Can
> someone please kindly comment on the parts I don't
> understand?
>
Sure.

> The key idea for this code as quoted from the book
> is ".To stop this
> transient, the L/2 [(L-1)/2 for odd L] samples at
> the beginning of the
> convolution are not calculated so that the output
> samples align(??) with the
> input samples.  ." By the way, L = length of the
> filter.  The book said the
> following method generates the same number of output
> samples as input
> samples.  So no startup and tailend transients
> exist.
>
Yeah. This is what we in the trade call a Dumb Idea.
It screws up your phase, and frequency response. Sure,
you won't get any delay i/p to o/p, but it'll sound
terrible. Tried it. It sucks.

>             //?? what does the following line mean??
>
>             //?? I guess I don't understand the role
> of lenCoef2??
>
>             int lenCoef2 = (m_length + 1)/2;
>
Well, lenCoef2 is roughly half the number of
coefficients.

You're really not going to believe this, and you'll
like it even less, but they're actually suggesting
that you just IGNORE half the impulse response!

>             //??I have problem understanding the
> purpose of the following 2
> lines??
>
>             const Type *endIn = vIn.getData(lenIn) +
> lenIn - 1;
>
endIn is a pointer to the end of the input samples.
When the current sample pointer points to endIn, then
you're processing the last sample.

>             const Type *prtIn = vIn.getData(lenIn) +
> lenCoef2 - 1;
>
This gives you a pointer to the input data, and jumps
you a few samples into it.
In other words: skip the first few samples.

>             //Initial value of accumulation length
> for startup
>
>             //??What does the above comment mean??
>
Probably very little.

Oh wait. In the for loop, we iterate for lenAcc
cycles. We can reduce lenAcc to iterate for fewer
cycles (i.e. so that we don't try and process samples
which are -after- our input data... it's a safeguard.)

>                         Type acc = *ptrCoef++ *
> *ptrData--;
>                         for (int j=0; j<lenAcc; j++)

>                                     acc +=
> *ptrCoef++ * *ptrData--;
>
>                         vOut[i] = acc;
>
Standard convolution equation.

>                         //?? I don't understand the
> logic of the following
> if-else statement
>
>                         //Check for end case
>
>                         if(ptrIn == endIn)
>
If we're nearing the end.
>                                     lenAcc--;
>
process one sample less the next time.

>                         else
>
otherwise

>                                     if(lenAcc <
> m_length)
>
if we're not using all the filter's samples,

>                                     {
>
>
>
>
> lenAcc++;
>
>                                     }
>
use one more of the filter's samples

>                                     ptrIn++;
>
This code doesn't do anything very exciting.
It's just a kludge to make the startup and ending of
processing a stationary block of audio sound a little
cleaner.

Yuck.

Dave.

__________________________________________________
Yahoo! Plus
For a better Internet experience
http://www.yahoo.co.uk/btoffer

```