2013-03-10 1 views
1

버퍼에 오디오 PCM 데이터가 포함 된 int16_t 버퍼가 있습니다. 점 a에서 점 b까지 버퍼를 반복 재생해야하므로 무한 오디오 루프가 들립니다.C : 리눅스에서 오디오 루프 재생

사운드를 재생하는 가장 쉬운 방법은 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

난 항상 리눅스에서 소리를 할 수있는 쉬운 방법을 생각 단지 파이프는/dev/snd''에 :) – nneonneo

+0

였습니다이 보인다 최근의 커널에서는 보안 문제 때문에 더 이상 허용되지 않습니다. 데비안 6.0.6과 커널 2.6.32-5를 사용하고 있습니다. – fortea

답변

1

예, 이는 정확하게 libao의 잘못된 사용으로 인해 발생할 수 있습니다. 그래서처럼 ao_play() 호출에서 +1을 제거하십시오 :

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

감사합니다. 정말 고마워요. 즉, "메모리 버퍼의 오디오 데이터 바이트 수"(세 번째 인수)가 처음 제외 되었습니까? – fortea

+0

나는 당신의 질문을 이해하지 못한다. 그러나 나는 어쨌든 설명하려고 노력할 것이다. 세 번째 인수는 지정된 버퍼에서 재생해야하는 바이트 수를 지정합니다. 그러나 바이트는 프레임과 동일하지 않으며 현재 "샘플 절반"또는 그와 비슷한 것을 재생할 수 없습니다. 따라서 인수는 프레임 크기 (샘플 크기 (바이트) * 채널 수)의 배수 여야합니다. 프레임이 2 바이트이고 n 프레임 + 1 바이트를 전달하기 위해 프레임을 추가하면 ao는 프레임 절반을 잃어 버리고 다음 번에 ao_play를 호출하면 샘플이 내부적으로 정렬되지 않으므로 소리가 나지 않습니다 (또는 잡음이 발생합니다). 다음 호출은 그들을 다시 정렬합니다. – clarry

+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