2010-12-08 38 views
4

我正在嘗試從一個採樣率向更高採樣率重新採樣信號(聲音採樣)。 不幸的是,它需要某種過濾器,因爲似乎出現了一些「別名」,並且我對過濾器不熟悉。這是我想出的:重新採樣一個聲音樣本,我使用哪個過濾器?

int i, j, a, b, z; 

a = 44100; 
b = 8363; 

// upsample by a 
for(i = z = 0; i < samplen; i++) 
    for(j = 0; j < a; j++) 
     cbuf[z++] = sampdata[i]; 

// some filter goes here??? 

// downsample by b 
for(j = i = 0; i < z; i += b) 
    buf[j++] = cbuf[i]; 

新的樣品是非常類似於原來的,但它有一些種類的噪音。 您能否告訴我我需要添加哪些過濾器,並且最好是與該過濾器相關的一些代碼?

原來的聲音:http://www.mediafire.com/?9gnga1in52d6t4x 重採樣聲音:http://www.mediafire.com/?x34h7ggk8n9k8z1

+0

從簡單的線性插值開始:不是將`cbuf [z]`設置爲`sampdata [i]`,而是將其設置爲`sampdata [i] +(j /(double)a) (sampdata [i + 1] - sampdata [i])`。我對聲音處理知之甚少,不知道它是否足夠接近,但它會讓你一直忙碌,直到有人來了解誰是他們的東西:-)你也可能需要反鋸齒縮樣。 – 2010-12-09 00:06:00

回答

10

除非採樣率(源和目標)都遠高於數據中的最高頻率,否則不要使用線性插值。這是一個非常差的低通濾波器。

你想要的是一個插值低通濾波器,其阻帶低於你處理的兩個採樣率中較低的一半。實現這一點的常用方法是使用IIR濾波器的上採樣/下采樣以及使用多相FIR濾波器。如果您不需要實時性能,並且不想上採樣/下采樣,則窗口化的Sinc插值器也適用於此。這裏有一個Windowed Sinc interpolating low-pass filter in Basic,這應該是微不足道的轉換成C.

如果你想使用IIR過濾,這裏是規範Cookbook for biquad IIR filters

如果你想要音頻重採樣理論的最佳解釋,這裏是Stanford CCRMA's Resampling page

+0

謝謝。我對濾波器一無所知,但我確實需要運行時性能,因爲我正在製作一種音樂播放器。老實說,我認爲從一個採樣率轉換到另一個採樣率會很複雜。 – 2010-12-09 20:34:32

9

你有沒有考慮使用專門的庫本,如libsamplerate

它非常便攜,它是由知道如何正確做這些事情的人開發的。即使你不直接使用它,你也可能會發現它實現的算法很有趣。

+3

如果獨立程序足夠,SoX(http://sox.sourceforge.net/)是另一種選擇。它有內置的採樣率轉換。很容易作爲`sox file1 -r [newsamplerate] file2` – mtrw 2010-12-09 08:02:43

2

幾點意見,雖然我只是猜測你的真實意圖:

  • 您是上採樣的速度44100次原來的採樣率。例如,如果您的輸入是10kHz,那麼您的中級cbuf[]將在441MHz,這對於大多數音頻分析來說是一個高點。假設你想要cbuf[]爲44100Hz,那麼你只需要在sampdata[]中創建44100/OrigSampleRate樣本cbuf[] /樣本。
  • 在上採樣循環中,您正在遞增z兩次。這導致cbuf[]的所有奇數元素都具有其原始值。我相信這最終導致最後的buf[]具有無效的奇怪元素,這可能是你的噪音的來源。如果您沒有使用至少兩次所需數量的元素創建它,那麼在cbuf中也會有潛在的緩衝區溢出。
  • 正如史蒂夫所提到的,線性插值通常是最簡單的,它可以在上採樣時創建一個很好的結果。如果需要,可以完成更復雜的上採樣(多項式,樣條等)。同樣,當下採樣時,您可能希望平均採樣而不是截斷。
+0

哦,我沒有注意到我正在增加z ++兩次。謝謝你指出。 – 2010-12-09 00:21:26

1

最佳採樣代碼,我曾經遇到過:http://shibatch.sourceforge.net/

爲源,並嘗試從中學到一些東西。它處於惡劣的狀態,但是重新採樣器的結果遠遠高於其他所有情況。

0

在重採樣到較低的採樣率之前,您必須低通濾波原始小於採樣率的1/2倍,否則您將引入alizing僞像。當頻率超過1/2採樣率時,頻譜將自行折回。因此,如果你想從44100重新採樣到11025,你必須在11025或5500赫茲的1/2下過濾44100低通濾波器,因爲再現的忠實度隨着較低的帶寬而降低,最好以最大幅度如-10Db的幅度進行。對於有符號的16位,該值爲最大幅度的10 ^( - 10/20)* 2 ^(16-1)或10362 +/-。確切的算法可能會在網上找到,因爲這些舊的和基本的想法應該沒有知識產權。在完成所有沒有舍入雙精度浮點的計算之後,您將結果舍入到它們的適當整數值,並在時間範圍內插入一個集截取另一個集的值。它需要相當豐富的想象力和記憶力以及以往的經驗才能讓您置身於數學家物理程序員的領域。 :-O :-)