# Real-time Rendering - Tweaking while recording

**URL:** <https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155>\
**Category:** Tracktion Engine\
**Created:** [July 10, 2022, 7:02am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155 "2022-07-10T07:02:04Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 10, 2022, 7:02am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/1 "2022-07-10T07:02:04Z")

</div>

Hi all!

My use case is a record button that let you record audio while tweaking knobs of a synth or effect.  
This is not possible with Renderer::renderToFile (even when using Renderer::Parameters::realTimeRender), as rendering is not allowed whilst attached to audio device.

Does anyone have any advice for my use case, or example of code to do this?

Thanks very much for any help!

---

<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:** [July 11, 2022, 9:55am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/2 "2022-07-11T09:55:36Z")

</div>

You can’t really do this whilst rendering, it’s an inherently offline process.

The way you’d normally do this is by recording the output of one track to another. To do this, get the use `auto inputDevice = AudioTrack::getWaveInputDevice()` on the source track and then assign that to a target track.

It’s a bit tricker with TrackInputDevices as you have to get them to be added to the state first before you can get an instance (this should probably be improved in future).

```auto
                edit.getEditInputDevices().getInstanceStateForInputDevice (*inputDevice);

                if (auto epc = edit.getCurrentPlaybackContext())
                    if (auto instance = epc->getInputFor (inputDevice))
                        instance->setTargetTrack (destTrack, 0, true);

```

* * *

Another approach is to simply record the parameter changes as automation and do the rendering afterwards.

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 12, 2022, 6:23am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/3 "2022-07-12T06:23:32Z")

</div>

Thank you Dave.  
I updated my code after your remarks. But it still doesn’t work as expected, I’m probably doing something wrong. Here is my code:

```auto

Audio::Audio()
{
	...
	_transport.play(true);

	te::InputDevice& inputDevice = track1->getWaveInputDevice();
	_edit.getEditInputDevices().getInstanceStateForInputDevice(inputDevice);

	if (auto epc = _edit.getCurrentPlaybackContext())
	{
		if (auto sourceTrackInputDeviceInstance = epc->getInputFor(&inputDevice))
			sourceTrackInputDeviceInstance->setTargetTrack(*track2, 1, true);
	}
}

void Gui::render()
{
	_edit.getTransport().stopAllTransports(_engine, false, true);
	te::Renderer::turnOffAllPlugins(_edit);
	_edit.getTransport().freePlaybackContext();

	File renderFile{ };

	File rendersDir{ File::getSpecialLocation(File::userDesktopDirectory) };
	juce::FileChooser fileChooser("Choose a location to save file...", rendersDir, "*.wav");

	if (fileChooser.browseForFileToSave(true)) {
		renderFile = fileChooser.getResult();
	}
	else
	{
		return;
	}

	te::EditTimeRange range{ 0.0, _edit.getLength() };
	juce::BigInteger tracksToDo{ 0 };
	tracksToDo.setBit(track2->getIndexInEditTrackList());
	WavAudioFormat wavformat;
	te::Renderer::Parameters renderParams{ _edit };
	renderParams.engine = &_engine;
	renderParams.destFile = renderFile;
	renderParams.audioFormat = &wavformat;
	renderParams.time = range;
	renderParams.tracksToDo = tracksToDo;
	renderParams.realTimeRender = true;
	te::Renderer::renderToFile("Render", renderParams);
	AlertWindow::showMessageBoxAsync(MessageBoxIconType::NoIcon, "Rendered", renderFile.getFullPathName());
}

```

Thanks a lot for your time Dave!

---

<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:** [July 12, 2022, 10:20am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/4 "2022-07-12T10:20:35Z")

</div>

Sorry, you can’t use the `Renderer` to do this track-to-track process, you need to arm the destination track and then do a `TransportControl::record()` operation, just like you would for live audio/MIDI input.

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 13, 2022, 10:03am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/5 "2022-07-13T10:03:07Z")

</div>

Ok, thank you.

Just to make sure I’m going in the right direction, is it possible to:

1. Record the output of the input track to the destination track using getWaveInputDevice() and setTargetTrack(destTrack, 0, true)
2. Arm the destination track and do a TransportControl::record() operation
3. Render the destination track to a file using Renderer::renderToFile with tracksToDo.setBit(destinationTrack)?

Thanks a lot for your time Dave

---

<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:** [July 13, 2022, 10:25am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/6 "2022-07-13T10:25:23Z")

</div>

Yes those are all true, but step 3, the render, needs to happen _after_ the recording has stopped. I’m not quite sure why you would need this step though as the “destination track” will contain a clip with the recorded file.

What additional processing would the “render” operation add?

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 13, 2022, 10:43am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/7 "2022-07-13T10:43:35Z")

