Birch-san / juicysfplugin

Audio plugin (e.g. VST, AU) to play soundfonts on macOS, Windows, Linux
GNU General Public License v3.0
209 stars 27 forks source link

Feature request: FluidSynth interpolation settings #54

Open DaforLynx opened 11 months ago

DaforLynx commented 11 months ago

This is a long shot, but would it be possible to include some kind of setting for the interpolation method used by FluidSynth? In their API, they have functions for this already. Here in the juicysf source code you already use another one of the API commands, fluid_synth_set_sample_rate.

I would just try to make a version with an added line myself, but I'm having trouble compiling it as it is on my Windows machine. Alternatively, somebody could assist me in that endeavor.

mrbumpy409 commented 11 months ago

I am also just now trying to do this as I noticed aliasing noise on some lower-bitrate samples. I'll let you know if I have any luck compiling this plugin, considering there are no instructions for Windows.

mrbumpy409 commented 11 months ago

Okay, so I'm totally lost trying to compile, so I will also say: it would be nice to be able to choose sample interpolation method. The default interpolation method (4th order) can sound a little grainy with lower-bitrate samples, so it would be nice to have the highest interpolation method (7th order) either as an option or as the default, depending on CPU hit.

DaforLynx commented 11 months ago

Hah, for me it's the opposite. I noticed certain older consoles use no interpolation when pitching samples, and it turns out it's hard to get that to work with soundfonts. Being able to set interp to NONE would make recreations more realistic.

Birch-san commented 11 months ago

there are no instructions for Windows.

I wrote some notes a while back regarding building on Windows with Visual Studio:
https://github.com/Birch-san/juicysfplugin/blob/master/Builds/VisualStudio2017/build-windows.md

but I don't maintain the Visual Studio solution or .msproj, because I did all the development on Mac. so it won't have kept up-to-date with Projucer updates, nor will it have all the current source files listed in it.

anyway, I switched the build over to be based on CMake, since this keeps it cross-platform, IDE-agnostic, and not such a hostage to Projucer.

the newer way to build for Windows via CMake is documented here:
https://github.com/Birch-san/juicysfplugin/blob/master/building.win32.md

the idea is that you would install Docker for Windows, use Linux containers, and that Dockerfile would use Linux to cross-compile for Windows (using LLVM and MinGW-w64).

the build output would be in the /x64/ directory of the container. if you volume-mount that to your host OS: you can try out the exe from there.

mrbumpy409 commented 11 months ago

Thank you, I'll give that a try! I was trying to build in Visual Studio and was getting "No global header file was included" error messages in reference to Juce. Most of my software compiling experience is Linux software, so Windows is still a bit foreign to me. Docker is also completely unknown to me, so I'll have to see what I can figure out. Do I need to put the dependencies in the same location specified in the Visual Studio instructions?

Birch-san commented 11 months ago

nope, you don't need to put any dependencies in. the Dockerfile shows the Linux container how to download dependencies from MSYS2's repositories (well, it just runs get_fluidsynth_deps.sh).
I sure hope they're still hosting all the versions I specified.

DaforLynx commented 11 months ago

Oh, thank you for replying. I'll try the new way and hopefully it works out.

DaforLynx commented 11 months ago

I've been trying the Docker method and banging my head against a wall and floundering around. I might as well ask for more help.

So I've gotten it to run the Docker script, and it gets all the way to RUN ./configure_fluidsynth.sh x86 where it then errors out:

0.740 -- The C compiler identification is Clang 14.0.0
...
...
4.409 -- Looking for objbase.h - found
4.421 -- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
4.421 -- Checking for modules 'glib-2.0>=2.6.5;gthread-2.0>=2.6.5'
4.423 --   Package 'libpcre2-8', required by 'glib-2.0', not found
4.424 --   Package 'libpcre2-8', required by 'glib-2.0', not found
4.424 CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:603 (message):
4.424   A required package was not found
4.424 Call Stack (most recent call first):
4.424   /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:825 (_pkg_check_modules_internal)
4.424   CMakeLists.txt:520 (pkg_check_modules)
4.424
4.424
4.424 -- Configuring incomplete, errors occurred!
4.424 See also "/fluidsynth/build_x86/CMakeFiles/CMakeOutput.log".
4.424 See also "/fluidsynth/build_x86/CMakeFiles/CMakeError.log".

