1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-22 07:28:03 +02:00

Rewrite many iterations over tracks and channels in src/commands

This commit is contained in:
Paul Licameli 2018-09-18 11:58:44 -04:00
parent 23a85893a1
commit c7ab9f2338
6 changed files with 77 additions and 112 deletions

@ -76,20 +76,20 @@ bool CompareAudioCommand::GetSelection(const CommandContext &context, AudacityPr
// Get the selected tracks and check that there are at least two to // Get the selected tracks and check that there are at least two to
// compare // compare
SelectedTrackListOfKindIterator iter(Track::Wave, proj.GetTracks()); auto trackRange = proj.GetTracks()->Selected< const WaveTrack >();
mTrack0 = (WaveTrack*)(iter.First()); mTrack0 = *trackRange.first;
if (mTrack0 == NULL) if (mTrack0 == NULL)
{ {
context.Error(wxT("No tracks selected! Select two tracks to compare.")); context.Error(wxT("No tracks selected! Select two tracks to compare."));
return false; return false;
} }
mTrack1 = (WaveTrack*)(iter.Next()); mTrack1 = * ++ trackRange.first;
if (mTrack1 == NULL) if (mTrack1 == NULL)
{ {
context.Error(wxT("Only one track selected! Select two tracks to compare.")); context.Error(wxT("Only one track selected! Select two tracks to compare."));
return false; return false;
} }
if (iter.Next() != NULL) if ( * ++ trackRange.first )
{ {
context.Status(wxT("More than two tracks selected - only the first two will be compared.")); context.Status(wxT("More than two tracks selected - only the first two will be compared."));
} }

@ -267,7 +267,7 @@ bool GetInfoCommand::SendTracks(const CommandContext & context)
context.AddItem( t->GetEndTime(), "end" ); context.AddItem( t->GetEndTime(), "end" );
context.AddItem( t->GetPan() , "pan"); context.AddItem( t->GetPan() , "pan");
context.AddItem( t->GetGain() , "gain"); context.AddItem( t->GetGain() , "gain");
context.AddItem( t->GetLinked() ? 2:1, "channels"); context.AddItem( TrackList::Channels(t).size(), "channels");
context.AddBool( t->GetSolo(), "solo" ); context.AddBool( t->GetSolo(), "solo" );
context.AddBool( t->GetMute(), "mute"); context.AddBool( t->GetMute(), "mute");
} ); } );
@ -280,28 +280,18 @@ bool GetInfoCommand::SendTracks(const CommandContext & context)
bool GetInfoCommand::SendClips(const CommandContext &context) bool GetInfoCommand::SendClips(const CommandContext &context)
{ {
TrackList *tracks = context.GetProject()->GetTracks(); TrackList *tracks = context.GetProject()->GetTracks();
TrackListIterator iter(tracks);
Track *t = iter.First();
int i=0; int i=0;
context.StartArray(); context.StartArray();
while (t) { for (auto waveTrack : tracks->Leaders<WaveTrack>()) {
if (t->GetKind() == Track::Wave) { WaveClipPointers ptrs( waveTrack->SortedClipArray());
WaveTrack *waveTrack = static_cast<WaveTrack*>(t); for(WaveClip * pClip : ptrs ) {
WaveClipPointers ptrs( waveTrack->SortedClipArray()); context.StartStruct();
for(WaveClip * pClip : ptrs ) { context.AddItem( (double)i, "track" );
context.StartStruct(); context.AddItem( pClip->GetStartTime(), "start" );
context.AddItem( (double)i, "track" ); context.AddItem( pClip->GetEndTime(), "end" );
context.AddItem( pClip->GetStartTime(), "start" ); context.AddItem( pClip->GetColourIndex(), "color" );
context.AddItem( pClip->GetEndTime(), "end" ); context.EndStruct();
context.AddItem( pClip->GetColourIndex(), "color" );
context.EndStruct();
}
} }
// Skip second tracks of stereo...
if( t->GetLinked() )
t= iter.Next();
if( t )
t=iter.Next();
i++; i++;
} }
context.EndArray(); context.EndArray();
@ -312,43 +302,33 @@ bool GetInfoCommand::SendClips(const CommandContext &context)
bool GetInfoCommand::SendEnvelopes(const CommandContext &context) bool GetInfoCommand::SendEnvelopes(const CommandContext &context)
{ {
TrackList *tracks = context.GetProject()->GetTracks(); TrackList *tracks = context.GetProject()->GetTracks();
TrackListIterator iter(tracks);
Track *t = iter.First();
int i=0; int i=0;
int j=0; int j=0;
context.StartArray(); context.StartArray();
while (t) { for (auto waveTrack : tracks->Leaders<WaveTrack>()) {
if (t->GetKind() == Track::Wave) { WaveClipPointers ptrs( waveTrack->SortedClipArray());
WaveTrack *waveTrack = static_cast<WaveTrack*>(t); for(WaveClip * pClip : ptrs ) {
WaveClipPointers ptrs( waveTrack->SortedClipArray()); context.StartStruct();
for(WaveClip * pClip : ptrs ) { context.AddItem( (double)i, "track" );
context.StartStruct(); context.AddItem( (double)j, "clip" );
context.AddItem( (double)i, "track" ); context.AddItem( pClip->GetStartTime(), "start" );
context.AddItem( (double)j, "clip" ); Envelope * pEnv = pClip->GetEnvelope();
context.AddItem( pClip->GetStartTime(), "start" ); context.StartField( "points" );
Envelope * pEnv = pClip->GetEnvelope(); context.StartArray();
context.StartField( "points" ); double offset = pEnv->mOffset;
context.StartArray(); for( size_t k=0;k<pEnv->mEnv.size(); k++)
double offset = pEnv->mOffset; {
for( size_t k=0;k<pEnv->mEnv.size(); k++) context.StartStruct( );
{ context.AddItem( pEnv->mEnv[k].GetT()+offset, "t" );
context.StartStruct( ); context.AddItem( pEnv->mEnv[k].GetVal(), "y" );
context.AddItem( pEnv->mEnv[k].GetT()+offset, "t" );
context.AddItem( pEnv->mEnv[k].GetVal(), "y" );
context.EndStruct();
}
context.EndArray();
context.EndField();
context.AddItem( pClip->GetEndTime(), "end" );
context.EndStruct(); context.EndStruct();
j++;
} }
context.EndArray();
context.EndField();
context.AddItem( pClip->GetEndTime(), "end" );
context.EndStruct();
j++;
} }
// Skip second tracks of stereo...
if( t->GetLinked() )
t= iter.Next();
if( t )
t=iter.Next();
} }
context.EndArray(); context.EndArray();

@ -777,20 +777,14 @@ wxRect ScreenshotCommand::GetTrackRect( AudacityProject * pProj, TrackPanel * pa
return rect; return rect;
}; };
TrackListIterator iter(pProj->GetTracks());
int count = 0; int count = 0;
for (auto t = iter.First(); t; t = iter.Next()) { for (auto t : pProj->GetTracks()->Leaders()) {
count += 1; count += 1;
if( count > n ) if( count > n )
{ {
wxRect r = FindRectangle( *panel, *t ); wxRect r = FindRectangle( *panel, *t );
return r; return r;
} }
if( t->GetLinked() ){
t = iter.Next();
if( !t )
break;
}
} }
return wxRect( 0,0,0,0); return wxRect( 0,0,0,0);
} }

@ -220,31 +220,30 @@ bool SelectTracksCommand::Apply(const CommandContext &context)
if( !bHasFirstTrack ) if( !bHasFirstTrack )
mFirstTrack = 0.0; mFirstTrack = 0.0;
// Stereo second tracks count as 0.5 of a track. // Multiple channels count as fractions of a track.
double last = mFirstTrack+mNumTracks; double last = mFirstTrack+mNumTracks;
double first = mFirstTrack; double first = mFirstTrack;
bool bIsSecondChannel = false;
TrackListIterator iter(tracks); for (auto t : tracks->Leaders()) {
Track *t = iter.First(); auto channels = TrackList::Channels(t);
while (t) { double term = 0.0;
// Add 0.01 so we are free of rounding errors in comparisons. // Add 0.01 so we are free of rounding errors in comparisons.
// Optionally add 0.5 for second track which counts as is half a track constexpr double fudge = 0.01;
double track = index + 0.01 + (bIsSecondChannel ? 0.5 : 0.0); for (auto channel : channels) {
bool sel = first <= track && track <= last; double track = index + fudge + term;
if( mMode == 0 ){ // Set bool sel = first <= track && track <= last;
t->SetSelected(sel); if( mMode == 0 ){ // Set
t->SetSelected(sel);
}
else if( mMode == 1 && sel ){ // Add
t->SetSelected(sel);
}
else if( mMode == 2 && sel ){ // Remove
t->SetSelected(!sel);
}
term += (1.0 - fudge) / channels.size();
} }
else if( mMode == 1 && sel ){ // Add ++index;
t->SetSelected(sel);
}
else if( mMode == 2 && sel ){ // Remove
t->SetSelected(!sel);
}
// Do second channel in stereo track too.
bIsSecondChannel = t->GetLinked();
if( !bIsSecondChannel )
++index;
t = iter.Next();
} }
return true; return true;
} }

