2016-11-03 8 views
2

작은 C 프로그램에서 ALSA을 통해 가변 길이의 짧은 음을 생성하려고합니다. 한 두 번째 가치의 사운드를 재생할 때 잘 작동 해 보인 몇 가지 예가 있지만 그보다 짧은 것은 아무 소리도 생성하지 않습니다.ALSA로 짧은 음색을 재생하는 방법

if ((err = snd_pcm_set_params(handle, 
           SND_PCM_FORMAT_FLOAT, 
           SND_PCM_ACCESS_RW_INTERLEAVED, 
           1, 
           44100, 
           1, 
           500000)) < 0) { 
printf("Playback open error: %s\n", snd_strerror(err)); 
exit(EXIT_FAILURE); 
} 

재생 :

frames = snd_pcm_writei(handle, buffer, BUFFER_LEN); 

하지만 원하는 경우 PCM 장치 매개 변수를 설정

#define BUFFER_LEN 44100 
int freq = 700;    //audio frequency 
int fs = 44100;    //sampling frequency 
float buffer [BUFFER_LEN]; 
for (k=0; k<BUFFER_LEN; k++) { 
    buffer[k] = (sin(2*M_PI*freq/fs*k));         
} 

:

는 그래서 같은 정현파로 버퍼를 작성하고 있습니다 음색을 바꾸기 위해 그것을 바꾸기 위해, 1 초의 1/4을 말하자면 (즉, BUFFER_LEN에서 11025로 변경) 아무것도 오지 않는다. 더 이상 스피커에서 빠져 나왔다.

float에서 short로 유형을 변경하고 PCM_FORMAT을 다른 값으로 설정하고 다른 방법으로 사인파로 버퍼를 채우려고 시도했습니다.

스피커에서 'bip'소리가 들리지만 예상 한 것과 다릅니다. 이 프로그램은 segfaults 또는 충돌하지 않지만 ALSA 짧은 샘플을 재생하는 방법을 난 그냥 혼란스러워.

정확한 프레임 또는 버퍼 크기 배수로 작업해야하는지 잘 모르겠지만 제안은 매우 열려 있습니다.

+0

야생 추측 : 지연 시간 == 500000us가 재생 시간 250000us보다 오래 걸리기 때문입니다. 대기 시간 == 0으로 어떤 것이 있습니까? –

+0

마지막 쓰기 통화 후 프로그램이 수행하는 작업은 무엇입니까? –

+0

@ 톰 Goodfellow 와우, 그 일했습니다! 이것은 작은 모스 부호 응용 프로그램을위한 것입니다. 나는 몇 번의 경고음을 쓸 수 있지만 두 번째 프로그램을 실행하면 항상 재생되지는 않습니다. 버퍼를 플러시하거나 리셋해야한다고 생각합니다. 확실하지는 않지만 유망 해 보입니다. 감사. – captcha

답변

1

응용 프로그램에서 버퍼에 샘플을 쓰고 버퍼에서 샘플을 읽는 하드웨어가 비동기 적으로 실행되는 두 가지 다른 프로세스입니다.

작성하려는 샘플의 양에 대해 버퍼에 여유 공간이 충분하지 않은 경우 snd_pcm_writei()은 충분한 공간이 확보 될 때까지 대기합니다. 그러나 snd_pcm_writei()이 반환하면 최대 샘플 버퍼가 아직 재생되지 않았을 수 있습니다.

버퍼가 비워질 때까지 대기하려면 snd_pcm_drain()을 사용하십시오.

+0

그래서 모든 쓰기 시작 또는 끝에 snd_pcm_drain()을 사용합니까? 어쨌든, 나는 약간의 진전을 보였고 대기 시간을 10000으로 설정함으로써 나는 좋은 재생을 얻고있다. 이제는 snd 장치를 닫을 때까지 콘솔에 대한 printf() 명령이 차단되었음을 알았지 만 .. – captcha

+0

버퍼를 비울 때까지 기다리고 싶을 때 사용합니다. –