a49e86d896b90e562ae11db0ba83c920b291e140
[vuplus_xbmc] / xbmc / cores / AudioEngine / Sinks / AESinkWASAPI.cpp
1 /*
2  *      Copyright (C) 2010-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "AESinkWASAPI.h"
22 #include <Audioclient.h>
23 #include <avrt.h>
24 #include <initguid.h>
25 #include <Mmreg.h>
26 #include <stdint.h>
27
28 #include "../Utils/AEUtil.h"
29 #include "settings/AdvancedSettings.h"
30 #include "utils/StdString.h"
31 #include "utils/log.h"
32 #include "threads/SingleLock.h"
33 #include "utils/CharsetConverter.h"
34 #include "../Utils/AEDeviceInfo.h"
35 #include <Mmreg.h>
36 #include <mmdeviceapi.h>
37 #include "utils/StringUtils.h"
38
39 #pragma comment(lib, "Avrt.lib")
40
41 const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
42 const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
43 const IID IID_IAudioClient = __uuidof(IAudioClient);
44 const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
45
46 static const unsigned int WASAPISampleRateCount = 10;
47 static const unsigned int WASAPISampleRates[] = {384000, 192000, 176400, 96000, 88200, 48000, 44100, 32000, 22050, 11025};
48
49 #define WASAPI_SPEAKER_COUNT 21
50 static const unsigned int WASAPIChannelOrder[] = {AE_CH_RAW,
51                                                   SPEAKER_FRONT_LEFT,           SPEAKER_FRONT_RIGHT,           SPEAKER_FRONT_CENTER,
52                                                   SPEAKER_LOW_FREQUENCY,        SPEAKER_BACK_LEFT,             SPEAKER_BACK_RIGHT,
53                                                   SPEAKER_FRONT_LEFT_OF_CENTER, SPEAKER_FRONT_RIGHT_OF_CENTER,
54                                                   SPEAKER_BACK_CENTER,          SPEAKER_SIDE_LEFT,             SPEAKER_SIDE_RIGHT,
55                                                   SPEAKER_TOP_FRONT_LEFT,       SPEAKER_TOP_FRONT_RIGHT,       SPEAKER_TOP_FRONT_CENTER,
56                                                   SPEAKER_TOP_CENTER,           SPEAKER_TOP_BACK_LEFT,         SPEAKER_TOP_BACK_RIGHT,
57                                                   SPEAKER_TOP_BACK_CENTER,      SPEAKER_RESERVED,              SPEAKER_RESERVED};
58
59 static const enum AEChannel AEChannelNames[]   = {AE_CH_RAW,
60                                                   AE_CH_FL,                     AE_CH_FR,                      AE_CH_FC,
61                                                   AE_CH_LFE,                    AE_CH_BL,                      AE_CH_BR,
62                                                   AE_CH_FLOC,                   AE_CH_FROC,
63                                                   AE_CH_BC,                     AE_CH_SL,                      AE_CH_SR,
64                                                   AE_CH_TFL,                    AE_CH_TFR,                     AE_CH_TFC ,
65                                                   AE_CH_TC  ,                   AE_CH_TBL,                     AE_CH_TBR,
66                                                   AE_CH_TBC,                    AE_CH_BLOC,                    AE_CH_BROC};
67
68 static const enum AEChannel layoutsList[][16] = 
69 {
70   /* Most common configurations */
71   {AE_CH_FC,  AE_CH_NULL}, // Mono
72   {AE_CH_FL,  AE_CH_FR,  AE_CH_NULL}, // Stereo
73   {AE_CH_FL,  AE_CH_FR,  AE_CH_BL,  AE_CH_BR,  AE_CH_NULL}, // Quad
74   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_BC,  AE_CH_NULL}, // Surround
75   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_NULL}, // Standard 5.1
76   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_NULL}, // Standard 7.1
77   /* Less common configurations */
78   {AE_CH_FL,  AE_CH_FR,  AE_CH_LFE, AE_CH_NULL}, // 2.1
79   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_BL,  AE_CH_BR,  AE_CH_NULL}, // 5.1 wide (obsolete)
80   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_BL,  AE_CH_BR,  AE_CH_FLOC,AE_CH_FROC,AE_CH_NULL}, // 7.1 wide (obsolete)
81   /* Exotic configurations */
82   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_NULL}, // 3 front speakers
83   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_NULL}, // 3 front speakers + LFE
84   {AE_CH_FL,  AE_CH_FR,  AE_CH_BL,  AE_CH_BR,  AE_CH_LFE, AE_CH_NULL}, // Quad + LFE
85   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_BC,  AE_CH_LFE, AE_CH_NULL}, // Surround + LFE
86   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_SL,  AE_CH_SR,  AE_CH_NULL}, // Standard 5.1 w/o LFE
87   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_BL,  AE_CH_BR,  AE_CH_NULL}, // 5.1 wide w/o LFE
88   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_SL,  AE_CH_SR,  AE_CH_BC,  AE_CH_NULL}, // Standard 5.1 w/o LFE + Back Center
89   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_BL,  AE_CH_BC,  AE_CH_BR,  AE_CH_NULL}, // 5.1 wide w/o LFE + Back Center
90   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_BL,  AE_CH_BR,  AE_CH_TC,  AE_CH_NULL}, // DVD speakers
91   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_BL,  AE_CH_BR,  AE_CH_BC,  AE_CH_LFE, AE_CH_NULL}, // 5.1 wide + Back Center
92   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_NULL}, // Standard 7.1 w/o LFE
93   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_BL,  AE_CH_BR,  AE_CH_FLOC,AE_CH_FROC,AE_CH_NULL}, // 7.1 wide w/o LFE
94   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BC,  AE_CH_BR,  AE_CH_NULL}, // Standard 7.1 + Back Center
95   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_FLOC,AE_CH_FROC,AE_CH_NULL}, // Standard 7.1 + front wide
96   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_TFL, AE_CH_TFR, AE_CH_NULL}, // Standard 7.1 + 2 front top
97   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_TFL, AE_CH_TFR, AE_CH_TFC, AE_CH_NULL}, // Standard 7.1 + 3 front top
98   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_TFL, AE_CH_TFR, AE_CH_TBL, AE_CH_TBR, AE_CH_NULL}, // Standard 7.1 + 2 front top + 2 back top
99   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_TFL, AE_CH_TFR, AE_CH_TFC, AE_CH_TBL, AE_CH_TBR, AE_CH_NULL}, // Standard 7.1 + 3 front top + 2 back top
100   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_TFL, AE_CH_TFR, AE_CH_TFC, AE_CH_TBL, AE_CH_TBR, AE_CH_TBC, AE_CH_NULL}, // Standard 7.1 + 3 front top + 3 back top
101   {AE_CH_FL,  AE_CH_FR,  AE_CH_FC,  AE_CH_LFE, AE_CH_SL,  AE_CH_SR,  AE_CH_BL,  AE_CH_BR,  AE_CH_TFL, AE_CH_TFR, AE_CH_TFC, AE_CH_TBL, AE_CH_TBR, AE_CH_TBC, AE_CH_TC,  AE_CH_NULL} // Standard 7.1 + 3 front top + 3 back top + Top Center
102 };
103
104 struct sampleFormat
105 {
106   GUID subFormat;
107   unsigned int bitsPerSample;
108   unsigned int validBitsPerSample;
109   AEDataFormat subFormatType;
110 };
111
112 /* Sample formats go from float -> 32 bit int -> 24 bit int (packed in 32) -> -> 24 bit int -> 16 bit int */
113 static const sampleFormat testFormats[] = { {KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 32, 32, AE_FMT_FLOAT},
114                                             {KSDATAFORMAT_SUBTYPE_PCM, 32, 32, AE_FMT_S32NE},
115                                             {KSDATAFORMAT_SUBTYPE_PCM, 32, 24, AE_FMT_S24NE4},
116                                             {KSDATAFORMAT_SUBTYPE_PCM, 24, 24, AE_FMT_S24NE3},
117                                             {KSDATAFORMAT_SUBTYPE_PCM, 16, 16, AE_FMT_S16NE} };
118
119 struct winEndpointsToAEDeviceType
120 {
121   std::string winEndpointType;
122   AEDeviceType aeDeviceType;
123 };
124
125 static const winEndpointsToAEDeviceType winEndpoints[EndpointFormFactor_enum_count] =
126 {
127   {"Network Device - ",         AE_DEVTYPE_PCM},
128   {"Speakers - ",               AE_DEVTYPE_PCM},
129   {"LineLevel - ",              AE_DEVTYPE_PCM},
130   {"Headphones - ",             AE_DEVTYPE_PCM},
131   {"Microphone - ",             AE_DEVTYPE_PCM},
132   {"Headset - ",                AE_DEVTYPE_PCM},
133   {"Handset - ",                AE_DEVTYPE_PCM},
134   {"Digital Passthrough - ", AE_DEVTYPE_IEC958},
135   {"SPDIF - ",               AE_DEVTYPE_IEC958},
136   {"HDMI - ",                  AE_DEVTYPE_HDMI},
137   {"Unknown - ",                AE_DEVTYPE_PCM},
138 };
139
140 AEDeviceInfoList DeviceInfoList;
141
142 #define EXIT_ON_FAILURE(hr, reason, ...) if(FAILED(hr)) {CLog::Log(LOGERROR, reason " - %s", __VA_ARGS__, WASAPIErrToStr(hr)); goto failed;}
143
144 #define ERRTOSTR(err) case err: return #err
145
146 DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
147
148 DWORD ChLayoutToChMask(const enum AEChannel * layout, unsigned int * numberOfChannels = NULL)
149 {
150   if (numberOfChannels)
151     *numberOfChannels = 0;
152   if (!layout)
153     return 0;
154   
155   DWORD mask = 0;
156   unsigned int i;
157   for (i = 0; layout[i] != AE_CH_NULL; i++)
158     mask |= WASAPIChannelOrder[layout[i]];
159   
160   if (numberOfChannels)
161     *numberOfChannels = i;
162
163   return mask;
164 }
165
166 CStdStringA localWideToUtf(LPCWSTR wstr)
167 {
168   if (wstr == NULL)
169     return "";
170   int bufSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
171   CStdStringA strA ("", bufSize);
172   if ( bufSize == 0 || WideCharToMultiByte(CP_UTF8, 0, wstr, -1, strA.GetBuf(bufSize), bufSize, NULL, NULL) != bufSize )
173     strA.clear();
174   strA.RelBuf();
175   return strA;
176 }
177
178 CAESinkWASAPI::CAESinkWASAPI() :
179   m_needDataEvent(0),
180   m_pDevice(NULL),
181   m_pAudioClient(NULL),
182   m_pRenderClient(NULL),
183   m_encodedFormat(AE_FMT_INVALID),
184   m_encodedChannels(0),
185   m_encodedSampleRate(0),
186   sinkReqFormat(AE_FMT_INVALID),
187   sinkRetFormat(AE_FMT_INVALID),
188   m_running(false),
189   m_initialized(false),
190   m_isSuspended(false),
191   m_isDirty(false),
192   m_uiBufferLen(0),
193   m_avgTimeWaiting(50),
194   m_sinkLatency(0.0),
195   m_pBuffer(NULL),
196   m_bufferPtr(0),
197   m_hnsRequestedDuration(0)
198 {
199   m_channelLayout.Reset();
200 }
201
202 CAESinkWASAPI::~CAESinkWASAPI()
203 {
204
205 }
206
207 bool CAESinkWASAPI::Initialize(AEAudioFormat &format, std::string &device)
208 {
209   if (m_initialized)
210     return false;
211
212   m_device = device;
213   bool bdefault = false;
214
215   /* Save requested format */
216   /* Clear returned format */
217   sinkReqFormat = format.m_dataFormat;
218   sinkRetFormat = AE_FMT_INVALID;
219
220   IMMDeviceEnumerator* pEnumerator = NULL;
221   IMMDeviceCollection* pEnumDevices = NULL;
222
223   HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
224   EXIT_ON_FAILURE(hr, __FUNCTION__": Could not allocate WASAPI device enumerator. CoCreateInstance error code: %li", hr)
225
226   /* Get our device. First try to find the named device. */
227   UINT uiCount = 0;
228
229   hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pEnumDevices);
230   EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint enumeration failed.")
231
232   hr = pEnumDevices->GetCount(&uiCount);
233   EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.")
234
235   if(StringUtils::EndsWith(device, std::string("default")))
236     bdefault = true;
237
238   if(!bdefault)
239   {
240     for (UINT i = 0; i < uiCount; i++)
241     {
242       IPropertyStore *pProperty = NULL;
243       PROPVARIANT varName;
244
245       hr = pEnumDevices->Item(i, &m_pDevice);
246       EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of WASAPI endpoint failed.")
247
248       hr = m_pDevice->OpenPropertyStore(STGM_READ, &pProperty);
249       EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of WASAPI endpoint properties failed.")
250
251       hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName);
252       if (FAILED(hr))
253       {
254         CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint GUID failed.");
255         SAFE_RELEASE(pProperty);
256         goto failed;
257       }
258
259       std::string strDevName = localWideToUtf(varName.pwszVal);
260
261       if (device == strDevName)
262         i = uiCount;
263       else
264         SAFE_RELEASE(m_pDevice);
265
266       PropVariantClear(&varName);
267       SAFE_RELEASE(pProperty);
268     }
269   }
270   SAFE_RELEASE(pEnumDevices);
271
272   if (!m_pDevice)
273   {
274     if(!bdefault)
275       CLog::Log(LOGINFO, __FUNCTION__": Could not locate the device named \"%s\" in the list of WASAPI endpoint devices.  Trying the default device...", device.c_str());
276     hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_pDevice);
277     EXIT_ON_FAILURE(hr, __FUNCTION__": Could not retrieve the default WASAPI audio endpoint.")
278
279     IPropertyStore *pProperty = NULL;
280     PROPVARIANT varName;
281
282     hr = m_pDevice->OpenPropertyStore(STGM_READ, &pProperty);
283     EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of WASAPI endpoint properties failed.")
284
285     hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName);
286
287     device = localWideToUtf(varName.pwszVal);
288     PropVariantClear(&varName);
289     SAFE_RELEASE(pProperty);
290   }
291
292   SAFE_RELEASE(pEnumerator);
293
294   hr = m_pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&m_pAudioClient);
295   EXIT_ON_FAILURE(hr, __FUNCTION__": Activating the WASAPI endpoint device failed.")
296
297   if (!InitializeExclusive(format))
298   {
299     CLog::Log(LOGINFO, __FUNCTION__": Could not Initialize Exclusive with that format");
300     goto failed;
301   }
302
303   /* get the buffer size and calculate the frames for AE */
304   m_pAudioClient->GetBufferSize(&m_uiBufferLen);
305
306   format.m_frames       = m_uiBufferLen;
307   format.m_frameSamples = format.m_frames * format.m_channelLayout.Count();
308   m_format              = format;
309   sinkRetFormat         = format.m_dataFormat;
310
311   hr = m_pAudioClient->GetService(IID_IAudioRenderClient, (void**)&m_pRenderClient);
312   EXIT_ON_FAILURE(hr, __FUNCTION__": Could not initialize the WASAPI render client interface.")
313
314   m_needDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
315   hr = m_pAudioClient->SetEventHandle(m_needDataEvent);
316   EXIT_ON_FAILURE(hr, __FUNCTION__": Could not set the WASAPI event handler.");
317
318   m_initialized = true;
319   m_isDirty     = false;
320
321   // allow feeding less samples than buffer size
322   // if the device is opened exclusive and event driven, provided samples must match buffersize
323   // ActiveAE tries to align provided samples with buffer size but cannot guarantee (e.g. transcoding)
324   // this can be avoided by dropping the event mode which has not much benefit; SoftAE polls anyway
325   delete [] m_pBuffer;
326   m_pBuffer = new uint8_t[format.m_frames * format.m_frameSize];
327   m_bufferPtr = 0;
328
329   return true;
330
331 failed:
332   CLog::Log(LOGERROR, __FUNCTION__": WASAPI initialization failed.");
333   SAFE_RELEASE(pEnumDevices);
334   SAFE_RELEASE(pEnumerator);
335   SAFE_RELEASE(m_pRenderClient);
336   SAFE_RELEASE(m_pAudioClient);
337   SAFE_RELEASE(m_pDevice);
338   if(m_needDataEvent)
339   {
340     CloseHandle(m_needDataEvent);
341     m_needDataEvent = 0;
342   }
343
344   return false;
345 }
346
347 void CAESinkWASAPI::Deinitialize()
348 {
349   if (!m_initialized && !m_isDirty)
350     return;
351
352   if (m_running)
353   {
354     try
355     {
356     m_pAudioClient->Stop();  //stop the audio output
357     m_pAudioClient->Reset(); //flush buffer and reset audio clock stream position
358     }
359     catch (...)
360     {
361       CLog::Log(LOGDEBUG, __FUNCTION__, "Invalidated AudioClient - Releasing");
362     }
363   }
364   m_running = false;
365
366   CloseHandle(m_needDataEvent);
367
368   SAFE_RELEASE(m_pRenderClient);
369   SAFE_RELEASE(m_pAudioClient);
370   SAFE_RELEASE(m_pDevice);
371
372   m_initialized = false;
373
374   delete [] m_pBuffer;
375   m_bufferPtr = 0;
376 }
377
378 bool CAESinkWASAPI::IsCompatible(const AEAudioFormat &format, const std::string &device)
379 {
380   if (!m_initialized || m_isDirty)
381     return false;
382
383   u_int notCompatible         = 0;
384   const u_int numTests        = 5;
385   std::string strDiffBecause ("");
386   static const char* compatibleParams[numTests] = {":Devices",
387                                                    ":Channels",
388                                                    ":Sample Rates",
389                                                    ":Data Formats",
390                                                    ":Passthrough Formats"};
391
392   notCompatible = (notCompatible  +!((AE_IS_RAW(format.m_dataFormat)  == AE_IS_RAW(m_encodedFormat))        ||
393                                      (!AE_IS_RAW(format.m_dataFormat) == !AE_IS_RAW(m_encodedFormat))))     << 1;
394   notCompatible = (notCompatible  +!((sinkReqFormat                   == format.m_dataFormat)               &&
395                                      (sinkRetFormat                   == m_format.m_dataFormat)))           << 1;
396   notCompatible = (notCompatible  + !(format.m_sampleRate             == m_format.m_sampleRate))            << 1;
397   notCompatible = (notCompatible  + !(format.m_channelLayout.Count()  == m_format.m_channelLayout.Count())) << 1;
398   notCompatible = (notCompatible  + !(m_device                        == device));
399
400   if (!notCompatible)
401   {
402     CLog::Log(LOGDEBUG, __FUNCTION__": Formats compatible - reusing existing sink");
403     return true;
404   }
405
406   for (int i = 0; i < numTests ; i++)
407   {
408     strDiffBecause += (notCompatible & 0x01) ? (std::string) compatibleParams[i] : "";
409     notCompatible    = notCompatible >> 1;
410   }
411
412   CLog::Log(LOGDEBUG, __FUNCTION__": Formats Incompatible due to different %s", strDiffBecause.c_str());
413   return false;
414 }
415
416 double CAESinkWASAPI::GetDelay()
417 {
418   if (!m_initialized)
419     return 0.0;
420
421   double time_played = 0.0;
422   if (m_running)
423   {
424     unsigned int now = XbmcThreads::SystemClockMillis();
425     time_played = (double)(now-m_lastWriteToBuffer) / 1000;
426   }
427
428   double delay = m_sinkLatency - time_played + (double)m_bufferPtr / (double)m_format.m_sampleRate;
429
430   if (delay < 0)
431     delay = 0.0;
432
433   return delay;
434 }
435
436 double CAESinkWASAPI::GetCacheTime()
437 {
438   /* This function deviates from the defined usage due to the event-driven */
439   /* mode of WASAPI utilizing twin buffers which are written to in single  */
440   /* buffer chunks. Therefore the buffers are either 100% full or 50% full */
441   /* At 50% issues arise with water levels in the stream and player. For   */
442   /* this reason the cache is shown as 100% full at all times, and control */
443   /* of the buffer filling is assumed in AddPackets() and by the WASAPI    */
444   /* implementation of the WaitforSingleObject event indicating one of the */
445   /* buffers is ready for filling via AddPackets                           */
446   if (!m_initialized)
447     return 0.0;
448
449   return m_sinkLatency;
450 }
451
452 double CAESinkWASAPI::GetCacheTotal()
453 {
454   if (!m_initialized)
455     return 0.0;
456
457   return m_sinkLatency;
458 }
459
460 unsigned int CAESinkWASAPI::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking)
461 {
462   if (!m_initialized)
463     return 0;
464
465   HRESULT hr;
466   BYTE *buf;
467   DWORD flags = 0;
468
469 #ifndef _DEBUG
470   LARGE_INTEGER timerStart;
471   LARGE_INTEGER timerStop;
472   LARGE_INTEGER timerFreq;
473 #endif
474
475   unsigned int NumFramesRequested = m_format.m_frames;
476   unsigned int FramesToCopy = std::min(m_format.m_frames - m_bufferPtr, frames);
477   if (m_bufferPtr != 0 || frames != m_format.m_frames)
478   {
479     memcpy(m_pBuffer+m_bufferPtr*m_format.m_frameSize, data, FramesToCopy*m_format.m_frameSize);
480     m_bufferPtr += FramesToCopy;
481     if (m_bufferPtr != m_format.m_frames)
482       return frames;
483   }
484
485   if (!m_running) //first time called, pre-fill buffer then start audio client
486   {
487     hr = m_pAudioClient->Reset();
488     if (FAILED(hr))
489     {
490       CLog::Log(LOGERROR, __FUNCTION__ " AudioClient reset failed due to %s", WASAPIErrToStr(hr));
491       return 0;
492     }
493     hr = m_pRenderClient->GetBuffer(NumFramesRequested, &buf);
494     if (FAILED(hr))
495     {
496       #ifdef _DEBUG
497       CLog::Log(LOGERROR, __FUNCTION__": GetBuffer failed due to %s", WASAPIErrToStr(hr));
498       #endif
499       m_isDirty = true; //flag new device or re-init needed
500       return INT_MAX;
501     }
502
503     /* Inject one buffer of silence if sink has just opened */
504     /* to avoid losing start of stream or GUI sound         */
505     if (g_advancedSettings.m_streamSilence)
506       memcpy(buf, data, NumFramesRequested * m_format.m_frameSize); //fill buffer with audio
507     else
508       memset(buf,    0, NumFramesRequested * m_format.m_frameSize); //fill buffer with silence
509
510     hr = m_pRenderClient->ReleaseBuffer(NumFramesRequested, flags); //pass back to audio driver
511     if (FAILED(hr))
512     {
513       #ifdef _DEBUG
514       CLog::Log(LOGDEBUG, __FUNCTION__": ReleaseBuffer failed due to %s.", WASAPIErrToStr(hr));
515       #endif
516       m_isDirty = true; //flag new device or re-init needed
517       return INT_MAX;
518     }
519     hr = m_pAudioClient->Start(); //start the audio driver running
520     if (FAILED(hr))
521       CLog::Log(LOGERROR, __FUNCTION__": AudioClient Start Failed");
522     m_running = true; //signal that we're processing frames
523     return g_advancedSettings.m_streamSilence ? NumFramesRequested : 0U;
524   }
525
526 #ifndef _DEBUG
527   /* Get clock time for latency checks */
528   QueryPerformanceFrequency(&timerFreq);
529   QueryPerformanceCounter(&timerStart);
530 #endif
531
532   /* Wait for Audio Driver to tell us it's got a buffer available */
533   DWORD eventAudioCallback;
534   if(!blocking)
535     eventAudioCallback = WaitForSingleObject(m_needDataEvent, 0);
536   else
537     eventAudioCallback = WaitForSingleObject(m_needDataEvent, 1100);
538
539   if (!blocking)
540   {
541     if(eventAudioCallback != WAIT_OBJECT_0)
542           return 0;
543   }
544   else
545   {
546     if(eventAudioCallback != WAIT_OBJECT_0 || !&buf)
547     {
548       /* Event handle timed out - flag sink as dirty for re-initializing */
549       CLog::Log(LOGERROR, __FUNCTION__": Endpoint Buffer timed out");
550       if (g_advancedSettings.m_streamSilence)
551       {
552         m_isDirty = true; //flag new device or re-init needed
553         Deinitialize();
554         m_running = false;
555         return INT_MAX;
556       }
557     }
558   }
559
560
561   if (!m_running)
562     return 0;
563
564 #ifndef _DEBUG
565   QueryPerformanceCounter(&timerStop);
566   LONGLONG timerDiff = timerStop.QuadPart - timerStart.QuadPart;
567   double timerElapsed = (double) timerDiff * 1000.0 / (double) timerFreq.QuadPart;
568   m_avgTimeWaiting += (timerElapsed - m_avgTimeWaiting) * 0.5;
569
570   if (m_avgTimeWaiting < 3.0)
571   {
572     CLog::Log(LOGDEBUG, __FUNCTION__": Possible AQ Loss: Avg. Time Waiting for Audio Driver callback : %dmsec", (int)m_avgTimeWaiting);
573   }
574 #endif
575
576   hr = m_pRenderClient->GetBuffer(NumFramesRequested, &buf);
577   if (FAILED(hr))
578   {
579     #ifdef _DEBUG
580       CLog::Log(LOGERROR, __FUNCTION__": GetBuffer failed due to %s", WASAPIErrToStr(hr));
581     #endif
582     return INT_MAX;
583   }
584   memcpy(buf, m_bufferPtr == 0 ? data : m_pBuffer, NumFramesRequested * m_format.m_frameSize); //fill buffer
585   m_bufferPtr = 0;
586   hr = m_pRenderClient->ReleaseBuffer(NumFramesRequested, flags); //pass back to audio driver
587   if (FAILED(hr))
588   {
589     #ifdef _DEBUG
590     CLog::Log(LOGDEBUG, __FUNCTION__": ReleaseBuffer failed due to %s.", WASAPIErrToStr(hr));
591     #endif
592     return INT_MAX;
593   }
594   m_lastWriteToBuffer = XbmcThreads::SystemClockMillis();
595
596   if (FramesToCopy != frames)
597   {
598     m_bufferPtr = frames-FramesToCopy;
599     memcpy(m_pBuffer, data+FramesToCopy*m_format.m_frameSize, m_bufferPtr*m_format.m_frameSize);
600   }
601
602   return frames;
603 }
604
605 bool CAESinkWASAPI::SoftSuspend()
606 {
607   /* Sink has been asked to suspend output - we release audio   */
608   /* device as we are in exclusive mode and thus allow external */
609   /* audio sources to play. This requires us to reinitialize    */
610   /* on resume.                                                 */
611
612   Deinitialize();
613
614   return true;
615 }
616
617 bool CAESinkWASAPI::SoftResume()
618 {
619   /* Sink asked to resume output. To release audio device in    */
620   /* exclusive mode we release the device context and therefore */
621   /* must reinitialize. Return false to force re-init by engine */
622
623   return false;
624 }
625
626 void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool force)
627 {
628   IMMDeviceEnumerator* pEnumerator = NULL;
629   IMMDeviceCollection* pEnumDevices = NULL;
630   IMMDevice*           pDefaultDevice = NULL;
631   CAEDeviceInfo        deviceInfo;
632   CAEChannelInfo       deviceChannels;
633   LPWSTR               pwszID = NULL;
634   std::wstring         wstrDDID;
635
636   WAVEFORMATEXTENSIBLE wfxex = {0};
637   HRESULT              hr;
638
639   hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
640   EXIT_ON_FAILURE(hr, __FUNCTION__": Could not allocate WASAPI device enumerator. CoCreateInstance error code: %li", hr)
641
642   UINT uiCount = 0;
643
644   // get the default audio endpoint
645   if(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDevice) == S_OK)
646   {
647     if(pDefaultDevice->GetId(&pwszID) == S_OK)
648     {
649       wstrDDID = pwszID;
650       CoTaskMemFree(pwszID);
651     }
652     SAFE_RELEASE(pDefaultDevice);
653   }
654
655   // enumerate over all audio endpoints
656   hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pEnumDevices);
657   EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint enumeration failed.")
658
659   hr = pEnumDevices->GetCount(&uiCount);
660   EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.")
661
662   for (UINT i = 0; i < uiCount; i++)
663   {
664     IMMDevice *pDevice = NULL;
665     IPropertyStore *pProperty = NULL;
666     PROPVARIANT varName;
667     PropVariantInit(&varName);
668
669     deviceInfo.m_channels.Reset();
670     deviceInfo.m_dataFormats.clear();
671     deviceInfo.m_sampleRates.clear();
672
673     hr = pEnumDevices->Item(i, &pDevice);
674     if (FAILED(hr))
675     {
676       CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint failed.");
677       goto failed;
678     }
679
680     hr = pDevice->OpenPropertyStore(STGM_READ, &pProperty);
681     if (FAILED(hr))
682     {
683       CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint properties failed.");
684       SAFE_RELEASE(pDevice);
685       goto failed;
686     }
687
688     hr = pProperty->GetValue(PKEY_Device_FriendlyName, &varName);
689     if (FAILED(hr))
690     {
691       CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint device name failed.");
692       SAFE_RELEASE(pDevice);
693       SAFE_RELEASE(pProperty);
694       goto failed;
695     }
696
697     std::string strFriendlyName = localWideToUtf(varName.pwszVal);
698     PropVariantClear(&varName);
699
700     hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName);
701     if(FAILED(hr))
702     {
703       CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint GUID failed.");
704       SAFE_RELEASE(pDevice);
705       SAFE_RELEASE(pProperty);
706       goto failed;
707     }
708
709     std::string strDevName = localWideToUtf(varName.pwszVal);
710     PropVariantClear(&varName);
711
712     hr = pProperty->GetValue(PKEY_AudioEndpoint_FormFactor, &varName);
713     if (FAILED(hr))
714     {
715       CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint form factor failed.");
716       SAFE_RELEASE(pDevice);
717       SAFE_RELEASE(pProperty);
718       goto failed;
719     }
720     std::string strWinDevType = winEndpoints[(EndpointFormFactor)varName.uiVal].winEndpointType;
721     AEDeviceType aeDeviceType = winEndpoints[(EndpointFormFactor)varName.uiVal].aeDeviceType;
722
723     PropVariantClear(&varName);
724
725     hr = pProperty->GetValue(PKEY_AudioEndpoint_PhysicalSpeakers, &varName);
726     if (FAILED(hr))
727     {
728       CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint speaker layout failed.");
729       SAFE_RELEASE(pDevice);
730       SAFE_RELEASE(pProperty);
731       goto failed;
732     }
733     unsigned int uiChannelMask = std::max(varName.uintVal, (unsigned int) KSAUDIO_SPEAKER_STEREO);
734
735     deviceChannels.Reset();
736
737     for (unsigned int c = 0; c < WASAPI_SPEAKER_COUNT; c++)
738     {
739       if (uiChannelMask & WASAPIChannelOrder[c])
740         deviceChannels += AEChannelNames[c];
741     }
742
743     PropVariantClear(&varName);
744
745     IAudioClient *pClient;
746     hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pClient);
747     if (SUCCEEDED(hr))
748     {
749       /* Test format DTS-HD */
750       wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
751       wfxex.Format.nSamplesPerSec       = 192000;
752       wfxex.dwChannelMask               = KSAUDIO_SPEAKER_7POINT1_SURROUND;
753       wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
754       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD;
755       wfxex.Format.wBitsPerSample       = 16;
756       wfxex.Samples.wValidBitsPerSample = 16;
757       wfxex.Format.nChannels            = 8;
758       wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
759       wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
760       hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
761       if (SUCCEEDED(hr))
762         deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_DTSHD));
763
764       /* Test format Dolby TrueHD */
765       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP;
766       hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
767       if (SUCCEEDED(hr))
768         deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_TRUEHD));
769
770       /* Test format Dolby EAC3 */
771       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS;
772       wfxex.Format.nChannels            = 2;
773       wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
774       wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
775       hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
776       if (SUCCEEDED(hr))
777         deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_EAC3));
778
779       /* Test format DTS */
780       wfxex.Format.nSamplesPerSec       = 48000;
781       wfxex.dwChannelMask               = KSAUDIO_SPEAKER_5POINT1;
782       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DTS;
783       wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
784       wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
785       hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
786       if (SUCCEEDED(hr))
787         deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_DTS));
788
789       /* Test format Dolby AC3 */
790       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL;
791       hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
792       if (SUCCEEDED(hr))
793         deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AC3));
794
795       /* Test format AAC */
796       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_AAC;
797       hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
798       if (SUCCEEDED(hr))
799         deviceInfo.m_dataFormats.push_back(AEDataFormat(AE_FMT_AAC));
800
801       /* Test format for PCM format iteration */
802       wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
803       wfxex.dwChannelMask               = KSAUDIO_SPEAKER_STEREO;
804       wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
805       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
806
807       for (int p = AE_FMT_FLOAT; p > AE_FMT_INVALID; p--)
808       {
809         if (p < AE_FMT_FLOAT)
810           wfxex.SubFormat               = KSDATAFORMAT_SUBTYPE_PCM;
811         wfxex.Format.wBitsPerSample     = CAEUtil::DataFormatToBits((AEDataFormat) p);
812         wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
813         wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
814         if (p <= AE_FMT_S24NE4 && p >= AE_FMT_S24BE4)
815         {
816           wfxex.Samples.wValidBitsPerSample = 24;
817         }
818         else
819         {
820           wfxex.Samples.wValidBitsPerSample = wfxex.Format.wBitsPerSample;
821         }
822
823         hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
824         if (SUCCEEDED(hr))
825           deviceInfo.m_dataFormats.push_back((AEDataFormat) p);
826       }
827
828       /* Test format for sample rate iteration */
829       wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
830       wfxex.dwChannelMask               = KSAUDIO_SPEAKER_STEREO;
831       wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
832       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_PCM;
833       wfxex.Format.wBitsPerSample       = 16;
834       wfxex.Samples.wValidBitsPerSample = 16;
835       wfxex.Format.nChannels            = 2;
836       wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
837       wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
838
839       for (int j = 0; j < WASAPISampleRateCount; j++)
840       {
841         wfxex.Format.nSamplesPerSec     = WASAPISampleRates[j];
842         wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
843         hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
844         if (SUCCEEDED(hr))
845           deviceInfo.m_sampleRates.push_back(WASAPISampleRates[j]);
846       }
847
848       /* Test format for channels iteration */
849       wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
850       wfxex.dwChannelMask               = KSAUDIO_SPEAKER_STEREO;
851       wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
852       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_PCM;
853       wfxex.Format.nSamplesPerSec       = 48000;
854       wfxex.Format.wBitsPerSample       = 16;
855       wfxex.Samples.wValidBitsPerSample = 16;
856       wfxex.Format.nChannels            = 2;
857       wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
858       wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
859
860       bool hasLpcm = false;
861
862       // Try with KSAUDIO_SPEAKER_DIRECTOUT
863       for (unsigned int k = WASAPI_SPEAKER_COUNT; k > 0; k--)
864       {
865         wfxex.dwChannelMask             = KSAUDIO_SPEAKER_DIRECTOUT;
866         wfxex.Format.nChannels          = k;
867         wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
868         wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
869         hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
870         if (SUCCEEDED(hr))
871         {
872           if (k > 3) // Add only multichannel LPCM
873           {
874             deviceInfo.m_dataFormats.push_back(AE_FMT_LPCM);
875             hasLpcm = true;
876           }
877           break;
878         }
879       }
880
881       /* Try with reported channel mask */
882       for (unsigned int k = WASAPI_SPEAKER_COUNT; k > 0; k--)
883       {
884         wfxex.dwChannelMask             = uiChannelMask;
885         wfxex.Format.nChannels          = k;
886         wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
887         wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
888         hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
889         if (SUCCEEDED(hr))
890         {
891           if ( !hasLpcm && k > 3) // Add only multichannel LPCM
892           {
893             deviceInfo.m_dataFormats.push_back(AE_FMT_LPCM);
894             hasLpcm = true;
895           }
896           break;
897         }
898       }
899
900       /* Try with specific speakers configurations */
901       for (unsigned int i = 0; i < ARRAYSIZE(layoutsList); i++)
902       {
903         unsigned int nmbOfCh;
904         wfxex.dwChannelMask             = ChLayoutToChMask(layoutsList[i], &nmbOfCh);
905         wfxex.Format.nChannels          = nmbOfCh;
906         wfxex.Format.nBlockAlign        = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
907         wfxex.Format.nAvgBytesPerSec    = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
908         hr = pClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
909         if (SUCCEEDED(hr))
910         {
911           if ( deviceChannels.Count() < nmbOfCh)
912             deviceChannels = layoutsList[i];
913           if ( !hasLpcm && nmbOfCh > 3) // Add only multichannel LPCM
914           {
915             deviceInfo.m_dataFormats.push_back(AE_FMT_LPCM);
916             hasLpcm = true;
917           }
918         }
919       }
920       pClient->Release();
921     }
922     else
923     {
924       CLog::Log(LOGDEBUG, __FUNCTION__": Failed to activate device for passthrough capability testing.");
925     }
926
927     deviceInfo.m_deviceName       = strDevName;
928     deviceInfo.m_displayName      = strWinDevType.append(strFriendlyName);
929     deviceInfo.m_displayNameExtra = std::string("WASAPI: ").append(strFriendlyName);
930     deviceInfo.m_deviceType       = aeDeviceType;
931     deviceInfo.m_channels         = deviceChannels;
932
933     /* Store the device info */
934     deviceInfoList.push_back(deviceInfo);
935
936     if(pDevice->GetId(&pwszID) == S_OK)
937     {
938       if(wstrDDID.compare(pwszID) == 0)
939       {
940         deviceInfo.m_deviceName = std::string("default");
941         deviceInfo.m_displayName = std::string("default");
942         deviceInfo.m_displayNameExtra = std::string("");
943         deviceInfoList.push_back(deviceInfo);
944       }
945       CoTaskMemFree(pwszID);
946     }
947
948     SAFE_RELEASE(pDevice);
949     SAFE_RELEASE(pProperty);
950   }
951   return;
952
953 failed:
954
955   if (FAILED(hr))
956     CLog::Log(LOGERROR, __FUNCTION__": Failed to enumerate WASAPI endpoint devices (%s).", WASAPIErrToStr(hr));
957
958   SAFE_RELEASE(pEnumDevices);
959   SAFE_RELEASE(pEnumerator);
960 }
961
962 //Private utility functions////////////////////////////////////////////////////
963
964 void CAESinkWASAPI::BuildWaveFormatExtensible(AEAudioFormat &format, WAVEFORMATEXTENSIBLE &wfxex)
965 {
966   wfxex.Format.wFormatTag        = WAVE_FORMAT_EXTENSIBLE;
967   wfxex.Format.cbSize            = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
968
969
970   if (!AE_IS_RAW(format.m_dataFormat)) // PCM data
971   {
972     wfxex.dwChannelMask          = SpeakerMaskFromAEChannels(format.m_channelLayout);
973     wfxex.Format.nChannels       = (WORD)format.m_channelLayout.Count();
974     wfxex.Format.nSamplesPerSec  = format.m_sampleRate;
975     wfxex.Format.wBitsPerSample  = CAEUtil::DataFormatToBits((AEDataFormat) format.m_dataFormat);
976     wfxex.SubFormat              = format.m_dataFormat <= AE_FMT_FLOAT ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
977   }
978   else //Raw bitstream
979   {
980     wfxex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
981     if (format.m_dataFormat == AE_FMT_AC3 || format.m_dataFormat == AE_FMT_DTS)
982     {
983       wfxex.dwChannelMask               = bool (format.m_channelLayout.Count() == 2) ? KSAUDIO_SPEAKER_STEREO : KSAUDIO_SPEAKER_5POINT1;
984       wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL;
985       wfxex.Format.wBitsPerSample       = 16;
986       wfxex.Samples.wValidBitsPerSample = 16;
987       wfxex.Format.nChannels            = (WORD)format.m_channelLayout.Count();
988       wfxex.Format.nSamplesPerSec       = format.m_sampleRate;
989     }
990     else if (format.m_dataFormat == AE_FMT_EAC3 || format.m_dataFormat == AE_FMT_TRUEHD || format.m_dataFormat == AE_FMT_DTSHD)
991     {
992       /* IEC 61937 transmissions over HDMI */            
993       wfxex.Format.nSamplesPerSec       = 192000L;
994       wfxex.Format.wBitsPerSample       = 16;
995       wfxex.Samples.wValidBitsPerSample = 16;
996       wfxex.dwChannelMask               = KSAUDIO_SPEAKER_7POINT1_SURROUND;
997
998       switch (format.m_dataFormat)
999       {
1000         case AE_FMT_EAC3:
1001           wfxex.SubFormat             = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS;
1002           wfxex.Format.nChannels      = 2; // One IEC 60958 Line.
1003           wfxex.dwChannelMask         = KSAUDIO_SPEAKER_5POINT1;
1004           break;
1005         case AE_FMT_TRUEHD:
1006           wfxex.SubFormat             = KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP;
1007           wfxex.Format.nChannels      = 8; // Four IEC 60958 Lines.
1008           wfxex.dwChannelMask         = KSAUDIO_SPEAKER_7POINT1_SURROUND;
1009           break;
1010         case AE_FMT_DTSHD:
1011           wfxex.SubFormat             = KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD;
1012           wfxex.Format.nChannels      = 8; // Four IEC 60958 Lines.
1013           wfxex.dwChannelMask         = KSAUDIO_SPEAKER_7POINT1_SURROUND;
1014           break;
1015       }
1016
1017       if (format.m_channelLayout.Count() == 8)
1018         wfxex.dwChannelMask         = KSAUDIO_SPEAKER_7POINT1_SURROUND;
1019       else
1020         wfxex.dwChannelMask         = KSAUDIO_SPEAKER_5POINT1;
1021     }
1022   }
1023
1024   if (wfxex.Format.wBitsPerSample == 32 && wfxex.SubFormat != KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)
1025     wfxex.Samples.wValidBitsPerSample = 24;
1026   else
1027     wfxex.Samples.wValidBitsPerSample = wfxex.Format.wBitsPerSample;
1028
1029   wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
1030   wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
1031 }
1032
1033 void CAESinkWASAPI::BuildWaveFormatExtensibleIEC61397(AEAudioFormat &format, WAVEFORMATEXTENSIBLE_IEC61937 &wfxex)
1034 {
1035   /* Fill the common structure */
1036   BuildWaveFormatExtensible(format, wfxex.FormatExt);
1037
1038   /* Code below kept for future use - preferred for later Windows versions */
1039   /* but can cause problems on older Windows versions and drivers          */
1040   /*
1041   wfxex.FormatExt.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE_IEC61937)-sizeof(WAVEFORMATEX);
1042   wfxex.dwEncodedChannelCount   = format.m_channelLayout.Count();
1043   wfxex.dwEncodedSamplesPerSec  = bool(format.m_dataFormat == AE_FMT_TRUEHD ||
1044                                        format.m_dataFormat == AE_FMT_DTSHD  ||
1045                                        format.m_dataFormat == AE_FMT_EAC3) ? 96000L : 48000L;
1046   wfxex.dwAverageBytesPerSec    = 0; //Ignored */
1047 }
1048
1049 bool CAESinkWASAPI::InitializeExclusive(AEAudioFormat &format)
1050 {
1051   WAVEFORMATEXTENSIBLE_IEC61937 wfxex_iec61937;
1052   WAVEFORMATEXTENSIBLE &wfxex = wfxex_iec61937.FormatExt;
1053
1054   if (format.m_dataFormat <= AE_FMT_FLOAT)
1055     BuildWaveFormatExtensible(format, wfxex);
1056   else
1057     BuildWaveFormatExtensibleIEC61397(format, wfxex_iec61937);
1058
1059   /* Test for incomplete format and provide defaults */
1060   if (format.m_sampleRate == 0 ||
1061       format.m_channelLayout == NULL ||
1062       format.m_dataFormat <= AE_FMT_INVALID ||
1063       format.m_dataFormat >= AE_FMT_MAX ||
1064       format.m_channelLayout.Count() == 0)
1065   {
1066     wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
1067     wfxex.Format.nChannels            = 2;
1068     wfxex.Format.nSamplesPerSec       = 44100L;
1069     wfxex.Format.wBitsPerSample       = 16;
1070     wfxex.Format.nBlockAlign          = 4;
1071     wfxex.Samples.wValidBitsPerSample = 16;
1072     wfxex.Format.cbSize               = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
1073     wfxex.Format.nAvgBytesPerSec      = wfxex.Format.nBlockAlign * wfxex.Format.nSamplesPerSec;
1074     wfxex.dwChannelMask               = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
1075     wfxex.SubFormat                   = KSDATAFORMAT_SUBTYPE_PCM;
1076   }
1077
1078   HRESULT hr = m_pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
1079
1080   if (SUCCEEDED(hr))
1081   {
1082     CLog::Log(LOGINFO, __FUNCTION__": Format is Supported - will attempt to Initialize");
1083     goto initialize;
1084   }
1085   else if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT) //It failed for a reason unrelated to an unsupported format.
1086   {
1087     CLog::Log(LOGERROR, __FUNCTION__": IsFormatSupported failed (%s)", WASAPIErrToStr(hr));
1088     return false;
1089   }
1090   else if (AE_IS_RAW(format.m_dataFormat)) //No sense in trying other formats for passthrough.
1091     return false;
1092
1093   CLog::Log(LOGERROR, __FUNCTION__": IsFormatSupported failed (%s) - trying to find a compatible format", WASAPIErrToStr(hr));
1094
1095   int closestMatch;
1096
1097   /* The requested format is not supported by the device.  Find something that works */
1098   for (int j = 0; j < sizeof(testFormats)/sizeof(sampleFormat); j++)
1099   {
1100     closestMatch = -1;
1101
1102     wfxex.Format.wFormatTag           = WAVE_FORMAT_EXTENSIBLE;
1103     wfxex.SubFormat                   = testFormats[j].subFormat;
1104     wfxex.Format.wBitsPerSample       = testFormats[j].bitsPerSample;
1105     wfxex.Samples.wValidBitsPerSample = testFormats[j].validBitsPerSample;
1106     wfxex.Format.nBlockAlign          = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3);
1107
1108     for (int i = 0 ; i < WASAPISampleRateCount; i++)
1109     {
1110       wfxex.Format.nSamplesPerSec    = WASAPISampleRates[i];
1111       wfxex.Format.nAvgBytesPerSec   = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
1112
1113       /* Trace format match iteration loop via log */
1114       #if 0
1115       CLog::Log(LOGDEBUG, "WASAPI: Trying Format: %s, %d, %d, %d", CAEUtil::DataFormatToStr(testFormats[j].subFormatType),
1116                                                                    wfxex.Format.nSamplesPerSec,
1117                                                                    wfxex.Format.wBitsPerSample,
1118                                                                    wfxex.Samples.wValidBitsPerSample);
1119       #endif
1120
1121       hr = m_pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL);
1122
1123       if (SUCCEEDED(hr))
1124       {
1125         /* If the current sample rate matches the source then stop looking and use it */
1126         if ((WASAPISampleRates[i] == format.m_sampleRate) && (testFormats[j].subFormatType <= format.m_dataFormat))
1127           goto initialize;
1128         /* If this rate is closer to the source then the previous one, save it */
1129         else if (closestMatch < 0 || abs((int)WASAPISampleRates[i] - (int)format.m_sampleRate) < abs((int)WASAPISampleRates[closestMatch] - (int)format.m_sampleRate))
1130           closestMatch = i;
1131       }
1132       else if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT)
1133           CLog::Log(LOGERROR, __FUNCTION__": IsFormatSupported failed (%s)", WASAPIErrToStr(hr));
1134     }
1135
1136     if (closestMatch >= 0)
1137     {
1138       wfxex.Format.nSamplesPerSec    = WASAPISampleRates[closestMatch];
1139       wfxex.Format.nAvgBytesPerSec   = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign;
1140       goto initialize;
1141     }
1142   }
1143
1144   CLog::Log(LOGERROR, __FUNCTION__": Unable to locate a supported output format for the device.  Check the speaker settings in the control panel.");
1145
1146   /* We couldn't find anything supported. This should never happen      */
1147   /* unless the user set the wrong speaker setting in the control panel */
1148   return false;
1149
1150 initialize:
1151
1152   AEChannelsFromSpeakerMask(wfxex.dwChannelMask);
1153
1154   /* When the stream is raw, the values in the format structure are set to the link    */
1155   /* parameters, so store the encoded stream values here for the IsCompatible function */
1156   m_encodedFormat     = format.m_dataFormat;
1157   m_encodedChannels   = wfxex.Format.nChannels;
1158   m_encodedSampleRate = format.m_encodedRate;
1159   wfxex_iec61937.dwEncodedChannelCount = wfxex.Format.nChannels;
1160   wfxex_iec61937.dwEncodedSamplesPerSec = m_encodedSampleRate;
1161
1162   /* Set up returned sink format for engine */
1163   if (!AE_IS_RAW(format.m_dataFormat))
1164   {
1165     if (wfxex.Format.wBitsPerSample == 32)
1166     {
1167       if (wfxex.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)
1168         format.m_dataFormat = AE_FMT_FLOAT;
1169       else if (wfxex.Samples.wValidBitsPerSample == 32)
1170         format.m_dataFormat = AE_FMT_S32NE;
1171       else
1172         format.m_dataFormat = AE_FMT_S24NE4;
1173     }
1174     else if (wfxex.Format.wBitsPerSample == 24)
1175       format.m_dataFormat = AE_FMT_S24NE3;
1176     else
1177       format.m_dataFormat = AE_FMT_S16NE;
1178   }
1179
1180   format.m_sampleRate    = wfxex.Format.nSamplesPerSec; //PCM: Sample rate.  RAW: Link speed
1181   format.m_frameSize     = (wfxex.Format.wBitsPerSample >> 3) * wfxex.Format.nChannels;
1182
1183   REFERENCE_TIME audioSinkBufferDurationMsec, hnsLatency;
1184
1185   /* Get m_audioSinkBufferSizeMsec from advancedsettings.xml */
1186   audioSinkBufferDurationMsec = (REFERENCE_TIME)g_advancedSettings.m_audioSinkBufferDurationMsec * 10000;
1187
1188   /* Use advancedsetting value for buffer size as long as it's over minimum set above */
1189   audioSinkBufferDurationMsec = (REFERENCE_TIME)std::max(audioSinkBufferDurationMsec, (REFERENCE_TIME)500000);
1190   audioSinkBufferDurationMsec = (REFERENCE_TIME)((audioSinkBufferDurationMsec / format.m_frameSize) * format.m_frameSize); //even number of frames
1191
1192   if (AE_IS_RAW(format.m_dataFormat))
1193     format.m_dataFormat = AE_FMT_S16NE;
1194
1195   hr = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
1196                                     audioSinkBufferDurationMsec, audioSinkBufferDurationMsec, &wfxex.Format, NULL);
1197
1198   m_hnsRequestedDuration = audioSinkBufferDurationMsec;
1199
1200   if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)
1201   {
1202     /* WASAPI requires aligned buffer */
1203     /* Get the next aligned frame     */
1204     hr = m_pAudioClient->GetBufferSize(&m_uiBufferLen);
1205     if (FAILED(hr))
1206     {
1207       CLog::Log(LOGERROR, __FUNCTION__": GetBufferSize Failed : %s", WASAPIErrToStr(hr));
1208       return false;
1209     }
1210
1211     audioSinkBufferDurationMsec = (REFERENCE_TIME) ((10000.0 * 1000 / wfxex.Format.nSamplesPerSec * m_uiBufferLen) + 0.5);
1212
1213     /* Release the previous allocations */
1214     SAFE_RELEASE(m_pAudioClient);
1215
1216     /* Create a new audio client */
1217     hr = m_pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&m_pAudioClient);
1218     if (FAILED(hr))
1219     {
1220       CLog::Log(LOGERROR, __FUNCTION__": Device Activation Failed : %s", WASAPIErrToStr(hr));
1221       return false;
1222     }
1223
1224     /* Open the stream and associate it with an audio session */
1225     hr = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
1226                                       audioSinkBufferDurationMsec, audioSinkBufferDurationMsec, &wfxex.Format, NULL);
1227   }
1228   if (FAILED(hr))
1229   {
1230     CLog::Log(LOGERROR, __FUNCTION__": Failed to initialize WASAPI in exclusive mode %d - (%s).", HRESULT(hr), WASAPIErrToStr(hr));
1231     CLog::Log(LOGDEBUG, "  Sample Rate     : %d", wfxex.Format.nSamplesPerSec);
1232     CLog::Log(LOGDEBUG, "  Sample Format   : %s", CAEUtil::DataFormatToStr(format.m_dataFormat));
1233     CLog::Log(LOGDEBUG, "  Bits Per Sample : %d", wfxex.Format.wBitsPerSample);
1234     CLog::Log(LOGDEBUG, "  Valid Bits/Samp : %d", wfxex.Samples.wValidBitsPerSample);
1235     CLog::Log(LOGDEBUG, "  Channel Count   : %d", wfxex.Format.nChannels);
1236     CLog::Log(LOGDEBUG, "  Block Align     : %d", wfxex.Format.nBlockAlign);
1237     CLog::Log(LOGDEBUG, "  Avg. Bytes Sec  : %d", wfxex.Format.nAvgBytesPerSec);
1238     CLog::Log(LOGDEBUG, "  Samples/Block   : %d", wfxex.Samples.wSamplesPerBlock);
1239     CLog::Log(LOGDEBUG, "  Format cBSize   : %d", wfxex.Format.cbSize);
1240     CLog::Log(LOGDEBUG, "  Channel Layout  : %s", ((std::string)format.m_channelLayout).c_str());
1241     CLog::Log(LOGDEBUG, "  Enc. Channels   : %d", wfxex_iec61937.dwEncodedChannelCount);
1242     CLog::Log(LOGDEBUG, "  Enc. Samples/Sec: %d", wfxex_iec61937.dwEncodedSamplesPerSec);
1243     CLog::Log(LOGDEBUG, "  Channel Mask    : %d", wfxex.dwChannelMask);
1244     CLog::Log(LOGDEBUG, "  Periodicty      : %d", audioSinkBufferDurationMsec);
1245     return false;
1246   }
1247
1248   /* Latency of WASAPI buffers in event-driven mode is equal to the returned value  */
1249   /* of GetStreamLatency converted from 100ns intervals to seconds then multiplied  */
1250   /* by two as there are two equally-sized buffers and playback starts when the     */
1251   /* second buffer is filled. Multiplying the returned 100ns intervals by 0.0000002 */
1252   /* is handles both the unit conversion and twin buffers.                          */
1253   hr = m_pAudioClient->GetStreamLatency(&hnsLatency);
1254   if (FAILED(hr))
1255   {
1256     CLog::Log(LOGERROR, __FUNCTION__": GetStreamLatency Failed : %s", WASAPIErrToStr(hr));
1257     return false;
1258   }
1259
1260   m_sinkLatency = hnsLatency * 0.0000002;
1261
1262   CLog::Log(LOGINFO, __FUNCTION__": WASAPI Exclusive Mode Sink Initialized using: %s, %d, %d",
1263                                      CAEUtil::DataFormatToStr(format.m_dataFormat),
1264                                      wfxex.Format.nSamplesPerSec,
1265                                      wfxex.Format.nChannels);
1266   return true;
1267 }
1268
1269 void CAESinkWASAPI::AEChannelsFromSpeakerMask(DWORD speakers)
1270 {
1271   m_channelLayout.Reset();
1272
1273   for (int i = 0; i < WASAPI_SPEAKER_COUNT; i++)
1274   {
1275     if (speakers & WASAPIChannelOrder[i])
1276       m_channelLayout += AEChannelNames[i];
1277   }
1278 }
1279
1280 DWORD CAESinkWASAPI::SpeakerMaskFromAEChannels(const CAEChannelInfo &channels)
1281 {
1282   DWORD mask = 0;
1283
1284   for (unsigned int i = 0; i < channels.Count(); i++)
1285   {
1286     for (unsigned int j = 0; j < WASAPI_SPEAKER_COUNT; j++)
1287       if (channels[i] == AEChannelNames[j])
1288         mask |= WASAPIChannelOrder[j];
1289   }
1290   return mask;
1291 }
1292
1293 const char *CAESinkWASAPI::WASAPIErrToStr(HRESULT err)
1294 {
1295   switch(err)
1296   {
1297     ERRTOSTR(AUDCLNT_E_NOT_INITIALIZED);
1298     ERRTOSTR(AUDCLNT_E_ALREADY_INITIALIZED);
1299     ERRTOSTR(AUDCLNT_E_WRONG_ENDPOINT_TYPE);
1300     ERRTOSTR(AUDCLNT_E_DEVICE_INVALIDATED);
1301     ERRTOSTR(AUDCLNT_E_NOT_STOPPED);
1302     ERRTOSTR(AUDCLNT_E_BUFFER_TOO_LARGE);
1303     ERRTOSTR(AUDCLNT_E_OUT_OF_ORDER);
1304     ERRTOSTR(AUDCLNT_E_UNSUPPORTED_FORMAT);
1305     ERRTOSTR(AUDCLNT_E_INVALID_SIZE);
1306     ERRTOSTR(AUDCLNT_E_DEVICE_IN_USE);
1307     ERRTOSTR(AUDCLNT_E_BUFFER_OPERATION_PENDING);
1308     ERRTOSTR(AUDCLNT_E_THREAD_NOT_REGISTERED);
1309     ERRTOSTR(AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED);
1310     ERRTOSTR(AUDCLNT_E_ENDPOINT_CREATE_FAILED);
1311     ERRTOSTR(AUDCLNT_E_SERVICE_NOT_RUNNING);
1312     ERRTOSTR(AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED);
1313     ERRTOSTR(AUDCLNT_E_EXCLUSIVE_MODE_ONLY);
1314     ERRTOSTR(AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL);
1315     ERRTOSTR(AUDCLNT_E_EVENTHANDLE_NOT_SET);
1316     ERRTOSTR(AUDCLNT_E_INCORRECT_BUFFER_SIZE);
1317     ERRTOSTR(AUDCLNT_E_BUFFER_SIZE_ERROR);
1318     ERRTOSTR(AUDCLNT_E_CPUUSAGE_EXCEEDED);
1319     ERRTOSTR(AUDCLNT_E_BUFFER_ERROR);
1320     ERRTOSTR(AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED);
1321     ERRTOSTR(AUDCLNT_E_INVALID_DEVICE_PERIOD);
1322     ERRTOSTR(E_POINTER);
1323     ERRTOSTR(E_INVALIDARG);
1324     ERRTOSTR(E_OUTOFMEMORY);
1325     default: break;
1326   }
1327   return NULL;
1328 }
1329
1330 void CAESinkWASAPI::Drain()
1331 {
1332   if(!m_pAudioClient)
1333     return;
1334
1335   Sleep( (DWORD)(m_hnsRequestedDuration / 10000));
1336
1337   if (m_running)
1338   {
1339     try
1340     {
1341       m_pAudioClient->Stop();  //stop the audio output
1342       m_pAudioClient->Reset(); //flush buffer and reset audio clock stream position
1343     }
1344     catch (...)
1345     {
1346       CLog::Log(LOGDEBUG, __FUNCTION__, "Invalidated AudioClient - Releasing");
1347     }
1348   }
1349   m_running = false;
1350 }