Tracktion Engine CLI Apps Possible?

I want a command line application that reads an Edit file, and renders audio from it. Will this be difficult to do?

If I use the projucer to create a CLI application, adding the traction_engine module I get the following assertion fails:

/** This macro is used to catch unsafe use of functions which expect to not be called
    outside the lifetime of the MessageManager.
*/
#define JUCE_ASSERT_MESSAGE_MANAGER_EXISTS \
    jassert (juce::MessageManager::getInstanceWithoutCreating() != nullptr);

Here’s the code:


#include <iostream>
#include "../JuceLibraryCode/JuceHeader.h"
#include "tracktion_engine/tracktion_engine.h"

//==============================================================================
int main (int argc, char* argv[])
{
    tracktion_engine::Engine engine{ "sweet" };
    std::cout << "Hello world" << std::endl;
    return 0;
}

Does this work if you add it to the beginning of main ?

auto mm = MessageManager::getInstance();

Thanks for suggestion, Xenakios (also hi, from the Reaper.fm forum circa 2010)

This causes a exception to be thrown from a file called juce_LeakedObjectDetector.h
*** Leaked objects detected: 1 instance(s) of class MixerThreadPool

class LeakCounter
    {
    public:
        LeakCounter() = default; 

        ~LeakCounter()
        {
            if (numObjects.value > 0)
            {
                DBG ("*** Leaked objects detected: " << numObjects.value << " instance(s) of class " << getLeakedObjectClassName());

                /** If you hit this, then you've leaked one or more objects of the type specified by
                    the 'OwnerClass' template parameter - the name should have been printed by the line above.

                    If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for
                    your object management. Tut, tut. Always, always use std::unique_ptrs, OwnedArrays,
                    ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs!
                */
                jassertfalse; <---- EXCEPTION THROWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            }
        }

        Atomic<int> numObjects;
    };

You may have to call MessageManager::deleteInstance() yourself if you’re creating it within a command line app

Yeah, I left that out…I just suggested creating the MessageManager instance for testing if it gets anything working further. :wink:

1 Like

I think the key is in *** Leaked objects detected: 1 instance(s) of class MixerThreadPool

This exception is being thrown after the main function returns – so it appears that JUCE is doing some magic behind the scenes, and I need to clean up some threads created by the TracktionEngine instance. Does that sound probable?

Unless anyone has clearer ideas, I’ll look at the example apps, and see If I can reverse engineer their shutdown behavior.

Thanks for the help so far!

I often find an instance of ScopedJuceInitialiser_GUI works for sorting out everything you need.

6 Likes

Perfect. I found I could sub class juce::JUCEApplicationBase, which is a convenient way to setup application lifecycle methods like initialize and shutdown, but for a simple CLI ScopedJuceInitialiser_GUI is much simpler.

1 Like