|
Wave Arts VQE
1.00
Voice Quality Enhancement
|
00001 /* 00002 * This file is part of the Wave Arts VQE library. 00003 * Copyright (C) 2011 Wave Arts, Inc. (http://wavearts.com) 00004 * 00005 * VQE is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * VQE is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * A copy of the GNU General Public License is included with VQE, 00016 * and can be found online at <http://www.gnu.org/licenses/>. 00017 * 00018 * If you'd like to distribute a closed-source product which uses VQE, 00019 * you must obtain a commercial VQE license from Wave Arts. 00020 */ 00021 // 00022 // WaAudioDev C++ wrapper around Windows Audio Services API (WASAPI). 00023 // 00024 // Bill Gardner, Jun, 2011 00025 // 00026 00033 00034 00035 #ifndef _WAD_WASAPI_H 00036 #define _WAD_WASAPI_H 00037 00038 #include "WaAudioDev.h" 00039 #include "SampleFifo.h" 00040 #include "WadResPort.h" 00041 #include "WadConvPort.h" 00042 #include <MMDeviceAPI.h> 00043 #include <AudioClient.h> 00044 #include <AudioPolicy.h> 00045 00047 #define USE_SIMPLE_OUT_VOL 1 00048 00049 #define CLOCK_TEST 0 00050 00055 typedef struct { 00056 LPWSTR id; 00057 WadDevInfo info; 00058 } WASAPIDevInfo; 00059 00065 class WadWASAPI : public WaAudioDev { 00066 protected: 00067 AUDCLNT_SHAREMODE shareMode; 00068 ERole role; 00069 // device discovery 00070 IMMDeviceEnumerator *pEnumerator; 00071 int numDev; 00072 WASAPIDevInfo *devTab; 00073 00074 bool GetDeviceName(IMMDevice *device, char *devName, size_t len); 00075 int defaultInDev; 00076 int defaultOutDev; 00077 // streaming 00078 IMMDevice *pCaptureDevice; 00079 IMMDevice *pRenderDevice; 00080 IAudioClient *pInAudioClient; 00081 IAudioClient *pOutAudioClient; 00082 IAudioCaptureClient *pCaptureClient; 00083 IAudioRenderClient *pRenderClient; 00084 IAudioClock *pInAudioClock; 00085 UINT64 inFrequency; 00086 IAudioClock *pOutAudioClock; 00087 UINT64 outFrequency; 00088 #if CLOCK_TEST 00089 UINT64 startInTime; 00090 UINT64 startInPos; 00091 UINT64 startOutTime; 00092 UINT64 startOutPos; 00093 #endif 00094 #if USE_SIMPLE_OUT_VOL 00095 ISimpleAudioVolume *pOutSimpleAudioVolume; 00096 #endif 00097 UINT32 inFrameCount; 00098 UINT32 outFrameCount; 00099 bool inNeedsConversion; 00100 bool outNeedsConversion; 00101 void *inBuf; 00102 void *outBuf; 00103 SampleFifo *inFifo; 00104 void *inFifoBuf; 00105 WAVEFORMATEX inWavFmt; 00106 WAVEFORMATEX outWavFmt; 00107 HANDLE hRenderEvent; 00108 HANDLE hCaptureEvent; 00109 HANDLE hQuitEvent; 00110 HANDLE hThread; 00111 WadCallbackFn *appInFn; 00112 WadCallbackFn *appOutFn; 00113 void *appArg; 00114 // Closest parameters: set these when WASAPI can't support format, 00115 // caller will fetch via GetClosestBlah() 00116 WadStreamFormat closestInFmt; 00117 WadStreamFormat closestOutFmt; 00118 00120 void CloseInternal(); 00122 REFERENCE_TIME GetDevicePeriodMultiple(REFERENCE_TIME minTime, REFERENCE_TIME devicePeriod); 00124 bool CalculateBufferTimes(IAudioClient *audioClient, bool isInput, 00125 REFERENCE_TIME *pBufferTime, REFERENCE_TIME *pDevicePeriod); 00127 HRESULT IsFormatSupported(IAudioClient *client, WAVEFORMATEX *pFormat, 00128 WAVEFORMATEX **ppClosestMatch); 00130 int AccessVol(int devId, bool isOutput, bool setVol, float *pVol); 00131 00132 public: 00134 WadWASAPI(AUDCLNT_SHAREMODE shareMode = AUDCLNT_SHAREMODE_SHARED, ERole role = eCommunications); 00136 ~WadWASAPI(); 00137 WadAPI GetAPI(); 00138 int Init(); 00139 00140 // implement WaAudioDev 00141 virtual int GetNumDevices(int *pNumDev); 00142 virtual int GetDevInfo(int devId, WadDevInfo *pInfo); 00143 virtual int GetDefaultInDevId(int *pId); 00144 virtual int GetDefaultOutDevId(int *pId); 00145 virtual int Open(WadParam *param, WadCallbackFn *inFn, WadCallbackFn *outFn, void *arg); 00146 virtual int Start(); 00147 virtual int Stop(); 00148 virtual void Close(); 00149 virtual void Wait(); 00150 virtual bool IsRunning(); 00151 virtual int SetVol(int devId, bool isOutput, float vol); 00152 virtual int GetVol(int devId, bool isOutput, float *pVol); 00153 virtual int GetClosestFormat(bool isOutput, WadStreamFormat *pFormat); 00154 virtual int GetBufTime(bool isOutput, int *pBufTimeMsec); 00156 DWORD Thread(); 00157 00158 }; 00159 00160 #if 0 00161 00162 // 00163 // Aborted effort to clean up the Open hack in WadResWASAPI. The idea is to 00164 // define WaAudioDev::GetPort which returns the port for the device. 00165 // So a derived device can set up additional processing, like sample 00166 // rate conversion, format conversion, etc., by providing a different 00167 // port. The device itself implement WaAudioDevPort, which is the 00168 // raw device without conversion. The problem with this method is that 00169 // the caller has to do: 00170 // wad = new WaAudioDev(...); 00171 // port = wad->GetPort(); 00172 // port->Open(...) 00173 // It's a lot cleaner to just call wad->Open(). So the hack stays. 00174 // 00175 class WadResWASAPIPort : public WaAudioDevPortObj 00176 { 00177 protected: 00178 public: 00179 WadResWASAPIPort(WaAudioDevPort *devPort); 00180 ~WadResWASAPIPort(); 00181 int Open(WadParam *param, WadCallbackFn *inFn, WadCallbackFn *outFn, void *arg); 00182 void Close(); 00183 }; 00184 00185 #endif 00186 00194 class WadResWASAPI : public WadWASAPI 00195 { 00196 protected: 00197 WadResPort *resPort; 00198 bool openingViaResPort; 00199 bool closingViaResPort; 00200 WadConvPort *convPort; 00201 00202 public: 00204 WadResWASAPI(); 00206 ~WadResWASAPI(); 00207 00208 int Open(WadParam *param, WadCallbackFn *inFn, WadCallbackFn *outFn, void *arg); 00209 void Close(); 00210 }; 00211 00212 #endif
1.7.5.1