prof-spock / FluidSynthPlugin

Simple Wrappers Around the FluidSynth Library as DAW Plugin and Pedantic Command Line Processor
5 stars 0 forks source link

Program change doesn't work #1

Closed johnnovak closed 5 months ago

johnnovak commented 1 year ago

The VST plugin doesn't seem to respond to program change events at all. I'm using the latest REAPER version on Windows, and I'm trying to use it with some game music MIDI I recorded from DOSBox. Everything works fine with other plugins such as Roland Sound Canvas VA and the Yamaha Y-SXG50, but with this plugin all sounds are played with the default piano patch...

I'm using a very simple config:

soundfont = "D:\Emulators\DOS\SoundFonts\SC-55.SoundFont.v1.2b.sf2"
prof-spock commented 1 year ago

Hello John,

sorry for answering that late, I was busy in consolidating FluidSynthPlugin with SoXPlugins and didn't check the issues.

And I did not really expect that anybody is using the FluidSynthPlugin ;-)

Anyhow in principle the program should handle program changes. Give me some time to verify that and I'll keep you informed.

Best regards, Prof. Spock

johnnovak commented 1 year ago

Hello John,

sorry for answering that late, I was busy in consolidating FluidSynthPlugin with SoXPlugins and didn't check the issues.

And I did not really expect that anybody is using the FluidSynthPlugin ;-)

Anyhow in principle the program should handle program changes. Give me some time to verify that and I'll keep you informed.

Best regards, Prof. Spock

Thanks for looking into it.

Well, I can't speak for others, but one would think there should be a great interest in a VST plugin version of FluidSynth, given there's almost nothing out there except for this single project (apart for some old abandoned stuff).

