Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

424 lines
9.2 KiB

  1. #include "precomp.h"
  2. // NetMeeting gunk
  3. #include "confroom.h"
  4. // Netmeeting SDK stuff
  5. #include "NmEnum.h"
  6. #include "SDKInternal.h"
  7. #include "NmConference.h"
  8. #include "NmChannel.h"
  9. #include "NmChannelAudio.h"
  10. CNmChannelAudioObj::CNmChannelAudioObj()
  11. {
  12. DBGENTRY(CNmChannelAudioObj::CNmChannelAudioObj);
  13. DBGEXIT(CNmChannelAudioObj::CNmChannelAudioObj);
  14. }
  15. CNmChannelAudioObj::~CNmChannelAudioObj()
  16. {
  17. DBGENTRY(CNmChannelAudioObj::~CNmChannelAudioObj);
  18. DBGEXIT(CNmChannelAudioObj::~CNmChannelAudioObj);
  19. }
  20. //
  21. HRESULT CNmChannelAudioObj::CreateInstance(CNmConferenceObj* pConfObj, INmChannel** ppChannel, bool bIsIncoming)
  22. {
  23. DBGENTRY(CNmChannelAudioObj::CreateInstance);
  24. HRESULT hr = S_OK;
  25. typedef CNmChannel<CNmChannelAudioObj, &IID_INmChannelAudio, NMCH_AUDIO> channel_type;
  26. channel_type* p = NULL;
  27. p = new CComObject<channel_type>(NULL);
  28. if (p != NULL)
  29. {
  30. if(ppChannel)
  31. {
  32. p->SetVoid(NULL);
  33. hr = p->QueryInterface(IID_INmChannel, reinterpret_cast<void**>(ppChannel));
  34. if(SUCCEEDED(hr))
  35. {
  36. // We don't have to RefCount this because our lifetime is
  37. // contained in the CConf's lifetime
  38. p->m_pConfObj = pConfObj;
  39. p->m_bIsIncoming = bIsIncoming;
  40. }
  41. if(FAILED(hr))
  42. {
  43. *ppChannel = NULL;
  44. }
  45. }
  46. else
  47. {
  48. hr = E_POINTER;
  49. }
  50. }
  51. else
  52. {
  53. hr = E_OUTOFMEMORY;
  54. }
  55. if(FAILED(hr))
  56. {
  57. delete p;
  58. }
  59. DBGEXIT_HR(CNmChannelAudioObj::CreateInstance,hr);
  60. return hr;
  61. }
  62. ///////////////////////////////////////////////////////////////////////////////////
  63. // INmChannelAudio2 methods
  64. ///////////////////////////////////////////////////////////////////////////////////
  65. STDMETHODIMP CNmChannelAudioObj::IsIncoming(void)
  66. {
  67. DBGENTRY(CNmChannelAudioObj::IsIncoming);
  68. HRESULT hr = E_UNEXPECTED;
  69. hr = m_bIsIncoming ? S_OK : S_FALSE;
  70. DBGEXIT_HR(CNmChannelAudioObj::IsIncoming,hr);
  71. return hr;
  72. }
  73. STDMETHODIMP CNmChannelAudioObj::GetState(NM_AUDIO_STATE *puState)
  74. {
  75. DBGENTRY(CNmChannelAudioObj::GetState);
  76. HRESULT hr = E_POINTER;
  77. if(puState)
  78. {
  79. hr = S_OK;
  80. *puState = NM_AUDIO_IDLE;
  81. if(S_OK == _IsActive())
  82. {
  83. if( ((S_OK == IsIncoming()) && IsSpeakerMuted()) || ((S_FALSE == IsIncoming()) && IsMicMuted()))
  84. {
  85. *puState = NM_AUDIO_LOCAL_PAUSED;
  86. }
  87. else
  88. {
  89. *puState = NM_AUDIO_TRANSFERRING;
  90. }
  91. }
  92. }
  93. DBGEXIT_HR(CNmChannelAudioObj::GetState,hr);
  94. return hr;
  95. }
  96. STDMETHODIMP CNmChannelAudioObj::GetProperty(NM_AUDPROP uID,ULONG_PTR *puValue)
  97. {
  98. DBGENTRY(CNmChannelAudioObj::GetProperty);
  99. HRESULT hr = E_POINTER;
  100. if(puValue)
  101. {
  102. hr = E_FAIL;
  103. if(IsChannelValid())
  104. {
  105. switch(uID)
  106. {
  107. case NM_AUDPROP_LEVEL:
  108. {
  109. HRESULT hIncoming = IsIncoming();
  110. if(S_OK == hIncoming)
  111. { // This is the receive channel
  112. *puValue = GetSpeakerVolume();
  113. hr = S_OK;
  114. }
  115. else if(S_FALSE == hIncoming)
  116. { // This is the send channel
  117. *puValue = GetRecorderVolume();
  118. hr = S_OK;
  119. }
  120. break;
  121. }
  122. case NM_AUDPROP_PAUSE:
  123. {
  124. HRESULT hIncoming = IsIncoming();
  125. if(S_OK == hIncoming)
  126. { // This is the receive channel
  127. *puValue = IsSpeakerMuted() ? 1 : 0;
  128. hr = S_OK;
  129. }
  130. else if(S_FALSE == hIncoming)
  131. { // This is the send channel
  132. *puValue = IsMicMuted() ? 1 : 0;
  133. hr = S_OK;
  134. }
  135. break;
  136. }
  137. default:
  138. hr = E_INVALIDARG;
  139. break;
  140. }
  141. }
  142. }
  143. DBGEXIT_HR(CNmChannelAudioObj::GetProperty,hr);
  144. return hr;
  145. }
  146. STDMETHODIMP CNmChannelAudioObj::SetProperty(NM_AUDPROP uID,ULONG_PTR uValue)
  147. {
  148. DBGENTRY(CNmChannelAudioObj::SetProperty);
  149. HRESULT hr = E_FAIL;
  150. if(IsChannelValid())
  151. {
  152. switch(uID)
  153. {
  154. case NM_AUDPROP_LEVEL:
  155. {
  156. hr = E_INVALIDARG;
  157. if(uValue < NM_MAX_AUDIO_LEVEL)
  158. {
  159. HRESULT hIncoming = IsIncoming();
  160. if(S_OK == hIncoming)
  161. { // This is the receive channel
  162. SetSpeakerVolume((ULONG)uValue);
  163. hr = S_OK;
  164. }
  165. else if(S_FALSE == hIncoming)
  166. { // This is the send channel
  167. SetRecorderVolume((ULONG)uValue);
  168. hr = S_OK;
  169. }
  170. }
  171. break;
  172. }
  173. case NM_AUDPROP_PAUSE:
  174. {
  175. HRESULT hIncoming = IsIncoming();
  176. if(S_OK == hIncoming)
  177. { // This is the receive channel
  178. MuteSpeaker(uValue ? TRUE : FALSE);
  179. hr = S_OK;
  180. }
  181. else if(S_FALSE == hIncoming)
  182. { // This is the send channel
  183. MuteMicrophone(uValue ? TRUE : FALSE);
  184. hr = S_OK;
  185. }
  186. break;
  187. }
  188. default:
  189. hr = E_INVALIDARG;
  190. break;
  191. }
  192. }
  193. DBGEXIT_HR(CNmChannelAudioObj::SetProperty,hr);
  194. return hr;
  195. }
  196. ///////////////////////////////////////////////////////////////////////////////////
  197. //INmChannelAudioNotify
  198. ///////////////////////////////////////////////////////////////////////////////////
  199. STDMETHODIMP CNmChannelAudioObj::StateChanged(NM_AUDIO_STATE uState)
  200. {
  201. DBGENTRY(CNmChannelAudioObj::StateChanged);
  202. HRESULT hr = S_OK;
  203. Activate(NM_AUDIO_IDLE != uState);
  204. // The internal GetState is a bit funky at times...
  205. GetState(&uState);
  206. hr = Fire_StateChanged(uState);
  207. DBGEXIT_HR(CNmChannelAudioObj::StateChanged,hr);
  208. return hr;
  209. }
  210. STDMETHODIMP CNmChannelAudioObj::PropertyChanged(DWORD dwReserved)
  211. {
  212. DBGENTRY(CNmChannelAudioObj::PropertyChanged);
  213. HRESULT hr = S_OK;
  214. hr = Fire_PropertyChanged(dwReserved);
  215. DBGEXIT_HR(CNmChannelAudioObj::PropertyChanged,hr);
  216. return hr;
  217. }
  218. ///////////////////////////////////////////////////////////////////////////////
  219. // IInternalChannelObj methods
  220. ///////////////////////////////////////////////////////////////////////////////
  221. STDMETHODIMP CNmChannelAudioObj::GetInternalINmChannel(INmChannel** ppChannel)
  222. {
  223. DBGENTRY(CNmChannelAudioObj::GetInternalINmChannel);
  224. HRESULT hr = E_POINTER;
  225. if(ppChannel)
  226. {
  227. *ppChannel = NULL;
  228. hr = S_OK;
  229. }
  230. DBGEXIT_HR(CNmChannelAudioObj::GetInternalINmChannel,hr);
  231. return hr;
  232. }
  233. HRESULT CNmChannelAudioObj::ChannelRemoved()
  234. {
  235. HRESULT hr = S_OK;
  236. RemoveMembers();
  237. CNmConferenceObj* pConfObj = GetConfObj();
  238. if(pConfObj)
  239. {
  240. hr = pConfObj->Fire_ChannelChanged(NM_CHANNEL_REMOVED, com_cast<INmChannel>(GetUnknown()));
  241. }
  242. else
  243. {
  244. ERROR_OUT(("ChannelRemoved, but no ConfObject"));
  245. hr = E_UNEXPECTED;
  246. }
  247. return hr;
  248. }
  249. ///////////////////////////////////////////////////////////////////////////////
  250. // Helpers
  251. ///////////////////////////////////////////////////////////////////////////////
  252. HRESULT CNmChannelAudioObj::Fire_MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pMember)
  253. {
  254. DBGENTRY(CNmChannelAudioObj::Fire_MemberChanged);
  255. HRESULT hr = S_OK;
  256. /////////////////////////////////////////////////////
  257. // INmChannelNotify
  258. /////////////////////////////////////////////////////
  259. IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelNotify, CComDynamicUnkArray>* pCP = this;
  260. for(int i = 0; i < pCP->m_vec.GetSize(); ++i )
  261. {
  262. INmChannelNotify* pNotify = reinterpret_cast<INmChannelNotify*>(pCP->m_vec.GetAt(i));
  263. if(pNotify)
  264. {
  265. pNotify->MemberChanged(uNotify, pMember);
  266. }
  267. }
  268. /////////////////////////////////////////////////////
  269. // INmChannelAudioNotify
  270. /////////////////////////////////////////////////////
  271. IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelAudioNotify, CComDynamicUnkArray>* pCP2 = this;
  272. for(i = 0; i < pCP2->m_vec.GetSize(); ++i )
  273. {
  274. INmChannelAudioNotify* pNotify2 = reinterpret_cast<INmChannelAudioNotify*>(pCP2->m_vec.GetAt(i));
  275. if(pNotify2)
  276. {
  277. pNotify2->MemberChanged(uNotify, pMember);
  278. }
  279. }
  280. DBGEXIT_HR(CNmChannelAudioObj::Fire_MemberChanged,hr)
  281. return hr;
  282. }
  283. HRESULT CNmChannelAudioObj::Fire_StateChanged(NM_AUDIO_STATE uState)
  284. {
  285. HRESULT hr = S_OK;
  286. /////////////////////////////////////////////////////
  287. // INmChannelAudioNotify
  288. /////////////////////////////////////////////////////
  289. IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelAudioNotify, CComDynamicUnkArray>* pCP2 = this;
  290. for(int i = 0; i < pCP2->m_vec.GetSize(); ++i )
  291. {
  292. INmChannelAudioNotify* pNotify2 = reinterpret_cast<INmChannelAudioNotify*>(pCP2->m_vec.GetAt(i));
  293. if(pNotify2)
  294. {
  295. pNotify2->StateChanged(uState);
  296. }
  297. }
  298. DBGEXIT_HR(CNmChannelAudioObj::Fire_MemberChanged,hr)
  299. return hr;
  300. }
  301. HRESULT CNmChannelAudioObj::Fire_PropertyChanged(DWORD dwReserved)
  302. {
  303. HRESULT hr = S_OK;
  304. /////////////////////////////////////////////////////
  305. // INmChannelAudioNotify
  306. /////////////////////////////////////////////////////
  307. IConnectionPointImpl<CNmChannelAudioObj, &IID_INmChannelAudioNotify, CComDynamicUnkArray>* pCP2 = this;
  308. for(int i = 0; i < pCP2->m_vec.GetSize(); ++i )
  309. {
  310. INmChannelAudioNotify* pNotify2 = reinterpret_cast<INmChannelAudioNotify*>(pCP2->m_vec.GetAt(i));
  311. if(pNotify2)
  312. {
  313. pNotify2->PropertyChanged(dwReserved);
  314. }
  315. }
  316. DBGEXIT_HR(CNmChannelAudioObj::Fire_MemberChanged,hr)
  317. return hr;
  318. }
  319. HRESULT CNmChannelAudioObj::_IsActive()
  320. {
  321. return GetbActive() ? S_OK : S_FALSE;
  322. }
  323. // We don't support switchable AV anymore
  324. HRESULT CNmChannelAudioObj::_SetActive(BOOL bActive)
  325. {
  326. if (GetbActive() == bActive)
  327. return S_OK;
  328. return E_FAIL;
  329. }
  330.