From what I can gather, it tries to check pkg-config, but it fails to find a version of "libpcre2-8". I tried to run llvm-mingw (the command should use mstorjo/llvm-minw btw) but I don't even know if that instance is synced with the docker build instance. And in any case even if I install the latest version of libpcre2-dev inside the llvm-mingw instance, building still fails with this error. So I must be doing something wrong, like maybe I installed msys2 incorrectly or incompletely.

mrbumpy409 commented 11 months ago

I can't even get that far. How am I supposed to run the DOCKER_BUILDKIT=0 docker build . -f win32.Dockerfile --tag=llvm-mingw command? It's clearly BASH, but if I run it in WSL, it says "-ash: docker: not found", and if I run it in a Git Bash terminal, it seems to work, but I get the following errors:

debconf: delaying package configuration, since apt-utils is not installed and further down: /usr/bin/env: 'bash\r': No such file or directory. It doesn't make it past "Step 7/80".

There doesn't seem to be an option to run this command from within Docker Desktop and no other terminals seem to work (cmd.exe, PowerShell), which makes sense, since they are not bash shells.

Sorry if I'm an idiot, but what am I missing here?

DaforLynx commented 11 months ago

@mrbumpy409 I did the following (skipping around an hour of doing other things that didn't yield any progress): Install Docker Desktop Open VSCode into the juicysf folder Run docker build . -f win32.Dockerfile --tag=llvm-mingw in the VSCode terminal (just a powershell terminal in the project folder) Watch things fail Install MSYS2 and follow all instructions on the page Run command again, watch things continue to fail

You did just remind me of the buildkit thing, but changing that setting didn't make a difference.

mrbumpy409 commented 11 months ago

I finally got the command to run in WSL--I had to install Ubuntu and enable integration with it in Docker Desktop--but alas, it throws the same errors as when I run it in a Git Bash terminal. I've attached the command output here: WSL_output.txt. I don't have Visual Studio installed on here. My previous Visual Studio compilation attempt was in VirtualBox but Docker won't run in a VM so I have to do this now on my main Windows install, which I'd like to avoid junking up with anything unnecessary. I'll install it if I need to, but I'd like to hear from @Birch-san first.

Birch-san commented 11 months ago

for what it’s worth: it is possible to run Docker for Windows + Linux containers without installing WSL2, but yes that’s probably the best way (since it’s the best way to run a Linux virtual machine).

It believes there’s a syntax error in the bash script, because it saw Windows-style line endings (CRLF). this means you cloned the repository using Windows defaults.

You need to clone the repository with Unix-style line-endings (core.autocrlf=input) to ensure that the bash scripts are valid when run in a POSIX environment:

git clone https://github.com/Birch-san/juicysfplugin.git --config core.autocrlf=input
Birch-san commented 11 months ago

to clarify: this docker build command should be run from the host machine (Windows), in your favourite shell (cmd or Git bash or whatever). since that’s where you installed the Docker client. which will kick off the work inside the Linux virtual machine (rather, inside a Docker container inside the virtual machine).

DaforLynx commented 11 months ago

I'm not getting errors related to the bash command. There seems to be something weird with either the way docker gets configured by the script (not including a needed package) or the way I set up the WSL environment. This virtualization business is pretty arcane to me, so I'm hoping someone else can replicate this issue.

Birch-san commented 11 months ago

I'm not getting errors related to the bash command. There seems to be something weird with either the way docker gets configured by the script (not including a needed package) or the way I set up the WSL environment.

none of these should be problems. everything inside the container is known-good; I believe you have the same environment as I do. we should be more suspicious of external factors, particularly the MSYS2 repository from which it downloads dependencies.

as for why it can't find libpcre…

I told get_fluidsynth_deps.sh to look in the MSYS2 repository for packages matching pcre-:
https://github.com/Birch-san/juicysfplugin/blob/c95eb5755aab634a22dfa778912facd136590d5c/win32_cross_compile/get_fluidsynth_deps.sh#L21, in https://repo.msys2.org/mingw/clang64/

it seems pcre-8.45-1 should match that, so it's not immediately obvious to me what the problem is.

you can try running just this script, locally in Git Bash for Windows, or inside WSL:

./get_fluidsynth_deps.sh

and see what kinds of stuff it downloads, and whether there's any obvious signs that libpcre is absent.

I think it will try to install them to /deps/x64, and will extract them to / — so you may want to modify the script slightly before running it.

Birch-san commented 11 months ago

oh interesting; it's looking for libpcre2. I specifically told it to look for libpcre (hence the deliberate filter on "pcre-"), which was correct at the time.

perhaps the newer glib wants the newer major version of libpcre, then.

try changing pcre- to pcre2 in get_fluidsynth_deps.sh:


-  declare -a PKGS=("libiconv" "flac" "glib2" "libogg" "opus-1" "libvorbis" "pcre-" "libsndfile" "gettext")
+  declare -a PKGS=("libiconv" "flac" "glib2" "libogg" "opus-1" "libvorbis" "pcre2" "libsndfile" "gettext")
mrbumpy409 commented 11 months ago

Okay, after fixing the line endings of the git clone, I have made it much further. Changing "pcre-" to "pcre2" allowed me to get past the Cmake error reported by @DaforLynx, and get_fluidsynth_deps.sh completes without any errors and is successfully fetching all packages.

The configure_fluidsynth.sh script also appeared to complete successfully despite config complaining about sndfile not finding its libmpg123 dependency. Adding "mpg123" to the declare -a PKGS line mentioned above solves this and enables SF3 support in FluidSynth.

I then had the process stop when it couldn't find the VST2 SDK:

Step 64/80 : COPY VST2_SDK/ /VST2_SDK/
COPY failed: file not found in build context or excluded by .dockerignore: stat VST2_SDK/: file does not exist

I happen to have the VST2 SDK 2.4, so I copied the contents of "vstsdk2.4" into "VST2_SDK" and the script proceeds.

Now I'm running into issues here: Step 74/80 : RUN /juicysfplugin/make_juicysfplugin.sh x86. Compiling aborts after generating many errors (and plenty of warnings before that). Here's the output: plugin_compiler_errors.txt

If these problems are unique to building x86 and/or VST2, I am happy to go without them, as I only plan to use 64-bit VST3.

UPDATE: Indeed, this appears to be the 32-bit UUIDGetter issue mentioned in the 3.1.0 release notes. So now, how to bypass 32-bit plugin building...

Birch-san commented 11 months ago

hmm I actually thought x86 was already disabled. I commented out the only entry in the graph that creates any dependency from the entrypoint to any of the x86 layers:
https://github.com/Birch-san/juicysfplugin/blob/c95eb5755aab634a22dfa778912facd136590d5c/win32.Dockerfile#L124

maybe if you don't specify a target: it builds all targets? I guess that's the problem.

you could try explicitly asking for the x64 target, via --target=juicysfplugin_x64:

docker build . -f win32.Dockerfile --tag=llvm-mingw --target=juicysfplugin_x64

this means that the final target (distribute) wouldn't be run, so you'll need to fish the build output out of /juicysfplugin/build_x64/JuicySFPlugin_artefacts/ instead of from /x64.

maybe there's a way to enable both targets? --target=juicysfplugin_x64 --target=distribute

since ./distribute/bundle_win32.sh expects to look for the x64 output at /x64. you can of course modify it though.

mrbumpy409 commented 11 months ago

I'll give it a try. How important is the "DOCKER_BUILDKIT=0" environment variable before that? Also, did you mean to close the ticket?

mrbumpy409 commented 11 months ago

What about commenting out the following lines in the win32.Dockerfile?:

FROM juicysfplugin_common AS juicysfplugin_x86
RUN /juicysfplugin/configure_juicysfplugin.sh x86
COPY win32_cross_compile/make_juicysfplugin.sh make_juicysfplugin.sh
RUN /juicysfplugin/make_juicysfplugin.sh x86

Would that simplify things regarding the distribution step? Either way, if I only need to manually copy the VST3 files rather than having an installer, that is not an issue for my use case.

Birch-san commented 11 months ago

DOCKER_BUILDKIT=0 is not important at all.

it disables the newer-generation parallel Docker build, to get back some old behaviours that were useful for developing changes to the Dockerfile. namely that any layer that is created successfully: it'd give you an image id, so if anything went wrong after that you could look inside the last completed layer (via docker run -it --rm $IMAGE_ID) and interactively continue the build manually, to try and figure out what went wrong.
it also had the benefit of showing you the full log history rather than just the final page leading to the failure.

if you don't intend to / know how to make use of those debugging/development techniques, then don't use DOCKER_BUILDKIT=0. the default way is faster anyway (any layers which can be built in parallel, will be).

Birch-san commented 11 months ago

yes, you can just comment out those x86 lines in the Dockerfile.

and yes, it's not essential to run the distribute step. that's simply how I automate putting it into a zip with licenses. but you might want to study the docker cp commands that it uses to copy files out of the container and onto your host system.

well, maybe WSL2 + Docker gives you some nice file explorer GUI to do that anyway.

mrbumpy409 commented 11 months ago

I'm currently building with the aforementioned Dockerfile lines commented out. Now I get much further, but again run into an error:

272.1 [ 62%] Linking CXX executable JuicySFPlugin_artefacts/Release/Standalone/juicysfplugin.exe
272.1 /usr/bin/cmake -E cmake_link_script CMakeFiles/JuicySFPlugin_Standalone.dir/link.txt --verbose=1
272.2 /usr/bin/cmake -E rm -f CMakeFiles/JuicySFPlugin_Standalone.dir/objects.a
272.2 /opt/llvm-mingw/bin/llvm-ar qc CMakeFiles/JuicySFPlugin_Standalone.dir/objects.a @CMakeFiles/JuicySFPlugin_Standalone.dir/objects1.rsp
272.2 /opt/llvm-mingw/bin/x86_64-w64-mingw32-clang++ -D__UIAutomationClient_LIBRARY_DEFINED__  -DUIA_IsDialogPropertyId="(30174)" -DUIA_IsPasswordPropertyId="(30019)" -DUIA_IsOffsc
reenPropertyId="(30022)" -DUIA_ToggleToggleStatePropertyId="(30086)" -DUIA_IsKeyboardFocusablePropertyId="(30009)" -DUIA_ProcessIdPropertyId="(30002)" -DUIA_HelpTextPropertyId="(30
013)" -DUIA_HasKeyboardFocusPropertyId="(30008)" -DUIA_FrameworkIdPropertyId="(30024)" -DUIA_NamePropertyId="(30005)" -DUIA_RangeValueValuePropertyId="(30047)" -DUIA_NativeWindowHa
ndlePropertyId="(30020)" -DUIA_ControlTypePropertyId="(30003)" -DUIA_IsEnabledPropertyId="(30010)" -DUIA_IsContentElementPropertyId="(30017)" -DUIA_FullDescriptionPropertyId="(3015
9)" -DUIA_ValueValuePropertyId="(30045)" -DUIA_AutomationIdPropertyId="(30011)" -DUIA_IsControlElementPropertyId="(30016)" -O3 -DNDEBUG -static-libgcc -static-libstdc++ /clang64/li
b/libiconv.a /opt/llvm-mingw/x86_64-w64-mingw32/lib/libwinpthread.a -mwindows -Wl,--whole-archive CMakeFiles/JuicySFPlugin_Standalone.dir/objects.a -Wl,--no-whole-archive -o JuicyS
FPlugin_artefacts/Release/Standalone/juicysfplugin.exe -Wl,--out-implib,JuicySFPlugin_artefacts/Release/Standalone/libjuicysfplugin.dll.a -Wl,--major-image-version,0,--minor-image-
version,0 @CMakeFiles/JuicySFPlugin_Standalone.dir/linklibs.rsp
272.2 lld: error: unable to find library -lmp3lame
272.2 lld: error: unable to find library -lmp3lame
272.2 clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
272.2 gmake[2]: *** [CMakeFiles/JuicySFPlugin_Standalone.dir/build.make:303: JuicySFPlugin_artefacts/Release/Standalone/juicysfplugin.exe] Error 1
272.2 gmake[2]: Leaving directory '/juicysfplugin/build_x64'
272.2 gmake[1]: *** [CMakeFiles/Makefile2:164: CMakeFiles/JuicySFPlugin_Standalone.dir/all] Error 2
272.2 gmake[1]: Leaving directory '/juicysfplugin/build_x64'
272.2 gmake: *** [Makefile:94: all] Error 2
------
win32.Dockerfile:119
--------------------
 117 |     RUN /juicysfplugin/configure_juicysfplugin.sh x64
 118 |     COPY win32_cross_compile/make_juicysfplugin.sh make_juicysfplugin.sh
 119 | >>> RUN /juicysfplugin/make_juicysfplugin.sh x64
 120 |
 121 |     FROM ubuntu:$UBUNTU_VER AS distribute
