Author Topic: Managing multiple effect VSTs in a row  (Read 678 times)

kafffee

  • Posts: 278
Managing multiple effect VSTs in a row
« on: 30 May '23 - 19:34 »
Hey everybody  :)

In my app I have a listbox in which the user can add, remove, or move vst effects in priority.

The listbox items are of the type PlugInsViewModel (which is a class containing name, path of the dll, status of the UI (open or not), the handle, and the handle of the UI window and other properties) and the listbox's items source is a list of these (AppliedFX).

The situation is that the user can also open the UIs of these vst effects from the listbox and the windows showing these UIs are supposed to be reinitialized when the user adds, removes, or moves items.

The following method is being called everytime the user adds, removes, or moves items of the listbox I mentioned above. It is supposed to remove all the "old" vst effects, unembed them from the UI editor, reinitialize them and copy the parameters to the "new" vsts and re-opening the UI editors again:

Code: [Select]
Private Sub InitializeVSTFX(sender As Object, e As NotifyCollectionChangedEventArgs)
For i = AppliedFX.Count - 1 To 0 Step -1     'counting in reverse to get the priority right
           
            AppliedFX(i).Handle = BassVst.BASS_VST_ChannelSetDSP(sourcechannel, AppliedFX(i).Path, 0, AppliedFX.Count - i)             'initializing the "new" effects
                Dim vstInfo As New BASS_VST_INFO()          'setting the name
                BassVst.BASS_VST_GetInfo(AppliedFX(i).Handle, vstInfo)
                AppliedFX(i).Name = vstInfo.effectName

            For Each item In CopiedAppliedFX          'looping thru list of "old" effects
                If AppliedFX(i).ID = item.ID Then       'checking ID in order to not mix up the effects
                    BassVst.BASS_VST_SetParamCopyParams(item.Handle, AppliedFX(i).Handle) 'copying parameters
                End If
                BassVst.BASS_VST_EmbedEditor(item.Handle, Nothing)       'unembed UIs
                BassVst.BASS_VST_ChannelRemoveDSP(sourcechannel, item.Handle)   'removing all the "old" effects
            Next

            If AppliedFX(i).UIOpen Then       'if it has been already open, re-open the UI
                BassVst.BASS_VST_EmbedEditor(AppliedFX(i).Handle, AppliedFX(i).UIHandle(0))
            End If
        Next

       
        CopiedAppliedFX.Clear()    'clear list

        For Each item In AppliedFX       'initializing list for the next call of InitializeVSTFX
            CopiedAppliedFX.Add(New PlugInsViewModel(item.ID, item.Path, item.Name, item.Bypass, item.Handle, item.UIHandle, item.UIOpen))
        Next

End Sub

I know its not the best code, for instance the ChannelRemoveDSP is called too often, but it should at least work, which it doesn't.

Anybody got an idea of how to do this better? I have been staring at my code for hours now but I can't figure out how else to do this...

The actual current problem is, that the "old" effects (before the change) don't seem to get removed from the source channel.

Copying the parameters works...

Ian @ un4seen

  • Administrator
  • Posts: 26108
Re: Managing multiple effect VSTs in a row
« Reply #1 on: 31 May '23 - 17:47 »
I'm not familiar with PlugInsViewModel, so can't offer any advice on that, but to perhaps get some clues on the problem, you should check all of the function call return values for success/failure (and the error code in case of failure). From what you say, it sounds like the BASS_VST_ChannelRemoveDSP calls are probably failing?

kafffee

  • Posts: 278
Re: Managing multiple effect VSTs in a row
« Reply #2 on: 31 May '23 - 22:33 »
Hey Ian,

yes there were, as expected, a bunch of calls failing, so I figured that in my case, it's just not possible to use SetParamCopyParams, because it requires two valid vst handles at the same time, which was just not given.

So I decided to just rewrite the whole function and to store and retrieve the vst params manually.

For now it's seems to be working right, I can add, remove and move effects without any errors, the only thing that causes trouble is that the params are not being retrieved and reset to the original values, when I re-open the vst effects in their editor.

I will take another look at that these days and post the results here, it's seems like there only has to be some debugging done.

So far, kafffee

« Last Edit: 31 May '23 - 22:55 by kafffee »

kafffee

  • Posts: 278
Re: Managing multiple effect VSTs in a row
« Reply #3 on: 5 Jun '23 - 13:43 »
Okay this is my working code, in case it's useful for somebody:

Code: [Select]
Public Sub InitializeVSTFX(sender As Object, e As NotifyCollectionChangedEventArgs)

        For Each item In CopiedAppliedEffcts
            item.Parameter.Clear()

            For i = 0 To BassVst.BASS_VST_GetParamCount(item.Handle) - 1
                Dim value As Single = BassVst.BASS_VST_GetParam(item.Handle, i)
                item.Parameter.Add(value)
            Next

            BassVst.BASS_VST_EmbedEditor(item.Handle, Nothing)
            BassVst.BASS_VST_ChannelRemoveDSP(sourcechannel, item.Handle)
        Next

        For i = AppliedEffects.Count - 1 To 0 Step -1
            AppliedEffects(i).Handle = BassVst.BASS_VST_ChannelSetDSP(sourcechannel, AppliedEffects(i).Pfad, 0, AppliedEffects.Count - i)

            Dim vstInfo As New BASS_VST_INFO()
            BassVst.BASS_VST_GetInfo(AppliedEffects(i).Handle, vstInfo)
            AppliedEffects(i).Name = vstInfo.effectName

            If AppliedEffects(i).Parameter.Count = 0 Then
                BassVst.BASS_VST_SetParamRestoreDefaults(AppliedEffects(i).Handle)
            Else
                For Each item In KopieAppliedEffects
                    If item.ID = AppliedEffects(i).ID Then
                        For j = 0 To item.Parameter.Count - 1
                            BassVst.BASS_VST_SetParam(AppliedEffects(i).Handle, j, item.Parameter(j))
                        Next
                    End If
                Next
            End If

            If AppliedEffects(i).UIIsOpen Then
                BassVst.BASS_VST_EmbedEditor(AppliedEffects(i).Handle, AppliedEffects(i).UIHandle(0))
            End If
        Next

        For Each item In AppliedEffects

            Dim itemColor As New Media.SolidColorBrush
            If item.Bypass Then
                itemColor = CType(Application.Current.Resources("HighLightedBrush"), Media.SolidColorBrush)
            Else
                itemColor = CType(Application.Current.Resources("ForeGroundBrush"), Media.SolidColorBrush)
            End If
            CopiedAppliedEffects.Add(New PlugInsViewModel(item.ID, item.Path, item.Name, item.Bypass, item.Handle, item.UIHandle, item.UIIsOpen, itemColor, item.Parameter))

        Next
    End Sub
« Last Edit: 6 Jun '23 - 11:26 by kafffee »