<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Reintegrate projectM Visualizer]]></title><description><![CDATA[<p dir="auto">Hi,</p>
<p dir="auto">I'm a maintainer of the projectM visualizer library. We've been working on making projectM better in many ways over the past two years or so, and finally released a new major version (4.0) back in April '23. This new version fixed a few bugs and improved the rendering quality, but was mainly focused on rewriting the build system (now only using CMake) and creating a proper API. libprojectM now supports building as a shared library on all platforms, and has a stable and clean C API instead of requiring direct access to the internal C++ code, which was a big issue for devs in all previous releases.</p>
<p dir="auto">Clementine used a forked copy of a very old projectM version, which was never updated and had numerous bugs and performance issues, so removing it from Strawberry was surely a good thing. Yet I think many users would like to have a visualizer again, and with the upcoming 4.1 release projectM will be (mostly) compatible with the latest Milkdrop release, support previously unimplemented preset features like loops and megabuf.</p>
<p dir="auto">The API won't change between 4.0 and 4.1, so if anyone has time to integrate it into Strawberry, you may start right away. If there are any questions, head over to <a href="https://discord.gg/mMrxAqaa3W" rel="nofollow ugc">our Discord</a> or post in our GitHub <a href="https://github.com/orgs/projectM-visualizer/discussions" rel="nofollow ugc">discussion board</a>, I'll be notified there. I try to check this forum from time to time, but expect longer delays here.</p>
]]></description><link>https://forum.strawberrymusicplayer.org/topic/1286/reintegrate-projectm-visualizer</link><generator>RSS for Node</generator><lastBuildDate>Sun, 14 Jun 2026 20:10:55 GMT</lastBuildDate><atom:link href="https://forum.strawberrymusicplayer.org/topic/1286.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 06 Sep 2023 10:35:53 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 04 Dec 2024 18:00:35 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/1">@jonas</a> 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</p>
<p dir="auto">I went making <a href="https://github.com/guprobr/WakkaQt" rel="nofollow ugc">https://github.com/guprobr/WakkaQt</a> instead to learn a bit more Qt before resuming this task<br />
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.</p>
<p dir="auto">But the first thing i would do is trying with latest Qt LTS, before anything.<br />
Second thing, to try with the same version on Windows!<br />
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.</p>
<p dir="auto">PS: sorry to take so long to answer, I just saw this today</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/7574</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/7574</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 04 Dec 2024 18:00:35 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Sat, 23 Nov 2024 16:28:07 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/2454">@Gustavo-L-Conte</a><br />
Are you still working on the projectM integration, or did you give it up?</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/7496</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/7496</guid><dc:creator><![CDATA[jonas]]></dc:creator><pubDate>Sat, 23 Nov 2024 16:28:07 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Sat, 10 Aug 2024 15:58:27 GMT]]></title><description><![CDATA[<p dir="auto">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)</p>
<pre><code>#include &lt;QtCore/QtEndian&gt;

void VisualizationSDL2::ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &amp;format) {
    Q_UNUSED(pipeline_id);

    GstMapInfo map;
    gst_buffer_map(buffer, &amp;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&lt;const int16_t *&gt;(map.data);
            if (format == QStringLiteral("S16BE")) {
                // Convert big-endian to little-endian if necessary
                std::vector&lt;int16_t&gt; temp_data(sample_count * 2);
                for (unsigned int i = 0; i &lt; 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&lt;const float *&gt;(map.data);
            if (format == QStringLiteral("F32BE")) {
                // Convert big-endian to little-endian if necessary
                std::vector&lt;float&gt; temp_data(sample_count * 2);
                for (unsigned int i = 0; i &lt; 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&lt;int16_t&gt; int16_samples(sample_count * 2);
            for (unsigned int i = 0; i &lt; sample_count * 2; ++i) {
                int16_samples[i] = static_cast&lt;int16_t&gt;((map.data[i * 3 + 2] &lt;&lt; 8) | map.data[i * 3 + 1]);
            }
            projectm_pcm_add_int16(projectm_instance_, int16_samples.data(), sample_count, PROJECTM_STEREO);
        }

        gst_buffer_unmap(buffer, &amp;map);
    }

    gst_buffer_unref(buffer);
}
</code></pre>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4598</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4598</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Sat, 10 Aug 2024 15:58:27 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Sun, 04 Aug 2024 04:39:18 GMT]]></title><description><![CDATA[<p dir="auto">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.</p>
<p dir="auto">But now I've tried bypassing the normal way presets are loaded, and only use this, i.e.</p>
<pre><code>projectm_playlist_add_path(projectm_playlist_instance_, "/home/guzpido/presets-cream-of-the-crop", true, true);
</code></pre>
<p dir="auto">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.</p>
<p dir="auto"><img src="/assets/uploads/files/1722746242081-screenshot-from-2024-08-04-01-37-12.png" alt="Screenshot from 2024-08-04 01-37-12.png" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1722746262720-screenshot-from-2024-08-04-01-33-11.png" alt="Screenshot from 2024-08-04 01-33-11.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">edit: also i cant determine if ConsumeBuffer is working</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4492</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4492</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Sun, 04 Aug 2024 04:39:18 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Fri, 02 Aug 2024 20:49:21 GMT]]></title><description><![CDATA[<p dir="auto"><a href="https://forum.qt.io/topic/155554/error-code-1282-when-using-opengl-functions-in-qopenglwindow/2" rel="nofollow ugc">https://forum.qt.io/topic/155554/error-code-1282-when-using-opengl-functions-in-qopenglwindow/2</a></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4472</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4472</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Fri, 02 Aug 2024 20:49:21 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Thu, 25 Jul 2024 17:20:41 GMT]]></title><description><![CDATA[<pre><code>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, &amp;QShortcut::activated, this, &amp;VisualizationContainer::close);

    QObject::connect(overlay_, &amp;VisualizationOverlay::OpacityChanged, this, &amp;VisualizationContainer::ChangeOverlayOpacity);
    QObject::connect(overlay_, &amp;VisualizationOverlay::ShowPopupMenu, this, &amp;VisualizationContainer::ShowPopupMenu);
    ChangeOverlayOpacity(1.0);

    projectm_visualization_-&gt;SetTextureSize(size_);
    SizeChanged();

    selector_-&gt;SetVisualization(projectm_visualization_);

    menu_-&gt;addAction(IconLoader::Load(QStringLiteral("view-fullscreen")), tr("Toggle fullscreen"), this, &amp;VisualizationContainer::ToggleFullscreen);

    QMenu *fps_menu = menu_-&gt;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-&gt;addActions(fps_group-&gt;actions());

    QMenu *quality_menu = menu_-&gt;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-&gt;addActions(quality_group-&gt;actions());

    menu_-&gt;addAction(tr("Select visualizations..."), selector_, &amp;VisualizationContainer::show);
    menu_-&gt;addSeparator();
    menu_-&gt;addAction(IconLoader::Load(QStringLiteral("application-exit")), tr("Close visualization"), this, &amp;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-&gt;setFormat(format);

    if (!openGLContext-&gt;create()) {
        qWarning() &lt;&lt; "Failed to create OpenGL context";
    } else {
        qDebug() &lt;&lt; "OpenGL context created successfully";
    }

    // Create a new shared context
    QOpenGLContext *sharedContext = new QOpenGLContext(this);
    sharedContext-&gt;setFormat(format);

    if (!sharedContext-&gt;create()) {
        qWarning() &lt;&lt; "Failed to create shared OpenGL context";
    } else {
        qDebug() &lt;&lt; "Shared OpenGL context created successfully";
    }

    // Set the shared context
    openGLContext-&gt;setShareContext(sharedContext);

    // Create the OpenGL window using the primary OpenGL context
    openGLWindow_ = new VisualizationOpenGLWidget(projectm_visualization_, openGLContext);
    openGLWindow_-&gt;setFormat(format);

    // Make the OpenGL context current
    if (!openGLContext-&gt;makeCurrent(openGLWindow_)) {
        qWarning() &lt;&lt; "Failed to make OpenGL context current";
    }

    // Wrap the QOpenGLWindow in a QWidget container
    glContainer = QWidget::createWindowContainer(openGLWindow_);
    glContainer-&gt;setFocusPolicy(Qt::TabFocus);
    glContainer-&gt;setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    glContainer-&gt;setParent(this);
    glContainer-&gt;setVisible(true);
    setCentralWidget(glContainer);
    projectm_visualization_-&gt;Resize(width(), height());

    // Add the overlay as a child of the container and set its visibility
    overlay_-&gt;setParent(glContainer);
    overlay_-&gt;resize(glContainer-&gt;size());  // Resize the overlay to match the container size
    overlay_-&gt;setVisible(true);
    overlay_-&gt;raise();
}
</code></pre>
<pre><code>#ifndef VISUALIZATIONOPENGLWIDGET_H
#define VISUALIZATIONOPENGLWIDGET_H

#include "config.h"

#include &lt;QOpenGLWindow&gt;
#include &lt;QOpenGLFunctions&gt;

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
</code></pre>
<pre><code>#include "config.h"

#include &lt;QPainter&gt;

#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_-&gt;format());
}

void VisualizationOpenGLWidget::initializeGL() {
    QOpenGLWindow::initializeGL();
    sharedContext_-&gt;makeCurrent(this);
    initializeOpenGLFunctions();
    projectm_visualization_-&gt;Init();
}

void VisualizationOpenGLWidget::paintGL() {
    sharedContext_-&gt;makeCurrent(this);

    QPainter p(this);
    p.beginNativePainting();
    
    if (projectm_visualization_) {
        Setup(width(), height());
        projectm_visualization_-&gt;RenderFrame(width(), height());
    }
    
    update();

    p.endNativePainting();

    GLenum error = glGetError();
    if (error != GL_NO_ERROR) {
        qWarning() &lt;&lt; "OpenGL error in paintGL:" &lt;&lt; error;
    }

    qLog(Debug) &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; "Completed";
}

void VisualizationOpenGLWidget::resizeGL(int width, int height) {
    sharedContext_-&gt;makeCurrent(this);

    Setup(width, height);
    projectm_visualization_-&gt;Resize(width, height);

    GLenum error = glGetError();
    if (error != GL_NO_ERROR) {
        qWarning() &lt;&lt; "OpenGL error in resizeGL:" &lt;&lt; error;
    }
}

void VisualizationOpenGLWidget::Setup(int width, int height) {
    // Ensure the correct OpenGL context is current
    if (!sharedContext_-&gt;makeCurrent(this)) {
        qWarning() &lt;&lt; "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() &lt;&lt; "OpenGL error in Setup:" &lt;&lt; error;
    }
}
</code></pre>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4355</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4355</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Thu, 25 Jul 2024 17:20:41 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Thu, 25 Jul 2024 12:45:14 GMT]]></title><description><![CDATA[<pre><code>void VisualizationOpenGLWidget::paintGL() {

  QPainter p(this);
  p.beginNativePainting();
  
  int w = width(); int h = height();
  this-&gt;resize(w*2,h*2);
  if (projectm_visualization_) {
    projectm_visualization_-&gt;Resize(w*2, h*2);
    projectm_visualization_-&gt;RenderFrame(w*2,h*2);
  }
  update();
  this-&gt;resize(w,h);
  if (projectm_visualization_) {
    projectm_visualization_-&gt;Resize(w, h);
    projectm_visualization_-&gt;RenderFrame(w,h);
  }
  update();

   p.endNativePainting();

  qLog(Debug) &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; glGetError();

}
</code></pre>
<p dir="auto">Its disgusting, but it really makes a HUGE percentage of presets to display instead of black screen.<br />
Ive done this without wraping the openglwindow into a widget;<br />
when you resize the window, it displays, several plugins happens that way.. actually the nicer ones like this one:</p>
<p dir="auto"><img src="https://forum.strawberrymusicplayer.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61e.png?v=faqqna7874c" class="not-responsive emoji emoji-android emoji--disappointed" style="height:23px;width:auto;vertical-align:middle" title=":(" alt="😞" /></p>
<p dir="auto"><img src="/assets/uploads/files/1721911500478-screenshot-from-2024-07-25-09-44-48.png" alt="Screenshot from 2024-07-25 09-44-48.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4348</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4348</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Thu, 25 Jul 2024 12:45:14 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Thu, 25 Jul 2024 08:35:28 GMT]]></title><description><![CDATA[<p dir="auto">this version I posted works MUCH better giving nice results with the cream-of-cream presets,<img src="/assets/uploads/files/1721896489949-screenshot-from-2024-07-25-05-32-42.png" alt="Screenshot from 2024-07-25 05-32-42.png" class=" img-fluid img-markdown" /> <img src="/assets/uploads/files/1721896495672-screenshot-from-2024-07-25-05-31-24.png" alt="Screenshot from 2024-07-25 05-31-24.png" class=" img-fluid img-markdown" /> <img src="/assets/uploads/files/1721896503976-screenshot-from-2024-07-25-05-17-39.png" alt="Screenshot from 2024-07-25 05-17-39.png" class=" img-fluid img-markdown" /> <img src="/assets/uploads/files/1721896512386-screenshot-from-2024-07-25-05-08-09.png" alt="Screenshot from 2024-07-25 05-08-09.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4344</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4344</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Thu, 25 Jul 2024 08:35:28 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Thu, 25 Jul 2024 09:22:47 GMT]]></title><description><![CDATA[<p dir="auto">I'm probably NOT the founder of the  <strong>I.O.G.L.N.U.S.A.H.A.</strong></p>
<p dir="auto">Tthe International Open GL NEVER Ugonna SLEEP AGAIN ha ha ha Society.</p>
<p dir="auto">Decided to go ahead and do the QOpenGLWindow on Strawberry.</p>
<p dir="auto"><img src="/assets/uploads/files/1721892297049-screenshot-from-2024-07-25-04-18-33-resized.png" alt="Screenshot from 2024-07-25 04-18-33.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">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)</p>
<pre><code>// 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_-&gt;setFormat(format);
  openGLWindow_-&gt;resize(1280, 720); // Default size for the OpenGL window

  // Wrap the QOpenGLWindow in a QWidget container
  auto *glContainer = QWidget::createWindowContainer(openGLWindow_);
  glContainer-&gt;setFocusPolicy(Qt::TabFocus);
  glContainer-&gt;setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  glContainer-&gt;setParent(this);
  glContainer-&gt;setVisible(true);
  ////////////setCentralWidget(glContainer);

  // Add the overlay as a child of the container and set its visibility
  ////////////////overlay_-&gt;setParent(glContainer);
  /////////////////overlay_-&gt;resize(320, 200); // Resize the overlay 
  //////////////////overlay_-&gt;setVisible(true);

  }
