From 35653f3a8613c3cc361b1c0299a832c2852e330e Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Tue, 21 Jun 2022 16:06:16 +0100 Subject: [PATCH] Start reworking log output --- meson.build | 5 +- rubberband/RubberBandStretcher.h | 34 ++++++++++- src/RubberBandStretcher.cpp | 45 +++++++++++++-- src/common/Log.h | 99 ++++++++++++++++++++++++++++++++ src/common/StretchCalculator.cpp | 6 +- src/common/StretchCalculator.h | 8 ++- src/faster/R2Stretcher.cpp | 7 ++- src/faster/R2Stretcher.h | 9 ++- src/finer/Guide.h | 12 ++-- src/finer/PhaseAdvance.h | 20 ++++--- src/finer/R3Stretcher.cpp | 54 ++++++++--------- src/finer/R3Stretcher.h | 26 ++++----- vamp/RubberBandVampPlugin.cpp | 4 +- 13 files changed, 258 insertions(+), 71 deletions(-) create mode 100644 src/common/Log.h diff --git a/meson.build b/meson.build index 442e274..6aa8677 100644 --- a/meson.build +++ b/meson.build @@ -42,10 +42,11 @@ library_sources = [ 'src/faster/R2Stretcher.cpp', 'src/faster/StretcherChannelData.cpp', 'src/faster/StretcherProcess.cpp', + 'src/common/Allocators.cpp', + 'src/common/FFT.cpp', + 'src/common/Log.cpp', 'src/common/Profiler.cpp', 'src/common/Resampler.cpp', - 'src/common/FFT.cpp', - 'src/common/Allocators.cpp', 'src/common/StretchCalculator.cpp', 'src/common/sysutils.cpp', 'src/common/Thread.cpp', diff --git a/rubberband/RubberBandStretcher.h b/rubberband/RubberBandStretcher.h index 60fc9d9..2771862 100644 --- a/rubberband/RubberBandStretcher.h +++ b/rubberband/RubberBandStretcher.h @@ -37,6 +37,8 @@ #include #include +#include +#include #include /** @@ -277,7 +279,6 @@ public: * provided for backward compatibility only. They are ignored by * the stretcher. */ - enum Option { OptionProcessOffline = 0x00000000, @@ -331,6 +332,13 @@ public: PercussiveOptions = 0x00102000 }; + struct Logger { + virtual void log0(const char *) = 0; + virtual void log1(const char *, double) = 0; + virtual void log2(const char *, double, double) = 0; + virtual ~Logger() { } + }; + /** * Construct a time and pitch stretcher object to run at the given * sample rate, with the given number of channels. @@ -361,6 +369,30 @@ public: Options options = DefaultOptions, double initialTimeRatio = 1.0, double initialPitchScale = 1.0); + + /** + * Construct a time and pitch stretcher object with a custom debug + * logger. This may be useful for debugging if the default logger + * output (which simply goes to cout) is not visible in the + * runtime environment, or if the application has a standard or + * more realtime-appropriate logging mechanism. + * + * See the documentation for the other constructor above for + * details of the arguments other than the logger. + * + * Note that although the supplied logger gets to decide what to + * do with log messages, the separately-set debug level (see + * setDebugLevel() and setDefaultDebugLevel()) still determines + * whether any given debug message is generated and sent to the + * logger in the first place. + */ + RubberBandStretcher(size_t sampleRate, + size_t channels, + std::shared_ptr logger, + Options options = DefaultOptions, + double initialTimeRatio = 1.0, + double initialPitchScale = 1.0); + ~RubberBandStretcher(); /** diff --git a/src/RubberBandStretcher.cpp b/src/RubberBandStretcher.cpp index 6043217..bba65e1 100644 --- a/src/RubberBandStretcher.cpp +++ b/src/RubberBandStretcher.cpp @@ -30,18 +30,39 @@ class RubberBandStretcher::Impl { R2Stretcher *m_r2; R3Stretcher *m_r3; - + + Log makeRBLog(std::shared_ptr logger) { + if (logger) { + return Log( + [=](const char *message) { + logger->log0(message); + }, + [=](const char *message, double arg0) { + logger->log1(message, arg0); + }, + [=](const char *message, double arg0, double arg1) { + logger->log2(message, arg0, arg1); + } + ); + } else { + return Log::makeCoutLog(); + } + } + public: Impl(size_t sampleRate, size_t channels, Options options, + std::shared_ptr logger, double initialTimeRatio, double initialPitchScale) : m_r2 (!(options & OptionEngineFiner) ? new R2Stretcher(sampleRate, channels, options, - initialTimeRatio, initialPitchScale) + initialTimeRatio, initialPitchScale, + makeRBLog(logger)) : nullptr), m_r3 ((options & OptionEngineFiner) ? new R3Stretcher(R3Stretcher::Parameters (double(sampleRate), channels, options), - initialTimeRatio, initialPitchScale) + initialTimeRatio, initialPitchScale, + makeRBLog(logger)) : nullptr) { } @@ -272,13 +293,14 @@ public: setDebugLevel(int level) { if (m_r2) m_r2->setDebugLevel(level); + else m_r3->setDebugLevel(level); } static void setDefaultDebugLevel(int level) { - R2Stretcher::setDefaultDebugLevel(level); -//!!! R3Stretcher::setDefaultDebugLevel(level); + Log::setDefaultDebugLevel(level); + R2Stretcher::setDefaultDebugLevel(level); //!!! } }; @@ -287,7 +309,18 @@ RubberBandStretcher::RubberBandStretcher(size_t sampleRate, Options options, double initialTimeRatio, double initialPitchScale) : - m_d(new Impl(sampleRate, channels, options, + m_d(new Impl(sampleRate, channels, options, nullptr, + initialTimeRatio, initialPitchScale)) +{ +} + +RubberBandStretcher::RubberBandStretcher(size_t sampleRate, + size_t channels, + std::shared_ptr logger, + Options options, + double initialTimeRatio, + double initialPitchScale) : + m_d(new Impl(sampleRate, channels, options, logger, initialTimeRatio, initialPitchScale)) { } diff --git a/src/common/Log.h b/src/common/Log.h new file mode 100644 index 0000000..450c24d --- /dev/null +++ b/src/common/Log.h @@ -0,0 +1,99 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Rubber Band Library + An audio time-stretching and pitch-shifting library. + Copyright 2007-2022 Particular Programs Ltd. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. + + Alternatively, if you have a valid commercial licence for the + Rubber Band Library obtained by agreement with the copyright + holders, you may redistribute and/or modify it under the terms + described in that licence. + + If you wish to distribute code using the Rubber Band Library + under terms other than those of the GNU General Public License, + you must obtain a valid commercial licence before doing so. +*/ + +#ifndef RUBBERBAND_LOG_H +#define RUBBERBAND_LOG_H + +#include +#include + +namespace RubberBand { + +class Log { +public: + Log(std::function _log0, + std::function _log1, + std::function _log2) : + m_log0(_log0), + m_log1(_log1), + m_log2(_log2), + m_debugLevel(m_defaultDebugLevel) { } + + Log(const Log &other) : + m_log0(other.m_log0), + m_log1(other.m_log1), + m_log2(other.m_log2), + m_debugLevel(other.m_debugLevel) { } + + Log &operator=(const Log &other) { + m_log0 = other.m_log0; + m_log1 = other.m_log1; + m_log2 = other.m_log2; + m_debugLevel = other.m_debugLevel; + return *this; + } + + void setDebugLevel(int level) { m_debugLevel = level; } + int getDebugLevel() const { return m_debugLevel; } + + static void setDefaultDebugLevel(int level) { m_defaultDebugLevel = level; } + + void log0(int level, const char *message) const { + if (level <= m_debugLevel) m_log0(message); + } + void log1(int level, const char *message, double arg0) const { + if (level <= m_debugLevel) m_log1(message, arg0); + } + + //!!! On reflection, log2 is a dumb choice of name + void log2(int level, const char *message, double arg0, double arg1) const { + if (level <= m_debugLevel) m_log2(message, arg0, arg1); + } + + static Log makeCoutLog() { + return Log( + [](const char *message) { + std::cout << "RubberBand: " << message << "\n"; + }, + [](const char *message, double arg0) { + std::cout << "RubberBand: " << message + << ": " << arg0 << "\n"; + }, + [](const char *message, double arg0, double arg1) { + std::cout << "RubberBand: " << message + << ": (" << arg0 << "," << arg1 << ")" << "\n"; + } + ); + } + +private: + std::function m_log0; + std::function m_log1; + std::function m_log2; + int m_debugLevel; + static int m_defaultDebugLevel; +}; + +} + +#endif diff --git a/src/common/StretchCalculator.cpp b/src/common/StretchCalculator.cpp index 25c440f..204ccd3 100644 --- a/src/common/StretchCalculator.cpp +++ b/src/common/StretchCalculator.cpp @@ -37,7 +37,8 @@ namespace RubberBand StretchCalculator::StretchCalculator(size_t sampleRate, size_t inputIncrement, - bool useHardPeaks) : + bool useHardPeaks, + Log log) : m_sampleRate(sampleRate), m_increment(inputIncrement), m_prevDf(0), @@ -49,7 +50,8 @@ StretchCalculator::StretchCalculator(size_t sampleRate, m_useHardPeaks(useHardPeaks), m_inFrameCounter(0), m_frameCheckpoint(0, 0), - m_outFrameCounter(0) + m_outFrameCounter(0), + m_log(log) { // std::cerr << "StretchCalculator::StretchCalculator: useHardPeaks = " << useHardPeaks << std::endl; } diff --git a/src/common/StretchCalculator.h b/src/common/StretchCalculator.h index e1f91fc..af12780 100644 --- a/src/common/StretchCalculator.h +++ b/src/common/StretchCalculator.h @@ -30,13 +30,18 @@ #include #include +#include "Log.h" + namespace RubberBand { class StretchCalculator { public: - StretchCalculator(size_t sampleRate, size_t inputIncrement, bool useHardPeaks); + StretchCalculator(size_t sampleRate, + size_t inputIncrement, + bool useHardPeaks, + Log log); virtual ~StretchCalculator(); /** @@ -107,6 +112,7 @@ protected: std::pair m_frameCheckpoint; int64_t expectedOutFrame(int64_t inFrame, double timeRatio); double m_outFrameCounter; + Log m_log; std::map m_keyFrameMap; std::vector m_peaks; diff --git a/src/faster/R2Stretcher.cpp b/src/faster/R2Stretcher.cpp index 202f69a..70f2988 100644 --- a/src/faster/R2Stretcher.cpp +++ b/src/faster/R2Stretcher.cpp @@ -65,7 +65,8 @@ R2Stretcher::R2Stretcher(size_t sampleRate, size_t channels, RubberBandStretcher::Options options, double initialTimeRatio, - double initialPitchScale) : + double initialPitchScale, + Log log) : m_sampleRate(sampleRate), m_channels(channels), m_timeRatio(initialTimeRatio), @@ -82,6 +83,7 @@ R2Stretcher::R2Stretcher(size_t sampleRate, #endif m_realtime(false), m_options(options), + m_log(log), m_debugLevel(m_defaultDebugLevel), m_mode(JustCreated), m_awindow(0), @@ -700,7 +702,8 @@ R2Stretcher::configure() delete m_stretchCalculator; m_stretchCalculator = new StretchCalculator (m_sampleRate, m_increment, - !(m_options & RubberBandStretcher::OptionTransientsSmooth)); + !(m_options & RubberBandStretcher::OptionTransientsSmooth), + m_log); m_stretchCalculator->setDebugLevel(m_debugLevel); m_inputDuration = 0; diff --git a/src/faster/R2Stretcher.h b/src/faster/R2Stretcher.h index 06efbcb..74b711b 100644 --- a/src/faster/R2Stretcher.h +++ b/src/faster/R2Stretcher.h @@ -31,6 +31,7 @@ #include "../common/RingBuffer.h" #include "../common/Scavenger.h" #include "../common/Thread.h" +#include "../common/Log.h" #include "../common/sysutils.h" #include "SincWindow.h" @@ -50,7 +51,8 @@ class R2Stretcher public: R2Stretcher(size_t sampleRate, size_t channels, RubberBandStretcher::Options options, - double initialTimeRatio, double initialPitchScale); + double initialTimeRatio, double initialPitchScale, + Log log); ~R2Stretcher(); void reset(); @@ -174,7 +176,8 @@ protected: bool m_realtime; RubberBandStretcher::Options m_options; - int m_debugLevel; + Log m_log; + int m_debugLevel; //!!! to go once Log switch complete enum ProcessMode { JustCreated, @@ -251,7 +254,7 @@ protected: void writeOutput(RingBuffer &to, float *from, size_t qty, size_t &outCount, size_t theoreticalOut); - static int m_defaultDebugLevel; + static int m_defaultDebugLevel; //!!! to go static const size_t m_defaultIncrement; static const size_t m_defaultFftSize; }; diff --git a/src/finer/Guide.h b/src/finer/Guide.h index f71148b..8ac8ecc 100644 --- a/src/finer/Guide.h +++ b/src/finer/Guide.h @@ -24,6 +24,8 @@ #ifndef RUBBERBAND_GUIDE_H #define RUBBERBAND_GUIDE_H +#include "../common/Log.h" + #include #include @@ -102,15 +104,12 @@ public: struct Parameters { double sampleRate; - std::function logger; - Parameters(double _sampleRate, - std::function _log) : - sampleRate(_sampleRate), - logger(_log) { } + Parameters(double _sampleRate) : sampleRate(_sampleRate) { } }; - Guide(Parameters parameters) : + Guide(Parameters parameters, Log log) : m_parameters(parameters), + m_log(log), m_configuration(roundUp(int(ceil(parameters.sampleRate / 16.0))), roundUp(int(ceil(parameters.sampleRate / 64.0))), roundUp(int(ceil(parameters.sampleRate / 32.0)))), @@ -334,6 +333,7 @@ public: protected: Parameters m_parameters; + Log m_log; Configuration m_configuration; double m_minLower; diff --git a/src/finer/PhaseAdvance.h b/src/finer/PhaseAdvance.h index 5fc6f99..0f23c7f 100644 --- a/src/finer/PhaseAdvance.h +++ b/src/finer/PhaseAdvance.h @@ -26,6 +26,7 @@ #include "Guide.h" +#include "../common/Log.h" #include "../common/mathmisc.h" #include @@ -41,15 +42,13 @@ public: int fftSize; double sampleRate; int channels; - std::function logger; - Parameters(int _fftSize, double _sampleRate, int _channels, - std::function _log) : - fftSize(_fftSize), sampleRate(_sampleRate), - channels(_channels), logger(_log) { } + Parameters(int _fftSize, double _sampleRate, int _channels) : + fftSize(_fftSize), sampleRate(_sampleRate), channels(_channels) { } }; - GuidedPhaseAdvance(Parameters parameters) : + GuidedPhaseAdvance(Parameters parameters, Log log) : m_parameters(parameters), + m_log(log), m_binCount(parameters.fftSize / 2 + 1), m_peakPicker(m_binCount), m_reported(false) { @@ -111,7 +110,7 @@ public: int lowest = configuration.fftBandLimits[myFftBand].b0min; int highest = configuration.fftBandLimits[myFftBand].b1max; - if (!m_reported) { + if (m_log.getDebugLevel() > 0 && !m_reported) { std::ostringstream ostr; ostr << "PhaseAdvance: fftSize = " << m_parameters.fftSize << ": bins = " << bs << ", channels = " << channels @@ -122,7 +121,7 @@ public: << "Hz), highest = " << highest << " (" << configuration.fftBandLimits[myFftBand].f1max << "Hz)" << std::endl; - m_parameters.logger(ostr.str()); + m_log.log0(1, ostr.str().c_str()); m_reported = true; } @@ -231,8 +230,13 @@ public: } } + void setDebugLevel(int debugLevel) { + m_log.setDebugLevel(debugLevel); + } + protected: Parameters m_parameters; + Log m_log; int m_binCount; Peak m_peakPicker; int **m_currentPeaks; diff --git a/src/finer/R3Stretcher.cpp b/src/finer/R3Stretcher.cpp index 57b8f6a..4c750da 100644 --- a/src/finer/R3Stretcher.cpp +++ b/src/finer/R3Stretcher.cpp @@ -31,12 +31,14 @@ namespace RubberBand { R3Stretcher::R3Stretcher(Parameters parameters, double initialTimeRatio, - double initialPitchScale) : + double initialPitchScale, + Log log) : m_parameters(parameters), + m_log(log), m_timeRatio(initialTimeRatio), m_pitchScale(initialPitchScale), m_formantScale(0.0), - m_guide(Guide::Parameters(m_parameters.sampleRate, parameters.logger)), + m_guide(Guide::Parameters(m_parameters.sampleRate), m_log), m_guideConfiguration(m_guide.getConfiguration()), m_channelAssembly(m_parameters.channels), m_inhop(1), @@ -83,18 +85,19 @@ R3Stretcher::R3Stretcher(Parameters parameters, (fftSize, m_guideConfiguration.longestFftSize); } } - + for (auto band: m_guideConfiguration.fftBandLimits) { int fftSize = band.fftSize; GuidedPhaseAdvance::Parameters guidedParameters - (fftSize, m_parameters.sampleRate, m_parameters.channels, - m_parameters.logger); - m_scaleData[fftSize] = std::make_shared(guidedParameters); + (fftSize, m_parameters.sampleRate, m_parameters.channels); + m_scaleData[fftSize] = std::make_shared(guidedParameters, + m_log); } m_calculator = std::unique_ptr (new StretchCalculator(int(round(m_parameters.sampleRate)), //!!! which is a double... - 1, false)); // no fixed inputIncrement + 1, false, // no fixed inputIncrement + m_log)); Resampler::Parameters resamplerParameters; resamplerParameters.quality = Resampler::FastestTolerable; @@ -119,10 +122,10 @@ R3Stretcher::R3Stretcher(Parameters parameters, m_prevOuthop = int(round(m_inhop * getEffectiveRatio())); if (!m_inhop.is_lock_free()) { - m_parameters.logger("WARNING: std::atomic is not lock-free"); + m_log.log0(0, "WARNING: std::atomic is not lock-free"); } if (!m_timeRatio.is_lock_free()) { - m_parameters.logger("WARNING: std::atomic is not lock-free"); + m_log.log0(0, "WARNING: std::atomic is not lock-free"); } // Pad to half of the longest frame. As with R2, in real-time mode @@ -131,7 +134,7 @@ R3Stretcher::R3Stretcher(Parameters parameters, // changes. if (!isRealTime()) { - m_parameters.logger("Offline mode: pre-padding"); + m_log.log0(1, "Offline mode: pre-padding"); int pad = m_guideConfiguration.longestFftSize / 2; for (int c = 0; c < m_parameters.channels; ++c) { m_channelData[c]->inbuf->zero(pad); @@ -139,7 +142,7 @@ R3Stretcher::R3Stretcher(Parameters parameters, // By the time we skip this later we will have resampled m_startSkip = int(round(pad / m_pitchScale)); } else { - m_parameters.logger("RT mode: no internal pre-pad"); + m_log.log0(1, "RT mode: no internal pre-pad"); } } @@ -176,7 +179,7 @@ R3Stretcher::setTimeRatio(double ratio) if (!isRealTime()) { if (m_mode == ProcessMode::Studying || m_mode == ProcessMode::Processing) { - m_parameters.logger("R3Stretcher::setTimeRatio: Cannot set time ratio while studying or processing in non-RT mode"); + m_log.log0(0, "R3Stretcher::setTimeRatio: Cannot set time ratio while studying or processing in non-RT mode"); return; } } @@ -192,7 +195,7 @@ R3Stretcher::setPitchScale(double scale) if (!isRealTime()) { if (m_mode == ProcessMode::Studying || m_mode == ProcessMode::Processing) { - m_parameters.logger("R3Stretcher::setTimeRatio: Cannot set pitch scale while studying or processing in non-RT mode"); + m_log.log0(0, "R3Stretcher::setTimeRatio: Cannot set pitch scale while studying or processing in non-RT mode"); return; } } @@ -208,7 +211,7 @@ R3Stretcher::setFormantScale(double scale) if (!isRealTime()) { if (m_mode == ProcessMode::Studying || m_mode == ProcessMode::Processing) { - m_parameters.logger("R3Stretcher::setTimeRatio: Cannot set formant scale while studying or processing in non-RT mode"); + m_log.log0(0, "R3Stretcher::setTimeRatio: Cannot set formant scale while studying or processing in non-RT mode"); return; } } @@ -230,11 +233,11 @@ void R3Stretcher::setKeyFrameMap(const std::map &mapping) { if (isRealTime()) { - m_parameters.logger("R3Stretcher::setKeyFrameMap: Cannot specify key frame map in RT mode"); + m_log.log0(0, "R3Stretcher::setKeyFrameMap: Cannot specify key frame map in RT mode"); return; } if (m_mode == ProcessMode::Processing || m_mode == ProcessMode::Finished) { - m_parameters.logger("R3Stretcher::setKeyFrameMap: Cannot specify key frame map after process() has begun"); + m_log.log0(0, "R3Stretcher::setKeyFrameMap: Cannot specify key frame map after process() has begun"); return; } @@ -266,22 +269,21 @@ R3Stretcher::calculateHop() if (proposedOuthop > 512.0) proposedOuthop = 512.0; if (proposedOuthop < 128.0) proposedOuthop = 128.0; - std::cout << "calculateHop: for ratio " << ratio << " proposedOuthop = " - << proposedOuthop << std::endl; + m_log.log2(1, "calculateHop: ratio and proposed outhop", ratio, proposedOuthop); double inhop = proposedOuthop / ratio; if (inhop < 1.0) { - m_parameters.logger("WARNING: Extreme ratio yields ideal inhop < 1, results may be suspect"); + m_log.log2(0, "WARNING: Extreme ratio yields ideal inhop < 1, results may be suspect", ratio, inhop); inhop = 1.0; } if (inhop > 768.0) { - m_parameters.logger("WARNING: Extreme ratio yields ideal inhop > 768, results may be suspect"); + m_log.log2(0, "WARNING: Extreme ratio yields ideal inhop > 768, results may be suspect", ratio, inhop); inhop = 768.0; } m_inhop = int(floor(inhop)); - std::cout << "R3Stretcher::calculateHop: inhop = " << m_inhop << ", proposed outhop = " << proposedOuthop << ", mean outhop = " << m_inhop * ratio << std::endl; + m_log.log2(1, "calculateHop: inhop and mean outhop", m_inhop, m_inhop * ratio); } void @@ -409,12 +411,12 @@ void R3Stretcher::study(const float *const *, size_t samples, bool) { if (isRealTime()) { - m_parameters.logger("R3Stretcher::study: Not meaningful in realtime mode"); + m_log.log0(0, "R3Stretcher::study: Not meaningful in realtime mode"); return; } if (m_mode == ProcessMode::Processing || m_mode == ProcessMode::Finished) { - m_parameters.logger("R3Stretcher::study: Cannot study after processing"); + m_log.log0(0, "R3Stretcher::study: Cannot study after processing"); return; } @@ -443,7 +445,7 @@ void R3Stretcher::process(const float *const *input, size_t samples, bool final) { if (m_mode == ProcessMode::Finished) { - m_parameters.logger("R3Stretcher::process: Cannot process again after final chunk"); + m_log.log0(0, "R3Stretcher::process: Cannot process again after final chunk"); return; } @@ -468,7 +470,7 @@ R3Stretcher::process(const float *const *input, size_t samples, bool final) size_t ws = m_channelData[0]->inbuf->getWriteSpace(); if (samples > ws) { //!!! check this - m_parameters.logger("R3Stretcher::process: WARNING: Forced to increase input buffer size. Either setMaxProcessSize was not properly called or process is being called repeatedly without retrieve."); + m_log.log0(0, "R3Stretcher::process: WARNING: Forced to increase input buffer size. Either setMaxProcessSize was not properly called or process is being called repeatedly without retrieve."); size_t newSize = m_channelData[0]->inbuf->getSize() - ws + samples; for (int c = 0; c < m_parameters.channels; ++c) { auto newBuf = m_channelData[c]->inbuf->resized(newSize); @@ -505,7 +507,7 @@ R3Stretcher::retrieve(float *const *output, size_t samples) const int gotHere = m_channelData[c]->outbuf->read(output[c], got); if (gotHere < got) { if (c > 0) { - m_parameters.logger("R3Stretcher::retrieve: WARNING: channel imbalance detected"); + m_log.log0(0, "R3Stretcher::retrieve: WARNING: channel imbalance detected"); } got = std::min(got, std::max(gotHere, 0)); } diff --git a/src/finer/R3Stretcher.h b/src/finer/R3Stretcher.h index 6ba2944..292f2c0 100644 --- a/src/finer/R3Stretcher.h +++ b/src/finer/R3Stretcher.h @@ -36,12 +36,12 @@ #include "../common/Allocators.h" #include "../common/Window.h" #include "../common/VectorOpsComplex.h" +#include "../common/Log.h" #include "../../rubberband/RubberBandStretcher.h" #include #include -#include namespace RubberBand { @@ -53,17 +53,15 @@ public: double sampleRate; int channels; RubberBandStretcher::Options options; - std::function logger; Parameters(double _sampleRate, int _channels, - RubberBandStretcher::Options _options, - std::function _log = &logCout) : - sampleRate(_sampleRate), channels(_channels), options(_options), - logger(_log) { } + RubberBandStretcher::Options _options) : + sampleRate(_sampleRate), channels(_channels), options(_options) { } }; R3Stretcher(Parameters parameters, double initialTimeRatio, - double initialPitchScale); + double initialPitchScale, + Log log); ~R3Stretcher() { } void reset(); @@ -89,6 +87,10 @@ public: size_t getLatency() const; size_t getChannelCount() const; + void setDebugLevel(int level) { + m_log.setDebugLevel(level); //!!! +others + } + protected: struct ClassificationReadaheadData { FixedVector timeDomain; @@ -242,7 +244,8 @@ protected: Window synthesisWindow; double windowScaleFactor; GuidedPhaseAdvance guided; - ScaleData(GuidedPhaseAdvance::Parameters guidedParameters) : + ScaleData(GuidedPhaseAdvance::Parameters guidedParameters, + Log log) : fftSize(guidedParameters.fftSize), fft(fftSize), analysisWindow(analysisWindowShape(fftSize), @@ -250,7 +253,7 @@ protected: synthesisWindow(synthesisWindowShape(fftSize), synthesisWindowLength(fftSize)), windowScaleFactor(0.0), - guided(guidedParameters) + guided(guidedParameters, log) { int asz = analysisWindow.getSize(), ssz = synthesisWindow.getSize(); int off = (asz - ssz) / 2; @@ -267,6 +270,7 @@ protected: }; Parameters m_parameters; + Log m_log; std::atomic m_timeRatio; std::atomic m_pitchScale; @@ -347,10 +351,6 @@ protected: return m_parameters.options & RubberBandStretcher::OptionProcessRealTime; } - - static void logCout(const std::string &message) { - std::cout << "RubberBandStretcher: " << message << std::endl; - } }; } diff --git a/vamp/RubberBandVampPlugin.cpp b/vamp/RubberBandVampPlugin.cpp index 6a8ca3a..a00ee1c 100644 --- a/vamp/RubberBandVampPlugin.cpp +++ b/vamp/RubberBandVampPlugin.cpp @@ -463,7 +463,9 @@ RubberBandVampPlugin::Impl::getRemainingFeaturesOffline() int rate = m_sampleRate; - RubberBand::StretchCalculator sc(rate, m_stretcher->getInputIncrement(), true); + RubberBand::StretchCalculator sc + (rate, m_stretcher->getInputIncrement(), true, + RubberBand::Log::makeCoutLog()); size_t inputIncrement = m_stretcher->getInputIncrement(); std::vector outputIncrements = m_stretcher->getOutputIncrements();