11namespace tracktion {
inline namespace engine
23 for (
auto s : snapshots)
24 if (s->getID() == itemID)
32 snapshots.addIfNotAlreadyThere (&snapshot);
37 snapshots.removeAllInstancesOf (&snapshot);
42 return snapshots.getLock();
62 if (itemID.isInvalid())
65 if (
auto snapshot = list->getEditSnapshot (itemID))
74 listHolder (
std::make_unique<ListHolder>()),
77 listHolder->list->addSnapshot (*
this);
81EditSnapshot::~EditSnapshot()
84 listHolder->list->removeSnapshot (*
this);
90 state = std::move (newState);
99 return state.
hasType (IDs::EDIT);
105 listeners.call (&Listener::editChanged, *
this);
108void EditSnapshot::addSubTracksRecursively (
const juce::XmlElement& parent,
int& audioTrackNameNumber)
110 for (
auto track : parent.getChildIterator())
117 auto trackName = track->getStringAttribute (IDs::name);
118 trackIDs.add (EditItemID::fromXML (*track, IDs::id));
120 mutedTracks.
setBit (numTracks, track->getBoolAttribute (IDs::mute,
false));
121 soloedTracks.
setBit (numTracks, track->getBoolAttribute (IDs::solo,
false));
122 soloIsolatedTracks.
setBit (numTracks, track->getBoolAttribute (IDs::soloIsolate,
false));
124 if (trackType == IDs::TRACK || trackType == IDs::MARKERTRACK)
126 if (trackName.isEmpty())
129 if (trackType == IDs::TRACK)
131 audioTracks.
setBit (numTracks);
132 addEditClips (*track);
133 addClipSources (*track);
134 ++audioTrackNameNumber;
136 else if (trackType == IDs::MARKERTRACK)
142 trackNames.
add (trackName);
145 addSubTracksRecursively (*track, audioTrackNameNumber);
159 :
juce::Time (changeHexString.getHexValue64());
165 viewState->getDoubleAttribute (IDs::loopPoint2));
166 markIn = loopRange.getStart();
167 markOut = loopRange.getEnd();
169 marksActive = markIn != markOut;
175 if (
auto tempoItem = tempoSeq->getChildByName (IDs::TEMPO))
176 tempo = tempoItem->getDoubleAttribute (IDs::bpm);
178 if (
auto timeSigItem = tempoSeq->getChildByName (IDs::TIMESIG))
180 timeSigNumerator = timeSigItem->getIntAttribute (IDs::numerator);
181 timeSigDenominator = timeSigItem->getIntAttribute (IDs::denominator);
186 if (
auto pitchItem = pitchSeq->getChildByName (IDs::PITCH))
187 pitch = pitchItem->getIntAttribute (IDs::pitch);
192 int audioTrackNameNumber = 1;
193 addSubTracksRecursively (xml, audioTrackNameNumber);
197int EditSnapshot::audioToGlobalTrackIndex (
int audioIndex)
const
199 int audioTrackIndex = 0;
201 for (
int i = 0; i < numTracks; ++i)
202 if (isAudioTrack (i))
203 if (audioTrackIndex++ == audioIndex)
213 refreshFromProjectItem (pi);
223 sourceFile = pi->getSourceFile();
224 auto newState = loadValueTree (sourceFile,
true);
226 if (! newState.hasType (IDs::EDIT))
229 name = pi->getName();
230 setState (newState, TimeDuration::fromSeconds (pi->getLength()));
234void EditSnapshot::refreshFromState()
236 auto editName = name;
237 auto editLength = length;
241 refreshFromXml (*xml, editName, editLength);
244void EditSnapshot::clear()
253 clipSourceIDs.clear();
260 timeSigNumerator = 4;
261 timeSigDenominator = 4;
268 for (
auto clip : track.getChildIterator())
269 if (clip->hasTagName (IDs::EDITCLIP))
270 editClipIDs.add (ProjectItemID (clip->getStringAttribute (
"source")));
275 for (
auto clip : track.getChildIterator())
277 auto sourceID = clip->getStringAttribute (
"source");
279 if (sourceID.isNotEmpty())
280 clipSourceIDs.add (ProjectItemID (sourceID));
286 for (
auto clip : track.getChildIterator())
289 m.name = clip->getStringAttribute (
"name",
TRANS(
"unnamed"));
291 auto start = TimePosition::fromSeconds (clip->getDoubleAttribute (
"start", 0.0));
292 auto len = TimeDuration::fromSeconds (clip->getDoubleAttribute (
"length", 0.0));
293 m.time = { start, start + len };
305 for (
auto itemID : baseEdit.getEditClips())
306 if (auto ptr = EditSnapshot::getEditSnapshot (baseEdit.engine, itemID))
307 addNestedEditObjects (*ptr, edits);
314 addNestedEditObjects (*
this, result);
BigInteger & clear() noexcept
int countNumberOfSetBits() const noexcept
BigInteger & setBit(int bitNumber)
static Colour fromString(StringRef encodedColourString)
Time getLastModificationTime() const
static constexpr Range between(const ValueType position1, const ValueType position2) noexcept
bool addIfNotAlreadyThere(ObjectClass *newObject)
void add(String stringToAdd)
void ensureStorageAllocated(int minNumElements)
std::unique_ptr< XmlElement > createXml() const
bool hasType(const Identifier &typeName) const noexcept
int getReferenceCount() const noexcept
ValueTree createCopy() const
int getNumChildElements() const noexcept
XmlElement * getChildByName(StringRef tagNameToLookFor) const noexcept
const String & getStringAttribute(StringRef attributeName) const noexcept
Holds a snapshot of an Edit file of the last time it was saved.
void setState(juce::ValueTree, TimeDuration editLength)
Sets the Edit XML that the XmlEdit should refer to.
void refreshCacheAndNotifyListeners()
Refreshes the cached properties and calls any listeners.
bool isValid() const
Returns true if the current source is a valid Edit.
void refreshFromProjectManager()
Looks in the ProjectManager for the relevant ProjectItem and updates it's state to reflect this.
juce::ReferenceCountedArray< EditSnapshot > getNestedEditObjects()
deals only with snapshots so it's relatively fast.
The Engine is the central class for all tracktion sessions.
ProjectManager & getProjectManager() const
Returns the ProjectManager instance.
An ID representing one of the items in a Project.
ProjectItem::Ptr getProjectItem(ProjectItemID)
tries to find the project that contains an id, and open it as a ProjectItem.
#define TRANS(stringLiteral)
Represents a duration in real-life time.
constexpr double inSeconds() const
Returns the TimeDuration as a number of seconds.
static bool isTrack(const juce::ValueTree &) noexcept
Returns true if the given ValeTree is for a known Track type.
#define CRASH_TRACER
This macro adds the current location to a stack which gets logged if a crash happens.