SOUL first beta release!

Well, all of it currently. You just need to have the patch DLL somewhere that can be dynamically loaded by the SOULPatchLibrary class: https://github.com/soul-lang/SOUL/blob/master/source/API/soul_patch/API/soul_patch_Library.h

We’ll be gradually releasing more code as we progress, this is just the first beta release.

Is the interface within the DLL/Dylib all C based? Would love to try out SOUL in more “exotic” settings like Rust or something.

The ABI to that DLL uses COM-style objects to make it as portable as humanly possible - there are only 2 or 3 functions exported from the DLL itself. I guess that most other languages have their own tricks for interfacing with that kind of thing, but our C++ interface classes are here:
https://github.com/soul-lang/SOUL/tree/master/source/API/soul_patch/API

Oh nice! I’m not that well-versed with COM, so time to read up on that :wink:

I’ll keep you posted on when/if I get this to run through Rust, if you’re interested.

Yeah, please do. I expect wrappers to be easy to write, and if not, we’ll fix things to make sure they are.

I’ve got the library loaded and createSOULPatchBundle() returns a valid pointer, but as a Mac developer I notice I’m not well-known enough with COM. Could you perhaps give some advice?

I thought COM was mostly a Windows-centric technology? Every tutorial I look for starts mentioning winapi funcs like CoInitialize() and the Windows Registry. What does it mean that the object pointers returned from createSOULPatchBundle() are COM-style?

I think in this case just that there’s a base class that has methods to increment and decrement reference counts. Probably nothing really to do with Windows COM as such.

Yeah, slowly realizing that too. COM-style is not the same as COM.

Still, pretty confused as to how to implement this in Rust (but that probably says more about my Rust skills than SOUL). Any advice is welcome. How for example would one start to wrap the SOUL dylib in C?

My understanding of COM interfaces and Rust, is that they are not compatible.

Rust works with a C ABI. COM is based on objects. Rust has no concept of class inheritance. We’d need a C compatible interface to SOUL to call it from Rust. This would also open it up to lots of other languages. IMO COM is limiting in this respect.

For example, the VST 3 spec, being based on COM, is also not compatible with Rust, which means that it is not possible to write a VST 3 plugin with Rust.

1 Like

Yes, I think you’d wrap this to C then call this from Rust. I’d have a go at this if I didn’t have a million other things to sort, but don’t worry, we’ll get that done soon enough…

TBH the direction this probably going to go in next year is for the patch layer to become open-source, and the closed-source layer to sink down into a more C-style flat, lower-level DLL that adds some more functionality. This won’t change the patch API, but will open up our lower-level APIs too, and that’s where we’ll start adding more language bindings. There’s quite a bit of internal work we need to do before we get there, so the current system was a simple way to get people access to the patch API in the meantime.

1 Like

Alright yeah, that was going to be my plan B as well. Wrapping to a C api seems completely doable. :slight_smile:

Hmm, that’s good to know! Very excited with where you’re taking this.

Not sure if I’d want to invest in baking a C api around SOUL for Rust right now if an actual flat C-like API is planned down the line, but I guess that’s understandable given this is still beta. If there’s anything I and others can currently do to speed up the process for language bindings I’d be glad to hear it.

@jules Just curious to know, how much of a challenge has this been? From the outside it seems like a pretty ambitious and difficult thing to take on. Sometimes in reality things that might seem really difficult aren’t actually as hard as expected, and sometimes things that look quite simple to do were incredibly difficult as the complexity is well hidden. I expect some bits of this would fall in either category, but on average, just wondering where this endeavour fits as a whole in that difficulty space.

What you think the major challenges will be going forwards to make a real success of this as you envision it?

Easily the hardest thing I’ve ever worked on! Never doubted that it’d be tricky, but underestimated it by a long way!

Yes, the thing that kept surprising us would be when a tiny, trivial-sounding feature would send us back-to-the-drawing-board for a couple of weeks refactoring huge chunks of the codebase, and this kept on happening!

…but yes, it’s all very unpredictable, e.g. I’d have thought that implementing generic functions would be hard, but it took me about a week. Whereas, there’s an obscure edge-case where you can’t use a certain type of compile-time constant as an array size, and we’re completely stumped as to how we can implement that without spending a month refactoring the entire type system!

Technically, I think we’re at the point now where the architecture’s pretty robust and the hard work now is behind the scenes in making really good back-ends, e.g. doing a really efficient graph parallelisation algorithm, getting it running on weird-shaped DSPs, making it stream smoothly across networks, getting it working on Metal, building a pure-WASM implementation for the web, etc.

Then there’s the work of convincing people to adopt it! And building a really great website for developers to share their code… Lots to do!

6 Likes

It’s an interesting point, I’m really intrigued to know what approach will be taken to encourage people to adopt it. What is/are the main problem(s) the technology is going to be presenting itself as a solution to? Both from the end-consumer musician/engineer and the developer perspectives. There’s the potential for Roli to make a massive impact with this tech. It can be challenging to deliver a powerful and focused message when there is such a broad range of applicable use-cases, so it’s fascinating to think about where that will ultimately go.

I’ll be really interested to know what is intended to come to market to support it all and how these can be partitioned in people’s minds. A high performance Mac with Metal and a first-party DSP accelerator product are such different platforms with unique strengths and weaknesses. Some types of algorithms clearly won’t work in some types of some systems even if they are both able to support the underlying SOUL technology due to compute/memory requirements, so how those needs will easily be communicated to consumers in understandable but somewhat abstract units of capability across such disparate platforms really intrigues me.

I would love this to present an opportunity for developers to work on powerful audio DSP platforms that are also available to a wide range of consumers in attractive formats (which they may or may not already own, be that a Mac with metal or a dedicated first/third party DSP card / thunderbolt tethered brick). The barriers to entry on traditional audio-focused DSP platforms are unattractively high for many developers and I’m optimistic this will lead to a big step forwards in that area, although it isn’t really clear in my mind yet where the gravitational pull is going to be at its strongest.

Is the Windows binary DLL usable with code compiled with MinGw? I would guess not, but just thought to ask anyway.

Can’t think of any reason why it wouldn’t work

Well, my understanding is that the Microsoft compiler and MinGW use a different low level structure for C++ classes and that can cause havoc especially when there are virtual methods involved. The DLL returns a pointer to a C++ object, right…?

No - the reason I did all that awful COM stuff was because it avoids all those C++ ABI problems.

2 Likes