Giter Club home page Giter Club logo

audioplugsharp's Introduction

AudioPlugSharp

Easily create VST3 audio plugins in C#

AudioPlugSharp provides a C++/CLI bridge to load managed audio plugins into VST hosts. User interfaces can be created with built-in support for WPF. Windows Forms interfaces are also possible.

Framework support is .NET Core only. By default, it is configured to use .NET 6.0.

See the SimpleExample and WPFExample projects for example usage.

Current Release

NuGet packages are available:

AudioPlugSharp (Needed for all plugins)

AudioPlugSharpWPF (Also needed for WPF user interfaces)

Plugin Project Setup and Deployment

NuGet Packages

Using the NuGet packages is the recommended way to build a project using AudioPlugSharp.

If you use the AudioPlugSharp/AudioPlugSharpWPF NuGet packages, copying the appropriate files to your output folder will be handled for you. You simply need to copy the files from the output folder to a folder on your VST plugin path (usually "C:\Program Files\Common Files\VST3").

Direct Referecing

If you are referencing AudioPlugSharp manually, your plugin project will need an assembly dependency on AudioPlugSharp.dll (and AudioPlugSharpWPF.dll if you are using it).

For deployment, you need to copy "AudioPlugSharpVst.vst3" to your output folder, and rename it to be "YourPluginDllNameBridge.vst3". So if your plugin dll is called "MyPlugin.dll", then you would rename "AudioPlugSharpVst.vst3" to "MyPluginBridge.vst3". You also need to copy "AudioPlugSharpVst.runtimeconfig.json" (or "wpf.runtimeconfig.json" if you are using WPF in your plugin) to your output folder as "YourPluginDllNameBridge.runtimeconfig.json". You also need to copy "Ijwhost.dll" to your output folder.

These steps can be done using a Post-build event. Have a look at the included sample plugins for examples - keep in mind you may need to change the source folder of the "copy" commands depending on where your copy of AudioPlugSharp is.

Examples

For an example of how to create your own plugin in its own solution, have a look at the LiveSpice VST plugin here:

https://github.com/dsharlet/LiveSPICE/tree/master/LiveSPICEVst

AudioPlugSharp Building Instructions

