클록 동기화
웨이브 싱크에서 수행해야 할 중요한 작업은 참조 클록과 샘플 클록 결정 간에 시간 드리프트를 resolve 것입니다. 위상 잠금 루프에 해당하는 소프트웨어로 이 작업을 수행합니다.
웨이브 싱크는 다음에 쓸 수 있는 버퍼의 샘플 번호를 추적합니다. 따라서 샘플 20과 같이 켜져 있다는 것을 알고 있더라도 웨이브 싱크는 여전히 참조 시간을 얻기 위해 master 클록을 검사 합니다. 약 20밀리초마다 절전 모드를 해제하고 현재 시간 동안 master 클록을 요청하는 스레드가 있습니다. 예를 들어 master 클록은 현재 시간(밀리초)이 420이라는 것을 다시 보고할 수 있습니다.
또한 웨이브 싱크는 master 클록과 샘플 시간에 따라 현재 시간 사이의 오프셋을 보여 주는 대기 시간 클록을 유지합니다. 이 정보를 사용하여 예상되는 master 클록 시간을 계산하고 이를 실제 master 클록 읽기와 비교하여 두 시계가 떨어져 있는지 확인합니다.
웨이브 싱크는 위상 잠금 루프를 사용하여 샘플 시간을 조정합니다. 드리프트를 확인할 때 판독값에 약간의 지터가 포함되어 있기 때문에 웨이브 싱크가 전체 양만큼 조정되지 않습니다. 대신 샘플 클록을 master 클록을 향해 거리의 일부분만큼 이동합니다. 이러한 방식으로 웨이브 싱크는 대략 동기화 상태를 유지하면서 지터 오류를 부드럽게 합니다. 또한 이 시간이 소요되고 master 클록을 기준으로 하는 대기 시간 클록 시간으로 변환합니다. 이는 애플리케이션이 어느 시점에서 신시사이저가 렌더링되는 위치를 알아야 할 수도 있기 때문에 중요합니다.
대기 시간 클록은 새 노트를 재생하도록 예약할 수 있는 가장 빠른 시간을 애플리케이션에 알려줍니다. 대기 시간 클록 시간은 master 클록 시간과 신시사이저의 대기 시간을 나타내는 오프셋입니다. 이 대기 시간은 애플리케이션이 새 메모를 제출하여 신시사이저가 실제로 노트를 재생하는 시간까지의 최소 지연 시간을 나타냅니다. 언제든지 애플리케이션은 현재 대기 시간 클록 시간보다 빠르지 않은 이상에서 재생되도록 메모를 예약할 수 있습니다.
예를 들어 master 클록이 현재 시간 420이고 애플리케이션에 가능한 한 빨리 재생하려는 메모가 있는 경우 대기 시간 클록은 노트를 재생할 수 있는 가장 빠른 시간을 알려줍니다. 소프트웨어 신시사이저의 대기 시간이 100밀리초인 경우 다음에 메모를 재생할 수 있는 시간은 520입니다.
이벤트가 참조 시간 520에 재생되도록 표시되어 있다고 가정합니다. 신시사이저는 노트를 샘플로 렌더링하고 샘플 시간에 모든 계산을 수행하여 작업을 수행합니다. 따라서 샘플 시간에 520의 참조 시간이 로 변환되는 것을 알아야 합니다. 사용자 모드에서 웨이브 싱크는 신디사이저에서 사용하는 두 가지 함수를 제공합니다.
IDirectMusicSynthSink::SampleToRefTime 및 IDirectMusicSynthSink::RefTimeToSample**
이 경우 변환을 수행하려면 synth는 웨이브 싱크에서 IDirectMusicSynthSink::RefTimeToSample 을 호출합니다.
그런 다음 웨이브 싱크는 샘플 시간(예: 600)을 다시 제공합니다. 문제의 메모는 샘플 시간 600에 렌더링됩니다. 그런 다음, synth IDirectMusicSynth::Render 메서드가 웨이브 싱크에 의해 호출되어 스트림의 다음 부분(예: 샘플 시간 600에서 800까지)을 렌더링하면 샘플 시간 600에 메모가 버퍼로 렌더링됩니다.
참고 샘플 시간은 롤오버를 방지하기 위해 64비트 숫자로 유지됩니다. (DWORD 값은 27시간 후에 롤오버됩니다.)
요약하자면, 신디사이저는 샘플 시간에 모든 내부 수학을 수행하고 웨이브 싱크는 참조 시간에서 샘플 시간으로 변환을 수행하고 그 반대의 경우도 마찬가지입니다. 또한 웨이브 싱크는 master 클록과의 동기화를 관리하고 대기 시간 정보를 제공합니다. 웨이브 싱크에서 이 기능을 숨기면 신디사이저를 더 쉽게 작성할 수 있습니다.