My specific use case is to A/B compare how different community-made SoundFonts aimed to emulate specific MIDI modules from the 90s compare to the real hardware, and for that a plugin like this is extremely useful. I've already have 2.5-hour long audio recordings of my old MIDI modules, plus the source MIDI files on another track. Then it only takes a few minutes to render the whole programme using a different VSTi plugin. Plus of course I can A/B compare in real-time before I render; that's super handy when narrowing down the SoundFont candidates (there's tens of them...)

prof-spock commented 1 year ago

Hello John,

thanks for your kind encouragement!

The effect you describe is definitely a bug, I could confirm it. What is strange about it is that explicitly setting the program via the edit field works perfectly, but program changes within the midi event stream are ignored.

My gut feeling is that the underlying FluidSynth library is in some state (possibly by not being initialized as specified) such that MIDI program changes do not come through.

Anyway the command line version of the tool now works as expected so hopefully the correction of the plugin just takes a few days.

Thanks for your patience!

Best regards, Prof. Spock

johnnovak commented 1 year ago

Thanks for that, and there's absolutely no rush. I'll wait for the VST plugin 😄

For reference, and maybe it would help with your troubleshooting, here's a pack of 47 MIDI files I'm using for my comparisons.

ms-dos-games-general-midi-pack.zip

All these feature lots of Program Change, Control Change, and various other MIDI control events which should all be taken into account, of course.

prof-spock commented 1 year ago

Hello John,

I have adapted the programs accordingly and in my opinion they should work now. At least I have tried it with sam-n-max.mid file from your collection and it sounded reasonable.

Surprisingly the reason for the bug was a bit more complicated than I thought: VST3 plugins cannot listen at all to program changes (as opposed to all other plugin formats I know of), because those events are filtered out of the MIDI event stream.

So any program change logic implemented in the program on that basis is futile: you have to explicitly provide (numerical) presets and then have the DAW select the corresponding preset whenever a program change is found.

Besides there are other quirks with VST3s that might affect you:

The latter point should be no real problem because typically in a DAW the voices of a MIDI file are put into several tracks where each one uses just a single channel or at least the same MIDI program across all its channels fed into a track-specific plugin.

For your convenience I have provided the corrected binaries in the latest release. Please have a look and tell me whether the new version solves your problem.

Best regards, Prof. Spock

johnnovak commented 1 year ago

Hi, thanks for looking into this. That's rather unfortunate about the VST3 standard, and creating 16 tracks for the 16 MIDI channels is quite cumbersome when switching SoundFonts is involved.

So I tried the command line tool instead, I've adapted the simpest example from the manual, but the sam-n-max.mid d:\Emulators\DOS\SoundFonts\FluidR3_GM.sf2 -F out.wav option just gives me a debug assertion error immediately and out.wav gets created with 0 bytes.

prof-spock commented 1 year ago

Hello John,

sorry that you are treated like a guinea pig, but I hope I am answering your justified criticisms professionally. Now you have been bitten by an omission in the command line version: it complains about any SysEx passages in a MIDI file (and of course your file contains those) and then quits. I have now changed the program to silently skip those sysex parts (since they are irrelevant anyhow because they typically manufacturer and device specific data) and now it processes the sam-n-max.mid file correctly. Since you seem to be using Windows, I have only changed the Windows release file. Please have a look and report back, whether now everything is okay (or not?).

Best regards, Prof. Spock

johnnovak commented 1 year ago

Sounds perfect, thanks. I'll test it later today and will get back to you!

prof-spock commented 1 year ago

Hello John, sorry, I have again let you run into a knife: the pitch-bends were off in the version provided yesterday. "One should not perform any (careless) architectural changes in a program when fixing a bug..." The current version is corrected, it produces output sounding similarly to the genuine fluidsynth. By the way: if you are just interested in checking soundfonts and you are using the command-line anyway, then you could also use fluidsynth itself. The differences between my pedantic converter and fluidsynth are very subtle and fluidsynth is, of course, the reference implementation and the much more mature program. I am unfortunately a bit pathological: a command-line version should produce output almost identical to its DAW plugin and here the pedantic converter is closer to the DAW than "genuine fluidsynth". But this is somewhat academic... Best regards, Prof. Spock

johnnovak commented 1 year ago

Ah, I forgot about the original fluidsynth command line tool... You're right, given that I can't use your VST plugin anyway for my purposes, it's probably best to use their "official" CLI tool. Well, thanks for looking into the problems anyway; at least we both have learned something about VST3 😄

prof-spock commented 1 year ago

Hello John,

I am about to close this issue, because I think that the error is fixed. Any objections?

Best regards, Prof. Spock

johnnovak commented 1 year ago

Sounds good 😄

prof-spock commented 1 year ago

closed as fixed (current release contains appropriate event handling for VST3 plugins)

DaforLynx commented 8 months ago

Sorry to necro this, @prof-spock , but any news on a fix for program changes not going through on time? Somehow, JuicySF is able to do program changes just fine, so I know it's possible. If this issue could be fixed I'd greatly appreciate it - I've been looking for a tool like this for ages.

More details: Using REAPER, Program Changes seem behind by a few milliseconds during playback (so having them at the same time as a note will not affect the note), but behind by entire measures when rendering.

prof-spock commented 6 months ago

Hello DaforLynx,

oops, I completely missed your request, since this issue was closed. Let me do some research on the topic. According to my understanding of the official VST3 spec from Steinberg the program changes should not occur in the MIDI stream.

I have to find out first and keep you informed about the results...

Best regards, Prof. Spock

DaforLynx commented 5 months ago

An update on this: I discovered that it's actually the VST2 version of juicysfplugin that I'm using which works with program changes. And indeed, the VST3 version simply doesn't work with program changes. So, it seems the only possible solution is...making a VST2 version of FluidSynthPlugin. I legitimately don't know how much work it would be to do that. There's probably a reason you haven't been doing that in the first place. But, and only if it's actually not too much trouble, I ask if that's a possibility.

DaforLynx commented 5 months ago

Oddly this post on the Steinberg forums has an official response that suggests Program Changes can be received by VST3 https://forums.steinberg.net/t/no-program-changes-in-vst3-regrettable-decision/122202/3

But this one suggests it's only sort of possible. I'm not a developer, so I don't entirely understand it. https://forum.juce.com/t/midi-program-change-forwarding-for-vst3/47161/5

Though, looking further up, I'm pretty sure you're already aware of these posts. So I guess my only hope here is that JUCE has fixed their stuff with the program change detection or that VST2 is possible...

prof-spock commented 5 months ago

Hello DaforLynx,

I am going to repeat my comment from the other issue, because it fits here.

The fluidsynth plugin is absolutely fine in following program changes in the MIDI stream on a per channel basis. There had been a VST2 version that did exactly that and also the AU-version for MacOS is perfectly capable of handling those.

Unfortunately - as far as I understand - VST3 does not provide those program changes within the MIDI stream any longer, but by separate program change information disguised as API calls to the plugin. There is a kludge workaround to select the program in a DAW by changing the plugin preset (which is completely idiotic in my opinion, presets have a different purpose!) and this is served to the plugin.

But this seems to be the only way where the JUCE framework reacts to program changes for VST3 (see also this discussion) and, of course, the FluidSynth plugin supports it. But those changes are not in sync with the remaining MIDI stream and by that program changes may come too late relative to the MIDI notes. JUCE might decide to map those API calls to MIDI events served to the plugin, but currently they do not and by that follow the VST3 recommendation.

Also unfortunately the VST2 format is discontinued by Steinberg since May 2018 (because they claim to have the follow-up format VST3 since 2006). So you have problems in finding the VST2 Software Development Kit and hence also building plugins for that framework. This is no ill will by me but I have to rely on the boundary conditions of the JUCE framework and here VST2 is history...

And I do not know how you use your DAW, but normally a single track contains a single instrument, because all the track postprocessing is normally tuned to that instrument. So the restriction of the FluidSynth plugin is not relevant in that case. But if a track on the other hand contains several instruments and changes (e.g. the Doom MIDI file), the FluidSynth plugin VST3 cannot be used for the above reasons. So it depends on your use case...

Because there is currently no way to handle the problem in VST3, I am closing the issue (again :wink:)

Best regards, Prof. Spock