removing dc offset from 24-bit sound samples

Started by April 11, 2015
```hi folks,

is there freely available C code to remove DC offset from 24-bit sound samples?

I have tried modifying code that was released by robert bristow-johnson for use with 16-bit sounds, but I'm unable to modify it correctly for use with 24-bit sounds.

Arun Chandra
COM 301
Performing Arts
The Evergreen State College
Olympia WA 98505

```
```On 11.04.15 05.14, Arun Chandra wrote:
> is there freely available C code to remove DC offset from 24-bit sound samples?

First of all you need to decide which kind of filter you want to apply.
It is impossible to remove /only/ DC on the fly because you would need
to know all samples in the future. So DC removal is in practical nothing
but a high pass filter. Once you have chosen a filter type you can look
for an implementation.

Option 1: Moving average filter with spectral inversion.
To achieve this you need to subtract from each sample the mean of the
neighbor +/-N samples. N defines the cut of frequency, approximately the
sampling frequency divided by 2N. E.g. N=+/-9600 for 96kHz sampling rate
will filter roughly at 5 Hz.
The selectivity of this filter is quite poor (rectangular window) but DC
is completely removed and it is linear phase.
Although this is an FIR filter with rather large N the needed
computation power is low, because if you know the sum of the samples
sum[i] = x[i-N:i+N] you simply have to subtract the first sample and add
a new one to get the sum for i+1, i.e. sum[i+1] = sum[i] - x[i-N] +
x[i+1+N]. So your output is y[i] = x[i] - sum[i]/N.

Option 2: IIR filter.
A IIR lowpass will also remove DC almost completely. It has a better
frequency selectivity than the moving average above but it is not linear
phase.
You have to choose an appropriate filter order and characteristic. For
this purpose filters with an aperiodic step response are preferred, i.e.
Butterworth. And a filter order of 2 is usually sufficient. So calculate
the IIR coefficients for e.g f0=5Hz and Q=0.7. There are enough sources
in the net how to do so.
The computation power is comparable to the moving average. But you have
to be careful with if your computations are done with 24 bit fixed point
arithmetic. Low frequency IIR filters tend to get unstable because of
round off noise. You should use more than 24 bit for the IIR
accumulators, e.g 32 bit or simpler double precision floats. But your
DSP will usually limit the latter.

Option 3: custom FIR filter.
Well, this one is usually overkill for DC removal unless frequency
selectivity and linear phase are both important. However you can achieve
almost any response this way.
The price is the needed computing power. But using the fast FFT
convolution it is usually no problem to process this in real time.

Marcel
```
```On 4/10/15 11:14 PM, Arun Chandra wrote:
> hi folks,
>
> is there freely available C code to remove DC offset from 24-bit sound samples?
>
> I have tried modifying code that was released by robert bristow-johnson for use with 16-bit sounds, but I'm unable to modify it correctly for use with 24-bit sounds.
>

might have to make your words bigger.

so i copied this from the dspguru tricks page.  now 15 bit shifts become
23 bit shifts.  make sure your 24-bit samples are **right** justified
and sign-extended in the 32-bit words of x[] and y[].

// let's say sizeof(long) = 4 (32 bits)
//  and sizeof(long long) = 8 (64 bits)

long x[], y[];
long long acc, A, prev_x, prev_y;
double pole;
unsigned long n, num_samples;

pole = 0.9999;
A = (long long)(8388608.0*(1.0 - pole));
acc = 0LL;
prev_x = 0LL;
prev_y = 0LL;
for (n=0; n<num_samples; n++)
{
acc   -= prev_x;
prev_x = (long)x[n]<<23;
acc   += prev_x;
acc   -= A*prev_y;
prev_y = acc>>23;               // quantization happens here
y[n]   = (short)prev_y;
// acc has y[n] in upper 41 bits and -e[n] in lower 23 bits
}

haven't tried that, but it should work.

--

r b-j                  rbj@audioimagination.com

"Imagination is more important than knowledge."

```
```On 4/11/15 4:00 AM, Marcel Mueller wrote:
> On 11.04.15 05.14, Arun Chandra wrote:
>> is there freely available C code to remove DC offset from 24-bit sound
>> samples?
>
> First of all you need to decide which kind of filter you want to apply.
> It is impossible to remove /only/ DC on the fly because you would need
> to know all samples in the future.

so how much DC is left if there is a zero squarely on z=1?

> So DC removal is in practical nothing
> but a high pass filter. Once you have chosen a filter type you can look
> for an implementation.
>
...
>
> Option 2: IIR filter.
> A IIR lowpass will also remove DC almost completely. It has a better
> frequency selectivity than the moving average above but it is not linear
> phase.
> You have to choose an appropriate filter order and characteristic. For
> this purpose filters with an aperiodic step response are preferred, i.e.
> Butterworth. And a filter order of 2 is usually sufficient. So calculate
> the IIR coefficients for e.g f0=5Hz and Q=0.7. There are enough sources
> in the net how to do so.
> The computation power is comparable to the moving average.

for comparable performance, you need to use noise shaping for the moving
average, also.

> But you have
> to be careful with if your computations are done with 24 bit fixed point
> arithmetic. Low frequency IIR filters tend to get unstable because of
> round off noise. You should use more than 24 bit for the IIR
> accumulators, e.g 32 bit or simpler double precision floats. But your
> DSP will usually limit the latter.
>

if the OP cannot do (long long), then i am not sure how to handle it.

a filter order of 1 will suffice.  but the pole has to be very close to
the zero which is at precisely z=1.  i wouldn't expect the filter to
blow up (like unstable), but there is a nasty limit-cycle problem which
is what that fixed-point DC block noise shaping trick is s'posed to deal
with (and the noise shaping also puts a zero at z=1 which kills any DC
error, including the limit cycle).

--

r b-j                  rbj@audioimagination.com

"Imagination is more important than knowledge."

```
```On 4/11/15 11:00 AM, robert bristow-johnson wrote:
> On 4/10/15 11:14 PM, Arun Chandra wrote:
>> hi folks,
>>
>> is there freely available C code to remove DC offset from 24-bit sound
>> samples?
>>
>> I have tried modifying code that was released by robert
>> bristow-johnson for use with 16-bit sounds, but I'm unable to modify
>> it correctly for use with 24-bit sounds.
>>
>
> might have to make your words bigger.
>
> so i copied this from the dspguru tricks page. now 15 bit shifts become
> 23 bit shifts. make sure your 24-bit samples are **right** justified and
> sign-extended in the 32-bit words of x[] and y[].
>
>

long x[], y[];
long long acc, A, prev_x, prev_y;
double pole;
unsigned long n, num_samples;

pole = 0.9999;
A = (long long)(8388608.0*(1.0 - pole));
acc = 0LL;
prev_x = 0LL;
prev_y = 0LL;
for (n=0; n<num_samples; n++)
{
acc   -= prev_x;
prev_x = ((long long)x[n])<<23;
acc   += prev_x;
acc   -= A*prev_y;
prev_y = acc>>23;               // quantization happens here
y[n]   = (short)prev_y;
// acc has y[n] in upper 41 bits and -e[n] in lower 23 bits
}

>
>
>
> haven't tried that, but it should work.
>
>

--

r b-j                  rbj@audioimagination.com

"Imagination is more important than knowledge."

```
```dammit!!  made another dumb missed-casting mistake.  (there should not
be the word "short" in this code.)

long x[], y[];     // 24-bit samples in right 24 bits and sign extended
long long acc, A, prev_x, prev_y;
double pole;
unsigned long n, num_samples;

pole = 0.9999;
A = (long long)(8388608.0*(1.0 - pole));
acc = 0LL;
prev_x = 0LL;
prev_y = 0LL;
for (n=0; n<num_samples; n++)
{
acc   -= prev_x;
prev_x = ((long long)x[n])<<23;
acc   += prev_x;
acc   -= A*prev_y;
prev_y = acc>>23;               // quantization happens here
y[n]   = (long)prev_y;
// acc has y[n] in upper 41 bits and -e[n] in lower 23 bits
}

--

r b-j                  rbj@audioimagination.com

"Imagination is more important than knowledge."

```
```robert bristow-johnson <rbj@audioimagination.com> writes:

> On 4/11/15 4:00 AM, Marcel Mueller wrote:
>> On 11.04.15 05.14, Arun Chandra wrote:
>>> is there freely available C code to remove DC offset from 24-bit sound
>>> samples?
>>
>> First of all you need to decide which kind of filter you want to apply.
>> It is impossible to remove /only/ DC on the fly because you would need
>> to know all samples in the future.
>
> so how much DC is left if there is a zero squarely on z=1?

He didn't say that you could not completely remove DC, but that you
cannot completely remove ONLY DC. Yeah, there are no infinitely-narrow
notch filters.
--
Randy Yates
Digital Signal Labs
http://www.digitalsignallabs.com
```
```On 4/11/15 11:55 AM, Randy Yates wrote:
> robert bristow-johnson<rbj@audioimagination.com>  writes:
>
>> On 4/11/15 4:00 AM, Marcel Mueller wrote:
>>> On 11.04.15 05.14, Arun Chandra wrote:
>>>> is there freely available C code to remove DC offset from 24-bit sound
>>>> samples?
>>>
>>> First of all you need to decide which kind of filter you want to apply.
>>> It is impossible to remove /only/ DC on the fly because you would need
>>> to know all samples in the future.
>>
>> so how much DC is left if there is a zero squarely on z=1?
>
> He didn't say that you could not completely remove DC, but that you
> cannot completely remove ONLY DC. Yeah, there are no infinitely-narrow
> notch filters.

yeah, you're right.  i misread it.

--

r b-j                  rbj@audioimagination.com

"Imagination is more important than knowledge."

```
```On Sat, 11 Apr 2015 11:00:49 -0400, robert bristow-johnson wrote:

> On 4/10/15 11:14 PM, Arun Chandra wrote:
>> hi folks,
>>
>> is there freely available C code to remove DC offset from 24-bit sound
>> samples?
>>
>> I have tried modifying code that was released by robert bristow-johnson
>> for use with 16-bit sounds, but I'm unable to modify it correctly for
>> use with 24-bit sounds.
>>
>>
> might have to make your words bigger.
>
I fail to see the practical application of a superfluous syllabic excess
to one's lexicographical utterances.

Oh wait -- you were saying he should make his COMPUTER words bigger.

Never mind.

--
www.wescottdesign.com
```
```DC is a vital part of music and should not be removed. Just try listening to AC/DC without the DC. Only half as good.

Bob
```