windows-nt/Source/XPSP1/NT/enduser/netmeeting/ui/conf/nmchannelaudio.cpp
2020-09-26 16:20:57 +08:00

416 lines
8.7 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "precomp.h"
// NetMeeting gunk
#include "confroom.h"
// Netmeeting SDK stuff
#include "NmEnum.h"
#include "SDKInternal.h"
#include "NmConference.h"
#include "NmChannel.h"
#include "NmChannelAudio.h"
CNmChannelAudioObj::CNmChannelAudioObj()
{
DBGENTRY(CNmChannelAudioObj::CNmChannelAudioObj);
DBGEXIT(CNmChannelAudioObj::CNmChannelAudioObj);
}
CNmChannelAudioObj::~CNmChannelAudioObj()
{
DBGENTRY(CNmChannelAudioObj::~CNmChannelAudioObj);
DBGEXIT(CNmChannelAudioObj::~CNmChannelAudioObj);
}
//
HRESULT CNmChannelAudioObj::CreateInstance(CNmConferenceObj* pConfObj, INmChannel** ppChannel, bool bIsIncoming)
{
DBGENTRY(CNmChannelAudioObj::CreateInstance);
HRESULT hr = S_OK;
typedef CNmChannel<CNmChannelAudioObj, &IID_INmChannelAudio, NMCH_AUDIO> channel_type;
channel_type* p = NULL;
p = new CComObject<channel_type>(NULL);
if (p != NULL)
{
if(ppChannel)
{
p->SetVoid(NULL);
hr = p->QueryInterface(IID_INmChannel, reinterpret_cast<void**>(ppChannel));
if(SUCCEEDED(hr))
{
// We don't have to RefCount this because our lifetime is
// contained in the CConf's lifetime
p->m_pConfObj = pConfObj;
p->m_bIsIncoming = bIsIncoming;
}
if(FAILED(hr))
{
delete p;
*ppChannel = NULL;
}
}
else
{
hr = E_POINTER;
}
}
else
{
hr = E_OUTOFMEMORY;
}
DBGEXIT_HR(CNmChannelAudioObj::CreateInstance,hr);
return hr;
}
///////////////////////////////////////////////////////////////////////////////////
// INmChannelAudio2 methods
///////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CNmChannelAudioObj::IsIncoming(void)
{
DBGENTRY(CNmChannelAudioObj::IsIncoming);
HRESULT hr = E_UNEXPECTED;
hr = m_bIsIncoming ? S_OK : S_FALSE;
DBGEXIT_HR(CNmChannelAudioObj::IsIncoming,hr);
return hr;
}
STDMETHODIMP CNmChannelAudioObj::GetState(NM_AUDIO_STATE *puState)
{
DBGENTRY(CNmChannelAudioObj::GetState);
HRESULT hr = E_POINTER;
if(puState)
{
hr = S_OK;
*puState = NM_AUDIO_IDLE;
if(S_OK == _IsActive())
{
if( ((S_OK == IsIncoming()) && IsSpeakerMuted()) || ((S_FALSE == IsIncoming()) && IsMicMuted()))
{
*puState = NM_AUDIO_LOCAL_PAUSED;
}
else
{
*puState = NM_AUDIO_TRANSFERRING;
}
}
}
DBGEXIT_HR(CNmChannelAudioObj::GetState,hr);
return hr;
}
STDMETHODIMP CNmChannelAudioObj::GetProperty(NM_AUDPROP uID,ULONG_PTR *puValue)
{
DBGENTRY(CNmChannelAudioObj::GetProperty);
HRESULT hr = E_POINTER;
if(puValue)
{
hr = E_FAIL;
if(IsChannelValid())
{
switch(uID)
{
case NM_AUDPROP_LEVEL:
{
HRESULT hIncoming = IsIncoming();
if(S_OK == hIncoming)
{ // This is the receive channel
*puValue = GetSpeakerVolume();
hr = S_OK;
}
else if(S_FALSE == hIncoming)
{ // This is the send channel
*puValue = GetRecorderVolume();
hr = S_OK;
}
break;
}
case NM_AUDPROP_PAUSE:
{
HRESULT hIncoming = IsIncoming();
if(S_OK == hIncoming)
{ // This is the receive channel
*puValue = IsSpeakerMuted() ? 1 : 0;
hr = S_OK;
}
else if(S_FALSE == hIncoming)
{ // This is the send channel
*puValue = IsMicMuted() ? 1 : 0;
hr = S_OK;
}
break;
}
default:
hr = E_INVALIDARG;
break;
}
}
}
DBGEXIT_HR(CNmChannelAudioObj::GetProperty,hr);
return hr;
}
STDMETHODIMP CNmChannelAudioObj::SetProperty(NM_AUDPROP uID,ULONG_PTR uValue)
{
DBGENTRY(CNmChannelAudioObj::SetProperty);
HRESULT hr = E_FAIL;
if(IsChannelValid())
{
switch(uID)
{
case NM_AUDPROP_LEVEL:
{
hr = E_INVALIDARG;
if(uValue < NM_MAX_AUDIO_LEVEL)
{
HRESULT hIncoming = IsIncoming();
if(S_OK == hIncoming)
{ // This is the receive channel
SetSpeakerVolume((ULONG)uValue);
hr = S_OK;
}
else if(S_FALSE == hIncoming)
{ // This is the send channel
SetRecorderVolume((ULONG)uValue);
hr = S_OK;
}
}
break;
}
case NM_AUDPROP_PAUSE:
{
HRESULT hIncoming = IsIncoming();
if(S_OK == hIncoming)
{ // This is the receive channel
MuteSpeaker(uValue ? TRUE : FALSE);
hr = S_OK;
}
else if(S_FALSE == hIncoming)
{ // This is the send channel
MuteMicrophone(uValue ? TRUE : FALSE);
hr = S_OK;
}
break;
}
default:
hr = E_INVALIDARG;
break;
}
}
DBGEXIT_HR(CNmChannelAudioObj::SetProperty,hr);
return hr;
}
///////////////////////////////////////////////////////////////////////////////////
//INmChannelAudioNotify
///////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CNmChannelAudioObj::StateChanged(NM_AUDIO_STATE uState)
{
DBGENTRY(CNmChannelAudioObj::StateChanged);
HRESULT hr = S_OK;
Activate(NM_AUDIO_IDLE != uState);
// The internal GetState is a bit funky at times...
GetState(&uState);
hr = Fire_StateChanged(uState);
DBGEXIT_HR(CNmChannelAudioObj::StateChanged,hr);
return hr;
}
STDMETHODIMP CNmChannelAudioObj::PropertyChanged(DWORD dwReserved)
{
DBGENTRY(CNmChannelAudioObj::PropertyChanged);
HRESULT hr = S_OK;
hr = Fire_PropertyChanged(dwReserved);
DBGEXIT_HR(CNmChannelAudioObj::PropertyChanged,hr);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// IInternalChannelObj methods
///////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CNmChannelAudioObj::GetInternalINmChannel(INmChannel** ppChannel)
{
DBGENTRY(CNmChannelAudioObj::GetInternalINmChannel);
HRESULT hr = E_POINTER;
if(ppChannel)
{
*ppChannel = NULL;
hr = S_OK;
}
DBGEXIT_HR(CNmChannelAudioObj::GetInternalINmChannel,hr);
return hr;
}
HRESULT CNmChannelAudioObj::ChannelRemoved()
{
HRESULT hr = S_OK;
RemoveMembers();
CNmConferenceObj* pConfObj = GetConfObj();
if(pConfObj)
{
hr = pConfObj->Fire_ChannelChanged(NM_CHANNEL_REMOVED, com_cast<INmChannel>(GetUnknown()));
}
else
{
ERROR_OUT(("ChannelRemoved, but no ConfObject"));
hr = E_UNEXPECTED;
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////
HRESULT CNmChannelAudioObj::Fire_MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
{
DBGENTRY(CNmChannelAudioObj::Fire_MemberChanged);
HRESULT hr = S_OK;
/////////////////////////////////////////////////////
// INmChannelNotify
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelNotify, CComDynamicUnkArray>* pCP = this;
for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
{
INmChannelNotify* pNotify = reinterpret_cast<INmChannelNotify*>(pCP->m_vec.GetAt(i));
if(pNotify)
{
pNotify->MemberChanged(uNotify, pMember);
}
}
/////////////////////////////////////////////////////
// INmChannelAudioNotify
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelAudioNotify, CComDynamicUnkArray>* pCP2 = this;
for(i = 0; i < pCP2->m_vec.GetSize(); ++i )
{
INmChannelAudioNotify* pNotify2 = reinterpret_cast<INmChannelAudioNotify*>(pCP2->m_vec.GetAt(i));
if(pNotify2)
{
pNotify2->MemberChanged(uNotify, pMember);
}
}
DBGEXIT_HR(CNmChannelAudioObj::Fire_MemberChanged,hr)
return hr;
}
HRESULT CNmChannelAudioObj::Fire_StateChanged(NM_AUDIO_STATE uState)
{
HRESULT hr = S_OK;
/////////////////////////////////////////////////////
// INmChannelAudioNotify
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelAudioNotify, CComDynamicUnkArray>* pCP2 = this;
for(int i = 0; i < pCP2->m_vec.GetSize(); ++i )
{
INmChannelAudioNotify* pNotify2 = reinterpret_cast<INmChannelAudioNotify*>(pCP2->m_vec.GetAt(i));
if(pNotify2)
{
pNotify2->StateChanged(uState);
}
}
DBGEXIT_HR(CNmChannelAudioObj::Fire_MemberChanged,hr)
return hr;
}
HRESULT CNmChannelAudioObj::Fire_PropertyChanged(DWORD dwReserved)
{
HRESULT hr = S_OK;
/////////////////////////////////////////////////////
// INmChannelAudioNotify
/////////////////////////////////////////////////////
IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelAudioNotify, CComDynamicUnkArray>* pCP2 = this;
for(int i = 0; i < pCP2->m_vec.GetSize(); ++i )
{
INmChannelAudioNotify* pNotify2 = reinterpret_cast<INmChannelAudioNotify*>(pCP2->m_vec.GetAt(i));
if(pNotify2)
{
pNotify2->PropertyChanged(dwReserved);
}
}
DBGEXIT_HR(CNmChannelAudioObj::Fire_MemberChanged,hr)
return hr;
}
HRESULT CNmChannelAudioObj::_IsActive()
{
return GetbActive() ? S_OK : S_FALSE;
}
// We don't support switchable AV anymore
HRESULT CNmChannelAudioObj::_SetActive(BOOL bActive)
{
if (GetbActive() == bActive)
return S_OK;
return E_FAIL;
}