Hallo liebe Community,
ich habe eine
Spoiler anzeigen
Die Klasse
Spoiler anzeigen
Die Listen beinhalten Daten zu den auf eine Audiospur angewendeten VST-Effekt-PlugIns. Der Zähler wird zur eindeutigen Identifikation benutzt in der Eigenschaft
Dann habe ich folgende Funktion, die immer ausgeführt wird, wenn ein Item zu
Spoiler anzeigen
Ziel dieser Funktion soll es sein, wenn sich etwas an AngewendeteEffekte ändert, die PlugIns neu initialisiert werden sollen. KopieAngewendeteEffekte soll nur eine "Hilfsliste" sein.
Also z.B. wenn der Benutzer die UI des PlugIns schon offen hat (Eigenschaft
Klappt soweit auch ganz gut, bloss bei der Parameter-Übernahme habe ich noch Probleme. Diese werden nur übernommen, wenn mehrere UIs offen sind und dann auch nur das, was als letztes zugefügt wurde (man beachte: die Schleife zählt rückwärts, s. Kommentare!!).
Ich vermute ich habe einen Denkfehler da drinnen. Aber ich komm nicht wirklich drauf, habs mir immer wieder angeschaut und auch zwei Nächte drüber geschlafen...
Beim Debuggen hab ich aber schon feststellen können, dass die Aufrufe zum Auslesen und wieder Setzen der Paramter jedenfalls keine Fehler verursachen, also das sollte klappen.
Wenn jemand den Fehler entdeckt wäre das gut, ich wäre aber auch dankbar für einen Ansatz beim Debuggen (was würdet ihr (als erstes) überprüfen?). Oder was würdet ihr sogar anders machen?
Edit: Hab mal versucht statt
ich habe eine
AngewendeteEffekte As ObservableCollection(Of PlugInsViewModel)
und eine KopieAngewendeteEffelte As List(Of PlugInsViewMoel) und einen Zähler:VB.NET-Quellcode
- Private KopieAngewendeteEffekte As New List(Of ViewModel.PlugInsViewModel)
- Private AktuelleID As Integer = 0
- Private _AngewendeteEffekte As ObservableCollection(Of ViewModel.PlugInsViewModel)
- Public Property AngewendeteEffekte As ObservableCollection(Of ViewModel.PlugInsViewModel)
- Get
- Return _AngewendeteEffekte
- End Get
- Set(value As ObservableCollection(Of ViewModel.PlugInsViewModel))
- _AngewendeteEffekte = value
- RaisePropertyChanged()
- End Set
- End Property
Die Klasse
PlugInsViewModel
sieht so aus, ist aber glaube ich nicht von Belang:VB.NET-Quellcode
- Option Strict On
- Imports System.Windows.Media
- Public Class PlugInsViewModel
- Inherits ViewModel.Instrastructure.ViewModelBase
- Friend ReadOnly ModelObjekt As New Model.PlugInsModel
- Public Sub New()
- End Sub
- Public Sub New(argID As Integer, argPfad As String, argName As String, argBypass As Boolean, argStreamHandle As Integer, argUIHandle As List(Of IntPtr), argUIOffen As Boolean, argByPassColorBrush As SolidColorBrush, argParameter As List(Of Single))
- ModelObjekt = New Model.PlugInsModel(argID, argPfad, argName, argBypass, argStreamHandle, argUIHandle, argUIOffen, argByPassColorBrush, argParameter)
- End Sub
- Friend Sub New(_ModelObjekt As Model.PlugInsModel)
- ModelObjekt = _ModelObjekt
- End Sub
- Public Property ID As Integer
- Get
- Return ModelObjekt.ID
- End Get
- Set(value As Integer)
- ModelObjekt.ID = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property Pfad As String
- Get
- Return ModelObjekt.Pfad
- End Get
- Set(value As String)
- ModelObjekt.Pfad = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property Name As String
- Get
- Return ModelObjekt.Name
- End Get
- Set(value As String)
- ModelObjekt.Name = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property Bypass As Boolean
- Get
- Return ModelObjekt.Bypass
- End Get
- Set(value As Boolean)
- ModelObjekt.Bypass = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property Handle As Integer
- Get
- Return ModelObjekt.StreamHandle
- End Get
- Set(value As Integer)
- ModelObjekt.StreamHandle = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property UIHandle As List(Of IntPtr)
- Get
- Return ModelObjekt.UIHandle
- End Get
- Set(value As List(Of IntPtr))
- ModelObjekt.UIHandle = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property UIOffen As Boolean
- Get
- Return ModelObjekt.UIOffen
- End Get
- Set(value As Boolean)
- ModelObjekt.UIOffen = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property ByPassColorBrush As SolidColorBrush
- Get
- Return ModelObjekt.ByPassColorBrush
- End Get
- Set(value As SolidColorBrush)
- ModelObjekt.ByPassColorBrush = value
- RaisePropertyChanged()
- End Set
- End Property
- Public Property Parameter As List(Of Single)
- Get
- Return ModelObjekt.Parameter
- End Get
- Set(value As List(Of Single))
- ModelObjekt.Parameter = value
- RaisePropertyChanged()
- End Set
- End Property
- End Class
Die Listen beinhalten Daten zu den auf eine Audiospur angewendeten VST-Effekt-PlugIns. Der Zähler wird zur eindeutigen Identifikation benutzt in der Eigenschaft
ID
und wird folgrndermassen gesetzt, wenn man einen Effekt zu AngewendeteEffekte
zufügt:VB.NET-Quellcode
- Dim EffektAktuell As PlugInsViewModel = New PlugInsViewModel(AktuelleID, GewaehlterEffekt.Pfad, GewaehlterEffekt.Name, False, Nothing, Nothing, False, CType(System.Windows.Application.Current.Resources("VordergrundfarbeBrush"), SolidColorBrush), New List(Of Single))
- AktuelleID += 1
- AngewendeteEffekte.Add(EffektAktuell)
Dann habe ich folgende Funktion, die immer ausgeführt wird, wenn ein Item zu
AngewendeteEffekte
hinzugefügt, eins entfernt oder eins nach oben oder unten in der Liste verschoben wird:VB.NET-Quellcode
- Public Sub InitilaisiereVSTEffekte(sender As Object, e As NotifyCollectionChangedEventArgs)
- For Each item In KopieAngewendeteEffekte
- Dim index As Integer = AngewendeteEffekte.ToList.FindIndex(Function(x) x.ID = item.ID) 'wenn IDs übereinstimmen dann...
- If index <> -1 Then
- For i = 0 To BassVst.BASS_VST_GetParamCount(item.Handle) - 1 'einzelne Parameter durchlaufen und Werte ermitteln
- Dim Wert As Single = BassVst.BASS_VST_GetParam(item.Handle, i)
- Debug.WriteLine("GetParam: " & Bass.BASS_ErrorGetCode)
- AngewendeteEffekte(index).Parameter.Add(Wert) 'einzelne Parameter speichern
- item.Parameter.Add(Wert)
- Next
- End If
- BassVst.BASS_VST_EmbedEditor(item.Handle, Nothing) 'UI des PlugIns schliessen
- BassVst.BASS_VST_ChannelRemoveDSP(sourcechannel, item.Handle) 'EffektPlugIn disposen
- Next
- For i = AngewendeteEffekte.Count - 1 To 0 Step -1 'rückwärts zählen, um die Priorität der Effekte richtig zu setzen
- AngewendeteEffekte(i).Handle = BassVst.BASS_VST_ChannelSetDSP(sourcechannel, AngewendeteEffekte(i).Pfad, 0, AngewendeteEffekte.Count - i) 'Effekt initialisieren, Priorität: letztes Argument
- If AngewendeteEffekte(i).Parameter.Count = 0 Then 'wenn keine Parameter gespeichert dann...
- BassVst.BASS_VST_SetParamRestoreDefaults(AngewendeteEffekte(i).Handle) '...Defaultwerte verwenden
- Else
- For Each item In KopieAngewendeteEffekte
- If item.ID = AngewendeteEffekte(i).ID Then 'wenn ID übereinstimmt dann...
- For j = 0 To item.Parameter.Count - 1 '...gespeicherte Paramter anwenden auf PlugIn
- BassVst.BASS_VST_SetParam(AngewendeteEffekte(i).Handle, j, AngewendeteEffekte(i).Parameter(j))
- Debug.WriteLine("SetParam: " & Bass.BASS_ErrorGetCode)
- Next
- End If
- Next
- End If
- If AngewendeteEffekte(i).UIOffen Then
- BassVst.BASS_VST_EmbedEditor(AngewendeteEffekte(i).Handle, AngewendeteEffekte(i).UIHandle(0)) 'Effekt-PlugIn-UI wieder öffnen, wenn es bereits vorher offen war
- End If
- Next
- For Each item In AngewendeteEffekte 'Aktuelle Werte in KopieAngewendeteEffekte speichern für den nächsten Durchlauf der Sub
- Dim itemFarbe As New Media.SolidColorBrush
- If item.Bypass Then
- itemFarbe = CType(Application.Current.Resources("AbsetzfarbeBrush"), Media.SolidColorBrush)
- Else
- itemFarbe = CType(Application.Current.Resources("VordergrundfarbeBrush"), Media.SolidColorBrush)
- End If
- KopieAngewendeteEffekte.Add(New PlugInsViewModel(item.ID, item.Pfad, item.Name, item.Bypass, item.Handle, item.UIHandle, item.UIOffen, itemFarbe, item.Parameter))
- Next
- End Sub
Ziel dieser Funktion soll es sein, wenn sich etwas an AngewendeteEffekte ändert, die PlugIns neu initialisiert werden sollen. KopieAngewendeteEffekte soll nur eine "Hilfsliste" sein.
Also z.B. wenn der Benutzer die UI des PlugIns schon offen hat (Eigenschaft
UIOffen
), dass diese UI dann nach dem re-initialisieren wieder geöffnet wird und auch die in Parameter
gespeicherten Ändeungen (also z.B. der Pitch des PlugIns) übernommen werden sollen.Klappt soweit auch ganz gut, bloss bei der Parameter-Übernahme habe ich noch Probleme. Diese werden nur übernommen, wenn mehrere UIs offen sind und dann auch nur das, was als letztes zugefügt wurde (man beachte: die Schleife zählt rückwärts, s. Kommentare!!).
Ich vermute ich habe einen Denkfehler da drinnen. Aber ich komm nicht wirklich drauf, habs mir immer wieder angeschaut und auch zwei Nächte drüber geschlafen...
Beim Debuggen hab ich aber schon feststellen können, dass die Aufrufe zum Auslesen und wieder Setzen der Paramter jedenfalls keine Fehler verursachen, also das sollte klappen.
Wenn jemand den Fehler entdeckt wäre das gut, ich wäre aber auch dankbar für einen Ansatz beim Debuggen (was würdet ihr (als erstes) überprüfen?). Oder was würdet ihr sogar anders machen?
Edit: Hab mal versucht statt
KopieAngewendeteEffekte
mit e.OldItems
zu arbeiten, da werden die Parameter richtig übernommen, aber die Eigenschaft .Handle
nicht, zumindest glauch ich dass es das ist, die Effekte werden jedenfalls nicht richtig disposed... Ich guck mir das mal weiter an.. Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „kafffee“ ()