2010년 06월 10일
Embedded Linux] wavplay - O_NONBLOCK 모드
버튼을 눌러 재생/정지를 반복하는데 그런 딜레이는 문제가 될 여지가 많다.
그렇다고 하면 Non-Blocking 모드를 이용해보자.
int fd = open("dev/dsp", O_WRONLY | ONONBLOCK);
// wav파일을 열고
// 파일을 read
// 장치에 write
참고 : http://forum.falinux.com/zbxe/?document_srl=406370
이런식으로 하면 잘될거 같지만... 그렇지 않다.
파일이 일정시간 재생이 된 후 끊겨 버린다.
재생을 아랑곳하지 않고 read -> write를 하니 사운드버퍼가 찼을때는 write를 못하는 것이다.
따라서 write시에 사운드 카드를 체크해야 한다.
int get_writable_size()
{
audio_buf_info bi;
ioctl(fd_soundcard, SNDCTL_DSP_GETOSPACE, &bi);
return bi.bytes;
}
writable_len = get_writable_size();
if( writable_len > read_size )
{
write(fd, buff, read_size);
}
그리고 interrupt 시엔 사운드 버퍼를 리셋하자.
ioctl(fd_soundcard, SNDCTL_DSP_RESET, NULL);
ioctl(fd_soundcard, SNDCTL_DSP_SYNC);
마지막으로 하나가 더 남았는데 interrupt는 다른 스레드에서 발생하기 때문에 자칫하면 에러가 발생할 수 있다.
따라서 write시와 reset시 MutexLock을 한다.
// 쓰기
MutexLock();
write(fd, buff, read_size);
MutexUnLock();
// 종료
MutexLock();
ioctl(fd_soundcard, SNDCTL_DSP_RESET, NULL);
ioctl(fd_soundcard, SNDCTL_DSP_SYNC);
MutexUnLock();
이렇게 해서 버튼 동작으로 재생/정지를 딜레이 없이 구현할 수 있었다.
ps. alsa를 이용하여 재생시에는 딜레이 없이 정지된다. 내부적으로 non-block모드를 이용하는지는 체크해봐야 한다.
# by | 2010/06/10 13:35 | Linux | 트랙백 | 덧글(0)






☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]