2016-07-01 3 views
1

저는 데이터를 파이프로 연결하여 신디사이저를 만들고 있습니다 (이상적이지는 않습니다) 사운드를 변경하는 키 누르기 뒤에서 사운드가 지연되고 있습니다. 저는 이것이 aplay가 8000Hz로 일정하기 때문에 발생한다고 생각합니다, 그러나 c 프로그램은 불안정한 속도로 진행되고 있습니다. for 루프를 C에서 8000Hz로 이동하려면 어떻게합니까?특정 샘플 속도로 오디오 데이터를 쓰려면 어떻게해야합니까?

+2

이 질문은 너무 광범위합니다. 이를 보장하기위한 간단한 조치는 없습니다. 타겟 플랫폼, 사용 가능한 라이브러리 등에 따라 다릅니다. – Olaf

+1

파이프를 사용하여'aplay'와 통신하는 대신 ALSA, PulseAudio 등과 같은 API를 사용하면 더 많은 성공을 거둘 것입니다. 이러한 API는 대기 시간을 도입하지 않고 원하는 샘플 속도 (예 : 8kHz)로 데이터를 안정적으로 생성 할 수 있도록 콜백 또는 차단 기능을 제공합니다. 파이프를 사용하면 커널 버퍼와 항상 경쟁하게됩니다 ... 기본적으로 64KB, 또는 16 비트 스테레오로 2 초! PortAudio와 같은 API를 랩핑하는 더 간단한 라이브러리도 있습니다 (아마도 가장 좋은 방법일까요?) –

답변

0

데이터를 aplay으로 파이프하는 경우 버퍼가 가득 차면 write() 때 커널이 프로그램을 차단하므로 샘플 속도 (예 : 8kHz)에 문제가 발생하지 않습니다. 이렇게하면 오디오 생성을 효과적으로 8 kHz로 제한 할 수 있습니다.

그러나 이것은 이상적인 것으로는 거리가 멀습니다. 파이프의 커널 버퍼가 가득 찼을 때만 응용 프로그램이 스로틀되며 Linux의 파이프 버퍼의 기본 크기는 64KB입니다. 8 kHz의 스테레오 16 비트 데이터의 경우 오디오 데이터는 2 초이므로 사용자가 입력 한 후 오디오가 2 초 이상 지연 될 것으로 예상됩니다. 이것은 신디사이저 어플리케이션에서는 받아 들여지지 않습니다.

유일한 실제 해결책은 ALSA 라이브러리를 직접 (또는 대체 사운드 API) 사용하는 것입니다. 이 API를 사용하면 커널 버퍼에 과도하게 대기중인 데이터를 축적하지 않고 버퍼링 된 오디오 데이터를 오디오 출력 장치로 보낼 수 있습니다.

몇 가지 팁은 A Guide Through The Linux Sound API Jungle을 참조하십시오.

1

8000 Hz (또는 고정 비율)로 오디오 샘플을 생성하려면 루프를 해당 속도로 "실행"하지 않으십시오. 이것은 다음 샘플을 생성하기까지 아무런 조치도 취하지 않는 엄청난 양의 오버 헤드 (99.99 % 또는 그 이상) 방적을 포함 할 것이고 (특히 방치하지 않고 잠을 자면) 프로세스가 깨어나서 스케줄되지 않을 수도 있다는 점에서 신뢰할 수 없습니다 시간의 일부 샘플에 대한.

대신 소비자 (aplay/오디오 장치)가 예상하는 것과 일치하는 전체 속도로 샘플을 생성하려고합니다. 버퍼 깊이에 비례하여 일정 기간 동안, 그 샘플에 잠을 생성 한 후,

current_time + buffer_depth - start_time 

다음,하지만 충분히 적은 당신이 이겼다 : 당신은 당신과 같은 무언가로까지 생성해야합니다 전체 현재 샘플 수를 계산할 수 있습니다 프로세스가 즉시 다시 스케줄되지 않으면 문제가 발생하지 않습니다. 사용할 수있는 버퍼 깊이는 필요한 대기 시간의 종류에 따라 다릅니다. 실시간/실시간 이벤트 사운드를 생성하는 경우 버퍼 깊이는 1/50 초 (20ms) 이하 여야합니다. 그렇지 않으면 5 ~ 10 초와 같이 거대한 버퍼를 행복하게 사용할 수 있습니다.

+0

두 개의 클럭 (오디오 출력은 종종 자체 시계에서 실행 됨) 때문에 오디오 결함이 발생합니다. –

+0

글쎄, 그런데, OP는'aplay'를 사용하기 때문에 그 문제에 대한 해결책은 없습니다. 직접 재생하려면 시스템 클럭을 사용하는 대신 오디오 장치를 시간 원본으로 사용해야합니다. 그렇지 않으면 시스템 클럭 기반 (또는 다른 클럭 기반) 오디오를 오디오 장치에 전달하는 프로세스 ('aplay' 또는 유사한) 교정을해야합니다. 그러나이 IMO 전체 주제는 OP의 질문/이해와 관련하여 매우 진보되어 있으며 프로세스가 몇 시간 동안 실행될 때까지 중요하지 않을 수 있습니다. –

+0

당신은 "문제가 될 것 같지 않습니다"라고 말하지만, 나는 정기적으로 동기화되지 않은 오디오 소스로 클릭과 팝을 얻습니다. 단지 'aplay'가 8000Hz 대신에 8001Hz로 실행되는 것입니다. (시스템 클럭으로 측정) –

관련 문제