You will need to have CMake (https://cmake.org) installed.

From a shell, run the following:

git clone --recursive https://github.com/mikeoliphant/AudioPlugSharp
cd AudioPlugSharp
cd vstbuild
cmake.exe -G "Visual Studio 17 2022" -A x64 ../vst3sdk

Then you can load the solution in Visual Studio and build. Note that you will need to change the last line above if you have a different version of Visual Studio.

audioplugsharp's People

Contributors

federerer avatar mikeoliphant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

audioplugsharp's Issues

Plugins not showing in DAW

Hi @mikeoliphant,
I am trying to get a grip on the example plugins but have not yet succeeded on getting them to show up in Reaper or Ableton. I copy pasted the examples and moved the resulting binaries and jsons to my VST folder.
Is there anything that needs to be done for them to show in my DAW? Or is there any other way to "host" them to see that the plugin is working properly?

Cheers,

WPFExample not able to load in Ableton

Hello, I can succesfully build the complete VS solution, and Ableton is able to detect all three plugins. The Midi and Simple Gain plugins can be added to a track and are functional. The WPF example fails, with Ableton reporting:

image

(Failed to create the VST3 plug-in "WPF Example Plugin". The VST3 plug-in could not be found) in case the image doesn't show.

Am I missing something?

Bart

Advice on development flow

Hi,

I could use some advice on developing a VST. The problem is that when a DAW is open (I tried Reaper and Ableton), they block the VST folder, so new compilations are not allowed to be copied in there.

I tried creating three projects: 1 - the AudioPlugSharp interface 2 - the View that will populate the VST and 3 - the library that will generate content. 1 won't need much changes, 2 from time to time, 3 is where the work is going on. I was thinking to only compile 3 and move it to the folder, so 1 (and/or 2) would not block me from keeping the DAW open. But alas, this doesn't work.

Closing the DAW, creating a new song, then a track, selecting the VST etc for every change seems cumbersome. Are there more efficient approaches available?

Cheers, Bart

Parameter changes not propagated back to DAW UI

Hi Mike,

when implement my own plugin I noted an issue concerning parameter settings that can also be reproduced with the WPF sample:
Ableton has a built-in view of the registered parameters of any plugin.

  • When turning a knob in the Ableton view, the respective control also changes its value in the WPF plugin (right screenshot)
  • When turning the dial in the WPF sample, the corresponding Ableton button does not receive the update and stays where it was (left screenshot).

The actual processing takes place with the correct value anyway, so this is maybe just a matter of PropertyChange somewhere.
I checked a few commercial plugins which seem to get it right.

grafik

Let me know if you need any further assistance there and thanks in advance,

Dennis

GetPluginFactory not exported

Hello! I've had no trouble compiling your repo and using the example VSTs. However, when trying to make my own, using SimpleExample as a guide, I'm unable to get my compiled VST to load. If I try to load it in VSTHost, nothing happens. I tried the VST3 SDK validator and received this error:

.\validator.exe MyVst.dll
* Loading module...

        MyVst.dll

Invalid Module!
The dll does not export the required 'GetPluginFactory' function

My project does contain a reference to AudioPlugSharp.dll. I've also tried simply adding AudioPlugSharp to the solution and then adding a project reference. Same result.

I followed your instructions on the README... my output directory does contain the bridge, runtimeconfig, deps.json, and Ijwhost.dll.

Any other place I should be looking for how to resolve this? I'm guessing something is wrong with my build config, but I'm at a loss for where to check. Thanks!

Upgraded WPFExample

I updated your WPFExamplePlugin to work with stereo input.
I commented out the original mono instructions and inserted the stereo input code.
That way the programmer can see both.

Would be happy to contribute if you like.
Send me an e-mail at [email protected]
Will send to you.

Thanks again for all the work on this.

Bruce Krell

A Notification

Mike,

Just wanted to let you know about an action I am planning to take.
I have created 6 example plugins that go far beyond your simple example.
Attached is a detailed description of those plugins.
SamplePluginsByBK.pdf

Unfortunately, your samples do not really instruct a programmer on how to realistically use your layer in a plugin.
Same examples: implementing to pan algorithm on mono. You can't hear the effect of pan when you move from
left to right when you have a mono input. You do not explain anywhere that I could find the use of GetEditorView.
I stumbled around until I bugged you, and you told me. The example you sent me was not sufficient to really scope
out the use of overriding GetEditorView. I encountered numerous problems when implementing algorithms that had
to run inside a chain processed by a host such as Cakewalk or Waveform. Any control created in GetEditorView has
thread affinity to the UI thread in WPF. Values can't be read in the Process method without some clever programming.
There are a bunch of other issues that I address in these simple examples that a programmer has to accommodate
that are illustrated in my examples. I even encountered a problem with Cakewalk that Waveform does not have.

So, I am creating a github repository. My repository will simply be your repository with my examples added.
So, my repository will include the vstsdk, your layer implementation (just like you included the vstsdk) and my
examples. I will make sure that you are given full credit and acknowledgement for the AudioPlugSharp portions
of the repository.

One more change I made in your repository. I changed the size of your dial from 20 - 60. Your dials are just too small.
I commented out your declaration and added mine below. Ideally, the size should be adjustable by the programmer
in his plugin code. I'm sure there is a way to do that but I couldn't find it. My examples use a custom slider and a custom
rotary control that I obtained from another guy, modified and will be giving him full credit also.

Please don't take this as a criticism. Your layer is awesome and worked perfectly. But, using your layer in a chain
processed by a host with your own mixed custom user control and WPF controls introduces a lot of complexities
that had to be addressed.

Thanks for all the work you did.
The result was excellent.

Bruce Krell

PS, you can mark this closed as soon as you read it. I would have sent you a personal e-mail but you clearly
want me to communicate with you only through issues.

AssemblyResolver shouldn't be static.

Currently AssemblyResolver class and specifically
static AssemblyLoadContext^ loadContext = nullptr;
are static, which causes problems when I'm trying to load more than one plugin that are using AudioPlugSharp and are in different folders, because the second one tries to resolve assemblies from the first's location.

Loading multiple plugins built with different versions of .net framework crashes the host.

With current version of AudioPlugSharp you cannot load plugins build with different versions of .net framework at the same time, Ijwhost.dll - it will throw an exception as you can't load multiple .net versions from single process when using mixed mode assemblies. There are some other options like hosting api, but it's limited to calling a static method (like main ๐Ÿ˜‰) and getting a result. From my testing setting rollForward: LatestMajor in runtimeconfig.json helps, but it's not ideal, as plugin gets whatever newest version user has installed and there might be some breaking changes between major versions, but I think that It's better than crashing a host every time ๐Ÿ˜ I think that it should be possible by adding runtimeconfig.template.json to the project link.

Some Build Issues

Very elegant wrapper classes to hide all the confusing VST plumbing and wiring.

AudioPlugSharpVst will not compile under VS 2022, Must use VS 2019
This is an MS problem. They issued VS 2022 without upgrading the
Apphost Pack and the Nuget package restore.
Compiling AudioPlugSharpVst leads to an error message. I found
about 6 suggested fixes. None of them work. Stay away from VS 2022
for these projects
I don't think you can fix this issue. Only microsoft can.

Must run VS 2019 as administrator
if you don't run as administrator, you get all sorts of set local host errors.
These occur when trying to copy the bridge files in the post build step.
Running as administrator lets them work correctly

current release has vstsdk as debug but AudioPlugSharp and others as release
for both vstsdk, AudioPlugSharp, change SOLUTION Active config to Realease/x64
VS complains when vstsdk is debug but AudioPlugSharp is release.

in AudioPlugSharp, click on WPFExample to open .csproj
change root project to Microsoft.NET.sdk
WPFExample has a problem with the root project as currently configured

you can fix the last two issues so that they are no longer a problem.

you might want to update your instructions to discuss the first two issues.

Unable to compile example projects on VS2022 on Windows 11 machine

Hello, I've been struggling to build the example projects from the repo on VS2022 (I ran all of the other steps in VS2019 to get CMake commands working) but I keep getting errors for both projects (I've attached log files for SimpleExample/WPFExample to this issue ticket).

