Using the Tracktion engine within a plugin?

Is it possible to use the Tracktion engine in a plugin?
Specifically I would like to trigger the playback of tracks using incoming midi inside a plugin. I cannot see a way to do this, is it even possible?

Currently not easily, but this is what we expect to be a common workflow, so I want to improve it asap. I’ll try and get a demo together for this.

The biggest issue is that Tracktion Engine expects a fixed size block, where plugins have to be able to deal with any block size. So it means adding a bit of delay and a fifo so you can always pass fixed size blocks to the engine. I think the engine should work will variable sized blocks if you don’t use sends/return or racks.

The idea is you need to subclass AudioIODevice, my example was InternalAudioDevice and then

dm.deviceManager.addAudioDeviceType (new InternalAudioDeviceType());
dm.deviceManager.setCurrentAudioDeviceType ("Internal Device", true);

And then pass the plugin audio to your internal audio device. I have this 80% written, I’ll try and get it cleaned up and posted by next week some time.

1 Like

Thanks. Yes using the engine within a plugin will be a very common workflow I think.

Some basic example code would definitely be very helpful.

At least now I know where to start in getting it to work, thanks again.

G-Mon was able to assist me in getting the engine going as a plugin a while back. A couple of major issues for me after doing so were handling midi and syncing to the host transport. Hopefully those 2 things can be addressed.

I’ve started working on this and I have a proof of concept working:
https://github.com/Tracktion/tracktion_engine/blob/develop/examples/EngineInPluginDemo.h (This should get pushed to public repo in the next few hours)

To give the demo a try, once you create the project from the PIP, you’ll need to edit the plugin settings to enable midi in. This demo create an engine, adds a track, puts the midi in on the track and a synth plugin.

Audio in/out is working and live midi in is working.

There are still several issues to fix / things to implement. I still need to implement midi recording , midi out, and syncing to playhead. Also need to clean up some singletons.

2 Likes

Any updates on syncing to playhead?

1 Like

Any news about this? I’m interested in MIDI recording and IN/OUT when running tracktion engine inside a plugin. Thanks!

Also another question about tracktion engine in a plugin: will the engine try to access any audio/midi devices directly (eg ALSA in linux) or will it just stick to the audio/midi in/outs provided by the plugin host? I’m working on a project trying to get tracktion engine working in ELK Audio OS embedded system. To get very low latencies in ELK they use their own audio/midi drivers and provide a VST plugin host that uses them. I’m making a plugin with the tracktion engine inside, but I need to make sure that it does not try to access audio/midi devices by itself and should just use the ins/outs provided by the plugin host. For example, in this bit of code of the EngineInPlugin demo:

    void setupInputs()
    {
        auto& dm = engine.getDeviceManager();
        for (int i = 0; i < dm.getNumMidiInDevices(); i++)
        {
            auto dev = dm.getMidiInDevice (i);
            dev->setEnabled (true);
            dev->setEndToEndEnabled (true);
        }
        
        edit.playInStopEnabled = true;
        edit.getTransport().ensureContextAllocated (true);
        
        if (auto t = EngineHelpers::getOrInsertAudioTrackAt (edit, 0))
            if (auto dev = dm.getMidiInDevice (0))
                for (auto instance : edit.getAllInputDevices())
                    if (&instance->getInputDevice() == dev)
                        instance->setTargetTrack (t, 0);
        
        edit.restartPlayback();
    }

Isn’t the engine trying to access devices outside the plugin host or will dm.getNumMidiInDevices() only return those provided by the host?

Maybe @dave96 can chime in as I briefly mentioned this to him at ADC. There are possibly other modifications I’ll need to make in tracktion engine/JUCE to make it compatible with ELK (mainly avoiding timer related syscalls in code which will be run in the RT thread), but I’ll comment about that in another thread once I advance more in my integration.

Thanks!!!

We’ve posted a roadmap here: https://github.com/Tracktion/tracktion_engine/blob/develop/ROADMAP.md The goal is to have the engine ready to be used in a plugin early next year.

Currently, when running as a plugin, the engine will get one MIDI input and in future one MIDI output. This will be whatever MIDI is on the track. It will get one mono input per channel on the track.

Nice, I can get away for now with the limited audio/midi in/out and add more functionality once the engine in plugin is finished. However, what about the other question? is the engine trying to access directly midi/audio devices? How could I check that? Thanks!

See the HostedAudioDeviceInterface class. When running in a plugin, the Engine sees this class as the AudioDevice. If you set useMidiDevices to true it will access the system MIDI devices, otherwise you are responsible for passing in a block of MIDI data.

When using the HostedAudioDeviceInterface it will never try and access audio hardware.

First thing you should do in your plugin is get the hosted interface and initialize it.

    EngineInPluginDemo()
        : AudioProcessor (BusesProperties().withInput  ("Input",  AudioChannelSet::stereo())
                                           .withOutput ("Output", AudioChannelSet::stereo())),
        audioInterface (engine.getDeviceManager().getHostedAudioDeviceInterface())
    {
        audioInterface.initialise ({});
    }

Thanks for the clarification @G-Mon!