MixerWrap.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726
  1. #include "StdAfx.h"
  2. #include "MixerWrap.h"
  3. #include <windows.h>
  4. #include <MMSystem.h>
  5. #include <stdlib.h>
  6. #include <string>
  7. #include <iostream>
  8. using namespace std;
  9. #include <mmdeviceapi.h>
  10. #include <endpointvolume.h>
  11. #include <Functiondiscoverykeys_devpkey.h>
  12. #include <comdef.h>
  13. #define SAFE_RELEASE(punk) \
  14. if ((punk) != NULL) \
  15. #define EXIT_ON_ERROR(hres) if (FAILED(hres)) { goto Exit; }
  16. #define SAFE_RELEASE(punk) if ((punk) != NULL) { (punk)->Release(); (punk) = NULL; }
  17. HRESULT getMicrophoneBoostVolumeLevel(IMMDevice *pEndptDev, IAudioVolumeLevel** ppVolumeLevel)
  18. {
  19. HRESULT hr = S_OK;
  20. DataFlow flow;
  21. IDeviceTopology *pDeviceTopology = NULL;
  22. IConnector *pConnFrom = NULL;
  23. IConnector *pConnTo = NULL;
  24. IPart *pPartPrev = NULL;
  25. IPart *pPartNext = NULL;
  26. *ppVolumeLevel = NULL;
  27. wchar_t microphoneBoostName[] = L"麦克风加强";//if your system language is English,the name is "microphone boost"
  28. if (pEndptDev == NULL)
  29. {
  30. EXIT_ON_ERROR(hr = E_POINTER)
  31. }
  32. // Get the endpoint device's IDeviceTopology interface.
  33. hr = pEndptDev->Activate(
  34. __uuidof(IDeviceTopology), CLSCTX_ALL, NULL,
  35. (void**)&pDeviceTopology);
  36. EXIT_ON_ERROR(hr)
  37. // The device topology for an endpoint device always
  38. // contains just one connector (connector number 0).
  39. hr = pDeviceTopology->GetConnector(0, &pConnFrom);
  40. SAFE_RELEASE(pDeviceTopology)
  41. EXIT_ON_ERROR(hr)
  42. // Make sure that this is a capture device.
  43. hr = pConnFrom->GetDataFlow(&flow);
  44. EXIT_ON_ERROR(hr)
  45. if (flow != Out)
  46. {
  47. // Error -- this is a rendering device.
  48. //EXIT_ON_ERROR(hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE)
  49. }
  50. // Outer loop: Each iteration traverses the data path
  51. // through a device topology starting at the input
  52. // connector and ending at the output connector.
  53. while (TRUE)
  54. {
  55. BOOL bConnected;
  56. hr = pConnFrom->IsConnected(&bConnected);
  57. EXIT_ON_ERROR(hr)
  58. // Does this connector connect to another device?
  59. if (bConnected == FALSE)
  60. {
  61. // This is the end of the data path that
  62. // stretches from the endpoint device to the
  63. // system bus or external bus. Verify that
  64. // the connection type is Software_IO.
  65. ConnectorType connType;
  66. hr = pConnFrom->GetType(&connType);
  67. EXIT_ON_ERROR(hr)
  68. if (connType == Software_IO)
  69. {
  70. break; // finished
  71. }
  72. EXIT_ON_ERROR(hr = E_FAIL)
  73. }
  74. // Get the connector in the next device topology,
  75. // which lies on the other side of the connection.
  76. hr = pConnFrom->GetConnectedTo(&pConnTo);
  77. EXIT_ON_ERROR(hr)
  78. SAFE_RELEASE(pConnFrom)
  79. // Get the connector's IPart interface.
  80. hr = pConnTo->QueryInterface(
  81. __uuidof(IPart), (void**)&pPartPrev);
  82. EXIT_ON_ERROR(hr)
  83. SAFE_RELEASE(pConnTo)
  84. CComPtr<IAudioAutoGainControl> m_pAGC; //麦克风自动增益接口
  85. hr = pPartPrev->Activate(CLSCTX_INPROC_SERVER, __uuidof(IAudioAutoGainControl), (void**)&m_pAGC);
  86. if (SUCCEEDED(hr) && m_pAGC)
  87. printf("this function\n");
  88. // Inner loop: Each iteration traverses one link in a
  89. // device topology and looks for input multiplexers.
  90. while (TRUE)
  91. {
  92. PartType parttype;
  93. IPartsList *pParts;
  94. // Follow downstream link to next part.
  95. hr = pPartPrev->EnumPartsOutgoing(&pParts);
  96. EXIT_ON_ERROR(hr)
  97. hr = pParts->GetPart(0, &pPartNext);
  98. pParts->Release();
  99. EXIT_ON_ERROR(hr)
  100. hr = pPartNext->GetPartType(&parttype);
  101. EXIT_ON_ERROR(hr)
  102. LPWSTR pName;
  103. if (SUCCEEDED(pPartNext->GetName(&pName)))
  104. {
  105. // Failure of the following call means only that
  106. char printStr[200];
  107. WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, pName, wcslen(pName) + 1, printStr, 200, NULL, NULL);
  108. if (wcscmp(microphoneBoostName,pName) == 0)
  109. {
  110. //get IAudioVolumeLevel to control volume
  111. hr = pPartNext->Activate(CLSCTX_ALL, __uuidof(IAudioVolumeLevel), (void**)ppVolumeLevel);
  112. goto Exit;
  113. }
  114. CoTaskMemFree(pName);
  115. }
  116. GUID subType;
  117. pPartNext->GetSubType(&subType);
  118. if (parttype == Connector)
  119. {
  120. // We've reached the output connector that
  121. // lies at the end of this device topology.
  122. hr = pPartNext->QueryInterface(
  123. __uuidof(IConnector),
  124. (void**)&pConnFrom);
  125. EXIT_ON_ERROR(hr)
  126. SAFE_RELEASE(pPartPrev)
  127. SAFE_RELEASE(pPartNext)
  128. break;
  129. }
  130. SAFE_RELEASE(pPartPrev)
  131. pPartPrev = pPartNext;
  132. pPartNext = NULL;
  133. }
  134. }
  135. Exit:
  136. SAFE_RELEASE(pConnFrom)
  137. SAFE_RELEASE(pConnTo)
  138. SAFE_RELEASE(pPartPrev)
  139. SAFE_RELEASE(pPartNext)
  140. return hr;
  141. }
  142. void MixerWrap::MicphoneBoost(bool bIsBoost)
  143. {
  144. int mixerNum ;//总的混音器数量
  145. HMIXER hMixer; //混音器设备句柄
  146. MMRESULT mmr;//函数调用返回
  147. MIXERCAPS MixerCaps; //混音器设备能力信息
  148. MIXERLINE MixerLine;//线路的信息
  149. //获取当前系统总的混音器数量
  150. mixerNum= mixerGetNumDevs();
  151. bool ifFind =false;
  152. for(int i=0;i<mixerNum;i++)
  153. {
  154. //打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
  155. mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
  156. ifFind =false;
  157. //取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
  158. //mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
  159. //获取混音器能力特征,如声音控制 和录音控制
  160. mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
  161. for(int j=0;j<MixerCaps.cDestinations;j++)
  162. //MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
  163. //如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
  164. {
  165. memset(&MixerLine, 0, sizeof(MIXERLINE));
  166. MixerLine.cbStruct = sizeof(MixerLine);
  167. MixerLine.dwDestination = j;
  168. // 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  169. // 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  170. //MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  171. //mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
  172. //取录音控制
  173. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
  174. DWORD dwConnections = MixerLine.cConnections;
  175. for (int count = 0; count < dwConnections; count++)
  176. {
  177. MixerLine.dwSource = count;
  178. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
  179. if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == MixerLine.dwComponentType)
  180. {
  181. //如果是录音控制的麦克风选项,则跳出
  182. ifFind = true;
  183. break;
  184. }
  185. }
  186. if (ifFind)
  187. {
  188. break;
  189. }
  190. }
  191. if (!ifFind)
  192. continue;
  193. //获取麦克风选项
  194. MIXERLINECONTROLS MixerLineControls;
  195. PMIXERCONTROL paMixerControls;
  196. paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
  197. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  198. MixerLineControls.dwLineID = MixerLine.dwLineID;
  199. MixerLineControls.cControls = MixerLine.cControls;
  200. MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
  201. MixerLineControls.pamxctrl = paMixerControls;
  202. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,
  203. MIXER_GETLINECONTROLSF_ALL);
  204. int u;
  205. ifFind = false;
  206. for (u = 0; u < MixerLine.cControls; u++)
  207. {
  208. if (_tcscmp(paMixerControls[u].szName, _T("麦克风加强")) == 0)
  209. {
  210. ifFind = true;
  211. break;
  212. }
  213. }
  214. if (!ifFind)
  215. {
  216. continue;
  217. }
  218. MIXERCONTROL MixerControl;
  219. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  220. MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
  221. MixerLineControls.cbmxctrl = sizeof(MixerControl);
  222. MixerLineControls.pamxctrl = &MixerControl;
  223. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
  224. free(paMixerControls);
  225. MIXERCONTROLDETAILS MixerControlDetails;
  226. PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
  227. pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc(1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  228. memset(&MixerControlDetails, 0, sizeof(MixerControlDetails));
  229. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  230. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  231. MixerControlDetails.cChannels = 1;
  232. MixerControlDetails.cMultipleItems = 0;
  233. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  234. MixerControlDetails.paDetails = &pMixerControlDetails_Boolean[0];
  235. // True to turn on boost, False to turn off
  236. pMixerControlDetails_Boolean[0].fValue = bIsBoost;
  237. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  238. free(pMixerControlDetails_Boolean);
  239. //关闭混音器
  240. mixerClose(hMixer);
  241. if (bIsBoost)
  242. {
  243. MicphoneMut(true);
  244. }
  245. }
  246. return;
  247. }
  248. #define ERROR_EXIT_HR(hr) if (hr != S_OK){ continue;}
  249. void MixerWrap::MicphoneBoost_W7(float fValue)
  250. {
  251. HRESULT hr=NULL;
  252. CoInitialize(NULL);
  253. IMMDeviceEnumerator *deviceEnumerator = NULL;
  254. IMMDeviceCollection *pEndpoints = NULL;
  255. hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
  256. __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
  257. IMMDevice *defaultDevice = NULL;
  258. if (hr != S_OK)
  259. {
  260. return ;
  261. }
  262. hr = deviceEnumerator->EnumAudioEndpoints(eCapture
  263. , DEVICE_STATE_ACTIVE, &pEndpoints);
  264. if (hr != S_OK) return;
  265. UINT deviceCount;
  266. hr = pEndpoints->GetCount(&deviceCount);
  267. if (hr != S_OK) return;
  268. IMMDevice *pDevice = NULL;
  269. //printf("devNum: %d\n", deviceCount);
  270. for (UINT dev = 0; dev < deviceCount; dev++)
  271. {
  272. pDevice = NULL;
  273. hr = pEndpoints->Item(dev, &pDevice);
  274. ERROR_EXIT_HR(hr);
  275. IPropertyStore *pProperties = NULL;
  276. hr = pDevice->OpenPropertyStore(STGM_READ, &pProperties);
  277. ERROR_EXIT_HR(hr);
  278. PROPVARIANT varName;
  279. PropVariantInit(&varName);
  280. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  281. char printStr[200];
  282. WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, varName.pwszVal, wcslen(varName.pwszVal) + 1, printStr, 200, NULL, NULL);
  283. //printf("Name: %s\n", printStr);
  284. IAudioVolumeLevel* pIaudioVolumeLevel;
  285. getMicrophoneBoostVolumeLevel(pDevice, &pIaudioVolumeLevel);
  286. if (pIaudioVolumeLevel != NULL)
  287. {
  288. pIaudioVolumeLevel->SetLevelUniform(fValue, NULL);
  289. }
  290. SAFE_RELEASE(pProperties);
  291. SAFE_RELEASE(pDevice);
  292. }
  293. deviceEnumerator->Release();
  294. deviceEnumerator = NULL;
  295. return ;
  296. }
  297. bool MixerWrap::checkMicphoneLevel(float fValue)
  298. {
  299. HRESULT hr = NULL;
  300. CoInitialize(NULL);
  301. IMMDeviceEnumerator *deviceEnumerator = NULL;
  302. IMMDeviceCollection *pEndpoints = NULL;
  303. hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
  304. __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
  305. IMMDevice *defaultDevice = NULL;
  306. bool result = true;
  307. if (hr != S_OK) return false;
  308. hr = deviceEnumerator->EnumAudioEndpoints(eCapture
  309. , DEVICE_STATE_ACTIVE, &pEndpoints);
  310. if (hr != S_OK) return false;
  311. UINT deviceCount;
  312. hr = pEndpoints->GetCount(&deviceCount);
  313. if (hr != S_OK) return false;
  314. IMMDevice *pDevice = NULL;
  315. //printf("devNum: %d\n", deviceCount);
  316. for (UINT dev = 0; dev < deviceCount; dev++)
  317. {
  318. pDevice = NULL;
  319. hr = pEndpoints->Item(dev, &pDevice);
  320. ERROR_EXIT_HR(hr);
  321. IPropertyStore *pProperties = NULL;
  322. hr = pDevice->OpenPropertyStore(STGM_READ, &pProperties);
  323. ERROR_EXIT_HR(hr);
  324. PROPVARIANT varName;
  325. PropVariantInit(&varName);
  326. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  327. char printStr[200];
  328. WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, varName.pwszVal, wcslen(varName.pwszVal) + 1, printStr, 200, NULL, NULL);
  329. //printf("Name: %s\n", printStr);
  330. IAudioVolumeLevel* pIaudioVolumeLevel;
  331. getMicrophoneBoostVolumeLevel(pDevice, &pIaudioVolumeLevel);
  332. if (pIaudioVolumeLevel != NULL)
  333. {
  334. float tempLevel;
  335. pIaudioVolumeLevel->GetLevel(0, &tempLevel);//0-30
  336. if (tempLevel != fValue) result = false;
  337. }
  338. SAFE_RELEASE(pProperties);
  339. SAFE_RELEASE(pDevice);
  340. }
  341. deviceEnumerator->Release();
  342. deviceEnumerator = NULL;
  343. return result;
  344. }
  345. void MixerWrap::GetMicphoneLevel(float &fValue)
  346. {
  347. HRESULT hr=NULL;
  348. CoInitialize(NULL);
  349. IMMDeviceEnumerator *deviceEnumerator = NULL;
  350. hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
  351. __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
  352. IMMDevice *defaultDevice = NULL;
  353. if (hr != S_OK)
  354. {
  355. return ;
  356. }
  357. hr = deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &defaultDevice);
  358. deviceEnumerator->Release();
  359. deviceEnumerator = NULL;
  360. IAudioVolumeLevel* pIaudioVolumeLevel;
  361. getMicrophoneBoostVolumeLevel(defaultDevice,&pIaudioVolumeLevel);
  362. defaultDevice->Release();
  363. defaultDevice = NULL;
  364. if (pIaudioVolumeLevel==NULL)
  365. {
  366. return ;
  367. }
  368. pIaudioVolumeLevel->GetLevel(0,&fValue);//0-30
  369. return ;
  370. }
  371. void MixerWrap::GetMicphoneLevelData(float &nMin, float &nMax, float &nStep)
  372. {
  373. HRESULT hr=NULL;
  374. CoInitialize(NULL);
  375. IMMDeviceEnumerator *deviceEnumerator = NULL;
  376. hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
  377. __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
  378. IMMDevice *defaultDevice = NULL;
  379. if (hr != S_OK)
  380. {
  381. return ;
  382. }
  383. hr = deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &defaultDevice);
  384. deviceEnumerator->Release();
  385. deviceEnumerator = NULL;
  386. IAudioVolumeLevel* pIaudioVolumeLevel;
  387. getMicrophoneBoostVolumeLevel(defaultDevice,&pIaudioVolumeLevel);
  388. defaultDevice->Release();
  389. defaultDevice = NULL;
  390. if (pIaudioVolumeLevel==NULL)
  391. {
  392. return ;
  393. }
  394. pIaudioVolumeLevel->GetLevelRange(0,&nMin, &nMax, &nStep);//0-30
  395. }
  396. void MixerWrap::MicphoneMut(bool bIsMut)
  397. {
  398. int mixerNum ;//总的混音器数量
  399. HMIXER hMixer; //混音器设备句柄
  400. MMRESULT mmr;//函数调用返回
  401. MIXERCAPS MixerCaps; //混音器设备能力信息
  402. MIXERLINE MixerLine;//线路的信息
  403. //获取当前系统总的混音器数量
  404. mixerNum= mixerGetNumDevs();
  405. bool ifFind =false;
  406. for(int i=0;i<mixerNum;i++)
  407. {
  408. //打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
  409. mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
  410. ifFind =false;
  411. //取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
  412. //mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
  413. //获取混音器能力特征,如声音控制 和录音控制
  414. mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
  415. for(int j=0;j<MixerCaps.cDestinations;j++)
  416. //MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
  417. //如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
  418. {
  419. memset(&MixerLine,0,sizeof(MIXERLINE));
  420. MixerLine.cbStruct = sizeof(MixerLine);
  421. MixerLine.dwDestination = j;
  422. // 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  423. // 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  424. //MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  425. //mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
  426. //取录音控制
  427. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
  428. DWORD dwConnections = MixerLine.cConnections;
  429. for ( int count = 0; count < dwConnections; count++ )
  430. {
  431. MixerLine.dwSource = count;
  432. mmr=mixerGetLineInfo((HMIXEROBJ)hMixer,&MixerLine,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
  433. if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == MixerLine.dwComponentType)
  434. {
  435. //如果是录音控制的麦克风选项,则跳出
  436. ifFind =true;
  437. break;
  438. }
  439. }
  440. if (ifFind)
  441. {
  442. break;
  443. }
  444. }
  445. if(!ifFind)
  446. continue;
  447. //获取麦克风选项
  448. MIXERLINECONTROLS MixerLineControls;
  449. PMIXERCONTROL paMixerControls;
  450. paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
  451. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  452. MixerLineControls.dwLineID = MixerLine.dwLineID;
  453. MixerLineControls.cControls = MixerLine.cControls;
  454. MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
  455. MixerLineControls.pamxctrl = paMixerControls;
  456. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,
  457. MIXER_GETLINECONTROLSF_ALL);
  458. int u ;
  459. ifFind =false;
  460. for ( u = 0; u < MixerLine.cControls; u++)
  461. {
  462. if (_tcscmp(paMixerControls[u].szName,_T("麦克风静音"))==0 || _tcscmp(paMixerControls[u].szName,_T("静音"))==0)
  463. {
  464. ifFind =true;
  465. break;
  466. }
  467. }
  468. if (!ifFind)
  469. {
  470. continue;
  471. }
  472. MIXERCONTROL MixerControl;
  473. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  474. MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
  475. MixerLineControls.cbmxctrl = sizeof(MixerControl);
  476. MixerLineControls.pamxctrl = &MixerControl;
  477. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
  478. free(paMixerControls);
  479. MIXERCONTROLDETAILS MixerControlDetails;
  480. PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
  481. pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc(1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  482. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  483. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  484. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  485. MixerControlDetails.cChannels =1;
  486. MixerControlDetails.cMultipleItems =0;
  487. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  488. MixerControlDetails.paDetails = &pMixerControlDetails_Boolean[0];
  489. // True to turn on boost, False to turn off
  490. pMixerControlDetails_Boolean[0].fValue = bIsMut;
  491. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  492. free(pMixerControlDetails_Boolean);
  493. //关闭混音器
  494. mixerClose(hMixer);
  495. }
  496. return ;
  497. }
  498. void MixerWrap::StereoMix(bool bIsMix)
  499. {
  500. int mixerNum ;//总的混音器数量
  501. HMIXER hMixer; //混音器设备句柄
  502. MMRESULT mmr;//函数调用返回
  503. MIXERCAPS MixerCaps; //混音器设备能力信息
  504. MIXERLINE MixerLine;//线路的信息
  505. //获取当前系统总的混音器数量
  506. mixerNum= mixerGetNumDevs();
  507. bool ifFind =false;
  508. for(int i=0;i<mixerNum;i++)
  509. {
  510. //打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
  511. mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
  512. ifFind =false;
  513. //取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
  514. //mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
  515. //获取混音器能力特征,如声音控制 和录音控制
  516. mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
  517. for(int j=0;j<MixerCaps.cDestinations;j++)
  518. //MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
  519. //如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
  520. {
  521. memset(&MixerLine,0,sizeof(MIXERLINE));
  522. MixerLine.cbStruct = sizeof(MixerLine);
  523. MixerLine.dwDestination = j;
  524. // 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  525. // 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  526. //MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  527. //mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
  528. //取录音控制
  529. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
  530. DWORD dwConnections = MixerLine.cConnections;
  531. for ( int count = 0; count < dwConnections; count++ )
  532. {
  533. MixerLine.dwSource = count;
  534. mmr=mixerGetLineInfo((HMIXEROBJ)hMixer,&MixerLine,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
  535. //_tprintf(_T("MixerLine.dwComponentType:%d,MixerLine.szName:%s,\r\n"),MixerLine.dwComponentType,MixerLine.szName);
  536. if (_tcscmp(MixerLine.szName,_T("立体声混音"))==0/*MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC == MixerLine.dwComponentType &&*/ )
  537. {
  538. //如果是立体声混音选项,则跳出
  539. //_tprintf(_T("MixerLine.szName:%s,result:%d\r\n"),MixerLine.szName,wcscmp(MixerLine.szName,_T("立体声混音")));
  540. ifFind =true;
  541. break;
  542. }
  543. }
  544. if (ifFind)
  545. {
  546. break;
  547. }
  548. }
  549. if(!ifFind)
  550. continue;
  551. //_tprintf(_T("ifFind%d\r\n"),ifFind);
  552. //获取麦克风选项
  553. MIXERLINECONTROLS MixerLineControls;
  554. PMIXERCONTROL paMixerControls;
  555. paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
  556. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  557. MixerLineControls.dwLineID = MixerLine.dwLineID;
  558. MixerLineControls.cControls = MixerLine.cControls;
  559. MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
  560. MixerLineControls.pamxctrl = paMixerControls;
  561. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,MIXER_GETLINECONTROLSF_ALL);
  562. int u ;
  563. ifFind =false;
  564. for ( u = 0; u < MixerLine.cControls; u++)
  565. {
  566. //_tprintf(_T("MixerLine.cControls:%d,MpaMixerControls[u].szName:%s,\r\n"),MixerLine.cControls,paMixerControls[u].szName);
  567. if (_tcscmp(paMixerControls[u].szName,_T("立体声混音静音"))==0 ||
  568. _tcscmp(paMixerControls[u].szName,_T("静音"))==0 ||
  569. _tcscmp(paMixerControls[u].szName,_T("立体声混音"))==0 )
  570. {
  571. ifFind =true;
  572. break;
  573. }
  574. }
  575. if (!ifFind)
  576. {
  577. continue;
  578. }
  579. MIXERCONTROL MixerControl;
  580. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  581. MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
  582. MixerLineControls.cbmxctrl = sizeof(MixerControl);
  583. MixerLineControls.pamxctrl = &MixerControl;
  584. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
  585. free(paMixerControls);
  586. MIXERCONTROLDETAILS MixerControlDetails;
  587. PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
  588. pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc(1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  589. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  590. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  591. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  592. MixerControlDetails.cChannels =1;
  593. MixerControlDetails.cMultipleItems =0;
  594. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  595. MixerControlDetails.paDetails = &pMixerControlDetails_Boolean[0];
  596. // True to turn on boost, False to turn off
  597. pMixerControlDetails_Boolean[0].fValue = bIsMix;
  598. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  599. free(pMixerControlDetails_Boolean);
  600. //关闭混音器
  601. mixerClose(hMixer);
  602. }
  603. return ;
  604. }
  605. void MixerWrap::StereoMixVolume(int nVolume)
  606. {
  607. int mixerNum ;//总的混音器数量
  608. HMIXER hMixer; //混音器设备句柄
  609. MMRESULT mmr;//函数调用返回
  610. MIXERCAPS MixerCaps; //混音器设备能力信息
  611. MIXERLINE MixerLine;//线路的信息
  612. //获取当前系统总的混音器数量
  613. mixerNum= mixerGetNumDevs();
  614. bool ifFind =false;
  615. for(int i=0;i<mixerNum;i++)
  616. {
  617. //打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
  618. mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
  619. ifFind =false;
  620. //取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
  621. //mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
  622. //获取混音器能力特征,如声音控制 和录音控制
  623. mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
  624. for(int j=0;j<MixerCaps.cDestinations;j++)
  625. //MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
  626. //如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
  627. {
  628. memset(&MixerLine,0,sizeof(MIXERLINE));
  629. MixerLine.cbStruct = sizeof(MixerLine);
  630. MixerLine.dwDestination = j;
  631. // 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  632. // 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  633. //MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  634. //mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
  635. //取录音控制
  636. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
  637. DWORD dwConnections = MixerLine.cConnections;
  638. for ( int count = 0; count < dwConnections; count++ )
  639. {
  640. MixerLine.dwSource = count;
  641. mmr=mixerGetLineInfo((HMIXEROBJ)hMixer,&MixerLine,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
  642. //_tprintf(_T("MixerLine.dwComponentType:%d,MixerLine.szName:%s,\r\n"),MixerLine.dwComponentType,MixerLine.szName);
  643. if (_tcscmp(MixerLine.szName,_T("立体声混音"))==0/*MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC == MixerLine.dwComponentType &&*/ )
  644. {
  645. //如果是立体声混音选项,则跳出
  646. //_tprintf(_T("MixerLine.szName:%s,result:%d\r\n"),MixerLine.szName,wcscmp(MixerLine.szName,_T("立体声混音")));
  647. ifFind =true;
  648. break;
  649. }
  650. }
  651. if (ifFind)
  652. {
  653. break;
  654. }
  655. }
  656. if(!ifFind)
  657. continue;
  658. //_tprintf(_T("ifFind%d\r\n"),ifFind);
  659. //获取麦克风选项
  660. MIXERLINECONTROLS MixerLineControls;
  661. PMIXERCONTROL paMixerControls;
  662. paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
  663. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  664. MixerLineControls.dwLineID = MixerLine.dwLineID;
  665. MixerLineControls.cControls = MixerLine.cControls;
  666. MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
  667. MixerLineControls.pamxctrl = paMixerControls;
  668. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,MIXER_GETLINECONTROLSF_ALL);
  669. int u ;
  670. ifFind =false;
  671. for ( u = 0; u < MixerLine.cControls; u++)
  672. {
  673. //_tprintf(_T("MixerLine.cControls:%d,MpaMixerControls[u].szName:%s,\r\n"),MixerLine.cControls,paMixerControls[u].szName);
  674. TCHAR temp[50];
  675. _stprintf(temp,_T("Name:%s"),paMixerControls[u].szName);
  676. _bstr_t strStr = temp;
  677. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  678. if (_tcscmp(paMixerControls[u].szName,_T("立体声混音"))==0 || _tcscmp(paMixerControls[u].szName,_T("立体声混音音量"))==0 )
  679. {
  680. ifFind =true;
  681. break;
  682. }
  683. }
  684. if (!ifFind)
  685. {
  686. continue;
  687. }
  688. MIXERCONTROL MixerControl;
  689. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  690. MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
  691. MixerLineControls.cbmxctrl = sizeof(MixerControl);
  692. MixerLineControls.pamxctrl = &MixerControl;
  693. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
  694. free(paMixerControls);
  695. /*MIXERCONTROLDETAILS mxcd;
  696. MIXERCONTROLDETAILS_UNSIGNED vol;
  697. vol.dwValue = nVolume;
  698. mxcd.hwndOwner = 0;
  699. mxcd.dwControlID = MixerControl.dwControlID;
  700. mxcd.cbStruct = sizeof(mxcd);
  701. mxcd.cbDetails = sizeof(vol);
  702. mxcd.paDetails = &vol;
  703. mxcd.cChannels = 1;
  704. mmr =mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE);
  705. if(mmr)
  706. return ;
  707. return ; */
  708. MIXERCONTROLDETAILS MixerControlDetails;
  709. PMIXERCONTROLDETAILS_UNSIGNED pMixerControlDetails_Unsigned;
  710. pMixerControlDetails_Unsigned = (PMIXERCONTROLDETAILS_UNSIGNED)malloc(1 * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
  711. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  712. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  713. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  714. MixerControlDetails.cChannels =1;
  715. MixerControlDetails.cMultipleItems =0;
  716. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  717. MixerControlDetails.paDetails = &pMixerControlDetails_Unsigned[0];
  718. pMixerControlDetails_Unsigned->dwValue= nVolume;
  719. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  720. free(pMixerControlDetails_Unsigned);
  721. //关闭混音器
  722. mixerClose(hMixer);
  723. }
  724. return ;
  725. }
  726. void MixerWrap::OutPutMicphoneVolume(int nVolume)
  727. {
  728. int mixerNum ;//总的混音器数量
  729. HMIXER hMixer; //混音器设备句柄
  730. MMRESULT mmr;//函数调用返回
  731. MIXERCAPS MixerCaps; //混音器设备能力信息
  732. MIXERLINE MixerLine;//线路的信息
  733. //获取当前系统总的混音器数量
  734. mixerNum= mixerGetNumDevs();
  735. bool ifFind =false;
  736. for(int i=0;i<mixerNum;i++)
  737. {
  738. //打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
  739. mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
  740. //取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
  741. //mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
  742. //获取混音器能力特征,如声音控制 和录音控制
  743. mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
  744. for(int j=0;j<MixerCaps.cDestinations;j++)
  745. //MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
  746. //如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
  747. {
  748. memset(&MixerLine,0,sizeof(MIXERLINE));
  749. MixerLine.cbStruct = sizeof(MixerLine);
  750. MixerLine.dwDestination = j;
  751. // 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  752. // 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  753. //MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  754. //mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
  755. //取录音控制
  756. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
  757. DWORD dwConnections = MixerLine.cConnections;
  758. for ( int count = 0; count < dwConnections; count++ )
  759. {
  760. MixerLine.dwSource = count;
  761. mmr=mixerGetLineInfo((HMIXEROBJ)hMixer,&MixerLine,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
  762. if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == MixerLine.dwComponentType)
  763. {
  764. //如果是录音控制的麦克风选项,则跳出
  765. ifFind =true;
  766. break;
  767. }
  768. }
  769. if (ifFind)
  770. {
  771. break;
  772. }
  773. }
  774. if(!ifFind)
  775. continue;
  776. //获取麦克风选项
  777. MIXERLINECONTROLS MixerLineControls;
  778. PMIXERCONTROL paMixerControls;
  779. paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
  780. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  781. MixerLineControls.dwLineID = MixerLine.dwLineID;
  782. MixerLineControls.cControls = MixerLine.cControls;
  783. MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
  784. MixerLineControls.pamxctrl = paMixerControls;
  785. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,
  786. MIXER_GETLINECONTROLSF_ALL);
  787. int u ;
  788. ifFind =false;
  789. for ( u = 0; u < MixerLine.cControls; u++)
  790. {
  791. if (_tcscmp(paMixerControls[u].szName,_T("麦克风音量"))==0 || _tcscmp(paMixerControls[u].szName,_T("静音"))==0)
  792. {
  793. ifFind =true;
  794. break;
  795. }
  796. }
  797. if (!ifFind)
  798. {
  799. continue;
  800. }
  801. MIXERCONTROL MixerControl;
  802. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  803. MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
  804. MixerLineControls.cbmxctrl = sizeof(MixerControl);
  805. MixerLineControls.pamxctrl = &MixerControl;
  806. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
  807. free(paMixerControls);
  808. MIXERCONTROLDETAILS MixerControlDetails;
  809. PMIXERCONTROLDETAILS_UNSIGNED pMixerControlDetails_Unsigned;
  810. pMixerControlDetails_Unsigned = (PMIXERCONTROLDETAILS_UNSIGNED)malloc(1 * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
  811. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  812. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  813. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  814. MixerControlDetails.cChannels =1;
  815. MixerControlDetails.cMultipleItems =0;
  816. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  817. MixerControlDetails.paDetails = &pMixerControlDetails_Unsigned[0];
  818. pMixerControlDetails_Unsigned->dwValue= nVolume;
  819. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  820. free(pMixerControlDetails_Unsigned);
  821. /*MIXERCONTROLDETAILS MixerControlDetails;
  822. PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
  823. pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc(1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  824. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  825. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  826. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  827. MixerControlDetails.cChannels =1;
  828. MixerControlDetails.cMultipleItems =0;
  829. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  830. MixerControlDetails.paDetails = &pMixerControlDetails_Boolean[0];
  831. pMixerControlDetails_Boolean[0].fValue = bIsMut;
  832. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  833. free(pMixerControlDetails_Boolean);*/
  834. //关闭混音器
  835. mixerClose(hMixer);
  836. }
  837. return ;
  838. }
  839. void MixerWrap::InPutMicphoneVolume(int nVolume)
  840. {
  841. int mixerNum ;//总的混音器数量
  842. HMIXER hMixer; //混音器设备句柄
  843. MMRESULT mmr;//函数调用返回
  844. MIXERCAPS MixerCaps; //混音器设备能力信息
  845. MIXERLINE MixerLine;//线路的信息
  846. //获取当前系统总的混音器数量
  847. mixerNum= mixerGetNumDevs();
  848. bool ifFind =false;
  849. for(int i=1;i<mixerNum;i++)
  850. {
  851. //打开混音器,第一个参数是记录混音器的handler,第二个参数是要打开的混音器ID
  852. mmr = mixerOpen(&hMixer, i, 0, 0L, MIXER_OBJECTF_MIXER);
  853. //取混音器id,第一个参数是混音器的handler,第二个参数记录混音器的id
  854. //mmr = mixerGetID((HMIXEROBJ)hMixer,&uMxid,MIXER_OBJECTF_HMIXER);
  855. //获取混音器能力特征,如声音控制 和录音控制
  856. mmr = mixerGetDevCaps((UINT)hMixer, &MixerCaps, sizeof(MixerCaps));
  857. for(int j=0;j<MixerCaps.cDestinations;j++)
  858. //MixerCaps.cDestinations表示此混音器设备的audio line目标的数量,
  859. //如一个audio line目标为“音量控制”,另一个audio line目标为“录音控制”。
  860. {
  861. memset(&MixerLine,0,sizeof(MIXERLINE));
  862. MixerLine.cbStruct = sizeof(MixerLine);
  863. MixerLine.dwDestination = j;
  864. // 音量控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
  865. // 录音控制目标line的component类型为MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  866. //MixerLine.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  867. //mixerGetLineInfo 第三个参数可以是:MIXER_GETLINEINFOF_COMPONENTTYPE,MIXER_GETLINEINFOF_SOURCE,MIXER_GETLINEINFOF_DESTINATION等
  868. //取录音控制
  869. mmr = mixerGetLineInfo((HMIXEROBJ)hMixer, &MixerLine, MIXER_GETLINEINFOF_DESTINATION);
  870. DWORD dwConnections = MixerLine.cConnections;
  871. for ( int count = 0; count < dwConnections; count++ )
  872. {
  873. MixerLine.dwSource = count;
  874. mmr=mixerGetLineInfo((HMIXEROBJ)hMixer,&MixerLine,MIXER_OBJECTF_MIXER | MIXER_GETLINEINFOF_SOURCE);
  875. if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == MixerLine.dwComponentType)
  876. {
  877. //如果是录音控制的麦克风选项,则跳出
  878. ifFind =true;
  879. break;
  880. }
  881. }
  882. if (ifFind)
  883. {
  884. break;
  885. }
  886. }
  887. if(!ifFind)
  888. continue;
  889. //获取麦克风选项
  890. MIXERLINECONTROLS MixerLineControls;
  891. PMIXERCONTROL paMixerControls;
  892. paMixerControls = (PMIXERCONTROL)malloc(sizeof(MIXERCONTROL) * MixerLine.cControls);
  893. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  894. MixerLineControls.dwLineID = MixerLine.dwLineID;
  895. MixerLineControls.cControls = MixerLine.cControls;
  896. MixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
  897. MixerLineControls.pamxctrl = paMixerControls;
  898. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls,
  899. MIXER_GETLINECONTROLSF_ALL);
  900. int u ;
  901. ifFind =false;
  902. for ( u = 0; u < MixerLine.cControls; u++)
  903. {
  904. if (_tcscmp(paMixerControls[u].szName,_T("麦克风输入音量"))==0 || _tcscmp(paMixerControls[u].szName,_T("麦克风音量"))==0)
  905. {
  906. ifFind =true;
  907. break;
  908. }
  909. }
  910. if (!ifFind)
  911. {
  912. continue;
  913. }
  914. MIXERCONTROL MixerControl;
  915. MixerLineControls.cbStruct = sizeof(MixerLineControls);
  916. MixerLineControls.dwControlID = paMixerControls[u].dwControlID;
  917. MixerLineControls.cbmxctrl = sizeof(MixerControl);
  918. MixerLineControls.pamxctrl = &MixerControl;
  919. mmr = mixerGetLineControls((HMIXEROBJ)hMixer, &MixerLineControls, MIXER_GETLINECONTROLSF_ONEBYID);
  920. free(paMixerControls);
  921. MIXERCONTROLDETAILS MixerControlDetails;
  922. PMIXERCONTROLDETAILS_UNSIGNED pMixerControlDetails_Unsigned;
  923. pMixerControlDetails_Unsigned = (PMIXERCONTROLDETAILS_UNSIGNED)malloc(1 * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
  924. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  925. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  926. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  927. MixerControlDetails.cChannels =1;
  928. MixerControlDetails.cMultipleItems =0;
  929. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  930. MixerControlDetails.paDetails = &pMixerControlDetails_Unsigned[0];
  931. pMixerControlDetails_Unsigned->dwValue= nVolume;
  932. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  933. free(pMixerControlDetails_Unsigned);
  934. /*MIXERCONTROLDETAILS MixerControlDetails;
  935. PMIXERCONTROLDETAILS_BOOLEAN pMixerControlDetails_Boolean;
  936. pMixerControlDetails_Boolean = (PMIXERCONTROLDETAILS_BOOLEAN)malloc(1 * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  937. memset(&MixerControlDetails,0,sizeof(MixerControlDetails));
  938. MixerControlDetails.cbStruct = sizeof(MixerControlDetails);
  939. MixerControlDetails.dwControlID = MixerControl.dwControlID;
  940. MixerControlDetails.cChannels =1;
  941. MixerControlDetails.cMultipleItems =0;
  942. MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  943. MixerControlDetails.paDetails = &pMixerControlDetails_Boolean[0];
  944. pMixerControlDetails_Boolean[0].fValue = bIsMut;
  945. mmr = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
  946. free(pMixerControlDetails_Boolean);*/
  947. //关闭混音器
  948. mixerClose(hMixer);
  949. }
  950. return ;
  951. }
  952. bool MixerWrap::GetSpeakerValue_W7(float &fVolume)
  953. {
  954. IMMDeviceEnumerator* pEnumerator;
  955. IMMDeviceCollection *pCollection = NULL;
  956. IMMDevice *pDevice=NULL;
  957. IPropertyStore *pProperties=NULL;
  958. IAudioEndpointVolume *pVolumeAPI=NULL;
  959. UINT deviceCount = 0;
  960. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  961. HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);
  962. if (hr != S_OK)
  963. {
  964. printf("CoCreateInstance Failed!/n");
  965. return 0;
  966. }
  967. hr = pEnumerator->EnumAudioEndpoints(/*eCapture*/ eRender, DEVICE_STATE_ACTIVE, &pCollection);
  968. //hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATEMASK_ALL , &pCollection );
  969. if (hr != S_OK)
  970. {
  971. printf("EnumAudioEndpoints Failed!/n");
  972. goto releasepEnumerator;
  973. }
  974. hr = pCollection->GetCount(&deviceCount);
  975. if (hr != S_OK)
  976. {
  977. printf("GetCount Failed!/n");
  978. goto releasepCollection;
  979. }
  980. for (UINT dev=0;dev<deviceCount;dev++)
  981. {
  982. pDevice = NULL;
  983. hr = pCollection->Item(dev,&pDevice);
  984. if (hr == S_OK)
  985. {
  986. hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);
  987. if (hr == S_OK)
  988. {
  989. PROPVARIANT varName;
  990. PropVariantInit(&varName);
  991. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  992. if (hr == S_OK )
  993. {
  994. //::MessageBox(NULL,varName.pwszVal,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  995. // if (wcsstr(varName.pwszVal,_T("扬声器"))!=NULL)
  996. {
  997. hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));
  998. if (hr==S_OK)
  999. {
  1000. UINT chanelCount = 0;
  1001. hr =pVolumeAPI->GetChannelCount(&chanelCount);
  1002. for (int i=0;i<chanelCount;i++)
  1003. {
  1004. float fVolumeTemp;
  1005. pVolumeAPI->GetMasterVolumeLevelScalar(&fVolumeTemp);
  1006. if(fabsf(fVolumeTemp -0) > 0.00001)
  1007. fVolume = 100 * fVolumeTemp + 0.5;
  1008. }
  1009. SAFE_RELEASE(pVolumeAPI);
  1010. }
  1011. }
  1012. }
  1013. SAFE_RELEASE(pProperties);
  1014. }
  1015. SAFE_RELEASE(pDevice);
  1016. }
  1017. }
  1018. releasepCollection:
  1019. SAFE_RELEASE(pCollection);
  1020. releasepEnumerator:
  1021. SAFE_RELEASE(pEnumerator);
  1022. return 0;
  1023. }
  1024. bool MixerWrap::SetSpeakerValue_W7(float fVolume) //设置喇叭音量
  1025. {
  1026. IMMDeviceEnumerator* pEnumerator;
  1027. IMMDeviceCollection *pCollection = NULL;
  1028. IMMDevice *pDevice=NULL;
  1029. IPropertyStore *pProperties=NULL;
  1030. IAudioEndpointVolume *pVolumeAPI=NULL;
  1031. IAudioAutoGainControl* pAutoGain=NULL;
  1032. GUID m_guidMyContext;
  1033. UINT deviceCount = 0;
  1034. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  1035. HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);
  1036. if (hr != S_OK)
  1037. {
  1038. printf("CoCreateInstance Failed!/n");
  1039. return 0;
  1040. }
  1041. hr = pEnumerator->EnumAudioEndpoints(/*eCapture*/ eRender, DEVICE_STATE_ACTIVE, &pCollection);
  1042. //hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATEMASK_ALL , &pCollection );
  1043. if (hr != S_OK)
  1044. {
  1045. printf("EnumAudioEndpoints Failed!/n");
  1046. goto releasepEnumerator;
  1047. }
  1048. hr = pCollection->GetCount(&deviceCount);
  1049. if (hr != S_OK)
  1050. {
  1051. printf("GetCount Failed!/n");
  1052. goto releasepCollection;
  1053. }
  1054. for (UINT dev=0;dev<deviceCount;dev++)
  1055. {
  1056. pDevice = NULL;
  1057. hr = pCollection->Item(dev,&pDevice);
  1058. if (hr == S_OK)
  1059. {
  1060. hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);
  1061. if (hr == S_OK)
  1062. {
  1063. PROPVARIANT varName;
  1064. PropVariantInit(&varName);
  1065. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  1066. if (hr == S_OK )
  1067. {
  1068. //::MessageBox(NULL,varName.pwszVal,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1069. // if (wcsstr(varName.pwszVal,_T("扬声器"))!=NULL)
  1070. {
  1071. //hr=pDevice->Activate(__uuidof(IAudioAutoGainControl),CLSCTX_ALL,NULL,(void **)(&pAutoGain));
  1072. hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));
  1073. if (hr==S_OK)
  1074. {
  1075. UINT chanelCount = 0;
  1076. hr =pVolumeAPI->GetChannelCount(&chanelCount);
  1077. for (int i=0;i<chanelCount;i++)
  1078. {
  1079. if((int)fVolume < 0)
  1080. fVolume = 0;
  1081. if((int)fVolume > MAX_VOL)
  1082. fVolume = MAX_VOL;
  1083. pVolumeAPI->SetMasterVolumeLevelScalar((float)fVolume / MAX_VOL, &m_guidMyContext);
  1084. }
  1085. SAFE_RELEASE(pVolumeAPI);
  1086. }
  1087. }
  1088. }
  1089. SAFE_RELEASE(pProperties);
  1090. }
  1091. SAFE_RELEASE(pDevice);
  1092. }
  1093. }
  1094. releasepCollection:
  1095. SAFE_RELEASE(pCollection);
  1096. releasepEnumerator:
  1097. SAFE_RELEASE(pEnumerator);
  1098. return 0;
  1099. }
  1100. bool MixerWrap::MutSpeaker_W7(bool bMute,float fVolume)
  1101. {
  1102. //::MessageBox(NULL,_T("MutSpeaker_W7"),_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1103. IMMDeviceEnumerator* pEnumerator;
  1104. IMMDeviceCollection *pCollection = NULL;
  1105. IMMDevice *pDevice=NULL;
  1106. IPropertyStore *pProperties=NULL;
  1107. IAudioEndpointVolume *pVolumeAPI=NULL;
  1108. IAudioAutoGainControl* pAutoGain=NULL;
  1109. UINT deviceCount = 0;
  1110. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  1111. HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);
  1112. if (hr != S_OK)
  1113. {
  1114. printf("CoCreateInstance Failed!/n");
  1115. return 0;
  1116. }
  1117. hr = pEnumerator->EnumAudioEndpoints(/*eCapture*/ eRender, DEVICE_STATE_ACTIVE, &pCollection);
  1118. //hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATEMASK_ALL , &pCollection );
  1119. if (hr != S_OK)
  1120. {
  1121. printf("EnumAudioEndpoints Failed!/n");
  1122. goto releasepEnumerator;
  1123. }
  1124. hr = pCollection->GetCount(&deviceCount);
  1125. if (hr != S_OK)
  1126. {
  1127. printf("GetCount Failed!/n");
  1128. goto releasepCollection;
  1129. }
  1130. for (UINT dev=0;dev<deviceCount;dev++)
  1131. {
  1132. pDevice = NULL;
  1133. hr = pCollection->Item(dev,&pDevice);
  1134. if (hr == S_OK)
  1135. {
  1136. hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);
  1137. if (hr == S_OK)
  1138. {
  1139. PROPVARIANT varName;
  1140. PropVariantInit(&varName);
  1141. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  1142. /* char temp[20];
  1143. sprintf_s(temp,"%d\0",hr);
  1144. _bstr_t strStr = temp;
  1145. LPCSTR lpctStrName = strStr;
  1146. ::MessageBox(NULL,(LPCWSTR)lpctStrName,_T("提示信息"),MB_OK | MB_ICONINFORMATION);*/
  1147. if (hr == S_OK )
  1148. {
  1149. //::MessageBox(NULL,varName.pwszVal,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1150. if (wcsstr(varName.pwszVal,L"扬声器")!=NULL)
  1151. {
  1152. //hr=pDevice->Activate(__uuidof(IAudioAutoGainControl),CLSCTX_ALL,NULL,(void **)(&pAutoGain));
  1153. hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));
  1154. if (hr==S_OK)
  1155. {
  1156. UINT chanelCount = 0;
  1157. hr =pVolumeAPI->GetChannelCount(&chanelCount);
  1158. for (int i=0;i<chanelCount;i++)
  1159. {
  1160. float fLevel =0;
  1161. float minLevel =0;
  1162. float maxLevel =0;
  1163. float stepLevel =0;
  1164. pVolumeAPI->GetVolumeRange(&minLevel,&maxLevel,&stepLevel);
  1165. float fVolumeTemp;
  1166. pVolumeAPI->GetMasterVolumeLevelScalar(&fVolumeTemp);
  1167. if(fVolume != NULL)
  1168. fVolume = 100 * fVolumeTemp + 0.5;
  1169. pVolumeAPI->SetChannelVolumeLevelScalar(i,fVolume,NULL);
  1170. int test=55;
  1171. }
  1172. hr = pVolumeAPI->SetMute(bMute,NULL);
  1173. SAFE_RELEASE(pVolumeAPI);
  1174. }
  1175. }
  1176. }
  1177. SAFE_RELEASE(pProperties);
  1178. }
  1179. SAFE_RELEASE(pDevice);
  1180. }
  1181. }
  1182. releasepCollection:
  1183. SAFE_RELEASE(pCollection);
  1184. releasepEnumerator:
  1185. SAFE_RELEASE(pEnumerator);
  1186. return 0;
  1187. }
  1188. int MixerWrap::GetMicphone_W7(DWORD &pdwVolume)
  1189. {
  1190. IMMDeviceEnumerator* pEnumerator;
  1191. IMMDeviceCollection *pCollection = NULL;
  1192. IMMDevice *pDevice=NULL;
  1193. IPropertyStore *pProperties=NULL;
  1194. IAudioEndpointVolume *pVolumeAPI=NULL;
  1195. UINT deviceCount = 0;
  1196. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  1197. HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);
  1198. if (hr != S_OK)
  1199. {
  1200. //printf("CoCreateInstance Failed!/n");
  1201. return 0;
  1202. }
  1203. hr = pEnumerator->EnumAudioEndpoints(eCapture /*eRender*/, DEVICE_STATE_ACTIVE, &pCollection);
  1204. //hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATEMASK_ALL , &pCollection );
  1205. if (hr != S_OK)
  1206. {
  1207. // printf("EnumAudioEndpoints Failed!/n");
  1208. goto releasepEnumerator;
  1209. }
  1210. //::MessageBox(NULL,_T("MicphoneMut_W7"),_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1211. hr = pCollection->GetCount(&deviceCount);
  1212. if (hr != S_OK)
  1213. {
  1214. //printf("GetCount Failed!/n");
  1215. goto releasepCollection;
  1216. }
  1217. for (UINT dev=0;dev<deviceCount;dev++)
  1218. {
  1219. pDevice = NULL;
  1220. hr = pCollection->Item(dev,&pDevice);
  1221. if (hr == S_OK)
  1222. {
  1223. hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);
  1224. if (hr == S_OK)
  1225. {
  1226. PROPVARIANT varName;
  1227. PropVariantInit(&varName);
  1228. //hr = pProperties->GetValue(PKEY_Device_BusTypeGuid, &varName);
  1229. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  1230. if (hr == S_OK )
  1231. {
  1232. if (wcsstr(varName.pwszVal,L"麦克风")!=NULL)
  1233. {
  1234. hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));
  1235. if (hr==S_OK)
  1236. {
  1237. float fVolume;
  1238. pVolumeAPI->GetMasterVolumeLevelScalar(&fVolume);
  1239. pdwVolume = 100 * fVolume + 0.5;
  1240. SAFE_RELEASE(pVolumeAPI);
  1241. }
  1242. }
  1243. }
  1244. SAFE_RELEASE(pProperties);
  1245. }
  1246. SAFE_RELEASE(pDevice);
  1247. }
  1248. }
  1249. releasepCollection:
  1250. SAFE_RELEASE(pCollection);
  1251. releasepEnumerator:
  1252. SAFE_RELEASE(pEnumerator);
  1253. return 0;
  1254. }
  1255. bool MixerWrap::MicphoneMut_W7(bool bMute,float fVolume)
  1256. {
  1257. IMMDeviceEnumerator* pEnumerator;
  1258. IMMDeviceCollection *pCollection = NULL;
  1259. IMMDevice *pDevice=NULL;
  1260. IPropertyStore *pProperties=NULL;
  1261. IAudioEndpointVolume *pVolumeAPI=NULL;
  1262. UINT deviceCount = 0;
  1263. GUID m_guidMyContext;
  1264. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  1265. HRESULT hr=CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),(void**)&pEnumerator);
  1266. if (hr != S_OK)
  1267. {
  1268. //printf("CoCreateInstance Failed!/n");
  1269. return 0;
  1270. }
  1271. hr = pEnumerator->EnumAudioEndpoints(eCapture /*eRender*/, DEVICE_STATE_ACTIVE, &pCollection);
  1272. //hr = pEnumerator->EnumAudioEndpoints( eRender , DEVICE_STATEMASK_ALL , &pCollection );
  1273. if (hr != S_OK)
  1274. {
  1275. // printf("EnumAudioEndpoints Failed!/n");
  1276. goto releasepEnumerator;
  1277. }
  1278. //::MessageBox(NULL,_T("MicphoneMut_W7"),_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1279. hr = pCollection->GetCount(&deviceCount);
  1280. if (hr != S_OK)
  1281. {
  1282. //printf("GetCount Failed!/n");
  1283. goto releasepCollection;
  1284. }
  1285. for (UINT dev=0;dev<deviceCount;dev++)
  1286. {
  1287. pDevice = NULL;
  1288. hr = pCollection->Item(dev,&pDevice);
  1289. if (hr == S_OK)
  1290. {
  1291. hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);
  1292. if (hr == S_OK)
  1293. {
  1294. PROPVARIANT varName;
  1295. PropVariantInit(&varName);
  1296. //hr = pProperties->GetValue(PKEY_Device_BusTypeGuid, &varName);
  1297. hr = pProperties->GetValue(PKEY_Device_FriendlyName, &varName);
  1298. if (hr == S_OK )
  1299. {
  1300. //if (wcsstr(varName.pwszVal,_T("Line In"))!=NULL)
  1301. //if (wcsstr(varName.pwszVal,_T("线路输入"))!=NULL)
  1302. //::MessageBox(NULL,varName.pwszVal,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1303. if (wcsstr(varName.pwszVal,L"麦克风")!=NULL)
  1304. {
  1305. hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));
  1306. if (hr==S_OK)
  1307. {
  1308. hr = pVolumeAPI->SetMute(bMute,NULL);
  1309. // hr = pVolumeAPI->SetChannelVolumeLevelScalar(0,fVolume,NULL);
  1310. pVolumeAPI->SetMasterVolumeLevelScalar((float)fVolume / 100,&m_guidMyContext);
  1311. SAFE_RELEASE(pVolumeAPI);
  1312. }
  1313. }
  1314. }
  1315. SAFE_RELEASE(pProperties);
  1316. }
  1317. SAFE_RELEASE(pDevice);
  1318. }
  1319. }
  1320. releasepCollection:
  1321. SAFE_RELEASE(pCollection);
  1322. releasepEnumerator:
  1323. SAFE_RELEASE(pEnumerator);
  1324. return 0;
  1325. }
  1326. int MixerWrap::SelectRecordIn(DWORD dwSrcType)
  1327. {
  1328. try{
  1329. HMIXER m_hmx; //混音器设备句柄
  1330. MMRESULT mmr = mixerOpen(&m_hmx, 1, 0, 0L, MIXER_OBJECTF_MIXER);
  1331. MIXERLINE mxl;
  1332. mxl.cbStruct = sizeof(mxl);
  1333. mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  1334. mixerGetLineInfo((HMIXEROBJ)m_hmx, &mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);
  1335. LPMIXERCONTROL pmxctrl ;
  1336. DWORD cbmxctrls = sizeof(*pmxctrl) * (UINT)mxl.cControls;
  1337. pmxctrl = (LPMIXERCONTROL)LocalAlloc(LPTR, cbmxctrls);
  1338. MIXERLINECONTROLS mxlctrl={sizeof(mxlctrl),mxl.dwLineID,0,mxl.cControls,sizeof(MIXERCONTROL),pmxctrl};
  1339. mixerGetLineControls((HMIXEROBJ)m_hmx, &mxlctrl,MIXER_GETLINECONTROLSF_ALL);
  1340. DWORD i;
  1341. for(i=0; i < mxl.cControls; i++)
  1342. if (MIXERCONTROL_CT_CLASS_LIST == (pmxctrl[i].dwControlType&MIXERCONTROL_CT_CLASS_MASK))
  1343. break;
  1344. wchar_t temp[50];
  1345. swprintf(temp,L"mxl.cControls:%d ",mxl.cControls);
  1346. _bstr_t strStr = temp;
  1347. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1348. if (i < mxl.cControls)
  1349. {
  1350. BOOL bOneItemOnly = FALSE;
  1351. switch (pmxctrl[i].dwControlType)
  1352. {
  1353. case MIXERCONTROL_CONTROLTYPE_MUX:
  1354. case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
  1355. bOneItemOnly = TRUE;
  1356. }
  1357. DWORD cChannels = mxl.cChannels, cMultipleItems = 0;
  1358. if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl[i].fdwControl)
  1359. cChannels = 1;
  1360. if (MIXERCONTROL_CONTROLF_MULTIPLE & pmxctrl[i].fdwControl)
  1361. cMultipleItems = pmxctrl[i].cMultipleItems;
  1362. // Get the text description of each item
  1363. LPMIXERCONTROLDETAILS_LISTTEXT plisttext =(LPMIXERCONTROLDETAILS_LISTTEXT)
  1364. malloc(cChannels * cMultipleItems * sizeof(MIXERCONTROLDETAILS_LISTTEXT));
  1365. MIXERCONTROLDETAILS mxcd = {sizeof(mxcd), pmxctrl[i].dwControlID,cChannels,(HWND)cMultipleItems, sizeof(MIXERCONTROLDETAILS_LISTTEXT),(LPVOID) plisttext};
  1366. mixerGetControlDetails((HMIXEROBJ)m_hmx, &mxcd,MIXER_GETCONTROLDETAILSF_LISTTEXT);
  1367. LPMIXERCONTROLDETAILS_BOOLEAN plistbool =(LPMIXERCONTROLDETAILS_BOOLEAN)
  1368. malloc(cChannels * cMultipleItems * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  1369. mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  1370. mxcd.paDetails = plistbool;
  1371. mixerGetControlDetails((HMIXEROBJ)m_hmx, &mxcd,MIXER_GETCONTROLDETAILSF_VALUE);
  1372. wchar_t temp[50];
  1373. swprintf(temp,L"cMultipleItems:%d ",cMultipleItems);
  1374. _bstr_t strStr = temp;
  1375. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1376. for (DWORD j=0; j <cMultipleItems; j = j + cChannels)
  1377. {
  1378. wchar_t temp[50];
  1379. swprintf(temp,L"Name:%s,P1:%d P2:%d,Type:%d",plisttext[j].szName,plisttext[j].dwParam1,plisttext[j].dwParam2,dwSrcType);
  1380. _bstr_t strStr = temp;
  1381. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1382. if (plisttext[j].dwParam2==dwSrcType||plisttext[j].dwParam1==dwSrcType)
  1383. {
  1384. plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 1;
  1385. }
  1386. else if (bOneItemOnly)
  1387. plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 0;
  1388. }
  1389. mixerSetControlDetails((HMIXEROBJ)m_hmx, &mxcd,MIXER_GETCONTROLDETAILSF_VALUE);
  1390. // free(pmxctrl);
  1391. free(plisttext);
  1392. free(plistbool);
  1393. }
  1394. else
  1395. free(pmxctrl);
  1396. return TRUE;
  1397. }
  1398. catch(...)
  1399. {
  1400. return FALSE;
  1401. }
  1402. }
  1403. int MixerWrap::SelectRecordInByName(TCHAR* szSrcName)
  1404. {
  1405. try{
  1406. HMIXER m_hmx; //混音器设备句柄
  1407. MMRESULT mmr = mixerOpen(&m_hmx, 1, 0, 0L, MIXER_OBJECTF_MIXER);
  1408. MIXERLINE mxl;
  1409. mxl.cbStruct = sizeof(mxl);
  1410. mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
  1411. mixerGetLineInfo((HMIXEROBJ)m_hmx, &mxl,MIXER_GETLINEINFOF_COMPONENTTYPE);
  1412. LPMIXERCONTROL pmxctrl ;
  1413. DWORD cbmxctrls = sizeof(*pmxctrl) * (UINT)mxl.cControls;
  1414. pmxctrl = (LPMIXERCONTROL)LocalAlloc(LPTR, cbmxctrls);
  1415. MIXERLINECONTROLS mxlctrl={sizeof(mxlctrl),mxl.dwLineID,0,mxl.cControls,sizeof(MIXERCONTROL),pmxctrl};
  1416. mixerGetLineControls((HMIXEROBJ)m_hmx, &mxlctrl,MIXER_GETLINECONTROLSF_ALL);
  1417. DWORD i;
  1418. for(i=0; i < mxl.cControls; i++)
  1419. if (MIXERCONTROL_CT_CLASS_LIST == (pmxctrl[i].dwControlType&MIXERCONTROL_CT_CLASS_MASK))
  1420. break;
  1421. wchar_t temp[50];
  1422. swprintf(temp,L"mxl.cControls:%d ",mxl.cControls);
  1423. _bstr_t strStr = temp;
  1424. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1425. if (i < mxl.cControls)
  1426. {
  1427. BOOL bOneItemOnly = FALSE;
  1428. switch (pmxctrl[i].dwControlType)
  1429. {
  1430. case MIXERCONTROL_CONTROLTYPE_MUX:
  1431. case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
  1432. bOneItemOnly = TRUE;
  1433. }
  1434. DWORD cChannels = mxl.cChannels, cMultipleItems = 0;
  1435. if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl[i].fdwControl)
  1436. cChannels = 1;
  1437. if (MIXERCONTROL_CONTROLF_MULTIPLE & pmxctrl[i].fdwControl)
  1438. cMultipleItems = pmxctrl[i].cMultipleItems;
  1439. // Get the text description of each item
  1440. LPMIXERCONTROLDETAILS_LISTTEXT plisttext =(LPMIXERCONTROLDETAILS_LISTTEXT)
  1441. malloc(cChannels * cMultipleItems * sizeof(MIXERCONTROLDETAILS_LISTTEXT));
  1442. MIXERCONTROLDETAILS mxcd = {sizeof(mxcd), pmxctrl[i].dwControlID,cChannels,(HWND)cMultipleItems, sizeof(MIXERCONTROLDETAILS_LISTTEXT),(LPVOID) plisttext};
  1443. mixerGetControlDetails((HMIXEROBJ)m_hmx, &mxcd,MIXER_GETCONTROLDETAILSF_LISTTEXT);
  1444. LPMIXERCONTROLDETAILS_BOOLEAN plistbool =(LPMIXERCONTROLDETAILS_BOOLEAN)
  1445. malloc(cChannels * cMultipleItems * sizeof(MIXERCONTROLDETAILS_BOOLEAN));
  1446. mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  1447. mxcd.paDetails = plistbool;
  1448. mixerGetControlDetails((HMIXEROBJ)m_hmx, &mxcd,MIXER_GETCONTROLDETAILSF_VALUE);
  1449. wchar_t temp[50];
  1450. swprintf(temp,L"cMultipleItems:%d ",cMultipleItems);
  1451. _bstr_t strStr = temp;
  1452. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1453. for (DWORD j=0; j <cMultipleItems; j = j + cChannels)
  1454. {
  1455. wchar_t temp[50];
  1456. swprintf(temp,L"Name:%s,P1:%d P2:%d,Type:%s",plisttext[j].szName,plisttext[j].dwParam1,plisttext[j].dwParam2,szSrcName);
  1457. _bstr_t strStr = temp;
  1458. // ::MessageBox(NULL,(LPCWSTR)strStr,_T("提示信息"),MB_OK | MB_ICONINFORMATION);
  1459. /*if (plisttext[j].dwParam2==dwSrcType||plisttext[j].dwParam1==dwSrcType)
  1460. {
  1461. plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 1;
  1462. }
  1463. else if (bOneItemOnly)
  1464. plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 0; */
  1465. if (_tcsstr(plisttext[j].szName,szSrcName)!=NULL )
  1466. {
  1467. plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 1;
  1468. }
  1469. else if (bOneItemOnly)
  1470. plistbool[j].fValue = plistbool[j+ cChannels - 1].fValue = 0;
  1471. }
  1472. mixerSetControlDetails((HMIXEROBJ)m_hmx, &mxcd,MIXER_GETCONTROLDETAILSF_VALUE);
  1473. // free(pmxctrl);
  1474. free(plisttext);
  1475. free(plistbool);
  1476. }
  1477. else
  1478. free(pmxctrl);
  1479. return TRUE;
  1480. }
  1481. catch(...)
  1482. {
  1483. return FALSE;
  1484. }
  1485. }