Is it still possible to open a .tracktionedit created with Waveform?

I’m trying to open a .tracktionedit file exported with Waveform 11.5.18 into the PlaybackDemo and encountering some issues. So far, things unrelated to audio clips seem to work OK (automation, LFO, plugins), but audio clips definitely do not play “out-of-the-box”.

I did some poking around and of course the .tracktionedit from Waveform is using the .tracktion project file which stores the path to the audio clip’s file, which is then referenced in the edit.

I manually edited the .tracktionedit and updated the source attribute of the audio clip to the path of the file on disk. I’m getting some new error of a StretchSegment’s timestretcher not being initialized. I’m not sure if related but its AudioClipBase::ProxyRenderingInfo.mode is set to disabled, even though it appeared to be enabled in Waveform… but, I’m probably getting ahead of myself here. Disabling time stretching for now at least got the edit loading with the audio clip playing properly.

Ideally for my use case I would like to be able to offer Waveform as a creation/editing tool for edits that will be loaded and used with a purpose-built Tracktion Engine app that is a specialized player of sorts.

Is there any way to load edits created in Waveform with audio clip support? I haven’t looked deeply into it, but it looks like originally the Tracktion Engine used the project approach, and then deprecated it, instead using an edit-only approach.

Is there still a supported way to properly open edits from Waveform and will it continue to be supported/function into the future even if it is not the recommended use? If not, is there a way to tell Waveform to write the actual file paths into the .tracktionedit instead of referencing them from the project file?

Thanks for any help with this, it’s actually a big part of my use case.

We’re planning to add relative file support to Waveform in the future and transition to that but it’s difficult as we’ll still need to support the old Project based approach as we have thousands of legacy projects in the wild. Figuring out this workflow is actually the tricky bit as we don’t want to add confusion to out customer base.

You can add support to your TE based app though if you support loading .tracktion project files. If you do that, the Project will be able to resolve the source IDs.

Sorry I can’t give any firmer idea of when we’ll get this fully sorted, we’ve currently got a bunch of stuff higher up in the priority list. We could possible add an “Export to relative edit file” in a semi-hidden place to Waveform if you don’t mind telling your customers to use that?

Having a save/export feature that writes paths directly into the edit file from Waveform would be fine for customers as I think I’m going to need an extra step in the workflow to prepare the content for playback in the TE player regardless and they will need to be educated on what that is.

That said, it seems like these two options would suffice if project files can still be opened in TE:

  • the TE player actually just loads a Waveform project + edit
  • I would write a custom “packaging” app that would load the project + edit, read the project’s asset paths and swap them in the edit, and then save the edit out, discarding the project file after this step

My main concern with the idea of project file + edit file would be if some time in the future it is fully deprecated and I’m stuck with a dead end solution. But I’m assuming since Waveform still requires this approach, it will be supported in TE as long as it is needed by Waveform, is that correct?

If so, I can totally find an approach that works as-is. But, my only final question is: is there any example code for what loading a project file + edit file looks like in TE? I found source reference to the ProjectManager class here, but after searching Google, this forum, and the tutorials I didn’t see any working examples.

Cheers.

OK I think I figured this out by poking around in source code and trial and error. Does this seem like a reasonable way to convert edits from Waveform/project-based to edit-only TE?

  const File projectFile = File("...path to project file..");
  auto project = projectManager.createNewProject(projectFile);
  bool filePathsUpdated = false;
  
  // go through all tracks
  auto& trackList = edit->getTrackList();
    
  for (int i = 0; i < trackList.size(); i++)
  {
      auto* track = trackList[i];
  
      // skip non-audio tracks...
      if (!track->isAudioTrack()) continue;
  
      // get the current list of clips for the track
      auto* audioTrack = dynamic_cast<te::AudioTrack*>(track);
      jassert(audioTrack != nullptr);
      auto& clips = audioTrack->getClips();
  
      // go through each clip...
      for (int c = 0; c < clips.size(); c++)
      {
          auto* clip = clips.getReference(c);
          jassert(clip != nullptr);
  
          // if the clip doesn't use a source file, there is nothing to update...
          if (!clip->usesSourceFile()) continue;
          auto& sourceFile = clip->getSourceFileReference();
  
          // get the source file's ProjectItemID and get the ProjectItem from the associated project...
          auto pId= sourceFile.getSourceProjectItemID();
          auto pItem = project->getProjectItemForID(pId);
          jassert(pItem != nullptr);
  
          // update the edit's source file using the project's file path
          sourceFile.setToDirectFileReference(File(pItem->getRawFileName()), true);
  
          // we found at least one path that needed to be updated...
          filePathsUpdated = true;
      }
  }
  
  // If any paths needed updating...
  if (filePathsUpdated)
  {
      // Create a copy of the edit with the directly substituted file paths
      File f = File("...new TE-ready edit file path...");
      auto efo = te::EditFileOperations(*edit);
      efo.saveAs(f, true);
  }

It’s working, but are there any gotchas to look out for here?

I don’t think we’ll be able to remove Project any time soon. If we do, we’ll need a way to smoothly transition old Projects anyway so that should be covered in TE.

Your code looks correct to me. I can’t think of any obvious gotchas but it can probably be written a little more succinctly like:

  const File projectFile ("...path to project file..");
  auto project = projectManager.createNewProject (projectFile);
  bool filePathsUpdated = false;
  
  // go through all tracks
  for (auto audioTrack : te::getAudioTracks (*edit))
  {
    for (auto clip : audioTrack->getClips())
    {
          // if the clip doesn't use a source file, there is nothing to update...
          if (! clip->usesSourceFile())
            continue;

          // get the source file's ProjectItemID and get the ProjectItem from the associated project...
          auto& sourceRef = clip->getSourceFileReference();
          auto pID= sourceRef.getSourceProjectItemID();

          if (auto pItem = project->getProjectItemForID (pID))
          {
            // update the edit's source file using the project's file path
            sourceRef.setToDirectFileReference (File (pItem->getRawFileName()), true);
  
            // we found at least one path that needed to be updated...
            filePathsUpdated = true;
          }
    }
  }
  
  // If any paths needed updating...
  if (filePathsUpdated)
  {
      // Create a copy of the edit with the directly substituted file paths
      File f ("...new TE-ready edit file path...");
      te::EditFileOperations(*edit).saveAs(f, true);
  }

Hope that works (I didn’t actually run it).

1 Like

Thanks for the info. The cleaned up code worked great. I’m happy to start actually digging into the Tracktion Engine; I’ve got a few things I would like to prototype, and it’s been on my roadmap for a bit!