【问题标题】:Implementing simple high and low pass filters in C在 C 中实现简单的高通和低通滤波器
【发布时间】:2012-12-02 15:40:02
【问题描述】:

尝试使用 portaudio 录制一些数据,然后使用算法过滤器更改录制的语音,然后播放。我已经验证了很多(来自示例),但我对 C 很陌生,我认为在我的过滤器实现中我做了一些愚蠢的事情。

#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

当记录的信号试图通过这些过滤器时,我得到以下错误:

*** 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)

我真的不确定这里发生了什么。有什么想法吗? Free 是从脚本末尾处调用的,在这里终止:

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;

【问题讨论】:

  • recordedSamples 的大小是多少?
  • 错误似乎发生在对 free 的调用中。能否请您也显示调用free 的代码?
  • RecordedSamples 大约是 200k
  • 啊,找到免费的,现在发布。
  • 你能显示错误发生的代码行吗?您可以使用调试器或通过代码添加printf 语句来确定这一点

标签: c filter signal-processing portaudio


【解决方案1】:

问题在于 data.recordedSamples 现在(在free() 时)指向分配在堆栈上而不是堆上的结构!

既然你有这个指令:

data.recordedSamples = filteredArray;

if( data.recordedSamples )

没有用,因为地址 id 有效,但不一致:它永远不会用malloc() 分配,它不在堆上,而是在堆栈上!

当您调用free() 时,该地址很可能指向另一个函数的堆栈。

如果需要,将过滤后的数据复制回原来的 recordedSamples,只是不要重新分配该指针。

编辑:

使用这个:

for(i = 0; i<numSamples; i++) {
    data.recordedSamples[i] = filteredArray[i];
}

【讨论】:

  • 谢谢你的回答,如果我太密集了,很抱歉,但我该怎么做呢?
  • @SlaterTyranus:要替换数据,请使用 for() 循环并通过浮点数复制浮点数;或使用 memcpy() (您需要包含 ); for(i = 0; i
  • 啊,太棒了。非常感谢!
【解决方案2】:

看起来您正在尝试释放堆栈变量。唯一需要调用 free 的情况是,您之前曾调用过 malloc(或它的朋友之一,例如 calloc),或者当您调用的库函数的文档显示您需要释放指针时它返回。

顺便说一句,任何时候你释放一个指针,一个好的做法是在之后立即将它设置为 NULL。

堆栈变量一旦超出范围就会消失。 This 可能会帮助您更好地理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-29
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多