123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #ifndef __C_WAVEIN_H__
- #define __C_WAVEIN_H__
- #include <windows.h>
- #include <mmsystem.h>
- #define EXIT_ON_ERROR(hr) \
- if (FAILED(hr)) { goto Exit; }
- #define SAFE_RELEASE(what) \
- if ((what) != NULL) \
- { (what)->Release(); (what) = NULL; }
- template<int numbuffers, int buffersize> class C_WAVEIN {
- private:
- short Samples[numbuffers][buffersize];
- WAVEFORMATEX wfx;
- WAVEHDR wvhdr[numbuffers];
- HWAVEIN hwi;
- WAVEINCAPS wic;
- unsigned long iNumDevs, iy;
- HRESULT hr;
- IMMDeviceEnumerator *pEnumerate;
- IMMDevice *pDevice;
- IMMDeviceCollection *ppDevices;
- IPropertyStore *pProps;
- BOOL useXpSound;
- PROPVARIANT varName;
- char buf[1024];
- public:
- C_WAVEIN() {
- hwi = NULL;
- memset(Samples, 0, sizeof(Samples));
- memset(wvhdr, 0, sizeof(wvhdr));
- iNumDevs = iy = 0;
- hr = S_OK;
- pEnumerate = NULL;
- pDevice = NULL;
- ppDevices = NULL;
- pProps = NULL;
- useXpSound = false;
- memset(buf, 0, sizeof(buf));
- }
- virtual ~C_WAVEIN() {
- Close();
- }
- char * getDeviceName(unsigned int devid=-1) {
- hr = S_OK;
- pEnumerate = NULL;
- pDevice = NULL;
- ppDevices = NULL;
- pProps = NULL;
- useXpSound = false;
- PROPVARIANT varName;
- PropVariantInit(&varName);
- // Get enumerator for audio endpoint devices.
- CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
- NULL, CLSCTX_INPROC_SERVER,
- __uuidof(IMMDeviceEnumerator),
- (void**)&pEnumerate);
- EXIT_ON_ERROR(hr)
- hr = pEnumerate->GetDefaultAudioEndpoint(eCapture,eConsole,&pDevice);
- EXIT_ON_ERROR(hr)
- Exit:
- if (FAILED(hr)) {
- useXpSound = true;
- } else
- useXpSound = false;
- memset(buf, 0, sizeof(buf));
- if (useXpSound) {
- if (!waveInGetDevCaps(devid, &wic, sizeof(WAVEINCAPS))) {
- lstrcpyn(buf, wic.szPname, ARRAYSIZE(buf));
- goto Fin;
- }
- } else {
- pDevice->OpenPropertyStore(STGM_READ, &pProps);
- pProps->GetValue(PKEY_Device_FriendlyName, &varName);
- WideCharToMultiByte(CP_ACP, 0, (LPWSTR)varName.pwszVal, -1, buf, ARRAYSIZE(buf), NULL, NULL);
- goto Fin;
- }
- Fin:
- PropVariantClear(&varName);
- SAFE_RELEASE(pProps)
- SAFE_RELEASE(pEnumerate)
- SAFE_RELEASE(pDevice)
- SAFE_RELEASE(ppDevices)
- CoUninitialize();
- return buf;
- }
- void Create(int sRate, int nCh,int devid=-1) {
- if (hwi == NULL) {
- wfx.wFormatTag = WAVE_FORMAT_PCM;
- wfx.wBitsPerSample = 16;
- wfx.nSamplesPerSec = sRate;
- wfx.nChannels = (WORD)nCh;
- wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8;
- wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
- wfx.cbSize = 0;
- waveInOpen(&hwi,devid,&wfx,0,0,CALLBACK_NULL);
- waveInStop(hwi);
- waveInReset(hwi);
- for(int i = 0; i < numbuffers; i++) {
- memset(&wvhdr[i],0,sizeof(wvhdr[i]));
- wvhdr[i].lpData = (char *)&Samples[i];
- wvhdr[i].dwBufferLength = buffersize * sizeof(short);
- waveInPrepareHeader(hwi,&wvhdr[i],sizeof(WAVEHDR));
- waveInAddBuffer(hwi,&wvhdr[i],sizeof(WAVEHDR));
- }
- waveInStart(hwi);
- }
- }
- void Close() {
- if (hwi != NULL) {
- waveInStop(hwi);
- waveInReset(hwi);
- for(int i = 0; i < numbuffers; i++) {
- if (wvhdr[i].dwFlags & WHDR_PREPARED) {
- waveInUnprepareHeader(hwi,&wvhdr[i],sizeof(WAVEHDR));
- }
- }
- waveInClose(hwi);
- hwi = NULL;
- }
- }
- short *operator[](int buffernum) {
- return (short *)&Samples[buffernum];
- }
- int getNumSamples(int buffernum) {
- return wvhdr[buffernum].dwBytesRecorded / (wfx.nChannels * sizeof(short));
- }
- int isOpen() {
- return hwi != NULL;
- }
- int isFilled(int buffernum) {
- return wvhdr[buffernum].dwFlags & WHDR_DONE && wvhdr[buffernum].dwBytesRecorded <= buffersize * sizeof(short);
- }
- void cycleBuffer(int buffernum) {
- if (hwi != NULL) {
- wvhdr[buffernum].dwFlags = WHDR_PREPARED;
- wvhdr[buffernum].dwBytesRecorded = 0;
- waveInAddBuffer(hwi,&wvhdr[buffernum],sizeof(WAVEHDR));
- }
- }
- };
- #endif // !__C_WAVEIN_H__
|