projectM-visualizer / projectm

projectM - Cross-platform Music Visualization Library. Open-source and Milkdrop-compatible.
https://discord.gg/mMrxAqaa3W
GNU Lesser General Public License v2.1
3.3k stars 368 forks source link

[Feature Request] VST Support? #371

Open CCF100 opened 4 years ago

CCF100 commented 4 years ago

Would it be possible to compile projectM as a VST, for use in DAWs?

milkdropper commented 4 years ago

I looked into this and it seems like a neat idea because DAW's should be able to send PCM data to VST plugins without any loopback. I also saw there are frameworks and SDK's for making VST's based on OpenGL. This would solve the problem on macOS where you might need to buy a driver for loopback. There are free cross-platform programs that support VST's like Audacity, but even with that I think the audience is small for this need.

revmischa commented 4 years ago

Could use something like https://github.com/juce-framework/JUCE

falkTX commented 3 years ago

I already have such a thing at https://github.com/DISTRHO/ProM Currently trying to figure out a possible self-contained build that does not need external resources. But is that even possible? The settings wants a path to a preset dir and font files.

falkTX commented 3 years ago

Seems to work

image

Sorry for big weird screenshot, testing high-dpi stuff at the moment. Just need to find a way to nicely package the plugin so that fonts and presets are shipped with the binares, but shouldnt too be hard.

revmischa commented 3 years ago

I already have such a thing at https://github.com/DISTRHO/ProM

Amazing! Please feel free to add a mention in the projectM README

Currently trying to figure out a possible self-contained build that does not need external resources. But is that even possible? The settings wants a path to a preset dir and font files.

It is possible, at least on mac. If you look at the Music.app plugin bundle it includes the presets in its package resources.

See: https://github.com/projectM-visualizer/projectm/blob/master/src/projectM-MusicPlugin/iprojectM_mac.mm#L169

falkTX commented 3 years ago

I already have such a thing at https://github.com/DISTRHO/ProM

Amazing! Please feel free to add a mention in the projectM README

Will do, but want to get a proper self-contained plugin version working first.

I am basically trying to build projectm together with the plugin, so the VST works as-is without any dependencies. The setup is at https://github.com/DISTRHO/ProM/blob/master/plugins/ProM/Makefile#L121

Have a few issues so far:

kblaschke commented 3 years ago

projectM uses this class to scan the preset path (and subdirectories):

https://github.com/projectM-visualizer/projectm/blob/master/src/libprojectM/FileScanner.cpp

falkTX commented 3 years ago

turns out I was not using the compiler macros properly, I thought projectm would read it from config.h, but that is only the case for a few parts of the code. With -DHAVE_FTS_H as gcc arg, the linux build works correctly now. So only one blocker now - Windows UI is completely black, nothing is drawn. Investigating... maybe something related to glew setup

falkTX commented 3 years ago

Alright I got it to work on Windows now.

But FYI the file scanner is broken in its generic implementation (when HAVE_FTS_H is not defined). This is why on the Linux side no presets were being found, and was resolved with HAVE_FTS_H macro. Since Windows doesn't have this, the falling-back to the generic (broken) implementation means no preset switch happens there. Maybe the generic implementation only works for MSVC? (using mingw here)

kblaschke commented 3 years ago

Do you use the CMake build system or the classic autotools-based configure script and the premade VS solution on Windows?

CMake should properly check for the availability of fts.h.

For the self-contained build, this is possible within limits. Link SDL2 (and GLEW on Windows) statically, then instantiate projectM using the settings structure. In this case, it won't use any hard-coded paths or settings, including the presets. You can also manually fill the playlist.

Fonts and other resources can't be bundled onto the binary as of now. Generic support for such a feature wouldn't be too hard, adding an optional file streaming callback API which would enable the host application to send data in a callback whenever projectM needs to load any file like a preset, texture or font. You can either create a feature request or directly add the code and create a pull request yourself.

falkTX commented 3 years ago

Do you use the CMake build system or the classic autotools-based configure script and the premade VS solution on Windows?

Neither. Since we need to have this static and be part of the plugin, I have projectm as vendored dependency and just build it together with the plugin. See https://github.com/DISTRHO/ProM/blob/master/plugins/ProM/Makefile#L121

It is still possible to use system-wide provided projectm, detected via pkg-config.

For the self-contained build, this is possible within limits. Link SDL2 (and GLEW on Windows) statically, then instantiate projectM using the settings structure. In this case, it won't use any hard-coded paths or settings, including the presets. You can also manually fill the playlist.

SDL is not needed (or wanted in plugins anyway, since it cant embed to other windows). I already setup the paths based on the where the plugin DLL is located, code for this at https://github.com/DISTRHO/ProM/blob/master/plugins/ProM/DistrhoUIProM.cpp#L132

As a workaround for VST2 being a single DLL, I just create a folder for the plugin and place the DLL together with the resources in there. This is not a problem for VST3 or LV2 formats though.

falkTX commented 3 years ago

text search works now too :) there are builds for testing at https://github.com/DISTRHO/ProM/actions lv2 and vst2 plugins included in the artifacts. just ignore the standalone executable

runs fine within renoise for example Screenshot_20210823_234824

kblaschke commented 3 years ago

Great to hear!

As a note, you might want to start using the C API (src/libprojectM/projectM.h) for interfacing with the library in the near future as the C++ classes might see some changes in the future due to refactoring. After the next major release, The C API will stay as-is (or only get additional methods). If you don't use any internals, the C API maps almost all public methods of the ProjectM and PCM classes.

falkTX commented 3 years ago

sure, but the C API is new, right? which first version has it? because for system-wide projectm building this will need to be set as a requirement.

kblaschke commented 2 years ago

It's been a while since the last comment, also wrote something in your still-open PR.

Yes, the C API is new and will completely replace the C++ interface starting with the next release (4.0, this is the main reason why it'll have a new major version number). While you could still use the internals directly, I strongly recommend to switch to the C API, even when using C++. We will make sure the C API won't change often, or if it does, will be backwards-compatible within the same minor release. this means if you compile your app with the 4.0.0 release and link libprojectM as a shared library, it should work with any 4.0.x versions after that by simply replacing the shared library - no recompilation or relinking required. Forward compatibility is not guaranteed though, so if you've built against version 4.0.10, it might not work with a 4.0.5 library.

We are still reworking some internals right now to clean up the public API as much as possible, removing unnecessary features (e.g. the key handler and the on-screen display) and providing useful API calls for everything that makes sense to control from the outside. Some optional features might still be provided as separate libraries or API headers if an application dev wants to save some time.

The new API header can be found here, may be moved somewhere else in the source tree until release and split up into smaller headers as well: https://github.com/projectM-visualizer/projectm/blob/73042a9fca8b17d915ad2f575a79fc15445dc1e6/src/libprojectM/projectM.h

Here is an up-to-date quickstart guide on how to use the new API: https://github.com/projectM-visualizer/projectm/wiki/Integration-Quickstart-Guide

falkTX commented 2 years ago

Those are very nice to hear! even when knowing that I will have to change quite some things on my side. But I would rather wait until projectm stabilizes a bit, when it is around time for RC do ping me and I can start the update and testing.

kblaschke commented 7 months ago

@falkTX With the 4.1 release almost done, and the API staying as-is from 4.0, now would be a good opportunity to look into this project again. Over the past year, the whole renderer and expression parser was reimplemented, so projectM now supports a majority of all Milkdrop 2 presets, including those using loops and megabuf. Audio processing was overhauled, smooth transitions are in, and random texture selection works as intended.