본문으로 건너뛰기

48 kHz에서 16 kHz로: 대역 제한 리샘플링이 지켜 주는 것과 그것이 일어나는 위치

Whisper 계열 모델은 16 kHz를 기대하고 대부분의 Mac 하드웨어는 48 kHz로 동작합니다. 저역 통과 필터 없이 데시메이션하면 8 kHz 위의 모든 성분이 음성 대역으로 접혀 들어옵니다. 대역 제한 변환이 하는 일과, Voice Type가 캡처 단계에서 처음부터 16 kHz를 요청하는 이유를 설명합니다.

핵심 요약

결론부터
  • 저역 통과 필터 없이 48 kHz를 16 kHz로 데시메이션하면 8 kHz 위의 모든 성분이 음성 대역으로 접혀 들어옵니다.
  • 대역 제한 변환은 먼저 8 kHz에서 저역 통과 필터링을 한 다음 3 대 1로 데시메이션합니다.
  • Voice Type는 Core Audio에 16 kHz 입력 스트림을 직접 요청하므로, 변환은 보통 앱이 아니라 오디오 드라이버에서 이루어집니다.
  • 기기가 16 kHz를 제공하지 못하면, 앱은 각 배치의 컨디셔닝 체인 끝에서 AVAudioConverter로 변환합니다.

Whisper 계열 모델은 16 kHz 오디오를 기대합니다. 대부분의 Mac 오디오 하드웨어는 48 kHz로 동작합니다. 둘 사이 어딘가에서 샘플링 레이트 변환이 일어나야 하는데, 필터 없이 변환하면 사용자의 목소리가 만들지 않은 에너지가 모델 입력에 들어갑니다.

요약

  • 저역 통과 필터 없이 48 kHz를 16 kHz로 데시메이션하면 8 kHz 위의 모든 성분이 음성 대역으로 접혀 들어옵니다.
  • 대역 제한 변환은 먼저 8 kHz에서 저역 통과 필터링을 한 다음 3 대 1로 데시메이션합니다.
  • Voice Type는 Core Audio에 16 kHz 입력 스트림을 직접 요청하므로, 변환은 보통 앱이 아니라 오디오 드라이버에서 이루어집니다.
  • 기기가 16 kHz를 제공하지 못하면, 앱은 각 배치의 컨디셔닝 체인 끝에서 AVAudioConverter로 변환합니다.

단순한 방식은 문제를 일으킵니다

세 샘플 중 두 개를 버리는 단순 데시메이션은 에일리어싱을 일으킵니다. 48 kHz 캡처에는 24 kHz까지의 성분이 들어 있습니다. 8 kHz 위의 성분은 16 kHz 스트림에서 갈 곳이 없어서 음성 대역으로 반사되어 내려옵니다. 10 kHz 톤은 6 kHz에 나타납니다. 모델은 화자가 내지 않은 소리를 듣게 됩니다.

저렴한 리샘플링은 저지 대역 감쇠가 아니라 속도에 맞춰 최적화되어 있습니다. 벨소리라면 괜찮지만 음성 인식에는 안 됩니다. “s”, “f”, “th”의 차이가 바로 필터가 지켜야 할 고주파 영역에 있기 때문입니다.

대역 제한 리샘플링

대역 제한 변환이란 목표 레이트의 나이퀴스트 주파수(16 kHz 출력이면 8 kHz)에서 저역 통과 필터를 적용한 다음 데시메이션하는 것입니다. 에일리어싱을 일으킬 주파수는 접혀 들어오기 전에 제거됩니다.

엔지니어링의 핵심은 필터입니다. 너무 강하면 마찰음을 구분하는 고주파 성분을 잃습니다. 너무 약하면 에일리어싱이 새어 들어옵니다.

Voice Type가 이것을 하는 위치

짐작하는 곳이 아니며, 이 페이지의 이전 버전이 말했던 곳도 아닙니다.

앱은 48 kHz로 캡처한 뒤 마지막에 변환하지 않습니다. 처음부터 입력 Audio Queue에 16 kHz 스트림을 요청하므로, 앱이 샘플을 보기 전에 캡처 경로에서 Core Audio가 레이트 변환을 수행합니다. 음성 활동 감지기, 배처, 인식기는 모두 16 kHz에서 동작합니다. 라이브 파이프라인에는 48 kHz 단계가 없습니다.

요청은 요청일 뿐 보장이 아니기 때문에, 앱 안에서 변환하는 곳이 두 군데 남아 있습니다.

  • 선택한 기기가 16 kHz가 아닌 레이트를 보고하면, 음성 활동 감지기의 입력을 먼저 변환합니다. 게이트가 16 kHz의 512샘플 프레임만을 기준으로 만들어져 있기 때문입니다.
  • 플러시된 각 배치는 16 kHz로의 리샘플링으로 끝나는 컨디셔닝 체인을 거칩니다. 캡처가 이미 16 kHz였다면 이 단계는 아무 일도 하지 않습니다. 그렇지 않았다면 AVAudioConverter가 처리하며, 짧은 클립이 이전 클립에서 프라이밍 아티팩트를 가져오지 않도록 컨버터는 호출마다 상태가 없는 것으로 취급됩니다.

이를 둘러싼 컨디셔닝 체인의 순서는 DC 오프셋 제거, 필터와 음량 제어 적용, 그다음 리샘플링입니다. 레이트를 바꾸기 전에 필터링하는 것이 올바른 순서입니다. 하이패스 차단 주파수는 Hz로 지정되고 필터 계수는 필터가 동작하는 샘플링 레이트에 따라 달라지기 때문입니다.

그냥 48 kHz로 녹음하고 나중에 변환하면 안 되나요?

그렇게 할 수 있고, 많은 파이프라인이 그렇게 합니다. 캡처 계층에서 모델의 레이트를 요청하는 것은 세 가지 면에서 더 저렴합니다. 버퍼가 필요 이상으로 3배 커지지 않고, 일반적인 경로에서는 음성 활동 감지기 앞에 변환이 필요 없으며, 실제로 일어나는 변환도 앱이 반복해서 하는 것이 아니라 오디오 드라이버가 한 번만 수행합니다.

대가는 자체 컨버터가 아니라 Core Audio의 컨버터를 신뢰한다는 점입니다. 우리는 이 선택에 만족합니다. 드라이버 수준의 샘플링 레이트 컨버터는 충분히 검증된 코드이고, 대안은 Apple이 이미 해결한 문제를 위해 우리 것을 직접 유지보수하는 것이기 때문입니다.

사용자에게 의미하는 것

거의 없습니다. 그것이 요점입니다. 레이트 변환은 조정 손잡이가 아니라 정확성의 문제입니다. 제대로 하면 보이지 않고, 잘못하면 모델 크기를 아무리 키워도 고쳐지지 않는, 자음이 미묘하게 틀린 변환 결과로 나타납니다.

비슷한 것을 만든다면, 대역 제한 컨버터로 변환하고, 한 번만 하며, 필터링 전이 아니라 후에 하세요.

관련 글: 음성 활동 감지 · 기술 개요