Author Topic: With Bass_VST can I use a 32bit vst in an x64 application?  (Read 925 times)

dts350z

  • Posts: 33
With Bass_VST can I use a 32bit vst in an x64 application?

Just switching my app to x64 it won't "assign" a 32bit vst (unfortunately there is no 64bit version of the VST I want to use).

Is there a way to make this work?

dsp = BASS_VST_ChannelSetDSP(chan, reinterpret_cast<const void*>(vst_full_path), BASS_UNICODE, 0);

everything is working if I target my app for x86.

Falcosoft

  • Posts: 113
With Bass_VST can I use a 32bit vst in an x64 application?

Just switching my app to x64 it won't "assign" a 32bit vst (unfortunately there is no 64bit version of the VST I want to use).

Is there a way to make this work?

dsp = BASS_VST_ChannelSetDSP(chan, reinterpret_cast<const void*>(vst_full_path), BASS_UNICODE, 0);

everything is working if I target my app for x86.

By default you cannot. It's an architecture limitation not a VST specific problem. 32-bit applications cannot use 64-bit libraries directly and vice versa. But there is a way to make this work. Namely you have to use a bridge. Such a bridge is Jbridge:
https://jstuff.wordpress.com/jbridge/

The standard way to use it is to install it, and after installation you have to prepare each 32-bit VST plugin that you want to use with your 64-bit host.
But there is a more simple way: I have a fork of Bass_VST that has direct built-in JBridge support. This means that after you installed JBridge you do not have to prepare plugins but you can use them directly (If 64-bit Bass_VST detects a 32-bit plugin it automatically uses JBridge to load it and vice versa).
https://github.com/Falcosoft/BASS_VST/releases

dts350z

  • Posts: 33
Thanks! I will check out your fork.

dts350z

  • Posts: 33
One issue will be while J-Bridge might be an acceptable technical solution, the fact that it is commercial software, and my app is donation ware, may mean it's not a practical solution.

I will still explore it, however.

Falcosoft

  • Posts: 113
One issue will be while J-Bridge might be an acceptable technical solution, the fact that it is commercial software, and my app is donation ware, may mean it's not a practical solution.

I will still explore it, however.

Then the most practical solution would be to compile and distribute 2 versions of your software: a 32-bit one for 32-bit plugins and a 64-bit one for 64-bit plugins.

radio42

  • Posts: 4737
Please also take a look here: https://github.com/r10s/BASS_VST

It contains various binaries (incl. x64) as well as the source code!

rv

  • Posts: 373
But there is a more simple way: I have a fork of Bass_VST that has direct built-in JBridge support. This means that after you installed JBridge you do not have to prepare plugins but you can use them directly (If 64-bit Bass_VST detects a 32-bit plugin it automatically uses JBridge to load it and vice versa).
https://github.com/Falcosoft/BASS_VST/releases

Great, but your code doesn't work as I am using BASS_Unicode for path in .net
Not sure if jbridge allows Unicode path
I just asked to the author

Falcosoft

  • Posts: 113
But there is a more simple way: I have a fork of Bass_VST that has direct built-in JBridge support. This means that after you installed JBridge you do not have to prepare plugins but you can use them directly (If 64-bit Bass_VST detects a 32-bit plugin it automatically uses JBridge to load it and vice versa).
https://github.com/Falcosoft/BASS_VST/releases

Great, but your code doesn't work as I am using BASS_Unicode for path in .net
Not sure if jbridge allows Unicode path
I just asked to the author

Hi,
I already contacted Joao (JBridge's author) half a year ago about
1. Missing SysEx support in case of VST instruments.
2. Missing unicode support.
In the last released beta of JBridge SysEx support is already implemented but we have to wait a little more for unicode support.
As You can see in the code snippet all path parameters have to be char*. We have to wait until Joao implements functions where path is LPCWSTR.
https://jstuff.wordpress.com/jbridge/how-to-add-direct-support-for-jbridge-in-your-host/

rv

  • Posts: 373
Can you maybe add a little code to convert the LPCWSTR to char* in case of bass_unicode

I think it is the szPath here to convert :
return pfnBridgeMain(audioMasterCallbackImpl, szPath );

It will work most of time in many countries

Falcosoft

  • Posts: 113
Can you maybe add a little code to convert the LPCWSTR to char* in case of bass_unicode

I think it is the szPath here to convert :
return pfnBridgeMain(audioMasterCallbackImpl, szPath );

It will work most of time in many countries

Hi,
Here is a new fixed version that allows you to use the Bass_Unicode flag but only works with characters that can be translated to the local ANSI code page
by using WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)dllFile, -1, (char*)ansiDllFile, MAX_PATH, NULL, NULL);

