Skip to content

Commit

Permalink
Add visualizations
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaski committed Sep 23, 2024
1 parent 254c442 commit 83475b3
Show file tree
Hide file tree
Showing 30 changed files with 2,261 additions and 7 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
libchromaprint-devel
fftw3-devel
libebur128-devel
projectM-devel
desktop-file-utils
update-desktop-files
appstream-glib
Expand All @@ -81,6 +82,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 @@ -189,6 +191,7 @@ jobs:
libchromaprint-devel
libebur128-devel
fftw-devel
libprojectM-devel
desktop-file-utils
libappstream-glib
hicolor-icon-theme
Expand Down Expand Up @@ -280,6 +283,7 @@ jobs:
lib64Qt6DBus-devel
lib64Qt6Gui-devel
lib64Qt6Widgets-devel
lib64Qt6OpenGL-devel
lib64Qt6Test-devel
qt6-cmake
qt6-qtbase-tools
Expand Down Expand Up @@ -376,6 +380,7 @@ jobs:
lib64fftw-devel
lib64dbus-devel
lib64appstream-devel
lib64projectm-devel
lib64qt6core-devel
lib64qt6gui-devel
lib64qt6widgets-devel
Expand All @@ -385,6 +390,7 @@ jobs:
lib64qt6dbus-devel
lib64qt6help-devel
lib64qt6test-devel
lib64qt6opengl-devel
protobuf-compiler
desktop-file-utils
appstream-util
Expand Down Expand Up @@ -480,6 +486,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 @@ -562,6 +569,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 @@ -646,6 +654,7 @@ jobs:
gstreamer1.0-alsa
gstreamer1.0-pulseaudio
protobuf-compiler
libprojectm-dev
- name: Install keyboxd
if: matrix.ubuntu_version == 'noble'
env:
Expand Down
16 changes: 15 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,22 @@ pkg_check_modules(LIBMTP libmtp>=1.0)
pkg_check_modules(GDK_PIXBUF gdk-pixbuf-2.0)
find_package(Gettext)
find_package(FFTW3)
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)
find_library(GMOCK_LIBRARY gmock)

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(DBUS_FOUND AND NOT WIN32)
list(APPEND QT_COMPONENTS DBus)
endif()
Expand Down Expand Up @@ -394,6 +402,12 @@ optional_component(EBUR128 ON "EBU R 128 loudness normalization"
DEPENDS "gstreamer" HAVE_GSTREAMER
)

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

if(APPLE OR WIN32)
set(USE_BUNDLE_DEFAULT ON)
else()
Expand Down
3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,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 @@ -46,6 +46,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
31 changes: 31 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,27 @@ optional_source(HAVE_EBUR128
SOURCES engine/ebur128analysis.cpp
)

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

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)

Expand Down Expand Up @@ -1109,6 +1130,10 @@ if(HAVE_DBUS)
target_link_libraries(strawberry_lib PUBLIC Qt${QT_VERSION_MAJOR}::DBus)
endif()

if(HAVE_VISUALIZATIONS)
target_link_libraries(strawberry_lib PUBLIC Qt${QT_VERSION_MAJOR}::OpenGLWidgets)
endif()

if(HAVE_ALSA)
target_include_directories(strawberry_lib SYSTEM PRIVATE ${ALSA_INCLUDE_DIRS})
target_link_directories(strawberry_lib PRIVATE ${ALSA_LIBRARY_DIRS})
Expand Down Expand Up @@ -1211,6 +1236,12 @@ if(HAVE_LIBMTP)
target_link_libraries(strawberry_lib PRIVATE ${LIBMTP_LIBRARIES})
endif()

if(HAVE_VISUALIZATIONS)
target_include_directories(strawberry_lib SYSTEM PRIVATE ${LIBPROJECTM_INCLUDE_DIRS})
target_link_directories(strawberry_lib PRIVATE ${LIBPROJECTM_LIBRARY_DIRS})
target_link_libraries(strawberry_lib PRIVATE ${LIBPROJECTM_LIBRARIES})
endif()

if(APPLE)
target_link_libraries(strawberry_lib PRIVATE
"-framework AppKit"
Expand Down
21 changes: 20 additions & 1 deletion src/analyzer/analyzercontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,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 @@ -121,6 +122,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 @@ -250,3 +262,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 @@ -55,4 +55,7 @@

#cmakedefine HAVE_EBUR128

#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 @@ -212,6 +212,11 @@

#include "organize/organizeerrordialog.h"

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

#ifdef Q_OS_WIN
# include "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 @@ -859,6 +870,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(QStringLiteral("WW selected of WW tracks - [ WW:WW ]")));
Expand Down Expand Up @@ -3283,3 +3295,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 @@ -101,6 +101,7 @@ class Windows7ThumbBar;
class AddStreamDialog;
class LastFMImportDialog;
class RadioViewContainer;
class VisualizationContainer;

class MainWindow : public QMainWindow, public PlatformInterface {
Q_OBJECT
Expand Down Expand Up @@ -270,6 +271,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 @@ -351,6 +353,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 @@ -522,7 +522,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 @@ -88,7 +88,7 @@ class GstEngine : public EngineBase, public GstBufferConsumer {
void SetStartup(GstStartup *gst_startup) { gst_startup_ = gst_startup; }
void EnsureInitialized() { gst_startup_->EnsureInitialized(); }

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 @@ -1303,7 +1303,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

0 comments on commit 83475b3

Please sign in to comment.