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

Code before:

  return supported;
}


bool CAESinkAUDIOTRACK::IsSupported(int sampleRateInHz, int channelConfig, int encoding)
{
  int ret = CJNIAudioTrack::getMinBufferSize( sampleRateInHz, channelConfig, encoding);
  return (ret > 0);
}

bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device)
{

  // try to recover used device
  if (!m_hasIEC)
    m_info = m_info_raw;
  else if (device == "Default" && !m_info.m_wantsIECPassthrough)
    m_info = m_info_raw;
  else if (device == "AudioTrack (RAW)")
    m_info = m_info_raw;
  else
    m_info = m_info_iec;

  m_format      = format;
  Deinitialize();
  m_stuckCounter = 0;
  m_pause_ms = 0.0;
  CLog::Log(LOGDEBUG,
            "CAESinkAUDIOTRACK::Initialize requested: sampleRate {}; format: {}; channels: {}",
            format.m_sampleRate, CAEUtil::DataFormatToStr(format.m_dataFormat),
            format.m_channelLayout.Count());

  int stream = CJNIAudioManager::STREAM_MUSIC;
  m_encoding = CJNIAudioFormat::ENCODING_PCM_16BIT;

  // If the device supports EAC3 passthrough, but not basic AC3 patthrough, send it as EAC3 (which is AC3 compatible) instead
  if (!m_info.m_wantsIECPassthrough)
  {
    if ((m_format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_AC3) && m_passthrough_use_eac3)
      m_format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_EAC3;
  }

  uint32_t distance = UINT32_MAX; // max upper distance, update at least ones to use one of our samplerates
  for (auto& s : m_sink_sampleRates)
  {
     // prefer best match or alternatively something that divides nicely and
     // is not too far away
     uint32_t d = std::abs((int)m_format.m_sampleRate - (int)s) + 8 * (s > m_format.m_sampleRate ? (s % m_format.m_sampleRate) : (m_format.m_sampleRate % s));
     if (d < distance)
     {

Review comment (bug):
A cosmetic thing is that since now is called always Deinitialize() preventively (which is good) is is displayed the log message "CAESinkAUDIOTRACK::Deinitialize" even the first time. Maybe move the log line: 

CLog::Log(LOGDEBUG, "CAESinkAUDIOTRACK::Deinitialize");

after 

```
  if (!m_at_jni)
    return;
```

(This way, the log is only shown when it's initialized and actually de-initialized)

Code after:

  return supported;
}


bool CAESinkAUDIOTRACK::IsSupported(int sampleRateInHz, int channelConfig, int encoding)
{
  int ret = CJNIAudioTrack::getMinBufferSize( sampleRateInHz, channelConfig, encoding);
  return (ret > 0);
}

bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device)
{

  // try to recover used device
  if (!m_hasIEC)
    m_info = m_info_raw;
  else if (device == "Default" && !m_info.m_wantsIECPassthrough)
    m_info = m_info_raw;
  else if (device == "AudioTrack (RAW)")
    m_info = m_info_raw;
  else
    m_info = m_info_iec;

  m_format      = format;
  Deinitialize();
  CLog::Log(LOGDEBUG,
            "CAESinkAUDIOTRACK::Initialize requested: sampleRate {}; format: {}; channels: {}",
            format.m_sampleRate, CAEUtil::DataFormatToStr(format.m_dataFormat),
            format.m_channelLayout.Count());

  int stream = CJNIAudioManager::STREAM_MUSIC;
  m_encoding = CJNIAudioFormat::ENCODING_PCM_16BIT;

  // If the device supports EAC3 passthrough, but not basic AC3 patthrough, send it as EAC3 (which is AC3 compatible) instead
  if (!m_info.m_wantsIECPassthrough)
  {
    if ((m_format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_AC3) && m_passthrough_use_eac3)
      m_format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_EAC3;
  }

  uint32_t distance = UINT32_MAX; // max upper distance, update at least ones to use one of our samplerates
  for (auto& s : m_sink_sampleRates)
  {
     // prefer best match or alternatively something that divides nicely and
     // is not too far away
     uint32_t d = std::abs((int)m_format.m_sampleRate - (int)s) + 8 * (s > m_format.m_sampleRate ? (s % m_format.m_sampleRate) : (m_format.m_sampleRate % s));
     if (d < distance)
     {
       m_sink_sampleRate = s;
       distance = d;