Source code of Windows XP (NT5)
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.

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