오디오 위치 속성

오디오 드라이버의 클라이언트는 KSPROPERTY_AUDIO_POSITION 속성을 사용하여 오디오 스트림에서 현재 위치를 가져와서 설정합니다. 속성은 KSAUDIO_POSITION 구조를 사용하여 현재 위치를 설명합니다. 구조체에는 PlayOffset 및 WriteOffset 의 두 멤버 가 포함됩니다.

PlayOffsetWriteOffset 멤버는 현재 오디오 디바이스의 전용 사용을 위해 예약된 클라이언트 버퍼 영역의 경계를 정의합니다. 클라이언트는 디바이스가 현재 이 지역에 포함된 데이터에 액세스할 수 있다고 가정해야 합니다. 따라서 클라이언트는 이 지역 외부에 있는 버퍼의 일부만 액세스해야 합니다. 스트림이 진행되면서 영역의 경계가 이동합니다.

클라이언트 버퍼가 루프되면(즉, 스트림 유형이 KSINTERFACE_STANDARD_LOOPED_STREAMING), PlayOffsetWriteOffset 은 버퍼 상대 오프셋입니다. 즉, 루프된 클라이언트 버퍼의 시작부터 바이트 오프셋으로 지정됩니다. 두 오프셋이 버퍼의 끝으로 증가하면 버퍼의 시작 부분에 래핑됩니다. (버퍼의 시작 부분에 있는 오프셋은 0입니다.) 따라서 두 오프셋 모두 버퍼 크기를 초과하지 않습니다.

클라이언트 버퍼가 없는 경우(즉, 스트림 유형이 KSINTERFACE_STANDARD_STREAMING), PlayOffsetWriteOffset 은 스트림 상대 오프셋입니다. 즉, 스트림 시작부터 바이트 오프셋으로 지정됩니다. 이러한 오프셋은 전체 스트림을 포함하고 처음부터 끝까지 연속되는 이상적인 버퍼에 대한 오프셋으로 간주될 수 있습니다.

렌더링 스트림의 경우 PlayOffset 멤버는 스트림의 재생 위치를 지정하고 WriteOffset 멤버는 스트림의 쓰기 위치를 지정합니다. 다음 그림에서는 클라이언트 버퍼의 재생 및 쓰기 위치를 보여 줍니다.

렌더링 스트림의 재생 및 쓰기 위치를 보여 주는 다이어그램

재생 위치는 현재 재생 중인 샘플의 바이트 오프셋입니다(즉, 디지털-아날로그 변환기 또는 DAC의 입력에 래치되는 샘플). 쓰기 위치는 클라이언트가 버퍼에 안전하게 쓸 수 있는 위치입니다. 스트림이 재생되면 이전 그림에서 재생 및 쓰기 위치가 왼쪽에서 오른쪽으로 이동합니다. 클라이언트의 쓰기는 쓰기 위치보다 앞서야 합니다. 또한 버퍼가 반복되면 클라이언트의 쓰기가 재생 위치를 추월해서는 안 됩니다.

WaveCyclic 또는 WavePci 포트 드라이버는 미니포트 드라이버를 사용하여 재생 위치를 추적하지만 포트 드라이버는 쓰기 위치를 추적합니다. WaveCyclic 및 WavePci 포트 드라이버는 다음과 같이 쓰기 위치를 업데이트합니다.

  • WaveCyclic

    WaveCyclic 포트 드라이버가 IDmaChannel::CopyTo 를 호출하여 새 데이터 블록을 클라이언트 버퍼의 순환 버퍼에 복사할 때마다 쓰기 위치는 데이터 블록의 마지막 바이트 위치(클라이언트 버퍼)로 이동합니다.

  • WavePci

    기본적으로 WavePci 미니포트 드라이버가 IPortWavePciStream::GetMapping 을 호출하여 새 매핑(클라이언트 버퍼의 일부)을 획득하고 호출이 성공할 때마다 쓰기 위치는 새 매핑에서 마지막 바이트의 위치(클라이언트 버퍼)로 이동합니다.

    WavePci 미니포트 드라이버가 포트 드라이버에 대한 프리페치 오프셋을 지정하여 기본 동작을 재정의하는 경우 현재 쓰기 위치는 항상 현재 재생 위치 및 프리페치 오프셋의 합계와 같습니다. 자세한 내용은 오프셋 프리페치를 참조하세요.

캡처 스트림의 경우 PlayOffset 멤버는 스트림의 레코드 위치를 지정하고 WriteOffset 멤버는 스트림의 읽기 위치를 지정합니다. 다음 그림에서는 클라이언트 버퍼의 레코드 및 읽기 위치를 보여 줍니다.

캡처 스트림의 레코드 및 읽기 위치를 보여 주는 다이어그램

레코드 위치는 아날로그-디지털 변환기 또는 ADC의 출력에서 래치할 최신 샘플의 바이트 오프셋입니다. (이 위치는 오디오 디바이스의 DMA 엔진이 결국 샘플을 작성할 버퍼 위치를 지정합니다.) 읽기 위치는 클라이언트가 버퍼에서 안전하게 읽을 수 없는 위치입니다. 스트림의 기록이 진행되면 이전 그림에서 읽기 및 레코드 위치가 왼쪽에서 오른쪽으로 이동합니다. 클라이언트의 읽기는 읽기 위치를 추적해야 합니다. 또한 버퍼가 반복되면 클라이언트의 읽기가 레코드 위치보다 앞서 있어야 합니다.

