Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visualizations #1467

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jobs:
libchromaprint-devel
fftw3-devel
libebur128-devel
projectM-devel
desktop-file-utils
update-desktop-files
appstream-glib
Expand All @@ -77,6 +78,7 @@ jobs:
qt6-base-common-devel
qt6-sql-sqlite
qt6-linguist-devel
qt6-opengl-devel
- name: Install kdsingleapplication-qt6-devel
if: matrix.opensuse_version == 'tumbleweed'
run: zypper -n --gpg-auto-import-keys in kdsingleapplication-qt6-devel
Expand Down Expand Up @@ -181,6 +183,7 @@ jobs:
libchromaprint-devel
libebur128-devel
fftw-devel
libprojectM-devel
desktop-file-utils
libappstream-glib
hicolor-icon-theme
Expand Down Expand Up @@ -268,6 +271,7 @@ jobs:
lib64Qt6DBus-devel
lib64Qt6Gui-devel
lib64Qt6Widgets-devel
lib64Qt6OpenGL-devel
lib64Qt6Test-devel
qt6-cmake
qt6-qtbase-tools
Expand Down Expand Up @@ -362,6 +366,7 @@ jobs:
lib64fftw-devel
lib64dbus-devel
lib64appstream-devel
lib64projectm-devel
lib64qt6core-devel
lib64qt6gui-devel
lib64qt6widgets-devel
Expand All @@ -371,6 +376,7 @@ jobs:
lib64qt6dbus-devel
lib64qt6help-devel
lib64qt6test-devel
lib64qt6opengl-devel
desktop-file-utils
appstream-util
hicolor-icon-theme
Expand Down Expand Up @@ -461,6 +467,7 @@ jobs:
qt6-tools-dev
qt6-tools-dev-tools
qt6-l10n-tools
libprojectm-dev
- name: Checkout
uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -539,6 +546,7 @@ jobs:
qt6-tools-dev
qt6-tools-dev-tools
qt6-l10n-tools
libprojectm-dev
- name: Checkout
uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -619,6 +627,7 @@ jobs:
qt6-l10n-tools
gstreamer1.0-alsa
gstreamer1.0-pulseaudio
libprojectm-dev
- name: Install keyboxd
if: matrix.ubuntu_version == 'noble'
env:
Expand Down
38 changes: 37 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,22 @@ else()
pkg_check_modules(TAGLIB REQUIRED IMPORTED_TARGET taglib>=1.12)
endif()

find_package(projectM4 COMPONENTS Playlist)
if(projectM4_FOUND)
set(LIBPROJECTM_FOUND ON)
set(HAVE_PROJECTM4 ON)
set(LIBPROJECTM_LIBRARIES libprojectM::projectM libprojectM::playlist)
else()
pkg_check_modules(LIBPROJECTM libprojectM)
endif()

find_package(GTest)

