41 for (
const auto &subViewPtr : waveChannelViewPtr->GetAllSubViews()){
42 if (subViewPtr->IsSpectral()) {
44 std::static_pointer_cast<SpectrumView>(subViewPtr).get();
45 const auto pData = sView->GetSpectralData();
46 if (!pData->dataHistory.empty()) {
61 using Type =
long long;
62 Type startSample{ std::numeric_limits<Type>::max() };
64 for (
auto pChannel : wt->Channels()) {
66 const auto &hopSize = pData->GetHopSize();
67 auto start = pData->GetStartSample();
68 endSample = std::max(endSample, pData->GetEndSample());
72 start = std::max(
static_cast<long long>(0), start - 2 * hopSize);
73 startSample =
std::min(startSample, start);
76 if (startSample >= endSample)
78 const auto t0 = wt->LongSamplesToTime(startSample);
79 const auto len = endSample - startSample;
80 const auto tLen = wt->LongSamplesToTime(len);
81 auto tempList = wt->WideEmptyCopy();
82 auto iter = (*tempList->Any<
WaveTrack>().
begin())->Channels().begin();
83 long long processed{};
84 for (
auto pChannel : wt->Channels()) {
85 Worker worker{ (*iter++).get(), setting };
89 for (
const auto &subViewPtr : waveChannelViewPtr->GetAllSubViews()){
90 if (!subViewPtr->IsSpectral())
92 auto sView = std::static_pointer_cast<SpectrumView>(subViewPtr).get();
93 auto pSpectralData = sView->GetSpectralData();
95 if (!pSpectralData->dataHistory.empty()) {
98 processed = std::max(processed, pSpectralData->GetLength());
99 worker.Process(*pChannel, pSpectralData);
100 applyCount +=
static_cast<int>(pSpectralData->dataHistory.size());
101 pSpectralData->clearAllData();
106 if (!tempList->empty()) {
113 wt->ClearAndPaste(t0, t0 + tLen, *tempList,
true,
false);
119 XO(
"Applied effect to selection"),
120 XO(
"Applied effect to selection"));
124 return applyCount > 0;
128 long long int startSC,
int hopSize,
double threshold,
int targetFreqBin)
132 Worker worker{
nullptr, setting };
134 return worker.ProcessSnapping(
135 channel, startSC, hopSize, setting.
mWindowSize, threshold, targetFreqBin);
139 long long int startSC,
146 Worker worker{
nullptr, setting };
148 return worker.ProcessOvertones(*wt, startSC, hopSize, setting.
mWindowSize, threshold, targetFreqBin);
154 setting.mNeedOutput, setting.mInWindowType, setting.mOutWindowType,
155 setting.mWindowSize, setting.mStepsPerWindow,
156 setting.mLeadingPadding, setting.mTrailingPadding
172 const std::shared_ptr<SpectralData> &pSpectralData)
174 mpSpectralData = pSpectralData;
175 const auto hopSize = mpSpectralData->GetHopSize();
176 const auto startSample = mpSpectralData->GetStartSample();
179 mStartHopNum = startSample / hopSize - (mStepsPerWindow - 1);
182 mpSpectralData->GetCorrectedStartSample(), mpSpectralData->GetLength());
186 long long startSC,
int hopSize,
size_t winSize,
double threshold,
189 mSnapThreshold = threshold;
190 mSnapTargetFreqBin = targetFreqBin;
193 startSC = std::max(
static_cast<long long>(0), startSC - 2 * hopSize);
196 1, startSC, winSize))
199 return mSnapReturnFreqBin;
203 const WaveChannel &channel,
long long startSC,
int hopSize,
size_t winSize,
204 double threshold,
int targetFreqBin)
206 mOvertonesThreshold = threshold;
207 mSnapTargetFreqBin = targetFreqBin;
210 startSC = std::max(
static_cast<long long>(0), startSC - 2 * hopSize);
213 OvertonesProcessor, channel, 1, startSC, winSize);
214 return move( mOvertonesTargetFreqBin );
218 auto &worker =
static_cast<Worker &
>(transformer);
221 MyWindow &record = worker.NthWindow(0);
223 const double dc = record.mRealFFTs[0];
224 *pSpectrum++ = dc * dc;
225 float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
226 for (
size_t nn = worker.mSpectrumSize - 2; nn--;) {
227 const double re = *pReal++, im = *pImag++;
228 *pSpectrum++ = re * re + im * im;
230 const double nyquist = record.mImagFFTs[0];
231 *pSpectrum = nyquist * nyquist;
233 const double &sr = worker.mSnapSamplingRate;
234 const double nyquistRate = sr / 2;
235 const double &threshold = worker.mSnapThreshold;
236 const double &spectrumSize = worker.mSpectrumSize;
237 const int &targetBin = worker.mSnapTargetFreqBin;
239 int binBound = spectrumSize * threshold;
243 for(
int i = -binBound; i < binBound; i++){
244 int idx = std::clamp(targetBin + i, 0,
static_cast<int>(spectrumSize - 1));
248 worker.mSnapReturnFreqBin = idx;
257 auto &worker =
static_cast<Worker &
>(transformer);
260 MyWindow &record = worker.NthWindow(0);
262 const double dc = record.mRealFFTs[0];
263 *pSpectrum++ = dc * dc;
264 float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
265 for (
size_t nn = worker.mSpectrumSize - 2; nn--;) {
266 const double re = *pReal++, im = *pImag++;
267 *pSpectrum++ = re * re + im * im;
269 const double nyquist = record.mImagFFTs[0];
270 *pSpectrum = nyquist * nyquist;
272 const double &spectrumSize = worker.mSpectrumSize;
273 const int &targetBin = worker.mSnapTargetFreqBin;
275 float targetValue = record.
mSpectrums[targetBin];
277 double fundamental = targetBin;
278 int overtone = 2, binNum = 0;
280 while ( fundamental >= 1 &&
281 ( binNum =
lrint( fundamental * overtone ) ) < spectrumSize) {
283 constexpr int tolerance = 3;
284 auto begin = pSpectrum + std::max( 0, binNum - (tolerance + 1) );
285 auto end = pSpectrum +
286 std::min<size_t>( spectrumSize, binNum + (tolerance + 1) + 1 );
287 auto peak = std::max_element(
begin,
end );
290 if ( peak ==
begin || peak ==
end - 1 )
293 int newBin = peak - pSpectrum;
294 worker.mOvertonesTargetFreqBin.push_back(newBin);
296 fundamental = double(newBin) / overtone++;
304 auto &worker =
static_cast<Worker &
>(transformer);
307 MyWindow &record = worker.NthWindow(0);
309 const double dc = record.mRealFFTs[0];
310 *pSpectrum++ = dc * dc;
311 float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
312 for (
size_t nn = worker.mSpectrumSize - 2; nn--;) {
313 const double re = *pReal++, im = *pImag++;
314 *pSpectrum++ = re * re + im * im;
316 const double nyquist = record.mImagFFTs[0];
317 *pSpectrum = nyquist * nyquist;
320 worker.ApplyEffectToSelection();
325 auto &record = NthWindow(0);
327 for(
auto &spectralDataMap: mpSpectralData->dataHistory){
329 for(
const int &freqBin: spectralDataMap[mStartHopNum]){
330 record.mRealFFTs[freqBin] = 0;
331 record.mImagFFTs[freqBin] = 0;
341-> std::unique_ptr<Window>
343 return std::make_unique<MyWindow>(windowSize);
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static ChannelView & Get(Channel &channel)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
Worker(WaveChannel *pChannel, const Setting &setting)
std::vector< int > ProcessOvertones(const WaveChannel &channel, long long int startSC, int hopSize, size_t winSize, double threshold, int targetFreqBin)
bool ApplyEffectToSelection()
bool DoFinish() override
Called after the last call to ProcessWindow().
bool DoStart() override
Called before any calls to ProcessWindow.
std::unique_ptr< Window > NewWindow(size_t windowSize) override
Allocates a window to place in the queue.
int ProcessSnapping(const WaveChannel &channel, long long int startSC, int hopSize, size_t winSize, double threshold, int targetFreqBin)
bool Process(const WaveChannel &channel, const std::shared_ptr< SpectralData > &sDataPtr)
static bool OvertonesProcessor(SpectrumTransformer &transformer)
static bool Processor(SpectrumTransformer &transformer)
static bool SnappingProcessor(SpectrumTransformer &transformer)
static std::vector< int > FindHighestFrequencyBins(WaveTrack *wt, long long int startSC, int hopSize, double threshold, int targetFreqBin)
static bool ProcessTracks(AudacityProject &project)
static int FindFrequencySnappingBin(const WaveChannel &channel, long long startSC, int hopSize, double threshold, int targetFreqBin)
static TrackList & Get(AudacityProject &project)
A Track that contains audio waveform data.
double GetRate() const override
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
const std::shared_ptr< SpectralData > FindSpectralData(Channel *pChannel)
eWindowFunctions mOutWindowType
eWindowFunctions mInWindowType