Crossfading in gstreamer backend

This commit is contained in:
David Sansome 2010-04-11 23:03:39 +00:00
parent c576ca92e8
commit 23880b3cb5
18 changed files with 269 additions and 170 deletions

View File

@ -22,6 +22,8 @@
#include <cmath>
#include <QSettings>
const char* Engine::Base::kSettingsGroup = "Player";
Engine::Base::Base()
@ -64,3 +66,12 @@ Engine::Base::makeVolumeLogarithmic( uint volume ) // static
// We're using a logarithmic function to make the volume ramp more natural.
return static_cast<uint>( 100 - 100.0 * std::log10( ( 100 - volume ) * 0.09 + 1.0 ) );
}
void Engine::Base::ReloadSettings() {
QSettings s;
s.beginGroup(kSettingsGroup);
fadeout_enabled_ = s.value("FadeoutEnabled", true).toBool();
fadeout_duration_ = s.value("FadeoutDuration", 2000).toInt();
crossfade_enabled_ = s.value("CrossfadeEnabled", true).toBool();
}

View File

@ -239,12 +239,10 @@ namespace Engine
/** allow the engine to perform necessary work on changes in the playlist **/
virtual void playlistChanged() { };
virtual void reloadSettings() {};
static const char* kSettingsGroup;
public slots:
virtual void ReloadSettings() {}
virtual void ReloadSettings();
/** Set whether equalizer is enabled
* You don't need to cache the parameters, setEqualizerParameters is called straight after this
@ -282,6 +280,10 @@ namespace Engine
QUrl m_url;
Scope m_scope;
bool m_isStream;
bool fadeout_enabled_;
int fadeout_duration_;
bool crossfade_enabled_;
};

View File

@ -96,13 +96,13 @@ bool GstEngine::init() {
}
void GstEngine::ReloadSettings() {
Engine::Base::ReloadSettings();
QSettings s;
s.beginGroup(kSettingsGroup);
sink_ = s.value("sink", kAutoSink).toString();
device_ = s.value("device").toString();
fadeout_enabled_ = s.value("FadeoutEnabled", true).toBool();
fadeout_duration_ = s.value("FadeoutDuration", 2000).toInt();
}
@ -289,18 +289,39 @@ void GstEngine::UpdateScope() {
bool GstEngine::load(const QUrl& url, bool stream) {
Engine::Base::load( url, stream );
bool crossfade = current_pipeline_ && crossfade_enabled_ && m_xfadeNextTrack;
shared_ptr<GstEnginePipeline> pipeline(CreatePipeline(url));
if (!pipeline)
return false;
if (crossfade)
StartFadeout();
current_pipeline_ = pipeline;
setVolume(m_volume);
setEqualizerEnabled(equalizer_enabled_);
setEqualizerParameters(equalizer_preamp_, equalizer_gains_);
// Maybe fade in this track
if (crossfade) {
current_pipeline_->StartFader(fadeout_duration_, QTimeLine::Forward);
m_xfadeNextTrack = false;
}
return true;
}
void GstEngine::StartFadeout() {
fadeout_pipeline_ = current_pipeline_;
disconnect(fadeout_pipeline_.get(), 0, 0, 0);
ClearScopeQ();
fadeout_pipeline_->StartFader(fadeout_duration_, QTimeLine::Backward);
connect(fadeout_pipeline_.get(), SIGNAL(FaderFinished()), SLOT(FadeoutFinished()));
}
bool GstEngine::play( uint offset ) {
// Try to play input pipeline; if fails, destroy input bin
@ -310,9 +331,6 @@ bool GstEngine::play( uint offset ) {
return false;
}
// Stop any active fadeout
fadeout_pipeline_.reset();
// If "Resume playback on start" is enabled, we must seek to the last position
if (offset) seek(offset);
@ -326,18 +344,8 @@ bool GstEngine::play( uint offset ) {
void GstEngine::stop() {
m_url = QUrl(); // To ensure we return Empty from state()
if (fadeout_enabled_) {
fadeout_pipeline_ = current_pipeline_;
disconnect(fadeout_pipeline_.get(), 0, 0, 0);
ClearScopeQ();
QTimeLine* fadeout = new QTimeLine(fadeout_duration_, this);
connect(fadeout, SIGNAL(valueChanged(qreal)), fadeout_pipeline_.get(), SLOT(SetVolumeModifier(qreal)));
connect(fadeout, SIGNAL(finished()), SLOT(FadeoutFinished()));
connect(fadeout_pipeline_.get(), SIGNAL(destroyed()), fadeout, SLOT(deleteLater()));
fadeout->setDirection(QTimeLine::Backward);
fadeout->start();
}
if (fadeout_enabled_)
StartFadeout();
current_pipeline_.reset();
emit stateChanged(Engine::Empty);

View File

@ -119,6 +119,8 @@ class GstEngine : public Engine::Base {
/** Beams the streaming buffer status to Amarok */
void SendBufferStatus();
void StartFadeout();
/////////////////////////////////////////////////////////////////////////////////////
// DATA MEMBERS
/////////////////////////////////////////////////////////////////////////////////////
@ -128,9 +130,6 @@ class GstEngine : public Engine::Base {
QString sink_;
QString device_;
bool fadeout_enabled_;
int fadeout_duration_;
boost::shared_ptr<GstEnginePipeline> current_pipeline_;
boost::shared_ptr<GstEnginePipeline> fadeout_pipeline_;

View File

@ -26,6 +26,7 @@ GstEnginePipeline::GstEnginePipeline()
sink_(GstEngine::kAutoSink),
volume_percent_(100),
volume_modifier_(1.0),
fader_(NULL),
pipeline_(NULL),
src_(NULL),
decodebin_(NULL),
@ -308,3 +309,18 @@ void GstEnginePipeline::UpdateVolume() {
float vol = double(volume_percent_) * 0.01 * volume_modifier_;
g_object_set(G_OBJECT(volume_), "volume", vol, NULL);
}
void GstEnginePipeline::StartFader(int duration_msec,
QTimeLine::Direction direction,
QTimeLine::CurveShape shape) {
delete fader_;
fader_ = new QTimeLine(duration_msec, this);
connect(fader_, SIGNAL(valueChanged(qreal)), SLOT(SetVolumeModifier(qreal)));
connect(fader_, SIGNAL(finished()), SIGNAL(FaderFinished()));
fader_->setDirection(direction);
fader_->setCurveShape(shape);
fader_->start();
SetVolumeModifier(fader_->currentValue());
}

View File

@ -19,6 +19,7 @@
#include <QObject>
#include <QUrl>
#include <QTimeLine>
#include <gst/gst.h>
@ -46,6 +47,9 @@ class GstEnginePipeline : public QObject {
void SetEqualizerEnabled(bool enabled);
void SetEqualizerParams(int preamp, const QList<int>& band_gains);
void SetVolume(int percent);
void StartFader(int duration_msec,
QTimeLine::Direction direction = QTimeLine::Forward,
QTimeLine::CurveShape shape = QTimeLine::LinearCurve);
// Get information about the music playback
bool is_valid() const { return valid_; }
@ -61,6 +65,7 @@ class GstEnginePipeline : public QObject {
void MetadataFound(const Engine::SimpleMetaBundle& bundle);
void BufferFound(GstBuffer* buf);
void Error(const QString& message);
void FaderFinished();
private:
// Static callbacks. The GstEnginePipeline instance is passed in the last
@ -84,6 +89,8 @@ class GstEnginePipeline : public QObject {
int volume_percent_;
qreal volume_modifier_;
QTimeLine* fader_;
GstElement* pipeline_;
// Bins

View File

@ -89,7 +89,7 @@ void Player::Init() {
}
void Player::ReloadSettings() {
engine_->reloadSettings();
engine_->ReloadSettings();
}
void Player::Next() {
@ -109,6 +109,7 @@ void Player::NextItem() {
return;
}
engine_->setXFadeNextTrack(true);
PlayAt(i, false);
}

View File

@ -37,6 +37,8 @@ SettingsDialog::SettingsDialog(QWidget* parent)
QImage(":nocover.png"));
// Playback
connect(ui_.fading_cross, SIGNAL(toggled(bool)), SLOT(FadingOptionsChanged()));
connect(ui_.fading_out, SIGNAL(toggled(bool)), SLOT(FadingOptionsChanged()));
connect(ui_.gst_plugin, SIGNAL(currentIndexChanged(int)), SLOT(GstPluginChanged(int)));
// Behaviour
@ -113,8 +115,9 @@ void SettingsDialog::accept() {
// Playback
s.beginGroup(Engine::Base::kSettingsGroup);
s.setValue("FadeoutEnabled", ui_.fadeout->isChecked());
s.setValue("FadeoutDuration", ui_.fadeout_duration->value());
s.setValue("FadeoutEnabled", ui_.fading_out->isChecked());
s.setValue("FadeoutDuration", ui_.fading_duration->value());
s.setValue("CrossfadeEnabled", ui_.fading_cross->isChecked());
s.endGroup();
s.beginGroup(GstEngine::kSettingsGroup);
@ -170,11 +173,9 @@ void SettingsDialog::showEvent(QShowEvent*) {
// Playback
s.beginGroup(Engine::Base::kSettingsGroup);
if (s.value("FadeoutEnabled", true).toBool())
ui_.fadeout->setChecked(true);
else
ui_.no_fadeout->setChecked(true);
ui_.fadeout_duration->setValue(s.value("FadeoutDuration", 2000).toInt());
ui_.fading_out->setChecked(s.value("FadeoutEnabled", true).toBool());
ui_.fading_cross->setChecked(s.value("CrossfadeEnabled", true).toBool());
ui_.fading_duration->setValue(s.value("FadeoutDuration", 2000).toInt());
s.endGroup();
s.beginGroup(GstEngine::kSettingsGroup);
@ -325,3 +326,8 @@ void SettingsDialog::GstPluginChanged(int index) {
ui_.gst_device->setEnabled(enabled);
ui_.gst_device_label->setEnabled(enabled);
}
void SettingsDialog::FadingOptionsChanged() {
ui_.fading_options->setEnabled(
ui_.fading_out->isChecked() || ui_.fading_cross->isChecked());
}

View File

@ -53,10 +53,9 @@ class SettingsDialog : public QDialog {
void ChooseFgColor();
void UpdatePopupVisible();
void ShowTrayIconToggled(bool on);
void GstPluginChanged(int index);
void FadingOptionsChanged();
private:
Ui::SettingsDialog ui_;

View File

@ -51,7 +51,7 @@
<string>Playback</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../data/data.qrc">
<normaloff>:/media-playback-start-32.png</normaloff>:/media-playback-start-32.png</iconset>
</property>
</item>
@ -60,7 +60,7 @@
<string>Behaviour</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../data/data.qrc">
<normaloff>:/icon.png</normaloff>:/icon.png</iconset>
</property>
</item>
@ -69,7 +69,7 @@
<string>Notifications</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../data/data.qrc">
<normaloff>:/lightbulb.png</normaloff>:/lightbulb.png</iconset>
</property>
</item>
@ -78,7 +78,7 @@
<string>Music Library</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../data/data.qrc">
<normaloff>:/library.png</normaloff>:/library.png</iconset>
</property>
</item>
@ -87,7 +87,7 @@
<string>Last.fm</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../data/data.qrc">
<normaloff>:/last.fm/as.png</normaloff>:/last.fm/as.png</iconset>
</property>
</item>
@ -118,71 +118,76 @@
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Fadeout</string>
<string>Fading</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="no_fadeout">
<widget class="QCheckBox" name="fading_out">
<property name="text">
<string>No fadeout</string>
<string>Fade out when stopping a track</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="fadeout">
<widget class="QCheckBox" name="fading_cross">
<property name="text">
<string>Fadeout</string>
<string>Cross-fade between tracks</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Fadeout duration</string>
</property>
<property name="indent">
<number>22</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="fadeout_duration">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
<property name="value">
<number>2000</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<widget class="QWidget" name="fading_options" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Fading duration</string>
</property>
<property name="indent">
<number>22</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="fading_duration">
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
<property name="value">
<number>2000</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>257</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
@ -556,9 +561,15 @@
</customwidgets>
<tabstops>
<tabstop>list</tabstop>
<tabstop>no_fadeout</tabstop>
<tabstop>fadeout</tabstop>
<tabstop>fadeout_duration</tabstop>
<tabstop>fading_out</tabstop>
<tabstop>fading_cross</tabstop>
<tabstop>fading_duration</tabstop>
<tabstop>gst_plugin</tabstop>
<tabstop>gst_device</tabstop>
<tabstop>b_show_tray_icon_</tabstop>
<tabstop>b_always_show_</tabstop>
<tabstop>b_always_hide_</tabstop>
<tabstop>b_remember_</tabstop>
<tabstop>notifications_none</tabstop>
<tabstop>notifications_native</tabstop>
<tabstop>notifications_pretty</tabstop>
@ -571,7 +582,9 @@
<tabstop>notifications_fg_choose</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<resources>
<include location="../data/data.qrc"/>
</resources>
<connections>
<connection>
<sender>list</sender>
@ -589,38 +602,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>fadeout</sender>
<signal>toggled(bool)</signal>
<receiver>fadeout_duration</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>272</x>
<y>108</y>
</hint>
<hint type="destinationlabel">
<x>369</x>
<y>132</y>
</hint>
</hints>
</connection>
<connection>
<sender>fadeout</sender>
<signal>toggled(bool)</signal>
<receiver>label</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>108</y>
</hint>
<hint type="destinationlabel">
<x>264</x>
<y>131</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>

View File

@ -709,13 +709,17 @@ msgstr "Knihovna hudby"
msgid "Last.fm"
msgstr "Last.fm"
msgid "Fadeout"
msgstr "Zeslabování"
msgid "Fading"
msgstr ""
msgid "No fadeout"
msgstr "Žádné zeslabování"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Délka zeslabování"
msgid " ms"
@ -903,6 +907,12 @@ msgstr ""
msgid "Enable equalizer"
msgstr ""
#~ msgid "Fadeout"
#~ msgstr "Zeslabování"
#~ msgid "No fadeout"
#~ msgstr "Žádné zeslabování"
#, fuzzy
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/"

View File

@ -712,13 +712,17 @@ msgstr "Μουσική βιβλιοθήκη"
msgid "Last.fm"
msgstr "Last.fm"
msgid "Fadeout"
msgstr "Ομαλό σβήσιμο"
msgid "Fading"
msgstr ""
msgid "No fadeout"
msgstr "Χωρίς ομαλό σβήσιμο"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Διάρκεια σβησίματος"
msgid " ms"
@ -902,3 +906,9 @@ msgstr "Προκαθορισμένα:"
msgid "Enable equalizer"
msgstr "Ενεργοποίηση του ισοσταθμιστή"
#~ msgid "Fadeout"
#~ msgstr "Ομαλό σβήσιμο"
#~ msgid "No fadeout"
#~ msgstr "Χωρίς ομαλό σβήσιμο"

View File

@ -715,13 +715,18 @@ msgstr "Colección de Música"
msgid "Last.fm"
msgstr "Last.fm"
msgid "Fadeout"
msgstr "Fundido"
#, fuzzy
msgid "Fading"
msgstr "Cuidado"
msgid "No fadeout"
msgstr "Sin fundido"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Duración del fundido"
msgid " ms"
@ -912,6 +917,12 @@ msgstr ""
msgid "Enable equalizer"
msgstr ""
#~ msgid "Fadeout"
#~ msgstr "Fundido"
#~ msgid "No fadeout"
#~ msgstr "Sin fundido"
#, fuzzy
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/"
@ -1074,9 +1085,6 @@ msgstr ""
#~ msgid "Default key:"
#~ msgstr "Acceso por defecto:"
#~ msgid "Warning"
#~ msgstr "Cuidado"
#~ msgid ""
#~ "You are about to reset to global shortcuts default values. Are you sure "
#~ "you want to continue?"

View File

@ -713,13 +713,17 @@ msgstr "Bibliothèque musicale"
msgid "Last.fm"
msgstr "Last.fm"
msgid "Fadeout"
msgstr "Fondu final"
msgid "Fading"
msgstr ""
msgid "No fadeout"
msgstr "Pas de fondu final"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Durée du fondu final"
msgid " ms"
@ -908,6 +912,12 @@ msgstr ""
msgid "Enable equalizer"
msgstr ""
#~ msgid "Fadeout"
#~ msgstr "Fondu final"
#~ msgid "No fadeout"
#~ msgstr "Pas de fondu final"
#, fuzzy
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/"

View File

@ -705,13 +705,17 @@ msgstr "Biblioteka muzyki"
msgid "Last.fm"
msgstr "Last.fm"
msgid "Fadeout"
msgstr "Zanikanie"
msgid "Fading"
msgstr ""
msgid "No fadeout"
msgstr "Bez zanikania"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Czas zanikania"
msgid " ms"
@ -900,6 +904,12 @@ msgstr ""
msgid "Enable equalizer"
msgstr ""
#~ msgid "Fadeout"
#~ msgstr "Zanikanie"
#~ msgid "No fadeout"
#~ msgstr "Bez zanikania"
#, fuzzy
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/"

View File

@ -706,13 +706,17 @@ msgstr "Музыкальная коллекция"
msgid "Last.fm"
msgstr "Last.fm"
msgid "Fadeout"
msgstr "Затихание"
msgid "Fading"
msgstr ""
msgid "No fadeout"
msgstr "Отключить"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Длительность затихания"
msgid " ms"
@ -899,6 +903,12 @@ msgstr ""
msgid "Enable equalizer"
msgstr ""
#~ msgid "Fadeout"
#~ msgstr "Затихание"
#~ msgid "No fadeout"
#~ msgstr "Отключить"
#, fuzzy
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/"

View File

@ -710,13 +710,18 @@ msgstr "Hudobná zbierka"
msgid "Last.fm"
msgstr ""
msgid "Fadeout"
msgstr "Zoslabovanie"
#, fuzzy
msgid "Fading"
msgstr "Varovanie"
msgid "No fadeout"
msgstr "Bez zoslabovania"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
#, fuzzy
msgid "Fading duration"
msgstr "Trvanie zoslabovania"
msgid " ms"
@ -905,6 +910,12 @@ msgstr ""
msgid "Enable equalizer"
msgstr ""
#~ msgid "Fadeout"
#~ msgstr "Zoslabovanie"
#~ msgid "No fadeout"
#~ msgstr "Bez zoslabovania"
#, fuzzy
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/"
@ -1064,9 +1075,6 @@ msgstr ""
#~ msgid "Default key:"
#~ msgstr "Pôvodný kľúč"
#~ msgid "Warning"
#~ msgstr "Varovanie"
#~ msgid ""
#~ "You are about to reset to global shortcuts default values. Are you sure "
#~ "you want to continue?"

View File

@ -699,13 +699,16 @@ msgstr ""
msgid "Last.fm"
msgstr ""
msgid "Fadeout"
msgid "Fading"
msgstr ""
msgid "No fadeout"
msgid "Fade out when stopping a track"
msgstr ""
msgid "Fadeout duration"
msgid "Cross-fade between tracks"
msgstr ""
msgid "Fading duration"
msgstr ""
msgid " ms"