2013-11-21 174 views
3

因此,讓我們說,我想混這2個音軌:Audacity如何混合音頻樣本?

Unmixed

在Audacity中,我可以使用「混合和渲染」選項將它們混合在一起,我會得到這個:

Audacity Mix

然而,當我嘗試寫我自己的代碼混合,我得到這個:

My Mix

這基本上是我怎麼混的樣本:(語法HAXE但它應該是容易遵循,如果你不知道它)

private function mixSamples(sample1:UInt, sample2:UInt):UInt 
{ 
    return (sample1 + sample2) & 0xFF; 
} 

這些是8位採樣音頻文件,並且我希望產品也是8位的,因此& 0xFF

我明白,只要簡單地加入樣本,我就會期望剪裁。我的問題是,Audacity中的混音不會導致裁剪(至少不會導致我的代碼),並且通過查看第二個(較長)軌道的「尾部」,似乎不會減小幅度。它聽起來也不軟。

所以基本上,我的問題是這樣的:Audacity在做什麼,我不是?我想混合音軌聽起來就好像他們在另一個上面播放,但我(顯然)不想要這個可怕的剪輯。

編輯:

這裏是我所得到的,如果我籤值之前添加,然後unsign和值,如建議通過Radiodef:

My Signed Mix

正如你所看到的它比以前好得多,但與Audacity產生的結果相比,仍然很扭曲和嘈雜。所以我的問題依然存在,Audacity必須以不同的方式做事。

EDIT2:

予混合所述第一軌道上本身,都與我的代碼和Audacity的,並且與發生失真的點。這就是無畏的結果:

Zoom Audacity

這是我的結果:

enter image description here

+1

僅基於屏幕截圖,看起來它們是相乘的,而不是相加的。 – ashes999

+0

這看起來比剪裁更怪異。看看短片段的總和,音頻完全被破壞,然後完全不受影響。你確定你的8位樣本在讀入時沒有被放大嗎?試着拿出&看看會發生什麼。 – Radiodef

+0

@ ashes999:我不確定你在說什麼,但我可以向你保證我的是被添加的(主要失真的原因是他們沒有簽名,正如Radiodef指出的那樣)。至於Audacity混音,Audacity手冊本身陳述了「混合多個曲目_adds_波形混在一起」的行爲:http://manual.audacityteam.org/man/Mixing – puggsoy

回答

5

我認爲正在發生的事情是,你正在總結他們作爲無符號。一個典型的聲波是正面和負面的,這就是爲什麼他們加在一起的方式(有些部分取消)。如果你有一些8位的採樣是-96,另一個是96,你總結他們,你會得到0.如果你有什麼是無符號的音頻,你將取而代之的樣本32和224總結= 256(偏移和溢出) 。

你需要做的是在求和之前對它們進行簽名。要簽名8位樣本,將它們轉換爲帶符號的int類型,並從它們中減去128。我假設你所擁有的是WAV文件,你需要在總和之後再次對其進行排序。

Audacity可能會進行浮點處理。我聽說過一些關於浮點的可疑聲明,例如它具有「無限動態範圍」和類似垃圾,但它不像整數那樣以明確的方式截取。浮點數的有限範圍與整數相同,但最大值和最小值的距離更遠。 (這是關於最簡單的方式)。浮點可以允許音頻中的幅度變化更大,但捕獲是整體信噪比低於整數。

隨着奇怪的變形我最好的猜測是它是從你正在做的面具& 0xFF。如果你想實際剪輯而不是溢出,你將需要自己做。

for (int i = 0; i < samplesLength; i++) { 
    if (samples[i] > 127) { 
     samples[i] = 127; 
    } else if (samples[i] < -128) { 
     samples[i] = -128; 
    } 
} 

否則說你有兩個樣本是125,總結得到你250(11111010)。然後你取消簽名(加128)並得到378(101111010)。一個&會得到你1111010這是122.其他數字可能會讓你的結果是有效的負數或接近0.

如果你想剪輯的東西以外的比特深度n的8位,滿量程將爲positive (2^(n - 1)) - 1negative 2^(n - 1),例如32767和-32768爲16位。

你可以做的另一件事情,而不是裁剪是搜索裁剪和規範化。例如:

double[] normalize(double[] samples, int length, int destBits) { 

    double fsNeg = -pow(2, destBits - 1); 
    double fsPos = -fsNeg - 1; 

    double peak = 0; 
    double norm = 1; 

    for (int i = 0; i < length; i++) { 
     // find highest clip if there is one 

     if (samples[i] < fsNeg || samples[i] > fsPos) { 
      norm = abs(samples[i]); 

      if (norm > peak) { 
       norm = peak; 
      } 
     } 
    } 

    if (peak != 0) { 

     // ratio to reduce to where there is not a clip 
     norm = -fsNeg/peak; 

     for (int i = 0; i < length; i++) { 
      samples[i] *= norm; 
     } 
    } 

    return samples; 
} 
+0

啊,這非常有道理,有點愚蠢我沒有意識到:P仍然使用這種方法後(簽名,添加,不簽名),我仍然得到相當嘈雜的波形,特別是在開始時。這不是可怕的剪裁,但它仍然顯着磨擦和不愉快。我將用截圖編輯問題。 – puggsoy

+0

「Scratchy」聽起來像量化噪聲的描述。這可能是由於8位,雖然在我的經驗中,8位的量化誤差通常不是那麼明顯。這取決於您的原始信號的RMS有多低。如果出於某種原因需要8位,我的建議是使用更高的位深度,並且只在最後進行量化。只有在最後量化才能最大限度地減少錯誤,因爲它不會通過中間操作複合。這可能是Audacity所做的記錄。沒有嚴肅的音頻應用程序會在源位深處執行任何DSP。 – Radiodef

+0

不幸的是,似乎沒有幫助,我得到了相同的結果。我甚至將它們轉換爲32位整數(乘以0xFFFFFF是如何完成的),並將它們加在一起,然後將它們寫入32位WAV,仍然是同樣的事情。在添加之前將它們轉換爲在1.0和-1.0之間浮動,然後再變回,也不起作用。 – puggsoy

1

這比您想象的要簡單得多;儘管您的原始文件是8位,但Audacity在內部將它們作爲32位浮點處理。您可以在屏幕截圖中的每條曲目左側的信息面板中看到這一點。這意味着將2個軌道加在一起意味着在每個點處添加兩個浮點採樣,並且將簡單地產生-2.0至+2.0的採樣值,然後將其鉗位到-1至+1範圍。相比之下,將兩個8位整數加在一起將產生另一個8位數字,其中的值溢出幷包圍。 (無論您使用帶符號還是無符號值,這都可以應用。)

+0

我注意到了,是的。事情是,我使用Haxe,所有整數都是32位,所以我認爲添加兩個8位整數不應該成爲問題。正如Radiodef指出的那樣,用0xFF掩蓋它會導致它環繞,這是我沒有意識到的。 – puggsoy