mirror of
https://github.com/strawberrymusicplayer/strawberry
synced 2024-12-27 16:54:19 +01:00
Remove broken xine fader until it's properly fixed
This commit is contained in:
parent
099d098dc7
commit
41b0b1efd4
@ -528,7 +528,7 @@ optional_source(HAVE_GSTREAMER
|
||||
|
||||
# Xine
|
||||
optional_source(HAVE_XINE
|
||||
SOURCES engine/xineengine.cpp engine/xinescope.c engine/xinefader.cpp
|
||||
SOURCES engine/xineengine.cpp engine/xinescope.c
|
||||
HEADERS engine/xineengine.h
|
||||
)
|
||||
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include "enginetype.h"
|
||||
#include "xineengine.h"
|
||||
#include "xinescope.h"
|
||||
#include "xinefader.h"
|
||||
|
||||
#include "settings/backendsettingspage.h"
|
||||
|
||||
@ -80,8 +79,6 @@ XineEngine::XineEngine(TaskManager *task_manager)
|
||||
eventqueue_(nullptr),
|
||||
post_(nullptr),
|
||||
preamp_(1.0),
|
||||
stop_fader_(false),
|
||||
fadeout_running_ (false),
|
||||
prune_(nullptr) {
|
||||
|
||||
type_ = Engine::Xine;
|
||||
@ -91,11 +88,6 @@ XineEngine::XineEngine(TaskManager *task_manager)
|
||||
|
||||
XineEngine::~XineEngine() {
|
||||
|
||||
if (fadeout_enabled_) {
|
||||
bool terminateFader = false;
|
||||
FadeOut(fadeout_duration_, &terminateFader, true); // true == exiting
|
||||
}
|
||||
|
||||
Cleanup();
|
||||
|
||||
}
|
||||
@ -122,7 +114,7 @@ bool XineEngine::Init() {
|
||||
prune_.reset(new PruneScopeThread(this));
|
||||
prune_->start();
|
||||
#endif
|
||||
|
||||
|
||||
SetDevice();
|
||||
|
||||
if (!ValidOutput(output_)) {
|
||||
@ -148,16 +140,6 @@ void XineEngine::Cleanup() {
|
||||
}
|
||||
prune_.reset();
|
||||
|
||||
// Wait until the fader thread is done
|
||||
if (s_fader_) {
|
||||
stop_fader_ = true;
|
||||
s_fader_->resume(); // safety call if the engine is in the pause state
|
||||
s_fader_->wait();
|
||||
}
|
||||
|
||||
s_fader_.reset();
|
||||
s_outfader_.reset();
|
||||
|
||||
if (stream_)
|
||||
xine_close(stream_);
|
||||
if (eventqueue_) {
|
||||
@ -189,7 +171,7 @@ void XineEngine::Cleanup() {
|
||||
|
||||
Engine::State XineEngine::state() const {
|
||||
|
||||
if (!stream_ || fadeout_running_) return Engine::Empty;
|
||||
if (!stream_) return Engine::Empty;
|
||||
|
||||
switch(xine_get_status(stream_)) {
|
||||
case XINE_STATUS_PLAY:
|
||||
@ -208,24 +190,6 @@ bool XineEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool for
|
||||
|
||||
Engine::Base::Load(url, change, force_stop_at_end, beginning_nanosec, end_nanosec);
|
||||
|
||||
if (s_outfader_) {
|
||||
s_outfader_->finish();
|
||||
s_outfader_.reset();
|
||||
}
|
||||
|
||||
if (fade_length_ > 0 && xine_get_status(stream_) == XINE_STATUS_PLAY && url.scheme().toLower() == "file" && xine_get_param(stream_, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE && (fade_next_track_ || crossfade_enabled_)) {
|
||||
|
||||
fade_next_track_ = false; // Set by engine controller when switching tracks automatically
|
||||
|
||||
// Stop a probably running fader
|
||||
if (s_fader_) {
|
||||
stop_fader_ = true;
|
||||
s_fader_->finish(); // Makes the fader stop abruptly
|
||||
}
|
||||
s_fader_.reset(new XineFader(this, xine_, stream_, audioport_, post_, fade_length_));
|
||||
SetEqualizerParameters(int_preamp_, equalizer_gains_);
|
||||
}
|
||||
|
||||
xine_close(stream_);
|
||||
|
||||
//int result = xine_open(stream_, url.path().toUtf8());
|
||||
@ -244,8 +208,6 @@ bool XineEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool for
|
||||
qLog(Error) << "Failed to play";
|
||||
}
|
||||
|
||||
// FAILURE to load!
|
||||
// s_fader_ will delete itself
|
||||
DetermineAndShowErrorMessage();
|
||||
|
||||
return false;
|
||||
@ -260,16 +222,9 @@ bool XineEngine::Play(quint64 offset_nanosec) {
|
||||
const bool audio_handled = xine_get_stream_info(stream_, XINE_STREAM_INFO_AUDIO_HANDLED);
|
||||
|
||||
if (has_audio && audio_handled && xine_play(stream_, 0, offset)) {
|
||||
if (s_fader_) s_fader_->start(QThread::LowestPriority);
|
||||
|
||||
emit StateChanged(Engine::Playing);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to stop the track that is prepped for crossfade
|
||||
if (s_fader_) s_fader_.reset();
|
||||
|
||||
emit StateChanged(Engine::Empty);
|
||||
|
||||
DetermineAndShowErrorMessage();
|
||||
@ -281,26 +236,14 @@ bool XineEngine::Play(quint64 offset_nanosec) {
|
||||
|
||||
void XineEngine::Stop(bool stop_after) {
|
||||
|
||||
if (s_fader_ && s_fader_->isRunning())
|
||||
s_fader_->resume(); // Safety call if the engine is in the pause state
|
||||
|
||||
if (!stream_) return;
|
||||
|
||||
if ((fadeout_enabled_ && !fadeout_running_) || state() == Engine::Paused) {
|
||||
s_outfader_.reset(new XineOutFader(this, fadeout_duration_));
|
||||
s_outfader_->start();
|
||||
::usleep(100); // To be sure engine state won't be changed before it is checked in FadeOut()
|
||||
url_ = QUrl(); // To ensure we return Empty from state()
|
||||
|
||||
std::fill(scope_.begin(), scope_.end(), 0);
|
||||
}
|
||||
else if (!fadeout_running_) {
|
||||
xine_stop(stream_);
|
||||
xine_close(stream_);
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
|
||||
}
|
||||
xine_stop(stream_);
|
||||
xine_close(stream_);
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
|
||||
|
||||
emit StateChanged(Engine::Empty);
|
||||
|
||||
}
|
||||
|
||||
void XineEngine::Pause() {
|
||||
@ -308,13 +251,9 @@ void XineEngine::Pause() {
|
||||
if (!stream_) return;
|
||||
|
||||
if (xine_get_param(stream_, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE) {
|
||||
|
||||
if (s_fader_ && s_fader_->isRunning()) s_fader_->pause();
|
||||
|
||||
xine_set_param(stream_, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
|
||||
emit StateChanged(Engine::Paused);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -324,12 +263,8 @@ void XineEngine::Unpause() {
|
||||
if (!stream_) return;
|
||||
|
||||
if (xine_get_param(stream_, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) {
|
||||
|
||||
if (s_fader_ && s_fader_->isRunning()) s_fader_->resume();
|
||||
|
||||
xine_set_param(stream_, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
|
||||
emit StateChanged(Engine::Playing);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -351,8 +286,7 @@ void XineEngine::Seek(quint64 offset_nanosec) {
|
||||
void XineEngine::SetVolumeSW(uint vol) {
|
||||
|
||||
if (!stream_) return;
|
||||
if (!s_fader_)
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_AMP_LEVEL, static_cast<uint>(vol * preamp_));
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_AMP_LEVEL, static_cast<uint>(vol * preamp_));
|
||||
|
||||
}
|
||||
|
||||
@ -658,46 +592,6 @@ void XineEngine::SetEqualizerParameters(int preamp, const QList<int> &gains) {
|
||||
|
||||
}
|
||||
|
||||
void XineEngine::FadeOut(uint fadeLength, bool *terminate, bool exiting) {
|
||||
|
||||
if (fadeout_running_) return; // Don't start another fadeout
|
||||
|
||||
fadeout_running_ = !fadeout_running_;
|
||||
const bool isPlaying = stream_ && (xine_get_status(stream_) == XINE_STATUS_PLAY);
|
||||
const float originalVol = Engine::Base::MakeVolumeLogarithmic(volume_) * preamp_;
|
||||
|
||||
// On shutdown, limit fadeout to 3 secs max, so that we don't risk getting killed
|
||||
const int length = exiting ? qMin(fadeLength, 3000u) : fadeLength;
|
||||
|
||||
if (length > 0 && isPlaying) {
|
||||
// fader-class doesn't work in this spot as is, so some parts need to be copied here... (ugly)
|
||||
uint stepsCount = length < 1000 ? length / 10 : 100;
|
||||
uint stepSizeUs = (int)(1000.0 * (float)length / (float)stepsCount);
|
||||
|
||||
::usleep(stepSizeUs);
|
||||
QTime t;
|
||||
t.start();
|
||||
float mix = 0.0;
|
||||
while (mix < 1.0) {
|
||||
if (*terminate) break;
|
||||
|
||||
::usleep(stepSizeUs);
|
||||
float vol = Engine::Base::MakeVolumeLogarithmic(volume_) * preamp_;
|
||||
float mix = (float)t.elapsed() / (float)length;
|
||||
if (mix > 1.0) break;
|
||||
if (stream_) {
|
||||
float v = 4.0 * (1.0 - mix) / 3.0;
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(v < 1.0 ? vol * v : vol));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fadeout_running_ && stream_)
|
||||
xine_set_param(stream_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint) originalVol);
|
||||
|
||||
fadeout_running_ = !fadeout_running_;
|
||||
|
||||
}
|
||||
|
||||
void XineEngine::XineEventListener(void *p, const xine_event_t *xineEvent) {
|
||||
|
||||
time_t current;
|
||||
@ -953,13 +847,13 @@ bool XineEngine::CreateStream() {
|
||||
#endif
|
||||
|
||||
#ifdef XINE_PARAM_EARLY_FINISHED_EVENT
|
||||
if (xine_check_version(1, 1, 1) && !(fade_length_ > 0)) {
|
||||
// Enable gapless playback
|
||||
qLog(Debug) << "gapless playback enabled.";
|
||||
xine_set_param(stream_, XINE_PARAM_EARLY_FINISHED_EVENT, 1);
|
||||
}
|
||||
// Enable gapless playback
|
||||
qLog(Debug) << "gapless playback enabled.";
|
||||
xine_set_param(stream_, XINE_PARAM_EARLY_FINISHED_EVENT, 1);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool XineEngine::EnsureStream() {
|
||||
|
@ -40,8 +40,6 @@ using std::shared_ptr;
|
||||
|
||||
class TaskManager;
|
||||
class PruneScopeThread;
|
||||
class XineFader;
|
||||
class XineOutFader;
|
||||
|
||||
class XineEvent : public QEvent {
|
||||
public:
|
||||
@ -97,15 +95,11 @@ class XineEngine : public Engine::Base {
|
||||
|
||||
void SetEqualizerEnabled(bool enabled);
|
||||
void SetEqualizerParameters(int preamp, const QList<int>&);
|
||||
|
||||
void FadeOut(uint fadeLength, bool* terminate, bool exiting = false);
|
||||
|
||||
// Simple accessors
|
||||
|
||||
xine_stream_t *stream() { return stream_; }
|
||||
float preamp() { return preamp_; }
|
||||
bool stop_fader() { return stop_fader_; }
|
||||
void set_stop_fader(bool stop_fader) { stop_fader_ = stop_fader; }
|
||||
|
||||
private:
|
||||
static const char *kAutoOutput;
|
||||
@ -119,8 +113,6 @@ class XineEngine : public Engine::Base {
|
||||
xine_event_queue_t *eventqueue_;
|
||||
xine_post_t *post_;
|
||||
float preamp_;
|
||||
bool stop_fader_;
|
||||
bool fadeout_running_;
|
||||
std::unique_ptr<PruneScopeThread> prune_;
|
||||
|
||||
QUrl url_;
|
||||
@ -132,15 +124,10 @@ class XineEngine : public Engine::Base {
|
||||
uint log_scope_call_count_ = 1; // Prevent divideByZero
|
||||
uint log_no_suitable_buffer_ = 0;
|
||||
|
||||
std::unique_ptr<XineFader> s_fader_;
|
||||
std::unique_ptr<XineOutFader> s_outfader_;
|
||||
|
||||
int int_preamp_;
|
||||
QMutex init_mutex_;
|
||||
int64_t current_vpts_;
|
||||
QList<int> equalizer_gains_;
|
||||
int fade_length_;
|
||||
bool fade_next_track_;
|
||||
|
||||
mutable Engine::SimpleMetaBundle current_bundle_;
|
||||
|
||||
|
@ -1,150 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2017-2018 Jonas Kvinge <jonas@jkvinge.net> *
|
||||
* Copyright (C) 2005 Christophe Thommeret <hftom@free.fr> *
|
||||
* (C) 2005 Ian Monroe <ian@monroe.nu> *
|
||||
* (C) 2005-2006 Mark Kretschmann <markey@web.de> *
|
||||
* (C) 2004-2005 Max Howell <max.howell@methylblue.com> *
|
||||
* (C) 2003-2004 J. Kofler <kaffeine@gmx.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <xine.h>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QThread>
|
||||
|
||||
#include "core/logging.h"
|
||||
|
||||
#include "xineengine.h"
|
||||
#include "xinefader.h"
|
||||
|
||||
XineFader::XineFader(XineEngine *engine, xine_t *xine, xine_stream_t *stream, xine_audio_port_t *audioport, xine_post_t *post, uint fade_length)
|
||||
: QThread(engine),
|
||||
engine_(engine),
|
||||
xine_(xine),
|
||||
stream_(stream),
|
||||
decrease_(stream),
|
||||
increase_(nullptr),
|
||||
port_(audioport),
|
||||
post_(post),
|
||||
fade_length_(fade_length),
|
||||
paused_(false),
|
||||
terminated_(false) {
|
||||
|
||||
if (engine->CreateStream()) {
|
||||
increase_ = stream_;
|
||||
xine_set_param(increase_, XINE_PARAM_AUDIO_AMP_LEVEL, 0);
|
||||
}
|
||||
else {
|
||||
terminated_ = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
XineFader::~XineFader() {
|
||||
|
||||
wait();
|
||||
|
||||
xine_close(decrease_);
|
||||
xine_dispose(decrease_);
|
||||
xine_close_audio_driver(xine_, port_);
|
||||
if (post_) xine_post_dispose(xine_, post_);
|
||||
|
||||
if (!engine_->stop_fader())
|
||||
engine_->SetVolume(engine_->volume());
|
||||
|
||||
engine_->set_stop_fader(false);
|
||||
|
||||
}
|
||||
|
||||
void XineFader::run() {
|
||||
|
||||
// Do a volume change in 100 steps (or every 10ms)
|
||||
uint stepsCount = fade_length_ < 1000 ? fade_length_ / 10 : 100;
|
||||
uint stepSizeUs = (int)(1000.0 * (float)fade_length_ / (float)stepsCount);
|
||||
|
||||
float mix = 0.0;
|
||||
float elapsedUs = 0.0;
|
||||
while (mix < 1.0) {
|
||||
if (terminated_) break;
|
||||
// Sleep a constant amount of time
|
||||
QThread::usleep(stepSizeUs);
|
||||
|
||||
if (paused_)
|
||||
continue;
|
||||
|
||||
elapsedUs += stepSizeUs;
|
||||
|
||||
// Get volume (amarok main * equalizer preamp)
|
||||
float vol = Engine::Base::MakeVolumeLogarithmic(engine_->volume()) * engine_->preamp();
|
||||
|
||||
// Compute the mix factor as the percentage of time spent since fade begun
|
||||
float mix = (elapsedUs / 1000.0) / (float)fade_length_;
|
||||
if (mix > 1.0) {
|
||||
if (increase_) xine_set_param(increase_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)vol);
|
||||
break;
|
||||
}
|
||||
|
||||
// Change volume of streams (using dj-like cross-fade profile)
|
||||
if (decrease_) {
|
||||
//xine_set_param(decrease_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(vol * (1.0 - mix))); // linear
|
||||
float v = 4.0 * (1.0 - mix) / 3.0;
|
||||
xine_set_param(decrease_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(v < 1.0 ? vol * v : vol));
|
||||
}
|
||||
if (increase_) {
|
||||
// xine_set_param(increase_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(vol * mix)); //linear
|
||||
float v = 4.0 * mix / 3.0;
|
||||
xine_set_param(increase_, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(v < 1.0 ? vol * v : vol));
|
||||
}
|
||||
}
|
||||
|
||||
// Stop using cpu!
|
||||
xine_stop(decrease_);
|
||||
|
||||
}
|
||||
|
||||
void XineFader::pause() {
|
||||
paused_ = true;
|
||||
}
|
||||
|
||||
void XineFader::resume() {
|
||||
paused_ = false;
|
||||
}
|
||||
|
||||
void XineFader::finish() {
|
||||
terminated_ = true;
|
||||
}
|
||||
|
||||
XineOutFader::XineOutFader(XineEngine *engine, uint fadeLength)
|
||||
: QThread(engine),
|
||||
engine_(engine),
|
||||
terminated_(false),
|
||||
fade_length_(fadeLength)
|
||||
{
|
||||
}
|
||||
|
||||
XineOutFader::~XineOutFader() {
|
||||
wait();
|
||||
}
|
||||
|
||||
void XineOutFader::run() {
|
||||
|
||||
engine_->FadeOut(fade_length_, &terminated_);
|
||||
|
||||
xine_stop(engine_->stream());
|
||||
xine_close(engine_->stream());
|
||||
xine_set_param(engine_->stream(), XINE_PARAM_AUDIO_CLOSE_DEVICE, 1);
|
||||
|
||||
}
|
||||
|
||||
void XineOutFader::finish() {
|
||||
terminated_ = true;
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2017-2018 Jonas Kvinge <jonas@jkvinge.net> *
|
||||
* Copyright (C) 2005 Christophe Thommeret <hftom@free.fr> *
|
||||
* (C) 2005 Ian Monroe <ian@monroe.nu> *
|
||||
* (C) 2005-2006 Mark Kretschmann <markey@web.de> *
|
||||
* (C) 2004-2005 Max Howell <max.howell@methylblue.com> *
|
||||
* (C) 2003-2004 J. Kofler <kaffeine@gmx.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef XINEFADER_H
|
||||
#define XINEFADER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QThread>
|
||||
|
||||
class XineFader : public QThread {
|
||||
|
||||
private:
|
||||
|
||||
XineEngine *engine_;
|
||||
xine_t *xine_;
|
||||
xine_stream_t *stream_;
|
||||
xine_stream_t *decrease_;
|
||||
xine_stream_t *increase_;
|
||||
xine_audio_port_t *port_;
|
||||
xine_post_t *post_;
|
||||
uint fade_length_;
|
||||
bool paused_;
|
||||
bool terminated_;
|
||||
|
||||
void run();
|
||||
|
||||
public:
|
||||
|
||||
XineFader(XineEngine *engine, xine_t *xine, xine_stream_t *stream, xine_audio_port_t *audioport, xine_post_t *post, uint fadeMs);
|
||||
~XineFader();
|
||||
|
||||
void pause();
|
||||
void resume();
|
||||
void finish();
|
||||
|
||||
};
|
||||
|
||||
class XineOutFader : public QThread {
|
||||
|
||||
private:
|
||||
|
||||
XineEngine *engine_;
|
||||
bool terminated_;
|
||||
uint fade_length_;
|
||||
|
||||
void run();
|
||||
|
||||
public:
|
||||
XineOutFader(XineEngine *, uint fadeLengthMs );
|
||||
~XineOutFader();
|
||||
|
||||
void finish();
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user