Wave Arts VQE  1.00
Voice Quality Enhancement
WadWASAPI.h
Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines