diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index abba83203..93dde211a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,10 +58,10 @@ set(SOURCES utilities/coverutils.cpp utilities/screenutils.cpp - engine/enginetype.cpp engine/enginebase.cpp engine/devicefinders.cpp engine/devicefinder.cpp + engine/enginemetadata.cpp analyzer/fht.cpp analyzer/analyzerbase.cpp diff --git a/src/analyzer/analyzerbase.cpp b/src/analyzer/analyzerbase.cpp index e89f76d03..b0f528015 100644 --- a/src/analyzer/analyzerbase.cpp +++ b/src/analyzer/analyzerbase.cpp @@ -108,8 +108,8 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) { p.fillRect(e->rect(), palette().color(QPalette::Window)); switch (engine_->state()) { - case Engine::State::Playing: { - const Engine::Scope &thescope = engine_->scope(timeout_); + case EngineBase::State::Playing: { + const EngineBase::Scope &thescope = engine_->scope(timeout_); int i = 0; // convert to mono here - our built in analyzers need mono, but the engines provide interleaved pcm @@ -126,7 +126,7 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) { break; } - case Engine::State::Paused: + case EngineBase::State::Paused: is_playing_ = false; analyze(p, lastscope_, new_frame_); break; diff --git a/src/analyzer/analyzerbase.h b/src/analyzer/analyzerbase.h index 79739b4e7..d188aa6dc 100644 --- a/src/analyzer/analyzerbase.h +++ b/src/analyzer/analyzerbase.h @@ -39,7 +39,6 @@ #include #include "analyzer/fht.h" -#include "engine/engine_fwd.h" #include "engine/enginebase.h" class QHideEvent; diff --git a/src/analyzer/analyzercontainer.cpp b/src/analyzer/analyzercontainer.cpp index 592eb2ebc..2fce0ed7b 100644 --- a/src/analyzer/analyzercontainer.cpp +++ b/src/analyzer/analyzercontainer.cpp @@ -44,7 +44,6 @@ #include "core/logging.h" #include "engine/enginebase.h" -#include "engine/enginetype.h" using namespace std::chrono_literals; @@ -104,7 +103,7 @@ AnalyzerContainer::AnalyzerContainer(QWidget *parent) void AnalyzerContainer::mouseReleaseEvent(QMouseEvent *e) { - if (engine_->type() != Engine::EngineType::GStreamer) { + if (engine_->type() != EngineBase::Type::GStreamer) { return; } diff --git a/src/analyzer/analyzercontainer.h b/src/analyzer/analyzercontainer.h index fa919add2..1caa59258 100644 --- a/src/analyzer/analyzercontainer.h +++ b/src/analyzer/analyzercontainer.h @@ -30,7 +30,7 @@ #include #include -#include "engine/engine_fwd.h" +#include "engine/enginebase.h" class QTimer; class QMouseEvent; diff --git a/src/analyzer/boomanalyzer.cpp b/src/analyzer/boomanalyzer.cpp index f7e2abca0..97e80c764 100644 --- a/src/analyzer/boomanalyzer.cpp +++ b/src/analyzer/boomanalyzer.cpp @@ -32,7 +32,6 @@ #include #include -#include "engine/engine_fwd.h" #include "engine/enginebase.h" #include "fht.h" #include "analyzerbase.h" @@ -110,7 +109,7 @@ void BoomAnalyzer::transform(Scope &s) { void BoomAnalyzer::analyze(QPainter &p, const Scope &scope, const bool new_frame) { - if (!new_frame || engine_->state() == Engine::State::Paused) { + if (!new_frame || engine_->state() == EngineBase::State::Paused) { p.drawPixmap(0, 0, canvas_); return; } diff --git a/src/analyzer/sonogram.cpp b/src/analyzer/sonogram.cpp index e3582ed2e..1112743ea 100644 --- a/src/analyzer/sonogram.cpp +++ b/src/analyzer/sonogram.cpp @@ -24,6 +24,8 @@ #include #include +#include "engine/enginebase.h" + #include "sonogram.h" const char *Sonogram::kName = QT_TRANSLATE_NOOP("AnalyzerContainer", "Sonogram"); @@ -42,7 +44,7 @@ void Sonogram::resizeEvent(QResizeEvent *e) { void Sonogram::analyze(QPainter &p, const Analyzer::Scope &s, bool new_frame) { - if (!new_frame || engine_->state() == Engine::State::Paused) { + if (!new_frame || engine_->state() == EngineBase::State::Paused) { p.drawPixmap(0, 0, canvas_); return; } diff --git a/src/context/contextview.cpp b/src/context/contextview.cpp index 782756c70..236fb070d 100644 --- a/src/context/contextview.cpp +++ b/src/context/contextview.cpp @@ -55,9 +55,7 @@ #include "utilities/strutils.h" #include "utilities/timeutils.h" #include "widgets/resizabletextedit.h" -#include "engine/engine_fwd.h" #include "engine/enginebase.h" -#include "engine/enginetype.h" #include "engine/devicefinders.h" #include "engine/devicefinder.h" #include "collection/collectionbackend.h" @@ -544,12 +542,12 @@ void ContextView::SetSong() { if (action_show_output_->isChecked()) { widget_play_output_->show(); - Engine::EngineType enginetype(Engine::EngineType::None); + EngineBase::Type enginetype = EngineBase::Type::None; if (app_->player()->engine()) enginetype = app_->player()->engine()->type(); - QIcon icon_engine = IconLoader::Load(EngineName(enginetype), true, 32); + QIcon icon_engine = IconLoader::Load(EngineBase::Name(enginetype), true, 32); label_engine_icon_->setPixmap(icon_engine.pixmap(QSize(32, 32))); - label_engine_->setText(EngineDescription(enginetype)); + label_engine_->setText(EngineBase::Description(enginetype)); spacer_play_output_->changeSize(20, 20, QSizePolicy::Fixed); DeviceFinder::Device device; diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 56ff8dd89..7306955d2 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -103,9 +103,7 @@ #include "utilities/filemanagerutils.h" #include "utilities/timeconstants.h" #include "utilities/screenutils.h" -#include "engine/enginetype.h" #include "engine/enginebase.h" -#include "engine/engine_fwd.h" #include "dialogs/errordialog.h" #include "dialogs/about.h" #include "dialogs/console.h" @@ -1246,7 +1244,7 @@ void MainWindow::Exit() { if (app_->player()->engine()->is_fadeout_enabled()) { // To shut down the application when fadeout will be finished QObject::connect(app_->player()->engine(), &EngineBase::FadeoutFinishedSignal, this, &MainWindow::DoExit); - if (app_->player()->GetState() == Engine::State::Playing) { + if (app_->player()->GetState() == EngineBase::State::Playing) { app_->player()->Stop(); ignore_close_ = true; close(); @@ -1275,11 +1273,11 @@ void MainWindow::ExitFinished() { } -void MainWindow::EngineChanged(Engine::EngineType enginetype) { +void MainWindow::EngineChanged(const EngineBase::Type enginetype) { - ui_->action_equalizer->setEnabled(enginetype == Engine::EngineType::GStreamer); + ui_->action_equalizer->setEnabled(enginetype == EngineBase::Type::GStreamer); #if defined(HAVE_AUDIOCD) && !defined(Q_OS_WIN) - ui_->action_open_cd->setEnabled(enginetype == Engine::EngineType::GStreamer); + ui_->action_open_cd->setEnabled(enginetype == EngineBase::Type::GStreamer); #else ui_->action_open_cd->setEnabled(false); ui_->action_open_cd->setVisible(false); @@ -1460,7 +1458,7 @@ void MainWindow::SavePlaybackStatus() { s.beginGroup(Player::kSettingsGroup); s.setValue("playback_state", static_cast(app_->player()->GetState())); - if (app_->player()->GetState() == Engine::State::Playing || app_->player()->GetState() == Engine::State::Paused) { + if (app_->player()->GetState() == EngineBase::State::Playing || app_->player()->GetState() == EngineBase::State::Paused) { s.setValue("playback_playlist", app_->playlist_manager()->active()->id()); s.setValue("playback_position", app_->player()->engine()->position_nanosec() / kNsecPerSec); } @@ -1482,10 +1480,10 @@ void MainWindow::LoadPlaybackStatus() { s.endGroup(); s.beginGroup(Player::kSettingsGroup); - const Engine::State playback_state = static_cast(s.value("playback_state", static_cast(Engine::State::Empty)).toInt()); + const EngineBase::State playback_state = static_cast(s.value("playback_state", static_cast(EngineBase::State::Empty)).toInt()); s.endGroup(); - if (resume_playback && playback_state != Engine::State::Empty && playback_state != Engine::State::Idle) { + if (resume_playback && playback_state != EngineBase::State::Empty && playback_state != EngineBase::State::Idle) { std::shared_ptr connection = std::make_shared(); *connection = QObject::connect(app_->playlist_manager(), &PlaylistManager::AllPlaylistsLoaded, this, [this, connection]() { QObject::disconnect(*connection); @@ -1501,7 +1499,7 @@ void MainWindow::ResumePlayback() { QSettings s; s.beginGroup(Player::kSettingsGroup); - const Engine::State playback_state = static_cast(s.value("playback_state", static_cast(Engine::State::Empty)).toInt()); + const EngineBase::State playback_state = static_cast(s.value("playback_state", static_cast(EngineBase::State::Empty)).toInt()); int playback_playlist = s.value("playback_playlist", -1).toInt(); int playback_position = s.value("playback_position", 0).toInt(); s.endGroup(); @@ -1509,7 +1507,7 @@ void MainWindow::ResumePlayback() { if (playback_playlist == app_->playlist_manager()->current()->id()) { // Set active to current to resume playback on correct playlist. app_->playlist_manager()->SetActiveToCurrent(); - if (playback_state == Engine::State::Paused) { + if (playback_state == EngineBase::State::Paused) { std::shared_ptr connection = std::make_shared(); *connection = QObject::connect(app_->player(), &Player::Playing, app_->player(), [this, connection]() { QObject::disconnect(*connection); @@ -1521,7 +1519,7 @@ void MainWindow::ResumePlayback() { // Reset saved playback status so we don't resume again from the same position. s.beginGroup(Player::kSettingsGroup); - s.setValue("playback_state", static_cast(Engine::State::Empty)); + s.setValue("playback_state", static_cast(EngineBase::State::Empty)); s.setValue("playback_playlist", -1); s.setValue("playback_position", 0); s.endGroup(); @@ -1539,7 +1537,7 @@ void MainWindow::PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscro } app_->playlist_manager()->SetActiveToCurrent(); - app_->player()->PlayAt(row, 0, Engine::TrackChangeType::Manual, autoscroll, true); + app_->player()->PlayAt(row, 0, EngineBase::TrackChangeType::Manual, autoscroll, true); } @@ -1556,14 +1554,14 @@ void MainWindow::PlaylistDoubleClick(const QModelIndex &idx) { switch (doubleclick_playlist_addmode_) { case BehaviourSettingsPage::PlaylistAddBehaviour::Play: app_->playlist_manager()->SetActiveToCurrent(); - app_->player()->PlayAt(source_idx.row(), 0, Engine::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true); + app_->player()->PlayAt(source_idx.row(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true); break; case BehaviourSettingsPage::PlaylistAddBehaviour::Enqueue: app_->playlist_manager()->current()->queue()->ToggleTracks(QModelIndexList() << source_idx); - if (app_->player()->GetState() != Engine::State::Playing) { + if (app_->player()->GetState() != EngineBase::State::Playing) { app_->playlist_manager()->SetActiveToCurrent(); - app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), 0, Engine::TrackChangeType::Manual, Playlist::AutoScroll::Never, true); + app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true); } break; } @@ -1749,7 +1747,7 @@ void MainWindow::ApplyPlayBehaviour(const BehaviourSettingsPage::PlayBehaviour b break; case BehaviourSettingsPage::PlayBehaviour::IfStopped: - mimedata->play_now_ = !(app_->player()->GetState() == Engine::State::Playing); + mimedata->play_now_ = !(app_->player()->GetState() == EngineBase::State::Playing); break; } } @@ -1835,7 +1833,7 @@ void MainWindow::PlaylistRightClick(const QPoint global_pos, const QModelIndex & playlist_menu_index_ = source_index; // Is this song currently playing? - if (app_->playlist_manager()->current()->current_row() == source_index.row() && app_->player()->GetState() == Engine::State::Playing) { + if (app_->playlist_manager()->current()->current_row() == source_index.row() && app_->player()->GetState() == EngineBase::State::Playing) { playlist_play_pause_->setText(tr("Pause")); playlist_play_pause_->setIcon(IconLoader::Load("media-playback-pause")); } @@ -2480,7 +2478,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) { app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + options.seek_by()); } - if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), 0, Engine::TrackChangeType::Manual, Playlist::AutoScroll::Maybe, true); + if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Maybe, true); if (options.show_osd()) app_->player()->ShowOSD(); @@ -3189,13 +3187,13 @@ void MainWindow::PlaylistDelete() { if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return; - if (app_->player()->GetState() == Engine::State::Playing && app_->playlist_manager()->current()->rowCount() == selected_songs.count()) { + if (app_->player()->GetState() == EngineBase::State::Playing && app_->playlist_manager()->current()->rowCount() == selected_songs.count()) { app_->player()->Stop(); } ui_->playlist->view()->RemoveSelected(); - if (app_->player()->GetState() == Engine::State::Playing && is_current_item) { + if (app_->player()->GetState() == EngineBase::State::Playing && is_current_item) { app_->player()->Next(); } diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h index 377244386..a1fb0e14f 100644 --- a/src/core/mainwindow.h +++ b/src/core/mainwindow.h @@ -52,8 +52,7 @@ #include "platforminterface.h" #include "song.h" #include "tagreaderclient.h" -#include "engine/enginetype.h" -#include "engine/engine_fwd.h" +#include "engine/enginebase.h" #include "osd/osdbase.h" #include "collection/collectionmodel.h" #include "playlist/playlist.h" @@ -142,7 +141,7 @@ class MainWindow : public QMainWindow, public PlatformInterface { private slots: void FilePathChanged(const QString &path); - void EngineChanged(Engine::EngineType enginetype); + void EngineChanged(const EngineBase::Type enginetype); void MediaStopped(); void MediaPaused(); void MediaPlaying(); diff --git a/src/core/metatypes.cpp b/src/core/metatypes.cpp index 336fb7732..eb265c26d 100644 --- a/src/core/metatypes.cpp +++ b/src/core/metatypes.cpp @@ -47,9 +47,8 @@ #include "song.h" -#include "engine/engine_fwd.h" #include "engine/enginebase.h" -#include "engine/enginetype.h" +#include "engine/enginemetadata.h" #ifdef HAVE_GSTREAMER # include "engine/gstenginepipeline.h" #endif @@ -103,11 +102,11 @@ void RegisterMetaTypes() { qRegisterMetaType("SongMap"); qRegisterMetaType("Song::Source"); qRegisterMetaType("Song::FileType"); - qRegisterMetaType("Engine::EngineType"); - qRegisterMetaType("Engine::SimpleMetaBundle"); - qRegisterMetaType("Engine::State"); - qRegisterMetaType("Engine::TrackChangeFlags"); + qRegisterMetaType("EngineBase::Type"); + qRegisterMetaType("EngineBase::State"); + qRegisterMetaType("EngineBase::TrackChangeFlags"); qRegisterMetaType("EngineBase::OutputDetails"); + qRegisterMetaType("EngineMetadata"); #ifdef HAVE_GSTREAMER qRegisterMetaType("GstBuffer*"); qRegisterMetaType("GstElement*"); diff --git a/src/core/mpris2.cpp b/src/core/mpris2.cpp index f744a6781..f0f2980f7 100644 --- a/src/core/mpris2.cpp +++ b/src/core/mpris2.cpp @@ -162,9 +162,9 @@ void Mpris2::PlaylistManagerInitialized() { QObject::connect(app_->playlist_manager()->sequence(), &PlaylistSequence::RepeatModeChanged, this, &Mpris2::RepeatModeChanged); } -void Mpris2::EngineStateChanged(Engine::State newState) { +void Mpris2::EngineStateChanged(EngineBase::State newState) { - if (newState != Engine::State::Playing && newState != Engine::State::Paused) { + if (newState != EngineBase::State::Playing && newState != EngineBase::State::Paused) { last_metadata_ = QVariantMap(); EmitNotification("Metadata"); } @@ -172,7 +172,7 @@ void Mpris2::EngineStateChanged(Engine::State newState) { EmitNotification("CanPlay"); EmitNotification("CanPause"); EmitNotification("PlaybackStatus", PlaybackStatus(newState)); - if (newState == Engine::State::Playing) EmitNotification("CanSeek", CanSeek(newState)); + if (newState == EngineBase::State::Playing) EmitNotification("CanSeek", CanSeek(newState)); } @@ -304,11 +304,11 @@ QString Mpris2::PlaybackStatus() const { return PlaybackStatus(app_->player()->GetState()); } -QString Mpris2::PlaybackStatus(Engine::State state) const { +QString Mpris2::PlaybackStatus(EngineBase::State state) const { switch (state) { - case Engine::State::Playing: return "Playing"; - case Engine::State::Paused: return "Paused"; + case EngineBase::State::Playing: return "Playing"; + case EngineBase::State::Paused: return "Paused"; default: return "Stopped"; } @@ -449,13 +449,13 @@ bool Mpris2::CanPlay() const { // This one's a bit different than MPRIS 1 - we want this to be true even when the song is already paused or stopped. bool Mpris2::CanPause() const { - return (app_->player()->GetCurrentItem() && app_->player()->GetState() == Engine::State::Playing && !(app_->player()->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused" || PlaybackStatus() == "Stopped"; + return (app_->player()->GetCurrentItem() && app_->player()->GetState() == EngineBase::State::Playing && !(app_->player()->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused" || PlaybackStatus() == "Stopped"; } bool Mpris2::CanSeek() const { return CanSeek(app_->player()->GetState()); } -bool Mpris2::CanSeek(Engine::State state) const { - return app_->player()->GetCurrentItem() && state != Engine::State::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream(); +bool Mpris2::CanSeek(EngineBase::State state) const { + return app_->player()->GetCurrentItem() && state != EngineBase::State::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream(); } bool Mpris2::CanControl() const { return true; } @@ -473,7 +473,7 @@ void Mpris2::Previous() { } void Mpris2::Pause() { - if (CanPause() && app_->player()->GetState() != Engine::State::Paused) { + if (CanPause() && app_->player()->GetState() != EngineBase::State::Paused) { app_->player()->Pause(); } } diff --git a/src/core/mpris2.h b/src/core/mpris2.h index 0434210ad..23555671f 100644 --- a/src/core/mpris2.h +++ b/src/core/mpris2.h @@ -38,7 +38,7 @@ #include #include -#include "engine/engine_fwd.h" +#include "engine/enginebase.h" #include "covermanager/albumcoverloaderresult.h" class Application; @@ -203,7 +203,7 @@ class Mpris2 : public QObject { private slots: void AlbumCoverLoaded(const Song &song, AlbumCoverLoaderResultPtr result = AlbumCoverLoaderResultPtr()); - void EngineStateChanged(Engine::State newState); + void EngineStateChanged(EngineBase::State newState); void VolumeChanged(); void PlaylistManagerInitialized(); @@ -218,11 +218,11 @@ class Mpris2 : public QObject { void EmitNotification(const QString &name, const QVariant &value); void EmitNotification(const QString &name, const QVariant &value, const QString &mprisEntity); - QString PlaybackStatus(Engine::State state) const; + QString PlaybackStatus(EngineBase::State state) const; QString current_track_id() const; - bool CanSeek(Engine::State state) const; + bool CanSeek(EngineBase::State state) const; QString DesktopEntryAbsolutePath() const; diff --git a/src/core/player.cpp b/src/core/player.cpp index 17fe90eda..30ddcb9a8 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -43,7 +43,7 @@ #include "application.h" #include "engine/enginebase.h" -#include "engine/enginetype.h" +#include "engine/enginemetadata.h" #ifdef HAVE_GSTREAMER # include "engine/gstengine.h" @@ -79,9 +79,9 @@ Player::Player(Application *app, QObject *parent) #endif analyzer_(nullptr), equalizer_(nullptr), - stream_change_type_(Engine::TrackChangeType::First), + stream_change_type_(EngineBase::TrackChangeType::First), autoscroll_(Playlist::AutoScroll::Maybe), - last_state_(Engine::State::Empty), + last_state_(EngineBase::State::Empty), nb_errors_received_(0), volume_(100), volume_before_mute_(100), @@ -94,23 +94,23 @@ Player::Player(Application *app, QObject *parent) QSettings s; s.beginGroup(BackendSettingsPage::kSettingsGroup); - Engine::EngineType enginetype = Engine::EngineTypeFromName(s.value("engine", EngineName(Engine::EngineType::GStreamer)).toString().toLower()); + EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); s.endGroup(); CreateEngine(enginetype); } -Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) { +EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) { - Engine::EngineType use_enginetype(Engine::EngineType::None); + EngineBase::Type use_enginetype = EngineBase::Type::None; - for (int i = 0; use_enginetype == Engine::EngineType::None; i++) { + for (int i = 0; use_enginetype == EngineBase::Type::None; i++) { switch (enginetype) { - case Engine::EngineType::None: + case EngineBase::Type::None: #ifdef HAVE_GSTREAMER - case Engine::EngineType::GStreamer:{ - use_enginetype=Engine::EngineType::GStreamer; + case EngineBase::Type::GStreamer:{ + use_enginetype=EngineBase::Type::GStreamer; std::unique_ptr gst_engine(new GstEngine(app_->task_manager())); gst_engine->SetStartup(gst_startup_); engine_.reset(gst_engine.release()); @@ -118,8 +118,8 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) { } #endif #ifdef HAVE_VLC - case Engine::EngineType::VLC: - use_enginetype = Engine::EngineType::VLC; + case EngineBase::Type::VLC: + use_enginetype = EngineBase::Type::VLC; engine_ = std::make_shared(app_->task_manager()); break; #endif @@ -127,7 +127,7 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) { if (i > 0) { qFatal("No engine available!"); } - enginetype = Engine::EngineType::None; + enginetype = EngineBase::Type::None; break; } } @@ -135,7 +135,7 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) { if (use_enginetype != enginetype) { // Engine was set to something else. Reset output and device. QSettings s; s.beginGroup(BackendSettingsPage::kSettingsGroup); - s.setValue("engine", EngineName(use_enginetype)); + s.setValue("engine", EngineBase::Name(use_enginetype)); s.setValue("output", engine_->DefaultOutput()); s.setValue("device", QVariant()); s.endGroup(); @@ -157,7 +157,7 @@ void Player::Init() { if (!engine_) { s.beginGroup(BackendSettingsPage::kSettingsGroup); - Engine::EngineType enginetype = Engine::EngineTypeFromName(s.value("engine", EngineName(Engine::EngineType::GStreamer)).toString().toLower()); + EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower()); s.endGroup(); CreateEngine(enginetype); } @@ -363,9 +363,9 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) { } -void Player::Next() { NextInternal(Engine::TrackChangeType::Manual, Playlist::AutoScroll::Always); } +void Player::Next() { NextInternal(EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Always); } -void Player::NextInternal(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) { +void Player::NextInternal(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) { pause_time_ = QDateTime(); play_offset_nanosec_ = 0; @@ -376,7 +376,7 @@ void Player::NextInternal(const Engine::TrackChangeFlags change, const Playlist: } -void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) { +void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) { pause_time_ = QDateTime(); play_offset_nanosec_ = 0; @@ -384,7 +384,7 @@ void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::Aut Playlist *active_playlist = app_->playlist_manager()->active(); // If we received too many errors in auto change, with repeat enabled, we stop - if (change == Engine::TrackChangeType::Auto) { + if (change == EngineBase::TrackChangeType::Auto) { const PlaylistSequence::RepeatMode repeat_mode = active_playlist->sequence()->repeat_mode(); if (repeat_mode != PlaylistSequence::RepeatMode::Off) { if ((repeat_mode == PlaylistSequence::RepeatMode::Track && nb_errors_received_ >= 3) || (nb_errors_received_ >= app_->playlist_manager()->active()->filter()->rowCount())) { @@ -397,7 +397,7 @@ void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::Aut } // Manual track changes override "Repeat track" - const bool ignore_repeat_track = change & Engine::TrackChangeType::Manual; + const bool ignore_repeat_track = change & EngineBase::TrackChangeType::Manual; int i = active_playlist->next_row(ignore_repeat_track); if (i == -1) { @@ -413,10 +413,10 @@ void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::Aut } void Player::PlayPlaylist(const QString &playlist_name) { - PlayPlaylistInternal(Engine::TrackChangeType::Manual, Playlist::AutoScroll::Always, playlist_name); + PlayPlaylistInternal(EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Always, playlist_name); } -void Player::PlayPlaylistInternal(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const QString &playlist_name) { +void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const QString &playlist_name) { pause_time_ = QDateTime(); play_offset_nanosec_ = 0; @@ -474,19 +474,19 @@ void Player::TrackEnded() { if (HandleStopAfter(Playlist::AutoScroll::Maybe)) return; - NextInternal(Engine::TrackChangeType::Auto, Playlist::AutoScroll::Maybe); + NextInternal(EngineBase::TrackChangeType::Auto, Playlist::AutoScroll::Maybe); } void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll autoscroll) { switch (engine_->state()) { - case Engine::State::Paused: + case EngineBase::State::Paused: UnPause(); emit Resumed(); break; - case Engine::State::Playing: { + case EngineBase::State::Playing: { if (current_item_->options() & PlaylistItem::Option::PauseDisabled) { Stop(); } @@ -498,9 +498,9 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll break; } - case Engine::State::Empty: - case Engine::State::Error: - case Engine::State::Idle: { + case EngineBase::State::Empty: + case EngineBase::State::Error: + case EngineBase::State::Idle: { pause_time_ = QDateTime(); play_offset_nanosec_ = offset_nanosec; app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id()); @@ -508,7 +508,7 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll int i = app_->playlist_manager()->active()->current_row(); if (i == -1) i = app_->playlist_manager()->active()->last_played_row(); if (i == -1) i = 0; - PlayAt(i, offset_nanosec, Engine::TrackChangeType::First, autoscroll, true); + PlayAt(i, offset_nanosec, EngineBase::TrackChangeType::First, autoscroll, true); break; } } @@ -572,14 +572,14 @@ bool Player::PreviousWouldRestartTrack() const { } -void Player::Previous() { PreviousItem(Engine::TrackChangeType::Manual); } +void Player::Previous() { PreviousItem(EngineBase::TrackChangeType::Manual); } -void Player::PreviousItem(const Engine::TrackChangeFlags change) { +void Player::PreviousItem(const EngineBase::TrackChangeFlags change) { pause_time_ = QDateTime(); play_offset_nanosec_ = 0; - const bool ignore_repeat_track = change & Engine::TrackChangeType::Manual; + const bool ignore_repeat_track = change & EngineBase::TrackChangeType::Manual; if (menu_previousmode_ == BehaviourSettingsPage::PreviousBehaviour::Restart) { // Check if it has been over two seconds since previous button was pressed @@ -604,9 +604,9 @@ void Player::PreviousItem(const Engine::TrackChangeFlags change) { } -void Player::EngineStateChanged(const Engine::State state) { +void Player::EngineStateChanged(const EngineBase::State state) { - if (state == Engine::State::Error) { + if (state == EngineBase::State::Error) { nb_errors_received_++; } else { @@ -614,21 +614,21 @@ void Player::EngineStateChanged(const Engine::State state) { } switch (state) { - case Engine::State::Paused: + case EngineBase::State::Paused: pause_time_ = QDateTime::currentDateTime(); play_offset_nanosec_ = engine_->position_nanosec(); emit Paused(); break; - case Engine::State::Playing: + case EngineBase::State::Playing: pause_time_ = QDateTime(); play_offset_nanosec_ = 0; emit Playing(); break; - case Engine::State::Error: + case EngineBase::State::Error: emit Error(); [[fallthrough]]; - case Engine::State::Empty: - case Engine::State::Idle: + case EngineBase::State::Empty: + case EngineBase::State::Idle: pause_time_ = QDateTime(); play_offset_nanosec_ = 0; emit Stopped(); @@ -695,17 +695,17 @@ void Player::VolumeDown() { } -void Player::PlayAt(const int index, const quint64 offset_nanosec, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform) { +void Player::PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform) { pause_time_ = QDateTime(); play_offset_nanosec_ = offset_nanosec; - if (current_item_ && change == Engine::TrackChangeType::Manual && engine_->position_nanosec() != engine_->length_nanosec()) { + if (current_item_ && change == EngineBase::TrackChangeType::Manual && engine_->position_nanosec() != engine_->length_nanosec()) { emit TrackSkipped(current_item_); } if (current_item_ && app_->playlist_manager()->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(app_->playlist_manager()->active()->item_at(index)->Metadata())) { - change |= Engine::TrackChangeType::SameAlbum; + change |= EngineBase::TrackChangeType::SameAlbum; } if (reshuffle) app_->playlist_manager()->active()->ReshuffleIndices(); @@ -774,25 +774,25 @@ void Player::SeekBackward() { SeekTo(engine()->position_nanosec() / kNsecPerSec - seek_step_sec_); } -void Player::EngineMetadataReceived(const Engine::SimpleMetaBundle &bundle) { +void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) { - if (bundle.type == Engine::SimpleMetaBundle::Type::Any || bundle.type == Engine::SimpleMetaBundle::Type::Current) { + if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Current) { PlaylistItemPtr item = app_->playlist_manager()->active()->current_item(); - if (item && bundle.media_url == item->Url()) { + if (item && engine_metadata.media_url == item->Url()) { Song song = item->Metadata(); - bool minor = song.MergeFromSimpleMetaBundle(bundle); + bool minor = song.MergeFromEngineMetadata(engine_metadata); app_->playlist_manager()->active()->SetStreamMetadata(item->Url(), song, minor); return; } } - if (bundle.type == Engine::SimpleMetaBundle::Type::Any || bundle.type == Engine::SimpleMetaBundle::Type::Next) { + if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Next) { int next_row = app_->playlist_manager()->active()->next_row(); if (next_row != -1) { PlaylistItemPtr next_item = app_->playlist_manager()->active()->item_at(next_row); - if (bundle.media_url == next_item->Url()) { + if (engine_metadata.media_url == next_item->Url()) { Song song = next_item->Metadata(); - song.MergeFromSimpleMetaBundle(bundle); + song.MergeFromEngineMetadata(engine_metadata); next_item->SetTemporaryMetadata(song); app_->playlist_manager()->active()->ItemChanged(next_row); } @@ -828,10 +828,10 @@ void Player::Pause() { engine_->Pause(); } void Player::Play(const quint64 offset_nanosec) { switch (GetState()) { - case Engine::State::Playing: + case EngineBase::State::Playing: SeekTo(offset_nanosec); break; - case Engine::State::Paused: + case EngineBase::State::Paused: UnPause(); break; default: @@ -929,7 +929,7 @@ void Player::InvalidSongRequested(const QUrl &url) { return; } - NextItem(Engine::TrackChangeType::Auto, Playlist::AutoScroll::Maybe); + NextItem(EngineBase::TrackChangeType::Auto, Playlist::AutoScroll::Maybe); } diff --git a/src/core/player.h b/src/core/player.h index f06ff6cb5..449ca31a5 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -34,8 +34,8 @@ #include #include "urlhandler.h" -#include "engine/engine_fwd.h" -#include "engine/enginetype.h" +#include "engine/enginebase.h" +#include "engine/enginemetadata.h" #include "playlist/playlist.h" #include "playlist/playlistitem.h" #include "settings/behavioursettingspage.h" @@ -48,10 +48,6 @@ class Equalizer; class GstStartup; #endif -namespace Engine { -struct SimpleMetaBundle; -} // namespace Engine - class PlayerInterface : public QObject { Q_OBJECT @@ -59,7 +55,7 @@ class PlayerInterface : public QObject { explicit PlayerInterface(QObject *parent = nullptr) : QObject(parent) {} virtual EngineBase *engine() const = 0; - virtual Engine::State GetState() const = 0; + virtual EngineBase::State GetState() const = 0; virtual uint GetVolume() const = 0; virtual PlaylistItemPtr GetCurrentItem() const = 0; @@ -74,7 +70,7 @@ class PlayerInterface : public QObject { virtual void SaveVolume() = 0; // Manual track change to the specified track - virtual void PlayAt(const int index, const quint64 offset_nanosec, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0; + virtual void PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0; // If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0; @@ -138,11 +134,11 @@ class Player : public PlayerInterface { static const char *kSettingsGroup; - Engine::EngineType CreateEngine(Engine::EngineType enginetype); + EngineBase::Type CreateEngine(EngineBase::Type Type); void Init(); EngineBase *engine() const override { return engine_.get(); } - Engine::State GetState() const override { return last_state_; } + EngineBase::State GetState() const override { return last_state_; } uint GetVolume() const override; PlaylistItemPtr GetCurrentItem() const override { return current_item_; } @@ -163,7 +159,7 @@ class Player : public PlayerInterface { void LoadVolume() override; void SaveVolume() override; - void PlayAt(const int index, const quint64 offset_nanosec, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) override; + void PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) override; void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) override; void PlayPauseHelper() override { PlayPause(play_offset_nanosec_); } void RestartOrPrevious() override; @@ -193,19 +189,19 @@ class Player : public PlayerInterface { void HandleAuthentication(); signals: - void EngineChanged(const Engine::EngineType enginetype); + void EngineChanged(const EngineBase::Type Type); private slots: - void EngineStateChanged(const Engine::State); - void EngineMetadataReceived(const Engine::SimpleMetaBundle &bundle); + void EngineStateChanged(const EngineBase::State); + void EngineMetadataReceived(const EngineMetadata &engine_metadata); void TrackAboutToEnd(); void TrackEnded(); // Play the next item on the playlist - disregarding radio stations like last.fm that might have more tracks. - void NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll); - void PreviousItem(const Engine::TrackChangeFlags change); + void NextItem(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll); + void PreviousItem(const EngineBase::TrackChangeFlags change); - void NextInternal(const Engine::TrackChangeFlags, const Playlist::AutoScroll autoscroll); - void PlayPlaylistInternal(const Engine::TrackChangeFlags, const Playlist::AutoScroll autoscroll, const QString &playlist_name); + void NextInternal(const EngineBase::TrackChangeFlags, const Playlist::AutoScroll autoscroll); + void PlayPlaylistInternal(const EngineBase::TrackChangeFlags, const Playlist::AutoScroll autoscroll, const QString &playlist_name); void FatalError(); void ValidSongRequested(const QUrl&); @@ -231,9 +227,9 @@ class Player : public PlayerInterface { PlaylistItemPtr current_item_; - Engine::TrackChangeFlags stream_change_type_; + EngineBase::TrackChangeFlags stream_change_type_; Playlist::AutoScroll autoscroll_; - Engine::State last_state_; + EngineBase::State last_state_; int nb_errors_received_; QMap url_handlers_; diff --git a/src/core/song.cpp b/src/core/song.cpp index 1e7de7fec..133afa8f8 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -48,8 +48,7 @@ #include #include "core/iconloader.h" - -#include "engine/enginebase.h" +#include "engine/enginemetadata.h" #include "utilities/strutils.h" #include "utilities/timeutils.h" #include "utilities/coverutils.h" @@ -1386,7 +1385,7 @@ void Song::ToMTP(LIBMTP_track_t *track) const { } #endif -bool Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) { +bool Song::MergeFromEngineMetadata(const EngineMetadata &engine_metadata) { d->valid_ = true; @@ -1394,47 +1393,47 @@ bool Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) { if (d->init_from_file_ || is_collection_song() || d->url_.isLocalFile()) { // This Song was already loaded using taglib. Our tags are probably better than the engine's. - if (title() != bundle.title && title().isEmpty() && !bundle.title.isEmpty()) { - set_title(bundle.title); + if (title() != engine_metadata.title && title().isEmpty() && !engine_metadata.title.isEmpty()) { + set_title(engine_metadata.title); minor = false; } - if (artist() != bundle.artist && artist().isEmpty() && !bundle.artist.isEmpty()) { - set_artist(bundle.artist); + if (artist() != engine_metadata.artist && artist().isEmpty() && !engine_metadata.artist.isEmpty()) { + set_artist(engine_metadata.artist); minor = false; } - if (album() != bundle.album && album().isEmpty() && !bundle.album.isEmpty()) { - set_album(bundle.album); + if (album() != engine_metadata.album && album().isEmpty() && !engine_metadata.album.isEmpty()) { + set_album(engine_metadata.album); minor = false; } - if (comment().isEmpty() && !bundle.comment.isEmpty()) set_comment(bundle.comment); - if (genre().isEmpty() && !bundle.genre.isEmpty()) set_genre(bundle.genre); - if (lyrics().isEmpty() && !bundle.lyrics.isEmpty()) set_lyrics(bundle.lyrics); + if (comment().isEmpty() && !engine_metadata.comment.isEmpty()) set_comment(engine_metadata.comment); + if (genre().isEmpty() && !engine_metadata.genre.isEmpty()) set_genre(engine_metadata.genre); + if (lyrics().isEmpty() && !engine_metadata.lyrics.isEmpty()) set_lyrics(engine_metadata.lyrics); } else { - if (title() != bundle.title && !bundle.title.isEmpty()) { - set_title(bundle.title); + if (title() != engine_metadata.title && !engine_metadata.title.isEmpty()) { + set_title(engine_metadata.title); minor = false; } - if (artist() != bundle.artist && !bundle.artist.isEmpty()) { - set_artist(bundle.artist); + if (artist() != engine_metadata.artist && !engine_metadata.artist.isEmpty()) { + set_artist(engine_metadata.artist); minor = false; } - if (album() != bundle.album && !bundle.album.isEmpty()) { - set_album(bundle.album); + if (album() != engine_metadata.album && !engine_metadata.album.isEmpty()) { + set_album(engine_metadata.album); minor = false; } - if (!bundle.comment.isEmpty()) set_comment(bundle.comment); - if (!bundle.genre.isEmpty()) set_genre(bundle.genre); - if (!bundle.lyrics.isEmpty()) set_lyrics(bundle.lyrics); + if (!engine_metadata.comment.isEmpty()) set_comment(engine_metadata.comment); + if (!engine_metadata.genre.isEmpty()) set_genre(engine_metadata.genre); + if (!engine_metadata.lyrics.isEmpty()) set_lyrics(engine_metadata.lyrics); } - if (bundle.length > 0) set_length_nanosec(bundle.length); - if (bundle.year > 0) d->year_ = bundle.year; - if (bundle.track > 0) d->track_ = bundle.track; - if (bundle.filetype != FileType::Unknown) d->filetype_ = bundle.filetype; - if (bundle.samplerate > 0) d->samplerate_ = bundle.samplerate; - if (bundle.bitdepth > 0) d->bitdepth_ = bundle.bitdepth; - if (bundle.bitrate > 0) d->bitrate_ = bundle.bitrate; + if (engine_metadata.length > 0) set_length_nanosec(engine_metadata.length); + if (engine_metadata.year > 0) d->year_ = engine_metadata.year; + if (engine_metadata.track > 0) d->track_ = engine_metadata.track; + if (engine_metadata.filetype != FileType::Unknown) d->filetype_ = engine_metadata.filetype; + if (engine_metadata.samplerate > 0) d->samplerate_ = engine_metadata.samplerate; + if (engine_metadata.bitdepth > 0) d->bitdepth_ = engine_metadata.bitdepth; + if (engine_metadata.bitrate > 0) d->bitrate_ = engine_metadata.bitrate; return minor; diff --git a/src/core/song.h b/src/core/song.h index 67ff8463b..293a50555 100644 --- a/src/core/song.h +++ b/src/core/song.h @@ -41,9 +41,7 @@ class SqlQuery; -namespace Engine { -struct SimpleMetaBundle; -} // namespace Engine +class EngineMetadata; namespace spb { namespace tagreader { @@ -172,7 +170,7 @@ class Song { void InitArtManual(); void InitArtAutomatic(); - bool MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle); + bool MergeFromEngineMetadata(const EngineMetadata &engine_metadata); #ifdef HAVE_LIBGPOD void InitFromItdb(_Itdb_Track *track, const QString &prefix); diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index c4ec0862d..71153fe21 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -51,7 +51,6 @@ #include "tagreaderclient.h" #include "database.h" #include "sqlrow.h" -#include "engine/enginetype.h" #include "engine/enginebase.h" #include "collection/collectionbackend.h" #include "collection/collectionquery.h" @@ -125,7 +124,7 @@ SongLoader::Result SongLoader::Load(const QUrl &url) { return Result::Success; } - if (player_->engine()->type() == Engine::EngineType::GStreamer) { + if (player_->engine()->type() == EngineBase::Type::GStreamer) { #ifdef HAVE_GSTREAMER preload_func_ = std::bind(&SongLoader::LoadRemote, this); return Result::BlockingLoadRequired; @@ -190,7 +189,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) { SongLoader::Result SongLoader::LoadAudioCD() { #if defined(HAVE_AUDIOCD) && defined(HAVE_GSTREAMER) - if (player_->engine()->type() == Engine::EngineType::GStreamer) { + if (player_->engine()->type() == EngineBase::Type::GStreamer) { CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this); QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot); QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded); diff --git a/src/engine/engine_fwd.h b/src/engine/engine_fwd.h deleted file mode 100644 index 3f548a10f..000000000 --- a/src/engine/engine_fwd.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef ENGINE_FWD_H -#define ENGINE_FWD_H - -#include - -/// Used by eg engineobserver.h, and thus we reduce header dependencies on enginebase.h - -namespace Engine { - -struct SimpleMetaBundle; -class Base; - -/** - * You should return: - * Playing when playing, - * Paused when paused - * Idle when you still have a URL loaded (ie you have not been told to stop()) - * Empty when you have been told to stop(), - * Error when an error occurred and you stopped yourself - * - * It is vital to be Idle just after the track has ended! - */ -enum class State { - Empty, - Idle, - Playing, - Paused, - Error -}; - -enum TrackChangeType { - // One of: - First = 0x01, - Manual = 0x02, - Auto = 0x04, - Intro = 0x08, - - // Any of: - SameAlbum = 0x10 -}; - -Q_DECLARE_FLAGS(TrackChangeFlags, TrackChangeType) - -} // namespace Engine - -using EngineBase = Engine::Base; - -Q_DECLARE_METATYPE(Engine::State) -Q_DECLARE_METATYPE(Engine::TrackChangeType) - -#endif // ENGINE_FWD_H diff --git a/src/engine/enginebase.cpp b/src/engine/enginebase.cpp index 793561e71..667e575ba 100644 --- a/src/engine/enginebase.cpp +++ b/src/engine/enginebase.cpp @@ -33,14 +33,12 @@ #include "utilities/envutils.h" #include "utilities/timeconstants.h" #include "core/networkproxyfactory.h" -#include "engine_fwd.h" #include "enginebase.h" #include "settings/backendsettingspage.h" #include "settings/networkproxysettingspage.h" -Engine::Base::Base(const EngineType type, QObject *parent) +EngineBase::EngineBase(QObject *parent) : QObject(parent), - type_(type), volume_control_(true), volume_(100), beginning_nanosec_(0), @@ -73,9 +71,40 @@ Engine::Base::Base(const EngineType type, QObject *parent) strict_ssl_enabled_(false), about_to_end_emitted_(false) {} -Engine::Base::~Base() = default; +EngineBase::~EngineBase() = default; -bool Engine::Base::Load(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) { +EngineBase::Type EngineBase::TypeFromName(const QString &name) { + + if (name.compare("gstreamer", Qt::CaseInsensitive) == 0) return Type::GStreamer; + if (name.compare("vlc", Qt::CaseInsensitive) == 0) return Type::VLC; + + return Type::None; + +} + +QString EngineBase::Name(const Type type) { + + switch (type) { + case Type::GStreamer: return QString("gstreamer"); + case Type::VLC: return QString("vlc"); + case Type::None: + default: return QString("None"); + } + +} + +QString EngineBase::Description(const Type type) { + + switch (type) { + case Type::GStreamer: return QString("GStreamer"); + case Type::VLC: return QString("VLC"); + case Type::None: + default: return QString("None"); + } + +} + +bool EngineBase::Load(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) { Q_UNUSED(force_stop_at_end); @@ -90,7 +119,7 @@ bool Engine::Base::Load(const QUrl &media_url, const QUrl &stream_url, const Tra } -bool Engine::Base::Play(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec, const quint64 offset_nanosec) { +bool EngineBase::Play(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec, const quint64 offset_nanosec) { if (!Load(media_url, stream_url, flags, force_stop_at_end, beginning_nanosec, end_nanosec)) { return false; @@ -100,21 +129,21 @@ bool Engine::Base::Play(const QUrl &media_url, const QUrl &stream_url, const Tra } -void Engine::Base::UpdateVolume(const uint volume) { +void EngineBase::UpdateVolume(const uint volume) { volume_ = volume; emit VolumeChanged(volume); } -void Engine::Base::SetVolume(const uint volume) { +void EngineBase::SetVolume(const uint volume) { volume_ = volume; SetVolumeSW(volume); } -void Engine::Base::ReloadSettings() { +void EngineBase::ReloadSettings() { QSettings s; @@ -190,7 +219,7 @@ void Engine::Base::ReloadSettings() { } -void Engine::Base::EmitAboutToFinish() { +void EngineBase::EmitAboutToFinish() { if (about_to_end_emitted_) { return; @@ -202,7 +231,7 @@ void Engine::Base::EmitAboutToFinish() { } -bool Engine::Base::ValidOutput(const QString &output) { +bool EngineBase::ValidOutput(const QString &output) { Q_UNUSED(output); diff --git a/src/engine/enginebase.h b/src/engine/enginebase.h index 70d2ccca1..bda5bc0cc 100644 --- a/src/engine/enginebase.h +++ b/src/engine/enginebase.h @@ -38,25 +38,54 @@ #include #include -#include "engine_fwd.h" -#include "enginetype.h" #include "devicefinders.h" +#include "enginemetadata.h" #include "core/song.h" -namespace Engine { - -struct SimpleMetaBundle; - -using Scope = std::vector; - -class Base : public QObject { +class EngineBase : public QObject { Q_OBJECT protected: - Base(const EngineType type = EngineType::None, QObject *parent = nullptr); + EngineBase(QObject *parent = nullptr); public: - ~Base() override; + ~EngineBase() override; + + enum class Type { + None, + GStreamer, + VLC, + Xine + }; + + // State: + // Playing when playing, + // Paused when paused + // Idle when you still have a URL loaded (ie you have not been told to stop()) + // Empty when you have been told to stop(), + // Error when an error occurred and you stopped yourself + // + // It is vital to be Idle just after the track has ended! + + enum class State { + Empty, + Idle, + Playing, + Paused, + Error + }; + + enum TrackChangeType { + // One of: + First = 0x01, + Manual = 0x02, + Auto = 0x04, + Intro = 0x08, + + // Any of: + SameAlbum = 0x10 + }; + Q_DECLARE_FLAGS(TrackChangeFlags, TrackChangeType) struct OutputDetails { QString name; @@ -65,6 +94,13 @@ class Base : public QObject { }; using OutputDetailsList = QList; + using Scope = std::vector; + + static Type TypeFromName(const QString &name); + static QString Name(const Type type); + static QString Description(const Type type); + + virtual Type type() const = 0; virtual bool Init() = 0; virtual State state() const = 0; virtual void StartPreloading(const QUrl&, const QUrl&, const bool, const qint64, const qint64) {} @@ -105,9 +141,7 @@ class Base : public QObject { void EmitAboutToFinish(); public: - // Simple accessors - EngineType type() const { return type_; } bool volume_control() const { return volume_control_; } inline uint volume() const { return volume_; } @@ -145,16 +179,15 @@ class Base : public QObject { // Emitted when Engine successfully started playing a song with the given QUrl. void ValidSongRequested(const QUrl &url); - void MetaData(const Engine::SimpleMetaBundle &bundle); + void MetaData(const EngineMetadata &metadata); // Signals that the engine's state has changed (a stream was stopped for example). // Always use the state from event, because it's not guaranteed that immediate subsequent call to state() won't return a stale value. - void StateChanged(const Engine::State state); + void StateChanged(const State state); void VolumeChanged(const uint volume); protected: - EngineType type_; bool volume_control_; uint volume_; quint64 beginning_nanosec_; @@ -208,38 +241,13 @@ class Base : public QObject { bool strict_ssl_enabled_; bool about_to_end_emitted_; - Q_DISABLE_COPY(Base) + Q_DISABLE_COPY(EngineBase) }; -struct SimpleMetaBundle { - SimpleMetaBundle() : type(Type::Any), length(-1), year(-1), track(-1), filetype(Song::FileType::Unknown), samplerate(-1), bitdepth(-1), bitrate(-1) {} - enum class Type { - Any, - Current, - Next - }; - Type type; - QUrl media_url; - QUrl stream_url; - QString title; - QString artist; - QString album; - QString comment; - QString genre; - qint64 length; - int year; - int track; - Song::FileType filetype; - int samplerate; - int bitdepth; - int bitrate; - QString lyrics; -}; - -} // namespace Engine - +Q_DECLARE_METATYPE(EngineBase::Type); +Q_DECLARE_METATYPE(EngineBase::State) +Q_DECLARE_METATYPE(EngineBase::TrackChangeType) Q_DECLARE_METATYPE(EngineBase::OutputDetails) -Q_DECLARE_METATYPE(Engine::SimpleMetaBundle) #endif // ENGINEBASE_H diff --git a/src/engine/enginemetadata.cpp b/src/engine/enginemetadata.cpp new file mode 100644 index 000000000..29538cc91 --- /dev/null +++ b/src/engine/enginemetadata.cpp @@ -0,0 +1,31 @@ +/* +* Strawberry Music Player +* Copyright 2018-2023, Jonas Kvinge +* +* Strawberry 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 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#include "enginemetadata.h" +#include "core/song.h" + +EngineMetadata::EngineMetadata() + : type(Type::Any), + length(-1), + year(-1), + track(-1), + filetype(Song::FileType::Unknown), + samplerate(-1), + bitdepth(-1), + bitrate(-1) {} diff --git a/src/engine/enginemetadata.h b/src/engine/enginemetadata.h new file mode 100644 index 000000000..721605c2c --- /dev/null +++ b/src/engine/enginemetadata.h @@ -0,0 +1,56 @@ +/* +* Strawberry Music Player +* Copyright 2018-2023, Jonas Kvinge +* +* Strawberry 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 3 of the License, or +* (at your option) any later version. +* +* Strawberry is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Strawberry. If not, see . +* +*/ + +#ifndef ENGINEMETADATA_H +#define ENGINEMETADATA_H + +#include +#include +#include + +#include "core/song.h" + +class EngineMetadata { + public: + EngineMetadata(); + enum class Type { + Any, + Current, + Next + }; + Type type; + QUrl media_url; + QUrl stream_url; + QString title; + QString artist; + QString album; + QString comment; + QString genre; + qint64 length; + int year; + int track; + Song::FileType filetype; + int samplerate; + int bitdepth; + int bitrate; + QString lyrics; +}; +Q_DECLARE_METATYPE(EngineMetadata) + +#endif // ENGINEMETADATA_H diff --git a/src/engine/enginetype.cpp b/src/engine/enginetype.cpp deleted file mode 100644 index e627eb088..000000000 --- a/src/engine/enginetype.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Strawberry Music Player - * Copyright 2013-2021, Jonas Kvinge - * - * Strawberry 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 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#include "config.h" - -#include - -#include "enginetype.h" - -namespace Engine { - -Engine::EngineType EngineTypeFromName(const QString &enginename) { - QString lower = enginename.toLower(); - if (lower == "gstreamer") return Engine::EngineType::GStreamer; - else if (lower == "vlc") return Engine::EngineType::VLC; - else return Engine::EngineType::None; -} - -QString EngineName(const Engine::EngineType enginetype) { - switch (enginetype) { - case Engine::EngineType::GStreamer: return QString("gstreamer"); - case Engine::EngineType::VLC: return QString("vlc"); - case Engine::EngineType::None: - default: return QString("None"); - } -} - -QString EngineDescription(Engine::EngineType enginetype) { - switch (enginetype) { - case Engine::EngineType::GStreamer: return QString("GStreamer"); - case Engine::EngineType::VLC: return QString("VLC"); - case Engine::EngineType::None: - default: return QString("None"); - - } -} - -} // namespace Engine diff --git a/src/engine/enginetype.h b/src/engine/enginetype.h deleted file mode 100644 index 25527b5aa..000000000 --- a/src/engine/enginetype.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Strawberry Music Player - * Copyright 2013-2021, Jonas Kvinge - * - * Strawberry 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 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#ifndef ENGINETYPE_H -#define ENGINETYPE_H - -#include "config.h" - -#include -#include - -namespace Engine { - -enum class EngineType { - None, - GStreamer, - VLC, - Xine -}; - -Engine::EngineType EngineTypeFromName(const QString &enginename); -QString EngineName(const Engine::EngineType enginetype); -QString EngineDescription(const Engine::EngineType enginetype); - -} // namespace Engine - -Q_DECLARE_METATYPE(Engine::EngineType) - -#endif // ENGINETYPE_H diff --git a/src/engine/gstengine.cpp b/src/engine/gstengine.cpp index 223ad6518..826b4d0d6 100644 --- a/src/engine/gstengine.cpp +++ b/src/engine/gstengine.cpp @@ -52,10 +52,10 @@ #include "core/signalchecker.h" #include "utilities/timeconstants.h" #include "enginebase.h" -#include "enginetype.h" #include "gstengine.h" #include "gstenginepipeline.h" #include "gstbufferconsumer.h" +#include "enginemetadata.h" const char *GstEngine::kAutoSink = "autoaudiosink"; const char *GstEngine::kALSASink = "alsasink"; @@ -75,7 +75,7 @@ const qint64 GstEngine::kPreloadGapNanosec = 8000 * kNsecPerMsec; // 8s const qint64 GstEngine::kSeekDelayNanosec = 100 * kNsecPerMsec; // 100msec GstEngine::GstEngine(TaskManager *task_manager, QObject *parent) - : Engine::Base(Engine::EngineType::GStreamer, parent), + : EngineBase(parent), task_manager_(task_manager), gst_startup_(nullptr), discoverer_(nullptr), @@ -138,21 +138,21 @@ bool GstEngine::Init() { } -Engine::State GstEngine::state() const { +EngineBase::State GstEngine::state() const { - if (!current_pipeline_) return stream_url_.isEmpty() ? Engine::State::Empty : Engine::State::Idle; + if (!current_pipeline_) return stream_url_.isEmpty() ? EngineBase::State::Empty : EngineBase::State::Idle; switch (current_pipeline_->state()) { case GST_STATE_NULL: - return Engine::State::Empty; + return EngineBase::State::Empty; case GST_STATE_READY: - return Engine::State::Idle; + return EngineBase::State::Idle; case GST_STATE_PLAYING: - return Engine::State::Playing; + return EngineBase::State::Playing; case GST_STATE_PAUSED: - return Engine::State::Paused; + return EngineBase::State::Paused; default: - return Engine::State::Empty; + return EngineBase::State::Empty; } } @@ -176,21 +176,21 @@ void GstEngine::StartPreloading(const QUrl &media_url, const QUrl &stream_url, c } -bool GstEngine::Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) { +bool GstEngine::Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) { EnsureInitialized(); - Engine::Base::Load(stream_url, media_url, change, force_stop_at_end, beginning_nanosec, end_nanosec); + EngineBase::Load(stream_url, media_url, change, force_stop_at_end, beginning_nanosec, end_nanosec); const QByteArray gst_url = FixupUrl(stream_url); - bool crossfade = current_pipeline_ && ((crossfade_enabled_ && change & Engine::TrackChangeType::Manual) || (autocrossfade_enabled_ && change & Engine::TrackChangeType::Auto) || ((crossfade_enabled_ || autocrossfade_enabled_) && change & Engine::TrackChangeType::Intro)); + bool crossfade = current_pipeline_ && ((crossfade_enabled_ && change & EngineBase::TrackChangeType::Manual) || (autocrossfade_enabled_ && change & EngineBase::TrackChangeType::Auto) || ((crossfade_enabled_ || autocrossfade_enabled_) && change & EngineBase::TrackChangeType::Intro)); - if (change & Engine::TrackChangeType::Auto && change & Engine::TrackChangeType::SameAlbum && !crossfade_same_album_) { + if (change & EngineBase::TrackChangeType::Auto && change & EngineBase::TrackChangeType::SameAlbum && !crossfade_same_album_) { crossfade = false; } - if (!crossfade && current_pipeline_ && current_pipeline_->stream_url() == stream_url && change & Engine::TrackChangeType::Auto) { + if (!crossfade && current_pipeline_ && current_pipeline_->stream_url() == stream_url && change & EngineBase::TrackChangeType::Auto) { // We're not crossfading, and the pipeline is already playing the URI we want, so just do nothing. return true; } @@ -279,7 +279,7 @@ void GstEngine::Stop(const bool stop_after) { current_pipeline_.reset(); BufferingFinished(); - emit StateChanged(Engine::State::Empty); + emit StateChanged(EngineBase::State::Empty); } @@ -293,7 +293,7 @@ void GstEngine::Pause() { current_pipeline_->StartFader(fadeout_pause_duration_nanosec_, QTimeLine::Forward, QEasingCurve::InOutQuad, false); is_fading_out_to_pause_ = false; has_faded_out_ = false; - emit StateChanged(Engine::State::Playing); + emit StateChanged(EngineBase::State::Playing); return; } @@ -303,7 +303,7 @@ void GstEngine::Pause() { } else { current_pipeline_->SetState(GST_STATE_PAUSED); - emit StateChanged(Engine::State::Paused); + emit StateChanged(EngineBase::State::Paused); StopTimers(); } } @@ -325,7 +325,7 @@ void GstEngine::Unpause() { has_faded_out_ = false; } - emit StateChanged(Engine::State::Playing); + emit StateChanged(EngineBase::State::Playing); StartTimers(); } @@ -373,7 +373,7 @@ qint64 GstEngine::length_nanosec() const { } -const Engine::Scope &GstEngine::scope(const int chunk_length) { +const EngineBase::Scope &GstEngine::scope(const int chunk_length) { // The new buffer could have a different size if (have_new_buffer_) { @@ -448,7 +448,7 @@ bool GstEngine::ALSADeviceSupport(const QString &output) { void GstEngine::ReloadSettings() { - Engine::Base::ReloadSettings(); + EngineBase::ReloadSettings(); if (output_.isEmpty()) output_ = kAutoSink; @@ -553,7 +553,7 @@ void GstEngine::HandlePipelineError(const int pipeline_id, const int domain, con current_pipeline_.reset(); BufferingFinished(); - emit StateChanged(Engine::State::Error); + emit StateChanged(EngineBase::State::Error); if ( (domain == static_cast(GST_RESOURCE_ERROR) && ( @@ -574,10 +574,10 @@ void GstEngine::HandlePipelineError(const int pipeline_id, const int domain, con } -void GstEngine::NewMetaData(const int pipeline_id, const Engine::SimpleMetaBundle &bundle) { +void GstEngine::NewMetaData(const int pipeline_id, const EngineMetadata &engine_metadata) { if (!current_pipeline_|| current_pipeline_->id() != pipeline_id) return; - emit MetaData(bundle); + emit MetaData(engine_metadata); } @@ -609,7 +609,7 @@ void GstEngine::FadeoutPauseFinished() { fadeout_pause_pipeline_->SetState(GST_STATE_PAUSED); current_pipeline_->SetState(GST_STATE_PAUSED); - emit StateChanged(Engine::State::Paused); + emit StateChanged(EngineBase::State::Paused); StopTimers(); is_fading_out_to_pause_ = false; @@ -664,7 +664,7 @@ void GstEngine::PlayDone(const GstStateChangeReturn ret, const quint64 offset_na Seek(offset_nanosec); } - emit StateChanged(Engine::State::Playing); + emit StateChanged(EngineBase::State::Playing); // We've successfully started playing a media stream with this url emit ValidSongRequested(stream_url_); @@ -819,7 +819,7 @@ std::shared_ptr GstEngine::CreatePipeline(const QUrl &media_u if (!ret->InitFromUrl(media_url, stream_url, gst_url, end_nanosec, error)) { ret.reset(); emit Error(error); - emit StateChanged(Engine::State::Error); + emit StateChanged(EngineBase::State::Error); emit FatalError(); } @@ -829,7 +829,7 @@ std::shared_ptr GstEngine::CreatePipeline(const QUrl &media_u void GstEngine::UpdateScope(const int chunk_length) { - using sample_type = Engine::Scope::value_type; + using sample_type = EngineBase::Scope::value_type; // Prevent dbz or invalid chunk size if (!GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(latest_buffer_))) return; @@ -858,10 +858,10 @@ void GstEngine::UpdateScope(const int chunk_length) { // Make sure we don't go beyond the end of the buffer if (scope_chunk_ == scope_chunks_ - 1) { - bytes = qMin(static_cast(map.size - (chunk_size * scope_chunk_)), scope_.size() * sizeof(sample_type)); + bytes = qMin(static_cast(map.size - (chunk_size * scope_chunk_)), scope_.size() * sizeof(sample_type)); } else { - bytes = qMin(static_cast(chunk_size), scope_.size() * sizeof(sample_type)); + bytes = qMin(static_cast(chunk_size), scope_.size() * sizeof(sample_type)); } scope_chunk_++; @@ -908,20 +908,20 @@ void GstEngine::StreamDiscovered(GstDiscoverer*, GstDiscovererInfo *info, GError GstDiscovererStreamInfo *stream_info = reinterpret_cast(g_list_first(audio_streams)->data); - Engine::SimpleMetaBundle bundle; + EngineMetadata engine_metadata; if (discovered_url == instance->current_pipeline_->gst_url()) { - bundle.type = Engine::SimpleMetaBundle::Type::Current; - bundle.media_url = instance->current_pipeline_->media_url(); - bundle.stream_url = instance->current_pipeline_->stream_url(); + engine_metadata.type = EngineMetadata::Type::Current; + engine_metadata.media_url = instance->current_pipeline_->media_url(); + engine_metadata.stream_url = instance->current_pipeline_->stream_url(); } else if (discovered_url == instance->current_pipeline_->next_gst_url()) { - bundle.type = Engine::SimpleMetaBundle::Type::Next; - bundle.media_url = instance->current_pipeline_->next_media_url(); - bundle.stream_url = instance->current_pipeline_->next_stream_url(); + engine_metadata.type = EngineMetadata::Type::Next; + engine_metadata.media_url = instance->current_pipeline_->next_media_url(); + engine_metadata.stream_url = instance->current_pipeline_->next_stream_url(); } - bundle.samplerate = static_cast(gst_discoverer_audio_info_get_sample_rate(GST_DISCOVERER_AUDIO_INFO(stream_info))); - bundle.bitdepth = static_cast(gst_discoverer_audio_info_get_depth(GST_DISCOVERER_AUDIO_INFO(stream_info))); - bundle.bitrate = static_cast(gst_discoverer_audio_info_get_bitrate(GST_DISCOVERER_AUDIO_INFO(stream_info)) / 1000); + engine_metadata.samplerate = static_cast(gst_discoverer_audio_info_get_sample_rate(GST_DISCOVERER_AUDIO_INFO(stream_info))); + engine_metadata.bitdepth = static_cast(gst_discoverer_audio_info_get_depth(GST_DISCOVERER_AUDIO_INFO(stream_info))); + engine_metadata.bitrate = static_cast(gst_discoverer_audio_info_get_bitrate(GST_DISCOVERER_AUDIO_INFO(stream_info)) / 1000); GstCaps *caps = gst_discoverer_stream_info_get_caps(stream_info); @@ -931,20 +931,20 @@ void GstEngine::StreamDiscovered(GstDiscoverer*, GstDiscovererInfo *info, GError if (!gst_structure) continue; QString mimetype = gst_structure_get_name(gst_structure); if (!mimetype.isEmpty() && mimetype != "audio/mpeg") { - bundle.filetype = Song::FiletypeByMimetype(mimetype); - if (bundle.filetype == Song::FileType::Unknown) { + engine_metadata.filetype = Song::FiletypeByMimetype(mimetype); + if (engine_metadata.filetype == Song::FileType::Unknown) { qLog(Error) << "Unknown mimetype" << mimetype; } } } - if (bundle.filetype == Song::FileType::Unknown) { + if (engine_metadata.filetype == Song::FileType::Unknown) { gchar *codec_description = gst_pb_utils_get_codec_description(caps); QString filetype_description = (codec_description ? QString(codec_description) : QString()); g_free(codec_description); if (!filetype_description.isEmpty()) { - bundle.filetype = Song::FiletypeByDescription(filetype_description); - if (bundle.filetype == Song::FileType::Unknown) { + engine_metadata.filetype = Song::FiletypeByDescription(filetype_description); + if (engine_metadata.filetype == Song::FileType::Unknown) { qLog(Error) << "Unknown filetype" << filetype_description; } } @@ -953,9 +953,9 @@ void GstEngine::StreamDiscovered(GstDiscoverer*, GstDiscovererInfo *info, GError gst_caps_unref(caps); gst_discoverer_stream_info_list_free(audio_streams); - qLog(Debug) << "Got stream info for" << discovered_url + ":" << Song::TextForFiletype(bundle.filetype); + qLog(Debug) << "Got stream info for" << discovered_url + ":" << Song::TextForFiletype(engine_metadata.filetype); - emit instance->MetaData(bundle); + emit instance->MetaData(engine_metadata); } else { diff --git a/src/engine/gstengine.h b/src/engine/gstengine.h index 363e6380f..3c639f754 100644 --- a/src/engine/gstengine.h +++ b/src/engine/gstengine.h @@ -39,7 +39,6 @@ #include #include "utilities/timeconstants.h" -#include "engine_fwd.h" #include "enginebase.h" #include "gststartup.h" #include "gstbufferconsumer.h" @@ -49,7 +48,7 @@ class QTimerEvent; class TaskManager; class GstEnginePipeline; -class GstEngine : public Engine::Base, public GstBufferConsumer { +class GstEngine : public EngineBase, public GstBufferConsumer { Q_OBJECT public: @@ -58,10 +57,11 @@ class GstEngine : public Engine::Base, public GstBufferConsumer { static const char *kAutoSink; + Type type() const override { return Type::GStreamer; } bool Init() override; - Engine::State state() const override; + EngineBase::State state() const override; void StartPreloading(const QUrl &media_url, const QUrl &stream_url, const bool force_stop_at_end, const qint64 beginning_nanosec, const qint64 end_nanosec) override; - bool Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override; + bool Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override; bool Play(const quint64 offset_nanosec) override; void Stop(const bool stop_after = false) override; void Pause() override; @@ -74,7 +74,7 @@ class GstEngine : public Engine::Base, public GstBufferConsumer { public: qint64 position_nanosec() const override; qint64 length_nanosec() const override; - const Engine::Scope &scope(const int chunk_length) override; + const EngineBase::Scope &scope(const int chunk_length) override; OutputDetailsList GetOutputsList() const override; bool ValidOutput(const QString &output) override; @@ -111,7 +111,7 @@ class GstEngine : public Engine::Base, public GstBufferConsumer { private slots: void EndOfStreamReached(const int pipeline_id, const bool has_next_track); void HandlePipelineError(const int pipeline_id, const int domain, const int error_code, const QString &message, const QString &debugstr); - void NewMetaData(const int pipeline_id, const Engine::SimpleMetaBundle &bundle); + void NewMetaData(const int pipeline_id, const EngineMetadata &engine_metadata); void AddBufferToScope(GstBuffer *buf, const int pipeline_id, const QString &format); void FadeoutFinished(); void FadeoutPauseFinished(); diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index 3d825a78b..30a4706a8 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -1307,24 +1307,24 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) { GstTagList *taglist = nullptr; gst_message_parse_tag(msg, &taglist); - Engine::SimpleMetaBundle bundle; - bundle.type = Engine::SimpleMetaBundle::Type::Current; - bundle.media_url = media_url_; - bundle.stream_url = stream_url_; - bundle.title = ParseStrTag(taglist, GST_TAG_TITLE); - bundle.artist = ParseStrTag(taglist, GST_TAG_ARTIST); - bundle.comment = ParseStrTag(taglist, GST_TAG_COMMENT); - bundle.album = ParseStrTag(taglist, GST_TAG_ALBUM); - bundle.bitrate = static_cast(ParseUIntTag(taglist, GST_TAG_BITRATE) / 1000); - bundle.lyrics = ParseStrTag(taglist, GST_TAG_LYRICS); + EngineMetadata engine_metadata; + engine_metadata.type = EngineMetadata::Type::Current; + engine_metadata.media_url = media_url_; + engine_metadata.stream_url = stream_url_; + engine_metadata.title = ParseStrTag(taglist, GST_TAG_TITLE); + engine_metadata.artist = ParseStrTag(taglist, GST_TAG_ARTIST); + engine_metadata.comment = ParseStrTag(taglist, GST_TAG_COMMENT); + engine_metadata.album = ParseStrTag(taglist, GST_TAG_ALBUM); + engine_metadata.bitrate = static_cast(ParseUIntTag(taglist, GST_TAG_BITRATE) / 1000); + engine_metadata.lyrics = ParseStrTag(taglist, GST_TAG_LYRICS); - if (!bundle.title.isEmpty() && bundle.artist.isEmpty() && bundle.album.isEmpty()) { + if (!engine_metadata.title.isEmpty() && engine_metadata.artist.isEmpty() && engine_metadata.album.isEmpty()) { QStringList title_splitted; - if (bundle.title.contains(" - ")) { - title_splitted = bundle.title.split(" - "); + if (engine_metadata.title.contains(" - ")) { + title_splitted = engine_metadata.title.split(" - "); } - else if (bundle.title.contains('~')) { - title_splitted = bundle.title.split('~'); + else if (engine_metadata.title.contains('~')) { + title_splitted = engine_metadata.title.split('~'); } if (!title_splitted.isEmpty() && title_splitted.count() >= 2) { int i = 0; @@ -1332,13 +1332,13 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) { ++i; switch (i) { case 1: - bundle.artist = title_part.trimmed(); + engine_metadata.artist = title_part.trimmed(); break; case 2: - bundle.title = title_part.trimmed(); + engine_metadata.title = title_part.trimmed(); break; case 3: - bundle.album = title_part.trimmed(); + engine_metadata.album = title_part.trimmed(); break; default: break; @@ -1349,7 +1349,7 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) { gst_tag_list_unref(taglist); - emit MetadataFound(id(), bundle); + emit MetadataFound(id(), engine_metadata); } diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index 634a3d215..ae0ebddfd 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -44,12 +44,10 @@ #include #include +#include "enginemetadata.h" + class QTimerEvent; class GstBufferConsumer; - -namespace Engine { -struct SimpleMetaBundle; -} // namespace Engine struct GstPlayBin; class GstEnginePipeline : public QObject { @@ -132,7 +130,7 @@ class GstEnginePipeline : public QObject { void Error(const int pipeline_id, const int domain, const int error_code, const QString &message, const QString &debug); void EndOfStreamReached(const int pipeline_id, const bool has_next_track); - void MetadataFound(const int pipeline_id, const Engine::SimpleMetaBundle &bundle); + void MetadataFound(const int pipeline_id, const EngineMetadata &bundle); void VolumeChanged(const uint volume); void FaderFinished(); diff --git a/src/engine/vlcengine.cpp b/src/engine/vlcengine.cpp index ed04291ff..8652811da 100644 --- a/src/engine/vlcengine.cpp +++ b/src/engine/vlcengine.cpp @@ -32,17 +32,15 @@ #include "core/taskmanager.h" #include "core/logging.h" #include "utilities/timeconstants.h" -#include "engine_fwd.h" #include "enginebase.h" -#include "enginetype.h" #include "vlcengine.h" #include "vlcscopedref.h" VLCEngine::VLCEngine(TaskManager *task_manager, QObject *parent) - : Engine::Base(Engine::EngineType::VLC, parent), + : EngineBase(parent), instance_(nullptr), player_(nullptr), - state_(Engine::State::Empty) { + state_(State::Empty) { Q_UNUSED(task_manager); @@ -52,7 +50,7 @@ VLCEngine::VLCEngine(TaskManager *task_manager, QObject *parent) VLCEngine::~VLCEngine() { - if (state_ == Engine::State::Playing || state_ == Engine::State::Paused) { + if (state_ == State::Playing || state_ == State::Paused) { libvlc_media_player_stop(player_); } @@ -100,7 +98,7 @@ bool VLCEngine::Init() { } -bool VLCEngine::Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) { +bool VLCEngine::Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) { Q_UNUSED(media_url); Q_UNUSED(change); @@ -197,7 +195,7 @@ void VLCEngine::SetVolumeSW(const uint percent) { qint64 VLCEngine::position_nanosec() const { - if (state_ == Engine::State::Empty) return 0; + if (state_ == State::Empty) return 0; const qint64 result = (position() * kNsecPerMsec); return qMax(0LL, result); @@ -205,7 +203,7 @@ qint64 VLCEngine::position_nanosec() const { qint64 VLCEngine::length_nanosec() const { - if (state_ == Engine::State::Empty) return 0; + if (state_ == State::Empty) return 0; const qint64 result = (end_nanosec_ - static_cast(beginning_nanosec_)); if (result > 0) { return result; @@ -297,32 +295,32 @@ void VLCEngine::StateChangedCallback(const libvlc_event_t *e, void *data) { break; case libvlc_MediaPlayerStopped:{ - const Engine::State state = engine->state_; - engine->state_ = Engine::State::Empty; - if (state == Engine::State::Playing) { + const EngineBase::State state = engine->state_; + engine->state_ = EngineBase::State::Empty; + if (state == EngineBase::State::Playing) { emit engine->StateChanged(engine->state_); } break; } case libvlc_MediaPlayerEncounteredError: - engine->state_ = Engine::State::Error; + engine->state_ = EngineBase::State::Error; emit engine->StateChanged(engine->state_); emit engine->FatalError(); break; case libvlc_MediaPlayerPlaying: - engine->state_ = Engine::State::Playing; + engine->state_ = EngineBase::State::Playing; emit engine->StateChanged(engine->state_); break; case libvlc_MediaPlayerPaused: - engine->state_ = Engine::State::Paused; + engine->state_ = EngineBase::State::Paused; emit engine->StateChanged(engine->state_); break; case libvlc_MediaPlayerEndReached: - engine->state_ = Engine::State::Idle; + engine->state_ = EngineBase::State::Idle; emit engine->TrackEnded(); break; } diff --git a/src/engine/vlcengine.h b/src/engine/vlcengine.h index e78fb0f14..352d1ffda 100644 --- a/src/engine/vlcengine.h +++ b/src/engine/vlcengine.h @@ -31,23 +31,23 @@ #include #include -#include "engine_fwd.h" #include "enginebase.h" struct libvlc_event_t; class TaskManager; -class VLCEngine : public Engine::Base { +class VLCEngine : public EngineBase { Q_OBJECT public: explicit VLCEngine(TaskManager *task_manager, QObject *parent = nullptr); ~VLCEngine() override; + Type type() const override { return Type::VLC; } bool Init() override; - Engine::State state() const override { return state_; } - bool Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override; + EngineBase::State state() const override { return state_; } + bool Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override; bool Play(const quint64 offset_nanosec) override; void Stop(const bool stop_after = false) override; void Pause() override; @@ -70,7 +70,7 @@ class VLCEngine : public Engine::Base { private: libvlc_instance_t *instance_; libvlc_media_player_t *player_; - Engine::State state_; + State state_; bool Initialized() const { return (instance_ && player_); } uint position() const; diff --git a/src/moodbar/moodbarcontroller.cpp b/src/moodbar/moodbarcontroller.cpp index 793e7f3c1..d709a7954 100644 --- a/src/moodbar/moodbarcontroller.cpp +++ b/src/moodbar/moodbarcontroller.cpp @@ -22,7 +22,7 @@ #include "core/application.h" #include "core/player.h" #include "core/song.h" -#include "engine/engine_fwd.h" +#include "engine/enginebase.h" #include "settings/moodbarsettingspage.h" #include "playlist/playlistmanager.h" @@ -94,9 +94,9 @@ void MoodbarController::AsyncLoadComplete(MoodbarPipeline *pipeline, const QUrl } // Did we stop the song? switch (app_->player()->GetState()) { - case Engine::State::Error: - case Engine::State::Empty: - case Engine::State::Idle: + case EngineBase::State::Error: + case EngineBase::State::Empty: + case EngineBase::State::Idle: return; default: diff --git a/src/settings/backendsettingspage.cpp b/src/settings/backendsettingspage.cpp index dbc322360..5cf8f6b0f 100644 --- a/src/settings/backendsettingspage.cpp +++ b/src/settings/backendsettingspage.cpp @@ -43,10 +43,8 @@ #include "core/iconloader.h" #include "core/player.h" #include "core/logging.h" -#include "engine/engine_fwd.h" #include "engine/enginebase.h" #include "engine/devicefinders.h" -#include "engine/enginetype.h" #include "engine/devicefinder.h" #include "widgets/lineedit.h" #include "widgets/stickyslider.h" @@ -67,7 +65,7 @@ BackendSettingsPage::BackendSettingsPage(SettingsDialog *dialog, QWidget *parent ui_(new Ui_BackendSettingsPage), configloaded_(false), engineloaded_(false), - enginetype_current_(Engine::EngineType::None) { + enginetype_current_(EngineBase::Type::None) { ui_->setupUi(this); setWindowIcon(IconLoader::Load("soundcard", true, 0, 32)); @@ -113,15 +111,15 @@ void BackendSettingsPage::Load() { QSettings s; s.beginGroup(kSettingsGroup); - Engine::EngineType enginetype = Engine::EngineTypeFromName(s.value("engine", EngineName(Engine::EngineType::None)).toString()); - if (enginetype == Engine::EngineType::None && engine()) enginetype = engine()->type(); + EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::None)).toString()); + if (enginetype == EngineBase::Type::None && engine()) enginetype = engine()->type(); ui_->combobox_engine->clear(); #ifdef HAVE_GSTREAMER - ui_->combobox_engine->addItem(IconLoader::Load("gstreamer"), EngineDescription(Engine::EngineType::GStreamer), static_cast(Engine::EngineType::GStreamer)); + ui_->combobox_engine->addItem(IconLoader::Load("gstreamer"), EngineBase::Description(EngineBase::Type::GStreamer), static_cast(EngineBase::Type::GStreamer)); #endif #ifdef HAVE_VLC - ui_->combobox_engine->addItem(IconLoader::Load("vlc"), EngineDescription(Engine::EngineType::VLC), static_cast(Engine::EngineType::VLC)); + ui_->combobox_engine->addItem(IconLoader::Load("vlc"), EngineBase::Description(EngineBase::Type::VLC), static_cast(EngineBase::Type::VLC)); #endif enginetype_current_ = enginetype; @@ -189,7 +187,7 @@ void BackendSettingsPage::Load() { if (!EngineInitialized()) return; - if (engine()->state() == Engine::State::Empty) { + if (engine()->state() == EngineBase::State::Empty) { if (ui_->combobox_engine->count() > 1) ui_->combobox_engine->setEnabled(true); else ui_->combobox_engine->setEnabled(false); } @@ -208,7 +206,7 @@ void BackendSettingsPage::Load() { // Check if engine, output or device is set to a different setting than the configured to force saving settings. - enginetype = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex()).value(); + enginetype = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex()).value(); QString output_name; if (ui_->combobox_output->currentText().isEmpty()) { output_name = engine()->DefaultOutput(); @@ -232,7 +230,7 @@ void BackendSettingsPage::Load() { bool BackendSettingsPage::EngineInitialized() { - if (!engine() || engine()->type() == Engine::EngineType::None) { + if (!engine() || engine()->type() == EngineBase::Type::None) { errordialog_.ShowMessage("Engine is not initialized! Please restart."); return false; } @@ -240,7 +238,7 @@ bool BackendSettingsPage::EngineInitialized() { } -void BackendSettingsPage::Load_Engine(const Engine::EngineType enginetype) { +void BackendSettingsPage::Load_Engine(const EngineBase::Type enginetype) { if (!EngineInitialized()) return; @@ -260,7 +258,7 @@ void BackendSettingsPage::Load_Engine(const Engine::EngineType enginetype) { if (engine()->type() != enginetype) { qLog(Debug) << "Switching engine."; - Engine::EngineType new_enginetype = dialog()->app()->player()->CreateEngine(enginetype); + EngineBase::Type new_enginetype = dialog()->app()->player()->CreateEngine(enginetype); dialog()->app()->player()->Init(); if (new_enginetype != enginetype) { ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(engine()->type()))); @@ -307,7 +305,7 @@ void BackendSettingsPage::Load_Output(QString output, QVariant device) { } } - if (engine()->type() == Engine::EngineType::GStreamer) { + if (engine()->type() == EngineBase::Type::GStreamer) { ui_->groupbox_buffer->setEnabled(true); ui_->groupbox_replaygain->setEnabled(true); } @@ -333,7 +331,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev ui_->lineedit_device->clear(); #ifdef Q_OS_WIN - if (engine()->type() != Engine::EngineType::GStreamer) + if (engine()->type() != EngineBase::Type::GStreamer) #endif ui_->combobox_device->addItem(IconLoader::Load("soundcard"), kOutputAutomaticallySelect, QVariant()); @@ -436,7 +434,7 @@ void BackendSettingsPage::Save() { if (!EngineInitialized()) return; QVariant enginetype_v = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex()); - Engine::EngineType enginetype = enginetype_v.value(); + EngineBase::Type enginetype = enginetype_v.value(); QString output_name; QVariant device_value; @@ -455,7 +453,7 @@ void BackendSettingsPage::Save() { QSettings s; s.beginGroup(kSettingsGroup); - s.setValue("engine", EngineName(enginetype)); + s.setValue("engine", EngineBase::Name(enginetype)); s.setValue("output", output_name); s.setValue("device", device_value); @@ -512,11 +510,11 @@ void BackendSettingsPage::EngineChanged(const int index) { if (!configloaded_ || !EngineInitialized()) return; QVariant v = ui_->combobox_engine->itemData(index); - Engine::EngineType enginetype = v.value(); + EngineBase::Type enginetype = v.value(); if (engine()->type() == enginetype) return; - if (engine()->state() != Engine::State::Empty) { + if (engine()->state() != EngineBase::State::Empty) { errordialog_.ShowMessage("Can't switch engine while playing!"); ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast(engine()->type()))); return; @@ -797,7 +795,7 @@ void BackendSettingsPage::FadingOptionsChanged() { if (!configloaded_ || !EngineInitialized()) return; EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value(); - if (engine()->type() == Engine::EngineType::GStreamer && + if (engine()->type() == EngineBase::Type::GStreamer && !(engine()->ALSADeviceSupport(output.name) && !ui_->lineedit_device->text().isEmpty() && (ui_->lineedit_device->text().contains(QRegularExpression("^hw:.*")) || ui_->lineedit_device->text().contains(QRegularExpression("^plughw:.*"))))) { ui_->groupbox_fading->setEnabled(true); } diff --git a/src/settings/backendsettingspage.h b/src/settings/backendsettingspage.h index b83890a2e..3290fd55f 100644 --- a/src/settings/backendsettingspage.h +++ b/src/settings/backendsettingspage.h @@ -26,13 +26,11 @@ #include #include -#include "engine/enginetype.h" -#include "dialogs/errordialog.h" -#include "settingspage.h" - #include "core/application.h" #include "core/player.h" -#include "engine/engine_fwd.h" +#include "engine/enginebase.h" +#include "dialogs/errordialog.h" +#include "settingspage.h" class SettingsDialog; class Ui_BackendSettingsPage; @@ -80,7 +78,7 @@ class BackendSettingsPage : public SettingsPage { bool EngineInitialized(); - void Load_Engine(Engine::EngineType enginetype); + void Load_Engine(const EngineBase::Type enginetype); void Load_Output(QString output, QVariant device); void Load_Device(const QString &output, const QVariant &device); #ifdef HAVE_ALSA @@ -97,7 +95,7 @@ class BackendSettingsPage : public SettingsPage { bool engineloaded_; ErrorDialog errordialog_; - Engine::EngineType enginetype_current_; + EngineBase::Type enginetype_current_; QString output_current_; QVariant device_current_; diff --git a/src/settings/settingsdialog.h b/src/settings/settingsdialog.h index 8c34cbfe0..0028561a1 100644 --- a/src/settings/settingsdialog.h +++ b/src/settings/settingsdialog.h @@ -34,7 +34,7 @@ #include #include -#include "engine/engine_fwd.h" +#include "engine/enginebase.h" #include "osd/osdbase.h" class QMainWindow;