Repository: xbmc/xbmc
File: xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp (C++)

Code before:

  if (isPassthrough)
    format.m_dataFormat = AE_FMT_S16NE;

  auto AudioClientInitialize = [this](REFERENCE_TIME bufferDurationHns, WAVEFORMATEX* format,
                                      bool needNewClient) -> HRESULT
  {
    if (needNewClient && m_pAudioClient != nullptr)
    {
      if (HRESULT hr = m_pDevice->Activate(m_pAudioClient.ReleaseAndGetAddressOf()); FAILED(hr))
      {
        CLog::LogF(LOGERROR, "Device Activation Failed : {}", CWIN32Util::FormatHRESULT(hr));
        return hr;
      }
    }

    return m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE,
                                      AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
                                          AUDCLNT_STREAMFLAGS_NOPERSIST,
                                      bufferDurationHns, bufferDurationHns, format, NULL);
  };

  REFERENCE_TIME audioSinkBufferDurationHns{bufferDuration.count() / 100};
  bool needNewClient = false;

  while (audioSinkBufferDurationHns >= hnsDefaultDevicePeriod)
  {
    hr = AudioClientInitialize(audioSinkBufferDurationHns, &wfxex.Format, needNewClient);

    if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)
    {
      // WASAPI requires aligned buffer. Get the next aligned frame
      if (FAILED(hr = m_pAudioClient->GetBufferSize(&m_uiBufferLen)))
      {
        CLog::LogF(LOGERROR, "GetBufferSize Failed : {}", CWIN32Util::FormatHRESULT(hr));
        return false;
      }

      audioSinkBufferDurationHns = static_cast<REFERENCE_TIME>(
          (10000.0 * 1000 / wfxex.Format.nSamplesPerSec * m_uiBufferLen) + 0.5);
      needNewClient = true;
    }
    else if (hr == AUDCLNT_E_BUFFER_SIZE_ERROR || hr == AUDCLNT_E_INVALID_DEVICE_PERIOD ||
             hr == E_OUTOFMEMORY)
    {
      // Requested buffer was too large, try again with a duration reduced by the min device period
      audioSinkBufferDurationHns -= hnsDefaultDevicePeriod;
      needNewClient = false;
    }
    else
    {

Review comment (suggestion):
This loop should be changed to do while loop because you want execute always:

```c++
do
{
   hr = AudioClientInitialize(...);
}
while (hr != S_OK && sinkBufferDurationHns >= hnsDefaultDevicePeriod);
```

Also the else break; condition it's quite ugly.

Code after:
    {
      if (HRESULT hr = m_pDevice->Activate(m_pAudioClient.ReleaseAndGetAddressOf()); FAILED(hr))
      {
        CLog::LogF(LOGERROR, "Device Activation Failed : {}", CWIN32Util::FormatHRESULT(hr));
        return hr;
      }
    }

    const AUDCLNT_SHAREMODE mode = AUDCLNT_SHAREMODE_EXCLUSIVE;
    const DWORD flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST;
    return m_pAudioClient->Initialize(mode, flags, periodHns, periodHns, format, NULL);
  };

  REFERENCE_TIME bufferHns{period.count() / 100};
  bool needNewClient = false;

  do
  {
    hr = AudioClientInitialize(bufferHns, &wfxex.Format, needNewClient);

    if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)
    {
      // WASAPI requires aligned buffer. Get the next aligned frame
      UINT32 numBufferFrames;
      if (FAILED(hr = m_pAudioClient->GetBufferSize(&numBufferFrames)))
      {
        CLog::LogF(LOGERROR, "GetBufferSize Failed : {}", CWIN32Util::FormatHRESULT(hr));
        return false;
      }

      bufferHns = static_cast<REFERENCE_TIME>(
          (10000.0 * 1000 / wfxex.Format.nSamplesPerSec * numBufferFrames) + 0.5);
      needNewClient = true;
    }
    else if (hr == AUDCLNT_E_BUFFER_SIZE_ERROR || hr == AUDCLNT_E_INVALID_DEVICE_PERIOD ||
             hr == E_OUTOFMEMORY)
    {
      // Requested buffer was too large, try again with a duration reduced by the min device period
      bufferHns -= defaultDevicePeriodHns;
      needNewClient = false;
    }
    else
    {
      // Success or HRESULT without dedicated handling
      break;
    }
  } while (bufferHns >= defaultDevicePeriodHns);

  if (FAILED(hr))
  {
    CLog::LogF(LOGERROR, "Failed to initialize WASAPI in exclusive mode - {}.",