From 308a53c389cdc2631860f434989cd57efbf91145 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sun, 17 Feb 2019 14:53:33 +0100 Subject: Implemented Tuner --- tuner.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'tuner.cpp') diff --git a/tuner.cpp b/tuner.cpp index d1833a3..3013390 100644 --- a/tuner.cpp +++ b/tuner.cpp @@ -2,12 +2,19 @@ #include "autocorrelation.h" #include "fft.h" +#include "util.h" + +#include +#include + +using namespace RIT; struct RIT::Tuner::Impl { public: - Impl(int size, int f_sample): mAC(size), m_f_sample(f_sample) {} + Impl(int size, int f_sample): mAC(size), m_f_sample(f_sample), mSize(size) {} RIT::AutoCorrelation mAC; int m_f_sample; + int mSize; }; RIT::Tuner::Tuner(int size, int f_sample): mImpl(std::make_unique(size, f_sample)) @@ -16,9 +23,36 @@ RIT::Tuner::Tuner(int size, int f_sample): mImpl(std::make_unique noteNames{ "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" }; + const double base = std::pow(2.0, 1./12); + + RIT::Pitch getPitch(double f) + { + double noteIndexD = std::log(f / 110.0) / std::log(base) + 0.5; + + double noteIndexI{}; + double deviation = std::modf(noteIndexD, ¬eIndexI) - 0.5; + int noteIndex = int(noteIndexI); + + noteIndex %= 12; + + return RIT::Pitch {f, deviation, noteNames[noteIndex]}; + } +} + RIT::Pitch RIT::Tuner::operator() (const std::vector> &v) { - std::vector> autoCorrelation = mImpl->mAC(v); + std::vector autoCorrelation = magnitudes(mImpl->mAC(v)); + + auto maxElement = std::max_element(std::begin(autoCorrelation) + 1, std::begin(autoCorrelation) + mImpl->mSize / 2); + + int index = maxElement - std::begin(autoCorrelation); + + if (autoCorrelation[index] > autoCorrelation[index - 1] && autoCorrelation[index] > autoCorrelation[index + 1]) { + double f = double(mImpl->m_f_sample) / index; + return getPitch(f); + } - return Pitch(); + return Pitch{}; } -- cgit v1.2.3