--------------------
ERROR: failed to solve: process "/bin/sh -c /juicysfplugin/make_juicysfplugin.sh x64" did not complete successfully: exit code: 2

Unable to find mp3lame library. Unfortunately, I need to head out for a few hours, so to be continued...

UPDATE: I'm guessing this might be related to my adding the mpg123 package for SF3 support. I will disable that again and recompile.

mrbumpy409 commented 11 months ago

Okay, last update before I have to leave. When I remove mpg123 from the FluidSynth dependencies, I get the following errors during linking: fluidsynth_linking_default.txt

When I add mpg123, I get the error reported in my previous comment (missing mp3lame library).

When I add both mpg123 and lame, I get the following: fluidsynth_linking_with_mpg123_lame.txt

Seems it's unhappy with Opus now?

DaforLynx commented 11 months ago

Edit: ah, the exact same error as @mrbumpy409 . At least I'm not alone.

The libpcre2 solution worked (thank you so much), but now I'm getting new compile errors XD Take a look:

137.9 [ 76%] Linking CXX executable JuicySFPlugin_artefacts/Release/Standalone/juicysfplugin.exe
137.9 /usr/bin/cmake -E cmake_link_script CMakeFiles/JuicySFPlugin_Standalone.dir/link.txt --verbose=1
137.9 /usr/bin/cmake -E rm -f CMakeFiles/JuicySFPlugin_Standalone.dir/objects.a
137.9 /opt/llvm-mingw/bin/llvm-ar qc CMakeFiles/JuicySFPlugin_Standalone.dir/objects.a @CMakeFiles/JuicySFPlugin_Standalone.dir/objects1.rsp
137.9 /opt/llvm-mingw/bin/x86_64-w64-mingw32-clang++ -D__UIAutomationClient_LIBRARY_DEFINED__  -DUIA_IsDialogPropertyId="(30174)" -DUIA_IsPasswordPropertyId="(30019)" -DUIA_IsOffscreenPropertyId="(30022)" -DUIA_ToggleToggleStatePropertyId="(30086)" -DUIA_IsKeyboardFocusablePropertyId="(30009)" -DUIA_ProcessIdPropertyId="(30002)" -DUIA_HelpTextPropertyId="(30013)" -DUIA_HasKeyboardFocusPropertyId="(30008)" -DUIA_FrameworkIdPropertyId="(30024)" -DUIA_NamePropertyId="(30005)" -DUIA_RangeValueValuePropertyId="(30047)" -DUIA_NativeWindowHandlePropertyId="(30020)" -DUIA_ControlTypePropertyId="(30003)" -DUIA_IsEnabledPropertyId="(30010)" -DUIA_IsContentElementPropertyId="(30017)" -DUIA_FullDescriptionPropertyId="(30159)" -DUIA_ValueValuePropertyId="(30045)" -DUIA_AutomationIdPropertyId="(30011)" -DUIA_IsControlElementPropertyId="(30016)" -O3 -DNDEBUG -static-libgcc -static-libstdc++ /clang64/lib/libiconv.a /opt/llvm-mingw/x86_64-w64-mingw32/lib/libwinpthread.a -mwindows -Wl,--whole-archive CMakeFiles/JuicySFPlugin_Standalone.dir/objects.a -Wl,--no-whole-archive -o JuicySFPlugin_artefacts/Release/Standalone/juicysfplugin.exe -Wl,--out-implib,JuicySFPlugin_artefacts/Release/Standalone/libjuicysfplugin.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles/JuicySFPlugin_Standalone.dir/linklibs.rsp
138.0 ld.lld: error: undefined symbol: __declspec(dllimport) g_rec_mutex_init
138.0 >>> referenced by libfluidsynth.a(fluid_settings.c.obj):(new_fluid_settings)
138.0 >>> referenced by libfluidsynth.a(fluid_synth.c.obj):(new_fluid_synth)
138.0 >>> referenced by libfluidsynth.a(fluid_sffile.c.obj):(fluid_sffile_open)
138.0
138.0 ld.lld: error: undefined symbol: __declspec(dllimport) g_rec_mutex_clear
138.0 >>> referenced by libfluidsynth.a(fluid_settings.c.obj):(delete_fluid_settings)
138.0 >>> referenced by libfluidsynth.a(fluid_synth.c.obj):(delete_fluid_synth)
138.0 >>> referenced by libfluidsynth.a(fluid_sffile.c.obj):(fluid_sffile_close)
138.0
138.0 ld.lld: error: undefined symbol: __declspec(dllimport) g_rec_mutex_lock
138.0 >>> referenced by libfluidsynth.a(fluid_settings.c.obj):(fluid_settings_register_str)
138.0 >>> referenced by libfluidsynth.a(fluid_settings.c.obj):(fluid_settings_register_num)
138.0 >>> referenced by libfluidsynth.a(fluid_settings.c.obj):(fluid_settings_register_int)
138.0 >>> referenced 28 more times
...

