namespace QuikDawEditor.EDITING; public partial class VstMethods { public static List ScannedVstEffectReferences { get; set; } = new List(); public static List ScannedVstInstrumentReferences { get; set; } = new List(); public static List ReturnedWithErrorVstReferences32bit { get; set; } = new List(); public static List ReturnedWithErrorVstReferencesIgnored { get; set; } = new List(); public static List ReturnedWithErrorVstReferencesOther { get; set; } = new List(); public static void SaveVstiFavorites() { File.WriteAllText(VstiFavoritesFilePath, JsonSerializer.Serialize(VstiFavorites, typeof(ObservableCollection), standardJSO)); } public static void GetVstiFavorites() { string readText = File.ReadAllText(VstiFavoritesFilePath); if (readText == "") VstiFavorites = new ObservableCollection(); else VstiFavorites = (ObservableCollection)JsonSerializer.Deserialize(readText, typeof(ObservableCollection), standardJSO); } public static void SaveVstFxFavorites() { File.WriteAllText(VstFxFavoritesFilePath, JsonSerializer.Serialize(VstFxFavorites, typeof(ObservableCollection), standardJSO)); } public static void GetVstFxFavorites() { string readText = File.ReadAllText(VstFxFavoritesFilePath); if (readText == "") VstFxFavorites = new ObservableCollection(); else VstFxFavorites = (ObservableCollection)JsonSerializer.Deserialize(readText, typeof(ObservableCollection), standardJSO); } public static void AddVSTInstrument(Track addToTrack, VstPluginReference vstPluginRef) { try { ActiveVstPlugin newVstPlugin = vstPluginRef.CreateActivePlugin(); newVstPlugin.OpenActivePluginContext(); addToTrack.TrackInstrumentVsts.Add(newVstPlugin); //set initial parameters if (newVstPlugin.VstParameters.Count == 0) for (int paramno = 0; paramno < newVstPlugin.myContext.PluginInfo.ParameterCount; paramno++) { newVstPlugin.VstParameters.Add(new VstParameter()); newVstPlugin.VstParameters[paramno].ParameterName = newVstPlugin.myContext.PluginCommandStub.Commands.GetParameterName(paramno); newVstPlugin.VstParameters[paramno].ParameterValue = newVstPlugin.myContext.PluginCommandStub.Commands.GetParameter(paramno); } else for (int paramno = 0; paramno < newVstPlugin.myContext.PluginInfo.ParameterCount; paramno++) newVstPlugin.myContext.PluginCommandStub.Commands.SetParameter(paramno, newVstPlugin.VstParameters[paramno].ParameterValue); if (newVstPlugin.IsGeneralMidi) { //Initialize BassMidi vst (general midi) //byte[] chunkbytes = new byte[0xCF4]; byte[] chunkbytes = new byte[newVstPlugin.myContext.PluginCommandStub.Commands.GetChunk(true).Length]; //Set soundfont filename string soundfontFile = AppDomain.CurrentDomain.BaseDirectory + @"\GeneralMidiVst\Reality_GMGS_falcomod.sf2"; byte[] gBytes = Encoding.Unicode.GetBytes(soundfontFile); Array.Copy(gBytes, chunkbytes, gBytes.Length); //Set soundfont volume Array.Copy(new byte[] { 0x64 }, 0, chunkbytes, 0x20A, 1); //Set kill last note only Array.Copy(new byte[] { 0x80, 0x3F, }, 0, chunkbytes, 0xA55, 2); //Set polyphony Array.Copy(new byte[] { 0x80, 0x43, }, 0, chunkbytes, 0xA6D, 2); //Set program default Array.Copy(new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, chunkbytes, 0xA70, 4); //Set channel volume Array.Copy(new byte[] { 0x58, }, 0, chunkbytes, 0xA83, 1); //Set pitchbend(0) Array.Copy(new byte[] { 0x20 }, 0, chunkbytes, 0xA78, 1); //Set pan default Array.Copy(new byte[] { 0x40 }, 0, chunkbytes, 0xA87, 1); newVstPlugin.myContext.PluginCommandStub.Commands.SetChunk(chunkbytes, true); newVstPlugin.PluginChunk = chunkbytes; //newVstPlugin.VstPluginChannels.Add(new GMChannel()); } } catch (Exception ex) { Debug.WriteLine("Error adding vst plugin\n" + ex.Message); } editingProject.NeedsSaving = true; } public static void AddVSTEffect(Track addToTrack, VstPluginReference vstPluginRef) { try { ActiveVstPlugin newVstPlugin = vstPluginRef.CreateActivePlugin(); newVstPlugin.OpenActivePluginContext(); addToTrack.TrackEffectVsts.Add(newVstPlugin); //set initial parameters when opening vst window if (newVstPlugin.VstParameters.Count == 0) for (int paramno = 0; paramno < newVstPlugin.myContext.PluginInfo.ParameterCount; paramno++) { newVstPlugin.VstParameters.Add(new VstParameter()); newVstPlugin.VstParameters[paramno].ParameterName = newVstPlugin.myContext.PluginCommandStub.Commands.GetParameterName(paramno); newVstPlugin.VstParameters[paramno].ParameterValue = newVstPlugin.myContext.PluginCommandStub.Commands.GetParameter(paramno); } else for (int paramno = 0; paramno < newVstPlugin.myContext.PluginInfo.ParameterCount; paramno++) newVstPlugin.myContext.PluginCommandStub.Commands.SetParameter(paramno, newVstPlugin.VstParameters[paramno].ParameterValue); Debug.WriteLine("Added new vstplugin: " + newVstPlugin.PluginName + " :: " + newVstPlugin.VstDllFileFullPath); } catch (Exception ex) { Debug.WriteLine("Error adding vst plugin\n" + ex.Message); } editingProject.NeedsSaving = true; } internal static void ScanVsts(string thisdir, bool checksubdirs) { try { VstPluginReference newVSTpir; foreach (string f in Directory.GetFiles(thisdir).Where(ff => ff.EndsWith(".dll"))) { if (Settings.Default.SkipLoadingPlugins.Contains(f)) { newVSTpir = new VstPluginReference() { VstDllFileFullPath = f, PluginName = Path.GetFileName(f), PluginCategory = "(Ignored)", SkipLoadingPlugin = true }; ReturnedWithErrorVstReferencesIgnored.Add(newVSTpir); } else { if (!Settings.Default.ErrorProducingVsts.Contains(f)) { //Debug.WriteLine("GetProcAddress(pluginmain)=" + GetProcAddress(LoadLibrary(f), "VSTPluginMain").ToString() + " _______(" + f + ")"); //Debug.WriteLine("GetProcAddress(main )=" + GetProcAddress(LoadLibrary(f), "main").ToString() + " _______(" + f + ")"); if (!(f.Contains("Jacobi.Vst.Core.dll") || f.Contains("net.dll"))) //if (GetProcAddress(LoadLibrary(f), "VSTPluginMain").ToString() != "0") // this returns 0 for VST.NET2 plugins.... { //Debug.WriteLine("vstname=" + Path.GetFileName(f) + "::::::::" + GetProcAddress(LoadLibrary(f), "VSTPluginMain")); newVSTpir = new VstPluginReference() { VstDllFileFullPath = f, PluginName = Path.GetFileName(f) }; switch (GetMachineType(f)) { case MachineType._32bit: newVSTpir.PluginName = newVSTpir.VstDllFile; newVSTpir.PluginCategory = "32-bit - Could not load"; newVSTpir.VstDllFile = ""; newVSTpir.ReturnedWithoutError = false; ReturnedWithErrorVstReferences32bit.Add(newVSTpir); break; case MachineType._64bit: try { newVSTpir.GetContextInfo(); } //catch (Exception vstex) { MessageBox.Sxhow("This vst\n" + System.IO.Path.GetFileName(f) + "\nis not usable (probably not 64-bit)\n\n" + vstex.Message); } //catch { MessageBox.Show("error getting context info: " + newVSTpir.VstDllFileFullPath); newVSTpir.PluginName = newVSTpir.VstDllFile; newVSTpir.PluginCategory = "Could not load"; newVSTpir.VstDllFile = ""; newVSTpir.ReturnedWithoutError = false; } catch (Exception ex2) { Debug.WriteLine("Could not load: " + newVSTpir.VstDllFile + ":::" + ex2.Message); newVSTpir.PluginName = newVSTpir.VstDllFile; newVSTpir.PluginCategory = "Could not load"; newVSTpir.VstDllFile = ""; newVSTpir.ReturnedWithoutError = false; } //if (tryReturnCIString != "ok") ((EditorWindow)(App.Current.MainWindow)).ShowLocalMessage(tryReturnCIString); //if (newVSTpir.PluginName.Contains("SynthMaster")) //{ // string ss = newVSTpir.PluginName + "\ncat: " + newVSTpir.PluginCategory + "\nvstver: " + newVSTpir.VSTVersion + "\npluginVer: " + newVSTpir.PluginVersion + "\n " + newVSTpir.Flags; // MessageBox.Sxhow(ss); //} if (newVSTpir.PluginCategory == "Synth") ScannedVstInstrumentReferences.Add(newVSTpir); else ScannedVstEffectReferences.Add(newVSTpir); break; } } } } } if (checksubdirs) foreach (string subdir in Directory.GetDirectories(thisdir)) ScanVsts(subdir, checksubdirs); } catch (Exception ex) { if (thisdir == "") MessageBox.Show("VST scanning directory is not set - No Vsts will be loaded"); else MessageBox.Show("Could not scan in directory:\n" + thisdir + "\n\n" + ex.Message); } } public enum MachineType { Native = 0, _32bit = 0x014c, Itanium = 0x0200, _64bit = 0x8664 } public static MachineType GetMachineType(string fileName) { const int PE_POINTER_OFFSET = 60; const int MACHINE_OFFSET = 4; byte[] data = new byte[4096]; using (Stream s = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { s.Read(data, 0, 4096); s.Close(); } // dos header is 64 bytes, last element, long (4 bytes) is the address of the PE header int PE_HEADER_ADDR = BitConverter.ToInt32(data, PE_POINTER_OFFSET); int machineUint = BitConverter.ToUInt16(data, PE_HEADER_ADDR + MACHINE_OFFSET); return (MachineType)machineUint; } }