Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone aurioTouch example: Remove DC

Tags:

iphone

audio

I am looking at the iPhone aurioTouch example specifically on the following code:

static OSStatus PerformThru(
                        void                        *inRefCon, 
                        AudioUnitRenderActionFlags  *ioActionFlags, 
                        const AudioTimeStamp        *inTimeStamp, 
                        UInt32                      inBusNumber, 
                        UInt32                      inNumberFrames, 
                        AudioBufferList             *ioData)
{
    aurioTouchAppDelegate *THIS = (aurioTouchAppDelegate *)inRefCon;
    OSStatus err = AudioUnitRender(THIS->rioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData);
    if (err) { printf("PerformThru: error %d\n", (int)err); return err; }

    // Remove DC component
    for(UInt32 i = 0; i < ioData->mNumberBuffers; ++i)
        THIS->dcFilter[i].InplaceFilter((SInt32*)(ioData->mBuffers[i].mData), inNumberFrames, 1);

    // ...

}

in the file aurioTouchAppDelegate.mm.

Beginner question: What does the "Remove DC component" do? Any pointer to tutorial article about it is appreciated.

Thanks in advance for your help.

like image 802
pion Avatar asked Jun 18 '10 14:06

pion


2 Answers

Here is the code for the InplaceFilter method:

void DCRejectionFilter::InplaceFilter(SInt32* ioData, UInt32 numFrames, UInt32 strides) 
{ 
    register SInt32 y1 = mY1, x1 = mX1; 
    for (UInt32 i=0; i < numFrames; i++) 
    { 
        register SInt32 x0, y0; 
        x0 = ioData[i*strides]; 
        y0 = smul32by16(y1, mA1); 
        y1 = smulAdd32by16(x0 - x1, mGain, y0) << 1; 
        ioData[i*strides] = y1; 
        x1 = x0; 
    } 
    mY1 = y1; 
    mX1 = x1; 
} 

Basically, the code is doing a high-pass filter on the audio to remove the DC component of the frequency spectrum which is also referred to as the DC offset. The coefficient (alpha in the wikipedia article) for the filter is set by default in the code to be 0.975 and typical values for DC removal filters are between 0.9 and 1.0. If you adjust the sampling rate then you might want to adjust that coefficient, but I wouldn't worry too much about it.

like image 139
Justin Peel Avatar answered Oct 20 '22 18:10

Justin Peel


The DC Rejection Filter here is actually a high pass filter. In electrical engineering, a high pass filter is implemented as a RC circuit, which allows only high frequency waves to pass through. Every high pass filter has a cut off frequency, defined as the frequency at which point the output energy is -3db of the input energy.

The InPlaceFilter method is a time domain digital implementation of a high pass filter. The digital implementation loops all the samples in order, and adjust the current output based on the previous output. In this implementation, a constant variable alpha whose value is between 0 and 1 is used. The cut off frequency of your high pass filter is dependent on the value you pick for Alpha (and also your sampling rate). Since in AurioTouch the sampling frequency is 44k. The cut off frequency can be calculated to be around 160Hz. (note that this does not mean you don't get any frequency reading below 160hz. It just means that the energy out put of frequencies below that frequency is significantly lower than those above it).

I have written a detailed explanation here http://timdotshi.blogspot.ca/2014/01/dc-rejection-filter-in-objective-c.html.

like image 33
Tim Shi Avatar answered Oct 20 '22 17:10

Tim Shi