set(QT_VERSION_MAJOR 6)
set(QT_MIN_VERSION 6.4.0)
set(QT_DEFAULT_MAJOR_VERSION ${QT_VERSION_MAJOR})
set(QT_COMPONENTS Core Concurrent Gui Widgets Network Sql)
set(QT_OPTIONAL_COMPONENTS LinguistTools Test)
set(QT_OPTIONAL_COMPONENTS OpenGLWidgets LinguistTools Test)
if(UNIX AND NOT APPLE)
list(APPEND QT_OPTIONAL_COMPONENTS DBus)
endif()
Expand Down Expand Up @@ -366,6 +375,11 @@ if(HAVE_X11_GLOBALSHORTCUTS OR HAVE_KGLOBALACCEL_GLOBALSHORTCUTS OR APPLE OR WIN
set(HAVE_GLOBALSHORTCUTS ON)
endif()

optional_component(VISUALIZATIONS ON "Visualizations"
DEPENDS "libprojectm" LIBPROJECTM_FOUND
DEPENDS "QtOpenGLWidgets" Qt${QT_VERSION_MAJOR}OpenGLWidgets_FOUND
)

if(NOT CMAKE_CROSSCOMPILING)
# Check that we have Qt with sqlite driver
set(CMAKE_REQUIRED_FLAGS "-std=c++17")
Expand Down Expand Up @@ -1441,6 +1455,26 @@ optional_source(HAVE_QOBUZ
src/settings/qobuzsettingspage.ui
)

optional_source(HAVE_VISUALIZATIONS
SOURCES
src/visualizations/projectmpresetmodel.cpp
src/visualizations/projectmvisualization.cpp
src/visualizations/visualizationcontainer.cpp
src/visualizations/visualizationoverlay.cpp
src/visualizations/visualizationselector.cpp
src/visualizations/visualizationopenglwidget.cpp
HEADERS
src/visualizations/projectmpresetmodel.h
src/visualizations/projectmvisualization.h
src/visualizations/visualizationcontainer.h
src/visualizations/visualizationoverlay.h
src/visualizations/visualizationselector.h
src/visualizations/visualizationopenglwidget.h
UI
src/visualizations/visualizationoverlay.ui
src/visualizations/visualizationselector.ui
)

qt_wrap_cpp(SOURCES ${HEADERS})
qt_wrap_ui(SOURCES ${UI})
qt_add_resources(SOURCES data/data.qrc data/icons.qrc)
Expand Down Expand Up @@ -1508,6 +1542,7 @@ target_link_libraries(strawberry_lib PUBLIC
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Sql
$<$<BOOL:${HAVE_DBUS}>:Qt${QT_VERSION_MAJOR}::DBus>
$<$<BOOL:${HAVE_VISUALIZATIONS}>:Qt${QT_VERSION_MAJOR}::OpenGLWidgets>
ICU::uc
ICU::i18n
$<$<BOOL:${HAVE_ALSA}>:ALSA::ALSA>
Expand All @@ -1521,6 +1556,7 @@ target_link_libraries(strawberry_lib PUBLIC
$<$<BOOL:${HAVE_AUDIOCD}>:PkgConfig::LIBCDIO>
$<$<BOOL:${HAVE_MTP}>:PkgConfig::LIBMTP>
$<$<BOOL:${HAVE_GPOD}>:PkgConfig::LIBGPOD PkgConfig::GDK_PIXBUF>
$<$<BOOL:${HAVE_VISUALIZATIONS}>:${LIBPROJECTM_LIBRARIES}>
$<$<BOOL:${HAVE_QTSPARKLE}>:PkgConfig::QTSPARKLE>
$<$<BOOL:${FREEBSD}>:execinfo>
$<$<BOOL:${WIN32}>:dsound dwmapi getopt-win::getopt>
Expand Down
3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ Build-Depends: debhelper (>= 11),
libmtp-dev,
libchromaprint-dev,
libfftw3-dev,
libebur128-dev
libebur128-dev,
libprojectm-dev
Standards-Version: 4.6.1

Package: strawberry
Expand Down
1 change: 1 addition & 0 deletions dist/unix/strawberry.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ BuildRequires: pkgconfig(taglib)
BuildRequires: pkgconfig(fftw3)
BuildRequires: pkgconfig(icu-uc)
BuildRequires: pkgconfig(icu-i18n)
BuildRequires: pkgconfig(libprojectM)
BuildRequires: cmake(Qt@QT_VERSION_MAJOR@Core)
BuildRequires: cmake(Qt@QT_VERSION_MAJOR@Concurrent)
BuildRequires: cmake(Qt@QT_VERSION_MAJOR@Network)
Expand Down
21 changes: 20 additions & 1 deletion src/analyzer/analyzercontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ AnalyzerContainer::AnalyzerContainer(QWidget *parent)
double_click_timer_(new QTimer(this)),
ignore_next_click_(false),
current_analyzer_(nullptr),
engine_(nullptr) {
engine_(nullptr),
action_visualization_(nullptr) {

QHBoxLayout *layout = new QHBoxLayout(this);
setLayout(layout);
Expand Down Expand Up @@ -118,6 +119,17 @@ void AnalyzerContainer::mouseReleaseEvent(QMouseEvent *e) {

}

void AnalyzerContainer::mouseDoubleClickEvent(QMouseEvent *e) {

Q_UNUSED(e);

double_click_timer_->stop();
ignore_next_click_ = true;

if (action_visualization_) action_visualization_->trigger();

}

void AnalyzerContainer::ShowPopupMenu() {
context_menu_->popup(last_click_pos_);
}
Expand Down Expand Up @@ -249,3 +261,10 @@ void AnalyzerContainer::AddFramerate(const QString &name, const int framerate) {
QObject::connect(action, &QAction::triggered, this, [this, framerate]() { ChangeFramerate(framerate); } );

}

void AnalyzerContainer::SetVisualizationsAction(QAction *visualization) {

action_visualization_ = visualization;
context_menu_->addAction(action_visualization_);

}
4 changes: 4 additions & 0 deletions src/analyzer/analyzercontainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class AnalyzerContainer : public QWidget {
explicit AnalyzerContainer(QWidget *parent);

void SetEngine(SharedPtr<EngineBase> engine);
void SetVisualizationsAction(QAction *visualization);

static const char *kSettingsGroup;
static const char *kSettingsFramerate;
Expand All @@ -55,6 +56,7 @@ class AnalyzerContainer : public QWidget {

protected:
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseDoubleClickEvent(QMouseEvent *e) override;
void wheelEvent(QWheelEvent *e) override;

private Q_SLOTS:
Expand Down Expand Up @@ -89,6 +91,8 @@ class AnalyzerContainer : public QWidget {

AnalyzerBase *current_analyzer_;
SharedPtr<EngineBase> engine_;

QAction *action_visualization_;
};

template<typename T>
Expand Down
3 changes: 3 additions & 0 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@

#cmakedefine ENABLE_WIN32_CONSOLE

#cmakedefine HAVE_VISUALIZATIONS
#cmakedefine HAVE_PROJECTM4

#endif // CONFIG_H_IN
33 changes: 33 additions & 0 deletions src/core/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@

#include "organize/organizeerrordialog.h"

#ifdef HAVE_VISUALIZATIONS
# include "visualizations/visualizationcontainer.h"
# include "engine/gstengine.h"
#endif

#ifdef Q_OS_WIN
# include "core/windows7thumbbar.h"
#endif
Expand Down Expand Up @@ -592,6 +597,12 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
stop_menu->addAction(ui_->action_stop_after_this_track);
ui_->stop_button->setMenu(stop_menu);

#ifdef HAVE_VISUALIZATIONS
QObject::connect(ui_->action_visualizations, &QAction::triggered, this, &MainWindow::ShowVisualizations);
#else
ui_->action_visualizations->setEnabled(false);
#endif

// Player connections
QObject::connect(ui_->volume, &VolumeSlider::valueChanged, &*app_->player(), &Player::SetVolumeFromSlider);

Expand Down Expand Up @@ -876,6 +887,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS

// Analyzer
QObject::connect(ui_->analyzer, &AnalyzerContainer::WheelEvent, this, &MainWindow::VolumeWheelEvent);
ui_->analyzer->SetVisualizationsAction(ui_->action_visualizations);

// Statusbar widgets
ui_->playlist_summary->setMinimumWidth(QFontMetrics(font()).horizontalAdvance(u"WW selected of WW tracks - [ WW:WW ]"_s));
Expand Down Expand Up @@ -3314,3 +3326,24 @@ void MainWindow::FocusSearchField() {
}

}

void MainWindow::ShowVisualizations() {

#ifdef HAVE_VISUALIZATIONS

if (!visualization_) {
visualization_.reset(new VisualizationContainer);

visualization_->SetActions(ui_->action_previous_track, ui_->action_play_pause, ui_->action_stop, ui_->action_next_track);
connect(&*app_->player(), &Player::Stopped, &*visualization_, &VisualizationContainer::Stopped);
connect(&*app_->player(), &Player::ForceShowOSD, &*visualization_, &VisualizationContainer::SongMetadataChanged);
connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, &*visualization_, &VisualizationContainer::SongMetadataChanged);

visualization_->SetEngine(qobject_cast<GstEngine*>(&*app_->player()->engine()));
}

visualization_->show();

#endif // HAVE_VISUALIZATIONS

}
6 changes: 6 additions & 0 deletions src/core/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class Windows7ThumbBar;
class AddStreamDialog;
class LastFMImportDialog;
class RadioViewContainer;
class VisualizationContainer;

class MainWindow : public QMainWindow, public PlatformInterface {
Q_OBJECT
Expand Down Expand Up @@ -266,6 +267,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
public Q_SLOTS:
void CommandlineOptionsReceived(const QByteArray &string_options);
void Raise();
void ShowVisualizations();

private:

Expand Down Expand Up @@ -345,6 +347,10 @@ class MainWindow : public QMainWindow, public PlatformInterface {

LastFMImportDialog *lastfm_import_dialog_;

#ifdef HAVE_VISUALIZATIONS
ScopedPtr<VisualizationContainer> visualization_;
#endif

QAction *collection_show_all_;
QAction *collection_show_duplicates_;
QAction *collection_show_untagged_;
Expand Down
6 changes: 6 additions & 0 deletions src/core/mainwindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@
<addaction name="action_cover_manager"/>
<addaction name="action_equalizer"/>
<addaction name="action_transcoder"/>
<addaction name="action_visualizations"/>
<addaction name="separator"/>
<addaction name="action_update_collection"/>
<addaction name="action_full_collection_scan"/>
Expand Down Expand Up @@ -867,6 +868,11 @@
<string>Import data from last.fm...</string>
</property>
</action>
<action name="action_visualizations">
<property name="text">
<string>Visualizations</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
Expand Down
2 changes: 1 addition & 1 deletion src/engine/gstbufferconsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class GstBufferConsumer {

// This is called in some unspecified GStreamer thread.
// Ownership of the buffer is transferred to the BufferConsumer, and it should gst_buffer_unref it.
virtual void ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format) = 0;
virtual void ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format, const int channels) = 0;

private:
Q_DISABLE_COPY(GstBufferConsumer)
Expand Down
4 changes: 3 additions & 1 deletion src/engine/gstengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ void GstEngine::ReloadSettings() {

}

void GstEngine::ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format) {
void GstEngine::ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format, const int channels) {

Q_UNUSED(channels);

// Schedule this to run in the GUI thread. The buffer gets added to the queue and unreffed by UpdateScope.
if (!QMetaObject::invokeMethod(this, "AddBufferToScope", Q_ARG(GstBuffer*, buffer), Q_ARG(int, pipeline_id), Q_ARG(QString, format))) {
Expand Down
2 changes: 1 addition & 1 deletion src/engine/gstengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class GstEngine : public EngineBase, public GstBufferConsumer {
bool ALSADeviceSupport(const QString &output) const override;
bool ExclusiveModeSupport(const QString &output) const override;

void ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format) override;
void ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format, const int channels) override;

public Q_SLOTS:
void ReloadSettings() override;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/gstenginepipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ GstPadProbeReturn GstEnginePipeline::BufferProbeCallback(GstPad *pad, GstPadProb

for (GstBufferConsumer *consumer : std::as_const(consumers)) {
gst_buffer_ref(buf);
consumer->ConsumeBuffer(buf, instance->id(), format);
consumer->ConsumeBuffer(buf, instance->id(), format, channels);
}

if (buf16) {
Expand Down
Loading
Loading