bool PAPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options) { m_defaultCrossfadeMS = CSettings::GetInstance().GetInt(CSettings::SETTING_MUSICPLAYER_CROSSFADE) * 1000; if (m_streams.size() > 1 || !m_defaultCrossfadeMS || m_isPaused) { CloseAllStreams(!m_isPaused); StopThread(); m_isPaused = false; // Make sure to reset the pause state } // if audio engine is suspended i.e. by a DisplayLost event (HDMI), MakeStream // waits until the engine is resumed. if we block the main thread here, it can't // resume the engine after a DisplayReset event if (CAEFactory::IsSuspended()) { if (!QueueNextFile(file)) return false; } else { if (!QueueNextFileEx(file, false)) return false; } CSharedLock lock(m_streamsLock); if (m_streams.size() == 2) { //do a short crossfade on trackskip, set to max 2 seconds for these prev/next transitions m_upcomingCrossfadeMS = std::min(m_defaultCrossfadeMS, (unsigned int)MAX_SKIP_XFADE_TIME); //start transition to next track StreamInfo* si = m_streams.front(); si->m_playNextAtFrame = si->m_framesSent; //start next track at current frame si->m_prepareTriggered = true; //next track is ready to go } lock.Leave(); if (!IsRunning()) Create(); /* trigger playback start */ m_isPlaying = true; m_startEvent.Set(); if (options.startpercent > 0.0) { Sleep(50); SeekPercentage(options.startpercent); } return true; }
bool PAPlayer::QueueNextFile(const CFileItem &file) { return QueueNextFile(file, true); }
bool PAPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options) { if (m_currentlyCrossFading) CloseFileInternal(false); //user seems to be in a hurry m_crossFading = g_guiSettings.GetInt("musicplayer.crossfade"); //WASAPI doesn't support multiple streams, no crossfading for cdda, cd-reading goes mad and no crossfading for last.fm doesn't like two connections if (file.IsCDDA() || file.IsLastFM() || g_guiSettings.GetString("audiooutput.audiodevice").find("wasapi:") != CStdString::npos) m_crossFading = 0; if (m_crossFading && IsPlaying()) { //do a short crossfade on trackskip //set to max 2 seconds for these prev/next transitions if (m_crossFading > 2) m_crossFading = 2; //queue for crossfading bool result = QueueNextFile(file, false); if (result) { //crossfading value may be update by QueueNextFile when nr of channels changed if (!m_crossFading) // swap to next track m_decoder[m_currentDecoder].SetStatus(STATUS_ENDED); else //force to fade to next track immediately m_forceFadeToNext = true; } return result; } // normal opening of file, nothing playing or crossfading not enabled // however no need to return to gui audio device CloseFileInternal(false); // always open the file using the current decoder m_currentDecoder = 0; if (!m_decoder[m_currentDecoder].Create(file, (__int64)(options.starttime * 1000), m_crossFading)) return false; m_iSpeed = 1; m_bPaused = false; m_bStopPlaying = false; m_bytesSentOut = 0; CLog::Log(LOGINFO, "PAPlayer: Playing %s", file.m_strPath.c_str()); m_timeOffset = (__int64)(options.starttime * 1000); unsigned int channel, sampleRate, bitsPerSample; m_decoder[m_currentDecoder].GetDataFormat(&channel, &sampleRate, &bitsPerSample); if (!CreateStream(m_currentStream, channel, sampleRate, bitsPerSample)) { m_decoder[m_currentDecoder].Destroy(); CLog::Log(LOGERROR, "PAPlayer::Unable to create audio stream"); } *m_currentFile = file; if (ThreadHandle() == NULL) Create(); m_startEvent.Set(); m_bIsPlaying = true; m_cachingNextFile = false; m_currentlyCrossFading = false; m_forceFadeToNext = false; m_bQueueFailed = false; m_decoder[m_currentDecoder].Start(); // start playback return true; }