Correct parameters for opening existing edit?

I am missing something fundamental when loading existing Edits.

When I create a new Edit, as in;

te::Edit::Options options{	engine,
				te::createEmptyEdit(),
				te::ProjectItemID::createNewID(0),
				te::Edit::forEditing,
				nullptr,
				te::Edit::getDefaultNumUndoLevels(),
				[editFile] { return editFile; } };

edit = std::make_unique<te::Edit>( options );

…everything works as expected.

Specifically, when I run

	auto& deviceManager = engine.getDeviceManager();
	const auto numWaveInDevices{ deviceManager.getNumWaveInDevices() };

then, numWaveInDevices equals 2, which is correct. And, edit->getAllInputDevices() equals 2, also correct.

However, if I am opening an existing edit. The numWaveInDevices equls 2. But, edit->getAllInputDevices() equals 0. And, of course, I am unable to set recording enabled, etc.

It must be something I am missing in the edit constructor.

I am using

te::Edit::Options options{	engine,
				te::loadEditFromFile(editFile, te::ProjectItemID::createNewID(0)),
				{},
				te::Edit::forEditing,
				nullptr,
				te::Edit::getDefaultNumUndoLevels(),
				[editFile] { return editFile; } };

edit = std::make_unique<te::Edit>( options );

I am sure that the second and third parameters for “options” are the culprit. What should they, in fact, be in order to load an existing edit?

Any help is most appreciated.

It sounds like the Edit isn’t being attached to the DeviceManager correctly.

Looking at your reloading code, you should be passing a valid ProjectItemID. There should be an assertion about this in the Edit constructor.

But beyond that, can you look and see if EditPlaybackContext is getting created and EditPlaybackContext::rebuildDeviceList() is correctly getting the devices?

What is the correct syntax for the passing the ProjectItemID?

I would think that it is available from the editfile being read in. But, how do I acces it to put it in the options parameter?

Since everything is working correctly when creating a new edit (see my original post), it is clear that the DeviceManager is attaching correctly for a new edit. My code is the same for opening an existing edit, except for the “te::loadEditFromFile” in my code, the “editState” option, and the “editProjectItemID” option. If I knew the correct values for those options, I am sure everything will work as expected. So, any help with how to set those values will be most appreciated!

The ProjectItemID is something you have to maintain yourself. You could store it in the Edit::state as a property if you want but you might also need to store it outside of that. The key thing is that it should be unique for each Edit and persist between loads of the Edit.

The main thing this is for is to create temp dirs for proxy files etc. If you create a new one or share an ID, you’ll walk all over the temp dir of another Edit.


Is you editFile actually a valid Edit file?
Did you try stepping through the loading code like I suggested to see if the EditPlaybackContext is getting created?

The PlaybackDemo example project will reload an existing Edit so I’m not quite sure where your’s is failing. If you can step through it a bit to give me some more info I can at the very least add some assertions to help catch behaviour or tighten up the API.

1 Like

Thank you! I was not aware the PlayBack Demo could load an edit. I will take a look at that and get back to you.

I have tried playing my edit with the Playback demo. They do not play. However, edits produced with Tracktion 7 do not play in Playback demo either (the included demos like Synthetique and 2BITs). So, please advise on this.

And, yes, I have tried to load the Tracktion 7 demo edits in my program. The tracks load, but edit->getAllInputDevices().size() equals 0, just as for my edits.

By the way, I am saving my edits using “te::EditFileOperations(*edit).save(true, true, false);”. Is this correct?

I am not modifying the state value tree in any way. In fact, my program, at this point, is basically simply the Recording Demo and the Plugin Demo combined.

One last potential clue—if I add a track with “edit->ensureNumberOfAudioTracks(getAudioTracks(*edit).size() + 1)”, then edit->getAllInputDevices().size() equals 2, as it is should. This also works when loading Tracktion 7 edits. So, something about adding a track “wakes up” the device.

Any help is greatly appreciated.

I’ve mentioned it a couple of times but are you sure the EditPlaybackContext is actually getting created?

Maybe you just need to call edit.getTransport().ensureContextAllocated() to actually build the audio graph and input devices which then also attaches it to the DeviceManager for playback?

1 Like

Thank you! That did the trick. Now things are working as expected.

Perhaps, edit.getTransport().ensureContextAllocated() should be called in the edit constructor when loading an edit from a file?

Anyway, I appreciate your help…and your patience.

I don’t think this can be called in the constructor because it relies on the Edit being fully constructed and valid to create the audio graph.

I think most people don’t run in to this problem because calling the TransportControl::play method creates the EditPlaybackContext.

But we should probably add a comment near the Edit constructor to explain this a bit.