2013-03-10 199 views
1

我有一個int16_t的緩衝區,裏面有一些音頻PCM數據。我需要從a點到b點重複播放緩衝區,以便聽到無限的音頻循環。C:在linux中播放音頻循環

我發現播放聲音最簡單的方法是使用libao,但我同意其他方法。 這是我的代碼:

int play(int a, int b, char *buf); 

int main() 
{ 
     int16_t *buf; /*my buffer*/ 
     int a, b; 
     /* a and b are the indexes of the buffer; 
     * because libao wants a buffer of char, 
     * and buf points to of int16_t, I'll pass 
     * the value a and b multiplied with 2. 
     */ 

     [···] 

     play(2*a, 2*b, (char *) buf); 
     return 0; 
} 
int play(int a, int b, char *buf) 
{ 
     ao_device *device; 
     ao_sample_format format; 
     int default_driver; 
     /* -- Initialize -- */ 
     fprintf(stderr, "libao example program\n"); 
     ao_initialize(); 
     /* -- Setup for default driver -- */ 
     default_driver = ao_default_driver_id(); 
     memset(&format, 0, sizeof(format)); 
     format.bits = 16; 
     format.channels = 1; 
     format.rate = 44100; 
     format.byte_format = AO_FMT_LITTLE; 
     /* -- Open driver -- */ 
     device = ao_open_live(default_driver, &format, NULL /* no options */); 
     if (device == NULL) { 
      fprintf(stderr, "Error opening device.\n"); 
      exit(1); 
     } 
     /* -- Play the infinite loop -- */ 
     for (;;){ 
      ao_play(device, buf+a, b-a+1); 
      /*buf+a is the start of the loop, b-a+1 the number of byte to play--edited*/ 
     } 
     /* -- Close and shutdown -- */ 
     ao_close(device); 
     ao_shutdown(); 
    return 0; 
} 

的問題是,我聽到一個時期的結束和循環的開始之間的沉默。因爲我正在使用此代碼來測試其他代碼,所以我絕對需要知道它是否可能是由於錯誤地使用了libao而導致的。

+0

我一直認爲做無害化在Linux中最簡單的方法只是爲了管'的/ dev/snd' :) – nneonneo 2013-03-10 13:41:40

+0

它似乎在最近的內核中不再允許,因爲安全性問題。我正在使用Debian 6.0.6和內核2.6.32-5 – fortea 2013-03-10 13:48:42

回答

1

是的,它絕對可能是由於不正確使用libao引起的。請從ao_play()調用刪除+1,就像這樣:

ao_play(device, buf+a, b-a); 
+0

好的,非常感謝。那麼這意味着「內存緩衝區中的音頻數據的字節數」(第三個參數)是第一個被保留的? – fortea 2013-03-11 18:23:18

+0

我不太瞭解你的問題,但我會盡力解釋。第三個參數指定從給定緩衝區應該播放多少個BYTES。然而,字節與幀不同,並且當前ao不能播放「半個樣本」或類似的東西。所以參數必須是幀大小的倍數(以字節爲單位的採樣大小*通道數)。如果你的幀是兩個字節,並且你添加一個傳遞n幀加上一個字節,那麼ao會丟失半幀,並且當你下一次調用ao_play時,這些採樣在內部沒有對齊,導致靜音(或噪聲!)。接下來的電話再次將它們對齊。 – clarry 2013-03-12 21:39:17

+0

我錯了,因爲問題依然存在。我做了一個測試包(http://www.megafileupload.com/en/file/404492/loop-test-tar-gz.html)。使用「gcc -lao stack_overflow.c」編譯並使用「./a.out test.wav」運行。無論是'b-a'還是'b-a + 1',循環結束和開始之間都會有一個沉默時刻。 – fortea 2013-03-22 13:07:43