</code></pre>
<pre><code>#ifndef VISUALIZATIONOPENGLWIDGET_H
#define VISUALIZATIONOPENGLWIDGET_H

#include "config.h"

#include &lt;QOpenGLWindow&gt;
#include &lt;QOpenGLFunctions&gt;

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
</code></pre>
<p dir="auto">.cpp</p>
<pre><code>#include "config.h"

#include &lt;QPainter&gt;

#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_-&gt;Init();
  

}

void VisualizationOpenGLWidget::paintGL() {

  QPainter p(this);
  //////////resizeGL(width(), height());
  p.beginNativePainting();
  projectm_visualization_-&gt;RenderFrame(width(), height());
  p.endNativePainting();
  update();

  qLog(Debug) &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; glGetError();

}

void VisualizationOpenGLWidget::resizeGL(const int width, const int height) {

  
  Setup(width, height);
  projectm_visualization_-&gt;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);

}
</code></pre>
<p dir="auto">ConsumeBuffer:</p>
<pre><code>void ProjectMVisualization::ConsumeBuffer(GstBuffer *buffer, const int pipeline_id, const QString &amp;format) {

  Q_UNUSED(pipeline_id);
  Q_UNUSED(format);

  GstMapInfo map;
  gst_buffer_map(buffer, &amp;map, GST_MAP_READ);

#ifdef HAVE_PROJECTM4
  if (projectm_instance_) {
    const unsigned int samples_per_channel = static_cast&lt;unsigned int&gt; (map.size / sizeof(size_t)) / 2;
    const int16_t *data = reinterpret_cast&lt;int16_t*&gt;(map.data);
    projectm_pcm_add_int16(projectm_instance_, data, samples_per_channel, PROJECTM_STEREO);
  }
#else
  if (projectm_) {
    const short samples_per_channel = static_cast&lt;short&gt;(map.size) / sizeof(short) / 2;
    const short *data = reinterpret_cast&lt;short*&gt;(map.data);
    projectm_-&gt;pcm()-&gt;addPCM16Data(data, samples_per_channel);
  }
#endif  // HAVE_PROJECTM4

  gst_buffer_unmap(buffer, &amp;map);
  gst_buffer_unref(buffer);

}
</code></pre>
<p dir="auto">InitprojectM</p>
<pre><code>// 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);
</code></pre>
<pre><code>"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_-&gt;selectPreset(index, true);
  }