WaveCyclic 또는 WavePci 포트 드라이버는 미니포트 드라이버를 사용하여 레코드 위치를 추적하지만 포트 드라이버는 읽기 위치를 추적합니다. WaveCyclic 및 WavePci 포트 드라이버는 다음과 같이 읽기 위치를 업데이트합니다.

  • WaveCyclic

    WaveCyclic 포트 드라이버가 IDmaChannel::CopyFrom 을 호출하여 순환 버퍼(클라이언트 버퍼)에서 새 데이터 블록을 복사할 때마다 읽기 위치는 데이터 블록의 마지막 바이트 위치(클라이언트 버퍼)로 이동합니다.

  • WavePci

    WavePci 미니포트 드라이버가 IPortWavePciStream::ReleaseMapping 을 호출하여 이전에 획득한 매핑(클라이언트 버퍼의 일부)을 해제할 때마다 읽기 위치는 릴리스된 매핑에서 마지막 바이트의 위치(클라이언트 버퍼)로 이동합니다.

미니포트 드라이버는 KSPROPERTY_AUDIO_POSITION 속성 요청에 대한 처리기 루틴을 구현할 필요가 없습니다. 대신 WaveCyclic 및 WavePci 포트 드라이버는 미니포트 드라이버를 대신하여 이러한 요청을 처리합니다. get-property 요청을 처리할 때 WaveCyclic 또는 WavePci 포트 드라이버에는 WriteOffset 값을 계산하는 데 필요한 모든 정보가 이미 있지만 PlayOffset 값을 계산하려면 미니포트 드라이버의 정보가 여전히 필요합니다. 이 정보를 얻기 위해 포트 드라이버는 미니포트 드라이버의 IMiniportWaveCyclicStream::GetPosition 또는 IMiniportWavePciStream::GetPosition 메서드를 호출합니다.

렌더링 스트림의 경우 GetPosition 메서드는 현재 DAC를 통해 재생 중인 샘플의 바이트 오프셋인 재생 위치를 검색합니다. 캡처 스트림의 경우 GetPosition 메서드는 ADC에서 캡처할 최신 샘플의 바이트 오프셋인 레코드 위치를 검색합니다.

GetPosition 호출에 의해 검색된 오프셋 값은 현재 스피커 잭을 통해 전송되는 신호에 해당하는 재생 위치이거나 마이크 잭을 통해 수신되는 신호에 해당하는 레코드 위치입니다. DMA 위치가 아닙니다. (DMA 위치는 오디오 디바이스의 DMA 엔진이 현재 DMA 버퍼로 또는 DMA 버퍼에서 전송 중인 샘플의 바이트 오프셋입니다.)

일부 오디오 하드웨어에는 현재 각 DAC 또는 ADC에 있는 샘플의 바이트 오프셋을 추적하는 위치 레지스터가 포함되어 있습니다. 이 경우 GetPosition 메서드는 적절한 스트림에 대한 위치 레지스터의 내용을 검색하기만 하면 됩니다. 다른 오디오 하드웨어는 드라이버에 DMA 위치만 제공할 수 있습니다. 이 경우 GetPosition 메서드는 현재 DMA 위치와 디바이스 내부의 버퍼링 지연을 고려하여 DAC 또는 ADC에서 샘플의 바이트 오프셋을 가장 잘 예측해야 합니다.

WaveCyclic 또는 WavePci 포트 드라이버의 속성 처리기는 스트림 상대 바이트 오프셋 또는 버퍼 상대 바이트 오프셋을 제공할지 여부를 결정하기 위해 루프 버퍼와 비루프 버퍼를 구분해야 하지만 이 세부 정보(즉, 버퍼가 루프 또는 비루프인지 여부)는 미니포트 드라이버에 투명합니다.

IMiniportWaveCyclicStream::GetPosition 메서드는 클라이언트 버퍼가 루프 또는 비루프인지에 관계없이 항상 버퍼 상대 재생 또는 레코드 위치를 보고합니다. 클라이언트 버퍼가 루프되면 속성 처리기는 미니포트 드라이버에서 보고한 버퍼 상대 위치를 순환 버퍼로 오프셋으로 표현된 클라이언트 버퍼로 변환합니다. 그러면 처리기가 PlayOffset 멤버에 씁니다. 클라이언트 버퍼가 없는 경우 속성 처리기는 PlayOffset 멤버에 쓰기 전에 버퍼 상대 재생 위치를 스트림 상대 플레이 위치로 변환합니다.

IMiniportWavePciStream::GetPosition 메서드는 클라이언트 버퍼가 루프 또는 비루프인지에 관계없이 항상 스트림 상대 재생 또는 레코드 위치를 보고합니다. 클라이언트 버퍼가 루프되면 속성 처리기는 속성 요청의 KSAUDIO_POSITION 구조에서 PlayOffset 멤버에 쓰기 전에 스트림 상대 플레이 위치를 버퍼 상대 플레이 위치(클라이언트 버퍼에 오프셋으로 표시됨)로 변환합니다. 클라이언트 버퍼가 없는 경우 속성 처리기는 PlayOffset 멤버에 스트림 상대 위치를 씁니다.

재생 또는 레코드 위치는 스트림 초기화 직후 0입니다. KSSTATE_STOP 상태로 전환하면( KSSTATE 참조) 위치가 0으로 다시 설정됩니다. 스트림이 KSSTATE_RUN KSSTATE_PAUSE 또는 KSSTATE_ACQUIRE 전환하여 중지되면 위치가 중지됩니다. 스트림이 KSSTATE_PAUSE 또는 KSSTATE_ACQUIRE 다시 KSSTATE_RUN 전환되면 고정되지 않습니다.

WaveCyclic 및 WavePci 미니포트 드라이버에 대한 GetPosition 메서드 구현의 예는 WDK(Windows 드라이버 키트)의 샘플 오디오 드라이버를 참조하세요.