c_wavein.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #ifndef __C_WAVEIN_H__
  2. #define __C_WAVEIN_H__
  3. #include <windows.h>
  4. #include <mmsystem.h>
  5. #define EXIT_ON_ERROR(hr) \
  6. if (FAILED(hr)) { goto Exit; }
  7. #define SAFE_RELEASE(what) \
  8. if ((what) != NULL) \
  9. { (what)->Release(); (what) = NULL; }
  10. template<int numbuffers, int buffersize> class C_WAVEIN {
  11. private:
  12. short Samples[numbuffers][buffersize];
  13. WAVEFORMATEX wfx;
  14. WAVEHDR wvhdr[numbuffers];
  15. HWAVEIN hwi;
  16. WAVEINCAPS wic;
  17. unsigned long iNumDevs, iy;
  18. HRESULT hr;
  19. IMMDeviceEnumerator *pEnumerate;
  20. IMMDevice *pDevice;
  21. IMMDeviceCollection *ppDevices;
  22. IPropertyStore *pProps;
  23. BOOL useXpSound;
  24. PROPVARIANT varName;
  25. char buf[1024];
  26. public:
  27. C_WAVEIN() {
  28. hwi = NULL;
  29. memset(Samples, 0, sizeof(Samples));
  30. memset(wvhdr, 0, sizeof(wvhdr));
  31. iNumDevs = iy = 0;
  32. hr = S_OK;
  33. pEnumerate = NULL;
  34. pDevice = NULL;
  35. ppDevices = NULL;
  36. pProps = NULL;
  37. useXpSound = false;
  38. memset(buf, 0, sizeof(buf));
  39. }
  40. virtual ~C_WAVEIN() {
  41. Close();
  42. }
  43. char * getDeviceName(unsigned int devid=-1) {
  44. hr = S_OK;
  45. pEnumerate = NULL;
  46. pDevice = NULL;
  47. ppDevices = NULL;
  48. pProps = NULL;
  49. useXpSound = false;
  50. PROPVARIANT varName;
  51. PropVariantInit(&varName);
  52. // Get enumerator for audio endpoint devices.
  53. CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  54. hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
  55. NULL, CLSCTX_INPROC_SERVER,
  56. __uuidof(IMMDeviceEnumerator),
  57. (void**)&pEnumerate);
  58. EXIT_ON_ERROR(hr)
  59. hr = pEnumerate->GetDefaultAudioEndpoint(eCapture,eConsole,&pDevice);
  60. EXIT_ON_ERROR(hr)
  61. Exit:
  62. if (FAILED(hr)) {
  63. useXpSound = true;
  64. } else
  65. useXpSound = false;
  66. memset(buf, 0, sizeof(buf));
  67. if (useXpSound) {
  68. if (!waveInGetDevCaps(devid, &wic, sizeof(WAVEINCAPS))) {
  69. lstrcpyn(buf, wic.szPname, ARRAYSIZE(buf));
  70. goto Fin;
  71. }
  72. } else {
  73. pDevice->OpenPropertyStore(STGM_READ, &pProps);
  74. pProps->GetValue(PKEY_Device_FriendlyName, &varName);
  75. WideCharToMultiByte(CP_ACP, 0, (LPWSTR)varName.pwszVal, -1, buf, ARRAYSIZE(buf), NULL, NULL);
  76. goto Fin;
  77. }
  78. Fin:
  79. PropVariantClear(&varName);
  80. SAFE_RELEASE(pProps)
  81. SAFE_RELEASE(pEnumerate)
  82. SAFE_RELEASE(pDevice)
  83. SAFE_RELEASE(ppDevices)
  84. CoUninitialize();
  85. return buf;
  86. }
  87. void Create(int sRate, int nCh,int devid=-1) {
  88. if (hwi == NULL) {
  89. wfx.wFormatTag = WAVE_FORMAT_PCM;
  90. wfx.wBitsPerSample = 16;
  91. wfx.nSamplesPerSec = sRate;
  92. wfx.nChannels = (WORD)nCh;
  93. wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8;
  94. wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  95. wfx.cbSize = 0;
  96. waveInOpen(&hwi,devid,&wfx,0,0,CALLBACK_NULL);
  97. waveInStop(hwi);
  98. waveInReset(hwi);
  99. for(int i = 0; i < numbuffers; i++) {
  100. memset(&wvhdr[i],0,sizeof(wvhdr[i]));
  101. wvhdr[i].lpData = (char *)&Samples[i];
  102. wvhdr[i].dwBufferLength = buffersize * sizeof(short);
  103. waveInPrepareHeader(hwi,&wvhdr[i],sizeof(WAVEHDR));
  104. waveInAddBuffer(hwi,&wvhdr[i],sizeof(WAVEHDR));
  105. }
  106. waveInStart(hwi);
  107. }
  108. }
  109. void Close() {
  110. if (hwi != NULL) {
  111. waveInStop(hwi);
  112. waveInReset(hwi);
  113. for(int i = 0; i < numbuffers; i++) {
  114. if (wvhdr[i].dwFlags & WHDR_PREPARED) {
  115. waveInUnprepareHeader(hwi,&wvhdr[i],sizeof(WAVEHDR));
  116. }
  117. }
  118. waveInClose(hwi);
  119. hwi = NULL;
  120. }
  121. }
  122. short *operator[](int buffernum) {
  123. return (short *)&Samples[buffernum];
  124. }
  125. int getNumSamples(int buffernum) {
  126. return wvhdr[buffernum].dwBytesRecorded / (wfx.nChannels * sizeof(short));
  127. }
  128. int isOpen() {
  129. return hwi != NULL;
  130. }
  131. int isFilled(int buffernum) {
  132. return wvhdr[buffernum].dwFlags & WHDR_DONE && wvhdr[buffernum].dwBytesRecorded <= buffersize * sizeof(short);
  133. }
  134. void cycleBuffer(int buffernum) {
  135. if (hwi != NULL) {
  136. wvhdr[buffernum].dwFlags = WHDR_PREPARED;
  137. wvhdr[buffernum].dwBytesRecorded = 0;
  138. waveInAddBuffer(hwi,&wvhdr[buffernum],sizeof(WAVEHDR));
  139. }
  140. }
  141. };
  142. #endif // !__C_WAVEIN_H__