Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing simple high and low pass filters in C

Trying to use portaudio to record some data, then use an algorithmic filter to change the recorded voice and then play it back. I've verified a lot of it (coming from example) but I'm quite new to C and I think in my filter implementation I've done something silly.

#if LOW_PASS 
{
    float RC = 1.0/(CUTOFF*2*3.14);
    float dt = 1.0/SAMPLE_RATE;
    float alpha = dt/(RC+dt);
    float filteredArray[numSamples];
    filteredArray[0] = data.recordedSamples[0];
    for(i=1; i<numSamples; i++){
        filteredArray[i] = filteredArray[i-1] + (alpha*(data.recordedSamples[i] - filteredArray[i-1]));
    }
    data.recordedSamples = filteredArray;
}
#endif
#if HIGH_PASS
{
    float RC = 1.0/(CUTOFF*2*3.14);
    float dt = 1.0/SAMPLE_RATE;
    float alpha = RC/(RC + dt);
    float filteredArray[numSamples];
    filteredArray[0] = data.recordedSamples[0];
    for (i = 1; i<numSamples; i++){
        filteredArray[i] = alpha * (filteredArray[i-1] + data.recordedSamples[i] - data.recordedSamples[i-1]);
    }
    data.recordedSamples = filteredArray;
}
#endif

When the recorded signal tries to go through these filters I get something the following error:

*** glibc detected *** ./paex_record: free(): invalid pointer: 0xbfd68600 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb75e2ee2]
./paex_record[0x8048fe5]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75864d3]
./paex_record[0x80487f1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:05 2363767    /home/svictoroff/Documents/CompArch/portaudio/examples/paex_record
...
bfd68000-bff1a000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

I'm just really not sure what's going on here. Any thoughts? Free is called from the end of the script at terminate here:

Pa_Terminate();
    if( data.recordedSamples )       /* Sure it is NULL or valid. */
        free( data.recordedSamples );
    if( err != paNoError )
    {
        fprintf( stderr, "An error occured while using the portaudio stream\n" );
        fprintf( stderr, "Error number: %d\n", err );
        fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
        err = 1;          /* Always return 0 or 1, but no other return codes. */
    }
    return err;
like image 365
Slater Victoroff Avatar asked Dec 14 '12 15:12

Slater Victoroff


People also ask

What is low-pass filter in DSP?

A lowpass filter is one which suppresses or attenuates the high frequency components of a spectrum while 'passing' the low frequencies within a specified range.

What is first-order high-pass filter?

A first-order (single-pole) Active High Pass Filter as its name implies, attenuates low frequencies and passes high frequency signals. It consists simply of a passive filter section followed by a non-inverting operational amplifier.


2 Answers

The problem is that data.recordedSamples now (at the time of free()) points towards a structure allocated on the stack, not on the heap!

Since you had this instruction:

data.recordedSamples = filteredArray;

The

if( data.recordedSamples )

is of no use, since the adress id valid, but not consistent: it is never allocated with malloc() and it is not on the heap, but on the stack!

At the moment when you are calling free(), that adress could well point towards the stack of another function.

Copy your filtered data back over the original recordedSamples if you want, just do not re-assign that pointer.

edit:

use this:

for(i = 0; i<numSamples; i++) {
    data.recordedSamples[i] = filteredArray[i];
}
like image 105
user1284631 Avatar answered Oct 01 '22 05:10

user1284631


It looks like you're trying to free a stack variable. The only time you have to call free is when you've previously called malloc (or one of its friends like calloc) or when the documentation for a library function you're calling says you need to free a pointer that it returns.

Incidentally, any time you do free a pointer, a good practice is to set it to NULL immediately afterwards.

Stack variables go away as soon as they're out of scope. This might help you understand better.

like image 45
nmichaels Avatar answered Oct 01 '22 07:10

nmichaels