@scubaboyc compare the fields of metadata of a working file with a problematic one. I believe there's a specific field missing thats part of the SQL constraint
Posts made by Gustavo L Conte
-
RE: Strawberry doesn't see new files
-
RE: External User commands
To integrate user-defined commands into Strawberry Music Player without requiring programming changes to its code, we can leverage UNIX concepts like shell scripting, command-line utilities, and inter-process communication.
Tools like zenity can be useful for creating a GUI
#!/bin/bash # Define actions ACTION=$(zenity --list --title="Strawberry Actions" \ --column="Action" --height=300 \ "Check Integrity" \ "Normalize Volume (ReplayGain)" \ "Open in Editor" \ "Move Files" \ "Display Spectrogram" \ "Query Database" \ "Cancel") case $ACTION in "Check Integrity") echo "Checking integrity of files..." # Implement your integrity check command here ;; "Normalize Volume (ReplayGain)") echo "Normalizing volume..." # Add replaygain command here ;; "Open in Editor") echo "Opening files in editor..." # Example: open the currently selected file in a text editor xdg-open "$CURRENT_FILE" ;; "Move Files") echo "Moving files..." # Example: mv selected files to another directory mv "$CURRENT_FILE" /path/to/destination/ ;; "Display Spectrogram") echo "Generating spectrogram..." # Example: display spectrogram for current track sox "$CURRENT_FILE" -n spectrogram ;; "Query Database") echo "Querying database..." # Custom query logic here ;; *) echo "Cancelled." ;; esac
Integrate with Strawberry Use Strawberry's command-line options to pass information about the current track or playlist. Strawberry supports commands like:
--playuri <uri>: Play a specific track.
--stop: Stop playback.
--next: Play the next track.Combine this with environment variables to pass the currently playing track:
CURRENT_FILE=$(strawberry --playuri | awk '{print $1}')
Create a Keybinding Use a global hotkey (e.g., via your desktop environment or a tool like xbindkeys) to trigger the script. This avoids modifying Strawberry itself.
Share Scripts Create a shared directory (e.g., ~/.strawberry-scripts) where users can place their custom commands. Your main script could dynamically load commands from this directory.
Benefits
- MOSTLY No coding changes to Strawberry itself.
- Highly flexible: users can define their commands.
- Simple integration using existing UNIX tools.
- Community-friendly: users can share scripts.
EDIT> It just occured to me that this approach would not be good for Windows users, shucks
-
What about: Captchas on the forum
We will, we will CAPTCHAs
Sing it
We will, we will CAPTCHAs
Everybody
We will, we will CAPTCHAs
Hmm
We will, we will CAPTCHAs
Alright
-
RE: WakkaQt - a Karaoke recorder written in C++ and Qt6
Just passing by to say that since last month
WakkaQt gone v1.0!
WakkaQt is a multiplatform karaoke application built with C++ and Qt6, designed to record vocals over a video/audio track and mix them into a rendered file.
- This app features webcam recording,
- YouTube video downloading,
- real-time sound visualization,
- and post-recording video rendering with FFmpeg.
- It automatically does some mastering on the vocal tracks.
- It also has a custom AutoTuner class I programmed called VocalEnhancer that provides slight pitch shift/correction and formant preservation.
more info here:
Merry christmas ppl
-
RE: QApplicationPrivate::notify_helper crash
@leo said in strawberry version 1.2.2 crashing:
ii libqt6widgets6:amd64 6.7.2+dfsg-4 amd64 Qt 6 widgets module
Hmm Qt 6.7
I use here on ubuntu 24.10 Qt 6.6.2When I have time will try compiling here strawberry against 6.7.2, to see if there are any issues.
Meanwhile keep us informed of anything
tks
-
RE: QApplicationPrivate::notify_helper crash
Hi Leo,
The issue appears to be a segmentation fault caused by the premature deletion of an object, likely within the Qt6 event handling system. Jonas is correct that the backtrace doesn't clearly indicate the exact problem, and we need to take some steps to diagnose and potentially resolve the issue:
-
Gather More Information
Crash Timing: Does the crash occur during specific actions (e.g., changing songs, idle state, playlist interactions)?
Playback Context: Are there any specific file types or codecs involved when the crash happens?
Reproducibility: Can you reliably reproduce the crash? If yes, describe the steps. -
System and Package Details
You mentioned you are using the Liquorix kernel. Did you install Strawberry from a package (e.g., a Debian/Ubuntu .deb) or build it from source? If from a package, specify its source.
Check for library mismatches:
Run
ldd $(which strawberry)
(to see if any library paths point to unexpected or mismatched versions)
- Check Dependencies
Ensure that all the required dependencies, particularly libQt6Core and libQt6Widgets, are consistent with the Strawberry version. Use:
dpkg -l | grep qt6
(to ensure they match the versions expected by Strawberry 1.2.2)
Workaround Suggestions
Switch to a Stable Kernel: Since you're on Liquorix, consider trying the default kernel of your distribution to rule out kernel-specific issues.
Downgrade Strawberry: Temporarily revert to the previous version if stability is critical while investigating further:sudo apt install strawberry=1.2.1
-
-
RE: Reintegrate projectM Visualizer
@jonas I would not say that I completely gave up, but I just started a new position in a company so I lost that whole free time to mess with this particular thing
I went making https://github.com/guprobr/WakkaQt instead to learn a bit more Qt before resuming this task
The last ideas we discussed, I never tried... but the last post on projectM made me feel second toughts on the viability of the idea.... anyway, i want to resume this task someday I don't think we should give up but certainly something is missing in the backend inner parts of how Qt works with OpenGL and how projectM works with OpenGL, as it was discussed on the thread on github.But the first thing i would do is trying with latest Qt LTS, before anything.
Second thing, to try with the same version on Windows!
We have to figure where the problem is. Obviously its a Qt issue, but what made me stop working on it was when SDL window version showed the same issues. That was very disappointing.PS: sorry to take so long to answer, I just saw this today
-
Notable Improvement in Memory Management
Lately I have noticed a much better memory management in the program as a whole. I'm used to long hours even days with a same session opened, and I can assure, not in a objective way, but by actually noticing, that memory consumption and management has improved big time.
- Use own thread for lyrics parsing -> this surely fixed something regarding to that
I don't remember other commits, but the cover/context ones surely made a huge benefit.
So here's my cheers for that, we don't need to post just trouble here but its good to recognize when things improve, its a lot of effort from Jonas to keep this a stable project with so many features to deal with at the same time. Strawberry RuleS!
-
WakkaQt - a Karaoke recorder written in C++ and Qt6
This software is currently in Alpha stage for developers to test. Help requested: for Windows and MacOS tests. NOTE: gStreamer is mandatory on all platforms.
WakkaQt - Karaoke App
WakkaQt is a karaoke application built with C++ and Qt6, designed to record vocals over a video/audio track and mix them into a rendered file.
This app features webcam recording, YouTube video downloading, real-time sound visualization, and post-recording video rendering with FFmpeg, also it uses an open-source Auto Tune algorithm called XC42, by Gareus, featuring automatic masterization of the final track with noise reduction, normalization, compression, etc.
You can adjust the volume of the vocals before rendering and you can render how many times you want until you are satisfied with the final mix.It records audio only too, but a webcam is still mandatory.
You can use different input audio sources than the webcam, but I still need to program a method to choose different webcams, if the user had multiple webcams.
In the future I believe I'm going to improve masterization, autotune and add some optional effects to audio and video.
Also intend to improve the sync method of video, vocals and playback, I'm not satisfied with it since I could not test in several different platforms. as a far feature I intend to use FFMpeg not as an external process, but via libav, programmed in an integrated right into the APP, instead of calling a sub-process. Same wish here with youtube downloader, which is also an external program. (yt-dlp)Its pretty easy to use, follow the instructions onscreen basically.
- if you want to download a karaoke playback from YouTube, just paste the URL and press FETCH
- When a playback is loaded, Qt6 will preview the video and the SING button becomes available.
- This will force you into a dialog to choose the correct audio input source for the session and after that, recording starts, indicated by the RED circle.
- Anytime, when you're done, just press FINISH and you will be prompted to preview the vocals-only, without any effect.
- In this dialog you are able to adjust the volume for the final mix.
- By clicking render, ffmpeg is invoked
and the coolest progress bar ever made on earthwill indicate FFMpeg render progress! YEAH! - and after rendering it will preview the final mix; you can RENDER AGAIN by pressing the button, if you are not satisfied with the volume adjustment. You can adjust to 0 - 100% and up to 500%; less than 100% reduces volume while values higher than 100% amplifies.
And now i'm very sorry for posting this, but i must show an example lol
god have mercy
tks guyslink text
https://gu.pro.br/seven/Requirements
To build and run this application, ensure you have the following:
C++17 or later
Qt6 (Qt Multimedia module)
FFmpeg binary (for video/audio mixing and rendering)
yt-dlp binary (for downloading YouTube videos)
gStreamer is necessary for the vocals-preview dialogInstall LV2 plugin for AutoTune
https://x42-plugins.com/x42/x42-autotuneThank you for having FUN!
https://github.com/guprobr/WakkaQt
-
RE: Strawberry & Easytag
@ashley194 said in Strawberry & Easytag:
a day ago
Hi all, First off, I'm running Debian 12.6 "Bookworm" KDE DE.
In Strawberry, every time I select 'Show in file browser' in the context menu it opens up Easytag instead of the Dolphin file manager!
Open a terminal.
Executexdg-open .
to see if it opens Dolphin. If not, you might need to fix the association. Sometimes xdg-open might be pointing to the wrong application. If xdg-open is opening files with the wrong application, you can fix this by adjusting your MIME type associations or setting the correct default application for handling specific types of files.
EXAMPLES
For Directories (typically handled by file managers like Dolphin):
xdg-mime default dolphin.desktop inode/directory
or, i.e. For Text Files:
xdg-mime default kate.desktop text/plain
or, For PDF Files:
xdg-mime default okular.desktop application/pdf
the query mistekko sent is very useful to debug which default application is set for opening folders, which is the case. The first command I sent is useful to actually test if the problem lies in Strawberry or system-wide.
-
RE: What Do You Listen To?
Hey guys nice topic! I'm very ecletic, but usually listen to rock and roll, oldies, br popular music (MPB) and electronic like kraftwerk or Jean Michel Jarre. Also like strokes, libertines, strawbs, well, as I said I'm quite ecletic. This includes even Shakira or Kylie Minogue lol
I've recently published my own instrumental songs (as GUSTAVO L CONTE) on Qobuz, tidal, spotify, YT, apple, etc, that I make on Linux with Renoise tracker. When the process finishes there will be about seven EPs available!
I'm an enthuasiast, but some songs have its moments lol
please give a peek if you can
tks!! ! -
RE: Reintegrate projectM Visualizer
I finally understood the mystery of why size_t is accidentally working in ConsumeBuffer: all my FLACs are S24LE, I just tested now one of my own songs which are S16LE and the correct int16 aapproach works for detecting and interacting audio with visuals! Therefore Im trying now to make a ConsumeBuffer with lasers to determine automatically the format and width: (but no luck making S24LE to work)
#include <QtCore/QtEndian> void VisualizationSDL2::ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format) { Q_UNUSED(pipeline_id); GstMapInfo map; gst_buffer_map(buffer, &map, GST_MAP_READ); if (projectm_instance_) { unsigned int sample_count = 0; const int16_t *int16_data = nullptr; const float *float_data = nullptr; if (format == QStringLiteral("S16LE") || format == QStringLiteral("S16BE")) { sample_count = map.size / sizeof(int16_t) / 2; int16_data = reinterpret_cast<const int16_t *>(map.data); if (format == QStringLiteral("S16BE")) { // Convert big-endian to little-endian if necessary std::vector<int16_t> temp_data(sample_count * 2); for (unsigned int i = 0; i < sample_count * 2; ++i) { temp_data[i] = qFromBigEndian(int16_data[i]); } int16_data = temp_data.data(); } projectm_pcm_add_int16(projectm_instance_, int16_data, sample_count, PROJECTM_STEREO); } else if (format == QStringLiteral("F32LE") || format == QStringLiteral("F32BE")) { sample_count = map.size / sizeof(float) / 2; float_data = reinterpret_cast<const float *>(map.data); if (format == QStringLiteral("F32BE")) { // Convert big-endian to little-endian if necessary std::vector<float> temp_data(sample_count * 2); for (unsigned int i = 0; i < sample_count * 2; ++i) { temp_data[i] = qFromBigEndian(float_data[i]); } float_data = temp_data.data(); } projectm_pcm_add_float(projectm_instance_, float_data, sample_count, PROJECTM_STEREO); } else if (format == QStringLiteral("S24LE")) { // Handle 24-bit audio (3 bytes per sample) sample_count = map.size / 3 / 2; std::vector<int16_t> int16_samples(sample_count * 2); for (unsigned int i = 0; i < sample_count * 2; ++i) { int16_samples[i] = static_cast<int16_t>((map.data[i * 3 + 2] << 8) | map.data[i * 3 + 1]); } projectm_pcm_add_int16(projectm_instance_, int16_samples.data(), sample_count, PROJECTM_STEREO); } gst_buffer_unmap(buffer, &map); } gst_buffer_unref(buffer); }
-
RE: strawberry playlist filtering is malfunctioning
@roman I think its better to confirm what I'm saying, but perphaps the search looks for the metadata, not the filename?
-
RE: Reintegrate projectM Visualizer
I'm trying lotsa stuff, using FBO and OpenGLWindow, changing profiles (between versions and compatibility/core), I even made an SDL2 window version. Every time I implement a different way, All result are the same: some presets working and the same majority not working.
But now I've tried bypassing the normal way presets are loaded, and only use this, i.e.
projectm_playlist_add_path(projectm_playlist_instance_, "/home/guzpido/presets-cream-of-the-crop", true, true);
it appears to make a bit more presets to work. this could be a clue. Maybe the way we are loading presets has some issue; but I've banging my head to figure it out if this makes even sense.
edit: also i cant determine if ConsumeBuffer is working
-
RE: Reintegrate projectM Visualizer
VisualizationContainer::VisualizationContainer(QWidget *parent) : QMainWindow(parent), projectm_visualization_(new ProjectMVisualization(this)), overlay_(new VisualizationOverlay), selector_(new VisualizationSelector(this)), overlay_proxy_(nullptr), engine_(nullptr), menu_(new QMenu(this)), fps_(kDefaultFps), size_(kDefaultTextureSize) { setWindowTitle(tr("Visualizations")); setWindowIcon(IconLoader::Load(QStringLiteral("strawberry"))); setMinimumSize(64, 64); { Settings s; s.beginGroup(QLatin1String(kSettingsGroup)); if (!restoreGeometry(s.value("geometry").toByteArray())) { resize(kDefaultWidth, kDefaultHeight); } fps_ = s.value("fps", kDefaultFps).toInt(); size_ = s.value("size", kDefaultTextureSize).toInt(); s.endGroup(); } QShortcut *close = new QShortcut(QKeySequence::Close, this); QObject::connect(close, &QShortcut::activated, this, &VisualizationContainer::close); QObject::connect(overlay_, &VisualizationOverlay::OpacityChanged, this, &VisualizationContainer::ChangeOverlayOpacity); QObject::connect(overlay_, &VisualizationOverlay::ShowPopupMenu, this, &VisualizationContainer::ShowPopupMenu); ChangeOverlayOpacity(1.0); projectm_visualization_->SetTextureSize(size_); SizeChanged(); selector_->SetVisualization(projectm_visualization_); menu_->addAction(IconLoader::Load(QStringLiteral("view-fullscreen")), tr("Toggle fullscreen"), this, &VisualizationContainer::ToggleFullscreen); QMenu *fps_menu = menu_->addMenu(tr("Framerate")); QActionGroup *fps_group = new QActionGroup(this); AddFramerateMenuItem(tr("Low (%1 fps)").arg(kLowFramerate), kLowFramerate, fps_, fps_group); AddFramerateMenuItem(tr("Medium (%1 fps)").arg(kMediumFramerate), kMediumFramerate, fps_, fps_group); AddFramerateMenuItem(tr("High (%1 fps)").arg(kHighFramerate), kHighFramerate, fps_, fps_group); AddFramerateMenuItem(tr("Super high (%1 fps)").arg(kSuperHighFramerate), kSuperHighFramerate, fps_, fps_group); fps_menu->addActions(fps_group->actions()); QMenu *quality_menu = menu_->addMenu(tr("Quality", "Visualization quality")); QActionGroup *quality_group = new QActionGroup(this); AddQualityMenuItem(tr("Low (256x256)"), 256, size_, quality_group); AddQualityMenuItem(tr("Medium (512x512)"), 512, size_, quality_group); AddQualityMenuItem(tr("High (1024x1024)"), 1024, size_, quality_group); AddQualityMenuItem(tr("Super high (2048x2048)"), 2048, size_, quality_group); quality_menu->addActions(quality_group->actions()); menu_->addAction(tr("Select visualizations..."), selector_, &VisualizationContainer::show); menu_->addSeparator(); menu_->addAction(IconLoader::Load(QStringLiteral("application-exit")), tr("Close visualization"), this, &VisualizationContainer::hide); // OpenGL // Create and configure the QSurfaceFormat QSurfaceFormat format; format.setVersion(3, 3); // Set OpenGL version to 3.3 format.setProfile(QSurfaceFormat::CoreProfile); // Use the core profile format.setDepthBufferSize(24); format.setStencilBufferSize(8); // Initialize the primary OpenGL context QOpenGLContext *openGLContext = new QOpenGLContext(this); openGLContext->setFormat(format); if (!openGLContext->create()) { qWarning() << "Failed to create OpenGL context"; } else { qDebug() << "OpenGL context created successfully"; } // Create a new shared context QOpenGLContext *sharedContext = new QOpenGLContext(this); sharedContext->setFormat(format); if (!sharedContext->create()) { qWarning() << "Failed to create shared OpenGL context"; } else { qDebug() << "Shared OpenGL context created successfully"; } // Set the shared context openGLContext->setShareContext(sharedContext); // Create the OpenGL window using the primary OpenGL context openGLWindow_ = new VisualizationOpenGLWidget(projectm_visualization_, openGLContext); openGLWindow_->setFormat(format); // Make the OpenGL context current if (!openGLContext->makeCurrent(openGLWindow_)) { qWarning() << "Failed to make OpenGL context current"; } // Wrap the QOpenGLWindow in a QWidget container glContainer = QWidget::createWindowContainer(openGLWindow_); glContainer->setFocusPolicy(Qt::TabFocus); glContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); glContainer->setParent(this); glContainer->setVisible(true); setCentralWidget(glContainer); projectm_visualization_->Resize(width(), height()); // Add the overlay as a child of the container and set its visibility overlay_->setParent(glContainer); overlay_->resize(glContainer->size()); // Resize the overlay to match the container size overlay_->setVisible(true); overlay_->raise(); }
#ifndef VISUALIZATIONOPENGLWIDGET_H #define VISUALIZATIONOPENGLWIDGET_H #include "config.h" #include <QOpenGLWindow> #include <QOpenGLFunctions> class ProjectMVisualization; class VisualizationOpenGLWidget : public QOpenGLWindow, protected QOpenGLFunctions { Q_OBJECT public: explicit VisualizationOpenGLWidget(ProjectMVisualization* projectm_visualization, QOpenGLContext* sharedContext, QWindow* parent = nullptr); void initializeGL() override; protected: void paintGL() override; void resizeGL(int width, int height) override; private: void Setup(int width, int height); ProjectMVisualization* projectm_visualization_; QOpenGLContext* sharedContext_; }; #endif // VISUALIZATIONOPENGLWIDGET_H
#include "config.h" #include <QPainter> #include "core/logging.h" #include "visualizationopenglwidget.h" #include "projectmvisualization.h" VisualizationOpenGLWidget::VisualizationOpenGLWidget(ProjectMVisualization* projectm_visualization, QOpenGLContext* sharedContext, QWindow* parent) : QOpenGLWindow(NoPartialUpdate, parent), projectm_visualization_(projectm_visualization), sharedContext_(sharedContext) { setFormat(sharedContext_->format()); } void VisualizationOpenGLWidget::initializeGL() { QOpenGLWindow::initializeGL(); sharedContext_->makeCurrent(this); initializeOpenGLFunctions(); projectm_visualization_->Init(); } void VisualizationOpenGLWidget::paintGL() { sharedContext_->makeCurrent(this); QPainter p(this); p.beginNativePainting(); if (projectm_visualization_) { Setup(width(), height()); projectm_visualization_->RenderFrame(width(), height()); } update(); p.endNativePainting(); GLenum error = glGetError(); if (error != GL_NO_ERROR) { qWarning() << "OpenGL error in paintGL:" << error; } qLog(Debug) << __PRETTY_FUNCTION__ << "Completed"; } void VisualizationOpenGLWidget::resizeGL(int width, int height) { sharedContext_->makeCurrent(this); Setup(width, height); projectm_visualization_->Resize(width, height); GLenum error = glGetError(); if (error != GL_NO_ERROR) { qWarning() << "OpenGL error in resizeGL:" << error; } } void VisualizationOpenGLWidget::Setup(int width, int height) { // Ensure the correct OpenGL context is current if (!sharedContext_->makeCurrent(this)) { qWarning() << "Failed to make OpenGL context current in Setup"; return; } // Initialize OpenGL functions initializeOpenGLFunctions(); // Set up OpenGL state glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 0); glViewport(0, 0, width, height); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, height, 0, -1, 1); // Set an orthographic projection matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glClearColor(0.0F, 0.0F, 0.0F, 0.0F); glLineStipple(2, 0xAAAA); GLenum error = glGetError(); if (error != GL_NO_ERROR) { qWarning() << "OpenGL error in Setup:" << error; } }
-
RE: Reintegrate projectM Visualizer
void VisualizationOpenGLWidget::paintGL() { QPainter p(this); p.beginNativePainting(); int w = width(); int h = height(); this->resize(w*2,h*2); if (projectm_visualization_) { projectm_visualization_->Resize(w*2, h*2); projectm_visualization_->RenderFrame(w*2,h*2); } update(); this->resize(w,h); if (projectm_visualization_) { projectm_visualization_->Resize(w, h); projectm_visualization_->RenderFrame(w,h); } update(); p.endNativePainting(); qLog(Debug) << __PRETTY_FUNCTION__ << glGetError(); }
Its disgusting, but it really makes a HUGE percentage of presets to display instead of black screen.
Ive done this without wraping the openglwindow into a widget;
when you resize the window, it displays, several plugins happens that way.. actually the nicer ones like this one: -
RE: Reintegrate projectM Visualizer
this version I posted works MUCH better giving nice results with the cream-of-cream presets,
-
RE: Reintegrate projectM Visualizer
I'm probably NOT the founder of the I.O.G.L.N.U.S.A.H.A.
Tthe International Open GL NEVER Ugonna SLEEP AGAIN ha ha ha Society.
Decided to go ahead and do the QOpenGLWindow on Strawberry.
Its worse than just the standalone program. Much more bugs. But the few that works are incredible. We are close. Here's what I've been messing around with my IogLnusaha association (I'm on Gnomes)
// Create and setup the QOpenGLWindow auto *openGLWindow_ = new VisualizationOpenGLWidget(projectm_visualization_); QSurfaceFormat format; format.setVersion(3, 3); // Set OpenGL version to 3.3 format.setProfile(QSurfaceFormat::CoreProfile); // Use the core profile format.setDepthBufferSize(24); format.setStencilBufferSize(8); openGLWindow_->setFormat(format); openGLWindow_->resize(1280, 720); // Default size for the OpenGL window // Wrap the QOpenGLWindow in a QWidget container auto *glContainer = QWidget::createWindowContainer(openGLWindow_); glContainer->setFocusPolicy(Qt::TabFocus); glContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); glContainer->setParent(this); glContainer->setVisible(true); ////////////setCentralWidget(glContainer); // Add the overlay as a child of the container and set its visibility ////////////////overlay_->setParent(glContainer); /////////////////overlay_->resize(320, 200); // Resize the overlay //////////////////overlay_->setVisible(true); }
#ifndef VISUALIZATIONOPENGLWIDGET_H #define VISUALIZATIONOPENGLWIDGET_H #include "config.h" #include <QOpenGLWindow> #include <QOpenGLFunctions> class ProjectMVisualization; class VisualizationOpenGLWidget : public QOpenGLWindow, protected QOpenGLFunctions { Q_OBJECT public: explicit VisualizationOpenGLWidget(ProjectMVisualization* projectm_visualization, QWindow* parent = nullptr); //explicit VisualizationOpenGLWidget(ProjectMVisualization *projectm_visualization, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); //explicit OpenGLWidgetContainer(QOpenGLWindow* openGLWindow, QWidget* parent = nullptr); void initializeGL() override; protected: void paintGL() override; void resizeGL(const int width, const int height) override; private: void Setup(const int width, const int height); private: ProjectMVisualization *projectm_visualization_; }; #endif // VISUALIZATIONOPENGLWIDGET_H
.cpp
#include "config.h" #include <QPainter> #include "core/logging.h" #include "visualizationopenglwidget.h" #include "projectmvisualization.h" VisualizationOpenGLWidget::VisualizationOpenGLWidget(ProjectMVisualization *projectm_visualization, QWindow *parent) : QOpenGLWindow(NoPartialUpdate, parent), projectm_visualization_(projectm_visualization) { } void VisualizationOpenGLWidget::initializeGL() { QOpenGLWindow::initializeGL(); QOpenGLFunctions::initializeOpenGLFunctions(); projectm_visualization_->Init(); } void VisualizationOpenGLWidget::paintGL() { QPainter p(this); //////////resizeGL(width(), height()); p.beginNativePainting(); projectm_visualization_->RenderFrame(width(), height()); p.endNativePainting(); update(); qLog(Debug) << __PRETTY_FUNCTION__ << glGetError(); } void VisualizationOpenGLWidget::resizeGL(const int width, const int height) { Setup(width, height); projectm_visualization_->Resize(width, height); } void VisualizationOpenGLWidget::Setup(const int width, const int height) { glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 0); glViewport(0, 0, width, height); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glClearColor(0.0F, 0.0F, 0.0F, 0.0F); glLineStipple(2, 0xAAAA); }
ConsumeBuffer:
void ProjectMVisualization::ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &format) { Q_UNUSED(pipeline_id); Q_UNUSED(format); GstMapInfo map; gst_buffer_map(buffer, &map, GST_MAP_READ); #ifdef HAVE_PROJECTM4 if (projectm_instance_) { const unsigned int samples_per_channel = static_cast<unsigned int> (map.size / sizeof(size_t)) / 2; const int16_t *data = reinterpret_cast<int16_t*>(map.data); projectm_pcm_add_int16(projectm_instance_, data, samples_per_channel, PROJECTM_STEREO); } #else if (projectm_) { const short samples_per_channel = static_cast<short>(map.size) / sizeof(short) / 2; const short *data = reinterpret_cast<short*>(map.data); projectm_->pcm()->addPCM16Data(data, samples_per_channel); } #endif // HAVE_PROJECTM4 gst_buffer_unmap(buffer, &map); gst_buffer_unref(buffer); }
InitprojectM
// Create projectM settings #ifdef HAVE_PROJECTM4 Q_ASSERT(projectm_instance_ == nullptr); Q_ASSERT(projectm_playlist_instance_ == nullptr); projectm_instance_ = projectm_create(); projectm_set_preset_duration(projectm_instance_, duration_); // Set initial window size projectm_set_window_size(projectm_instance_, 1280, 720); // Additional ProjectM setup projectm_set_mesh_size(projectm_instance_, 32, 24); projectm_set_fps(projectm_instance_, 60); projectm_set_aspect_correction(projectm_instance_, true); projectm_set_hard_cut_enabled(projectm_instance_, true); projectm_set_hard_cut_duration(projectm_instance_, 10); projectm_set_hard_cut_sensitivity(projectm_instance_, 1.0); projectm_set_beat_sensitivity(projectm_instance_, 0.5); projectm_set_soft_cut_duration(projectm_instance_, 10); //projectm_set_window_size(projectm_instance_, 512, 512); const char *texture_search_paths[] = { "/usr/local/share/projectM/textures" }; projectm_set_texture_search_paths(projectm_instance_, texture_search_paths, 1); projectm_playlist_instance_ = projectm_playlist_create(projectm_instance_); projectm_playlist_set_shuffle(projectm_playlist_instance_, false);
"patched" SetImmediatePreset (FOR TESTING, but works on v3) void ProjectMVisualization::SetImmediatePreset(const int index) { #ifdef HAVE_PROJECTM4 if (projectm_playlist_instance_) { projectm_playlist_set_position(projectm_playlist_instance_, index, true); /* projectm_playlist_play_previous(projectm_playlist_instance_, true); projectm_set_preset_duration(projectm_instance_, 1); projectm_set_preset_locked(projectm_instance_, false); QTimer::singleShot(1500, this, [index,this]() { projectm_set_preset_locked(projectm_instance_, true); projectm_set_preset_duration(projectm_instance_, duration_); }); */ } #else if (projectm_) { projectm_->selectPreset(index, true); } #endif // HAVE_PROJECTM4 }
It appears that when it wraps to a QWidget, the shader codes don't like and start to stop doing its things. ITs not a matter of context, but its like a corruption happens when you wrap.
I could manage to bind key_S to open the visualizations selector, when setting as central, because I could not figure out why the overlay and interface don't work