Warning thrown when inserting wave clip (Absolute path is expected)

Hi all,

I’m trying to insert a wave clip to an edit that’s been loaded from a file. When I try to do so I get a jassertfalse error thrown by juce::File, which is expecting a colon but there isn’t one because the file passed to it is relative. Weird thing is the clip is still added after this error is thrown, so it doesn’t seem to be a big deal.

Here’s my code that loads the edit:
songEdit(te::Edit::Options{ engine, te::loadEditFromFile(engine, songEditFile, {}), te::ProjectItemID::createNewID(0), te::Edit::forEditing, nullptr, te::Edit::getDefaultNumUndoLevels(), [songEditFile] { return songEditFile; } })

Here’s the code that adds the clip to the edit (this line throws the error):
te::WaveAudioClip::Ptr songClip = firstTrack->insertWaveClip (file.getFileNameWithoutExtension(), file, { { 0.0, audioFile.getLength() }, 0.0 }, false);

Can you post a stack trace of when the assertion fails so I can see what lines trigger it?

Here’s the stack trace:

>	MyProgram.exe!juce::File::parseAbsolutePath(const juce::String & p) Line 166	C++
 	MyProgram.exe!juce::File::File(const juce::String & fullPathName) Line 29	C++
 	MyProgram.exe!SongListComponent::addSongToList(juce::ValueTree & c) Line 50	C++
 	MyProgram.exe!SongListComponent::valueTreeChildAdded(juce::ValueTree & v, juce::ValueTree & c) Line 45	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::<lambda>(juce::ValueTree::Listener & l) Line 106	C++
 	MyProgram.exe!juce::ListenerList<juce::ValueTree::Listener,juce::Array<juce::ValueTree::Listener *,juce::DummyCriticalSection,0>>::callExcluding<void <lambda>(juce::ValueTree::Listener &) &>(juce::ValueTree::Listener * listenerToExclude, juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::void <lambda>(juce::ValueTree::Listener &) & callback) Line 141	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::callListeners<void <lambda>(juce::ValueTree::Listener &)>(juce::ValueTree::Listener * listenerToExclude, juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::void <lambda>(juce::ValueTree::Listener &) fn) Line 86	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::callListenersForAllParents<void <lambda>(juce::ValueTree::Listener &)>(juce::ValueTree::Listener * listenerToExclude, juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::void <lambda>(juce::ValueTree::Listener &) fn) Line 94	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree child) Line 106	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::addChild(juce::ValueTree::SharedObject * child, int index, juce::UndoManager * undoManager) Line 269	C++
 	MyProgram.exe!juce::ValueTree::addChild(const juce::ValueTree & child, int index, juce::UndoManager * undoManager) Line 918	C++
 	MyProgram.exe!SongComponent::valueTreeChildAdded(juce::ValueTree & v, juce::ValueTree & c) Line 79	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::<lambda>(juce::ValueTree::Listener & l) Line 106	C++
 	MyProgram.exe!juce::ListenerList<juce::ValueTree::Listener,juce::Array<juce::ValueTree::Listener *,juce::DummyCriticalSection,0>>::callExcluding<void <lambda>(juce::ValueTree::Listener &) &>(juce::ValueTree::Listener * listenerToExclude, juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::void <lambda>(juce::ValueTree::Listener &) & callback) Line 141	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::callListeners<void <lambda>(juce::ValueTree::Listener &)>(juce::ValueTree::Listener * listenerToExclude, juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::void <lambda>(juce::ValueTree::Listener &) fn) Line 86	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::callListenersForAllParents<void <lambda>(juce::ValueTree::Listener &)>(juce::ValueTree::Listener * listenerToExclude, juce::ValueTree::SharedObject::sendChildAddedMessage::__l2::void <lambda>(juce::ValueTree::Listener &) fn) Line 94	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree child) Line 106	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::addChild(juce::ValueTree::SharedObject * child, int index, juce::UndoManager * undoManager) Line 269	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::AddOrRemoveChildAction::perform() Line 493	C++
 	MyProgram.exe!juce::UndoManager::perform(juce::UndoableAction * newAction) Line 124	C++
 	MyProgram.exe!juce::ValueTree::SharedObject::addChild(juce::ValueTree::SharedObject * child, int index, juce::UndoManager * undoManager) Line 278	C++
 	MyProgram.exe!juce::ValueTree::addChild(const juce::ValueTree & child, int index, juce::UndoManager * undoManager) Line 918	C++
 	MyProgram.exe!tracktion_engine::ClipTrack::insertClipWithState(juce::ValueTree clipState) Line 585	C++
 	MyProgram.exe!tracktion_engine::ClipTrack::insertClipWithState(const juce::ValueTree & stateToUse, const juce::String & name, tracktion_engine::TrackItem::Type type, tracktion_engine::ClipPosition position, bool deleteExistingClips, bool allowSpottingAdjustment) Line 634	C++
 	MyProgram.exe!tracktion_engine::ClipTrack::insertWaveClip(const juce::String & name, const juce::File & sourceFile, tracktion_engine::ClipPosition position, bool deleteExistingClips) Line 666	C++
 	MyProgram.exe!Controller::setFile(const juce::File & file, tracktion_engine::Edit & edit) Line 377	C++
 	MyProgram.exe!Controller::buttonClicked(juce::Button * button) Line 286	C++
 	MyProgram.exe!juce::Button::sendClickMessage::__l2::<lambda>(juce::Button::Listener & l) Line 401	C++
 	MyProgram.exe!juce::ListenerList<juce::Button::Listener,juce::Array<juce::Button::Listener *,juce::DummyCriticalSection,0>>::callChecked<void <lambda>(juce::Button::Listener &),juce::Component::BailOutChecker>(const juce::Component::BailOutChecker & bailOutChecker, juce::Button::sendClickMessage::__l2::void <lambda>(juce::Button::Listener &) && callback) Line 153	C++
 	MyProgram.exe!juce::Button::sendClickMessage(const juce::ModifierKeys & modifiers) Line 403	C++
 	MyProgram.exe!juce::Button::internalClickCallback(const juce::ModifierKeys & modifiers) Line 351	C++
 	MyProgram.exe!juce::Button::mouseUp(const juce::MouseEvent & e) Line 472	C++
 	MyProgram.exe!juce::Component::internalMouseUp(juce::MouseInputSource source, juce::Point<float> relativePos, juce::Time time, const juce::ModifierKeys oldModifiers, float pressure, float orientation, float rotation, float tiltX, float tiltY) Line 2436	C++
 	MyProgram.exe!juce::MouseInputSourceInternal::sendMouseUp(juce::Component & comp, juce::Point<float> screenPos, juce::Time time, juce::ModifierKeys oldMods) Line 155	C++
 	MyProgram.exe!juce::MouseInputSourceInternal::setButtons(juce::Point<float> screenPos, juce::Time time, juce::ModifierKeys newButtonState) Line 198	C++
 	MyProgram.exe!juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer & newPeer, juce::Point<float> positionWithinPeer, juce::Time time, const juce::ModifierKeys newMods, float newPressure, float newOrientation, juce::PenDetails pen) Line 333	C++
 	MyProgram.exe!juce::MouseInputSource::handleEvent(juce::ComponentPeer & peer, juce::Point<float> pos, __int64 time, juce::ModifierKeys mods, float pressure, float orientation, const juce::PenDetails & penDetails) Line 634	C++
 	MyProgram.exe!juce::ComponentPeer::handleMouseEvent(juce::MouseInputSource::InputSourceType type, juce::Point<float> pos, juce::ModifierKeys newMods, float newPressure, float newOrientation, __int64 time, juce::PenDetails pen, int touchIndex) Line 87	C++
 	MyProgram.exe!juce::HWNDComponentPeer::doMouseEvent(juce::Point<float> position, float pressure, float orientation, juce::ModifierKeys mods) Line 2495	C++
 	MyProgram.exe!juce::HWNDComponentPeer::doMouseUp(juce::Point<float> position, const unsigned __int64 wParam) Line 2672	C++
 	MyProgram.exe!juce::HWNDComponentPeer::peerWindowProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 3566	C++
 	MyProgram.exe!juce::HWNDComponentPeer::windowProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 3459	C++
 	[External Code]	
 	MyProgram.exe!juce::InternalMessageQueue::dispatchNextMessage(bool returnIfNoPendingMessages) Line 149	C++
 	MyProgram.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 266	C++
 	MyProgram.exe!juce::MessageManager::runDispatchLoop() Line 128	C++
 	MyProgram.exe!juce::JUCEApplicationBase::main() Line 266	C++
 	MyProgram.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 112	C++
 	[External Code]

Looking at the source code for the insertWaveClip method, there’s a comment that says: // Insert with a relative path if possible, otherwise an absolute and the code proceeds to add the file as a relative path, which seems to lead to the error. Could this be a bug in Tracktion?

I don’t think it does…
This line:
newState.setProperty (IDs::source, SourceFileReference::findPathFromFile (edit, sourceFile, useRelativePath), nullptr);
uses SourceFileReference::findPathFromFile to create either an absolute or relative path.


It sounds like your problem isn’t actually with the Tracktion Engine code but that you’re getting a relative path from the clip and then creating a juce::File from it?

  1. Make sure you’re passing a valid file to ClipTrack::insertWaveClip
  2. Once you’ve done that, you’re getting that relative path and creating a juce::File in SongListComponent::addSongToList
  3. You need to get the Clip that was just created, call its Clip::getSourceFileReference method and then SourceFileReference::getFile() to resolve the path correctly.
  4. Alternatively, you can call Clip::getCurrentSourceFile() which will do 3 above

Does that sounds like what’s happening?

You were right, the SongComponent::addSongToList was trying to create a juce::File from a source passed in through a ValueTree, which was relative. I’ve modified the code so it’s able to get the last added file’s absolute path.

Thank you!