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