Sorry ... this is a bit long.
I have minimised my memory loss and loading speed problems by creating a pool of VST Streams, creating one VST stream per VSTi on startup. When I finish a song I release the VST channel and DSP handles, but instead of freeing the VST stream I make it available again in the pool. The result: no memory leaks, however the pool can grow to a size larger than I would like to keep, so I would like to implement a cull on the pool, and sadly that will reintroduce the memory leak.
So ... I successfully got bass_vst to debug build, and I'm able to debug with it in my app - thank you for the help to get that far. Now to comment on the reported leaks (using MS Developer Studio 2022 heap snapshots).
I have created an infinite loop, thus:
m_hVST_stream = BASS_VST_ChannelCreate(44100, 2, lpszFilePath, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE);
while (true)
{
BASS_VST_ChannelFree(m_hVST_stream);
Sleep(10000);
m_hVST_stream = BASS_VST_ChannelCreate(44100, 2, lpszFilePath, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE);
}
... and I break after the sleep and then look at the heap differences (ignoring the first time, because of possible startup extras)
Because I do not have a debug version of BASS, I cannot investigate beyond BASS_VST. My detailed testing was on the Addictive Keys VSTi. There are 79,050 "unresolved allocations" reported after the second snapshot, but they come from quite a small number of calls:
- My call to BASS_VST_ChannelCreate(); traces as far as BASS_VST_ChannelCreateEx() where it calls BASS_StreamCreate() but I can trace no further. This reports one single allocation of 128 bytes still allocated, which is of no consequence unless it's a pointer to something else that should get destroyed but is not.
- BASS_VST_ChannelCreateEx() calls loadVstLibrary() after which the call stack takes me into the VSTi dll, which I can't debug. This call is reported 78,910 times. Most are for small amounts, but one is 2.3M. Total 10,876,895 bytes.
- BASS_VST_ChannelCreateEx() calls this_->aeffect->dispatcher(this_->aeffect, effMainsChanged, 0, 1/*resume*/, NULL, 0.0); after which the call stack disappears into the VSTi dll. This call is reported 7 times, accounting for only 401 bytes in total.
- My call to BASS_Channel_Free routes through BASS and reappears in BASS_VST in the onChannelDestroy callback. The second unrefHandle() call to free the channel calls destroyHandle(ptrToDestroy); since the usage counter hits 0, which makes the call this_->aeffect->dispatcher(this_->aeffect, effClose, 0, 0, NULL, 0.0); - this call is reported 88 times, accounting for 4,719 bytes in total.
There are other miscellaneous memory allocations reported, but not every time. The above get reported every time around my loop, and therefore appears to me to constitute a memory leak. I tested the loop 12 times for this report, and heap usage jumped 10.5M (+/- 100k) each time.
I then tested Cakewalk's SI-Bass Guitar and SI_Drum kit. The first 128 bytes (1, above) was common, but only 2 (above) in addition, and not many of them.
I then tested Strum Session 2. Again, 128 bytes (1, above), then quite a few of 2 (above), and then some belonging entirely to Strum Session 2, so not our concern.
An additional note that seemed a bit peculiar:
static VstIntPtr audioMasterCallbackImpl(...) called from this_->aeffect->dispatcher(this_->aeffect, effSetBlockSize, 0, sampleRate/*one second*/, NULL, 0.0); in LoadVSTLibrary()
- reported "plug called opcode #23" falling to default case for opcode (only for the Addictive Keys VSTi)
- reported "plug called audioMasterWantMidi" called from this_->aeffect->dispatcher(this_->aeffect, effMainsChanged, 0, 1/*resume*/, NULL, 0.0); in LoadVSTLibrary() (all VSTi's I tested)
Does that information make sense? Does any of it trigger thoughts (apart from "I wish this guy would go away)?