런타임 시 클럭 비트 전송률 변경(ALSA, PCM) AM335x

런타임 시 클럭 비트 전송률 변경(ALSA, PCM) AM335x

저는 현재 AM335x의 MCASP1을 사용하는 WM8776으로 임베디드 보드를 개발 중입니다. 이는 예상대로 작동하며 예상된 동작을 갖습니다.

지금 하고 싶은 것은 주파수를 전환할 수 있는 드라이버를 만드는 것입니다. 클럭 멀티플렉서를 통해 GPIO를 통해 MCASP로 이동하는 두 개의 클럭이 있습니다. 이 GPIO가 높으면 32/48/64/96/196 등의 오디오에 대해 24,576 클럭이 있고 44.1/88.2/174 등의 오디오에 대해 11,960 클럭이 있습니다.

이제 내 목표는 커널 공간에서 시계를 변경할 수 있는 것입니다. 지금까지 내가 한 일은 현재 샘플 속도를 인쇄하는 코드를 입력하는 것이었습니다. 모두 제일 좋다. 현재 전달된 샘플 속도가 표시됩니다.

그러나 .asoundrc에서 ALSA 리샘플링을 비활성화하면 44.1khz(11,960mhz) 클럭에서 96khz 노래를 재생하려고 할 때 다음 오류가 발생합니다. alsa_open:303 unable to get period size: Invalid argument

이 클럭에서 리샘플링하지 않고는 어떤 Integer도 완벽한 비트 전송률을 달성할 수 없기 때문에 이것은 물론 논리적입니다. 문제는 앞서 언급한 커널에 넣은 인쇄 주석에 현재 비트 전송률에 대한 정보가 더 이상 포함되어 있지 않다는 것입니다. ALSA가 이미 이것을 포착했다고 생각하기 때문에 이 기능에 도달하지 못합니다.

그래서 저는 이 오류의 원인을 추적하여 다음과 같이 커널을 프로그래밍할 수 있도록 노력하고 있습니다. 우리는 이 비트 전송률로 재생하고 있으므로 이 특정 사운드 카드를 사용할 때 노래가 변경될 때마다 변경하고 싶습니다. 이 시계에. 하지만 커널 사운드 코드를 보면 이 오류를 어디에서도 찾을 수 없습니다.

간단히 말해서 사용 사례는 다음과 같습니다.

시작 주파수는 11.960Mhz입니다. -> 현재 44.1Khz 곡을 재생하고 있습니다. -> 96Khz 노래로 변경 -> GPIO를 높게 설정(클럭은 현재 24,512Mhz) -> 시계가 변경되었음을 ALSA 및 MCASP에 알립니다.

커널 공간에서 MCASP를 변경하는 방법을 알고 있습니다. 이제 내 질문은 다음과 같습니다.

새로운 재생이 시작될 때마다(예: 노래 변경) 첫 번째 기능은 무엇입니까?

이 오류의 원인은 어디서 찾을 수 있나요?

내가 하고 싶은 일을 하는 더 좋은 방법이 있을까요?

답변1

두 가지가 있습니다. PCM 샘플 스트림을 재생하는 애플리케이션과 ALSA의 커널 측 사이에는 사용자 공간 alsalib과 선택적 내부 리샘플링이 있습니다. 애플리케이션이 이를 비활성화하지 않고 장치를 있는 그대로 요청하는 경우 커널은 원래 묘목 비율이 무엇인지 알 수 없습니다. 커널에는 전혀 표시되지 않습니다. 응용 프로그램이 순수 하드웨어 인터페이스로 ALSA를 사용하지 않고 대신 사용자 공간 사운드 서버(예: Pulseaudio, Pipeline, esound 또는 JACK)를 사용하는 경우(또한 ALSA 장치의 사용자 공간 구현을 제공하고 다음을 수행할 수 있습니다.) 내부적으로 믹싱/리샘플링) 상황이 더 정확합니다. 이는 최신 Linux 데스크탑의 표준입니다.

응용 프로그램이 하드웨어를 특정 속도로 샘플링하기를 원하는 경우 snd_pcm_hw_patamsalsalib에서 호출하여 커널 드라이버에 요청된 속도를 알리는 데 필요한 시스템 호출을 수행합니다. 아무것도 하지 않는 최소한의 프로그램을 작성한 다음, 이를 추적하여 그것이 무엇인지 확인하십시오!

일반적으로 여러 스트림을 동시에, 다른 속도로 재생하는 것이 일반적이므로 대부분의 응용 프로그램에서는 하드웨어 매개 변수 자체를 조작하려고 하지 않는 것이 당연합니다. 장치가 올바르게 설정되도록 요청하며 일반적으로 다음을 포함합니다. 선택한 사용자 공간 매개변수.

관련 정보