Forums

removing dc offset from 24-bit sound samples

Started by Arun Chandra 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.

any leads would be appreciated.

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[]. > >
made one mistake. 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