Teleport - Strangest discovery of Rack VST so far....

Mine is set up as per manufacturer and it works with that. Don’t really want to change that setting right now so can’t say for sure as to the other options.

If I had to guess I would say it would work for Per Plugin (as multiple instances of same plugin are sandboxed together), but not for individually hosted (as the instances would be in different sandboxes).

But hey - we’re talking Teleportation! who’s to say the walls of a mere box will stand in the way? You might need a sandbox with quantum shielding or something like that…

1 Like

No, that’s fine, that’s good enough to know…

I’m going to assume that if Rack instances are individually hosted then it won’t…

That’s how I have mine set at the moment - as I like to restrict core affinity and farm out certain plugins to groups of cores using Process Lasso.

But until Rack VST has access to more than 1 CPU thread, there’s not much point in doing that, to be fair - so I’ll probably change Rack to the Bitwig default

Can’t wait for the full release of this module!!

I am waiting patiently as well. This will hopefully be the solution to route one patch to different midi-channels in Ableton.

I just did a quick test on this which suggests it would work. (I’m in Bitwig but principle should hopefully work in Live).

In first Rack instance, I had a NoteSeq 16 sending V/Oct and Gate out by Teleport

In second instance I had Teleport receiving the V/Oct and Gate and connected those Teleport outputs to CV > Midi

On a third track I had Serum set up to receive midi from the second Rack instance. Serum seems to be playing things in tune and in time.

1 Like

interesting this came up in another topic

I had a quick look at the code and I say it is not thread-safe…

first I should say, its common for threading bugs to lurk for really long periods of time, and not cause any issue - simply because they require certain pre-conditions to be triggered, and also often very ‘unfortunate’ timing. also, there can be other things in play e.g. timing constraints that are in play that are unintentional.

sure std::map is ok for const access… but not for being modified.

I’ll just give one example… so the processing code has this in it.

	void process(const ProcessArgs &args) override {

		if(sourceExists(label)){
			TeleportInModule *src = sources[label];
			for(int i = 0; i < NUM_TELEPORT_INPUTS; i++) {
				Input input = src->inputs[TeleportInModule::INPUT_1 + i];

theres a couple of issues I believe here:

first the divisibility of sourceExists (which is find) and then the access. in a multi-threaded environment (esp with multi cores), there is nothing to stop the source existing for the IF statement (so true), but then for the source to disappear before sources[label] is executed.

even if this was ok, another thread (Id assume the UI thread) could delete the object that was refer to in the map whilst we have a local copy of the pointer . i.e. its not just the map that needs to be safe, but also the thing it contains.

I could go on… but you probably get the picture…

“But it doesn’t crash” - well lucky you :slight_smile:

there are quite a lot of pre-conditions at play here… obviously, its only going to occur if you use these objects in your patch. next. I think its most likely to occur with multi dsp threads (vcv standalone defaults to one, but in daw, we are likely be using more)

the other reason is the ‘danger time window’ is very small… if we look at above, we can see it quickly access the pointer, and just sets a few floats … this is going to be very few cpu cycles in which to get it wrong… also this is only an issue when the map changes, and in particular when the source is removed. so it’s extremely unlikely that this would occur at the same time. (but importantly, not impossible)

also you’d need to look at the vcv rack ui code, it may be that it is some how protecting this module with additional timing constraints. e.g. if it suspended processing of all modules whilst it removed modules or something similar.

as I said, in multi threaded coding, it is not unusual to have code that can run for days/months and be perfectly happy… then one bad day, it just crashes out of the blue.

so you’ll almost certainly be fine… but id not want to risk it in a live performance, or have unsaved work, and Id be cautious in recommending it to others in multi threaded environment.

4 Likes

Yep, you speak the truth. I’ve seen a lot of threading issues in source code I’ve looked at.

And, as always, you can’t just use a mutex from the audio thread or badness will happen.

You are right, there are likely several thread-safety issues with Teleport, and it’s probably not suitable for live performance. Basically I got the idea and just tried to see if it works, and so far I don’t know of it causing crashes.

It would be good to verify how the Rack engine handles deletions, to see if the TOCTOU race condition you mention can cause problems in practice, and perhaps document it in the code.

I’m happy to accept a PR that makes the module thread-safe! I have basically zero experience with lock-free multi-threaded programming, which is what one would want for audio I guess. In prinicple the architecture should be okay for multithreading, there is always only one input that can write to the shared map, and multiple teleport outputs can read from it.

4 Likes