</div>

I have no additional processing in the “render”.  
How can I get the file saved with the clip on the “destination track”?

---

<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:** [July 13, 2022, 10:56am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/8 "2022-07-13T10:56:39Z")

</div>

`AudioClipBase::getSourceFileReference().getFile()`

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 13, 2022, 2:06pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/9 "2022-07-13T14:06:16Z")

</div>

Is the clip created automatically during recording? Here is my test code, with line 61 returning 0:  
[MainComponent.h](https://forum.juce.com/uploads/short-url/owuxt3rI9WBJGmKWye65elAt3fH.h) (5.8 KB)

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 13, 2022, 2:20pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/10 "2022-07-13T14:20:40Z")

</div>

ok it works when I call “\_transport.play(true);” before configuring the output from one track to another 🙂

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 13, 2022, 4:19pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/11 "2022-07-13T16:19:44Z")

</div>

It works perfectly, thanks again!  
Is it possible to merge recorded clips or input tracks, to have only one final .wav file?

---

<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:** [July 14, 2022, 4:02pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/12 "2022-07-14T16:02:07Z")

</div>

That’s when you’d do an offline render operation like you were originally.

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 14, 2022, 5:26pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/13 "2022-07-14T17:26:54Z")

</div>

Thank you Dave, it works perfectly.

Two small feedbacks:

1- In tracktion\_Renderer.cpp, line 430, I think you need to add this line: r.tracksToDo = tracksToDo;

2- When I render to a file, I must have this line, otherwise the file is not updated:

```auto
	if (fileChooser.browseForFileToSave(true)) {
		renderFile = fileChooser.getResult();

		if (renderFile.existsAsFile())
			renderFile.deleteFile(); // added line

	}

```

---

<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:** [July 18, 2022, 10:50am UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/14 "2022-07-18T10:50:23Z")

</div>

> [@Pooyan](#):
>
> 1- In tracktion\_Renderer.cpp, line 430, I think you need to add this line: r.tracksToDo = tracksToDo;

Thanks, will add then in a min.

> [@Pooyan](#):
>
> 2- When I render to a file, I must have this line, otherwise the file is not updated:

I think that’s correct behaviour. I don’t think it’s the Renderer’s responsibility to delete the file. You should make sure the file doesn’t exist and the location is writable before you start rendering.

---

<div class="post-metadata">

**Author:** ![bwall](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/bwall/32/618_2.png) [@bwall](https://forum.juce.com/u/bwall)\
**Post date:** [July 18, 2022, 2:12pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/15 "2022-07-18T14:12:28Z")

</div>

This is what I do for the render file.

```auto
File renderPath{ te::EditFileOperations(*currentEdit).getEditFile().getParentDirectory() };
File renderFile{ renderPath.getChildFile("Render").getNonexistentChildFile("render", ".wav") };

```

This creates a “render.wav” file in the “Render” folder with the edit. If the file already exists, it appends a number, i.e. - “Render(1).wav”.

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [July 18, 2022, 5:34pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/16 "2022-07-18T17:34:49Z")

</div>

Thank you for your replies.

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [September 20, 2022, 9:54pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/17 "2022-09-20T21:54:13Z")

</div>

Hi Dave

I tried recording the output of one track to another, and getting the file with AudioClipBase::getSourceFileReference().getFile(), but the resulting .wav is very saturated when there are overlapping notes.

Here is my TE 2.0 test code:  
[MainComponent.h](https://forum.juce.com/uploads/short-url/yExNfqsWrIH6aRWSrlddD6cfwSH.h) (3.3 KB)

Thanks very much for any help!

---

<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 3, 2022, 12:41pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/18 "2022-10-03T12:41:45Z")

</div>

Apologies for the delayed reply, I’ve been on holiday for the last two weeks.

Are you sure this isn’t just a gain staging issue? I can’t remember how 4OSC starts but does the real-time audio playback sound the same?

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [October 3, 2022, 4:09pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/19 "2022-10-03T16:09:54Z")

</div>

No problem Dave, thank you for your help!  
The real-time audio playback is fine.  
It’s only the rendered wav that is saturated.  
Normally, with the code I uploaded, it’s quick to reproduce.

---

<div class="post-metadata">

**Author:** ![Pooyan](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pooyan/32/13785_2.png) [@Pooyan](https://forum.juce.com/u/Pooyan)\
**Post date:** [October 7, 2022, 12:46pm UTC](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155/20 "2022-10-07T12:46:20Z")

</div>

Hi @dave96  
Any idea how to solve this?  
Thanks in advance!

[Next page](https://forum.juce.com/t/real-time-rendering-tweaking-while-recording/52155.md?page=2)