https://github.com/Falcosoft/BASS_VST/releases

BTW, if you have some free time for testing please test some VST insstruments with larger Bass update periods for Midi precision. I have added code to set proper deltaFrames values so VSTi plugins should get proper sample offsets inside blocks (original Bass_VST sets constant 0 into deltaFrames fields so Midi precision depends entirely on update period)
« Last Edit: 26 Jan '22 - 11:37 by Falcosoft »

rv

  • Posts: 373
Great thank you
Maybe you can help him because I think he doesn't know how to manage Unicode :)
Sysex is very important for some XG / GS synths

Falcosoft

  • Posts: 113
Yeah, actually we already have a rather long conversation about both SysEx and unicode support and while the conversation about how to implement SysEx support was fruitful the same cannot be told about unicode. Since I do not know the source I could only tell him such things:

Quote
1. I do not think so. WideCharToMultiByte() only works when the Unicode/WideChar strings contain characters that are representable by the ANSI code page set by the 1st parameter. In our case we could only use CP_ACP as the 1st  CodePage parameter and hope that the string only contains characters that are representable by the OS current ANSI code page (set in system locale) . But e.g. if a user(OS) has Western code page set as default but he uses a unicode string with Japanese/Chinese/etc. characters WideCharToMultiByte() fails. Would it be hard to make an overridden version of pfnBridgeMain(audioMaster, szPath ) where szPath could be LPCWSTR and inside your function you would call
LoadLibraryW ((LPCWSTR) szPath); instead of LoadLibraryA ((char*) szPath); ?
...
and later:
Quote
Hi,
Thanks! It is much better now :) Actually now it works with all my SysEx using VSTi plugins (SYXG-50, SC-VA, Munt VSTi). I have found no problems so far with SysEx messages.
So my last problem is missing Unicode/Widechar support. It would be good if you could add a pfnBridgeMainW( audioMaster, szPath ) function where  szPath could be LPCWSTR instead of char*.
Thanks in advance and also thanks for your efforts you have done so far!
« Last Edit: 26 Jan '22 - 13:00 by Falcosoft »

rv

  • Posts: 373
I am testing now, and have a lot of midi evens that are skipped with bridged plugins
I am playing piano in realtime, and midi notes are dropped very often

Falcosoft

  • Posts: 113
I am testing now, and have a lot of midi evens that are skipped with bridged plugins
I am playing piano in realtime, and midi notes are dropped very often

For the testing I meant Bass_VST itself, not the bridge. The new deltaFrames setting code is in the new Bass_VST and it has nothing to do with JBridge. So I would like to know if the greater precision in case of larger update periods works for you or not when using VSTi instruments (without the bridge).
BTW the bridge has many settings that can be reached by editing the config file or be pressing 'Settings' button at the bottom part of Jbridge's UI.
E.g. you can try disabling 'Performance mode' or try enabling 'Switch to separate GUI mode' etc.
With my Midi player + new Bass_VST + Jbridge 1.76 beta I could achieve almost perfect results with some tinkering. 

@Edit:
I made a test video that uses 64-bit Midi Player and 32-bit S-YXG50 VSTi + 20 ms update period of Bass. I also tried to send fast real time events through the virtual piano in the video. No lost of Midi events  could be detected.
https://youtu.be/FTTCXJD0kGI
« Last Edit: 26 Jan '22 - 16:11 by Falcosoft »

rv

  • Posts: 373
This is very strange   S-YXG50 VSTi  does not have problems, but other 32 bit VSTi has
I have tried Hypersonic2 and VB3II
A lot of midievents are missed
No problem with 64 bit plugins
Only bridged ones

Falcosoft

  • Posts: 113
Can you recommend a free/demo version of a problematic VSTi for testing (that is not in the gigabyte range)?  I have also tested my own Bassmidi VSTi, Munt VSTi, OPL3 GM VSTi as well as Roland SC-VA and they work without major problems (similarly to S-YXG50).

