Audio Plugin VST host

alienoiz

New member
Joined
Oct 22, 2025
Messages
1
Programming Experience
Beginner
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....

C#:
Expand Collapse Copy
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!");
    }
}
 
There is no point posting the same question in different forums here, if nobody knows then nobody knows.
 
Do you get sound when you just use the sample project that is in GitHub for that library?
 
Back
Top Bottom