Change lots of code that uses linking to use the new

scheme.
This commit is contained in:
businessmanprogrammersteve 2010-02-16 20:50:38 +00:00
parent 98ca2b474b
commit e35e019e17
22 changed files with 344 additions and 530 deletions

View File

@ -90,6 +90,7 @@ LabelTrack::LabelTrack(DirManager * projDirManager):
mSelIndex(-1),
mMouseOverLabelLeft(-1),
mMouseOverLabelRight(-1),
mClipLen(0.0),
mIsAdjustingLabel(false)
{
SetDefaultName(_("Label Track"));
@ -114,6 +115,7 @@ LabelTrack::LabelTrack(const LabelTrack &orig) :
mSelIndex(-1),
mMouseOverLabelLeft(-1),
mMouseOverLabelRight(-1),
mClipLen(0.0),
mIsAdjustingLabel(false)
{
int len = orig.mLabels.Count();
@ -149,7 +151,7 @@ void LabelTrack::SetOffset(double dOffset)
}
}
void LabelTrack::ShiftLabelsOnClear(double b, double e)
bool LabelTrack::Clear(double b, double e)
{
for (size_t i=0;i<mLabels.GetCount();i++){
if (mLabels[i]->t >= e){//label is after deletion region
@ -169,10 +171,12 @@ void LabelTrack::ShiftLabelsOnClear(double b, double e)
//nothing
}
}
return true;
}
//used when we want to use clear only on the labels
void LabelTrack::ChangeLabelsOnClear(double b, double e)
bool LabelTrack::SplitDelete(double b, double e)
{
for (size_t i=0;i<mLabels.GetCount();i++) {
if (mLabels[i]->t >= b && mLabels[i]->t1 <= e){//deletion region encloses label
@ -186,6 +190,8 @@ void LabelTrack::ChangeLabelsOnClear(double b, double e)
mLabels[i]->t1 = b;
}
}
return true;
}
void LabelTrack::ShiftLabelsOnInsert(double length, double pt)
{
@ -2135,7 +2141,17 @@ bool LabelTrack::Save(wxTextFile * out, bool overwrite)
}
#endif
bool LabelTrack::Cut(double t0, double t1, Track ** dest)
bool LabelTrack::Cut(double t0, double t1, Track **dest)
{
if (!SplitCut(t0, t1, dest))
return false;
if (!Clear(t0, t1))
return false;
return true;
}
bool LabelTrack::SplitCut(double t0, double t1, Track ** dest)
{
*dest = new LabelTrack(GetDirManager());
int len = mLabels.Count();
@ -2182,7 +2198,7 @@ bool LabelTrack::Copy(double t0, double t1, Track ** dest)
}
bool LabelTrack::Paste(double t, Track * src)
bool LabelTrack::PasteOver(double t, Track * src)
{
if (src->GetKind() != Track::Label)
return false;
@ -2206,11 +2222,20 @@ bool LabelTrack::Paste(double t, Track * src)
return true;
}
bool LabelTrack::Paste(double t, Track *src)
{
if (src->GetKind() != Track::Label)
return false;
LabelTrack *lt = (LabelTrack *)src;
double shiftAmt = lt->mClipLen > 0.0 ? lt->mClipLen : lt->GetEndTime();
ShiftLabelsOnInsert(shiftAmt, t);
return PasteOver(t, src);
}
// This repeats the labels in a time interval a specified number of times.
// Like Paste(), it does not shift existing labels over
// - It assumes that you've already called ShiftLabelsOnInsert(), because
// sometimes with linking enabled that's hard to avoid.
// - It assumes that you inserted the necessary extra time at t1, not t0.
bool LabelTrack::Repeat(double t0, double t1, int n)
{
// Sanity-check the arguments
@ -2218,6 +2243,9 @@ bool LabelTrack::Repeat(double t0, double t1, int n)
double tLen = t1 - t0;
// Insert space for the repetitions
ShiftLabelsOnInsert(tLen * n, t1);
for (unsigned int i = 0; i < mLabels.GetCount(); i++)
{
if (mLabels[i]->t >= t0 && mLabels[i]->t <= t1 &&
@ -2254,30 +2282,6 @@ bool LabelTrack::Repeat(double t0, double t1, int n)
return true;
}
bool LabelTrack::Clear(double t0, double t1)
{
AudacityProject *p = GetActiveProject();
if (p && p->IsSticky()){
TrackGroupIterator grpIter(p->GetTracks());
Track *t = grpIter.First(this);
// If this track is part of a group, find a Wave track in the group and do
// the clear from there to ensure proper group behavior
while (t) {
if (t->GetKind() == Track::Wave) {
return t->Clear(t0, t1);
}
t = grpIter.Next();
}
// Fallback: shift labels in this track
ShiftLabelsOnClear(t0, t1);
}
else
ChangeLabelsOnClear(t0, t1);
return true;
}
bool LabelTrack::Silence(double t0, double t1)
{
int len = mLabels.Count();

View File

@ -175,8 +175,10 @@ class LabelTrack:public Track {
void MayAdjustLabel( int iLabel, int iEdge, bool bAllowSwapping, double fNewTime);
void MayMoveLabel( int iLabel, int iEdge, double fNewTime);
void ShiftLabelsOnClear(double b, double e);
void ChangeLabelsOnClear(double b, double e);
// This pastes labels without shifting existing ones
bool PasteOver(double t, Track *src);
bool SplitCut(double b, double e, Track **dest);
bool SplitDelete(double b, double e);
void ShiftLabelsOnInsert(double length, double pt);
void ChangeLabelsOnReverse(double b, double e);
void ScaleLabels(double b, double e, double change);
@ -221,7 +223,7 @@ class LabelTrack:public Track {
bool mRightDragging; /// flag to tell if it's a valid dragging
bool mDrawCursor; /// flag to tell if drawing the cursor or not
// Used only for a LabelTrack on the clipboard
// Set in copied label tracks
double mClipLen;
void ComputeLayout(const wxRect & r, double h, double pps);

View File

@ -2992,7 +2992,7 @@ void AudacityProject::OnRedo()
void AudacityProject::OnCut()
{
TrackAndGroupIterator iter(mTracks);
TrackListIterator iter(mTracks);
Track *n = iter.First();
Track *dest;
@ -3042,7 +3042,8 @@ void AudacityProject::OnCut()
n = iter.First();
while (n) {
if (n->GetSelected()) {
// We clear from selected and synchro-selected tracks
if (n->GetSelected() || n->IsSynchroSelected()) {
switch (n->GetKind())
{
#if defined(USE_MIDI)
@ -3064,12 +3065,7 @@ void AudacityProject::OnCut()
break;
}
}
// Selected wave and label tracks may need group iteration
if (IsSticky() && n->GetSelected() &&
(n->GetKind() == Track::Wave || n->GetKind() == Track::Label))
n = iter.NextGroup();
else
n = iter.Next();
n = iter.Next();
}
msClipLen = (mViewInfo.sel1 - mViewInfo.sel0);
@ -3299,10 +3295,6 @@ void AudacityProject::OnPaste()
bool trackTypeMismatch = false;
bool advanceClipboard = true;
// Keeps track of whether n would be the first WaveTrack in its group to
// receive data from the paste.
bool firstInGroup = true;
while (n && c) {
if (n->GetSelected()) {
advanceClipboard = true;
@ -3329,8 +3321,6 @@ void AudacityProject::OnPaste()
c = tmpC;
while (n && (c->GetKind() != n->GetKind()) )
{
if (n && n->GetKind() == Track::Label)
firstInGroup = true;
n = iter.Next();
}
if (!n) c = NULL;
@ -3368,25 +3358,19 @@ void AudacityProject::OnPaste()
{
// If not the first in group we set useHandlePaste to true
pastedSomething = ((WaveTrack*)n)->ClearAndPaste(t0, t1,
(WaveTrack*)c, true, true, NULL, false, !firstInGroup);
firstInGroup = firstInGroup && !pastedSomething;
(WaveTrack*)c, true, true);
}
else if (c->GetKind() == Track::Label &&
n && n->GetKind() == Track::Label)
{
// AWD: LabelTrack::Paste() doesn't shift future labels (and
// WaveTrack::HandleGroupPaste() doesn't adjust selected group
// tracks, so some other track's paste hasn't done it either). To
// be (sort of) consistent with Clear behavior, we'll only shift
// them if linking is on and we have already pasted into a wave
// track in this group.
if (IsSticky() && !firstInGroup)
{
((LabelTrack *)n)->ShiftLabelsOnClear(t0, t1);
((LabelTrack *)n)->ShiftLabelsOnInsert(msClipLen, t0);
}
((LabelTrack *)n)->Clear(t0, t1);
pastedSomething = n->Paste(t0, c);
// To be (sort of) consistent with Clear behavior, we'll only shift
// them if linking is on
if (IsSticky())
((LabelTrack *)n)->ShiftLabelsOnInsert(msClipLen, t0);
pastedSomething = ((LabelTrack *)n)->PasteOver(t0, c);
}
else
{
@ -3405,17 +3389,7 @@ void AudacityProject::OnPaste()
((WaveTrack *) n)->Clear(t0, t1);
}
// firstInGroup should always be false here, unless pasting to
// the first channel failed
if (firstInGroup)
{
pastedSomething = ((WaveTrack *)n)->Paste(t0, c);
firstInGroup = !pastedSomething;
}
else
{
pastedSomething = ((WaveTrack *)n)->HandlePaste(t0, c);
}
pastedSomething = ((WaveTrack *)n)->Paste(t0, c);
}
else {
n->Clear(t0, t1);
@ -3430,10 +3404,12 @@ void AudacityProject::OnPaste()
prev = c;
c = clipIter.Next();
}
} // if (n->GetSelected())
else if (n->IsSynchroSelected())
{
n->SyncAdjust(t1, t0 + msClipLen);
}
if (n && n->GetKind() == Track::Label)
firstInGroup = true;
n = iter.Next();
}
@ -3450,8 +3426,7 @@ void AudacityProject::OnPaste()
if (n->GetSelected() && n->GetKind()==Track::Wave){
if (c && c->GetKind() == Track::Wave){
pastedSomething = ((WaveTrack *)n)->ClearAndPaste(t0, t1,
(WaveTrack *)c, true, true, NULL, false, !firstInGroup);
firstInGroup = firstInGroup && !pastedSomething;
(WaveTrack *)c, true, true);
}else{
WaveTrack *tmp;
tmp = mTrackFactory->NewWaveTrack( ((WaveTrack*)n)->GetSampleFormat(), ((WaveTrack*)n)->GetRate());
@ -3459,24 +3434,24 @@ void AudacityProject::OnPaste()
tmp->Flush();
pastedSomething = ((WaveTrack *)n)->ClearAndPaste(t0, t1,
tmp, true, true, NULL, false, !firstInGroup);
firstInGroup = firstInGroup && !pastedSomething;
tmp, true, true);
delete tmp;
}
}
else if (n->GetSelected() && n->GetKind() == Track::Label)
else if (n->GetKind() == Track::Label && n->GetSelected())
{
// Make room in label tracks as necessary
if (IsSticky() && !firstInGroup)
{
((LabelTrack *)n)->ShiftLabelsOnClear(t0, t1);
((LabelTrack *)n)->Clear(t0, t1);
// As above, only shift labels if linking is on
if (IsSticky())
((LabelTrack *)n)->ShiftLabelsOnInsert(msClipLen, t0);
}
}
else if (n->IsSynchroSelected())
{
n->SyncAdjust(t1, t0 + msClipLen);
}
if (n && n->GetKind() == Track::Label)
firstInGroup = true;
n = iter.Next();
}
}

View File

@ -3671,18 +3671,20 @@ void AudacityProject::ClearClipboard()
void AudacityProject::Clear()
{
TrackAndGroupIterator iter(mTracks);
TrackListIterator iter(mTracks);
Track *n = iter.First();
while (n) {
if (n->GetSelected()) {
n->Clear(mViewInfo.sel0, mViewInfo.sel1);
// Wave and Label tracks have group behaviour
if (IsSticky() && (n->GetKind() == Track::Wave || n->GetKind() == Track::Label)) n = iter.NextGroup();
else n = iter.Next();
if (n->GetSelected() || n->IsSynchroSelected()) {
// AWD: Preserve traditional label track behavior: only shift time in
// linked mode
if (n->GetKind() == Track::Label && IsSticky())
((LabelTrack *)n)->SplitDelete(mViewInfo.sel0, mViewInfo.sel1);
else
n->Clear(mViewInfo.sel0, mViewInfo.sel1);
}
else n = iter.Next();
n = iter.Next();
}
double seconds = mViewInfo.sel1 - mViewInfo.sel0;
@ -3981,10 +3983,11 @@ void AudacityProject::GetRegionsByLabel( Regions &regions )
//Executes the edit function on all selected wave tracks with
//regions specified by selected labels
//If No tracks selected, function is applied on all tracks
//If the function deletes audio, groupIteration should probably be set to true,
// so it won't delete too many times.
//If the function replaces the selection with audio of a different length
// syncTracks should be set true to perform the same action on sync-selected
// tracks.
void AudacityProject::EditByLabel( WaveTrack::EditFunction action,
bool groupIteration )
bool syncTracks )
{
Regions regions;
@ -3992,7 +3995,7 @@ void AudacityProject::EditByLabel( WaveTrack::EditFunction action,
if( regions.GetCount() == 0 )
return;
TrackAndGroupIterator iter( mTracks );
TrackListIterator iter( mTracks );
Track *n;
bool allTracks = true;
@ -4011,23 +4014,14 @@ void AudacityProject::EditByLabel( WaveTrack::EditFunction action,
n = iter.First();
while (n)
{
if( n->GetKind() == Track::Wave && ( allTracks || n->GetSelected() ) )
if( n->GetKind() == Track::Wave && ( allTracks || n->GetSelected() ||
(syncTracks && n->IsSynchroSelected()) ) )
{
WaveTrack *wt = ( WaveTrack* )n;
for( int i = ( int )regions.GetCount() - 1; i >= 0; i-- )
( wt->*action )( regions.Item( i )->start, regions.Item( i )->end );
// Tracks operated on may need group iteration
if (IsSticky() && groupIteration)
n = iter.NextGroup();
else
n = iter.Next();
}
else
{
// Tracks not operated on need normal iteration
n = iter.Next();
}
n = iter.Next();
}
//delete label regions
@ -4440,7 +4434,7 @@ bool AudacityProject::GetSnapTo()
bool AudacityProject::IsSticky()
{
#ifdef EXPERIMENTAL_LINKING
return (GetStickyFlag() && (mLastFlags & LabelTracksExistFlag));
return GetStickyFlag();
#else
return false;
#endif

View File

@ -280,7 +280,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
void Rewind(bool shift);
void SkipEnd(bool shift);
void SetStop(bool bStopped);
void EditByLabel( WaveTrack::EditFunction action, bool groupIteration );
void EditByLabel( WaveTrack::EditFunction action, bool syncTracks );
void EditClipboardByLabel( WaveTrack::EditDestFunction action );
bool IsSticky();
bool GetStickyFlag() { return mStickyFlag; };

View File

@ -229,6 +229,34 @@ bool Track::IsSynchroSelected()
return false;
}
bool Track::SyncAdjust(double oldT1, double newT1)
{
if (newT1 > oldT1) {
// Insert space within the track
if (oldT1 > GetEndTime())
return true;
Track *tmp;
bool ret;
ret = Cut(oldT1, GetEndTime(), &tmp);
if (!ret) return false;
ret = Paste(newT1, tmp);
delete tmp;
return ret;
}
else if (newT1 < oldT1) {
// Remove from the track
return Clear(newT1, oldT1);
}
// fall-through: no change
return true;
}
// TrackListIterator
TrackListIterator::TrackListIterator(TrackList * val)
{

View File

@ -162,6 +162,10 @@ class AUDACITY_DLL_API Track: public XMLTagHandler
virtual bool Clear(double t0, double t1) {return false;}
virtual bool Paste(double t, Track * src) {return false;}
// This can be used to adjust a synchro-selected track when the selection
// is replaced by one of a different length.
virtual bool SyncAdjust(double oldT1, double newT1);
virtual bool Silence(double t0, double t1) {return false;}
virtual bool InsertSilence(double t, double len) {return false;}

View File

@ -270,23 +270,14 @@ bool WaveTrack::IsEmpty(double t0, double t1)
}
bool WaveTrack::Cut(double t0, double t1, Track **dest)
{
return Cut(t0, t1, dest, true);
}
bool WaveTrack::Cut(double t0, double t1, Track **dest, bool groupCut)
{
if (t1 < t0)
return false;
// Cut is the same as 'Copy', then 'Delete'
if (!Copy(t0, t1, dest))
return false;
if (groupCut)
return Clear(t0, t1);
else
return HandleClear(t0, t1, false, false);
return Clear(t0, t1);
}
bool WaveTrack::SplitCut(double t0, double t1, Track **dest)
@ -325,47 +316,44 @@ bool WaveTrack::Trim (double t0, double t1)
WaveClipList::compatibility_iterator it;
for(it = GetClipIterator(); it; it = it->GetNext())
{
WaveClip * clip = it->GetData();
{
WaveClip * clip = it->GetData();
//Find the first clip greater than the offset.
//If we end up clipping the entire track, this is useful.
if(firstGreaterOffset < 0 &&
//Find the first clip greater than the offset.
//If we end up clipping the entire track, this is useful.
if(firstGreaterOffset < 0 &&
clip->GetStartTime() >= t0)
firstGreaterOffset = clip->GetStartTime();
firstGreaterOffset = clip->GetStartTime();
if(t1 > clip->GetStartTime() && t1 < clip->GetEndTime())
{
if (!clip->Clear(t1,clip->GetEndTime()))
return false;
inside1 = true;
}
if(t0 > clip->GetStartTime() && t0 < clip->GetEndTime())
{
if (!clip->Clear(clip->GetStartTime(),t0))
return false;
clip->SetOffset(t0);
inside0 = true;
}
if(t1 > clip->GetStartTime() && t1 < clip->GetEndTime())
{
if (!clip->Clear(t1,clip->GetEndTime()))
return false;
inside1 = true;
}
if(t0 > clip->GetStartTime() && t0 < clip->GetEndTime())
{
if (!clip->Clear(clip->GetStartTime(),t0))
return false;
clip->SetOffset(t0);
inside0 = true;
}
}
//if inside0 is false, then the left selector was between
//clips, so delete everything to its left.
if(false == inside1)
{
if (!Clear(t1,GetEndTime()))
return false;
}
{
if (!Clear(t1,GetEndTime()))
return false;
}
if(false == inside0)
{
if (!Clear(0,t0))
return false;
//Reset the track offset to be at the point of the first remaining clip.
SetOffset(firstGreaterOffset );
}
{
if (!SplitDelete(0,t0))
return false;
}
return true;
}
@ -462,45 +450,15 @@ bool WaveTrack::Copy(double t0, double t1, Track **dest)
return true;
}
bool WaveTrack::Paste(double t0, Track *src)
{
return Paste(t0, src, NULL, false);
}
bool WaveTrack::Paste(double t0, Track *src, TrackList* tracks, bool relativeLabels)
{
AudacityProject *p = GetActiveProject();
if( p && p->IsSticky() && GetNode() )
return HandleGroupPaste(t0, src, tracks, relativeLabels);
else
return HandlePaste(t0, src);
}
bool WaveTrack::Clear(double t0, double t1)
{
return Clear(t0, t1, NULL);
}
bool WaveTrack::Clear(double t0, double t1, TrackList* tracks)
{
bool addCutLines = false;
bool split = false;
AudacityProject *p = GetActiveProject();
if( p && p->IsSticky() && GetNode() )
return HandleGroupClear(t0, t1, addCutLines, split, tracks);
else
return HandleClear(t0, t1, addCutLines, split);
return HandleClear(t0, t1, false, false);
}
bool WaveTrack::ClearAndAddCutLine(double t0, double t1)
{
bool addCutLines = true;
bool split = false;
AudacityProject *p = GetActiveProject();
if( p && p->IsSticky() )
return HandleGroupClear(t0, t1, addCutLines, split);
else
return HandleClear(t0, t1, addCutLines, split);
return HandleClear(t0, t1, true, false);
}
//
@ -522,9 +480,6 @@ bool WaveTrack::ClearAndPaste(double t0, // Start of time to clear
Track *src, // What to paste
bool preserve, // Whether to reinsert splits/cuts
bool merge, // Whether to remove 'extra' splits
TrackList* tracks, // Used in Paste
bool relativeLabels, // Whether to handle labels
bool useHandlePaste, // Which pasting method
TimeWarper *effectWarper // How does time change
)
{
@ -537,10 +492,7 @@ bool WaveTrack::ClearAndPaste(double t0, // Start of time to clear
// If duration is 0, then it's just a plain paste
if (dur == 0.0) {
if (useHandlePaste)
return HandlePaste(t0, src);
else
return Paste(t0, src, tracks, relativeLabels);
return Paste(t0, src);
}
// If provided time warper was NULL, use a default one that does nothing
@ -601,15 +553,8 @@ bool WaveTrack::ClearAndPaste(double t0, // Start of time to clear
// Now, clear the selection
if (HandleClear(t0, t1, false, false)) {
// The pasting method depends on how this method was called
bool pasteResult;
if (useHandlePaste)
pasteResult = HandlePaste(t0, src);
else
pasteResult = Paste(t0, src, tracks, relativeLabels);
// And paste in the new data
if (pasteResult) {
if (Paste(t0, src)) {
unsigned int i;
// First, merge the new clip(s) in with the existing clips
@ -722,36 +667,6 @@ void WaveTrack::AddClip(WaveClip* clip)
mClips.Append(clip);
}
bool WaveTrack::HandleGroupClear(double t0, double t1, bool addCutLines, bool split, TrackList* tracks)
{
// get tracks
AudacityProject *p = GetActiveProject();
if (p) {
if (!tracks) tracks = p->GetTracks();
}
else return false;
TrackGroupIterator it(tracks);
Track *t = it.First(this);
if (t == NULL)
// the present track is in a project with groups but doesn't belong to any of them
return HandleClear(t0, t1, addCutLines, split);
for( ; t; t = it.Next() ) {
if (t->GetKind() == Track::Wave) {
if ( !( ( (WaveTrack *) t)->HandleClear(t0, t1, addCutLines, split) ) )
return false;
}
else if (t->GetKind() == Track::Label) {
if (!split)
( (LabelTrack *)t )->ShiftLabelsOnClear(t0, t1);
}
}
return true;
}
bool WaveTrack::HandleClear(double t0, double t1,
bool addCutLines, bool split)
{
@ -878,102 +793,57 @@ bool WaveTrack::HandleClear(double t0, double t1,
return true;
}
bool WaveTrack::HandleGroupPaste(double t0, Track *src, TrackList* tracks, bool relativeLabels)
bool WaveTrack::SyncAdjust(double oldT1, double newT1)
{
// get tracks
AudacityProject *p = GetActiveProject();
if (newT1 > oldT1) {
// Insert space within the track
if (p) {
if (!tracks) tracks = p->GetTracks();
}
else return false;
double length = src->GetEndTime();
ViewInfo *info = &p->mViewInfo;
double sel_len = max(info->sel1 - max(info->sel0, t0), 0.0);
TrackGroupIterator it(tracks);
Track *t = it.First(this);
if (t == NULL)
// the present track is in a project with groups but doesn't belong to any of them
return HandlePaste(t0, src);
if (oldT1 > GetEndTime())
return true;
// False return from this function causes its changes to not be pushed to
// the undo stack. So we paste into this track first, so any failure
// (usually from "clips can't move" mode) comes before other changes.
// Failures to paste to the group tracks should not cause this function to
// return false; the result might be OK with the user, and if not he can
// easily undo it
if (!HandlePaste(t0, src))
{
return false;
}
// If track is empty at oldT1 insert whitespace; otherwise, silence
if (IsEmpty(oldT1, oldT1))
{
bool ret = false;
for( ; t; t = it.Next() ) {
if (t->GetKind() == Track::Wave) {
WaveTrack *wt = (WaveTrack *)t;
if (t==this) {
// This track has already been pasted; if it's a stereo track skip
// over the other channel as well.
if (t->GetLinked()) t=it.Next();
}
else {
if (! (t->GetSelected()) ) {
if ( sel_len > length )
// if selection is bigger than the content to add then we
// need to clear the extra length in the group tracks
wt->HandleClear(t0+length, t0+sel_len, false, false);
else if (sel_len < length) {
// if selection is smaller than the content to add then we
// need to add extra space in the group tracks. If the track
// is empty at this point insert whitespace; otherwise,
// silence
if (wt->IsEmpty(t0+sel_len, t0+sel_len))
{
// Have to check if clips can move in this case
bool clipsCanMove = true;
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &clipsCanMove);
if (clipsCanMove)
{
Track *tmp = NULL;
wt->Cut(t0 + sel_len,
wt->GetEndTime()+1.0/wt->GetRate(), &tmp, false);
wt->HandlePaste(t0 + length, tmp);
delete tmp;
}
}
else
{
TrackFactory *factory = p->GetTrackFactory();
WaveTrack *tmp = factory->NewWaveTrack( wt->GetSampleFormat(), wt->GetRate());
tmp->InsertSilence(0.0, length-sel_len);
tmp->Flush();
wt->HandlePaste(t0+sel_len, tmp);
}
}
}
// Check if clips can move
bool clipsCanMove = true;
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &clipsCanMove);
if (clipsCanMove) {
Track *tmp = NULL;
ret = Cut (oldT1, GetEndTime() + 1.0/GetRate(), &tmp);
if (!ret) return false;
ret = Paste(newT1, tmp);
delete tmp;
}
return ret;
}
else if (t->GetKind() == Track::Label) {
LabelTrack *lt = (LabelTrack *)t;
if (!t->GetSelected())
{
if (relativeLabels && (sel_len != 0.0))
lt->ScaleLabels(info->sel0, info->sel1, length/sel_len);
else {
if ((length - sel_len) > 0.0)
lt->ShiftLabelsOnInsert(length-sel_len, t0);
else if ((length - sel_len) < 0.0)
lt->ShiftLabelsOnClear(info->sel0+length, info->sel1);
}
}
else {
// AWD: Could just use InsertSilence() on its own here, but it doesn't
// follow EditClipCanMove rules (Paste() does it right)
AudacityProject *p = GetActiveProject();
if (!p) return false;
TrackFactory *f = p->GetTrackFactory();
if (!f) return false;
WaveTrack *tmp = f->NewWaveTrack(GetSampleFormat(), GetRate());
tmp->InsertSilence(0.0, newT1 - oldT1);
tmp->Flush();
Paste(oldT1, tmp);
delete tmp;
}
}
else if (newT1 < oldT1) {
return Clear(newT1, oldT1);
}
// fall-through: no change
return true;
}
bool WaveTrack::HandlePaste(double t0, Track *src)
bool WaveTrack::Paste(double t0, Track *src)
{
bool editClipCanMove = true;
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove);
@ -1032,8 +902,8 @@ bool WaveTrack::HandlePaste(double t0, Track *src)
// move everything to the right, then try to paste again
if (!IsEmpty(t0, GetEndTime())) {
Track *tmp = NULL;
Cut(t0, GetEndTime()+1.0/mRate, &tmp, false);
HandlePaste(t0 + insertDuration, tmp);
Cut(t0, GetEndTime()+1.0/mRate, &tmp);
Paste(t0 + insertDuration, tmp);
delete tmp;
}
} else
@ -1197,11 +1067,13 @@ bool WaveTrack::InsertSilence(double t, double len)
for (WaveClipList::compatibility_iterator it=GetClipIterator(); it; it=it->GetNext())
{
WaveClip *clip = it->GetData();
if (clip->GetStartTime() > t)
if (clip->BeforeClip(t))
clip->Offset(len);
else if (clip->GetEndTime() > t)
else if (clip->WithinClip(t))
{
return clip->InsertSilence(t, len);
if (!clip->InsertSilence(t, len)) {
return false;
}
}
}

View File

@ -133,9 +133,6 @@ class AUDACITY_DLL_API WaveTrack: public Track {
Track *src,
bool preserve = true,
bool merge = true,
TrackList* tracks = NULL,
bool relativeLabels = false,
bool useHandlePaste = false,
TimeWarper *effectWarper = NULL);
virtual bool Silence(double t0, double t1);
@ -156,15 +153,9 @@ class AUDACITY_DLL_API WaveTrack: public Track {
virtual bool Trim (double t0, double t1);
bool Clear(double t0, double t1, TrackList* tracks);
bool HandleGroupClear(double t0, double t1, bool addCutLines, bool split, TrackList* tracks = NULL);
bool HandleClear(double t0, double t1, bool addCutLines, bool split);
bool Paste(double t0, Track *src, TrackList* tracks, bool relativeLabels = false);
bool HandleGroupPaste(double t0, Track *src, TrackList* tracks, bool relativeLabels);
bool HandlePaste(double t0, Track *src);
bool Cut(double t0, double t1, Track **dest, bool groupCut);
virtual bool SyncAdjust(double oldT1, double newT1);
// Returns true if there are no WaveClips in that region
bool IsEmpty(double t0, double t1);

View File

@ -89,9 +89,9 @@ bool EffectChangeSpeed::TransferParameters( Shuttle & shuttle )
// the region are shifted along according to how the region size changed.
bool EffectChangeSpeed::ProcessLabelTrack(Track *t)
{
SetTimeWarper(new RegionTimeWarper(mCurT0, mCurT1,
new LinearTimeWarper(mCurT0, mCurT0,
mCurT1, mCurT0 + (mCurT1-mCurT0)*mFactor)));
SetTimeWarper(new RegionTimeWarper(mT0, mT1,
new LinearTimeWarper(mT0, mT0,
mT1, mT0 + (mT1-mT0)*mFactor)));
LabelTrack *lt = (LabelTrack*)t;
if (lt == NULL) return false;
lt->WarpLabels(*GetTimeWarper());
@ -108,42 +108,28 @@ bool EffectChangeSpeed::Process()
bool bGoodResult = true;
TrackListIterator iter(mOutputTracks);
// go to first wavetrack
Track* t;
for (t = iter.First(); t->GetKind() != Track::Wave; t = iter.Next());
if (!t)
return false;
WaveTrack* pOutWaveTrack = (WaveTrack*)t;
mCurTrackNum = 0;
m_maxNewLength = 0.0;
mFactor = 100.0 / (100.0 + m_PercentChange);
//Get start and end times from track
mCurT0 = pOutWaveTrack->GetStartTime();
mCurT1 = pOutWaveTrack->GetEndTime();
//Set the current bounds to whichever left marker is
//greater and whichever right marker is less:
mCurT0 = wxMax(mT0, mCurT0);
mCurT1 = wxMin(mT1, mCurT1);
// we only do a "group change" in the first selected track of the group.
// ClearAndPaste has a call to Paste that does changes to the group tracks
bool first = true;
t = iter.First();
while (t != NULL)
{
if (t->GetKind() == Track::Label) {
first = true;
if (t->GetSelected() && !ProcessLabelTrack(t))
if (t->GetSelected() || t->IsSynchroSelected())
{
bGoodResult = false;
break;
if (!ProcessLabelTrack(t)) {
bGoodResult = false;
break;
}
}
}
else if (t->GetKind() == Track::Wave && t->GetSelected()) {
pOutWaveTrack = (WaveTrack*)t;
else if (t->GetKind() == Track::Wave &&
(t->GetSelected() || t->IsSynchroSelected()))
{
WaveTrack *pOutWaveTrack = (WaveTrack*)t;
//Get start and end times from track
mCurT0 = pOutWaveTrack->GetStartTime();
mCurT1 = pOutWaveTrack->GetEndTime();
@ -160,15 +146,18 @@ bool EffectChangeSpeed::Process()
sampleCount end = pOutWaveTrack->TimeToLongSamples(mCurT1);
//ProcessOne() (implemented below) processes a single track
if (!ProcessOne(pOutWaveTrack, start, end, first))
if (!ProcessOne(pOutWaveTrack, start, end))
{
bGoodResult = false;
break;
}
first = false;
}
mCurTrackNum++;
}
else if (t->IsSynchroSelected() && !t->GetSelected())
{
t->SyncAdjust(mT1, mT0 + (mT1 - mT0) * mFactor);
}
//Iterate to the next track
t=iter.Next();
@ -185,7 +174,7 @@ bool EffectChangeSpeed::Process()
// ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
// and calls libsamplerate code on these blocks.
bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
sampleCount start, sampleCount end, bool first)
sampleCount start, sampleCount end)
{
if (track == NULL)
return false;
@ -268,8 +257,10 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track,
// sample data
double newLength = outputTrack->GetEndTime();
if (bLoopSuccess) {
SetTimeWarper(new LinearTimeWarper(mCurT0, mCurT0, mCurT1, mCurT0 + newLength ));
track->ClearAndPaste(mCurT0, mCurT1, outputTrack, true, false, mOutputTracks, true, first, GetTimeWarper());
SetTimeWarper(new LinearTimeWarper(
mCurT0, mCurT0, mCurT1, mCurT0 + newLength ));
track->ClearAndPaste(mCurT0, mCurT1, outputTrack, true, false,
GetTimeWarper());
}
if (newLength > m_maxNewLength)

View File

@ -57,13 +57,13 @@ class EffectChangeSpeed : public Effect {
virtual bool Process();
private:
bool ProcessOne(WaveTrack * t, sampleCount start, sampleCount end, bool first);
bool ProcessOne(WaveTrack * t, sampleCount start, sampleCount end);
bool ProcessLabelTrack(Track *t);
private:
// track related
int mCurTrackNum;
double m_maxNewLength;
double m_maxNewLength;
double mCurT0;
double mCurT1;

View File

@ -247,31 +247,12 @@ void Effect::CopyInputTracks(int trackType)
TrackListOfKindIterator aIt(trackType, mTracks);
t2bHash added;
//for each track that is selected
for (Track *aTrack = aIt.First(); aTrack; aTrack = aIt.Next()) {
if (!aTrack->GetSelected()) {
continue;
}
TrackGroupIterator gIt(mTracks);
Track *gTrack = gIt.First(aTrack);
//if the track is part of a group
if (trackType == Track::All && gTrack != NULL) {
//go to the project tracks and add all the tracks in the same group
for( ; gTrack; gTrack = gIt.Next() ) {
// only add if the track was not added before
if (added.find(gTrack) == added.end()) {
added[gTrack]=true;
Track *o = gTrack->Duplicate();
mOutputTracks->Add(o);
mIMap.Add(gTrack);
mOMap.Add(o);
}
}
}
//otherwise just add the track
else {
// Include selected tracks, plus sync-selected tracks for Track::All)
if (aTrack->GetSelected() ||
(trackType == Track::All && aTrack->IsSynchroSelected()))
{
Track *o = aTrack->Duplicate();
mOutputTracks->Add(o);
mIMap.Add(aTrack);

View File

@ -26,8 +26,7 @@ bool Generator::Process()
BeforeGenerate();
// Set up mOutputTracks. This effect needs Track::All because it uses ClearAndPaste
// that need to have label tracks.
// Set up mOutputTracks. This effect needs Track::All for grouping
this->CopyInputTracks(Track::All);
// Iterate over the tracks
@ -36,15 +35,9 @@ bool Generator::Process()
TrackListIterator iter(mOutputTracks);
Track* t = iter.First();
// we only do a "group change" in the first selected track of the group.
// ClearAndPaste has a call to Paste that does changes to the group tracks
bool first = true;
while (t != NULL)
{
if (t->GetKind() == Track::Label)
first = true;
else if (t->GetKind() == Track::Wave && t->GetSelected()) {
if (t->GetKind() == Track::Wave && t->GetSelected()) {
WaveTrack* track = (WaveTrack*)t;
bool editClipCanMove;
@ -76,11 +69,7 @@ bool Generator::Process()
tmp->Flush();
SetTimeWarper(new StepTimeWarper(mT1, mDuration-mT1));
bGoodResult = track->ClearAndPaste(mT0, mT1, tmp, true,
false, mOutputTracks,
false, !first, GetTimeWarper());
if (first) {
first = false;
}
false, GetTimeWarper());
delete tmp;
}
@ -98,6 +87,9 @@ bool Generator::Process()
ntrack++;
}
else if (t->IsSynchroSelected()) {
t->SyncAdjust(mT1, mT0 + mDuration);
}
// Move on to the next track
t = iter.Next();
}

View File

@ -110,44 +110,28 @@ bool EffectRepeat::TransferParameters( Shuttle & shuttle )
bool EffectRepeat::Process()
{
// Set up mOutputTracks. This effect needs Track::All because it uses Paste that needs to have label tracks.
// Set up mOutputTracks. This effect needs Track::All for grouping
this->CopyInputTracks(Track::All);
int nTrack = 0;
bool bGoodResult = true;
double maxDestLen = 0.0; // used to change selection to generated bit
// Is linking enabled?
AudacityProject *p = GetActiveProject();
bool isSticky = ( p && p->IsSticky());
TrackListIterator iter(mOutputTracks);
// we only do a "group change" in the first selected track of the group.
// Paste call does changes to the group tracks
bool first = true;
for (Track *t = iter.First(); t && bGoodResult; t = iter.Next()) {
if (t->GetKind() == Track::Label)
{
// We repeat labels if linking is enabled and a WaveTrack before this
// has been repeated, or if the label track is selected
if (t->GetSelected() || (isSticky && !first))
if (t->GetSelected() || t->IsSynchroSelected())
{
LabelTrack* track = (LabelTrack*)t;
// If this track isn't selected, ShiftLabelsOnInsert() has
// already been called
if (t->GetSelected())
track->ShiftLabelsOnInsert((mT1 - mT0) * repeatCount, mT1);
if (!track->Repeat(mT0, mT1, repeatCount))
{
bGoodResult = false;
break;
}
}
first = true;
}
else if (t->GetKind() == Track::Wave && t->GetSelected())
{
@ -166,30 +150,23 @@ bool EffectRepeat::Process()
track->Copy(mT0, mT1, &dest);
for(int j=0; j<repeatCount; j++)
{
if (first) {
if (!track->Paste(tc, dest, mOutputTracks) ||
TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
{
bGoodResult = false;
break;
}
}
else {
if (!track->HandlePaste(tc, dest) ||
TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
{
bGoodResult = false;
break;
}
if (!track->Paste(tc, dest) ||
TrackProgress(nTrack, j / repeatCount)) // TrackProgress returns true on Cancel.
{
bGoodResult = false;
break;
}
tc += tLen;
}
first = false;
if (tc > maxDestLen)
maxDestLen = tc;
delete dest;
nTrack++;
}
else if (t->IsSynchroSelected())
{
t->SyncAdjust(mT1, mT1 + (mT1 - mT0) * repeatCount);
}
}
if (bGoodResult)

View File

@ -36,41 +36,33 @@ bool EffectReverse::Process()
//Track::All is needed because Reverse should move the labels too
this->CopyInputTracks(Track::All); // Set up mOutputTracks.
bool bGoodResult = true;
Track *lastGroup = NULL; // First track of group of last acted-on WaveTrack
TrackGroupIterator gIt(mOutputTracks);
TrackListIterator iter(mOutputTracks);
Track *t = iter.First();
int count = 0;
while (t) {
if (t->GetKind() == Track::Wave) {
if (t->GetKind() == Track::Wave &&
(t->GetSelected() || t->IsSynchroSelected()))
{
WaveTrack *track = (WaveTrack*)t;
if (track->GetSelected()) {
if (mT1 > mT0) {
sampleCount start = track->TimeToLongSamples(mT0);
sampleCount end = track->TimeToLongSamples(mT1);
sampleCount len = (sampleCount)(end - start);
if (!ProcessOneWave(count, track, start, len))
{
bGoodResult = false;
break;
}
if (mT1 > mT0) {
sampleCount start = track->TimeToLongSamples(mT0);
sampleCount end = track->TimeToLongSamples(mT1);
sampleCount len = (sampleCount)(end - start);
if (!ProcessOneWave(count, track, start, len))
{
bGoodResult = false;
break;
}
// Update grouping variables
lastGroup = gIt.First(t);
}
}
else if (t->GetKind() == Track::Label) {
AudacityProject *p = GetActiveProject();
if ((p && p->IsSticky() && gIt.First(t) == lastGroup) ||
t->GetSelected())
{
LabelTrack *track = (LabelTrack*)t;
track->ChangeLabelsOnReverse(mT0, mT1);
}
else if (t->GetKind() == Track::Label &&
(t->GetSelected() || t->IsSynchroSelected()))
{
LabelTrack *track = (LabelTrack*)t;
track->ChangeLabelsOnReverse(mT0, mT1);
}
t = iter.Next();
count++;

View File

@ -156,14 +156,14 @@ bool EffectSBSMS::ProcessLabelTrack(Track *t)
TimeWarper *warper = NULL;
if (rateStart == rateEnd)
{
warper = new LinearTimeWarper(mCurT0, mCurT0,
mCurT1, mCurT0+(mCurT1-mCurT0)*mTotalStretch);
warper = new LinearTimeWarper(mT0, mT0,
mT1, mT0+(mT1-mT0)*mTotalStretch);
} else
{
warper = new LogarithmicTimeWarper(mCurT0, mCurT1,
warper = new LogarithmicTimeWarper(mT0, mT1,
rateStart, rateEnd);
}
SetTimeWarper(new RegionTimeWarper(mCurT0, mCurT1, warper));
SetTimeWarper(new RegionTimeWarper(mT0, mT1, warper));
LabelTrack *lt = (LabelTrack*)t;
if (lt == NULL) return false;
lt->WarpLabels(*GetTimeWarper());
@ -183,11 +183,7 @@ bool EffectSBSMS::Process()
//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);
// go to first wavetrack
Track* t;
for (t = iter.First(); t->GetKind() != Track::Wave; t = iter.Next());
if (!t)
return false;
mCurTrackNum = 0;
double maxDuration = 0.0;
@ -197,21 +193,25 @@ bool EffectSBSMS::Process()
else
mTotalStretch = 1.0/(rateEnd-rateStart)*log(rateEnd/rateStart);
// Must sync if selection length will change
bool mustSync = (mTotalStretch != 1.0);
// we only do a "group change" in the first selected track of the group.
// ClearAndPaste has a call to Paste that does changes to the group tracks
bool first = true;
t = iter.First();
while (t != NULL) {
if (t->GetKind() == Track::Label) {
first = true;
if (t->GetSelected() && !ProcessLabelTrack(t))
if (t->GetKind() == Track::Label &&
(t->GetSelected() || (mustSync && t->IsSynchroSelected())) )
{
if (t->GetSelected() || t->IsSynchroSelected())
{
bGoodResult = false;
break;
if (!ProcessLabelTrack(t)) {
bGoodResult = false;
break;
}
}
}
else if (t->GetKind() == Track::Wave && t->GetSelected()) {
else if (t->GetKind() == Track::Wave &&
(t->GetSelected() || (mustSync && t->IsSynchroSelected())) )
{
WaveTrack* leftTrack = (WaveTrack*)t;
//Get start and end times from track
@ -396,16 +396,20 @@ bool EffectSBSMS::Process()
if(rightTrack)
rb.outputRightTrack->Flush();
leftTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputLeftTrack, true, false, NULL, true, first, GetTimeWarper());
leftTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputLeftTrack,
true, false, GetTimeWarper());
if(rightTrack) {
rightTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputRightTrack, true, false, NULL, true, false, GetTimeWarper());
rightTrack->ClearAndPaste(mCurT0, mCurT1, rb.outputRightTrack,
true, false, GetTimeWarper());
}
first = false;
}
mCurTrackNum++;
}
else if (mustSync && t->IsSynchroSelected())
{
t->SyncAdjust(mCurT1, mCurT0 + (mCurT1 - mCurT0) * mTotalStretch);
}
//Iterate to the next track
t = iter.Next();
}

View File

@ -18,9 +18,9 @@ effect that uses SoundTouch to do its processing (ChangeTempo
#include <math.h>
#include "SoundTouchEffect.h"
#include "../WaveTrack.h"
#include "../Project.h"
#include "SoundTouchEffect.h"
#include "TimeWarper.h"
bool EffectSoundTouch::ProcessLabelTrack(Track *track)
@ -37,37 +37,40 @@ bool EffectSoundTouch::ProcessLabelTrack(Track *track)
bool EffectSoundTouch::Process()
{
// Assumes that mSoundTouch has already been initialized
// by the subclass for subclass-specific parameters.
// by the subclass for subclass-specific parameters. The
// time warper should also be set.
// Check if this effect will alter the selection length; if so, we need
// to operate on sync-selected tracks
bool mustSync = true;
if (mT1 == GetTimeWarper()->Warp(mT1)) {
mustSync = false;
}
//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.
//Track::All is needed for group behavior
this->CopyInputTracks(Track::All);
bool bGoodResult = true;
TrackListIterator iter(mOutputTracks);
// go to first wavetrack
Track* t;
for (t = iter.First(); t->GetKind() != Track::Wave; t = iter.Next());
if (!t)
return false;
WaveTrack* leftTrack = (WaveTrack*)t;
mCurTrackNum = 0;
m_maxNewLength = 0.0;
// we only do a "group change" in the first selected track of the group.
// ClearAndPaste has a call to Paste that does changes to the group tracks
bool first = true;
m_maxNewLength = 0.0;
t = iter.First();
while (t != NULL) {
if (t->GetKind() == Track::Label) {
first = true;
if (t->GetSelected() && !ProcessLabelTrack(t))
if (t->GetKind() == Track::Label &&
(t->GetSelected() || (mustSync && t->IsSynchroSelected())) )
{
if (!ProcessLabelTrack(t))
{
bGoodResult = false;
break;
}
}
else if (t->GetKind() == Track::Wave && t->GetSelected()) {
else if (t->GetKind() == Track::Wave &&
(t->GetSelected() || (mustSync && t->IsSynchroSelected())) )
{
WaveTrack* leftTrack = (WaveTrack*)t;
//Get start and end times from track
mCurT0 = leftTrack->GetStartTime();
@ -102,7 +105,7 @@ bool EffectSoundTouch::Process()
mSoundTouch->setChannels(2);
//ProcessStereo() (implemented below) processes a stereo track
if (!ProcessStereo(leftTrack, rightTrack, start, end, first))
if (!ProcessStereo(leftTrack, rightTrack, start, end))
{
bGoodResult = false;
break;
@ -117,16 +120,19 @@ bool EffectSoundTouch::Process()
mSoundTouch->setChannels(1);
//ProcessOne() (implemented below) processes a single track
if (!ProcessOne(leftTrack, start, end, first))
if (!ProcessOne(leftTrack, start, end))
{
bGoodResult = false;
break;
}
}
first = false;
}
mCurTrackNum++;
}
else if (mustSync && t->IsSynchroSelected()) {
t->SyncAdjust(mT1, GetTimeWarper()->Warp(mT1));
}
//Iterate to the next track
t = iter.Next();
}
@ -146,7 +152,7 @@ bool EffectSoundTouch::Process()
//ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
//and executes ProcessSoundTouch on these blocks
bool EffectSoundTouch::ProcessOne(WaveTrack *track,
sampleCount start, sampleCount end, bool first)
sampleCount start, sampleCount end)
{
WaveTrack *outputTrack;
sampleCount s;
@ -217,7 +223,7 @@ bool EffectSoundTouch::ProcessOne(WaveTrack *track,
// Take the output track and insert it in place of the original
// sample data
track->ClearAndPaste(mCurT0, mCurT1, outputTrack, true, false, NULL, true, first, GetTimeWarper());
track->ClearAndPaste(mCurT0, mCurT1, outputTrack, true, false, GetTimeWarper());
double newLength = outputTrack->GetEndTime();
m_maxNewLength = wxMax(m_maxNewLength, newLength);
@ -230,7 +236,7 @@ bool EffectSoundTouch::ProcessOne(WaveTrack *track,
}
bool EffectSoundTouch::ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack,
sampleCount start, sampleCount end, bool first)
sampleCount start, sampleCount end)
{
mSoundTouch->setSampleRate((unsigned int)(leftTrack->GetRate()+0.5));
@ -321,8 +327,8 @@ bool EffectSoundTouch::ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack
// Take the output tracks and insert in place of the original
// sample data.
leftTrack->ClearAndPaste(mCurT0, mCurT1, outputLeftTrack, true, false, NULL, true, first, GetTimeWarper());
rightTrack->ClearAndPaste(mCurT0, mCurT1, outputRightTrack, true, false, NULL, true, false, GetTimeWarper());
leftTrack->ClearAndPaste(mCurT0, mCurT1, outputLeftTrack, true, false, GetTimeWarper());
rightTrack->ClearAndPaste(mCurT0, mCurT1, outputRightTrack, true, false, GetTimeWarper());
// Track the longest result length
double newLength = outputLeftTrack->GetEndTime();

View File

@ -44,17 +44,16 @@ class EffectSoundTouch:public Effect {
private:
bool ProcessLabelTrack(Track *track);
bool ProcessOne(WaveTrack * t,
sampleCount start, sampleCount end, bool first);
bool ProcessOne(WaveTrack * t, sampleCount start, sampleCount end);
bool ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack,
sampleCount start, sampleCount end, bool first);
sampleCount start, sampleCount end);
bool ProcessStereoResults(const unsigned int outputCount,
WaveTrack* outputLeftTrack,
WaveTrack* outputRightTrack);
int mCurTrackNum;
double m_maxNewLength;
double m_maxNewLength;
};
#endif

View File

@ -96,7 +96,7 @@ bool EffectStereoToMono::ProcessOne(int count)
double minStart = wxMin(mLeftTrack->GetStartTime(), mRightTrack->GetStartTime());
mLeftTrack->Clear(mLeftTrack->GetStartTime(), mLeftTrack->GetEndTime());
mOutTrack->Flush();
mLeftTrack->HandlePaste(minStart, mOutTrack);
mLeftTrack->Paste(minStart, mOutTrack);
mLeftTrack->SetLinked(false);
mRightTrack->SetLinked(false);
mLeftTrack->SetChannel(Track::MonoChannel);

View File

@ -421,13 +421,10 @@ bool EffectTruncSilence::Process()
// Remove stale data at end of output tracks.
if (!cancelled && (outTrackOffset < end)) {
t = (WaveTrack *) iterOut.First();
if( p->IsSticky() )
t->Clear(outTrackOffset / rate, t1, mOutputTracks);
else
while(t) {
t->Clear(outTrackOffset / rate, t1, mOutputTracks);
t = (WaveTrack *) iterOut.Next();
}
while(t) {
t->Clear(outTrackOffset / rate, t1);
t = (WaveTrack *) iterOut.Next();
}
t1 = outTrackOffset / rate;
}

View File

@ -508,6 +508,8 @@ bool EffectNyquist::Process()
mDebugOutput = "";
// Keep track of whether the current track is first selected in its group
// (we have no idea what the length of the returned audio will be, so we have
// to handle group behavior the "old" way).
mFirstInGroup = true;
Track *gtLast = NULL;
@ -775,9 +777,19 @@ bool EffectNyquist::ProcessOne()
out = mOutputTrack[0];
}
// If this track is not first in its group we set useHandlePaste
mCurTrack[i]->ClearAndPaste(mT0, mT1, out, false, false,
NULL, false, !mFirstInGroup);
mCurTrack[i]->ClearAndPaste(mT0, mT1, out, false, false);
// If we were first in the group adjust non-selected group tracks
if (mFirstInGroup) {
TrackGroupIterator git(mOutputTracks);
Track *t;
for (t = git.First(mCurTrack[i]); t; t = git.Next())
{
if (!t->GetSelected() && t->IsSynchroSelected()) {
t->SyncAdjust(mT1, mT0 + out->GetEndTime());
}
}
}
// Only the first channel can be first in its group
mFirstInGroup = false;
}

View File

@ -1000,10 +1000,6 @@ void ControlToolBar::SetupCutPreviewTracks(double playStart, double cutStart,
if (track1)
{
// Temporarily disable sticky track handling
bool sticky = p->GetStickyFlag();
p->SetStickyFlag(false);
// Duplicate and change tracks
track1 = track1->Duplicate();
track1->Clear(cutStart, cutEnd);
@ -1017,9 +1013,6 @@ void ControlToolBar::SetupCutPreviewTracks(double playStart, double cutStart,
mCutPreviewTracks->Add(track1);
if (track2)
mCutPreviewTracks->Add(track2);
// Reinstate sticky track handling
p->SetStickyFlag(sticky);
}
}
}