# Can't pass params to renderToFile

**URL:** <https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901>\
**Category:** Tracktion Engine\
**Created:** [October 23, 2024, 12:19pm UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901 "2024-10-23T12:19:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![simonadcock](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/simonadcock/32/19591_2.png) [@simonadcock](https://forum.juce.com/u/simonadcock)\
**Post date:** [October 23, 2024, 12:19pm UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901/1 "2024-10-23T12:19:10Z")

</div>

I’m new to using Tracktion Engine, but have been really pleased with how much I’ve got done so quickly. However I’m struggling with passing params to renderToFile.

This code works fine, it renders the entire timeline:

```auto
auto tf = std::make_unique<juce::TemporaryFile> (".wav");
bool renderSuccess = tracktion::Renderer::renderToFile(*edit, tf->getFile(), false);

```

However when I try and pass parameters I get an error:

```auto
auto tf = std::make_unique<juce::TemporaryFile> (".wav");
tracktion::Renderer::Parameters params (*edit);
params.destFile = tf->getFile();
params.time = params.time.withLength (tracktion::TimeDuration::fromSeconds(4));
params.audioFormat = engine.getAudioFileFormatManager().getWavFormat();
juce::File renderedFile = tracktion::Renderer::renderToFile("Exporting audio", params);

```

```auto
JUCE Assertion failure in tracktion_Plugin.cpp:664

```

```auto
jassert (initialiseCount > 0);

```

Seems to be something to do with plugins not being initialised properly, but I can’t see why it should behave differently. Am I doing something wrong? Many thanks!

Tracktion Engine v3.0.0  
Juce v8.0.3

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 24, 2024, 11:55am UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901/2 "2024-10-24T11:55:46Z")

</div>

That is strange. Are you using the `develop` branch of TE?

---

<div class="post-metadata">