and so on. From what I could gather, the linker, LLD, doesn't appear to be detecting the glib2 import. This might not even be juicysf's fault, but maybe some tweak to one of the configuration files could fix it. I don't have a clue what or which, though. We are successfully installing the mingw-w64-clang-x86_64-glib2 package at an earlier step. It should contain those functions. The linker just isn't importing them somehow. I'm not sure how it works. In my searches I found that apparently LLD doesn't work with gcc LTO files, whatever that is. I don't know if this is related. Same error happens when I try to compile just the VST3. And sorry for leaving all this in an issue.

mrbumpy409 commented 11 months ago

I can't figure this out either. I've long wanted to learn C++, but it would probably be a while before I would have learned enough to be able to understand what is going on here.

DaforLynx commented 11 months ago

So far I've tried:

None of these change the error. So I'm quite at a loss. Again, this is building from master without any modifications. It does seem to be a fluidsynth issue, but it's hard to say whether it's something they can fix. Fluidsynth itself seems to build fine on WSL. Maybe it's an issue with mingw (it probably is).

DaforLynx commented 11 months ago

Update: fluidsynth seems to compile fine in MSYS2 MINGW64 using the same cmake configuration as in configure_fluidsynth.sh

DaforLynx commented 11 months ago

@mrbumpy409 @Birch-san I'm going to move the compilation discussion to a new issue #56 because it's really rather unrelated to the original intent of this issue. You're free to close this if you don't see it going anywhere (i.e. you don't think it'd be a worthy feature).