How to render a MidiClip? Any hints?

I have an AudioTrack with a Plugin and midiclip with note data created on it. I would like to render the midiclip and get access to the rendered audiofile. Any suggestions?


1 Like

Assuming you have a clip c the following will render it to a file in the temp directory. It will use the current sample rate and block size that is being used for playback. If you pass useThread as true then you must implement UIBehaviour::runTaskWithProgressBar. If you need more control over the render output use the version of the function that takes a Renderer::Parameters.

auto& edit = c->edit;
int idx = 0;
BigInteger tracksToDo;

for (auto t : getAllTracks (edit))
    if (c->getTrack() == t)
        tracksToDo.setBit (idx);

auto clipPos = c->getPosition();

Array<Clip*> clips;
clips.add (c);

const bool usePlugins = true;
const bool audio = usePlugins || dynamic_cast<AudioClipBase*> (c);

File dir = File::getSpecialLocation (File::tempDirectory);
auto f = dir.getNonexistentChildFile (File::createLegalFileName (c->getName()), audio ? ".wav" : ".mid");

Renderer::renderToFile (TRANS("Render Clip"), f, edit, clipPos.time,
                        tracksToDo, usePlugins, clips, false);
1 Like

That works perfectly! Thanks

When I implement UIBehaviour::runTaskWithProgressBar (which is necessary for the parameter version), I get an assertion on edit->getTransport().isPlayContextActive(). Should I manually free the context first and reallocate after the thread finishes?

Can you add the line const Edit::ScopedRenderStatus srs (r.edit, true); to the function juce::File Renderer::renderToFile (const String& taskDescription, const Parameters& r) just before the line TransportControl::stopAllTransports (*r.engine, false, true); and see if that fixes it?

ScopedRenderStatus only takes 1 argument:
const Edit::ScopedRenderStatus srs(*r.edit); fixes it.