I’m a C# (WPF) dev who is super interested in using JUCE for audio. Is it possible to make a DLL that handles all the DSP work in JUCE but does everything else in C#? I know I can make calls to an unmanned DLL from C#, but I’m wondering if anything specific about JUCE that wouldn’t allow or break it.
Forgive me if this is a stupid question but I’ve read some similar posts on here where people seemed to be having trouble.
So you want to use JUCEs audio classes but have the UI in C#? It’s possible but it’s expensive to marshal things between managed and unmanaged code. I don’t think it would scale very well to a full application. Why not just go C++/Juce entirely?
Which likely doesn’t matter if the actual audio data or similar high frequency data isn’t involved. (And even in those cases the overhead may be acceptable. Everything doesn’t necessarily need to be super optimized.)
There’s a great WPF framework called Prism that I love using. You can do some really cool things like de-coupling, modularity, inject views into regions, etc. It’s really good for scaling and application re-use. If that way is too expensive, is there another way you’d recommend?
I of course can’t promise you it’s 100% possible, since I haven’t done it myself. But in principle there shouldn’t be a problem to build a DLL that exports some C functions, that are internally implemented as C++ and use Juce. (For example Juce’s VST2 plugin client works that way.) Note that you are almost certainly going to need to implement the C layer. Using C++ code directly from a DLL is already a headache with C++ itself!
Another possibility could be to implement the Juce parts as an external process and implement an interprocess communication system between that and the C# application.
No, interprocess communication would have more overhead and is more complicated to implement. But the DLL and the marshalling involved could end up close to the overhead and code complexity anyway…The benefit of the external process approach would be that you wouldn’t need to deal with any possible issues with threading, message loops and those kinds of things together with the C# code. I don’t know anything about how C# and WPF applications work, but I’d consider those potential issues.
check out swig. It generates the c++/c# bindings automatically and can save you quite a lot of manual labour when doing cross language stuff like this. I used it to interface c++ to unity in several occasions and it worked great. Some stuff (directors if I remember correctly) did not work or required some convincing - but all quirks considered, it was much more pleasant and less error prone than writing this glue code manually.
Looks cool. I’ve currently written the glue code (connecting C# to C++) in Microsoft’s C++/CLI language, and it’s pretty painful because there is very little documentation or examples available.
As to performance, I’ve had no trouble whatsoever, because most of your CPU-intensive code will be pure c++/JUCE.
I’ve done some marshalling going the other way - calling a managed C# DLL from a C++ app. It was a bit painful but once the pattern was in place not too bad to manage. I’d say what you want to do is totally possible, and potentially a good way to go about building something, but you may run into issues where certain JUCE features don’t work properly (I think only if you are building a UWP app). Also try and keep the cross-language calls to a minimum, only where necessary. Note its also possible to have JUCE generate part of your UI, good for bits where the audio and GUI are tightly coupled, e.g. waveforms, visualisers etc.
That looks awesome, thank you! Big doc too so that’s super useful.
This is unfortunately a huge concern.
I’ve decided to try using Qt/QML with Juce and keep the c# interop as a potential backup plan. It’s cool that it can be done and I’ll definitely use it in a different project but doesn’t seem like a good idea with responsive knobs and sliders constantly firing at unmanaged code.
For anyone looking at this in the future: Qt Quick is similar to WPF and shouldn’t be too bad of a learning curve. It requires some workarounds (like bidirectional binding) but you can do MVVM so it’ll feel familiar.