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

Code before:
      }
      else
      {
        double duration =
            (static_cast<double>(loop_written) / m_format.m_frameSize) / m_format.m_sampleRate;
        m_duration_written += duration;
      }

      // just try again to care for fragmentation
      if (written < size)
        out_buf = out_buf + loop_written;

      loop_written = 0;
    }
  }
  unsigned int written_frames = static_cast<unsigned int>(written / m_format.m_frameSize);
  double time_to_add_ms = 1000.0 * (CurrentHostCounter() - startTime) / CurrentHostFrequency();
  // Get Back in Sync with faked pause bursts
  if (m_passthrough && !m_info.m_wantsIECPassthrough)
  {
    if (m_pause_ms > 0.0)
    {
      // Idea here is: Slowly correct the wrong buffer so that AE should not realize
      // but do not underrun while doing so
      double extra_sleep_ms = m_format.m_streamInfo.GetDuration() / 2.0 - time_to_add_ms;
      if (extra_sleep_ms > 0)
      {
        CLog::Log(LOGDEBUG, "Sleeping for {:f}", extra_sleep_ms);
        m_pause_ms -= extra_sleep_ms;
        usleep(extra_sleep_ms * 1000);
      }
      if (m_pause_ms <= 0.0)
      {
        m_pause_ms = 0.0;
        extra_sleep_ms = 0.0;
        CLog::Log(LOGDEBUG, "Resetting pause bursts as buffer level was reached! (1)");
      }
    }
  }
  return written_frames;
}

void CAESinkAUDIOTRACK::AddPause(unsigned int millis)
{
  if (!m_at_jni)
    return;

  // just sleep out the frames
  if (m_at_jni->getPlayState() != CJNIAudioTrack::PLAYSTATE_PAUSED)
    m_at_jni->pause();


Review comment (suggestion):
As commented in forum this improves a lot DTS-HD MA in RAW. 

Tested 4.0 divider and not improves TrueHD and broke DTS-HD MA again. Tested also 1.5 with no good results.

Seems 2.0 is the best value for DTS-HD MA and anyway devices that supports TrueHD also should be able to use IEC and Kodi packer.

Code after:
        }
      }
      else
      {
        double duration =
            (static_cast<double>(loop_written) / m_format.m_frameSize) / m_format.m_sampleRate;
        m_duration_written += duration;
      }

      // just try again to care for fragmentation
      if (written < size)
        out_buf = out_buf + loop_written;

      loop_written = 0;
    }
  }
  unsigned int written_frames = static_cast<unsigned int>(written / m_format.m_frameSize);
  double time_to_add_ms = 1000.0 * (CurrentHostCounter() - startTime) / CurrentHostFrequency();
  // Get Back in Sync with faked pause bursts
  if (m_passthrough && !m_info.m_wantsIECPassthrough)
  {
    if (m_pause_ms > 0.0)
    {
      // Idea here is: Slowly correct the wrong buffer so that AE should not realize
      // but do not underrun while doing so
      double extra_sleep_ms = m_format.m_streamInfo.GetDuration() / 2.0 - time_to_add_ms;
      if (extra_sleep_ms > 0)
      {
        CLog::Log(LOGDEBUG, "Sleeping for {:f}", extra_sleep_ms);
        m_pause_ms -= extra_sleep_ms;
        usleep(extra_sleep_ms * 1000);
      }
      if (m_pause_ms <= 0.0)
      {
        m_pause_ms = 0.0;
        extra_sleep_ms = 0.0;
        CLog::Log(LOGDEBUG, "Resetting pause bursts as buffer level was reached! (1)");
      }
    }
  }
  return written_frames;
}

void CAESinkAUDIOTRACK::AddPause(unsigned int millis)
{
  if (!m_at_jni)
    return;

  // just sleep out the frames
  if (m_at_jni->getPlayState() != CJNIAudioTrack::PLAYSTATE_PAUSED)
    m_at_jni->pause();