@ -67,27 +67,21 @@ bool SetLabelCommand::Apply(const CommandContext & context)
//wxString mode = GetString(wxT("Type")); //wxString mode = GetString(wxT("Type"));
AudacityProject * p = context.GetProject(); AudacityProject * p = context.GetProject();
TrackList *tracks = context.GetProject()->GetTracks(); TrackList *tracks = context.GetProject()->GetTracks();
TrackListIterator iter(tracks);
Track *t = iter.First();
LabelStruct * pLabel = NULL; LabelStruct * pLabel = NULL;
int i=0; int i=0;
int nn=0; int nn=0;
LabelTrack *labelTrack = nullptr; LabelTrack *labelTrack {};
while (t && i<=mLabelIndex) { for (auto lt : tracks->Any<LabelTrack>()) {
if (t->GetKind() == Track::Label) { if( i > mLabelIndex )
labelTrack = static_cast<LabelTrack*>(t); break;
if( labelTrack ) labelTrack = lt;
{ for (nn = 0;
for (nn = 0; (nn< (int)labelTrack->mLabels.size()) && i<=mLabelIndex;
(nn< (int)labelTrack->mLabels.size()) && i<=mLabelIndex; nn++) {
nn++) { i++;
i++; pLabel = &labelTrack->mLabels[nn];
pLabel = &labelTrack->mLabels[nn];
}
}
} }
t = iter.Next();
} }
if ( (i< mLabelIndex) || (pLabel == NULL)) if ( (i< mLabelIndex) || (pLabel == NULL))