#endif  // HAVE_PROJECTM4

}
</code></pre>
<p dir="auto">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.<br />
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 <img src="https://forum.strawberrymusicplayer.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f355.png?v=faqqna7874c" class="not-responsive emoji emoji-android emoji--pizza" style="height:23px;width:auto;vertical-align:middle" title=":pizza:" alt="🍕" /></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4343</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4343</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Thu, 25 Jul 2024 09:22:47 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 24 Jul 2024 22:31:44 GMT]]></title><description><![CDATA[<p dir="auto"><a href="https://gu.pro.br/ProjectQ.mp4" rel="nofollow ugc">current status</a></p>
<p dir="auto">the FPS on the video is very low due: * frameskipping at the desktop recorder</p>
<ul>
<li>fps was set t o 10 fps for testing purposes on projectm instance</li>
</ul>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4338</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4338</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 24 Jul 2024 22:31:44 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 24 Jul 2024 13:08:16 GMT]]></title><description><![CDATA[<p dir="auto">I had success starting to display stuff with v4 using QOpenGLWindow in a separate, smaller program.   Soon I'll upload the code, I just need to adjust some things like resize and OpenGL context. I've used as ConsumeBuffer the pulseaudio capture code. I just need to adjust some stuff i think to make it better, but i got so excited about a positive display in v4 that i wanted to share ASAP</p>
<p dir="auto">LoooooooooooooooooooooooooooL!</p>
<p dir="auto">PS: still, several GL error 1282 in the majority of presets tested.</p>
<p dir="auto"><img src="/assets/uploads/files/1721823636548-screenshot-from-2024-07-24-09-19-42.png" alt="Screenshot from 2024-07-24 09-19-42.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">while some actually works <img src="https://forum.strawberrymusicplayer.org/assets/plugins/nodebb-plugin-emoji/emoji/android/2764.png?v=faqqna7874c" class="not-responsive emoji emoji-android emoji--heart" style="height:23px;width:auto;vertical-align:middle" title="&lt;3" alt="❤" /></p>
<p dir="auto"><img src="/assets/uploads/files/1721826490305-screenshot-from-2024-07-24-10-07-52.png" alt="Screenshot from 2024-07-24 10-07-52.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4330</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4330</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 24 Jul 2024 13:08:16 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 17 Jul 2024 23:36:40 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/1">@jonas</a> roger that, gonna go back focus v4<br />
By the way I did compile latest git from v4 with his fixes, and tested with branch visualisations, did not work, same results. I'm curious about QOpenGLWindow results, with his fixes.</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4202</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4202</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 17 Jul 2024 23:36:40 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 17 Jul 2024 22:36:26 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/2454">@Gustavo-L-Conte</a><br />
Thanks for looking into it. It seems that projectm version 3 is buggy, I think we should try to get version 4 working instead, and drop support for version 3. See the discussion on <a href="https://github.com/orgs/projectM-visualizer/discussions/820" rel="nofollow ugc">https://github.com/orgs/projectM-visualizer/discussions/820</a></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4201</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4201</guid><dc:creator><![CDATA[jonas]]></dc:creator><pubDate>Wed, 17 Jul 2024 22:36:26 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 17 Jul 2024 21:12:02 GMT]]></title><description><![CDATA[<p dir="auto">Now, here's another one to worry about:</p>
<p dir="auto">A few days ago I installed those newest cream-of-cream set of plugins. Awesome by the way.<br />
They seem all working fine. I spent days testing on random mode. I still want to compare one by one with the SDL app.</p>
<p dir="auto">Now, problem is, when I go to the select visualization window, all the previews gets bugged if The first ones of the list (mostly called "Fast transition..") are selected. They don't seem to be normal plugins. Anyway, Thing is, if you select for preview any of these first ones, it bugs all other subsequent plugins. glClear color is not black anymore and they render all dumb. Only restarting Strawberry for normal behaviour again.<br />
Gonna look at the milkdrop code, later, to compare the "normal" ones from these "Fast transition..." ones.</p>
<p dir="auto"><img src="/assets/uploads/files/1721250719570-screenshot-from-2024-07-17-18-09-40.png" alt="Screenshot from 2024-07-17 18-09-40.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4200</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4200</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 17 Jul 2024 21:12:02 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 10 Jul 2024 01:11:42 GMT]]></title><description><![CDATA[<p dir="auto">in time, i just saw initializeGL with only BLEND command. All of those are required!!! Sorry if I did not express myself correctly. BLEND does the trick for the blank/black screens, but some visual bugs happens in lots of presets without the complete set.</p>
<pre><code>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);
</code></pre>
<p dir="auto">ALSO, you need to run the commands always before renderFrame, at drawBackground method.</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4053</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4053</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 10 Jul 2024 01:11:42 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Wed, 10 Jul 2024 00:22:30 GMT]]></title><description><![CDATA[<p dir="auto">Just found this, maybe useful</p>
<p dir="auto"><a href="https://lwn.net/Articles/750152/" rel="nofollow ugc">https://lwn.net/Articles/750152/</a></p>
<pre><code>if (projectm_) {
  projectm_-&gt;setShuffleEnabled(false);
  projectm_-&gt;selectPreset(index, true);
  projectm_-&gt;changePresetDuration(1);
  projectm_-&gt;setPresetLock(false);
  projectm_-&gt;selectPrevious(index);

  QTimer::singleShot(1250, this, [index,this]() {
    projectm_-&gt;setPresetLock(true);
    projectm_-&gt;changePresetDuration(duration_);
    projectm_-&gt;setShuffleEnabled(true);
  });
}
</code></pre>
<p dir="auto">Here's an improved version 0.1b to prevent altering shuffle globally in the settings. But don't forget to set smoothPresetDuration = 0 in the settings, this is required.</p>
<p dir="auto">B I N G O<br />
<strong>MilkDrop was heavily Windows-based, implemented with DirectX, Win32 APIs, and assembler. ProjectM did a good job of replicating the functionality in a cross-platform manner but one DirectX-specific piece remains: the shader code in the preset files. Some presets can contain GPU shader programs as mentioned previously. Because they were written for MilkDrop, they are in HLSL, a shader language for DirectX. Support for HLSL was provided in projectM by NVIDIA's Cg toolkit, but that has long been deprecated and is unsupported. Either manual or automatic conversion (possibly using something along the lines of HLSL2GLSL for Unity) needs to be added along with code to compile and upload the shaders. This would greatly increase performance and capabilities, enable the most advanced presets, and drop the dependency on an out-of-date and unsupported proprietary framework.</strong></p>
<p dir="auto">I saw on some presets some kind of shader language. The ones that bug!</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4052</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4052</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Wed, 10 Jul 2024 00:22:30 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Tue, 09 Jul 2024 21:57:56 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/1">@jonas</a> I really tried to understand that. I did put size_t because I saw somewhere that map.size type was size_t in gStreamer</p>
<p dir="auto">The channels I tought it wouldnt be an issue, but thinking about it, it is.</p>
<p dir="auto">###GstMapInfo</p>
<p dir="auto"><strong>A structure containing the result of a map operation such as Memory.map. It contains the data and size.</strong></p>
<pre><code>struct GstMapInfo {
GstMemory* memory;
GstMapFlags flags;
ubyte* data;
size_t size;
size_t maxsize;
void*[4] userData;
void*[4] GstReserved;
}
</code></pre>
<p dir="auto"><em>its not the buffer, its the SIZE of the buffer, thats why its not 16 bit like the buffer itself!<br />
Maybe thats why</em></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4050</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4050</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Tue, 09 Jul 2024 21:57:56 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Tue, 09 Jul 2024 20:58:09 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/2454">@Gustavo-L-Conte</a><br />
short is the same as int16_t, 2 bytes because the consumed buffer is 16 bit, but size_t is 8 bytes, I'd like to understand why that is correct.<br />
Another thing is that channels are hard-coded, so if the buffer has more then 2 channels, it will be wrong so we should pass channels to ConsumeBuffer</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4049</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4049</guid><dc:creator><![CDATA[jonas]]></dc:creator><pubDate>Tue, 09 Jul 2024 20:58:09 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Tue, 09 Jul 2024 20:08:56 GMT]]></title><description><![CDATA[<p dir="auto">now my <em>elegant</em> BEAUTIFUL hack is <em>gorgeous</em>!</p>
<ul>
<li>we got ConsumeBuffer consuming</li>
<li>we got drawBackground drawing</li>
<li>we got playlist preview selector selecting and previewing</li>
<li>we aint got no segfault, mon!</li>
</ul>
<p dir="auto"><strong>YES WE HAVE PROJECTM v3 (and v2 maybe) working</strong></p>
<pre><code>void ProjectMVisualization::SetImmediatePreset(const int index) {

#ifdef HAVE_PROJECTM4
  if (projectm_playlist_instance_) {
    projectm_playlist_set_position(projectm_playlist_instance_, index, true);
  }
#else
  if (projectm_) {
    projectm_-&gt;selectPreset(index, true);
    projectm_-&gt;changePresetDuration(1);
    projectm_-&gt;setPresetLock(false);
    projectm_-&gt;selectPrevious(index);
  
    QTimer::singleShot(1500, this, [index,this]() {
      projectm_-&gt;setPresetLock(true);
      projectm_-&gt;changePresetDuration(duration_);
    }); 
     
  }
#endif  // HAVE_PROJECTM4

}
</code></pre>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4048</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4048</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Tue, 09 Jul 2024 20:08:56 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Mon, 08 Jul 2024 18:49:52 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/1">@jonas</a> Its because i need to set the PREVIOUS preset, so that it elapses the transition, thats the only way I found not to bug some presets (that bug only on the preview); After fixing stuff, in the preview interface, some presets bug, i dunno why. But when they are playing normally as a playlist. when projectM is managing the transition, without us forcing with SelectPreset, this bug does not occur.</p>
<p dir="auto">So I managed to do this ugly hack, that sets the previous preset, unlock, lets projectM do the transition, then "quickly" locks again after the timer <img src="https://forum.strawberrymusicplayer.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61b.png?v=faqqna7874c" class="not-responsive emoji emoji-android emoji--stuck_out_tongue" style="height:23px;width:auto;vertical-align:middle" title=":P" alt="😛" /></p>
<p dir="auto">Read my previous posts, it was quite a journey. Thats the only thing missing I believe, to work with v3.</p>
<p dir="auto">v2 is used on ubuntu and has some issues, i posted previously about that too.</p>
<p dir="auto">The -1 would segfault, so I force the LAST preset to begin the first, when index = 0 is selected.</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4036</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4036</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Mon, 08 Jul 2024 18:49:52 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Mon, 08 Jul 2024 18:22:37 GMT]]></title><description><![CDATA[<p dir="auto"><a class="mention plugin-mentions-user plugin-mentions-a" href="https://forum.strawberrymusicplayer.org/uid/2454">@Gustavo-L-Conte</a> said in <a href="/post/4028">Reintegrate projectM Visualizer</a>:</p>
<blockquote>
<pre><code>if ( index &lt;= 0 )
  projectm_-&gt;selectPresetPosition(projectm_-&gt;getPlaylistSize());
else
  projectm_-&gt;selectPresetPosition(index-1);
</code></pre>
</blockquote>
<p dir="auto">This looks wrong, since the index starts with zero, <code>getPlaylistSize</code> will be too high, needs to do - 1. Also, why are you using index-1 when the index is set? Doesn't <code>IndexOfPreset</code> return the correct index?</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4034</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4034</guid><dc:creator><![CDATA[jonas]]></dc:creator><pubDate>Mon, 08 Jul 2024 18:22:37 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Mon, 08 Jul 2024 12:11:09 GMT]]></title><description><![CDATA[<p dir="auto">Thats it! If we put those OpenGL commands in <strong>drawBackground</strong>,<br />
change the static_cast to englobe both <strong>( map.size / sizeof(size_t) )</strong> /2 in <strong>ConsumeBuffer</strong><br />
with these changes in <strong>settings</strong>:</p>
<pre><code>  s.smoothPresetDuration = 0;
  s.presetDuration = duration_;
  s.shuffleEnabled = false;
</code></pre>
<p dir="auto">and my brand new ugly disgusting hack that now makes the preview work for the first element:</p>
<pre><code>void ProjectMVisualization::SetImmediatePreset(const int index) {

#ifdef HAVE_PROJECTM4
  if (projectm_playlist_instance_) {
    projectm_playlist_set_position(projectm_playlist_instance_, index, true);
  }
#else
  if (projectm_) {
    Lock(false);
    projectm_-&gt;changePresetDuration(1);
    if ( index &lt;= 0 )
      projectm_-&gt;selectPresetPosition(projectm_-&gt;getPlaylistSize());
    else
      projectm_-&gt;selectPresetPosition(index-1);
    // Create a QTimer to call Lock(true) after a delay
        QTimer::singleShot(500, this, [this]() {
            Lock(true);
            projectm_-&gt;changePresetDuration(duration_);
        });
  }
#endif  // HAVE_PROJECTM4

}
</code></pre>
<p dir="auto">I believe we have a working v3 integration with projectM! I executed the program for more than ten hours without segfaults or bugs.</p>
<p dir="auto"><img src="/assets/uploads/files/1720440634139-screenshot-from-2024-07-08-09-08-44.png" alt="Screenshot from 2024-07-08 09-08-44.png" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1720440646534-screenshot-from-2024-07-08-09-08-51.png" alt="Screenshot from 2024-07-08 09-08-51.png" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1720440659977-screenshot-from-2024-07-08-09-08-35.png" alt="Screenshot from 2024-07-08 09-08-35.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/4028</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/4028</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Mon, 08 Jul 2024 12:11:09 GMT</pubDate></item><item><title><![CDATA[Reply to Reintegrate projectM Visualizer on Sat, 06 Jul 2024 23:00:57 GMT]]></title><description><![CDATA[<p dir="auto">Considering what I posted before, about the way selectPreset(index) brakes some presets, making it impossible to preview via the interface, I've made this disgusting, ugly hack to enable preview. The problem is that the indexes are incremented in projectM, so I have to pick index-1 making impossible to get index  = 0 which would be the first preset of the list <img src="https://forum.strawberrymusicplayer.org/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61b.png?v=faqqna7874c" class="not-responsive emoji emoji-android emoji--stuck_out_tongue" style="height:23px;width:auto;vertical-align:middle" title=":P" alt="😛" /> LoLLL</p>
<pre><code>void ProjectMVisualization::SetImmediatePreset(const int index) {

#ifdef HAVE_PROJECTM4
  if (projectm_playlist_instance_) {
    projectm_playlist_set_position(projectm_playlist_instance_, index, true);
  }
#else
  if (projectm_) {
    if ( index &lt;= 0 )
      return;
    Lock(false);
    projectm_-&gt;changePresetDuration(1);
    projectm_-&gt;selectPresetPosition(index-1);
    // Create a QTimer to call Lock(true) after a delay
        QTimer::singleShot(500, this, [this]() {
            Lock(true);
            projectm_-&gt;changePresetDuration(duration_);
        });
  }
#endif  // HAVE_PROJECTM4

}
</code></pre>
<p dir="auto">pretty ugly, but its the proof of concept about what I've posted before. It works. Every single plugin works in the preview now, except the first one (yuck)</p>
<p dir="auto">PS: the idea here is, instead of setting the preset directly, making projectM make a transition as if it was playing as a playlist queue of the main window. This way, it does not brake the preview, since they all work when projectM manages the transition.</p>
]]></description><link>https://forum.strawberrymusicplayer.org/post/3992</link><guid isPermaLink="true">https://forum.strawberrymusicplayer.org/post/3992</guid><dc:creator><![CDATA[Gustavo L Conte]]></dc:creator><pubDate>Sat, 06 Jul 2024 23:00:57 GMT</pubDate></item></channel></rss>