From 6c71159593b4626ec4f6cd1a3a0c3e878d5daa05 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Wed, 22 Mar 2023 13:26:15 +0000 Subject: [PATCH] More reset tests, tighten up reset logic --- src/finer/BinClassifier.h | 11 ++++ src/finer/R3Stretcher.cpp | 2 + src/finer/R3Stretcher.h | 6 +- src/test/TestStretcher.cpp | 122 +++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/src/finer/BinClassifier.h b/src/finer/BinClassifier.h index 88a3d0d..d489946 100644 --- a/src/finer/BinClassifier.h +++ b/src/finer/BinClassifier.h @@ -92,6 +92,17 @@ public: void reset() { + while (m_vfQueue.getReadSpace() > 0) { + process_t *entry = m_vfQueue.readOne(); + deallocate(entry); + } + + for (int i = 0; i < m_parameters.horizontalFilterLag; ++i) { + process_t *entry = + allocate_and_zero(m_parameters.binCount); + m_vfQueue.write(&entry, 1); + } + m_hFilters->reset(); } diff --git a/src/finer/R3Stretcher.cpp b/src/finer/R3Stretcher.cpp index bfbbbde..d99b17c 100644 --- a/src/finer/R3Stretcher.cpp +++ b/src/finer/R3Stretcher.cpp @@ -533,6 +533,7 @@ void R3Stretcher::reset() { m_calculator->reset(); + if (m_resampler) { m_resampler->reset(); } @@ -545,6 +546,7 @@ R3Stretcher::reset() cd->reset(); } + m_unityCount = 0; m_studyInputDuration = 0; m_suppliedInputDuration = 0; m_totalTargetDuration = 0; diff --git a/src/finer/R3Stretcher.h b/src/finer/R3Stretcher.h index 88660f1..f8f39a6 100644 --- a/src/finer/R3Stretcher.h +++ b/src/finer/R3Stretcher.h @@ -172,6 +172,7 @@ protected: void reset() { v_zero(prevMag.data(), prevMag.size()); + v_zero(pendingKick.data(), pendingKick.size()); v_zero(accumulator.data(), accumulator.size()); accumulatorFill = 0; } @@ -226,7 +227,7 @@ protected: std::unique_ptr formant; ChannelData(BinSegmenter::Parameters segmenterParameters, BinClassifier::Parameters classifierParameters, - int longestFftSize, + int /*!!! longestFftSize */, int windowSourceSize, int inRingBufferSize, int outRingBufferSize) : @@ -252,6 +253,9 @@ protected: segmentation = BinSegmenter::Segmentation(); prevSegmentation = BinSegmenter::Segmentation(); nextSegmentation = BinSegmenter::Segmentation(); + for (size_t i = 0; i < nextClassification.size(); ++i) { + nextClassification[i] = BinClassifier::Classification::Residual; + } inbuf->reset(); outbuf->reset(); for (auto &s : scales) { diff --git a/src/test/TestStretcher.cpp b/src/test/TestStretcher.cpp index 6954cb0..b003486 100644 --- a/src/test/TestStretcher.cpp +++ b/src/test/TestStretcher.cpp @@ -1251,6 +1251,79 @@ BOOST_AUTO_TEST_CASE(final_fast_lower_realtime_finer_after) false); } +BOOST_AUTO_TEST_CASE(impulses_2x_0up_offline_reset_finer) +{ + int n = 10000; + int rate = 44100; + RubberBandStretcher stretcher + (rate, 1, RubberBandStretcher::OptionEngineFiner); + + stretcher.setTimeRatio(2.0); + stretcher.setPitchScale(1.0); + + vector in(n, 0.f), out1(n * 2, 0.f), out2(n * 2, 0.f); + + in[100] = 1.f; + in[101] = -1.f; + + in[5000] = 1.f; + in[5001] = -1.f; + + in[9900] = 1.f; + in[9901] = -1.f; + + float *inp = in.data(), *outp1 = out1.data(), *outp2 = out2.data(); + + stretcher.setMaxProcessSize(n); + stretcher.setExpectedInputDuration(n); + BOOST_TEST(stretcher.available() == 0); + + stretcher.study(&inp, n, true); + BOOST_TEST(stretcher.available() == 0); + + stretcher.process(&inp, n, true); + BOOST_TEST(stretcher.available() == n * 2); + + BOOST_TEST(stretcher.getStartDelay() == 0); // offline mode + + size_t got = stretcher.retrieve(&outp1, n * 2); + BOOST_TEST(got == n * 2); + BOOST_TEST(stretcher.available() == -1); + + stretcher.reset(); + + stretcher.setMaxProcessSize(n); + stretcher.setExpectedInputDuration(n); + BOOST_TEST(stretcher.available() == 0); + + stretcher.study(&inp, n, true); + BOOST_TEST(stretcher.available() == 0); + + stretcher.process(&inp, n, true); + BOOST_TEST(stretcher.available() == n * 2); + + BOOST_TEST(stretcher.getStartDelay() == 0); // offline mode + + got = stretcher.retrieve(&outp2, n * 2); + BOOST_TEST(got == n * 2); + BOOST_TEST(stretcher.available() == -1); + + for (int i = 0; i < n * 2; ++i) { + BOOST_TEST(outp1[i] == outp2[i]); + if (outp1[i] != outp2[i]) { + std::cerr << "Failure at index " << i << std::endl; + break; + } + } + +/* + std::cout << "ms\tV" << std::endl; + for (int i = 0; i < n*2; ++i) { + std::cout << i << "\t" << out[i] << std::endl; + } +*/ +} + BOOST_AUTO_TEST_CASE(impulses_2x_5up_offline_reset_finer) { int n = 10000; @@ -1324,4 +1397,53 @@ BOOST_AUTO_TEST_CASE(impulses_2x_5up_offline_reset_finer) */ } +BOOST_AUTO_TEST_CASE(impulses_2x_5up_realtime_reset_finer) +{ + int n = 10000; + int rate = 44100; + RubberBandStretcher stretcher + (rate, 1, RubberBandStretcher::OptionEngineFiner); + + stretcher.setTimeRatio(2.0); + stretcher.setPitchScale(1.5); + + vector in(n, 0.f), out1(n * 2, 0.f), out2(n * 2, 0.f); + + in[100] = 1.f; + in[101] = -1.f; + + in[5000] = 1.f; + in[5001] = -1.f; + + in[9900] = 1.f; + in[9901] = -1.f; + + float *inp = in.data(), *outp1 = out1.data(), *outp2 = out2.data(); + + stretcher.process(&inp, n, true); + size_t got1 = stretcher.retrieve(&outp1, n * 2); + BOOST_TEST(got1 <= n * 2); + + stretcher.reset(); + + stretcher.process(&inp, n, true); + size_t got2 = stretcher.retrieve(&outp2, n * 2); + BOOST_TEST(got2 == got1); + + for (size_t i = 0; i < got1; ++i) { + BOOST_TEST(outp1[i] == outp2[i]); + if (outp1[i] != outp2[i]) { + std::cerr << "Failure at index " << i << std::endl; + break; + } + } + +/* + std::cout << "ms\tV" << std::endl; + for (int i = 0; i < n*2; ++i) { + std::cout << i << "\t" << out[i] << std::endl; + } +*/ +} + BOOST_AUTO_TEST_SUITE_END()