**Author:** ![simonadcock](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/simonadcock/32/19591_2.png) [@simonadcock](https://forum.juce.com/u/simonadcock)\
**Post date:** [October 27, 2024, 9:34am UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901/3 "2024-10-27T09:34:58Z")

</div>

I tried develop and master both do the same.

I’ve been doing a lot of digging and debugging, and ended up creating a new simple as possible project to experiment with renderToFile, I’m getting a different error now. Unfortunately I can’t find an example in the demos or tutorials of using renderToFile.

I’ve created a public repo for the basic Juce app and will update it once I have this working in case it’s helpful to anyone else. [GitHub - simonadcock/tracktion-engine-render-test](https://github.com/simonadcock/tracktion-engine-render-test/tree/main)

I’m just trying to load an audio file, then renderToFile with params. (Without parms works).

Below is a summary of the code:

```auto
edit->ensureNumberOfAudioTracks(1);
auto track = tracktion_engine::getAudioTracks(*edit)[0];
tracktion_engine::AudioFile audioFile(edit->engine, file);
auto newClip = track->insertWaveClip(file.getFileNameWithoutExtension(), file, { { {}, tracktion::TimeDuration::fromSeconds(audioFile.getLength()) }, {} }, false);

juce::File outputFile = juce::File::getSpecialLocation(juce::File::userDesktopDirectory).getChildFile("output.wav");
auto tracks = tracktion_engine::getAllTracks(*edit);
auto bitset = tracktion_engine::toBitSet(tracks);
tracktion::Renderer::Parameters params (*edit);
params.destFile = outputFile;
params.time = tracktion::TimeRange(tracktion::TimePosition::fromSeconds(0), tracktion::TimePosition::fromSeconds(4));
params.audioFormat = engine.getAudioFileFormatManager().getWavFormat();
params.tracksToDo = bitset;
juce::File renderedFile = tracktion::Renderer::renderToFile("Exporting audio", params);

```

It now crashes in TracktionNodePlayer, looks like processStateToUse is null.

However if I run the following it does work as expected:

```auto
tracktion::Renderer::renderToFile({}, outputFile, *edit, timeRange, bitset, true, true, {}, false);

```

Any pointers would be really appreciated!

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [November 5, 2024, 11:46am UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901/4 "2024-11-05T11:46:30Z")

</div>

I can’t replicate this. I’ve added this test to our TestRunner app which is basically the same as yours:

```auto
    TEST_CASE ("renderToFile")
    {
        auto& engine = *Engine::getEngines()[0];
        auto edit = test_utilities::createTestEdit (engine);
        edit->ensureNumberOfAudioTracks (1);

        auto fileLength = 5_td;
        auto sinFile = graph::test_utilities::getSinFile<juce::WavAudioFormat> (44100.0, fileLength.inSeconds());

        auto track = getAudioTracks (*edit)[0];
        insertWaveClip (*track, {}, sinFile->getFile(), { .time = { 0_tp, fileLength } },
                        DeleteExistingClips::no);

        juce::TemporaryFile destFile (".wav");
        auto tracks = tracktion_engine::getAllTracks(*edit);
        auto bitset = tracktion_engine::toBitSet(tracks);

        Renderer::Parameters params (*edit);
        params.time = params.time.withLength (fileLength);
        params.audioFormat = engine.getAudioFileFormatManager().getWavFormat();
        params.destFile = destFile.getFile();
        params.time = tracktion::TimeRange(tracktion::TimePosition::fromSeconds(0), tracktion::TimePosition::fromSeconds(4));
        params.audioFormat = engine.getAudioFileFormatManager().getWavFormat();
        params.tracksToDo = bitset;
        [[maybe_unused]] juce::File renderedFile = tracktion::Renderer::renderToFile("Exporting audio", params);
    }

```

If I step through the last line I get this:

- `Renderer::renderToFile`
- `render_utils::createRenderTask`
- `processState` etc. are created
- Edit `Node` is created then `Renderer::RenderTask` is created

Can you step through the above in your example and see if any of the above steps aren’t happening?

---

<div class="post-metadata">

**Author:** ![simonadcock](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/simonadcock/32/19591_2.png) [@simonadcock](https://forum.juce.com/u/simonadcock)\
**Post date:** [November 18, 2024, 3:24pm UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901/5 "2024-11-18T15:24:00Z")

</div>

Hi Dave,  
Great to meet you at ADC last week! It seems that because I’m basically running the engine headless (the UI is a WebView) I want to run the render task without using runTaskWithProgressBar. The other render functions allows you to pass in a useThread bool. I’ve amended the function that accepts parameters to the following and it now works as expected. I don’t know if it would be preferable to pass useThread in as one of the parameters.  
Does this seem a sensible approach? Or have I missed something?

```auto
juce::File Renderer::renderToFile (const juce::String& taskDescription, const Parameters& r, bool useThread)
    {
    CRASH_TRACER
    
    jassert (r.sampleRateForAudio > 7000);
    jassert (r.edit != nullptr);
    jassert (r.engine != nullptr);
    
    TransportControl::stopAllTransports (*r.engine, false, true);
    
    turnOffAllPlugins (*r.edit);
    
    if (r.tracksToDo.countNumberOfSetBits() > 0
        && r.destFile.hasWriteAccess()
        && ! r.destFile.isDirectory())
    {
        auto task = render_utils::createRenderTask (r, taskDescription, nullptr, nullptr);
        
        if (useThread)
        {
            auto& ui = r.edit->engine.getUIBehaviour();
            if (task)
            {
                ui.runTaskWithProgressBar (*task);
                turnOffAllPlugins (*r.edit);
                
                if (r.destFile.existsAsFile())
                {
                    if (task->errorMessage.isNotEmpty())
                    {
                        r.destFile.deleteFile();
                        ui.showWarningMessage (task->errorMessage);
                        return {};
                    }
                    
                    return r.destFile;
                }
                
                if (task->getCurrentTaskProgress() >= 0.9f && task->errorMessage.isNotEmpty())
                    ui.showWarningMessage (task->errorMessage);
            }
            else
            {
                ui.showWarningMessage (TRANS("Couldn't render, as the selected region was empty"));
            }
        }
        else if (task)
        {
            while (task->runJob() == juce::ThreadPoolJob::jobNeedsRunningAgain)
            {}
            return r.destFile;
        }
    }
    return {};
}

```

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [December 17, 2024, 9:43am UTC](https://forum.juce.com/t/cant-pass-params-to-rendertofile/63901/6 "2024-12-17T09:43:50Z")

</div>

You might want to look at the new `EditRenderer` class (at the top of `tracktion_Renderer.h`) as that provides a way to render asynchronously with a stop/progress handle and completion callback.

If you have a web UI, this is probably the preferable way to do it so you don’t just block the UI whilst rendering.
