| 54 | } |
| 55 | |
| 56 | bool SpectralDataManager::ProcessTracks(AudacityProject &project){ |
| 57 | auto &tracks = TrackList::Get(project); |
| 58 | int applyCount = 0; |
| 59 | Setting setting; |
| 60 | for (auto wt : tracks.Any<WaveTrack>()) { |
| 61 | using Type = long long; |
| 62 | Type startSample{ std::numeric_limits<Type>::max() }; |
| 63 | Type endSample{ std::numeric_limits<Type>::min() }; |
| 64 | for (auto pChannel : wt->Channels()) { |
| 65 | if (const auto pData = FindSpectralData(pChannel.get())) { |
| 66 | const auto &hopSize = pData->GetHopSize(); |
| 67 | auto start = pData->GetStartSample(); |
| 68 | endSample = std::max(endSample, pData->GetEndSample()); |
| 69 | |
| 70 | // Correct the start of range so that the first full window is |
| 71 | // centered at that position |
| 72 | start = std::max(static_cast<long long>(0), start - 2 * hopSize); |
| 73 | startSample = std::min(startSample, start); |
| 74 | } |
| 75 | } |
| 76 | if (startSample >= endSample) |
| 77 | continue; |
| 78 | const auto t0 = wt->LongSamplesToTime(startSample); |
| 79 | const auto len = endSample - startSample; |
| 80 | const auto tLen = wt->LongSamplesToTime(len); |
| 81 | auto tempTrack = wt->EmptyCopy(); |
| 82 | auto iter = tempTrack->Channels().begin(); |
| 83 | long long processed{}; |
| 84 | for (auto pChannel : wt->Channels()) { |
| 85 | Worker worker{ (*iter++).get(), setting }; |
| 86 | auto &view = ChannelView::Get(*pChannel); |
| 87 | |
| 88 | if (auto waveChannelViewPtr = dynamic_cast<WaveChannelView*>(&view)){ |
| 89 | for (const auto &subViewPtr : waveChannelViewPtr->GetAllSubViews()){ |
| 90 | if (!subViewPtr->IsSpectral()) |
| 91 | continue; |
| 92 | auto sView = std::static_pointer_cast<SpectrumView>(subViewPtr).get(); |
| 93 | auto pSpectralData = sView->GetSpectralData(); |
| 94 | |
| 95 | if (!pSpectralData->dataHistory.empty()) { |
| 96 | // TODO make this correct in case start or end of spectral data in |
| 97 | // the channels differs |
| 98 | processed = std::max(processed, pSpectralData->GetLength()); |
| 99 | worker.Process(*pChannel, pSpectralData); |
| 100 | applyCount += static_cast<int>(pSpectralData->dataHistory.size()); |
| 101 | pSpectralData->clearAllData(); |
| 102 | } |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | if (tempTrack) { |
| 107 | TrackSpectrumTransformer::PostProcess(*tempTrack, processed); |
| 108 | // Take the output track and insert it in place of the original |
| 109 | // sample data |
| 110 | // TODO make this correct in case start or end of spectral data in |
| 111 | // the channels differs |
| 112 | wt->ClearAndPaste(t0, t0 + tLen, *tempTrack, true, false); |
| 113 | } |
nothing calls this directly
no test coverage detected