ALSA에 아웃풋 과정
글쓴이: leenetwork / 작성시간: 화, 2014/07/08 - 2:38오전
현재 오디오 관련하여 프로그래밍을 하고있습니다.
Application - middle ware - ALSA - kernel 이런식으로 되어있는데요. 현재 미들에서 PCM 데이터는 포인터로 가져오고 있는데 ALSA에 쏴주기 전에 로칼아웃풋을 다른 쪽으로 스트리밍 시킬려고 합니다.
오디오쪽은 처음이라서 많이 햇갈리네요.
지금 현재 TinyALSA 라는 프로그램을 사용중이며 PCM 데이터는 포인터로 읽어오고 있는 상황입니다 (다만 데이터의 포인터 값이 한번 스트리밍이 발생되면 변하지 않습니다. 아무래도 mmap 으로 잡혀 있는거 같아요.)
PCM을 ALSA로 쏴주는게 정확히 ioctl 을 사용해서 하는것인가요 ? (개념이 가장 햇갈리네요)
보통 스트림 버퍼로 읽어와서 루프로 쏴주는줄 아는데 PCM 은 정확히 어떻게 처리해야 해당 ALSA쪽에도 들리게 할수 있나요?
초보자라 보니 설명이 이상하네요. 사운드쪽 잘 아시는분들 많은 도움 부탁드립니다.
Forums:
android 인가요
tinyalsa 가 사용 되는 곳이 android 인데 android를 말씀하시는가 보군요.
user(Audio HAL) 영역에서 kernel(ALSA) 영역으로 pcm data를 넘기는 방법은(=읽는 방법) 2가지가 있습니다.
tinyalsa library에서 다음 두 함수를 이용해서 넘깁니다.
int pcm_write(struct pcm *pcm, const void *data, unsigned int count);
pcm_write 함수는 두번째 매개변수에 pcm data pointer, 세번째 매개변수에 bytes 양을 넘깁니다.
그럼 tinyalsa는 ioctl을 이용하여 kernel 영역과 드라이빙 하며 copy_from_user 를 이용해서
data를 kernel 내 메모리에 복사합니다.
int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);
sound hw driver가 mmap 을 지원한다면 이 함수를 이용할 수 있습니다.
mmap의 개념은 linux device driver mmap 개념과 같고
user 영역에서 바로 memcpy를 이용하여 복사하는 방식입니다.
memcpy 하고 alsa driver에게 offset 값만 알려 주는 방식입니다 ( 이미 data는 복사 되었으므로 )
pcm_write 전에 data를 다른쪽으로 스트리밍(혹은 덤프) 하고 싶다면
int pcm_write(struct pcm *pcm, const void *data, unsigned int count); 에서
에서 data point 와 count를 알고 있으므로 그쪽으로 던지거나 저장하면 됩니다.
pcm_write 개념을 쉽게 설명하면..
FIFO에 data를 size(count)만큼 계속 채워 넣는 다고 생각하시면 됩니다.
FIFO가 꽉 차면 더이상 data를 넣을 수 없고 대기 하게 됩니다.
FIFO에서 data가 소리로 나오게 되고 어느 정도(period_size)
FIFO가 비워지면 대기 하고 있던 pcm_write 가 수행 되어 FIFO 가 비워진 만큼(소리가 나간 만큼) 다시 복사를 합니다.
이 행동을 계속 반복 하게 됩니다.
댓글 달기