diff --git a/src/AudioProcessor.cpp b/src/AudioProcessor.cpp index 86e433c..f13dcaf 100644 --- a/src/AudioProcessor.cpp +++ b/src/AudioProcessor.cpp @@ -1,6 +1,7 @@ #include "AudioProcessor.h" #include "SpeexDSP.h" +#include "Timer.h" #include "WebRTCDSP.h" #include @@ -9,7 +10,7 @@ namespace SpeexWebRTCTest { namespace { -Q_LOGGING_CATEGORY(AudioProcessor, "processor") +Q_LOGGING_CATEGORY(processor, "processor") } QVector calculateAudioLevels(const QAudioBuffer& buffer); @@ -130,6 +131,8 @@ void AudioProcessor::process() void AudioProcessor::processBuffer(QAudioBuffer& inputBuffer, const QAudioBuffer& monitorBuffer) { + TIMER(qDebug(processor)) + QVector inputLevels = calculateAudioLevels(inputBuffer); if (dsp_) diff --git a/src/SpeexDSP.cpp b/src/SpeexDSP.cpp index fc2a547..9ab969e 100644 --- a/src/SpeexDSP.cpp +++ b/src/SpeexDSP.cpp @@ -1,5 +1,7 @@ #include "SpeexDSP.h" +#include "Timer.h" + #include #include @@ -36,6 +38,8 @@ SpeexDSP::~SpeexDSP() void SpeexDSP::processFrame(QAudioBuffer& mainBuffer, const QAudioBuffer& auxBuffer) { + TIMER(qDebug(Speex)) + qDebug(Speex).noquote() << QString( "got %1 near-end samples (%2ms) and %3 far-end samples (%4ms)") .arg(mainBuffer.frameCount()) diff --git a/src/Timer.h b/src/Timer.h new file mode 100644 index 0000000..03d96e5 --- /dev/null +++ b/src/Timer.h @@ -0,0 +1,144 @@ +#ifndef _SPEEX_WEBRTC_TEST_TIMER_H_ +#define _SPEEX_WEBRTC_TEST_TIMER_H_ + +#include + +#include +#include +#include + +namespace SpeexWebRTCTest { + +namespace _detail { + +template +struct is_one_of; + +template +struct is_one_of +{ + static constexpr bool value = std::is_same::value; +}; + +template +struct is_one_of +{ + static constexpr bool value = std::is_same::value || is_one_of::value; +}; + + +template ::value>::type> +constexpr const char* duration_suffix() +{ + if (std::is_same::value) + { + return "h"; + } + else if (std::is_same::value) + { + return "min"; + } + else if (std::is_same::value) + { + return "s"; + } + else if (std::is_same::value) + { + return "ms"; + } + else if (std::is_same::value) + { + return "us"; + } + else if (std::is_same::value) + { + return "ns"; + } + return ""; +} + +template +std::string format_impl(DurationIn) +{ + return {}; +} + +template +std::string format_impl(DurationIn d) +{ + std::string out; + + auto val = std::chrono::duration_cast(d); + if (val.count() != 0) + { + out = std::to_string(val.count()) + duration_suffix(); + + if (sizeof...(RestDurations) > 0) + { + out += " " + format_impl(d - val); + } + } + else + { + if (sizeof...(RestDurations) > 0) + { + out = format_impl(d); + } + else if (count == 0) + { + out = std::to_string(0) + duration_suffix(); + } + } + + return out; +} + +} // namespace _detail + +template +std::string format(DurationIn d) +{ + return _detail::format_impl<0, DurationIn, RestDurations...>(d); +} + +template +class Timer final +{ +public: + explicit Timer(const QDebug& debug, QString name = "") : debug_(debug), name_(std::move(name)) + { + start_ = std::chrono::high_resolution_clock::now(); + } + + ~Timer() + { + TimePoint stop = std::chrono::high_resolution_clock::now(); + if (name_.isEmpty()) + debug_.nospace().noquote() << "Timer: " << format(stop - start_).c_str(); + else + debug_.nospace().noquote() + << "Timer [" << name_ << "]: " << format(stop - start_).c_str(); + } + +private: + using TimePoint = std::chrono::time_point; + QDebug debug_; + QString name_; + TimePoint start_; +}; + +using MsTimer = Timer; + +} // namespace SpeexWebRTCTest + +#define TIMER(debug) MsTimer timer(debug, __func__); + +#endif //_SPEEX_WEBRTC_TEST_TIMER_H_ diff --git a/src/WebRTCDSP.cpp b/src/WebRTCDSP.cpp index ca745b4..c9ae6ab 100644 --- a/src/WebRTCDSP.cpp +++ b/src/WebRTCDSP.cpp @@ -1,5 +1,7 @@ #include "WebRTCDSP.h" +#include "Timer.h" + #include #include @@ -113,6 +115,8 @@ QString errorDescription(int error) void WebRTCDSP::processFrame(QAudioBuffer& mainBuffer, const QAudioBuffer& auxBuffer) { + TIMER(qDebug(WebRTC)) + qDebug(WebRTC).noquote() << QString( "got %1 near-end samples at %2 Hz (%3ms) and %4 far-end " "samples at %5 (%6ms)")