2011-06-09 78 views
4

我在這裏有以下問題:我得到一個字節塊(uint16_t *)代表音頻數據,並且生成它們的設備捕獲單聲道聲音,所以顯然我有單聲道音頻數據。我需要將這些數據傳遞給其他設備,這些設備需要交錯立體聲數據(如此,2個通道)。我想要做的是基本上覆制數據中的1個通道,這樣立體聲數據的兩個通道將包含相同的字節。你能指點我一個有效的算法嗎?單聲道到立體聲轉換

謝謝, f。

+0

你使用什麼音頻格式/框架? – 2011-06-09 12:41:06

+0

PCM,簽名16位,48000khz – fritzone 2011-06-09 12:42:36

+0

安德斯還要求提供框架。 – 2011-06-09 12:43:46

回答

11

如果你只是想交錯的立體聲採樣,那麼你可以使用這樣的功能:

void interleave(const uint16_t * in_L,  // mono input buffer (left channel) 
       const uint16_t * in_R,  // mono input buffer (right channel) 
       uint16_t * out,   // stereo output buffer 
       const size_t num_samples) // number of samples 
{ 
    for (size_t i = 0; i < num_samples; ++i) 
    { 
     out[i * 2] = in_L[i]; 
     out[i * 2 + 1] = in_R[i]; 
    } 
} 

要生成從單聲道立體聲緩衝區,那麼你將只是傳遞了IN_L和IN_R,例如相同的指針

interleave(mono_buffer, mono_buffer, stereo_buffer, num_samples); 
+0

下次您刪除編輯時,您是否至少可以通知投稿人? : -/ – 2014-06-13 14:04:40

+0

當然,雖然我不確定我該怎麼做? – 2014-06-13 14:17:35

+0

我在添加就地版本後忘了添加評論。我的錯。 – 2014-06-13 14:20:50

2

傳遞給兩個通道相同的指針?如果違反restrict規則,請使用memcpy()

對不起,但您的問題是其他廣泛。 API? OS? CPUArchitectures?

+0

這不起作用,我沒有發送每個通道的數據,我發送了大量的字節和設備編號。 2是根據需要將它們分開。 – fritzone 2011-06-09 13:04:12

0

您將不得不復制緩衝區並複製它。因爲你沒有告訴我們格式,它是如何終止的,我不能給代碼,但它看起來像一個簡單的for循環。

int_16* allocateInterleaved(int_16* data, int length) 
    int i; 
    int *copy = malloc(sizeof(int_16)*length*2); 
    if(copy == NULL) { 
    /* handle error */ 
    } 
    for(i =0; i<length; i++) { 
    copy[2*i] = data[i]; 
    copy[2*i+1] = data[i]; 
    } 
    return copy; 
} 

原諒任何明顯的錯別字,我的C有點生疏。 typdef,無論你需要什麼類型的16位到int_16。不要忘記釋放複製緩衝區,或者更好地重用它。

+0

@保羅R,謝謝,我修好了 – 2011-06-09 13:44:31

1

您可能想要在原地進行轉換以節省一些內存。取決於有問題的設備有多少內存。所以,你可能想使用這樣的事情,而不是保羅·R的方式的:

void interleave(uint16_t buf[], const int len) 
{ 
    for (int i = len/2 - 1, j = len - 1; i > 0; --i) { 
     buf[j--] = buf[i]; 
     buf[j--] = buf[i]; 
    } 
} 

當從單設備獲取的聲音數據,你分配一個緩衝區根據需要並傳遞到單設備的兩倍大。這將用單聲道音頻填充一半緩衝區。然後將該緩衝區傳遞給上述函數,該函數將其轉換爲立體聲。最後你將緩衝區傳遞給立體聲設備。您節省了額外的分配空間,因此轉換的內存減少了33%。

相關問題