VST Plugin Effect Tail

Started by David_AVD,

David_AVD

I was looking to use BASS_ChannelSetAttribute with BASS_ATTRIB_TAIL to extend the file playback so that the VST effect doesn't get cut off.

I have seen posts about how to get the tail length with BassFx effect, but how do you query a VST plugin to get that value? Is it even possible to get a reliable value, especially with multiple plugins applied?

David_AVD

I just realised that BASS_ATTRIB_TAIL probably won't help me for my use as I usually stop the playback before the end of the file is naturally reached by setting a sync of BASS_SYNC_POS.

The alternative is to feed the stream into a mixer and apply the VST to the mixer stream instead of the source stream? It seems a bit of a waste to use a mixer for each source though.

Ian @ un4seen

Are you playing a single file/stream at a time? If so, you could simply apply the VST to BASS's final ouput mix, which is accessible by using STREAMPROC_DEVICE with BASS_StreamCreate:

outputmix = BASS_StreamCreate(0, 0, 0, STREAMPROC_DEVICE, 0); // get output mix stream
BASS_VST_ChannelSetDSP(outputmix, ...); // set VST on it

If you need to apply it to files/streams individually then another option is use a DSP function (with higher "priority" setting than the VST) to replace the decoder output with silence, and continue for a bit so that the VST effect's tail is heard. Something like this:

HDSP taildsp; // tail DSP handle
int tailcount; // tail counter

void CALLBACK TailDSP(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user)
{
    memset(buffer, 0, length); // replace sample data with silence (change 0 to 128 if it's 8-bit)
    tailcount -= length; // decrease tail counter
    if (tailcount <= 0) { // end of tail
        BASS_ChannelStop(channel); // end the channel
        BASS_ChannelRemoveDSP(channel, handle); // remove DSP function
    }
}

...

tailcount = BASS_ChannelSeconds2Bytes(stream, 1); // set tail length (1 second)
taildsp = BASS_ChannelSetDSP(stream, TailDSP, 0, INT_MAX); // start DSP function

You'll want to set BASS_ATTRIB_TAIL too, for the end of the file.

Regarding getting a VST effect's tail, I haven't tried it myself, but there's an effGetTailSize option that you can try using with BASS_VST_Dispatcher:

#define effGetTailSize 52
QWORD tailsamples = BASS_VST_Dispatcher(vsthandle, effGetTailSize, 0, 0, 0, 0);

If that doesn't work well, you could set another DSP function, this time with a lower "priority" than the VST so it's called afterwards, and have it check the level of the sample data and stop the stream when it's silent (or close to).

David_AVD

There can be multiple files playing at once, but the effects are (almost always) on a per file basis so applying them to the overall output is not a solution for me.

There is also a situation where I have a playlist of files which can overlap (like a mix transition) and the effects should apply to that mix. This was the partly the reason for asking about using a mixer in another forum thread. Applying an overall volume / pan to the mixer would also be easier than applying it to the playlist files individually.

I take it that if I use a mixer to combine the playlist files and I apply the VST effects to the mixer, the effects tail would not be truncated when the sources are stopped?

If so, using a mixer for the individual file situation would also mean I don't have to worry about the effects tail as the mixer would persist after the single source has stopped.

Ian @ un4seen

If the VST effect is set on a mixer then that would simplify things, as you can use the BASS_MIXER_NONSTOP flag to have the mixer generate silence when no sources are active. No need for BASS_ATTRIB_TAIL or DSP functions as in my last post.

David_AVD

Ah, so the BASS_MIXER_NONSTOP would be required so the VST effects don't stall as soon as the sources stop?

Ian @ un4seen

Yes. The BASS_MIXER_NONSTOP option is basically like an unlimited BASS_ATTRIB_TAIL setting; both generate silent data when the decoder has stopped providing data, and any DSP/FX (including VST effects) will be applied to that.