DirectPlay DirectPlay Voice 음성 클라이언트 메시지의 처리 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
여기에서는, Microsoft® DirectPlay® 음성 세션의 클라이언트의 메시지를 처리하는 방법에 대해 설명한다. 호스트 관련의 메시징의 설명에 대해서는, 「음성 호스트 메시지의 처리」를 참조할것. 메시징의 전반적인 내용에 대해서는, 「DirectPlay 메시징의 처리」를 참조할것.
DirectPlay Voice 로 사용되는 많은 메시지는, DirectPlay 코어 애플리케이션 프로그래밍 인터페이스 (API)로 사용되는 것과 유사하다. 그러나, 유사한 코어 메시지와 Voice 메시지여도, 사용법이 다른 경우가 있다.
예를 들어, 코어 세션 또는 음성 세션에 접속 하면, DirectPlay 는 접속 시행의 결과가 포함된 완료 메시지를 돌려준다. 코어 세션에서는, 동기적으로 접속하는 경우에서도, 상황에 따라서는 DPN_MSGID_CONNECT_COMPLETE 완료 메시지를 수신하는 일이 있다. 그러나, DirectPlay Voice 에서는, 동기적으로 음성 세션에 접속하려고 하는 경우, 완료 메시지를 수신할 것은 없다. 비동기에게 음성 세션에 접속하는 경우만,DVMSGID_CONNECTRESULT 완료 메시지를 수신한다.
코어 메시지와 음성 메시지의 처리로 크게 다른 점의 1 개는, 코어 메시지 핸들러는 모든 코어 메시지를 수신하는 것이다. DirectPlay Voice 에는,IDirectPlayVoiceClient::SetNotifyMask 를 호출해, 수신하고 싶은 메시지의 리스트를 지정하는 옵션이 있다. pdwMessageMask 파라미터를 통해서 이 메서드에 건네주는, 통지 리스트에 있는 메시지만이 수신된다. 이 리스트에는, 적어도 1 개의 메시지가 포함되어 있을 필요가 있다. IDirectPlayVoiceClient::SetNotifyMask 를 사용해, 모든 DirectPlay Voice 메시지를 무효로 하는 것은 할 수 없다.
DirectPlay Voice 는, 보통의 DirectPlay 세션에 대한 추가의 옵션이다. 이것에 의해, 세션의 멤버간의 음성 통신이 가능하게 된다. 음성 세션의 클라이언트가 되려면 , 적절한 DirectPlay 개체를 생성 해, 보통의 피어 투 피어 또는 클라이언트/서버 세션에 접속하고 있을 필요가 있다. 더 자세한 정보는, 「피어 투 피어 세션」또는 「클라이언트/서버 세션」을 참조할것.
모든 음성 세션에는, 호스트가 필요하다. 피어 투 피어 세션의 경우는, 멤버의 1 명이 음성 세션의 호스트로서 선택되고 있을 필요가 있다. 음성 호스트는, 코어 세션의 호스트가 되고 있는 멤버와 같은 필요는 없다. 클라이언트/서버 세션의 경우, 서버는 음성 세션과 코어 세션의 호스트가 될 필요가 있다. 세션 호스트가 결정하면 호스트는 음성 서버 개체를 생성 해,IDirectPlayVoiceServer::StartSession 를 호출해, 음성 세션을 시작 할 필요가 있다. 세션이 시작 되면 클라이언트는 접속할 수 있다.
여기에서는, 음성 클라이언트가 세션에 참가할 경우에 수신할 수 있는 메시지의 개요를 나타낸다.
세션이 설정되면 클라이언트는 IDirectPlayVoiceClient::Connect 를 호출해, 음성 세션에 접속할 필요가 있다. 이 메서드를 비동기에게 호출해, 메서드가 DV_PENDING 를 돌려주는 경우, 접속 시행의 결과가 포함된 DVMSGID_CONNECTRESULT 메시지를 수신한다. 이 메시지는,IDirectPlayVoiceClient::Connect 가 DV_PENDING 를 돌려주기 전 또는 후에 도착한다. 동기적으로 이 메서드를 호출하는 경우,DVMSGID_CONNECTRESULT 메시지는 수신하지 않는다. 동기 접속의 시행 결과는, 메서드의 반환값에 의해 나타난다.
음성 클라이언트는, 피어 투 피어 음성 세션의 멤버인 경우만, 이 메시지를 수신한다. 접속해 DVMSGID_CONNECTRESULT 를 처리한 후는, 자신과 음성 세션의 멤버 마다,DVMSGID_CREATEVOICEPLAYER 메시지를 수신한다. 이 메시지에 부속되는 구조체에는, 세션중에 player를 식별하기 위해서 사용하는 DVID 값이 포함되어 있다. 이 구조체의 dwFlags 멤버에는, player를 나타내는 2 개의 플래그가 포함되어 있다. player가 로컬 player의 경우, DVPLAYERCAPS_LOCAL 플래그가 설정된다. player가 반이중의 경우, DVPLAYERCAPS_HALFDUPLEX 플래그가 설정된다.
player의 음성 세션 player값을 생성 하는 경우는, 이 메시지를 처리할 경우에 실시할 필요가 있다. player 문맥값의 더 자세한 정보는, 「player 문맥값의 사용법」을 참조할것. 해당하는 DVMSGID_CREATEVOICEPLAYER 메시지를 처리할 때까지는, player는 대응하는 메시지를 수신하지 않는다.
정상적으로 접속한 후는, 음성 세션중에 수많은 메시지를 수신한다. 수신할 가능성이 있는 메시지는, 피어 투 피어 세션이나 클라이언트/서버 세션 등에 의해서 다르다. 원칙으로서 클라이언트/서버 음성 세션의 음성 클라이언트는, 특정의 player에 관련된 메시지를 수신하지 않는다.
다음의 메시지는, 음성 세션의 양쪽 모두의 종류의 클라이언트가 수신한다.
이러한 메시지에 의해, 캡춰 포커스가 있을지 어떨지라고 오디오를 캡춰 하고 있을지 어떨지를 알 수 있다. 체프체포카스를 취득해 오디오 캡춰를 시작 하면,DVMSGID_GAINFOCUS 메시지를 수신한다. 체프체포카스를 잃어, 오디오 캡춰가 정지 하면,DVMSGID_LOSTFOCUS 메시지를 수신한다. 양쪽 모두의 메시지는 간단한 통지이며, 관련하는 구조체는 없다. 캡춰 포커스의 더 자세한 정보는, 「캡춰 포커스」 및 「DirectPlay 와 DirectPlay Voice 에 있어서의 콜백 함수의 처리」을 참조할것.
이러한 메시지는, 로컬 player가 전송을 실행하고 있는 것을 통지한다. 전송이 시작 하면 DVMSGID_RECORDSTART 메시지를 수신해, 전송이 종료 하면 DVMSGID_RECORDSTOP 를 수신한다. 이러한 메시지에 부속되는 구조체에는, 로컬 player의 Voice player 문맥값이 포함되어 있다. 전송의 시작과 정지가 발생하는 원인은, 푸쉬 투 토크 또는 음성 기동에 의한 전송 제어를 사용하고 있을까하고, 애플리케이션이 오디오 캡춰 포커스를 취득했는지 잃었는지를 따라 다르다.
가장 간단한 케이스는, 오디오 캡춰의 포커스가 변경되지 않는 경우이다. 이 경우, 사용자의 음성이, 액티브하게 하고 귀의값을 넘었을 때에, 음성 기동에 의한 전송이 시작 한다. 이 전송은, 음성이 해 귀의값을 밑돌았을 때에 정지한다. 푸쉬 투 토크 전송에서는, 보통, 사용자가 버튼을 눌러 떼어 놓는 것으로, 전송은 수동으로 시작 해, 정지한다.
player의 음성이, 액티브하게 되고 귀의값을 넘는지,[푸쉬 투 토크] 를 눌렀을 경우에서도, 애플리케이션이 전송을 실행하기 위해서는 캡춰 포커스가 필요하다. player가 이야기하고 있지만, 애플리케이션에 오디오 캡춰 포커스가 없는 경우, 애플리케이션이 오디오 캡춰 포커스를 취득하지 않으면 전송은 시작 되지 않는다. 이 때,DVMSGID_GAINFOCUS 메시지를 수신해, 계속되어 DVMSGID_RECORDSTART 메시지를 수신한다. player가 이야기하고 있을 때 오디오 캡춰 포커스가 없어지면DVMSGID_LOSTFOCUS 메시지를 수신해, 계속되어 DVMSGID_RECORDSTOP 메시지를 수신한다. 오디오 캡춰 포커스를 취득해, player가 아직 이야기하고 있는 경우, 전송은 한번 더 시작 된다.
보통, 전송이 정지 하면, 그 이유 (와)는 관계없는 것으로 DVMSGID_RECORDSTOP 메시지를 수신한다. 그러나, 전송중에 음성 세션으로부터 접속을 해제 하면,DVMSGID_RECORDSTOP 메시지의 수신은 보증되지 않는다.
캡춰 포커스의 더 자세한 정보는, 「캡춰 포커스」를 참조할것. 전송 제어의 더 자세한 정보는, 「전송 제어」를 참조할것.
DVMSGID_INPUTLEVEL 메시지는, player의 마이크로부터의 현재의 음성 입력 레벨을 나타낸다. DVMSGID_OUTPUTLEVEL 메시지는, player의 스피커 또는 헤드폰으로부터의 현재의 음성 입력 레벨을 나타낸다. 이러한 메시지는, 주기적으로 송신된다. 또,DVMSGID_RECORDSTART 메시지를 처리한 후에 시작 되어 대응하는 DVMSGID_RECORDSTOP 메시지를 처리 하면 정지한다. 메시지의 송신 간격을 지정하려면 ,DVCLIENTCONFIG 구조체의 dwNotifyPeriod 멤버에, 적절한 간격을 설정한다. 메시지를 송신하지 않게 하려면 ,dwNotifyPeriod 에 0 을 설정한다.
다음의 메시지는, 피어 투 피어 음성 세션의 클라이언트가 수신한다.
음성 세션에 player가 추가될 때마다,DVMSGID_CREATEVOICEPLAYER 메시지를 수신한다. 이 메시지는, 세션에 접속했을 때에 수신한 player의 생성 메시지와 같은 방법으로 처리할 필요가 있다. player가 음성 세션을 빠지면DVMSGID_DELETEVOICEPLAYER 메시지를 수신한다. DVMSGID_CREATEVOICEPLAYER 메시지 마다,DVMSGID_DELETEVOICEPLAYER 메시지를 수신한다. DVMSGID_DELETEVOICEPLAYER 메시지를 처리한 후는, 그 player의 메시지를 수신하지 않게 된다.
음성 타겟의 일람이 변경되면DVMSGID_SETTARGETS 메시지를 수신한다. 이 메시지는, 음성 클라이언트가 IDirectPlayVoiceClient::SetTransmitTargets 를 호출하는지, 음성 호스트가 IDirectPlayVoiceServer::SetTransmitTargets 를 호출하면, 언제라도 생성된다.
player로부터 전송을 수신하기 시작하면DVMSGID_PLAYERVOICESTART 메시지가 송신된다. 레벨 통지를 유효하게 하고 있는 경우,DVMSGID_PLAYEROUTPUTLEVEL 메시지의 수신을 시작 한다. player의 전송이 정지 하면,DVMSGID_PLAYERVOICESTOP 메시지가 송신된다. 이 메시지를 처리 하면,DVMSGID_PLAYEROUTPUTLEVEL 메시지는 정지한다. 오디오 캡춰 포커스가 변경되었을 경우, 기본적으로 DVMSGID_RECORDSTART 및 DVMSGID_RECORDSTOP 와 같은 방법으로, 이러한 메시지가 처리된다. 해당하는 DVMSGID_CREATEVOICEPLAYER 메시지를 처리할 때까지, player에 관련하는 이러한 메시지는 수신되지 않는다.
DVMSGID_PLAYEROUTPUTLEVEL 는, 특정의 player의 송신에 대해서, player의 스피커 또는 헤드폰의 현재의 음성 출력 레벨을 나타낸다. 이러한 메시지는, 주기적으로 송신된다. 또,DVMSGID_RECORDSTART 메시지를 처리한 후에 시작 되어 대응하는 DVMSGID_RECORDSTOP 메시지를 처리 하면 정지한다. 메시지의 송신 간격을 지정하려면 ,DVCLIENTCONFIG 구조체의 dwNotifyPeriod 멤버에, 적절한 간격을 설정한다. 메시지를 송신하지 않게 하려면 ,dwNotifyPeriod 에 0 을 설정한다.
음성 호스트가 처리 하면,DVMSGID_LOCALHOSTSETUP 메시지가 새로운 음성 호스트에게 송신된다. 이 메시지에 의해, 새로운 음성 호스트는, 새로운 음성 서버 개체를 생성 할 경우에 사용되는 콜백 함수와 문맥값을 설정한다. 애플리케이션이 이 메시지의 처리로부터 돌아오면DVMSGID_HOSTMIGRATED 메시지를 수신한다.
호스트가 처리 하면, 음성 세션의 다른 모든 멤버에 DVMSGID_HOSTMIGRATED 메시지가 송신된다. 관련하는 구조체에는, 새로운 음성 호스트의 DVID 가 포함된다. 호스트가 처리 하면, DirectPlay Voice 는 자동적으로 새로운 음성 서버 개체를 생성 한다. 애플리케이션이 새로운 음성 호스트인 경우,DVMSGID_HOSTMIGRATED 메시지의 구조체에, 음성 서버의 IDirectPlayVoiceServer 인터페이스의 포인터도 포함된다. 이 인터페이스를 사용하는 경우, 인터페이스의 AddRef 메서드를 호출해, 인터페이스의 참조 카운트를 인크리먼트(increment) 할 필요가 있다. IDirectPlayVoiceServer 로 AddRef 를 호출했을 경우, 인터페이스의 조작을 종료했을 때에, 반드시 Release 를 호출할 필요가 있다.
IDirectPlayVoiceClient::Disconnect 를 호출해, 음성 세션에의 접속을 해제한다. 이 메서드를 비동기에게 호출해, 메서드가 DV_PENDING 를 돌려주는 경우, 결과를 알리는 DVMSGID_DISCONNECTRESULT 메시지를 수신한다. 이 메시지는,IDirectPlayVoiceClient::Disconnect 가 돌아오기 전 또는 후에 도착한다. 동기적으로 IDirectPlayVoiceClient::Disconnect 를 호출하는 경우,DVMSGID_DISCONNECTRESULT 메시지는 송신되지 않는다. 동기 접속 해제의 시행 결과는, 메서드의 반환값에 의해 나타난다.
피어 투 피어 음성 세션에서는, 클라이언트는 DVMSGID_DISCONNECTRESULT 를 받기 전에, 세션의 모든 player의 DVMSGID_DELETEVOICEPLAYER 를 수신한다.
회복 불가능한 에러로 세션이 예기 하지 않고 종료했을 경우, 클라이언트는 DVMSGID_SESSIONLOST 메시지를 수신한다. 실패의 이유는, 관련하는 구조체의 hrResult 멤버로 지정되고 있다.
피어 투 피어 음성 세션에서는, 클라이언트는 DVMSGID_SESSIONLOST 를 받기 전에, 세션의 모든 player의 DVMSGID_DELETEVOICEPLAYER 를 수신한다.
피어 투 피어 세션에서는,IDirectPlayVoiceClient::Disconnect 를 호출하는지, 세션이 없어지리라고는 관계없이, 접속을 해제했을 때에, 음성 세션의 다른 모든 player의 DVMSGID_DELETEVOICEPLAYER 메시지를 수신한다. 이것에 의해, 수신하는 모든 DVMSGID_CREATEVOICEPLAYER 에는 대응하는 DVMSGID_DELETEVOICEPLAYER 메시지가 있게 된다. 접속 해제가 완료하기까지, 모든 DVMSGID_DELETEVOICEPLAYER 를 수신한다.