void AudacityProject::OnSplitLabels(wxEvent & event) { TrackListIterator iter(mTracks); VTrack *n = iter.First(); VTrack *srcRight = 0; VTrack *srcLeft = 0; bool stereo = false; LabelTrack *label = 0; while(n) { if(n->GetSelected()) { if(n->GetKind() == VTrack::Wave) { if(n->GetLinked() == true) { stereo = true; srcLeft = n; srcRight = iter.Next(); } else { srcRight = n; stereo = false; } } else if(n->GetKind() == VTrack::Label) label = (LabelTrack*)n; // cast necessary to call LabelTrack specific methods } n = iter.Next(); } // one new track for every label, from that label to the next TrackList newTracks; for(int i = 0; i < label->GetNumLabels(); i++) { wxString name = label->GetLabel(i)->title; double begin = label->GetLabel(i)->t; double end; // if on the last label, extend to the end of the wavetrack if(i == label->GetNumLabels() - 1) { if(stereo) end = wxMax(srcLeft->GetMaxLen(), srcRight->GetMaxLen()); else end = srcLeft->GetMaxLen(); } else end = label->GetLabel(i+1)->t; VTrack *destLeft = 0; VTrack *destRight = 0; srcLeft->Copy(begin, end, &destLeft); if (destLeft) { destLeft->Init(*srcLeft); destLeft->SetOffset(wxMax(begin, srcLeft->GetOffset())); destLeft->SetName(name); mTracks->Add(destLeft); } if(stereo) { srcRight->Copy(begin, end, &destRight); if (destRight) { destRight->Init(*srcRight); destRight->SetOffset(wxMax(begin, srcRight->GetOffset())); destRight->SetName(name); mTracks->Add(destRight); } else if(destLeft) // account for possibility of a non-aligned linked track, which could // cause the left channel to be eligible for creating a new track, // but not the right. destLeft->SetLinked(false); } } PushState(_("Split at labels")); FixScrollbars(); mTrackPanel->Refresh(false); }
void SnapManager::Reinit() { int snapTo = mProject->GetSnapTo(); double rate = mProject->GetRate(); wxString format = mProject->GetSelectionFormat(); // No need to reinit if these are still the same if (snapTo == mSnapTo && rate == mRate && format == mFormat) { return; } // Save NEW settings mSnapTo = snapTo; mRate = rate; mFormat = format; mSnapPoints.clear(); // Grab time-snapping prefs (unless otherwise requested) mSnapToTime = false; // Look up the format string if (mSnapTo != SNAP_OFF && !mNoTimeSnap) { mSnapToTime = true; mConverter.SetSampleRate(mRate); mConverter.SetFormatName(mFormat); } // 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; for (int i = 0, cnt = labelTrack->GetNumLabels(); i < cnt; ++i) { const LabelStruct *label = labelTrack->GetLabel(i); const double t0 = label->getT0(); const double t1 = label->getT1(); CondListAdd(t0, labelTrack); if (t1 != t0) { CondListAdd(t1, labelTrack); } } } else if (track->GetKind() == Track::Wave) { auto waveTrack = static_cast<const WaveTrack *>(track); for (const auto &clip: waveTrack->GetClips()) { if (mClipExclusions) { bool skip = false; for (size_t j = 0, cnt = mClipExclusions->size(); j < cnt; ++j) { if ((*mClipExclusions)[j].track == waveTrack && (*mClipExclusions)[j].clip == clip.get()) { skip = true; break; } } if (skip) { continue; } } CondListAdd(clip->GetStartTime(), waveTrack); CondListAdd(clip->GetEndTime(), waveTrack); } } #ifdef USE_MIDI else if (track->GetKind() == Track::Note) { CondListAdd(track->GetStartTime(), track); CondListAdd(track->GetEndTime(), track); } #endif } // Sort all by time std::sort(mSnapPoints.begin(), mSnapPoints.end()); }
SnapManager::SnapManager(TrackList *tracks, TrackClipArray *exclusions, double zoom, int pixelTolerance, bool noTimeSnap) { int i; // Grab time-snapping prefs (unless otherwise requested) mSnapToTime = false; AudacityProject *p = GetActiveProject(); wxASSERT(p); if (p) { // Look up the format string if (p->GetSnapTo() && !noTimeSnap) { mSnapToTime = true; mConverter.SetSampleRate(p->GetRate()); mConverter.SetFormatName(p->GetSelectionFormat()); } } mSnapPoints = new SnapPointArray(CompareSnapPoints); if (zoom > 0 && pixelTolerance > 0) mTolerance = pixelTolerance / zoom; else { // This shouldn't happen, but we don't want to crash if we get // illegal values. The net effect of this is to never snap. mTolerance = 0.0; } // Two time points closer than this are considered the same mEpsilon = 1 / 44100.0; // Add a SnapPoint at t=0 mSnapPoints->Add(new SnapPoint(0.0, NULL)); TrackListIterator iter(tracks); Track *track = iter.First(); while (track) { if (track->GetKind() == Track::Label) { LabelTrack *labelTrack = (LabelTrack *)track; for(i = 0; i < labelTrack->GetNumLabels(); i++) { const LabelStruct *label = labelTrack->GetLabel(i); CondListAdd(label->t, labelTrack); if (label->t1 != label->t) { CondListAdd(label->t1, labelTrack); } } } else if (track->GetKind() == Track::Wave) { WaveTrack *waveTrack = (WaveTrack *)track; WaveClipList::compatibility_iterator it; for (it=waveTrack->GetClipIterator(); it; it=it->GetNext()) { WaveClip *clip = it->GetData(); if (exclusions) { bool skip = false; for(int j=0; j<(int)exclusions->GetCount(); j++) { if ((*exclusions)[j].track == waveTrack && (*exclusions)[j].clip == clip) skip = true; } if (skip) continue; } CondListAdd(clip->GetStartTime(), waveTrack); CondListAdd(clip->GetEndTime(), waveTrack); } } #ifdef USE_MIDI else if (track->GetKind() == Track::Note) { CondListAdd(track->GetStartTime(), track); CondListAdd(track->GetEndTime(), track); } #endif track = iter.Next(); } }