MixerMicrophoneValue.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. #include "MixerMicrophoneValue.h"
  2. #include <vector>
  3. #include <algorithm>
  4. #include <string>
  5. #include <unordered_map>
  6. #include <iostream>
  7. #include <exception>
  8. namespace MixerMicrophoneValue_namespace
  9. {
  10. std::unordered_map<size_t,std::string> map_componenttype;
  11. std::unordered_map<size_t,std::string> map_controltype;
  12. const char *GetTextErrorMMSystem(int err)
  13. {
  14. const char *res = nullptr;
  15. switch(err)
  16. {
  17. case MMSYSERR_NOERROR :res="MMSYSERR_NOERROR";break;
  18. case MMSYSERR_ERROR :res="MMSYSERR_ERROR";break;
  19. case MMSYSERR_BADDEVICEID :res="MMSYSERR_BADDEVICEID";break;
  20. case MMSYSERR_NOTENABLED :res="MMSYSERR_NOTENABLED";break;
  21. case MMSYSERR_ALLOCATED :res="MMSYSERR_ALLOCATED";break;
  22. case MMSYSERR_INVALHANDLE :res="MMSYSERR_INVALHANDLE";break;
  23. case MMSYSERR_NODRIVER :res="MMSYSERR_NODRIVER";break;
  24. case MMSYSERR_NOMEM :res="MMSYSERR_NOMEM";break;
  25. case MMSYSERR_NOTSUPPORTED :res="MMSYSERR_NOTSUPPORTED";break;
  26. case MMSYSERR_BADERRNUM :res="MMSYSERR_BADERRNUM";break;
  27. case MMSYSERR_INVALFLAG :res="MMSYSERR_INVALFLAG";break;
  28. case MMSYSERR_INVALPARAM :res="MMSYSERR_INVALPARAM";break;
  29. case MMSYSERR_HANDLEBUSY :res="MMSYSERR_HANDLEBUSY";break;
  30. case MMSYSERR_INVALIDALIAS :res="MMSYSERR_INVALIDALIAS";break;
  31. case MMSYSERR_BADDB :res="MMSYSERR_BADDB";break;
  32. case MMSYSERR_KEYNOTFOUND :res="MMSYSERR_KEYNOTFOUND";break;
  33. case MMSYSERR_READERROR :res="MMSYSERR_READERROR";break;
  34. case MMSYSERR_WRITEERROR :res="MMSYSERR_WRITEERROR";break;
  35. case MMSYSERR_DELETEERROR :res="MMSYSERR_DELETEERROR";break;
  36. case MMSYSERR_VALNOTFOUND :res="MMSYSERR_VALNOTFOUND";break;
  37. case MMSYSERR_NODRIVERCB :res="MMSYSERR_NODRIVERCB";break;
  38. // case MMSYSERR_MOREDATA :res="MMSYSERR_MOREDATA ";break;
  39. case MIXERR_INVALCONTROL :res="MIXERR_INVALCONTROL";break;
  40. }
  41. return res;
  42. }
  43. void FillComponetAndControlTypeMessges()
  44. {
  45. map_componenttype.clear();
  46. map_controltype.clear();
  47. using namespace std;
  48. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL,"MIXERLINE_COMPONENTTYPE_SRC_DIGITAL"));
  49. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_LINE,"MIXERLINE_COMPONENTTYPE_SRC_LINE"));
  50. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,"MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE"));
  51. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER,"MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER"));
  52. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC,"MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC"));
  53. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE,"MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE"));
  54. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER,"MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER"));
  55. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,"MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT"));
  56. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY,"MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY"));
  57. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_ANALOG,"MIXERLINE_COMPONENTTYPE_SRC_ANALOG"));
  58. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED,"MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED"));
  59. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_DIGITAL,"MIXERLINE_COMPONENTTYPE_DST_DIGITAL"));
  60. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_LINE,"MIXERLINE_COMPONENTTYPE_DST_LINE"));
  61. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_MONITOR,"MIXERLINE_COMPONENTTYPE_DST_MONITOR"));
  62. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,"MIXERLINE_COMPONENTTYPE_DST_SPEAKERS"));
  63. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES,"MIXERLINE_COMPONENTTYPE_DST_HEADPHONES"));
  64. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE,"MIXERLINE_COMPONENTTYPE_DST_TELEPHONE"));
  65. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_WAVEIN,"MIXERLINE_COMPONENTTYPE_DST_WAVEIN"));
  66. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_VOICEIN,"MIXERLINE_COMPONENTTYPE_DST_VOICEIN"));
  67. map_componenttype.insert(pair<size_t,string>(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED,"MIXERLINE_COMPONENTTYPE_DST_UNDEFINED"));
  68. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_BASS ,"MIXERCONTROL_CONTROLTYPE_BASS "));
  69. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_EQUALIZER ,"MIXERCONTROL_CONTROLTYPE_EQUALIZER "));
  70. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_FADER ,"MIXERCONTROL_CONTROLTYPE_FADER "));
  71. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_TREBLE ,"MIXERCONTROL_CONTROLTYPE_TREBLE "));
  72. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_VOLUME,"MIXERCONTROL_CONTROLTYPE_VOLUME"));
  73. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MIXER ,"MIXERCONTROL_CONTROLTYPE_MIXER "));
  74. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT ,"MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT "));
  75. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MUX ,"MIXERCONTROL_CONTROLTYPE_MUX "));
  76. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_SINGLESELECT,"MIXERCONTROL_CONTROLTYPE_SINGLESELECT"));
  77. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER ,"MIXERCONTROL_CONTROLTYPE_BOOLEANMETER "));
  78. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_PEAKMETER ,"MIXERCONTROL_CONTROLTYPE_PEAKMETER "));
  79. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER ,"MIXERCONTROL_CONTROLTYPE_SIGNEDMETER "));
  80. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER,"MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER"));
  81. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_DECIBELS ,"MIXERCONTROL_CONTROLTYPE_DECIBELS "));
  82. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_PERCENT ,"MIXERCONTROL_CONTROLTYPE_PERCENT "));
  83. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_SIGNED ,"MIXERCONTROL_CONTROLTYPE_SIGNED "));
  84. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_UNSIGNED,"MIXERCONTROL_CONTROLTYPE_UNSIGNED"));
  85. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_PAN ,"MIXERCONTROL_CONTROLTYPE_PAN "));
  86. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN ,"MIXERCONTROL_CONTROLTYPE_QSOUNDPAN "));
  87. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_SLIDER,"MIXERCONTROL_CONTROLTYPE_SLIDER"));
  88. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_BOOLEAN ,"MIXERCONTROL_CONTROLTYPE_BOOLEAN "));
  89. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_BUTTON,"MIXERCONTROL_CONTROLTYPE_BUTTON"));
  90. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_LOUDNESS ,"MIXERCONTROL_CONTROLTYPE_LOUDNESS "));
  91. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MONO,"MIXERCONTROL_CONTROLTYPE_MONO"));
  92. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MUTE,"MIXERCONTROL_CONTROLTYPE_MUTE"));
  93. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_ONOFF,"MIXERCONTROL_CONTROLTYPE_ONOFF"));
  94. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_STEREOENH,"MIXERCONTROL_CONTROLTYPE_STEREOENH"));
  95. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MICROTIME,"MIXERCONTROL_CONTROLTYPE_MICROTIME"));
  96. map_controltype.insert(pair<size_t,string>(MIXERCONTROL_CONTROLTYPE_MILLITIME,"MIXERCONTROL_CONTROLTYPE_MILLITIME"));
  97. }
  98. };
  99. using namespace MixerMicrophoneValue_namespace;
  100. using namespace std;
  101. MixerMicrophoneValue::MixerMicrophoneValue(void)
  102. {
  103. flagLinkedToDeviceControl = false;
  104. defaultname.assign("default");
  105. MixerMicrophoneValue_namespace::FillComponetAndControlTypeMessges();
  106. }
  107. MixerMicrophoneValue::~MixerMicrophoneValue(void)
  108. {
  109. Release();
  110. }
  111. const string &MixerMicrophoneValue::GetNameOfLinkedDevice()
  112. {
  113. return NameOfLinkedWaveIn;
  114. }
  115. void MixerMicrophoneValue::Release(void)
  116. {
  117. flagLinkedToDeviceControl=false;
  118. }
  119. int MixerMicrophoneValue::CheckDefaultInDevice(void)
  120. {//return 0 in success
  121. try
  122. {
  123. int res=0;
  124. std::string resstring;
  125. WAVEFORMATEX wf;
  126. HWAVEIN HWI;
  127. int SamplesPerSec=16000;
  128. int BitsPerSample=16;
  129. int channels=2;
  130. wf.wBitsPerSample=static_cast<unsigned short>(BitsPerSample);
  131. wf.nAvgBytesPerSec=SamplesPerSec*BitsPerSample/8;
  132. wf.nChannels=static_cast<unsigned short>(channels);
  133. wf.nSamplesPerSec=SamplesPerSec;
  134. wf.wFormatTag=WAVE_FORMAT_PCM;
  135. wf.nBlockAlign=channels*BitsPerSample/8;
  136. wf.cbSize=0;
  137. //Name of default device restoring by waveInOpen with parameter WAVE_MAPPER
  138. int resOfOpen = waveInOpen(&HWI,WAVE_MAPPER,&wf,NULL,NULL,CALLBACK_NULL);
  139. if(resOfOpen == MMSYSERR_NOERROR)
  140. {
  141. HMIXER mixerHandle;
  142. MMRESULT err = mixerOpen(&mixerHandle, (UINT)HWI, 0, 0, MIXER_OBJECTF_HWAVEIN);
  143. if(!err)
  144. {
  145. MIXERCAPSA mixcaps;
  146. if (!mixerGetDevCapsA((UINT)mixerHandle, &mixcaps, sizeof(MIXERCAPSA)))
  147. {
  148. //found
  149. resstring.assign(mixcaps.szPname);
  150. NameOfDefaultWaveIn=resstring;
  151. }
  152. mixerClose(mixerHandle);
  153. }else
  154. {
  155. cerr<<"CheckDefaultInDevice error: "<<GetTextErrorMMSystem(err);
  156. res=-2;
  157. }
  158. waveInClose(HWI);
  159. }else{
  160. cerr<<"CheckDefaultInDevice error: "<<GetTextErrorMMSystem(resOfOpen);
  161. res=-1;
  162. }
  163. return res;
  164. }
  165. catch (std::exception &e)
  166. {
  167. myDebug()<<e.what();
  168. return -1;
  169. }
  170. }
  171. double MixerMicrophoneValue::GetVolume(void)
  172. {// 0.-1.
  173. try
  174. {
  175. double res=0.;
  176. double Volume_01=0.;
  177. if(flagLinkedToDeviceControl)
  178. {
  179. MMRESULT result;
  180. HMIXER hMixer;
  181. // get a handle to the mixer device
  182. result = mixerOpen(&hMixer, ID_OfTargetWaveIn , 0, 0, MIXER_OBJECTF_MIXER);
  183. if (MMSYSERR_NOERROR == result)
  184. {
  185. if(true)
  186. {
  187. MIXERCONTROLDETAILS_UNSIGNED mixValue;
  188. MIXERCONTROLDETAILS mixDetails;
  189. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  190. mixDetails.dwControlID = LastMicroMixerControl.dwControlID;
  191. mixDetails.cChannels = (DWORD) 1;
  192. mixDetails.hwndOwner = NULL;
  193. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  194. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_UNSIGNED)&mixValue;
  195. //read value
  196. result=mixerGetControlDetails((HMIXEROBJ)hMixer, (LPMIXERCONTROLDETAILS) &mixDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  197. if(MMSYSERR_NOERROR == result)
  198. {
  199. Volume_01=(double)mixValue.dwValue/(double)LastMicroMixerControl.Bounds.lMaximum;
  200. }
  201. else
  202. {
  203. cerr<<" mixerSetControlDetails for source failed\n";
  204. cerr<<GetTextErrorMMSystem(result)<<endl;
  205. }
  206. }
  207. mixerClose(hMixer);
  208. }
  209. else
  210. {
  211. cerr<<"mixerOpen() failed"<<endl;
  212. }
  213. }
  214. return res=Volume_01;
  215. }
  216. catch (std::exception &e)
  217. {
  218. myDebug()<<e.what();
  219. return 0;
  220. }
  221. }
  222. void MixerMicrophoneValue::SetVolume(double Volume01)//
  223. { //[0.0,1.0]
  224. try
  225. {
  226. if(flagLinkedToDeviceControl)
  227. {
  228. MMRESULT result;
  229. HMIXER hMixer;
  230. // get a handle to the mixer device
  231. result = mixerOpen(&hMixer, ID_OfTargetWaveIn , 0, 0, MIXER_OBJECTF_MIXER);
  232. if (MMSYSERR_NOERROR == result)
  233. {
  234. if(true)
  235. {
  236. MIXERCONTROLDETAILS_UNSIGNED mixValue;
  237. mixValue.dwValue =(int)((double)LastMicroMixerControl.Bounds.lMaximum*Volume01) ;
  238. MIXERCONTROLDETAILS mixDetails;
  239. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  240. mixDetails.dwControlID = LastMicroMixerControl.dwControlID;
  241. mixDetails.cChannels = (DWORD) 1;
  242. mixDetails.hwndOwner = NULL;
  243. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  244. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_UNSIGNED)&mixValue;
  245. //set value
  246. result=mixerSetControlDetails((HMIXEROBJ)hMixer, (LPMIXERCONTROLDETAILS) &mixDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  247. if(MMSYSERR_NOERROR == result){
  248. // clog<<" Volume changed to "<<mixValue.dwValue<<endl;
  249. }
  250. else
  251. {
  252. cerr<<" mixerSetControlDetails for source failed\n";
  253. cerr<<GetTextErrorMMSystem(result)<<endl;
  254. }
  255. }
  256. mixerClose(hMixer);
  257. }
  258. else
  259. {
  260. cerr<<"mixerOpen() failed"<<endl;
  261. }
  262. }
  263. }
  264. catch (std::exception &e)
  265. {
  266. myDebug()<<e.what();
  267. }
  268. }
  269. int MixerMicrophoneValue::MuteOff(bool state)
  270. {
  271. try
  272. {
  273. int res=0;
  274. if(flagLinkedToDeviceControl)
  275. {
  276. MMRESULT result;
  277. HMIXER hMixer;
  278. // get a handle to the mixer device
  279. result = mixerOpen(&hMixer, ID_OfTargetWaveIn , 0, 0, MIXER_OBJECTF_MIXER);
  280. if (MMSYSERR_NOERROR == result)
  281. {
  282. if( LastMicroMixerControl_Mute.dwControlType==MIXERCONTROL_CONTROLTYPE_MUTE
  283. /*||mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_ONOFF*/ //onoff for usb it is usually automatic recording level control - DONT TOUCH
  284. )
  285. {
  286. MIXERCONTROLDETAILS mixDetails;
  287. MIXERCONTROLDETAILS_BOOLEAN mixMute;
  288. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  289. mixDetails.dwControlID = LastMicroMixerControl_Mute.dwControlID;
  290. mixDetails.cChannels = (DWORD) 1;
  291. mixDetails.hwndOwner = NULL;
  292. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  293. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&mixMute;
  294. result = mixerGetControlDetails((HMIXEROBJ)hMixer,(LPMIXERCONTROLDETAILS) &mixDetails, MIXER_GETCONTROLDETAILSF_VALUE);
  295. if(MMSYSERR_NOERROR == result)
  296. {
  297. //Mute off/on
  298. if(state)
  299. {
  300. mixMute.fValue = LastMicroMixerControl_Mute.Bounds.lMinimum; // Mute off
  301. }
  302. else
  303. {
  304. mixMute.fValue = LastMicroMixerControl_Mute.Bounds.lMaximum; //Mute on
  305. }
  306. result=mixerSetControlDetails((HMIXEROBJ)hMixer, (LPMIXERCONTROLDETAILS) &mixDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  307. if(MMSYSERR_NOERROR == result)
  308. {
  309. // cout<<" Mute(OnOf) changed to "<<mixMute.fValue<<endl;
  310. }else
  311. {
  312. res=-1;
  313. // cerr<<" mixerSetControlDetails for source failed\n";
  314. cerr<<GetTextErrorMMSystem(result)<<endl;
  315. }
  316. }
  317. else
  318. {
  319. res=-1;
  320. cerr<<"mixerGetControlDetails for source failed\n";
  321. cerr<<GetTextErrorMMSystem(result)<<endl;
  322. }
  323. }
  324. mixerClose(hMixer);
  325. }
  326. else
  327. {
  328. res=-1;
  329. cerr<<"mixerOpen() failed"<<endl;
  330. }
  331. }
  332. return res;
  333. }
  334. catch (std::exception &e)
  335. {
  336. myDebug()<<e.what();
  337. return -1;
  338. }
  339. }
  340. bool MixerMicrophoneValue::IsMuteOff()
  341. {
  342. try
  343. {
  344. bool flagMuteOff=true;
  345. if(flagLinkedToDeviceControl)
  346. {
  347. MMRESULT result;
  348. HMIXER hMixer;
  349. // get a handle to the mixer device
  350. result = mixerOpen(&hMixer, ID_OfTargetWaveIn , 0, 0, MIXER_OBJECTF_MIXER);
  351. if (MMSYSERR_NOERROR == result)
  352. {
  353. if( LastMicroMixerControl_Mute.dwControlType==MIXERCONTROL_CONTROLTYPE_MUTE
  354. /*||mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_ONOFF*/ //onoff for usb it is usually automatic recording level control - DONT TOUCH
  355. )
  356. {
  357. MIXERCONTROLDETAILS mixDetails;
  358. MIXERCONTROLDETAILS_BOOLEAN mixMute;
  359. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  360. mixDetails.dwControlID = LastMicroMixerControl_Mute.dwControlID;
  361. mixDetails.cChannels = (DWORD) 1;
  362. mixDetails.hwndOwner = NULL;
  363. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  364. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&mixMute;
  365. result = mixerGetControlDetails((HMIXEROBJ)hMixer,(LPMIXERCONTROLDETAILS) &mixDetails, MIXER_GETCONTROLDETAILSF_VALUE);
  366. if(MMSYSERR_NOERROR == result)
  367. {
  368. //Checjk state Mute off/on
  369. result=mixerGetControlDetails((HMIXEROBJ)hMixer, (LPMIXERCONTROLDETAILS) &mixDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  370. if(MMSYSERR_NOERROR == result)
  371. {
  372. flagMuteOff= mixMute.fValue == LastMicroMixerControl_Mute.Bounds.lMinimum?true:false;
  373. }
  374. else
  375. {
  376. // cerr<<" mixerSetControlDetails for source failed\n";
  377. cerr<<GetTextErrorMMSystem(result)<<endl;
  378. }
  379. }
  380. else
  381. {
  382. cerr<<"mixerGetControlDetails for source failed\n";
  383. cerr<<GetTextErrorMMSystem(result)<<endl;
  384. }
  385. }
  386. mixerClose(hMixer);
  387. }
  388. else
  389. {
  390. cerr<<"mixerOpen() failed"<<endl;
  391. }
  392. }
  393. return flagMuteOff;
  394. }
  395. catch (std::exception &e)
  396. {
  397. myDebug()<<e.what();
  398. }
  399. }
  400. int MixerMicrophoneValue::LinkToDevice(const std::string &namedevice)
  401. {
  402. try
  403. {
  404. int result=0;
  405. //restoring name of default device
  406. CheckDefaultInDevice();
  407. int numOfDefaultWaveIn=0;
  408. if(namedevice==defaultname)
  409. {
  410. NameOfTargetWaveIn=NameOfDefaultWaveIn;
  411. }
  412. else
  413. {
  414. NameOfTargetWaveIn=namedevice;
  415. }
  416. MIXERCAPSA mixcaps;
  417. memset(&mixcaps, 0, sizeof(MIXERCAPSA));
  418. unsigned long iNumDevs;
  419. // Get the number of Mixer devices in this computer
  420. iNumDevs = mixerGetNumDevs();
  421. std::vector<char> vector_NamePossibleTarget;
  422. int max_len=0;
  423. int targetdevice_num=-1;
  424. for (unsigned int i = 0; i < iNumDevs; i++)
  425. {
  426. if (!mixerGetDevCapsA(i, &mixcaps, sizeof(MIXERCAPSA)))
  427. {
  428. //check for ID of target WaveIn
  429. int len_name=strlen(mixcaps.szPname);
  430. auto pair_mismatch=std::mismatch(mixcaps.szPname,mixcaps.szPname+len_name,NameOfTargetWaveIn.begin(), NameOfTargetWaveIn.end());
  431. int lenequal_1=std::distance(NameOfTargetWaveIn.begin(),pair_mismatch.second);
  432. if(lenequal_1>max_len)
  433. {//target - max distance of mismatch
  434. max_len=lenequal_1;
  435. targetdevice_num=i;//ID of possible target
  436. vector_NamePossibleTarget.resize(len_name);
  437. copy(mixcaps.szPname,mixcaps.szPname+len_name,vector_NamePossibleTarget.begin());
  438. }
  439. //check for ID of default WaveIn
  440. auto pair_mismatch_default=std::mismatch(mixcaps.szPname,mixcaps.szPname+len_name,NameOfDefaultWaveIn.begin(), NameOfDefaultWaveIn.end());
  441. size_t lenequal_default=std::distance(NameOfDefaultWaveIn.begin(),pair_mismatch_default.second);
  442. if(lenequal_default==NameOfDefaultWaveIn.length())
  443. {
  444. numOfDefaultWaveIn=i;//ID of default
  445. }
  446. }
  447. }
  448. if(targetdevice_num>=0)
  449. {//target found
  450. ID_OfTargetWaveIn=targetdevice_num;
  451. NameOfLinkedWaveIn.assign(&(vector_NamePossibleTarget[0]),vector_NamePossibleTarget.size());
  452. }
  453. else
  454. {//target not found - change target to deafult
  455. ID_OfTargetWaveIn=numOfDefaultWaveIn;
  456. NameOfLinkedWaveIn.assign(NameOfDefaultWaveIn);
  457. }
  458. flagLinkedToDeviceControl=true;
  459. LinkToMicrophone();
  460. result=flagLinkedToDeviceControl?0:-1;
  461. return result;
  462. }
  463. catch (std::exception &e)
  464. {
  465. myDebug()<<e.what();
  466. }
  467. }
  468. bool MixerMicrophoneValue::LinkToMicrophone(void)
  469. {
  470. try
  471. {
  472. bool res=false;
  473. if(flagLinkedToDeviceControl)
  474. {
  475. MMRESULT result;
  476. HMIXER hMixer;
  477. MIXERLINE ml = {0};
  478. MIXERLINECONTROLS mlc = {0};
  479. MIXERCONTROLDETAILS mcd = {0};
  480. MIXERCONTROLDETAILS_UNSIGNED mcdu = {0};
  481. // get a handle to the mixer device
  482. result = mixerOpen(&hMixer, ID_OfTargetWaveIn , 0, 0, MIXER_OBJECTF_MIXER);
  483. if (MMSYSERR_NOERROR == result)
  484. {
  485. MIXERCAPSA mixCaps;
  486. result = mixerGetDevCapsA(ID_OfTargetWaveIn, (LPMIXERCAPSA) &mixCaps,sizeof(MIXERCAPSA));
  487. if (MMSYSERR_NOERROR == result)
  488. {
  489. std::clog<<mixCaps.szPname<<" #"<<ID_OfTargetWaveIn<<endl;
  490. bool flag_microphone_volume_control_found=false;
  491. for(unsigned int id=0;id<mixCaps.cDestinations;++id){
  492. if(flag_microphone_volume_control_found)break;
  493. bool flag_microphone=false;
  494. unsigned int TypeSRCInMux=0;
  495. int NumSRCInMux=0;
  496. bool flag_NumSRCInMux_by_num=false;
  497. // WwavIn or all than can be Microphone
  498. memset(&ml,0,sizeof(ml));
  499. ml.cbStruct = sizeof(MIXERLINE);
  500. ml.dwDestination = (DWORD) id;
  501. ml.dwSource = (DWORD) 0;
  502. // Get information on this line
  503. result = mixerGetLineInfo((HMIXEROBJ) hMixer, &ml, MIXER_GETLINEINFOF_DESTINATION);
  504. if (MMSYSERR_NOERROR == result)
  505. {
  506. if( ml.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_VOICEIN
  507. ||ml.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  508. )
  509. {
  510. flag_microphone=true;
  511. }
  512. if(flag_microphone)
  513. {
  514. // try find controller
  515. memset(&mlc,0,sizeof(mlc));
  516. mlc.cbStruct = sizeof(MIXERLINECONTROLS);
  517. mlc.dwLineID = ml.dwLineID;
  518. mlc.cControls = ml.cControls;//1;
  519. MIXERCONTROL mcarr[50];
  520. memset(&mcarr,0,sizeof(mcarr));
  521. mlc.pamxctrl = &(mcarr[0]);
  522. mlc.cbmxctrl = sizeof(MIXERCONTROL);
  523. // get the volume controls associated with the speaker line
  524. result = mixerGetLineControls((HMIXEROBJ) hMixer, &mlc,MIXER_GETLINECONTROLSF_ALL /*MIXER_GETLINECONTROLSF_ONEBYTYPE*/);
  525. if (MMSYSERR_NOERROR == result)
  526. {
  527. for(unsigned int k=0;k<mlc.cControls;++k)
  528. {
  529. // For this control, I make various checks on its type
  530. if(mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_VOLUME
  531. ||mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_MUTE
  532. /*||mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_ONOFF*/ //onoff for usb it is usually automatic recording level control - DONT TOUCH
  533. ){
  534. //if mute than ON
  535. //remember value of Volume contol
  536. memset(&mcdu,0,sizeof(mcdu));
  537. mcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  538. mcd.hwndOwner = 0;
  539. mcd.dwControlID = mcarr[k].dwControlID;//mc.dwControlID
  540. mcd.paDetails = &mcdu;
  541. mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  542. mcd.cChannels = 1;
  543. // set the volume
  544. result = mixerGetControlDetails((HMIXEROBJ) hMixer, &mcd, MIXER_SETCONTROLDETAILSF_VALUE);
  545. if (MMSYSERR_NOERROR == result)
  546. {
  547. if(mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_VOLUME)
  548. {
  549. LastMicroMixerControl=mcarr[k];
  550. ID_Device=ID_OfTargetWaveIn;
  551. ID_Line_Dest=ml.dwLineID;
  552. ID_Line_SRC=-1;
  553. ID_Line_SRC_Num_Control=-1;//id MIXERCONTROL_CONTROLTYPE_VOLUME
  554. flag_microphone_volume_control_found=true;
  555. }
  556. if( mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_MUTE
  557. /*||mcarr[k].dwControlType==MIXERCONTROL_CONTROLTYPE_ONOFF*/ //onoff for usb it is usually automatic recording level control - DONT TOUCH
  558. )
  559. {
  560. MIXERCONTROLDETAILS mixDetails;
  561. MIXERCONTROLDETAILS_BOOLEAN mixMute;
  562. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  563. mixDetails.dwControlID = mcarr[k].dwControlID;
  564. mixDetails.cChannels = (DWORD) 1;
  565. mixDetails.hwndOwner = NULL;
  566. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  567. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&mixMute;
  568. result = mixerGetControlDetails((HMIXEROBJ)hMixer,(LPMIXERCONTROLDETAILS) &mixDetails, MIXER_GETCONTROLDETAILSF_VALUE);
  569. if(MMSYSERR_NOERROR == result)
  570. {
  571. LastMicroMixerControl_Mute=mcarr[k];//remeber if we need in the future mute wavein
  572. //Mute off
  573. mixMute.fValue = mcarr[k].Bounds.lMinimum;
  574. result=mixerSetControlDetails((HMIXEROBJ)hMixer, (LPMIXERCONTROLDETAILS) &mixDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  575. if(MMSYSERR_NOERROR == result){
  576. // cout<<" Mute(OnOf) changed to "<<mixMute.fValue<<endl;
  577. }
  578. else
  579. {
  580. // cerr<<" mixerSetControlDetails for source failed\n";
  581. cerr<<GetTextErrorMMSystem(result)<<endl;
  582. }
  583. }
  584. else
  585. {
  586. cerr<<"mixerGetControlDetails for source failed\n";
  587. cerr<<GetTextErrorMMSystem(result)<<endl;
  588. }
  589. }
  590. }
  591. else
  592. {
  593. cerr<<"mixerSetControlDetails() failed"<<endl;
  594. cerr<<GetTextErrorMMSystem(result)<<endl;
  595. }
  596. }
  597. if(mcarr[k].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX ||
  598. mcarr[k].dwControlType ==MIXERCONTROL_CONTROLTYPE_MIXER)
  599. {
  600. //remeber type of active device for src control
  601. // MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
  602. //find destination that work in source
  603. if(mcarr[k].cMultipleItems>1)
  604. {
  605. MIXERCONTROLDETAILS_BOOLEAN mixBoolean[50];
  606. MIXERCONTROLDETAILS_LISTTEXT mixList[50];
  607. // flag_MUX=true;
  608. NumSRCInMux=0;
  609. mcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  610. mcd.dwControlID = mcarr[k].dwControlID;
  611. mcd.cChannels = 1;//mixLine.cChannels;
  612. mcd.cMultipleItems = mcarr[k].cMultipleItems;
  613. mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  614. mcd.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&mixBoolean[0];
  615. result = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_VALUE);
  616. if (MMSYSERR_NOERROR ==result)
  617. {
  618. for(unsigned int iS=0;iS<mcarr[k].cMultipleItems;iS++)
  619. {
  620. if(mixBoolean[iS].fValue==1)
  621. {
  622. NumSRCInMux=iS;
  623. }
  624. }
  625. //check type of controller for NumSRCInMux
  626. mcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  627. mcd.dwControlID = mcarr[k].dwControlID;
  628. mcd.cChannels = 1;//mixLine.cChannels;
  629. mcd.cMultipleItems = mcarr[k].cMultipleItems;
  630. mcd.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
  631. mcd.paDetails = (LPMIXERCONTROLDETAILS_LISTTEXT)&mixList[0];
  632. result = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_LISTTEXT);
  633. if (MMSYSERR_NOERROR ==result)
  634. {
  635. //type of controller for NumSRCInMux
  636. TypeSRCInMux=mixList[NumSRCInMux].dwParam2;
  637. // cout<<"TypeSRCInMux: ["<<map_componenttype[mixList[NumSRCInMux].dwParam2]<<"] "<<endl;
  638. }
  639. else
  640. {
  641. cerr<<GetTextErrorMMSystem(result)<<endl;
  642. }
  643. }
  644. else
  645. {
  646. cerr<<GetTextErrorMMSystem(result)<<endl;
  647. }
  648. }
  649. else
  650. {
  651. flag_NumSRCInMux_by_num=true;
  652. }
  653. }
  654. }
  655. }
  656. else
  657. {
  658. cerr<<"mixerGetLineControls for dest failed\n";
  659. cerr<<GetTextErrorMMSystem(result)<<endl;
  660. }
  661. if(!flag_microphone_volume_control_found)
  662. {
  663. //try get control from SRC
  664. // cout<<"Get all "<<ml.cConnections<<" Source for this line \n";
  665. // cout<<"NumSRCInMux "<<NumSRCInMux<<endl;
  666. int cDest=ml.cConnections;
  667. bool flag_found_source=false;
  668. for(int iS=0;iS<cDest;++iS)
  669. {
  670. if(flag_found_source)
  671. {
  672. break;
  673. }
  674. //find source whose type is equal with TypeSRCInMux
  675. MIXERLINE mixLine;
  676. mixLine.cbStruct = sizeof(MIXERLINE);
  677. mixLine.dwDestination = (DWORD) ml.dwDestination;
  678. mixLine.dwSource = (DWORD) iS;
  679. result = mixerGetLineInfo((HMIXEROBJ)hMixer, (LPMIXERLINE) &mixLine, MIXER_GETLINEINFOF_SOURCE);
  680. if(MMSYSERR_NOERROR == result){
  681. // cout<<"\n"<<iS<<":"<<mixLine.szName<<" #"<<iS<<" "<<map_componenttype[mixLine.dwComponentType]<<endl;
  682. if(flag_NumSRCInMux_by_num||cDest==1)
  683. {
  684. // cout<<"Only one device source - we need it"<<endl;
  685. flag_found_source=true;
  686. }
  687. if(TypeSRCInMux==mixLine.dwComponentType)
  688. {
  689. // cout<<"WE nedeed it!"<<endl;
  690. flag_found_source=true;
  691. }
  692. if(!flag_found_source)continue;
  693. MIXERLINECONTROLS mixControls;
  694. MIXERCONTROL mixClist[50];
  695. mixControls.cbStruct = sizeof(MIXERLINECONTROLS);
  696. mixControls.dwLineID = mixLine.dwLineID;
  697. mixControls.cControls = mixLine.cControls;
  698. mixControls.cbmxctrl = sizeof(mixClist[0]);
  699. mixControls.pamxctrl = (LPMIXERCONTROL) &mixClist[0];
  700. result=mixerGetLineControls((HMIXEROBJ)hMixer, (LPMIXERLINECONTROLS) &mixControls,MIXER_GETLINECONTROLSF_ALL);
  701. if(MMSYSERR_NOERROR == result)
  702. {
  703. //go throgh all cotntrols fo this line
  704. for(unsigned int iC=0;iC<mixLine.cControls;iC++)
  705. {
  706. MIXERCONTROLDETAILS_UNSIGNED mixValue;
  707. // cout<<map_controltype[mixClist[iC].dwControlType]<<" : "<<mixClist[iC].dwControlID;
  708. if(mixClist[iC].dwControlType==MIXERCONTROL_CONTROLTYPE_VOLUME){
  709. MIXERCONTROLDETAILS mixDetails;
  710. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  711. mixDetails.dwControlID = mixClist[iC].dwControlID;
  712. mixDetails.cChannels = (DWORD) 1;
  713. mixDetails.hwndOwner = NULL;
  714. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_UNSIGNED);
  715. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_UNSIGNED)&mixValue;
  716. result = mixerGetControlDetails((HMIXEROBJ)hMixer,(LPMIXERCONTROLDETAILS) &mixDetails, MIXER_GETCONTROLDETAILSF_VALUE);
  717. if(MMSYSERR_NOERROR == result)
  718. {
  719. if(flag_found_source)
  720. {
  721. //remeber sequence
  722. LastMicroMixerControl=mixClist[iC];
  723. ID_Device=ID_OfTargetWaveIn;
  724. ID_Line_Dest=id;
  725. ID_Line_SRC=iS;
  726. ID_Line_SRC_Num_Control=iC;//number of MIXERCONTROL_CONTROLTYPE_VOLUME
  727. }
  728. // cout<<" mixValue="<<mixValue.dwValue<<" : ";
  729. }
  730. else
  731. {
  732. cerr<<" mixerGetControlDetails for source failed\n";
  733. cerr<<GetTextErrorMMSystem(result)<<endl;
  734. }
  735. }
  736. //if mute on - set OFF
  737. if(mixClist[iC].dwControlType==MIXERCONTROL_CONTROLTYPE_MUTE
  738. /*||mixClist[iC].dwControlType==MIXERCONTROL_CONTROLTYPE_ONOFF*/ //onoff for usb it is usually automatic recording level control - DONT TOUCH
  739. )
  740. {
  741. MIXERCONTROLDETAILS mixDetails;
  742. MIXERCONTROLDETAILS_BOOLEAN mixMute;
  743. mixDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  744. mixDetails.dwControlID = mixClist[iC].dwControlID;
  745. mixDetails.cChannels = (DWORD) 1;
  746. mixDetails.hwndOwner = NULL;
  747. mixDetails.cbDetails =sizeof(MIXERCONTROLDETAILS_BOOLEAN);
  748. mixDetails.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&mixMute;
  749. result = mixerGetControlDetails((HMIXEROBJ)hMixer,(LPMIXERCONTROLDETAILS) &mixDetails, MIXER_GETCONTROLDETAILSF_VALUE);
  750. if(MMSYSERR_NOERROR == result)
  751. {
  752. LastMicroMixerControl_Mute=mixClist[iC];//remeber if we need in the future mute wavein
  753. //set mute to off
  754. mixMute.fValue = mixClist[iC].Bounds.lMinimum;
  755. result=mixerSetControlDetails((HMIXEROBJ)hMixer, (LPMIXERCONTROLDETAILS) &mixDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  756. if(MMSYSERR_NOERROR == result)
  757. {
  758. // cerr<<" Mute(OnOf) changed to "<<mixMute.fValue<<endl;
  759. }
  760. else
  761. {
  762. cerr<<" mixerSetControlDetails for source failed\n";
  763. cerr<<GetTextErrorMMSystem(result)<<endl;
  764. }
  765. }
  766. else
  767. {
  768. cerr<<"mixerGetControlDetails for source failed\n";
  769. cerr<<GetTextErrorMMSystem(result)<<endl;
  770. }
  771. }
  772. }
  773. }
  774. else
  775. {
  776. cerr<<" mixerGetLineControls for source failed\n";
  777. cerr<<GetTextErrorMMSystem(result)<<endl;
  778. }
  779. }
  780. else
  781. {
  782. cerr<<" mixerGetLineInfo for source failed\n";
  783. cerr<<GetTextErrorMMSystem(result)<<endl;
  784. }
  785. }//iS
  786. }
  787. else
  788. {
  789. break;
  790. }
  791. };
  792. }
  793. else
  794. {
  795. cerr<<"mixerGetLineInfo for dest failed\n";
  796. cerr<<GetTextErrorMMSystem(result)<<endl;
  797. }
  798. }
  799. if(flag_microphone_volume_control_found)res=true;
  800. }
  801. else
  802. {
  803. cerr<<"mixerGetDevCaps failed\n";
  804. cerr<<GetTextErrorMMSystem(result)<<endl;
  805. }
  806. mixerClose(hMixer);
  807. }
  808. else
  809. {
  810. cerr<<"mixerOpen() failed"<<endl;
  811. }
  812. }
  813. return res;
  814. }
  815. catch (std::exception &e)
  816. {
  817. myDebug()<<e.what();
  818. }
  819. }