I am running this on a Windows 11 machine, and I wondered if this may cause an issue with building this project?

If you need any more details I'll be able to provide those

SimpleExample errors.txt
WPFExample errors.txt

HandleNoteOn / HandleNoteOff / HandleParameterChange does not get called or is inconsistent

Hi love your work!
I just tried making a small plugin for 10 hours, but even the example plugin does not work correctly? The functions above will not get called. Only HandleParameterChange will get called once per startup per plugin instance, but for some reason I can not get these functions to behave correctly. I have tried a lot of debugging, but I think this might not be a fault with my code? I am using FLStudio 21. I am very grateful for your work I think it's awesome to see C# for VST!

A Couple Of Issues

I have two problems that I can't seem to resolve.
Maybe you can give me insight if you have seen them before.

  1. Cakewalk suddenly started giving me a load error:
    AudioPlugSharVst, GetPluginFactory
    LoadError
    I have attached a screen dump. I tried cleaning/rebuilding, copying and
    renaming into project folders, nothing fixes the problem.
    Any idea why I would get this problem and how to fix it?

  2. The second problem is a bit more insidious.
    I have a bunch of simple apps in which I override GetEditorWindow.
    For all of them, I use WPF controls.
    So, I decided to do a custom user control.
    I found a really nice knob control on the web in xaml.
    Converted to list to a named canvas.
    so I created a User Control. I created knob programmatically
    in C#. Then made the knob a child of the named canvas.
    I put the code the generates the knob into a WPF DLL and
    that CODE calls the rotary control DLL to setup the handlers.
    Wrote a test driver. Works great, I can move the pointers around
    and read the dial values.

    Then, I integrated into a plugin.
    The knob displays beautifully.
    But, when I tried to read the value of the knob, I am told:
    can't access because that control is on a different thread from the
    calling thread.

    I have tried everything I can find to defeat this: using dispatcher,
    I get a null dispatcher, I finally seemed to find a way to get a non-null,
    dispatcher but the call to get the value returns nothing!

    I see you have done lots of plugins. Have you ever had this problem?
    How did you get around it? I looked through your code but don't see
    what you did. Any ideas?

    I have one other idea I will try -- putting the two classes into the
    plugin directly. That might fix the problem. Even if that fixes, don't
    understand why separate DLLs are a problem.

    Any ideas would be much appreciated.

Thanks.

Bruce

A Clarification

I am a bit confused about how the host and the plugin interact.

How can a plug-in detect that real data is coming through because the operator has pushed the start button?

From what I can tell using message boxes, when the operator loads the plug in into the host, a series
of function calls are made to the plugin which include Initialize, InitializeProcessing, and Start.
Then, regular calls to Process are made -- even though the user has not clicked on play in the host.

