[英]How to mix voice audio
我目前正在開發一個簡單的VoIP項目,其中多個客戶端將他的聲音發送到服務器,然后服務器將這些聲音混合在一起。
但是,我無法使用簡單的數學加法直接將其混合。 每個周期,客戶端將向混合器發送3584字節的語音數據。
以下是接收器緩沖區中包含的值的代碼段:
BYTE buffer[3584];
[0] 0 unsigned char
[1] 192 'À' unsigned char
[2] 176 '°' unsigned char
[3] 61 '=' unsigned char
[4] 0 unsigned char
[5] 80 'P' unsigned char
[6] 172 '¬' unsigned char
[7] 61 '=' unsigned char
[8] 0 unsigned char
[9] 144 '' unsigned char
[10] 183 '·' unsigned char
[11] 61 '=' unsigned char
.
.
.
我不確定如何從客戶端以這種方式生成緩沖區內的模式,但我認為這可能是波動模式。 現在讓我們說我有另一個類似的數據,如何將聲音混合在一起。
請幫忙。 謝謝。
您需要確定VoIP系統是否使用壓縮。 它可能會這樣做,在這種情況下,您需要做的第一件事是解壓縮流,然后將它們混合,然后重新壓縮。
如果它是原始PCM數據,則可能是一個浮點數組(不太可能是由於所提供的字節模式)或單個整數,因此請嘗試按原樣使用它。 混合到PCM流非常簡單,只需將它們加在一起並除以2(使用其他權重進行音量控制)即可。
我再次查看了您的數據,它們似乎是浮點值,原因是我在上一篇文章中弄錯了原因可能與我在大型字節序系統上工作了一段時間有關。 但是,您的數據位於小端IEEE浮點數中。 這是轉換后我得到的值。
0.089630127 -> 0x0090b73d
0.084136963 -> 0x0050ac3d
0.086303711 -> 0x00c0b03d
如您所見,這些值很小,因此在應用體積時可能需要考慮到這一點。 通常的慣例是,此數據的最小和最大體積分別在0..1或-1..1之間。
這是我幾年前編寫的混合循環的一部分,作為參考, 可以在此處找到完整的混合器
for(int i = 0; i < a_Sample->count() / a_Sample->channels(); i++){
float l_Volume = a_Sample->volume() * m_MasterVolume;
*l_Output++ += *l_Left * l_PanLeft * l_Volume;
*l_Output++ += *l_Right * l_PanRight * l_Volume;
l_Left += a_Sample->channels();
l_Right += a_Sample->channels();
}
請注意,對於輸出,您可能需要將數據轉換為有符號整數,因此如果這是混頻器或輸出設備的職責,請進行正確的通信。
正如其他人提到的那樣,您必須知道緩沖區的格式。不能簡單地直接對字節進行操作(可以,但是會變得很復雜)。 大多數原始PCM數據通常為44100位/秒,16位,2通道。 但是,並非總是如此。 這些中的每一個都可以不同。 它不會太大影響,只是一個例子。 但是,即使WAV文件也可以采用其他格式(例如IEEE Float)。 您將需要正確地將緩沖區解釋為適當的數據類型,以便對其進行操作。
喜歡:
BYTE buffer[3584];
if (SampleTypeIsPcm16Bit())
{
short *data = reinterpret_cast<short *>(buffer);
// Rock on
}
else if (SampleTypeIsFloat())
{
float *data = reinterpret_cast<float *>(buffer);
// Rock on
}
當然,您可以使用模板使其更通用,但請忽略:P。
請記住,如果要處理浮點數,則需要將它們限制在-1.0和1.0范圍內。
因此,您當前是否在說“加兩個值並除以2”(Jasper提到)不起作用? 當您聽到靜音時如何播放數據? 我想知道這是否是一個問題,因為如果您的數學運算關閉,您可能會聽到音頻毛刺(啪啪聲/咔嗒聲/等),而不僅僅是安靜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.