public void UnloadVst(RemoteVstPlugin remoteVst) { lock (_audioLock) { lock (_guiLock) { if (remoteVst.BackgroundProcessing) { Debug.WriteLine($"{remoteVst.DllFilename}: removing from list"); _plugins.Remove(remoteVst); } UnpatchPluginFromAudioOutput(); UnpatchPluginFromMidiInput(); if (remoteVst.IsEditorOpen) { Debug.WriteLine($"{remoteVst.DllFilename}: closing editor in shutdown"); Application.Current.Dispatcher.Invoke(() => { remoteVst.CloseEditor(); }); } Debug.WriteLine($"{remoteVst.DllFilename}: stopping process"); remoteVst.PluginContext?.PluginCommandStub.StopProcess(); Debug.WriteLine($"{remoteVst.DllFilename}: turning off"); remoteVst.PluginContext?.PluginCommandStub.MainsChanged(false); Debug.WriteLine($"{remoteVst.DllFilename}: starting shutdown"); remoteVst.PluginContext?.PluginCommandStub.Close(); remoteVst.PluginContext = null; remoteVst.IsLoaded = false; } } }
public void UnpatchPluginFromMidiInput() { foreach (var inputDevice in _midiInputDevices) { inputDevice.Close(); inputDevice.Dispose(); } _midiTarget = null; }
public void LoadVst(RemoteVstPlugin remoteVst, bool debug = false) { LoadVstInternal(remoteVst, debug); if (remoteVst.BackgroundProcessing) { lock (_audioLock) { lock (_guiLock) { _plugins.Add(remoteVst); } } } }
private static void LoadVstInternal(RemoteVstPlugin remoteVst, bool debug = false) { var hostCommandStub = new NewHostCommandStub(remoteVst.Logger); hostCommandStub.PluginDll = Path.GetFileName(remoteVst.DllPath); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Loading plugin"); var ctx = VstPluginContext.Create(remoteVst.DllPath, hostCommandStub); ctx.Set("Plugin", remoteVst); remoteVst.PluginContext = ctx; ctx.Set("PluginPath", remoteVst.DllPath); ctx.Set("HostCmdStub", hostCommandStub); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Opening plugin"); ctx.PluginCommandStub.Open(); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Setting Sample Rate {SampleRate}"); ctx.PluginCommandStub.SetSampleRate(SampleRate); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Setting Block Size {BlockSize}"); ctx.PluginCommandStub.SetBlockSize(BlockSize); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Setting 32 bit precision"); ctx.PluginCommandStub.SetProcessPrecision(VstProcessPrecision.Process32); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Activating output"); remoteVst.PluginContext.PluginCommandStub.MainsChanged(true); remoteVst.Logger.Debug($"{hostCommandStub.PluginDll}: Start Processing"); ctx.PluginCommandStub.StartProcess(); remoteVst.IsLoaded = true; }
public void PatchPluginToMidiInput(RemoteVstPlugin plugin, MidiInputDevice device) { _midiTarget = plugin; var midiService = new MidiService(); var midiInput = midiService.GetMidiEndpoint(device); if (midiInput == null) { throw new Exception( $"Unable to open MIDI device {device.Name} because the device (currently) doesn't exists"); } midiInput.NoteOn += MidiInputOnNoteOn; midiInput.NoteOff += MidiInputOnNoteOff; midiInput.Open(); _midiInputDevices.Add(midiInput); }
public void PatchPluginToAudioOutput(RemoteVstPlugin plugin, AudioOutputDevice device, int latency) { var audioService = new AudioService(); var ep = audioService.GetAudioEndpoint(device); if (ep == null) { throw new Exception( $"Unable to open audio device {device.Name} because the device (currently) doesn't exist"); } UnpatchPluginFromAudioOutput(); _outputDevice = new WasapiOut(ep, AudioClientShareMode.Shared, true, latency); _vstWaveProvider = new VSTStream(); _vstWaveProvider.pluginContext = plugin.PluginContext; _vstWaveProvider.SetWaveFormat(_outputDevice.OutputWaveFormat.SampleRate, _outputDevice.OutputWaveFormat.Channels); _outputDevice.Init(_vstWaveProvider); _outputDevice.Play(); }
private void MIDI(RemoteVstPlugin plugin, byte Cmd, byte Val1, byte Val2, int deltaFrames = 0) { /* * Just a small note on the code for setting up a midi event: * You can use the VstEventCollection class (Framework) to setup one or more events * and then call the ToArray() method on the collection when passing it to * ProcessEvents. This will save you the hassle of dealing with arrays explicitly. * http://computermusicresource.com/MIDI.Commands.html * * Freq to Midi notes etc: * http://www.sengpielaudio.com/calculator-notenames.htm * * Example to use NAudio Midi support * http://stackoverflow.com/questions/6474388/naudio-and-midi-file-reading */ var midiData = new byte[4]; midiData[0] = Cmd; midiData[1] = Val1; midiData[2] = Val2; midiData[3] = 0; // Reserved, unused var vse = new VstMidiEvent(deltaFrames, /*NoteLength*/ 0, /*NoteOffset*/ 0, midiData, /*Detune*/ 0, /*NoteOffVelocity*/ 127); var ve = new VstEvent[1]; ve[0] = vse; plugin.PluginContext.PluginCommandStub.ProcessEvents(ve); }
public void PerformIdleLoop(RemoteVstPlugin plugin, int loops) { IdleLoop(plugin.PluginContext, loops); }
public void MIDI_NoteOn(RemoteVstPlugin plugin, byte Note, byte Velocity, int deltaFrames = 0) { byte Cmd = 0x90; MIDI(plugin, Cmd, Note, Velocity, deltaFrames); }
public void MIDI_CC(RemoteVstPlugin plugin, byte Number, byte Value) { byte Cmd = 0xB0; MIDI(plugin, Cmd, Number, Value); }
public void ReloadPlugin(RemoteVstPlugin remoteVst) { UnloadVst(remoteVst); LoadVstInternal(remoteVst); }
public void EnableTimeInfo(RemoteVstPlugin remoteVst) { ((NewHostCommandStub)remoteVst.PluginContext.HostCommandStub).DisableTimeInfo = false; }
private bool DoAudioWaveExport(RemoteVstPlugin plugin, string tempFileName, List <(int loop, int offset, byte note)> noteOnEvents, List <(int loop, int offset, byte note)> noteOffEvents,
public void ExportPresetAudioPreviewRealtime(RemoteVstPlugin plugin, PresetExportInfo preset, byte[] data, int initialDelay) { var ctx = plugin.PluginContext; if ((ctx.PluginCommandStub.PluginContext.PluginInfo.Flags & VstPluginFlags.IsSynth) == 0) { throw new EffectsNotSupportedException(); } // check if the plugin supports real time processing if (ctx.PluginCommandStub.CanDo(VstCanDoHelper.ToString(VstPluginCanDo.NoRealTime)) == VstCanDoResult.Yes) { throw new NoRealtimeProcessingException(); } //ctx.PluginCommandStub.SetChunk(data, false); var tempFileName = preset.GetPreviewFilename(true); Directory.CreateDirectory(Path.GetDirectoryName(tempFileName)); var noteOnEvents = new List <(int loop, int offset, byte note)>(); var noteOffEvents = new List <(int loop, int offset, byte note)>(); foreach (var note in preset.PreviewNotePlayer.PreviewNotes) { var onLoop = (double)VstHost.SampleRate * note.Start / VstHost.BlockSize; var onOffset = (int)((onLoop - (int)onLoop) * VstHost.BlockSize); noteOnEvents.Add((loop: (int)onLoop, offset: onOffset, note: (byte)(note.NoteNumber + 12))); var offLoop = (double)VstHost.SampleRate * (note.Start + note.Duration) / VstHost.BlockSize; var offOffset = (int)((offLoop - (int)offLoop) * VstHost.BlockSize); noteOffEvents.Add((loop: (int)offLoop, offset: offOffset, note: (byte)(note.NoteNumber + 12))); } var hasExportedAudio = false; for (var i = 0; i < 10; i++) { if (DoAudioWaveExport(plugin, tempFileName, noteOnEvents, noteOffEvents, initialDelay, preset.PreviewNotePlayer.MaxDuration)) { hasExportedAudio = true; break; } } if (hasExportedAudio) { ConvertToOGG(tempFileName, preset.GetPreviewFilename()); } else { plugin.Logger.Error("No audio data was returned by the plugin. Most likely it was still loading " + "the preset data; try to increase the audio preview pre-delay in the plugin " + "settings and try again"); } File.Delete(tempFileName); }