I have an algorithm that I only want to run in the presence of actual data.
If this algorithm runs without real data, then the algorithm crashes the application.

I tried checking if the inputSamples.Length is > 0. Well, that value is greater than zero although
there is no real data to process.

So, how do I detect that there is real data in the input buffer?
I thought that Start or InitializeProcessing would be called just after
the operator clicked on Play or that no Process calls would be made if the operator
had not clicked on Play. But, apparently, all of those are invoked at the time
the plugin is loaded.

So, How can a plug-in detect that real data is coming through because the operator has pushed the start button?
Any ideas?

You can't check for all zeros in the input buffer because that would also indicate silence.

Thanks.

Bruce

VST3 WpfExample not recognized in Cubase

I've cloned the AudioPlugSharp repository, build the vstsdk.sln and AudioPlugSharp.sln, moved the files to a folder which Cubase scans for plugins. But my Cubase 12 Elements does not recognize WpfExample plugin as a VST3 plugin, it thinks it's a VST2 plugin and adds comment "Unsupported Architecture". Am I doing something wrong ?

unsupported

Looking For Advice

Hi, Mike, Not sure this is an issue but I am seeing some strange behavior.
I wrote a plugin. The plugin creates a helper class to do the work. Inside the helper
class are some buffers used to store historical information.

When sound data enters the plugin, I check to see if parameters have changed. If so, I pass them to the helper class.
Then I pass the sound data to the helper class and the outputs are calculated.
The first plugin has 2 parameters. As I change the parameters, I can hear the output sound being updated.
So, the knob changes are correctly being fed to the helper class.

I then created two additional helper classes for two other plugins.
Plugin one has 4 parameters, plugin two has 5 parameters.
I am using the same approach.

One of these plugins doesn't produce any output sound.
The other plugin stops working after I change a few of the parameters.

I know the helper classes work perfectly.
All 3 are statistical algorithms.
I implemented them in matlab, then in C#.
The C# implementations are stress tested with a driver.
Furthermore, all 3 helper classes are used in a number of desktop applications
for the past 10 years.

The helper classes do maintain historical data so the buffers are redefined when
the parameters change. I tried making the helper class instances as static variables,
but that did not make any difference.

This is all pretty vague.

Any suggestions here?
Also, am wondering if the Plugins do some funny things with memory that is different from a desktop.
But, if so, why would the first plugin work correctly but the others mess up?

Thanks for any help/suggestions.

Bruce

What would it take to integrate this into a Maui app on WinUI-3, and then extend it for ios and android?

Two parts to this question:

  • Maui on Windows App SDK (WinUI-3).
    You mention C++ binding and WPF; adapting to Maui (but WIndows only at first) should be similar to what was done for WPF, AFAIK.

  • Any suggestions for getting the C++ bindings working on iOS/Android. .Net Core code should "just work" on those platforms, once it works in Maui on Windows. But I don't know what would need to be done re C++ bindings.

Using Other Controls

Mike,

I really need to able to manipulate the EditorView to add and process other controls, such as graphic windows, buttons, dropdowns, textbox, etc.

I finally was able to do that. I had to add about a dozen lines across 5 files to make the grid and the parameterdisplay accessible to the plugin. Finally implemented that and added a textblock and button example to
the WPF file. Also, added a button handler to the button. The button handler accesses the content property of the button, showing that you can use the "value" of any control you have placed in the grid within the Process method.

Would you like the files? would be a pretty powerful feature to add to your wrapper class.

Bruce Krell

Change parameter definition at runtime

First please link me to some way to buy you a beer, this is such a nice Library!

Is there a way to add/remove/modify parameters while the plugin is running?

I've tried calling add parameter but it doesn't seem to update in the daw, though it does seem to register in AudioPluginBase.parameterList.

I'm getting a list of parameters over the network (udp request), and I guess this could be done during Initialize but it would involve restarting the plugin each time the remote parameter list changes.

I noticed there's a kParamTitlesChanged event in the vst source. So I guess they can be renamed at runtime which would also be fine

Compile for MacOS / WinForm example

Hi !
I just stumbled upon this repository, and it looks pretty promising !
I used to work on VST2 development with Steinberg's SDK in C++.

I was wondering, does this compile also for MacOS hosts ?
I'm pretty unfamiliar with the VST3 specs.

On a side note, is there any example for a WinForm VST ?
And if not, could you point me to what method of your API I could use to modify a parameter from a WinForm control ?

Thanks !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.