Start reworking log output

This commit is contained in:
Chris Cannam
2022-06-21 16:06:16 +01:00
parent e546767a6d
commit 35653f3a86
13 changed files with 258 additions and 71 deletions

View File

@@ -42,10 +42,11 @@ library_sources = [
'src/faster/R2Stretcher.cpp', 'src/faster/R2Stretcher.cpp',
'src/faster/StretcherChannelData.cpp', 'src/faster/StretcherChannelData.cpp',
'src/faster/StretcherProcess.cpp', 'src/faster/StretcherProcess.cpp',
'src/common/Allocators.cpp',
'src/common/FFT.cpp',
'src/common/Log.cpp',
'src/common/Profiler.cpp', 'src/common/Profiler.cpp',
'src/common/Resampler.cpp', 'src/common/Resampler.cpp',
'src/common/FFT.cpp',
'src/common/Allocators.cpp',
'src/common/StretchCalculator.cpp', 'src/common/StretchCalculator.cpp',
'src/common/sysutils.cpp', 'src/common/sysutils.cpp',
'src/common/Thread.cpp', 'src/common/Thread.cpp',

View File

@@ -37,6 +37,8 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <string>
#include <memory>
#include <cstddef> #include <cstddef>
/** /**
@@ -277,7 +279,6 @@ public:
* provided for backward compatibility only. They are ignored by * provided for backward compatibility only. They are ignored by
* the stretcher. * the stretcher.
*/ */
enum Option { enum Option {
OptionProcessOffline = 0x00000000, OptionProcessOffline = 0x00000000,
@@ -331,6 +332,13 @@ public:
PercussiveOptions = 0x00102000 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 * Construct a time and pitch stretcher object to run at the given
* sample rate, with the given number of channels. * sample rate, with the given number of channels.
@@ -361,6 +369,30 @@ public:
Options options = DefaultOptions, Options options = DefaultOptions,
double initialTimeRatio = 1.0, double initialTimeRatio = 1.0,
double initialPitchScale = 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> logger,
Options options = DefaultOptions,
double initialTimeRatio = 1.0,
double initialPitchScale = 1.0);
~RubberBandStretcher(); ~RubberBandStretcher();
/** /**

View File

@@ -31,17 +31,38 @@ class RubberBandStretcher::Impl
R2Stretcher *m_r2; R2Stretcher *m_r2;
R3Stretcher *m_r3; R3Stretcher *m_r3;
Log makeRBLog(std::shared_ptr<RubberBandStretcher::Logger> 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: public:
Impl(size_t sampleRate, size_t channels, Options options, Impl(size_t sampleRate, size_t channels, Options options,
std::shared_ptr<RubberBandStretcher::Logger> logger,
double initialTimeRatio, double initialPitchScale) : double initialTimeRatio, double initialPitchScale) :
m_r2 (!(options & OptionEngineFiner) ? m_r2 (!(options & OptionEngineFiner) ?
new R2Stretcher(sampleRate, channels, options, new R2Stretcher(sampleRate, channels, options,
initialTimeRatio, initialPitchScale) initialTimeRatio, initialPitchScale,
makeRBLog(logger))
: nullptr), : nullptr),
m_r3 ((options & OptionEngineFiner) ? m_r3 ((options & OptionEngineFiner) ?
new R3Stretcher(R3Stretcher::Parameters new R3Stretcher(R3Stretcher::Parameters
(double(sampleRate), channels, options), (double(sampleRate), channels, options),
initialTimeRatio, initialPitchScale) initialTimeRatio, initialPitchScale,
makeRBLog(logger))
: nullptr) : nullptr)
{ {
} }
@@ -272,13 +293,14 @@ public:
setDebugLevel(int level) setDebugLevel(int level)
{ {
if (m_r2) m_r2->setDebugLevel(level); if (m_r2) m_r2->setDebugLevel(level);
else m_r3->setDebugLevel(level);
} }
static void static void
setDefaultDebugLevel(int level) setDefaultDebugLevel(int level)
{ {
R2Stretcher::setDefaultDebugLevel(level); Log::setDefaultDebugLevel(level);
//!!! R3Stretcher::setDefaultDebugLevel(level); R2Stretcher::setDefaultDebugLevel(level); //!!!
} }
}; };
@@ -287,7 +309,18 @@ RubberBandStretcher::RubberBandStretcher(size_t sampleRate,
Options options, Options options,
double initialTimeRatio, double initialTimeRatio,
double initialPitchScale) : 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> logger,
Options options,
double initialTimeRatio,
double initialPitchScale) :
m_d(new Impl(sampleRate, channels, options, logger,
initialTimeRatio, initialPitchScale)) initialTimeRatio, initialPitchScale))
{ {
} }

99
src/common/Log.h Normal file
View File

@@ -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 <functional>
#include <iostream>
namespace RubberBand {
class Log {
public:
Log(std::function<void(const char *)> _log0,
std::function<void(const char *, double)> _log1,
std::function<void(const char *, double, double)> _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<void(const char *)> m_log0;
std::function<void(const char *, double)> m_log1;
std::function<void(const char *, double, double)> m_log2;
int m_debugLevel;
static int m_defaultDebugLevel;
};
}
#endif

View File

@@ -37,7 +37,8 @@ namespace RubberBand
StretchCalculator::StretchCalculator(size_t sampleRate, StretchCalculator::StretchCalculator(size_t sampleRate,
size_t inputIncrement, size_t inputIncrement,
bool useHardPeaks) : bool useHardPeaks,
Log log) :
m_sampleRate(sampleRate), m_sampleRate(sampleRate),
m_increment(inputIncrement), m_increment(inputIncrement),
m_prevDf(0), m_prevDf(0),
@@ -49,7 +50,8 @@ StretchCalculator::StretchCalculator(size_t sampleRate,
m_useHardPeaks(useHardPeaks), m_useHardPeaks(useHardPeaks),
m_inFrameCounter(0), m_inFrameCounter(0),
m_frameCheckpoint(0, 0), m_frameCheckpoint(0, 0),
m_outFrameCounter(0) m_outFrameCounter(0),
m_log(log)
{ {
// std::cerr << "StretchCalculator::StretchCalculator: useHardPeaks = " << useHardPeaks << std::endl; // std::cerr << "StretchCalculator::StretchCalculator: useHardPeaks = " << useHardPeaks << std::endl;
} }

View File

@@ -30,13 +30,18 @@
#include <map> #include <map>
#include <cstdint> #include <cstdint>
#include "Log.h"
namespace RubberBand namespace RubberBand
{ {
class StretchCalculator class StretchCalculator
{ {
public: public:
StretchCalculator(size_t sampleRate, size_t inputIncrement, bool useHardPeaks); StretchCalculator(size_t sampleRate,
size_t inputIncrement,
bool useHardPeaks,
Log log);
virtual ~StretchCalculator(); virtual ~StretchCalculator();
/** /**
@@ -107,6 +112,7 @@ protected:
std::pair<int64_t, int64_t> m_frameCheckpoint; std::pair<int64_t, int64_t> m_frameCheckpoint;
int64_t expectedOutFrame(int64_t inFrame, double timeRatio); int64_t expectedOutFrame(int64_t inFrame, double timeRatio);
double m_outFrameCounter; double m_outFrameCounter;
Log m_log;
std::map<size_t, size_t> m_keyFrameMap; std::map<size_t, size_t> m_keyFrameMap;
std::vector<Peak> m_peaks; std::vector<Peak> m_peaks;

View File

@@ -65,7 +65,8 @@ R2Stretcher::R2Stretcher(size_t sampleRate,
size_t channels, size_t channels,
RubberBandStretcher::Options options, RubberBandStretcher::Options options,
double initialTimeRatio, double initialTimeRatio,
double initialPitchScale) : double initialPitchScale,
Log log) :
m_sampleRate(sampleRate), m_sampleRate(sampleRate),
m_channels(channels), m_channels(channels),
m_timeRatio(initialTimeRatio), m_timeRatio(initialTimeRatio),
@@ -82,6 +83,7 @@ R2Stretcher::R2Stretcher(size_t sampleRate,
#endif #endif
m_realtime(false), m_realtime(false),
m_options(options), m_options(options),
m_log(log),
m_debugLevel(m_defaultDebugLevel), m_debugLevel(m_defaultDebugLevel),
m_mode(JustCreated), m_mode(JustCreated),
m_awindow(0), m_awindow(0),
@@ -700,7 +702,8 @@ R2Stretcher::configure()
delete m_stretchCalculator; delete m_stretchCalculator;
m_stretchCalculator = new StretchCalculator m_stretchCalculator = new StretchCalculator
(m_sampleRate, m_increment, (m_sampleRate, m_increment,
!(m_options & RubberBandStretcher::OptionTransientsSmooth)); !(m_options & RubberBandStretcher::OptionTransientsSmooth),
m_log);
m_stretchCalculator->setDebugLevel(m_debugLevel); m_stretchCalculator->setDebugLevel(m_debugLevel);
m_inputDuration = 0; m_inputDuration = 0;

View File

@@ -31,6 +31,7 @@
#include "../common/RingBuffer.h" #include "../common/RingBuffer.h"
#include "../common/Scavenger.h" #include "../common/Scavenger.h"
#include "../common/Thread.h" #include "../common/Thread.h"
#include "../common/Log.h"
#include "../common/sysutils.h" #include "../common/sysutils.h"
#include "SincWindow.h" #include "SincWindow.h"
@@ -50,7 +51,8 @@ class R2Stretcher
public: public:
R2Stretcher(size_t sampleRate, size_t channels, R2Stretcher(size_t sampleRate, size_t channels,
RubberBandStretcher::Options options, RubberBandStretcher::Options options,
double initialTimeRatio, double initialPitchScale); double initialTimeRatio, double initialPitchScale,
Log log);
~R2Stretcher(); ~R2Stretcher();
void reset(); void reset();
@@ -174,7 +176,8 @@ protected:
bool m_realtime; bool m_realtime;
RubberBandStretcher::Options m_options; RubberBandStretcher::Options m_options;
int m_debugLevel; Log m_log;
int m_debugLevel; //!!! to go once Log switch complete
enum ProcessMode { enum ProcessMode {
JustCreated, JustCreated,
@@ -251,7 +254,7 @@ protected:
void writeOutput(RingBuffer<float> &to, float *from, void writeOutput(RingBuffer<float> &to, float *from,
size_t qty, size_t &outCount, size_t theoreticalOut); 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_defaultIncrement;
static const size_t m_defaultFftSize; static const size_t m_defaultFftSize;
}; };

View File

@@ -24,6 +24,8 @@
#ifndef RUBBERBAND_GUIDE_H #ifndef RUBBERBAND_GUIDE_H
#define RUBBERBAND_GUIDE_H #define RUBBERBAND_GUIDE_H
#include "../common/Log.h"
#include <functional> #include <functional>
#include <sstream> #include <sstream>
@@ -102,15 +104,12 @@ public:
struct Parameters { struct Parameters {
double sampleRate; double sampleRate;
std::function<void(const std::string &)> logger; Parameters(double _sampleRate) : sampleRate(_sampleRate) { }
Parameters(double _sampleRate,
std::function<void(const std::string &)> _log) :
sampleRate(_sampleRate),
logger(_log) { }
}; };
Guide(Parameters parameters) : Guide(Parameters parameters, Log log) :
m_parameters(parameters), m_parameters(parameters),
m_log(log),
m_configuration(roundUp(int(ceil(parameters.sampleRate / 16.0))), m_configuration(roundUp(int(ceil(parameters.sampleRate / 16.0))),
roundUp(int(ceil(parameters.sampleRate / 64.0))), roundUp(int(ceil(parameters.sampleRate / 64.0))),
roundUp(int(ceil(parameters.sampleRate / 32.0)))), roundUp(int(ceil(parameters.sampleRate / 32.0)))),
@@ -334,6 +333,7 @@ public:
protected: protected:
Parameters m_parameters; Parameters m_parameters;
Log m_log;
Configuration m_configuration; Configuration m_configuration;
double m_minLower; double m_minLower;

View File

@@ -26,6 +26,7 @@
#include "Guide.h" #include "Guide.h"
#include "../common/Log.h"
#include "../common/mathmisc.h" #include "../common/mathmisc.h"
#include <sstream> #include <sstream>
@@ -41,15 +42,13 @@ public:
int fftSize; int fftSize;
double sampleRate; double sampleRate;
int channels; int channels;
std::function<void(const std::string &)> logger; Parameters(int _fftSize, double _sampleRate, int _channels) :
Parameters(int _fftSize, double _sampleRate, int _channels, fftSize(_fftSize), sampleRate(_sampleRate), channels(_channels) { }
std::function<void(const std::string &)> _log) :
fftSize(_fftSize), sampleRate(_sampleRate),
channels(_channels), logger(_log) { }
}; };
GuidedPhaseAdvance(Parameters parameters) : GuidedPhaseAdvance(Parameters parameters, Log log) :
m_parameters(parameters), m_parameters(parameters),
m_log(log),
m_binCount(parameters.fftSize / 2 + 1), m_binCount(parameters.fftSize / 2 + 1),
m_peakPicker(m_binCount), m_peakPicker(m_binCount),
m_reported(false) { m_reported(false) {
@@ -111,7 +110,7 @@ public:
int lowest = configuration.fftBandLimits[myFftBand].b0min; int lowest = configuration.fftBandLimits[myFftBand].b0min;
int highest = configuration.fftBandLimits[myFftBand].b1max; int highest = configuration.fftBandLimits[myFftBand].b1max;
if (!m_reported) { if (m_log.getDebugLevel() > 0 && !m_reported) {
std::ostringstream ostr; std::ostringstream ostr;
ostr << "PhaseAdvance: fftSize = " << m_parameters.fftSize ostr << "PhaseAdvance: fftSize = " << m_parameters.fftSize
<< ": bins = " << bs << ", channels = " << channels << ": bins = " << bs << ", channels = " << channels
@@ -122,7 +121,7 @@ public:
<< "Hz), highest = " << highest << "Hz), highest = " << highest
<< " (" << configuration.fftBandLimits[myFftBand].f1max << " (" << configuration.fftBandLimits[myFftBand].f1max
<< "Hz)" << std::endl; << "Hz)" << std::endl;
m_parameters.logger(ostr.str()); m_log.log0(1, ostr.str().c_str());
m_reported = true; m_reported = true;
} }
@@ -231,8 +230,13 @@ public:
} }
} }
void setDebugLevel(int debugLevel) {
m_log.setDebugLevel(debugLevel);
}
protected: protected:
Parameters m_parameters; Parameters m_parameters;
Log m_log;
int m_binCount; int m_binCount;
Peak<double> m_peakPicker; Peak<double> m_peakPicker;
int **m_currentPeaks; int **m_currentPeaks;

View File

@@ -31,12 +31,14 @@ namespace RubberBand {
R3Stretcher::R3Stretcher(Parameters parameters, R3Stretcher::R3Stretcher(Parameters parameters,
double initialTimeRatio, double initialTimeRatio,
double initialPitchScale) : double initialPitchScale,
Log log) :
m_parameters(parameters), m_parameters(parameters),
m_log(log),
m_timeRatio(initialTimeRatio), m_timeRatio(initialTimeRatio),
m_pitchScale(initialPitchScale), m_pitchScale(initialPitchScale),
m_formantScale(0.0), 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_guideConfiguration(m_guide.getConfiguration()),
m_channelAssembly(m_parameters.channels), m_channelAssembly(m_parameters.channels),
m_inhop(1), m_inhop(1),
@@ -87,14 +89,15 @@ R3Stretcher::R3Stretcher(Parameters parameters,
for (auto band: m_guideConfiguration.fftBandLimits) { for (auto band: m_guideConfiguration.fftBandLimits) {
int fftSize = band.fftSize; int fftSize = band.fftSize;
GuidedPhaseAdvance::Parameters guidedParameters GuidedPhaseAdvance::Parameters guidedParameters
(fftSize, m_parameters.sampleRate, m_parameters.channels, (fftSize, m_parameters.sampleRate, m_parameters.channels);
m_parameters.logger); m_scaleData[fftSize] = std::make_shared<ScaleData>(guidedParameters,
m_scaleData[fftSize] = std::make_shared<ScaleData>(guidedParameters); m_log);
} }
m_calculator = std::unique_ptr<StretchCalculator> m_calculator = std::unique_ptr<StretchCalculator>
(new StretchCalculator(int(round(m_parameters.sampleRate)), //!!! which is a double... (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; Resampler::Parameters resamplerParameters;
resamplerParameters.quality = Resampler::FastestTolerable; resamplerParameters.quality = Resampler::FastestTolerable;
@@ -119,10 +122,10 @@ R3Stretcher::R3Stretcher(Parameters parameters,
m_prevOuthop = int(round(m_inhop * getEffectiveRatio())); m_prevOuthop = int(round(m_inhop * getEffectiveRatio()));
if (!m_inhop.is_lock_free()) { if (!m_inhop.is_lock_free()) {
m_parameters.logger("WARNING: std::atomic<int> is not lock-free"); m_log.log0(0, "WARNING: std::atomic<int> is not lock-free");
} }
if (!m_timeRatio.is_lock_free()) { if (!m_timeRatio.is_lock_free()) {
m_parameters.logger("WARNING: std::atomic<double> is not lock-free"); m_log.log0(0, "WARNING: std::atomic<double> is not lock-free");
} }
// Pad to half of the longest frame. As with R2, in real-time mode // Pad to half of the longest frame. As with R2, in real-time mode
@@ -131,7 +134,7 @@ R3Stretcher::R3Stretcher(Parameters parameters,
// changes. // changes.
if (!isRealTime()) { if (!isRealTime()) {
m_parameters.logger("Offline mode: pre-padding"); m_log.log0(1, "Offline mode: pre-padding");
int pad = m_guideConfiguration.longestFftSize / 2; int pad = m_guideConfiguration.longestFftSize / 2;
for (int c = 0; c < m_parameters.channels; ++c) { for (int c = 0; c < m_parameters.channels; ++c) {
m_channelData[c]->inbuf->zero(pad); 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 // By the time we skip this later we will have resampled
m_startSkip = int(round(pad / m_pitchScale)); m_startSkip = int(round(pad / m_pitchScale));
} else { } 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 (!isRealTime()) {
if (m_mode == ProcessMode::Studying || if (m_mode == ProcessMode::Studying ||
m_mode == ProcessMode::Processing) { 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; return;
} }
} }
@@ -192,7 +195,7 @@ R3Stretcher::setPitchScale(double scale)
if (!isRealTime()) { if (!isRealTime()) {
if (m_mode == ProcessMode::Studying || if (m_mode == ProcessMode::Studying ||
m_mode == ProcessMode::Processing) { 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; return;
} }
} }
@@ -208,7 +211,7 @@ R3Stretcher::setFormantScale(double scale)
if (!isRealTime()) { if (!isRealTime()) {
if (m_mode == ProcessMode::Studying || if (m_mode == ProcessMode::Studying ||
m_mode == ProcessMode::Processing) { 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; return;
} }
} }
@@ -230,11 +233,11 @@ void
R3Stretcher::setKeyFrameMap(const std::map<size_t, size_t> &mapping) R3Stretcher::setKeyFrameMap(const std::map<size_t, size_t> &mapping)
{ {
if (isRealTime()) { 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; return;
} }
if (m_mode == ProcessMode::Processing || m_mode == ProcessMode::Finished) { 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; return;
} }
@@ -266,22 +269,21 @@ R3Stretcher::calculateHop()
if (proposedOuthop > 512.0) proposedOuthop = 512.0; if (proposedOuthop > 512.0) proposedOuthop = 512.0;
if (proposedOuthop < 128.0) proposedOuthop = 128.0; if (proposedOuthop < 128.0) proposedOuthop = 128.0;
std::cout << "calculateHop: for ratio " << ratio << " proposedOuthop = " m_log.log2(1, "calculateHop: ratio and proposed outhop", ratio, proposedOuthop);
<< proposedOuthop << std::endl;
double inhop = proposedOuthop / ratio; double inhop = proposedOuthop / ratio;
if (inhop < 1.0) { 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; inhop = 1.0;
} }
if (inhop > 768.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; inhop = 768.0;
} }
m_inhop = int(floor(inhop)); 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 void
@@ -409,12 +411,12 @@ void
R3Stretcher::study(const float *const *, size_t samples, bool) R3Stretcher::study(const float *const *, size_t samples, bool)
{ {
if (isRealTime()) { if (isRealTime()) {
m_parameters.logger("R3Stretcher::study: Not meaningful in realtime mode"); m_log.log0(0, "R3Stretcher::study: Not meaningful in realtime mode");
return; return;
} }
if (m_mode == ProcessMode::Processing || m_mode == ProcessMode::Finished) { 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; return;
} }
@@ -443,7 +445,7 @@ void
R3Stretcher::process(const float *const *input, size_t samples, bool final) R3Stretcher::process(const float *const *input, size_t samples, bool final)
{ {
if (m_mode == ProcessMode::Finished) { 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; return;
} }
@@ -468,7 +470,7 @@ R3Stretcher::process(const float *const *input, size_t samples, bool final)
size_t ws = m_channelData[0]->inbuf->getWriteSpace(); size_t ws = m_channelData[0]->inbuf->getWriteSpace();
if (samples > ws) { if (samples > ws) {
//!!! check this //!!! 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; size_t newSize = m_channelData[0]->inbuf->getSize() - ws + samples;
for (int c = 0; c < m_parameters.channels; ++c) { for (int c = 0; c < m_parameters.channels; ++c) {
auto newBuf = m_channelData[c]->inbuf->resized(newSize); 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); int gotHere = m_channelData[c]->outbuf->read(output[c], got);
if (gotHere < got) { if (gotHere < got) {
if (c > 0) { 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)); got = std::min(got, std::max(gotHere, 0));
} }

View File

@@ -36,12 +36,12 @@
#include "../common/Allocators.h" #include "../common/Allocators.h"
#include "../common/Window.h" #include "../common/Window.h"
#include "../common/VectorOpsComplex.h" #include "../common/VectorOpsComplex.h"
#include "../common/Log.h"
#include "../../rubberband/RubberBandStretcher.h" #include "../../rubberband/RubberBandStretcher.h"
#include <map> #include <map>
#include <memory> #include <memory>
#include <functional>
namespace RubberBand namespace RubberBand
{ {
@@ -53,17 +53,15 @@ public:
double sampleRate; double sampleRate;
int channels; int channels;
RubberBandStretcher::Options options; RubberBandStretcher::Options options;
std::function<void(const std::string &)> logger;
Parameters(double _sampleRate, int _channels, Parameters(double _sampleRate, int _channels,
RubberBandStretcher::Options _options, RubberBandStretcher::Options _options) :
std::function<void(const std::string &)> _log = &logCout) : sampleRate(_sampleRate), channels(_channels), options(_options) { }
sampleRate(_sampleRate), channels(_channels), options(_options),
logger(_log) { }
}; };
R3Stretcher(Parameters parameters, R3Stretcher(Parameters parameters,
double initialTimeRatio, double initialTimeRatio,
double initialPitchScale); double initialPitchScale,
Log log);
~R3Stretcher() { } ~R3Stretcher() { }
void reset(); void reset();
@@ -89,6 +87,10 @@ public:
size_t getLatency() const; size_t getLatency() const;
size_t getChannelCount() const; size_t getChannelCount() const;
void setDebugLevel(int level) {
m_log.setDebugLevel(level); //!!! +others
}
protected: protected:
struct ClassificationReadaheadData { struct ClassificationReadaheadData {
FixedVector<double> timeDomain; FixedVector<double> timeDomain;
@@ -242,7 +244,8 @@ protected:
Window<double> synthesisWindow; Window<double> synthesisWindow;
double windowScaleFactor; double windowScaleFactor;
GuidedPhaseAdvance guided; GuidedPhaseAdvance guided;
ScaleData(GuidedPhaseAdvance::Parameters guidedParameters) : ScaleData(GuidedPhaseAdvance::Parameters guidedParameters,
Log log) :
fftSize(guidedParameters.fftSize), fftSize(guidedParameters.fftSize),
fft(fftSize), fft(fftSize),
analysisWindow(analysisWindowShape(fftSize), analysisWindow(analysisWindowShape(fftSize),
@@ -250,7 +253,7 @@ protected:
synthesisWindow(synthesisWindowShape(fftSize), synthesisWindow(synthesisWindowShape(fftSize),
synthesisWindowLength(fftSize)), synthesisWindowLength(fftSize)),
windowScaleFactor(0.0), windowScaleFactor(0.0),
guided(guidedParameters) guided(guidedParameters, log)
{ {
int asz = analysisWindow.getSize(), ssz = synthesisWindow.getSize(); int asz = analysisWindow.getSize(), ssz = synthesisWindow.getSize();
int off = (asz - ssz) / 2; int off = (asz - ssz) / 2;
@@ -267,6 +270,7 @@ protected:
}; };
Parameters m_parameters; Parameters m_parameters;
Log m_log;
std::atomic<double> m_timeRatio; std::atomic<double> m_timeRatio;
std::atomic<double> m_pitchScale; std::atomic<double> m_pitchScale;
@@ -347,10 +351,6 @@ protected:
return m_parameters.options & return m_parameters.options &
RubberBandStretcher::OptionProcessRealTime; RubberBandStretcher::OptionProcessRealTime;
} }
static void logCout(const std::string &message) {
std::cout << "RubberBandStretcher: " << message << std::endl;
}
}; };
} }

View File

@@ -463,7 +463,9 @@ RubberBandVampPlugin::Impl::getRemainingFeaturesOffline()
int rate = m_sampleRate; 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(); size_t inputIncrement = m_stretcher->getInputIncrement();
std::vector<int> outputIncrements = m_stretcher->getOutputIncrements(); std::vector<int> outputIncrements = m_stretcher->getOutputIncrements();