@Edit:
I have tried the VB3II 64-bit plugin with my 32-bit Midi player and it runs perfectly without any dropping events problem.
Nevertheless your problem can be related to the 'reversed' bridging mode? I mean S-YXG50 is 32-bit only so you must be using it with a 64-bit host to test it bridged.
But the other 2 problematic VSTi plugins you mentioned are 64-bit only so you must be using them with a 32-bit host. So maybe the difference is because the reversed direction of bridging.

VB3II testing video:
https://youtu.be/cjVu2ViZj98
« Last Edit: 26 Jan '22 - 18:18 by Falcosoft »

rv

  • Posts: 373
I suspect the problem is caused by my midi keyboard that I am building that is actually sending 100 aftertouch midi messages per second together with the midi notes, because it it unplugged
I am using 64 bit host with 32 bit plugins
I am sorry it not VB3II but a very old Native Instruments B4II VSTi and hypersonic that it is very old
Maybe somewhere the buffer of the midi events should be full and lost.
Maybe it is a plugin problem, as some are working OK

rv

  • Posts: 373
No this is not my midi keyboard.
Another midi keyboard is doing the same
Will continue to do other test to find the problem reason
I just installed Windows 11 too

rv

  • Posts: 373
I have found the issue

Unfortunately some VST doesn't like the new deltaFrames addition

Removing this line, and the problem is corrected :
if (tmpTimeMs > 0) deltaFrames = (int)(tmpTimeMs * (getSampleRate(this_) * 0.001));

rv

  • Posts: 373
Maybe the DeltaFrames should not be bigger than the processed buffer size
I don't know...

Falcosoft

  • Posts: 113
Maybe the DeltaFrames should not be bigger than the processed buffer size
I don't know...

To be clear: Does the new deltaframes calculation also causes problems when the bridge is Not used or only causes problem when used with JBridge?
Bigger deltaFrames than buffer size really should not be given but in theory such deltaframe values are not even possible since the timestamp is reset at each buffer update period.
Have you detected such situation when deltaframes is bigger than buffer size?
What update period of Bass you used for testing? Maybe the problem is that the buffer size itself is badly calculated at some (too low?) update periods. 

@Edit:
Can you try what happens if you replace the above code you cited with
   if (tmpTimeMs > 0) deltaFrames = min(this_->effBlockSize - 1, (int)(tmpTimeMs * (getSampleRate(this_) * 0.001)));
?
« Last Edit: 27 Jan '22 - 04:59 by Falcosoft »

rv

  • Posts: 373
The code
 if (tmpTimeMs > 0) deltaFrames = min(this_->effBlockSize - 1, (int)(tmpTimeMs * (getSampleRate(this_) * 0.001)));
almost corrected the problem, so we are in the good direction

It still miss one event from time to time when I play tons of notes very very fast on the keyboard
I suspect bass changes the next buffer size from time to time, but it is not known at the moment you play the midi note
I am using wasapi exclusive with very low latency (256 samples) as I playing midi piano in realtime


rv

  • Posts: 373
Maybe the solution is to check every delta time before sending the whole midi events array to the plugin..................

rv

  • Posts: 373
i can confirm the problem is almost corrected, but is not related to jBridge, but depends on the plugin, how it deals with a delta time bigger than the buffer size

Falcosoft

  • Posts: 113
i can confirm the problem is almost corrected, but is not related to jBridge, but depends on the plugin, how it deals with a delta time bigger than the buffer size
OK, thanks. Please, try the following: In bass_vst_process.cpp add the following code to callProcess() function:

Code: [Select]
static void callProcess(BASS_VST_PLUGIN* this_, BASS_VST_PLUGIN* buffers, long numSamples)
{
if( this_->effStartProcessCalled )
{
// do MIDI processing
EnterCriticalSection(&this_->midiCritical_);
if( this_->midiEventsCurr && this_->midiEventsCurr->numEvents )
{
                        //new code starts

int i;
for( i = 0; i < this_->midiEventsCurr->numEvents; i++ )
{
this_->midiEventsCurr->events[i]->deltaFrames = min(this_->midiEventsCurr->events[i]->deltaFrames, numSamples - 1);

}

                        //new code ends

this_->aeffect->dispatcher(this_->aeffect, effProcessEvents, 0, 0, this_->midiEventsCurr, 0.0);

// prepare for the next round ... use the other buffer
...