Beispiel #1
0
        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;
                }
            }
        }
Beispiel #2
0
        public void UnpatchPluginFromMidiInput()
        {
            foreach (var inputDevice in _midiInputDevices)
            {
                inputDevice.Close();
                inputDevice.Dispose();
            }

            _midiTarget = null;
        }
Beispiel #3
0
        public void LoadVst(RemoteVstPlugin remoteVst, bool debug = false)
        {
            LoadVstInternal(remoteVst, debug);

            if (remoteVst.BackgroundProcessing)
            {
                lock (_audioLock)
                {
                    lock (_guiLock)
                    {
                        _plugins.Add(remoteVst);
                    }
                }
            }
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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();
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
 public void PerformIdleLoop(RemoteVstPlugin plugin, int loops)
 {
     IdleLoop(plugin.PluginContext, loops);
 }
Beispiel #9
0
        public void MIDI_NoteOn(RemoteVstPlugin plugin, byte Note, byte Velocity, int deltaFrames = 0)
        {
            byte Cmd = 0x90;

            MIDI(plugin, Cmd, Note, Velocity, deltaFrames);
        }
Beispiel #10
0
        public void MIDI_CC(RemoteVstPlugin plugin, byte Number, byte Value)
        {
            byte Cmd = 0xB0;

            MIDI(plugin, Cmd, Number, Value);
        }
Beispiel #11
0
 public void ReloadPlugin(RemoteVstPlugin remoteVst)
 {
     UnloadVst(remoteVst);
     LoadVstInternal(remoteVst);
 }
Beispiel #12
0
 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);
        }