From bedff7b04314206e212d1b05ac1e0e913ad2902b Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 15 Sep 2013 16:31:22 +0200 Subject: [PATCH 1/3] paplayer: fix gapless playback of cue sheets --- xbmc/cores/paplayer/PAPlayer.cpp | 57 ++++++++++++++++++++++++++++++-- xbmc/cores/paplayer/PAPlayer.h | 1 + 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/xbmc/cores/paplayer/PAPlayer.cpp b/xbmc/cores/paplayer/PAPlayer.cpp index 94a339397bf0a..64792bf6bbbc8 100644 --- a/xbmc/cores/paplayer/PAPlayer.cpp +++ b/xbmc/cores/paplayer/PAPlayer.cpp @@ -75,7 +75,8 @@ PAPlayer::PAPlayer(IPlayerCallback& callback) : m_currentStream (NULL ), m_audioCallback (NULL ), m_FileItem (new CFileItem()), - m_jobCounter (0) + m_jobCounter (0), + m_continueStream (false) { memset(&m_playerGUIData, 0, sizeof(m_playerGUIData)); } @@ -310,6 +311,23 @@ bool PAPlayer::QueueNextFileEx(const CFileItem &file, bool fadeIn/* = true */, b { StreamInfo *si = new StreamInfo(); + // check if we advance a track of a CUE sheet + // if this is the case we don't need to open a new stream + if (file.GetPath().Equals(m_FileItem->GetPath()) && + file.m_lStartOffset && + file.m_lStartOffset == m_FileItem->m_lEndOffset && + m_currentStream && m_currentStream->m_prepareTriggered) + { + m_continueStream = true; + m_upcomingCrossfadeMS = 0; + *m_FileItem = file; + return true; + } + else + { + m_continueStream = false; + } + if (!si->m_decoder.Create(file, (file.m_lStartOffset * 1000) / 75)) { CLog::Log(LOGWARNING, "PAPlayer::QueueNextFileEx - Failed to create the decoder"); @@ -708,8 +726,41 @@ inline bool PAPlayer::ProcessStream(StreamInfo *si, double &delay, double &buffe si->m_decoder.ReadSamples(PACKET_SIZE) == RET_ERROR || ((si->m_endOffset) && (si->m_framesSent / si->m_sampleRate >= (si->m_endOffset - si->m_startOffset) / 1000))) { - CLog::Log(LOGINFO, "PAPlayer::ProcessStream - Stream Finished"); - return false; + if (si == m_currentStream && m_continueStream) + { + // update current stream with info of next track + si->m_startOffset = m_FileItem->m_lStartOffset * 1000 / 75; + if (m_FileItem->m_lEndOffset) + si->m_endOffset = m_FileItem->m_lEndOffset * 1000 / 75; + else + si->m_endOffset = 0; + si->m_framesSent = 0; + + int64_t streamTotalTime = si->m_decoder.TotalTime() - si->m_startOffset; + if (si->m_endOffset) + streamTotalTime = si->m_endOffset - si->m_startOffset; + + // calculate time when to prepare next stream + si->m_prepareNextAtFrame = 0; + if (streamTotalTime >= TIME_TO_CACHE_NEXT_FILE + m_defaultCrossfadeMS) + si->m_prepareNextAtFrame = (int)((streamTotalTime - TIME_TO_CACHE_NEXT_FILE - m_defaultCrossfadeMS) * si->m_sampleRate / 1000.0f); + + si->m_prepareTriggered = false; + si->m_playNextAtFrame = 0; + si->m_playNextTriggered = false; + + //update the current stream to start playing the next track at the correct frame. + UpdateStreamInfoPlayNextAtFrame(m_currentStream, m_upcomingCrossfadeMS); + + UpdateGUIData(si); + m_callback.OnPlayBackStarted(); + m_continueStream = false; + } + else + { + CLog::Log(LOGINFO, "PAPlayer::ProcessStream - Stream Finished"); + return false; + } } if (!QueueData(si)) diff --git a/xbmc/cores/paplayer/PAPlayer.h b/xbmc/cores/paplayer/PAPlayer.h index be21fe3f144e5..f555a91a9b760 100644 --- a/xbmc/cores/paplayer/PAPlayer.h +++ b/xbmc/cores/paplayer/PAPlayer.h @@ -142,6 +142,7 @@ friend class CQueueNextFileJob; StreamList m_finishing; /* finishing streams */ int m_jobCounter; CEvent m_jobEvent; + bool m_continueStream; bool QueueNextFileEx(const CFileItem &file, bool fadeIn = true, bool job = false); void SoftStart(bool wait = false); From a671ea075224aecd6709a9048b7e87c3ed4ede94 Mon Sep 17 00:00:00 2001 From: fritsch Date: Sun, 15 Sep 2013 17:13:37 +0200 Subject: [PATCH 2/3] PaPlayer: Fix crossfade song change for audio cds --- xbmc/cores/paplayer/PAPlayer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/paplayer/PAPlayer.cpp b/xbmc/cores/paplayer/PAPlayer.cpp index 64792bf6bbbc8..88bba5d36b2e6 100644 --- a/xbmc/cores/paplayer/PAPlayer.cpp +++ b/xbmc/cores/paplayer/PAPlayer.cpp @@ -387,8 +387,12 @@ bool PAPlayer::QueueNextFileEx(const CFileItem &file, bool fadeIn/* = true */, b streamTotalTime = si->m_endOffset - si->m_startOffset; si->m_prepareNextAtFrame = 0; - if (streamTotalTime >= TIME_TO_CACHE_NEXT_FILE + m_defaultCrossfadeMS) - si->m_prepareNextAtFrame = (int)((streamTotalTime - TIME_TO_CACHE_NEXT_FILE - m_defaultCrossfadeMS) * si->m_sampleRate / 1000.0f); + // cd drives don't really like it to be crossfaded or prepared + if(!file.IsCDDA()) + { + if (streamTotalTime >= TIME_TO_CACHE_NEXT_FILE + m_defaultCrossfadeMS) + si->m_prepareNextAtFrame = (int)((streamTotalTime - TIME_TO_CACHE_NEXT_FILE - m_defaultCrossfadeMS) * si->m_sampleRate / 1000.0f); + } si->m_prepareTriggered = false; From 7093b1c6f77a813c476e755ed38b402687d330e9 Mon Sep 17 00:00:00 2001 From: fritsch Date: Sun, 15 Sep 2013 21:45:14 +0200 Subject: [PATCH 3/3] paplayer: explicitely disable crossfading for audio cd --- xbmc/cores/paplayer/PAPlayer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/paplayer/PAPlayer.cpp b/xbmc/cores/paplayer/PAPlayer.cpp index 88bba5d36b2e6..e28e3c68c43ce 100644 --- a/xbmc/cores/paplayer/PAPlayer.cpp +++ b/xbmc/cores/paplayer/PAPlayer.cpp @@ -277,7 +277,11 @@ bool PAPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options) void PAPlayer::UpdateCrossfadeTime(const CFileItem& file) { - m_upcomingCrossfadeMS = m_defaultCrossfadeMS = CSettings::Get().GetInt("musicplayer.crossfade") * 1000; + // we explicitely disable crossfading for audio cds + if(file.IsCDDA()) + m_upcomingCrossfadeMS = 0; + else + m_upcomingCrossfadeMS = m_defaultCrossfadeMS = CSettings::Get().GetInt("musicplayer.crossfade") * 1000; if (m_upcomingCrossfadeMS) { if (m_streams.size() == 0 ||