mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Use TrackIterRange::Visit
This commit is contained in:
parent
17089d03bf
commit
1be3187b99
261
src/Menus.cpp
261
src/Menus.cpp
@ -2289,13 +2289,12 @@ CommandFlag MenuCommandHandler::GetUpdateFlags
|
||||
if (!selectedRegion.isPoint())
|
||||
flags |= TimeSelectedFlag;
|
||||
|
||||
TrackListIterator iter(project.GetTracks());
|
||||
Track *t = iter.First();
|
||||
while (t) {
|
||||
auto tracks = project.GetTracks();
|
||||
auto trackRange = tracks->Any();
|
||||
if ( trackRange )
|
||||
flags |= TracksExistFlag;
|
||||
if (t->GetKind() == Track::Label) {
|
||||
LabelTrack *lt = (LabelTrack *) t;
|
||||
|
||||
trackRange.Visit(
|
||||
[&](LabelTrack *lt) {
|
||||
flags |= LabelTracksExistFlag;
|
||||
|
||||
if (lt->GetSelected()) {
|
||||
@ -2313,8 +2312,8 @@ CommandFlag MenuCommandHandler::GetUpdateFlags
|
||||
if (lt->IsTextSelected()) {
|
||||
flags |= CutCopyAvailableFlag;
|
||||
}
|
||||
}
|
||||
else if (t->GetKind() == Track::Wave) {
|
||||
},
|
||||
[&](WaveTrack *t) {
|
||||
flags |= WaveTracksExistFlag;
|
||||
flags |= PlayableTracksExistFlag;
|
||||
if (t->GetSelected()) {
|
||||
@ -2331,9 +2330,8 @@ CommandFlag MenuCommandHandler::GetUpdateFlags
|
||||
flags |= HasWaveDataFlag;
|
||||
}
|
||||
#if defined(USE_MIDI)
|
||||
else if (t->GetKind() == Track::Note) {
|
||||
NoteTrack *nt = (NoteTrack *) t;
|
||||
|
||||
,
|
||||
[&](NoteTrack *nt) {
|
||||
flags |= NoteTracksExistFlag;
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
flags |= PlayableTracksExistFlag;
|
||||
@ -2346,8 +2344,7 @@ CommandFlag MenuCommandHandler::GetUpdateFlags
|
||||
}
|
||||
}
|
||||
#endif
|
||||
t = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
if((AudacityProject::msClipT1 - AudacityProject::msClipT0) > 0.0)
|
||||
flags |= ClipboardFlag;
|
||||
@ -5589,24 +5586,21 @@ void MenuCommandHandler::OnCut(const CommandContext &context)
|
||||
auto pNewClipboard = TrackList::Create();
|
||||
auto &newClipboard = *pNewClipboard;
|
||||
|
||||
n = iter.First();
|
||||
while (n) {
|
||||
if (n->GetSelected()) {
|
||||
Track::Holder dest;
|
||||
tracks->Selected().Visit(
|
||||
#if defined(USE_MIDI)
|
||||
if (n->GetKind() == Track::Note)
|
||||
// Since portsmf has a built-in cut operator, we use that instead
|
||||
dest = n->Cut(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
else
|
||||
[&](NoteTrack *n) {
|
||||
// Since portsmf has a built-in cut operator, we use that instead
|
||||
auto dest = n->Cut(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
FinishCopy(n, std::move(dest), newClipboard);
|
||||
},
|
||||
#endif
|
||||
dest = n->Copy(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
|
||||
[&](Track *n) {
|
||||
auto dest = n->Copy(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
FinishCopy(n, std::move(dest), newClipboard);
|
||||
}
|
||||
n = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
// Survived possibility of exceptions. Commit changes to the clipboard now.
|
||||
newClipboard.Swap(*AudacityProject::msClipboard);
|
||||
@ -5614,35 +5608,28 @@ void MenuCommandHandler::OnCut(const CommandContext &context)
|
||||
// Proceed to change the project. If this throws, the project will be
|
||||
// rolled back by the top level handler.
|
||||
|
||||
n = iter.First();
|
||||
while (n) {
|
||||
// We clear from selected and sync-lock selected tracks.
|
||||
if (n->GetSelected() || n->IsSyncLockSelected()) {
|
||||
switch (n->GetKind())
|
||||
{
|
||||
(tracks->Any() + &Track::IsSelectedOrSyncLockSelected).Visit(
|
||||
#if defined(USE_MIDI)
|
||||
case Track::Note:
|
||||
//if NoteTrack, it was cut, so do not clear anything
|
||||
break;
|
||||
[](NoteTrack*) {
|
||||
//if NoteTrack, it was cut, so do not clear anything
|
||||
|
||||
// PRL: But what if it was sync lock selected only, not selected?
|
||||
},
|
||||
#endif
|
||||
case Track::Wave:
|
||||
if (gPrefs->Read(wxT("/GUI/EnableCutLines"), (long)0)) {
|
||||
((WaveTrack*)n)->ClearAndAddCutLine(
|
||||
selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
break;
|
||||
}
|
||||
|
||||
// Fall through
|
||||
|
||||
default:
|
||||
n->Clear(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
break;
|
||||
[&](WaveTrack *wt, const Track::Fallthrough &fallthrough) {
|
||||
if (gPrefs->Read(wxT("/GUI/EnableCutLines"), (long)0)) {
|
||||
wt->ClearAndAddCutLine(
|
||||
selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
else
|
||||
fallthrough();
|
||||
},
|
||||
[&](Track *n) {
|
||||
n->Clear(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
n = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
AudacityProject::msClipT0 = selectedRegion.t0();
|
||||
AudacityProject::msClipT1 = selectedRegion.t1();
|
||||
@ -5670,35 +5657,30 @@ void MenuCommandHandler::OnSplitCut(const CommandContext &context)
|
||||
auto &selectedRegion = project.GetViewInfo().selectedRegion;
|
||||
auto historyWindow = project.GetHistoryWindow();
|
||||
|
||||
TrackListIterator iter(tracks);
|
||||
Track *n = iter.First();
|
||||
|
||||
AudacityProject::ClearClipboard();
|
||||
|
||||
auto pNewClipboard = TrackList::Create();
|
||||
auto &newClipboard = *pNewClipboard;
|
||||
|
||||
while (n) {
|
||||
if (n->GetSelected()) {
|
||||
Track::Holder dest;
|
||||
if (n->GetKind() == Track::Wave)
|
||||
{
|
||||
dest = ((WaveTrack*)n)->SplitCut(
|
||||
selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
else
|
||||
{
|
||||
dest = n->Copy(selectedRegion.t0(),
|
||||
Track::Holder dest;
|
||||
|
||||
tracks->Selected().Visit(
|
||||
[&](WaveTrack *n) {
|
||||
dest = n->SplitCut(
|
||||
selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
if (dest)
|
||||
FinishCopy(n, std::move(dest), newClipboard);
|
||||
},
|
||||
[&](Track *n) {
|
||||
dest = n->Copy(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
n->Silence(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
n->Silence(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
if (dest)
|
||||
FinishCopy(n, std::move(dest), newClipboard);
|
||||
}
|
||||
n = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
// Survived possibility of exceptions. Commit changes to the clipboard now.
|
||||
newClipboard.Swap(*AudacityProject::msClipboard);
|
||||
@ -6255,32 +6237,19 @@ void MenuCommandHandler::OnTrim(const CommandContext &context)
|
||||
if (selectedRegion.isPoint())
|
||||
return;
|
||||
|
||||
TrackListIterator iter(tracks);
|
||||
Track *n = iter.First();
|
||||
|
||||
while (n) {
|
||||
if (n->GetSelected()) {
|
||||
switch (n->GetKind())
|
||||
{
|
||||
#if defined(USE_MIDI)
|
||||
case Track::Note:
|
||||
((NoteTrack*)n)->Trim(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
break;
|
||||
tracks->Selected().Visit(
|
||||
#ifdef USE_MIDI
|
||||
[&](NoteTrack *nt) {
|
||||
nt->Trim(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
},
|
||||
#endif
|
||||
|
||||
case Track::Wave:
|
||||
//Delete the section before the left selector
|
||||
((WaveTrack*)n)->Trim(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[&](WaveTrack *wt) {
|
||||
//Delete the section before the left selector
|
||||
wt->Trim(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
n = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
project.PushState(
|
||||
wxString::Format(
|
||||
@ -6303,24 +6272,16 @@ void MenuCommandHandler::OnSplitDelete(const CommandContext &context)
|
||||
auto tracks = project.GetTracks();
|
||||
auto &selectedRegion = project.GetViewInfo().selectedRegion;
|
||||
|
||||
TrackListIterator iter(tracks);
|
||||
|
||||
Track *n = iter.First();
|
||||
|
||||
while (n) {
|
||||
if (n->GetSelected()) {
|
||||
if (n->GetKind() == Track::Wave)
|
||||
{
|
||||
((WaveTrack*)n)->SplitDelete(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
else {
|
||||
n->Silence(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
tracks->Selected().Visit(
|
||||
[&](WaveTrack *wt) {
|
||||
wt->SplitDelete(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
},
|
||||
[&](Track *n) {
|
||||
n->Silence(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
}
|
||||
n = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
project.PushState(
|
||||
wxString::Format(_("Split-deleted %.2f seconds at t=%.2f"),
|
||||
@ -6713,39 +6674,43 @@ void MenuCommandHandler::OnSplitNew(const CommandContext &context)
|
||||
auto tracks = project.GetTracks();
|
||||
auto &selectedRegion = project.GetViewInfo().selectedRegion;
|
||||
|
||||
TrackListIterator iter(tracks);
|
||||
Track *l = iter.Last();
|
||||
Track::Holder dest;
|
||||
|
||||
for (Track *n = iter.First(); n; n = iter.Next()) {
|
||||
if (n->GetSelected()) {
|
||||
Track::Holder dest;
|
||||
double newt0 = 0, newt1 = 0;
|
||||
double offset = n->GetOffset();
|
||||
if (n->GetKind() == Track::Wave) {
|
||||
const auto wt = static_cast<WaveTrack*>(n);
|
||||
// This iteration is unusual because we add to the list inside the loop
|
||||
auto range = tracks->Selected();
|
||||
auto last = *range.rbegin();
|
||||
for (auto track : range) {
|
||||
track->TypeSwitch(
|
||||
[&](WaveTrack *wt) {
|
||||
// Clips must be aligned to sample positions or the NEW clip will not fit in the gap where it came from
|
||||
double offset = wt->GetOffset();
|
||||
offset = wt->LongSamplesToTime(wt->TimeToLongSamples(offset));
|
||||
newt0 = wt->LongSamplesToTime(wt->TimeToLongSamples(selectedRegion.t0()));
|
||||
newt1 = wt->LongSamplesToTime(wt->TimeToLongSamples(selectedRegion.t1()));
|
||||
double newt0 = wt->LongSamplesToTime(wt->TimeToLongSamples(
|
||||
selectedRegion.t0()));
|
||||
double newt1 = wt->LongSamplesToTime(wt->TimeToLongSamples(
|
||||
selectedRegion.t1()));
|
||||
dest = wt->SplitCut(newt0, newt1);
|
||||
if (dest) {
|
||||
dest->SetOffset(wxMax(newt0, offset));
|
||||
FinishCopy(wt, std::move(dest), *tracks);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
,
|
||||
// LL: For now, just skip all non-wave tracks since the other do not
|
||||
// yet support proper splitting.
|
||||
else {
|
||||
dest = n->Cut(selectedRegion.t0(),
|
||||
selectedRegion.t1());
|
||||
[&](Track *n) {
|
||||
dest = n->Cut(viewInfo.selectedRegion.t0(),
|
||||
viewInfo.selectedRegion.t1());
|
||||
if (dest) {
|
||||
dest->SetOffset(wxMax(0, n->GetOffset()));
|
||||
FinishCopy(n, std::move(dest), *tracks);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (dest) {
|
||||
dest->SetOffset(wxMax(newt0, offset));
|
||||
FinishCopy(n, std::move(dest), *tracks);
|
||||
}
|
||||
}
|
||||
|
||||
if (n == l) {
|
||||
);
|
||||
if (track == last)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
project.PushState(_("Split to new track"), _("Split New"));
|
||||
@ -8928,29 +8893,25 @@ void MenuCommandHandler::OnScoreAlign(const CommandContext &context)
|
||||
auto tracks = project.GetTracks();
|
||||
const auto rate = project.GetRate();
|
||||
|
||||
TrackListIterator iter(tracks);
|
||||
Track *t = iter.First();
|
||||
int numWaveTracksSelected = 0;
|
||||
int numNoteTracksSelected = 0;
|
||||
int numOtherTracksSelected = 0;
|
||||
NoteTrack *nt;
|
||||
double endTime = 0.0;
|
||||
|
||||
// Iterate through once to make sure that there is exactly
|
||||
// one WaveTrack and one NoteTrack selected.
|
||||
while (t) {
|
||||
if (t->GetSelected()) {
|
||||
if (t->GetKind() == Track::Wave) {
|
||||
numWaveTracksSelected++;
|
||||
WaveTrack *wt = (WaveTrack *) t;
|
||||
endTime = endTime > wt->GetEndTime() ? endTime : wt->GetEndTime();
|
||||
} else if(t->GetKind() == Track::Note) {
|
||||
numNoteTracksSelected++;
|
||||
nt = (NoteTrack *) t;
|
||||
} else numOtherTracksSelected++;
|
||||
GetTracks()->Selected().Visit(
|
||||
[&](WaveTrack *wt) {
|
||||
numWaveTracksSelected++;
|
||||
endTime = endTime > wt->GetEndTime() ? endTime : wt->GetEndTime();
|
||||
},
|
||||
[&](NoteTrack *) {
|
||||
numNoteTracksSelected++;
|
||||
},
|
||||
[&](Track*) {
|
||||
numOtherTracksSelected++;
|
||||
}
|
||||
t = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
if(numWaveTracksSelected == 0 ||
|
||||
numNoteTracksSelected != 1 ||
|
||||
|
@ -3821,55 +3821,45 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCopy)
|
||||
|
||||
mTags->WriteXML(xmlFile);
|
||||
|
||||
const Track *t;
|
||||
WaveTrack* pWaveTrack;
|
||||
TrackListConstIterator iter(GetTracks());
|
||||
t = iter.First();
|
||||
unsigned int ndx = 0;
|
||||
while (t) {
|
||||
if ((t->GetKind() == Track::Wave) && bWantSaveCopy)
|
||||
{
|
||||
auto wt = static_cast<const WaveTrack *>(t);
|
||||
GetTracks()->Any().Visit(
|
||||
[&](WaveTrack *pWaveTrack) {
|
||||
if (bWantSaveCopy) {
|
||||
if (!pWaveTrack->IsLeader())
|
||||
return;
|
||||
|
||||
//vvv This should probably be a method, WaveTrack::WriteCompressedTrackXML().
|
||||
xmlFile.StartTag(wxT("import"));
|
||||
xmlFile.WriteAttr(wxT("filename"), mStrOtherNamesArray[ndx]); // Assumes mTracks order hasn't changed!
|
||||
//vvv This should probably be a method, WaveTrack::WriteCompressedTrackXML().
|
||||
xmlFile.StartTag(wxT("import"));
|
||||
xmlFile.WriteAttr(wxT("filename"), mStrOtherNamesArray[ndx]); // Assumes mTracks order hasn't changed!
|
||||
|
||||
// Don't store "channel" and "linked" tags because the importer can figure that out,
|
||||
// e.g., from stereo Ogg files.
|
||||
// xmlFile.WriteAttr(wxT("channel"), t->GetChannel());
|
||||
// xmlFile.WriteAttr(wxT("linked"), t->GetLinked());
|
||||
// Don't store "channel" and "linked" tags because the importer can figure that out,
|
||||
// e.g., from stereo Ogg files.
|
||||
// xmlFile.WriteAttr(wxT("channel"), t->GetChannel());
|
||||
// xmlFile.WriteAttr(wxT("linked"), t->GetLinked());
|
||||
|
||||
xmlFile.WriteAttr(wxT("offset"), t->GetOffset(), 8);
|
||||
xmlFile.WriteAttr(wxT("mute"), wt->GetMute());
|
||||
xmlFile.WriteAttr(wxT("solo"), wt->GetSolo());
|
||||
xmlFile.WriteAttr(wxT("height"), t->GetActualHeight());
|
||||
xmlFile.WriteAttr(wxT("minimized"), t->GetMinimized());
|
||||
xmlFile.WriteAttr(wxT("offset"), pWaveTrack->GetOffset(), 8);
|
||||
xmlFile.WriteAttr(wxT("mute"), pWaveTrack->GetMute());
|
||||
xmlFile.WriteAttr(wxT("solo"), pWaveTrack->GetSolo());
|
||||
xmlFile.WriteAttr(wxT("height"), pWaveTrack->GetActualHeight());
|
||||
xmlFile.WriteAttr(wxT("minimized"), pWaveTrack->GetMinimized());
|
||||
|
||||
pWaveTrack = (WaveTrack*)t;
|
||||
// Don't store "rate" tag because the importer can figure that out.
|
||||
// xmlFile.WriteAttr(wxT("rate"), pWaveTrack->GetRate());
|
||||
xmlFile.WriteAttr(wxT("gain"), (double)pWaveTrack->GetGain());
|
||||
xmlFile.WriteAttr(wxT("pan"), (double)pWaveTrack->GetPan());
|
||||
xmlFile.EndTag(wxT("import"));
|
||||
// Don't store "rate" tag because the importer can figure that out.
|
||||
// xmlFile.WriteAttr(wxT("rate"), pWaveTrack->GetRate());
|
||||
xmlFile.WriteAttr(wxT("gain"), (double)pWaveTrack->GetGain());
|
||||
xmlFile.WriteAttr(wxT("pan"), (double)pWaveTrack->GetPan());
|
||||
xmlFile.EndTag(wxT("import"));
|
||||
|
||||
ndx++;
|
||||
if (t->GetLinked())
|
||||
t = iter.Next();
|
||||
}
|
||||
else if (t->GetKind() == Track::Wave)
|
||||
{
|
||||
pWaveTrack = (WaveTrack*)t;
|
||||
pWaveTrack->SetAutoSaveIdent(mAutoSaving ? ++ndx : 0);
|
||||
ndx++;
|
||||
}
|
||||
else {
|
||||
pWaveTrack->SetAutoSaveIdent(mAutoSaving ? ++ndx : 0);
|
||||
pWaveTrack->WriteXML(xmlFile);
|
||||
}
|
||||
},
|
||||
[&](Track *t) {
|
||||
t->WriteXML(xmlFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
t->WriteXML(xmlFile);
|
||||
}
|
||||
|
||||
t = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
if (!mAutoSaving)
|
||||
{
|
||||
|
36
src/Snap.cpp
36
src/Snap.cpp
@ -16,6 +16,7 @@
|
||||
|
||||
#include "Project.h"
|
||||
#include "LabelTrack.h"
|
||||
#include "NoteTrack.h"
|
||||
#include "WaveTrack.h"
|
||||
|
||||
inline bool operator < (SnapPoint s1, SnapPoint s2)
|
||||
@ -100,19 +101,14 @@ void SnapManager::Reinit()
|
||||
// Add a SnapPoint at t=0
|
||||
mSnapPoints.push_back(SnapPoint{});
|
||||
|
||||
TrackListConstIterator iter(mTracks);
|
||||
for (const Track *track = iter.First(); track; track = iter.Next())
|
||||
{
|
||||
if (mTrackExclusions &&
|
||||
mTrackExclusions->end() !=
|
||||
std::find(mTrackExclusions->begin(), mTrackExclusions->end(), track))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (track->GetKind() == Track::Label)
|
||||
{
|
||||
LabelTrack *labelTrack = (LabelTrack *)track;
|
||||
auto trackRange =
|
||||
mTracks->Any()
|
||||
- [&](const Track *pTrack){
|
||||
return mTrackExclusions &&
|
||||
make_iterator_range( *mTrackExclusions ).contains( pTrack );
|
||||
};
|
||||
trackRange.Visit(
|
||||
[&](const LabelTrack *labelTrack) {
|
||||
for (int i = 0, cnt = labelTrack->GetNumLabels(); i < cnt; ++i)
|
||||
{
|
||||
const LabelStruct *label = labelTrack->GetLabel(i);
|
||||
@ -124,10 +120,8 @@ void SnapManager::Reinit()
|
||||
CondListAdd(t1, labelTrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (track->GetKind() == Track::Wave)
|
||||
{
|
||||
auto waveTrack = static_cast<const WaveTrack *>(track);
|
||||
},
|
||||
[&](const WaveTrack *waveTrack) {
|
||||
for (const auto &clip: waveTrack->GetClips())
|
||||
{
|
||||
if (mClipExclusions)
|
||||
@ -144,9 +138,7 @@ void SnapManager::Reinit()
|
||||
}
|
||||
|
||||
if (skip)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CondListAdd(clip->GetStartTime(), waveTrack);
|
||||
@ -154,13 +146,13 @@ void SnapManager::Reinit()
|
||||
}
|
||||
}
|
||||
#ifdef USE_MIDI
|
||||
else if (track->GetKind() == Track::Note)
|
||||
{
|
||||
,
|
||||
[&](const NoteTrack *track) {
|
||||
CondListAdd(track->GetStartTime(), track);
|
||||
CondListAdd(track->GetEndTime(), track);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
);
|
||||
|
||||
// Sort all by time
|
||||
std::sort(mSnapPoints.begin(), mSnapPoints.end());
|
||||
|
@ -229,28 +229,23 @@ bool EffectChangeSpeed::Process()
|
||||
CopyInputTracks(Track::All); // Set up mOutputTracks.
|
||||
bool bGoodResult = true;
|
||||
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
Track* t;
|
||||
mCurTrackNum = 0;
|
||||
mMaxNewLength = 0.0;
|
||||
|
||||
mFactor = 100.0 / (100.0 + m_PercentChange);
|
||||
|
||||
t = iter.First();
|
||||
while (t != NULL)
|
||||
{
|
||||
if (t->GetKind() == Track::Label) {
|
||||
if (t->GetSelected() || t->IsSyncLockSelected())
|
||||
mOutputTracks->Any().VisitWhile( bGoodResult,
|
||||
[&](LabelTrack *lt) {
|
||||
if (lt->GetSelected() || lt->IsSyncLockSelected())
|
||||
{
|
||||
if (!ProcessLabelTrack(static_cast<LabelTrack*>(t))) {
|
||||
if (!ProcessLabelTrack(lt))
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->GetKind() == Track::Wave && t->GetSelected())
|
||||
{
|
||||
WaveTrack *pOutWaveTrack = (WaveTrack*)t;
|
||||
},
|
||||
[&](WaveTrack *pOutWaveTrack, const Track::Fallthrough &fallthrough) {
|
||||
if (!pOutWaveTrack->GetSelected())
|
||||
return fallthrough();
|
||||
|
||||
//Get start and end times from track
|
||||
mCurT0 = pOutWaveTrack->GetStartTime();
|
||||
mCurT1 = pOutWaveTrack->GetEndTime();
|
||||
@ -268,21 +263,15 @@ bool EffectChangeSpeed::Process()
|
||||
|
||||
//ProcessOne() (implemented below) processes a single track
|
||||
if (!ProcessOne(pOutWaveTrack, start, end))
|
||||
{
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCurTrackNum++;
|
||||
},
|
||||
[&](Track *t) {
|
||||
if (t->IsSyncLockSelected())
|
||||
t->SyncLockAdjust(mT1, mT0 + (mT1 - mT0) * mFactor);
|
||||
}
|
||||
else if (t->IsSyncLockSelected())
|
||||
{
|
||||
t->SyncLockAdjust(mT1, mT0 + (mT1 - mT0) * mFactor);
|
||||
}
|
||||
|
||||
//Iterate to the next track
|
||||
t=iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
if (bGoodResult)
|
||||
ReplaceProcessedTracks(bGoodResult);
|
||||
|
@ -1348,154 +1348,152 @@ bool Effect::ProcessPass()
|
||||
mBufferSize = 0;
|
||||
mBlockSize = 0;
|
||||
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
int count = 0;
|
||||
bool clear = false;
|
||||
Track* t = iter.First();
|
||||
|
||||
for (t = iter.First(); t; t = iter.Next())
|
||||
{
|
||||
if (t->GetKind() != Track::Wave || !t->GetSelected())
|
||||
{
|
||||
if (t->IsSyncLockSelected())
|
||||
{
|
||||
t->SyncLockAdjust(mT1, mT0 + mDuration);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const bool multichannel = mNumAudioIn > 1;
|
||||
auto range = multichannel
|
||||
? mOutputTracks->Leaders()
|
||||
: mOutputTracks->Any();
|
||||
range.VisitWhile( bGoodResult,
|
||||
[&](WaveTrack *left, const Track::Fallthrough &fallthrough) {
|
||||
if (!left->GetSelected())
|
||||
return fallthrough();
|
||||
|
||||
WaveTrack *left = (WaveTrack *)t;
|
||||
WaveTrack *right;
|
||||
sampleCount len;
|
||||
sampleCount leftStart;
|
||||
sampleCount rightStart;
|
||||
WaveTrack *right;
|
||||
sampleCount len;
|
||||
sampleCount leftStart;
|
||||
sampleCount rightStart;
|
||||
|
||||
if (!isGenerator)
|
||||
{
|
||||
GetSamples(left, &leftStart, &len);
|
||||
mSampleCnt = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
leftStart = 0;
|
||||
mSampleCnt = left->TimeToLongSamples(mDuration);
|
||||
}
|
||||
|
||||
mNumChannels = 1;
|
||||
|
||||
if (left->GetChannel() == Track::LeftChannel)
|
||||
{
|
||||
map[0] = ChannelNameFrontLeft;
|
||||
}
|
||||
else if (left->GetChannel() == Track::RightChannel)
|
||||
{
|
||||
map[0] = ChannelNameFrontRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[0] = ChannelNameMono;
|
||||
}
|
||||
map[1] = ChannelNameEOL;
|
||||
|
||||
right = NULL;
|
||||
rightStart = 0;
|
||||
if (left->GetLinked() && mNumAudioIn > 1)
|
||||
{
|
||||
// Assume linked track is wave
|
||||
right = static_cast<WaveTrack *>(iter.Next());
|
||||
if (!isGenerator)
|
||||
{
|
||||
GetSamples(right, &rightStart, &len);
|
||||
}
|
||||
clear = false;
|
||||
mNumChannels = 2;
|
||||
|
||||
if (right->GetChannel() == Track::LeftChannel)
|
||||
{
|
||||
map[1] = ChannelNameFrontLeft;
|
||||
}
|
||||
else if (right->GetChannel() == Track::RightChannel)
|
||||
{
|
||||
map[1] = ChannelNameFrontRight;
|
||||
GetSamples(left, &leftStart, &len);
|
||||
mSampleCnt = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[1] = ChannelNameMono;
|
||||
len = 0;
|
||||
leftStart = 0;
|
||||
mSampleCnt = left->TimeToLongSamples(mDuration);
|
||||
}
|
||||
map[2] = ChannelNameEOL;
|
||||
}
|
||||
|
||||
// Let the client know the sample rate
|
||||
SetSampleRate(left->GetRate());
|
||||
mNumChannels = 1;
|
||||
|
||||
// Get the block size the client wants to use
|
||||
auto max = left->GetMaxBlockSize() * 2;
|
||||
mBlockSize = SetBlockSize(max);
|
||||
if (left->GetChannel() == Track::LeftChannel)
|
||||
{
|
||||
map[0] = ChannelNameFrontLeft;
|
||||
}
|
||||
else if (left->GetChannel() == Track::RightChannel)
|
||||
{
|
||||
map[0] = ChannelNameFrontRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[0] = ChannelNameMono;
|
||||
}
|
||||
map[1] = ChannelNameEOL;
|
||||
|
||||
// Calculate the buffer size to be at least the max rounded up to the clients
|
||||
// selected block size.
|
||||
const auto prevBufferSize = mBufferSize;
|
||||
mBufferSize = ((max + (mBlockSize - 1)) / mBlockSize) * mBlockSize;
|
||||
right = NULL;
|
||||
rightStart = 0;
|
||||
if (left->GetLinked() && multichannel)
|
||||
{
|
||||
// Assume linked track is wave
|
||||
right = static_cast<WaveTrack *>(left->GetLink());
|
||||
if (!isGenerator)
|
||||
{
|
||||
GetSamples(right, &rightStart, &len);
|
||||
}
|
||||
clear = false;
|
||||
mNumChannels = 2;
|
||||
|
||||
// If the buffer size has changed, then (re)allocate the buffers
|
||||
if (prevBufferSize != mBufferSize)
|
||||
{
|
||||
// Always create the number of input buffers the client expects even if we don't have
|
||||
// the same number of channels.
|
||||
inBufPos.reinit( mNumAudioIn );
|
||||
inBuffer.reinit( mNumAudioIn, mBufferSize );
|
||||
if (right->GetChannel() == Track::LeftChannel)
|
||||
{
|
||||
map[1] = ChannelNameFrontLeft;
|
||||
}
|
||||
else if (right->GetChannel() == Track::RightChannel)
|
||||
{
|
||||
map[1] = ChannelNameFrontRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[1] = ChannelNameMono;
|
||||
}
|
||||
map[2] = ChannelNameEOL;
|
||||
}
|
||||
|
||||
// We won't be using more than the first 2 buffers, so clear the rest (if any)
|
||||
for (size_t i = 2; i < mNumAudioIn; i++)
|
||||
// Let the client know the sample rate
|
||||
SetSampleRate(left->GetRate());
|
||||
|
||||
// Get the block size the client wants to use
|
||||
auto max = left->GetMaxBlockSize() * 2;
|
||||
mBlockSize = SetBlockSize(max);
|
||||
|
||||
// Calculate the buffer size to be at least the max rounded up to the clients
|
||||
// selected block size.
|
||||
const auto prevBufferSize = mBufferSize;
|
||||
mBufferSize = ((max + (mBlockSize - 1)) / mBlockSize) * mBlockSize;
|
||||
|
||||
// If the buffer size has changed, then (re)allocate the buffers
|
||||
if (prevBufferSize != mBufferSize)
|
||||
{
|
||||
// Always create the number of input buffers the client expects even if we don't have
|
||||
// the same number of channels.
|
||||
inBufPos.reinit( mNumAudioIn );
|
||||
inBuffer.reinit( mNumAudioIn, mBufferSize );
|
||||
|
||||
// We won't be using more than the first 2 buffers, so clear the rest (if any)
|
||||
for (size_t i = 2; i < mNumAudioIn; i++)
|
||||
{
|
||||
for (size_t j = 0; j < mBufferSize; j++)
|
||||
{
|
||||
inBuffer[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Always create the number of output buffers the client expects even if we don't have
|
||||
// the same number of channels.
|
||||
outBufPos.reinit( mNumAudioOut );
|
||||
// Output buffers get an extra mBlockSize worth to give extra room if
|
||||
// the plugin adds latency
|
||||
outBuffer.reinit( mNumAudioOut, mBufferSize + mBlockSize );
|
||||
}
|
||||
|
||||
// (Re)Set the input buffer positions
|
||||
for (size_t i = 0; i < mNumAudioIn; i++)
|
||||
{
|
||||
inBufPos[i] = inBuffer[i].get();
|
||||
}
|
||||
|
||||
// (Re)Set the output buffer positions
|
||||
for (size_t i = 0; i < mNumAudioOut; i++)
|
||||
{
|
||||
outBufPos[i] = outBuffer[i].get();
|
||||
}
|
||||
|
||||
// Clear unused input buffers
|
||||
if (!right && !clear && mNumAudioIn > 1)
|
||||
{
|
||||
for (size_t j = 0; j < mBufferSize; j++)
|
||||
{
|
||||
inBuffer[i][j] = 0.0;
|
||||
inBuffer[1][j] = 0.0;
|
||||
}
|
||||
clear = true;
|
||||
}
|
||||
|
||||
// Always create the number of output buffers the client expects even if we don't have
|
||||
// the same number of channels.
|
||||
// Output buffers get an extra mBlockSize worth to give extra room if
|
||||
// the plugin adds latency
|
||||
outBufPos.reinit( mNumAudioOut );
|
||||
outBuffer.reinit( mNumAudioOut, mBufferSize + mBlockSize );
|
||||
}
|
||||
// Go process the track(s)
|
||||
bGoodResult = ProcessTrack(
|
||||
count, map, left, right, leftStart, rightStart, len,
|
||||
inBuffer, outBuffer, inBufPos, outBufPos);
|
||||
if (!bGoodResult)
|
||||
return;
|
||||
|
||||
// (Re)Set the input buffer positions
|
||||
for (size_t i = 0; i < mNumAudioIn; i++)
|
||||
{
|
||||
inBufPos[i] = inBuffer[i].get();
|
||||
count++;
|
||||
},
|
||||
[&](Track *t) {
|
||||
if (t->IsSyncLockSelected())
|
||||
t->SyncLockAdjust(mT1, mT0 + mDuration);
|
||||
}
|
||||
|
||||
// (Re)Set the output buffer positions
|
||||
for (size_t i = 0; i < mNumAudioOut; i++)
|
||||
{
|
||||
outBufPos[i] = outBuffer[i].get();
|
||||
}
|
||||
|
||||
// Clear unused input buffers
|
||||
if (!right && !clear && mNumAudioIn > 1)
|
||||
{
|
||||
for (size_t j = 0; j < mBufferSize; j++)
|
||||
{
|
||||
inBuffer[1][j] = 0.0;
|
||||
}
|
||||
clear = true;
|
||||
}
|
||||
|
||||
// Go process the track(s)
|
||||
bGoodResult = ProcessTrack(
|
||||
count, map, left, right, leftStart, rightStart, len,
|
||||
inBuffer, outBuffer, inBufPos, outBufPos);
|
||||
if (!bGoodResult)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
);
|
||||
|
||||
if (bGoodResult && GetType() == EffectTypeGenerate)
|
||||
{
|
||||
|
@ -38,14 +38,11 @@ bool Generator::Process()
|
||||
// Iterate over the tracks
|
||||
bool bGoodResult = true;
|
||||
int ntrack = 0;
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
Track* t = iter.First();
|
||||
|
||||
while (t != NULL)
|
||||
{
|
||||
if (t->GetKind() == Track::Wave && t->GetSelected()) {
|
||||
WaveTrack* track = (WaveTrack*)t;
|
||||
|
||||
mOutputTracks->Any().VisitWhile( bGoodResult,
|
||||
[&](WaveTrack *track, const Track::Fallthrough &fallthrough) {
|
||||
if (!track->GetSelected())
|
||||
return fallthrough();
|
||||
bool editClipCanMove = gPrefs->GetEditClipsCanMove();
|
||||
|
||||
//if we can't move clips, and we're generating into an empty space,
|
||||
@ -59,7 +56,8 @@ bool Generator::Process()
|
||||
wxICON_STOP,
|
||||
_("Error"));
|
||||
Failure();
|
||||
return false;
|
||||
bGoodResult = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetDuration() > 0.0)
|
||||
@ -87,7 +85,7 @@ bool Generator::Process()
|
||||
|
||||
if (!bGoodResult) {
|
||||
Failure();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -98,21 +96,23 @@ bool Generator::Process()
|
||||
}
|
||||
|
||||
ntrack++;
|
||||
},
|
||||
[&](Track *t) {
|
||||
if (t->IsSyncLockSelected()) {
|
||||
t->SyncLockAdjust(mT1, mT0 + GetDuration());
|
||||
}
|
||||
}
|
||||
else if (t->IsSyncLockSelected()) {
|
||||
t->SyncLockAdjust(mT1, mT0 + GetDuration());
|
||||
}
|
||||
// Move on to the next track
|
||||
t = iter.Next();
|
||||
);
|
||||
|
||||
if (bGoodResult) {
|
||||
Success();
|
||||
|
||||
this->ReplaceProcessedTracks(bGoodResult);
|
||||
|
||||
mT1 = mT0 + GetDuration(); // Update selection.
|
||||
}
|
||||
|
||||
Success();
|
||||
|
||||
this->ReplaceProcessedTracks(bGoodResult);
|
||||
|
||||
mT1 = mT0 + GetDuration(); // Update selection.
|
||||
|
||||
return true;
|
||||
return bGoodResult;
|
||||
}
|
||||
|
||||
bool BlockGenerator::GenerateTrack(WaveTrack *tmp,
|
||||
|
@ -113,27 +113,19 @@ bool EffectRepeat::Process()
|
||||
bool bGoodResult = true;
|
||||
double maxDestLen = 0.0; // used to change selection to generated bit
|
||||
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
|
||||
for (Track *t = iter.First(); t && bGoodResult; t = iter.Next())
|
||||
{
|
||||
if (t->GetKind() == Track::Label)
|
||||
mOutputTracks->Any().VisitWhile( bGoodResult,
|
||||
[&](LabelTrack *track)
|
||||
{
|
||||
if (t->GetSelected() || t->IsSyncLockSelected())
|
||||
if (track->GetSelected() || track->IsSyncLockSelected())
|
||||
{
|
||||
LabelTrack* track = (LabelTrack*)t;
|
||||
|
||||
if (!track->Repeat(mT0, mT1, repeatCount))
|
||||
{
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->GetKind() == Track::Wave && t->GetSelected())
|
||||
},
|
||||
[&](WaveTrack *track, const Track::Fallthrough &fallthrough)
|
||||
{
|
||||
WaveTrack* track = (WaveTrack*)t;
|
||||
|
||||
if (!track->GetSelected())
|
||||
return fallthrough(); // Fall through to next lambda
|
||||
auto start = track->TimeToLongSamples(mT0);
|
||||
auto end = track->TimeToLongSamples(mT1);
|
||||
auto len = end - start;
|
||||
@ -141,9 +133,7 @@ bool EffectRepeat::Process()
|
||||
double tc = mT0 + tLen;
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
|
||||
auto dest = track->Copy(mT0, mT1);
|
||||
for(int j=0; j<repeatCount; j++)
|
||||
@ -151,7 +141,7 @@ bool EffectRepeat::Process()
|
||||
if (TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
|
||||
{
|
||||
bGoodResult = false;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
track->Paste(tc, dest.get());
|
||||
tc += tLen;
|
||||
@ -159,12 +149,13 @@ bool EffectRepeat::Process()
|
||||
if (tc > maxDestLen)
|
||||
maxDestLen = tc;
|
||||
nTrack++;
|
||||
}
|
||||
else if (t->IsSyncLockSelected())
|
||||
},
|
||||
[&](Track *t)
|
||||
{
|
||||
t->SyncLockAdjust(mT1, mT1 + (mT1 - mT0) * repeatCount);
|
||||
if( t->IsSyncLockSelected() )
|
||||
t->SyncLockAdjust(mT1, mT1 + (mT1 - mT0) * repeatCount);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (bGoodResult)
|
||||
{
|
||||
|
@ -67,37 +67,27 @@ bool EffectReverse::Process()
|
||||
//Track::All is needed because Reverse should move the labels too
|
||||
this->CopyInputTracks(Track::All); // Set up mOutputTracks.
|
||||
bool bGoodResult = true;
|
||||
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
Track *t = iter.First();
|
||||
int count = 0;
|
||||
while (t) {
|
||||
if (t->GetKind() == Track::Wave &&
|
||||
(t->GetSelected() || t->IsSyncLockSelected()))
|
||||
{
|
||||
WaveTrack *track = (WaveTrack*)t;
|
||||
|
||||
auto trackRange =
|
||||
mOutputTracks->Any() + &Track::IsSelectedOrSyncLockSelected;
|
||||
trackRange.VisitWhile( bGoodResult,
|
||||
[&](WaveTrack * track) {
|
||||
if (mT1 > mT0) {
|
||||
auto start = track->TimeToLongSamples(mT0);
|
||||
auto end = track->TimeToLongSamples(mT1);
|
||||
auto len = end - start;
|
||||
|
||||
if (!ProcessOneWave(count, track, start, len))
|
||||
{
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->GetKind() == Track::Label &&
|
||||
(t->GetSelected() || t->IsSyncLockSelected()))
|
||||
{
|
||||
LabelTrack *track = (LabelTrack*)t;
|
||||
count++;
|
||||
},
|
||||
[&](LabelTrack * track) {
|
||||
track->ChangeLabelsOnReverse(mT0, mT1);
|
||||
count++;
|
||||
}
|
||||
t = iter.Next();
|
||||
count++;
|
||||
}
|
||||
);
|
||||
|
||||
this->ReplaceProcessedTracks(bGoodResult);
|
||||
return bGoodResult;
|
||||
|
@ -217,8 +217,6 @@ bool EffectSBSMS::Process()
|
||||
//Iterate over each track
|
||||
//Track::All is needed because this effect needs to introduce silence in the group tracks to keep sync
|
||||
this->CopyInputTracks(Track::All); // Set up mOutputTracks.
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
Track* t;
|
||||
mCurTrackNum = 0;
|
||||
|
||||
double maxDuration = 0.0;
|
||||
@ -229,19 +227,16 @@ bool EffectSBSMS::Process()
|
||||
Slide pitchSlide(pitchSlideType,pitchStart,pitchEnd);
|
||||
mTotalStretch = rateSlide.getTotalStretch();
|
||||
|
||||
t = iter.First();
|
||||
while (bGoodResult && t != NULL) {
|
||||
if (t->GetKind() == Track::Label &&
|
||||
(t->GetSelected() || (mustSync && t->IsSyncLockSelected())) )
|
||||
{
|
||||
if (!ProcessLabelTrack(static_cast<LabelTrack*>(t))) {
|
||||
mOutputTracks->Leaders().VisitWhile( bGoodResult,
|
||||
[&](LabelTrack *lt, const Track::Fallthrough &fallthrough) {
|
||||
if (!(lt->GetSelected() || (mustSync && lt->IsSyncLockSelected())))
|
||||
return fallthrough();
|
||||
if (!ProcessLabelTrack(lt))
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (t->GetKind() == Track::Wave && t->GetSelected() )
|
||||
{
|
||||
WaveTrack* leftTrack = (WaveTrack*)t;
|
||||
},
|
||||
[&](WaveTrack *leftTrack, const Track::Fallthrough &fallthrough) {
|
||||
if (!leftTrack->GetSelected())
|
||||
return fallthrough();
|
||||
|
||||
//Get start and end times from track
|
||||
mCurT0 = leftTrack->GetStartTime();
|
||||
@ -261,7 +256,7 @@ bool EffectSBSMS::Process()
|
||||
if (leftTrack->GetLinked()) {
|
||||
double t;
|
||||
// Assume linked track is wave or null
|
||||
rightTrack = static_cast<WaveTrack*>(iter.Next());
|
||||
rightTrack = static_cast<WaveTrack*>(leftTrack->GetLink());
|
||||
|
||||
//Adjust bounds by the right tracks markers
|
||||
t = rightTrack->GetStartTime();
|
||||
@ -321,7 +316,8 @@ bool EffectSBSMS::Process()
|
||||
( samplesToProcess.as_long_long() ),
|
||||
0, nullptr);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rb.bPitch = false;
|
||||
outSlideType = (srProcess==srTrack?SlideIdentity:SlideConstant);
|
||||
outResampleCB = postResampleCB;
|
||||
@ -414,8 +410,10 @@ bool EffectSBSMS::Process()
|
||||
frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once.
|
||||
}
|
||||
}
|
||||
if (TrackProgress(nWhichTrack, frac))
|
||||
return false;
|
||||
if (TrackProgress(nWhichTrack, frac)) {
|
||||
bGoodResult = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@ -425,35 +423,34 @@ bool EffectSBSMS::Process()
|
||||
std::rethrow_exception(pException);
|
||||
}
|
||||
|
||||
if (bGoodResult) {
|
||||
rb.outputLeftTrack->Flush();
|
||||
if(rightTrack)
|
||||
rb.outputRightTrack->Flush();
|
||||
rb.outputLeftTrack->Flush();
|
||||
if(rightTrack)
|
||||
rb.outputRightTrack->Flush();
|
||||
|
||||
leftTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputLeftTrack.get(),
|
||||
true, false, warper.get());
|
||||
leftTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputLeftTrack.get(),
|
||||
true, false, warper.get());
|
||||
|
||||
if(rightTrack)
|
||||
rightTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputRightTrack.get(),
|
||||
true, false, warper.get());
|
||||
}
|
||||
if(rightTrack)
|
||||
rightTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputRightTrack.get(),
|
||||
true, false, warper.get());
|
||||
}
|
||||
mCurTrackNum++;
|
||||
},
|
||||
[&](Track *t) {
|
||||
if (mustSync && t->IsSyncLockSelected())
|
||||
{
|
||||
t->SyncLockAdjust(mCurT1, mCurT0 + (mCurT1 - mCurT0) * mTotalStretch);
|
||||
}
|
||||
}
|
||||
else if (mustSync && t->IsSyncLockSelected())
|
||||
{
|
||||
t->SyncLockAdjust(mCurT1, mCurT0 + (mCurT1 - mCurT0) * mTotalStretch);
|
||||
}
|
||||
//Iterate to the next track
|
||||
t = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
if (bGoodResult)
|
||||
if (bGoodResult) {
|
||||
ReplaceProcessedTracks(bGoodResult);
|
||||
|
||||
// Update selection
|
||||
mT0 = mCurT0;
|
||||
mT1 = mCurT0 + maxDuration;
|
||||
// Update selection
|
||||
mT0 = mCurT0;
|
||||
mT1 = mCurT0 + maxDuration;
|
||||
}
|
||||
|
||||
return bGoodResult;
|
||||
}
|
||||
|
@ -86,36 +86,28 @@ bool EffectSoundTouch::ProcessWithTimeWarper(const TimeWarper &warper)
|
||||
this->CopyInputTracks(Track::All);
|
||||
bool bGoodResult = true;
|
||||
|
||||
TrackListIterator iter(mOutputTracks.get());
|
||||
Track* t;
|
||||
mCurTrackNum = 0;
|
||||
m_maxNewLength = 0.0;
|
||||
|
||||
t = iter.First();
|
||||
while (t != NULL) {
|
||||
if (t->GetKind() == Track::Label &&
|
||||
(t->GetSelected() || (mustSync && t->IsSyncLockSelected())) )
|
||||
{
|
||||
if (!ProcessLabelTrack(static_cast<LabelTrack*>(t), warper))
|
||||
{
|
||||
mOutputTracks->Leaders().VisitWhile( bGoodResult,
|
||||
[&]( LabelTrack *lt, const Track::Fallthrough &fallthrough ) {
|
||||
if ( !(lt->GetSelected() || (mustSync && lt->IsSyncLockSelected())) )
|
||||
return fallthrough();
|
||||
if (!ProcessLabelTrack(lt, warper))
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
#ifdef USE_MIDI
|
||||
else if (t->GetKind() == Track::Note &&
|
||||
(t->GetSelected() || (mustSync && t->IsSyncLockSelected())))
|
||||
{
|
||||
if (!ProcessNoteTrack(static_cast<NoteTrack*>(t), warper))
|
||||
{
|
||||
[&]( NoteTrack *nt, const Track::Fallthrough &fallthrough ) {
|
||||
if ( !(nt->GetSelected() || (mustSync && nt->IsSyncLockSelected())) )
|
||||
return fallthrough();
|
||||
if (!ProcessNoteTrack(nt, warper))
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
#endif
|
||||
else if (t->GetKind() == Track::Wave && t->GetSelected())
|
||||
{
|
||||
WaveTrack* leftTrack = (WaveTrack*)t;
|
||||
[&]( WaveTrack *leftTrack, const Track::Fallthrough &fallthrough ) {
|
||||
if (!leftTrack->GetSelected())
|
||||
return fallthrough();
|
||||
|
||||
//Get start and end times from track
|
||||
mCurT0 = leftTrack->GetStartTime();
|
||||
mCurT1 = leftTrack->GetEndTime();
|
||||
@ -131,7 +123,7 @@ bool EffectSoundTouch::ProcessWithTimeWarper(const TimeWarper &warper)
|
||||
if (leftTrack->GetLinked()) {
|
||||
double t;
|
||||
// Assume linked track is wave
|
||||
WaveTrack* rightTrack = static_cast<WaveTrack*>(iter.Next());
|
||||
WaveTrack* rightTrack = static_cast<WaveTrack*>(leftTrack->GetLink());
|
||||
|
||||
//Adjust bounds by the right tracks markers
|
||||
t = rightTrack->GetStartTime();
|
||||
@ -150,10 +142,7 @@ bool EffectSoundTouch::ProcessWithTimeWarper(const TimeWarper &warper)
|
||||
|
||||
//ProcessStereo() (implemented below) processes a stereo track
|
||||
if (!ProcessStereo(leftTrack, rightTrack, start, end, warper))
|
||||
{
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
mCurTrackNum++; // Increment for rightTrack, too.
|
||||
} else {
|
||||
//Transform the marker timepoints to samples
|
||||
@ -165,21 +154,17 @@ bool EffectSoundTouch::ProcessWithTimeWarper(const TimeWarper &warper)
|
||||
|
||||
//ProcessOne() (implemented below) processes a single track
|
||||
if (!ProcessOne(leftTrack, start, end, warper))
|
||||
{
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mCurTrackNum++;
|
||||
},
|
||||
[&]( Track *t ) {
|
||||
if (mustSync && t->IsSyncLockSelected()) {
|
||||
t->SyncLockAdjust(mT1, warper.Warp(mT1));
|
||||
}
|
||||
}
|
||||
else if (mustSync && t->IsSyncLockSelected()) {
|
||||
t->SyncLockAdjust(mT1, warper.Warp(mT1));
|
||||
}
|
||||
|
||||
//Iterate to the next track
|
||||
t = iter.Next();
|
||||
}
|
||||
);
|
||||
|
||||
if (bGoodResult)
|
||||
ReplaceProcessedTracks(bGoodResult);
|
||||
|
@ -523,31 +523,26 @@ bool EffectTruncSilence::DoRemoval
|
||||
mTruncLongestAllowedSilence);
|
||||
}
|
||||
|
||||
double cutLen = std::max(0.0, inLength - outLength);
|
||||
const double cutLen = std::max(0.0, inLength - outLength);
|
||||
// Don't waste time cutting nothing.
|
||||
if( cutLen == 0.0 )
|
||||
continue;
|
||||
|
||||
totalCutLen += cutLen;
|
||||
|
||||
TrackListIterator iterOut(mOutputTracks.get());
|
||||
bool lastSeen = false;
|
||||
for (Track *t = iterOut.StartWith(firstTrack); t && !lastSeen; t = iterOut.Next())
|
||||
{
|
||||
lastSeen = (t == lastTrack);
|
||||
if (!(t->GetSelected() || t->IsSyncLockSelected()))
|
||||
continue;
|
||||
double cutStart = (r->start + r->end - cutLen) / 2;
|
||||
double cutEnd = cutStart + cutLen;
|
||||
(mOutputTracks->Any()
|
||||
.StartingWith(firstTrack).EndingAfter(lastTrack)
|
||||
+ &Track::IsSelectedOrSyncLockSelected
|
||||
- [&](const Track *pTrack) { return
|
||||
// Don't waste time past the end of a track
|
||||
pTrack->GetEndTime() < r->start;
|
||||
}
|
||||
).Visit(
|
||||
[&](WaveTrack *wt) {
|
||||
|
||||
// Don't waste time past the end of a track
|
||||
if (t->GetEndTime() < r->start)
|
||||
continue;
|
||||
|
||||
// Don't waste time cutting nothing.
|
||||
if( cutLen == 0.0 )
|
||||
continue;
|
||||
|
||||
double cutStart = (r->start + r->end - cutLen) / 2;
|
||||
double cutEnd = cutStart + cutLen;
|
||||
if (t->GetKind() == Track::Wave)
|
||||
{
|
||||
// In WaveTracks, clear with a cross-fade
|
||||
WaveTrack *const wt = static_cast<WaveTrack*>(t);
|
||||
auto blendFrames = mBlendFrameCount;
|
||||
// Round start/end times to frame boundaries
|
||||
cutStart = wt->LongSamplesToTime(wt->TimeToLongSamples(cutStart));
|
||||
@ -580,11 +575,12 @@ bool EffectTruncSilence::DoRemoval
|
||||
|
||||
// Write cross-faded data
|
||||
wt->Set((samplePtr)buf1.get(), floatSample, t1, blendFrames);
|
||||
}
|
||||
else
|
||||
},
|
||||
[&](Track *t) {
|
||||
// Non-wave tracks: just do a sync-lock adjust
|
||||
t->SyncLockAdjust(cutEnd, cutStart);
|
||||
}
|
||||
}
|
||||
);
|
||||
++whichReg;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user