2009-11-16 5 views
1

나는와 ALSA의 pcm_min.c 예를 컴파일 할 때ALSA의 pcm_min.c 예제의 경고/오류. 가능한 문제?

gcc -Wall -lasound pcm_min.c -o pcm_min 

모든 것은 괜찮지 만, 그것을 실행, 나는 예상대로 화이트 노이즈를 얻을 수 있지만, 나는 또한이 경고/오류 얻을 :

Short write (expected 16384, wrote 7616) 

제공 마지막 if-statement로부터.

#include <alsa/asoundlib.h> 

static char *device = "default";      /* playback device */ 

snd_output_t *output = NULL; 
unsigned char buffer[16*1024];       /* some random data */ 

int main(void) 
{ 
     int err; 
     unsigned int i; 
     snd_pcm_t *handle; 
     snd_pcm_sframes_t frames; 

     for (i = 0; i < sizeof(buffer); i++) 
       buffer[i] = random() & 0xff; 

     if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { 
       printf("Playback open error: %s\n", snd_strerror(err)); 
       exit(EXIT_FAILURE); 
     } 
     if ((err = snd_pcm_set_params(handle, 
             SND_PCM_FORMAT_U8, 
             SND_PCM_ACCESS_RW_INTERLEAVED, 
             1, 
             48000, 
             1, 
             500000)) < 0) { /* 0.5sec */ 
       printf("Playback open error: %s\n", snd_strerror(err)); 
       exit(EXIT_FAILURE); 
     } 

     for (i = 0; i < 16; i++) { 
       frames = snd_pcm_writei(handle, buffer, sizeof(buffer)); 
       if (frames < 0) 
         frames = snd_pcm_recover(handle, frames, 0); 
       if (frames < 0) { 
         printf("snd_pcm_writei failed: %s\n", snd_strerror(err)); 
         break; 
       } 
       if (frames > 0 && frames < (long)sizeof(buffer)) 
         printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames); 
     } 

     snd_pcm_close(handle); 
     return 0; 
} 

이 경고/오류의 원인을 누가 볼 수 있습니까? 중 하나 신호가 수신 또는 언더런이있을 때

포옹, 루이스

답변

3

snd_pcm_writei() 기능은보다 sizeof(buffer)를 반환 할 수 있습니다. 귀하의 경우에는 바이트와 프레임을 혼합하는 것 같습니다. 호출의 마지막 매개 변수는 버퍼에있는 프레임 수입니다. 버퍼의 바이트 수를 대신 전달하기 때문에 언더런이 발생합니다.

+0

나는 당신이 시도하고 싶은 것을 이해하지 못합니다. 좀 더 설명해 주시겠습니까? – Louise

+0

프레임 수 대신 바이트 수를 전달하므로 내 대답을 편집했습니다. – Gonzalo

+0

매우 근사합니다. 이제 내 자신의 구현이 충돌하지 않습니다 =)하지만 나는 여전히 같은 경고/오류가 발생합니다. Btw. for-loop를 제거하면 (물론 내용을 유지하더라도) 소리가 나지 않는 이유는 무엇입니까? – Louise

1

이 예제에는 몇 가지 문제가 있습니다. 나는 조금 수정했고 이제는 효과가있다.

#include <stdio.h> 
#include <stdlib.h> 
#include <alsa/asoundlib.h> 

static char *device = "default"; /* playback device */ 
snd_output_t *output = NULL; 
unsigned char buffer[16*1024]; /* some random data */ 

int main(void) 
{ 
    int err; 
    unsigned int i; 
    snd_pcm_t *handle; 
    snd_pcm_sframes_t frames; 
    snd_pcm_uframes_t bufferSize, periodSize; 

    for (i = 0; i < sizeof(buffer); i++) 
     buffer[i] = random() & 0xff; 

    if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { 
     printf("Playback open error: %s\n", snd_strerror(err)); 
     exit(EXIT_FAILURE); 
    } 
    if ((err = snd_pcm_set_params(handle, 
            SND_PCM_FORMAT_S16_LE, 
            SND_PCM_ACCESS_RW_INTERLEAVED, 
            1, //channels 
            44100, //sample rate 
            1, //allow resampling 
            500000) //required latency in us 
     ) < 0) { 
     printf("Playback open error: %s\n", snd_strerror(err)); 
     exit(EXIT_FAILURE); 
    } 

    if ((err = snd_pcm_prepare(handle)) < 0) { 
     printf("Pcm prepare error: %s\n", snd_strerror(err)); 
     exit(EXIT_FAILURE); 
    } 

    if ((err = snd_pcm_get_params(handle, &bufferSize, &periodSize)) < 0) { 
     printf("Pcm get params error: %s\n", snd_strerror(err)); 
     exit(EXIT_FAILURE); 
    } 
    printf("Buffer size:%d, Period size:%d\n", (int)bufferSize, (int)periodSize); 

    for (i = 0; i < 16; i++) { 
     frames = snd_pcm_writei(handle, buffer, periodSize); 
     if (frames < 0) 
      frames = snd_pcm_recover(handle, frames, 0); 
     if (frames < 0) { 
      printf("snd_pcm_writei failed: %s\n", snd_strerror(err)); 
      break; 
     } 
     if (frames > 0 && frames < (long)periodSize) 
      printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames); 
    } 
    snd_pcm_close(handle); 
    return 0; 
} 
관련 문제