@ -92,28 +92,26 @@ bool SetTrackBase::Apply(const CommandContext & context )
{ {
long i = 0;// track counter long i = 0;// track counter
long j = 0;// channel counter long j = 0;// channel counter
TrackListIterator iter(context.GetProject()->GetTracks()); auto tracks = context.GetProject()->GetTracks();
Track *t = iter.First(); for ( auto t : tracks->Leaders() )
bIsSecondChannel = false;
while (t )
{ {
bool bThisTrack = auto channels = TrackList::Channels(t);
for ( auto channel : channels ) {
bool bThisTrack =
#ifdef USE_OWN_TRACK_SELECTION #ifdef USE_OWN_TRACK_SELECTION
(bHasTrackIndex && (i==mTrackIndex)) || (bHasTrackIndex && (i==mTrackIndex)) ||
(bHasChannelIndex && (j==mChannelIndex ) ) || (bHasChannelIndex && (j==mChannelIndex ) ) ||
(!bHasTrackIndex && !bHasChannelIndex) ; (!bHasTrackIndex && !bHasChannelIndex) ;
#else #else
t->GetSelected(); channel->GetSelected();
#endif #endif
if( bThisTrack ){ if( bThisTrack ){
ApplyInner( context, t ); ApplyInner( context, t );
}
++j; // count all channels
} }
bIsSecondChannel = t->GetLinked(); ++i; // count groups of channels
if( !bIsSecondChannel )
++i;
j++;
t = iter.Next();
} }
return true; return true;
} }