Hi everyone..im new here and a bit lame with coding...anyway ...ive been trying to create a minimal VSThost with C# and VST.NET pack....
The code returns no errors but i cannot produce sound...just UI...any idea? Thanks (PS: im posting the full code cause im not sure what is buggins....
The code returns no errors but i cannot produce sound...just UI...any idea? Thanks (PS: im posting the full code cause im not sure what is buggins....
C#:using Jacobi.Vst.Core; using Jacobi.Vst.Core.Host; using Jacobi.Vst.Host.Interop; using Microsoft.VisualBasic; using NAudio.Midi; using NAudio.Wave; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Windows.Forms; namespace Jacobi.Vst.Samples.Host; partial class MainForm : Form { private List<VstPluginContext> _plugins = new List<VstPluginContext>(); public MainForm() { InitializeComponent(); Text = "VST HOST"; } private VstPluginContext OpenPlugin(string pluginPath) { try { var hostCmdStub = new DummyHostCommandStub(); hostCmdStub.PluginCalled += new EventHandler<PluginCalledEventArgs>(HostCmdStub_PluginCalled); var ctx = VstPluginContext.Create(pluginPath, hostCmdStub); // actually open the plugin itself ctx.PluginCommandStub.Commands.Open(); var plugin = ctx.PluginCommandStub; var commands = plugin.Commands; if (commands.EditorGetRect(out var rect)) { int width = rect.Right - rect.Left; int height = rect.Bottom - rect.Top; using (Form editorForm = new Form()) { editorForm.Text = commands.GetEffectName(); editorForm.ClientSize = new System.Drawing.Size(width, height); editorForm.StartPosition = FormStartPosition.CenterParent; commands.EditorOpen(editorForm.Handle); // Keep GUI updating var timer = new Timer { Interval = 30 }; timer.Tick += (s, ev) => commands.EditorIdle(); timer.Start(); editorForm.ShowDialog(this); commands.EditorClose(); } } else { MessageBox.Show("This plugin does not provide a GUI."); } return ctx; } catch (Exception e) { MessageBox.Show(this, e.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Error); } return null; } private void ReleaseAllPlugins() { _plugins.Clear(); } public object PluginContext { get; private set; } private void HostCmdStub_PluginCalled(object sender, PluginCalledEventArgs e) { var hostCmdStub = (DummyHostCommandStub)sender; // can be null when called from inside the plugin main entry point. if (hostCmdStub.PluginContext.PluginInfo != null) { Debug.WriteLine("Plugin " + hostCmdStub.PluginContext.PluginInfo.PluginID + " called:" + e.Message); } else { Debug.WriteLine("The loading Plugin called:" + e.Message); } } private IWavePlayer _waveOut; private VstAudioProcessor _vstProcessor; private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { ReleaseAllPlugins(); } public class HostCommandStub : IVstHostCommandStub { IVstPluginContext IVstHostCommandStub.PluginContext { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } IVstHostCommands20 IVstHostCommandStub.Commands => throw new NotImplementedException(); public int GetSampleRate() => 44100; public int GetBlockSize() => 512; public VstTimeInfo GetTimeInfo(VstTimeInfoFlags filterFlags) => new VstTimeInfo { SampleRate = 44100 }; public void ProcessIdle() { } public void UpdateDisplay() { } public void SetParameterAutomated(int index, float value) { } public int GetCurrentPluginID() => 1234; public int GetVersion() => 1000; public bool SizeWindow(int width, int height) => true; } // Compatible with both VST.NET 1.x and 2.x private static VstAudioBuffer[] GetBuffersCompat(VstAudioBufferManager mgr) { var type = mgr.GetType(); var prop = type.GetProperty("Buffers"); if (prop != null) { var value = prop.GetValue(mgr); if (value is System.Collections.IEnumerable enumerable) return enumerable.Cast<VstAudioBuffer>().ToArray(); } var method = type.GetMethod("GetBuffers"); if (method != null) { var result = method.Invoke(mgr, null); if (result is System.Collections.IEnumerable enumerable) return enumerable.Cast<VstAudioBuffer>().ToArray(); } // fallback for older API var countProp = type.GetProperty("BufferCount"); int count = (int)(countProp?.GetValue(mgr) ?? 0); return Enumerable.Range(0, count) .Select(i => (VstAudioBuffer)type.GetMethod("get_Item")?.Invoke(mgr, new object[] { i })) .ToArray(); } public class VstAudioProcessor : ISampleProvider { private readonly VstPluginContext _plugin; private readonly WaveFormat _waveFormat; private readonly int _blockSize = 512; private readonly VstAudioBufferManager _inputMgr; private readonly VstAudioBufferManager _outputMgr; private readonly VstAudioBuffer[] _inputs; private readonly VstAudioBuffer[] _outputs; private double _phase; public WaveFormat WaveFormat => _waveFormat; public VstAudioProcessor(VstPluginContext plugin) { _plugin = plugin; _waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 2); _inputMgr = new VstAudioBufferManager(2, _blockSize); _outputMgr = new VstAudioBufferManager(2, _blockSize); _inputs = _inputMgr.Buffers.ToArray(); _outputs = _outputMgr.Buffers.ToArray(); var cmds = _plugin.PluginCommandStub.Commands; cmds.SetSampleRate(44100); cmds.SetBlockSize(_blockSize); cmds.MainsChanged(true); } public int Read(float[] buffer, int offset, int count) { int frames = Math.Min(count / 2, _blockSize); double freq = 440.0; double phaseStep = 2.0 * Math.PI * freq / WaveFormat.SampleRate; for (int i = 0; i < frames; i++) { float sample = (float)Math.Sin(_phase); _phase += phaseStep; if (_phase > 2 * Math.PI) _phase -= 2 * Math.PI; _inputs[0][i] = sample; _inputs[1][i] = sample; } _plugin.PluginCommandStub.Commands.ProcessReplacing(_inputs, _outputs); int index = offset; for (int i = 0; i < frames; i++) { buffer[index++] = _outputs[0][i]; buffer[index++] = _outputs[1][i]; } return frames * 2; } } private VstPluginContext _plugin; private void ViewPluginBtn_Click(object sender, EventArgs e) { var path = "C:\\ATMOS\\ATMOS.dll"; InitAudio(path); OpenPlugin(path); } private void InitAudio(string pluginPath) { // 1?? Create VST host var hostStub = new DummyHostCommandStub(); _plugin = VstPluginContext.Create(pluginPath, hostStub); // 2?? Open the plugin _plugin.PluginCommandStub.Commands.Open(); _plugin.PluginCommandStub.Commands.MainsChanged(true); // 3?? Create the audio processor (this handles plugin processing) _vstProcessor = new VstAudioProcessor(_plugin); // 4?? Initialize the audio output (WaveOut) _waveOut = new WaveOutEvent(); _waveOut.Init(_vstProcessor); // 5?? Start playback _waveOut.Play(); MessageBox.Show("Audio engine initialized and started!"); } }