2012-12-14 78 views
5

嘗試使用portaudio錄製一些數據,然後使用算法篩選器更改錄製的語音,然後播放它。我已經驗證了很多(來自示例),但我對C很陌生,我認爲在我的過濾器實現中我做了一些愚蠢的事情。在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) 

我只是真的不知道是怎麼回事。有什麼想法嗎?

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; 
+0

* recordedSamples *的大小是多少? – user1284631

+2

錯誤似乎發生在對'free'的調用中。你能否顯示那些叫'免費'的代碼? – simonc

+0

錄製的樣品約200k –

回答

1

的問題是,現在data.recordedSamples(在free()的時間)對在棧中分配,而不是堆的結構分: 免費從腳本的最後終止於這裏叫!

既然你有這樣的指令:

data.recordedSamples = filteredArray; 

if(data.recordedSamples) 

是沒有用的,因爲ADRESS ID有效,但不是一致的:它從不與malloc()分配,這是不在堆上,但在堆棧上!

當你打電話給free()的時候,那個地址可能會指向另一個函數的堆棧。

如果需要,將過濾的數據複製回原始的recordedSamples,只是不要重新分配該指針。

編輯:

使用本:

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

謝謝您的回答,並且對不起,如果我很密集,但我該怎麼做? –

+0

@SlaterTyranus:要替換數據,使用for()循環並通過float複製float;或使用memcpy()(您需要包含);對於(i = 0; i user1284631

+0

@SlaterTyranus:看到我更新的答案 – user1284631

0

它看起來像你試圖釋放堆棧變量。唯一需要撥打free的時間是先前撥打malloc(或其中一位朋友,如calloc),或者當您要調用的庫函數的文檔說您需要釋放它返回的指針時。順便說一句,任何時候你釋放一個指針,一個好的做法是在之後立即將它設置爲NULL。

堆棧變量一旦超出範圍就會消失。 This可能會幫助您更好地理解。