diff options
author | Roland Stigge <stigge@antcom.de> | 2019-02-17 12:55:13 +0100 |
---|---|---|
committer | Roland Stigge <stigge@antcom.de> | 2019-02-17 12:55:13 +0100 |
commit | fef594c82518a8fe4c96794852c1fc849c0ed3b3 (patch) | |
tree | 2efbedc8b126a77d91633ce8b9201dc4a7db764c | |
parent | 1a219839034e9b11a4771fb84c90d4a2667365ce (diff) |
Added tunerdemo
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 29 | ||||
-rw-r--r-- | autocorrelation.cpp | 29 | ||||
-rw-r--r-- | autocorrelation.h | 20 | ||||
-rw-r--r-- | fft.cpp | 26 | ||||
-rw-r--r-- | fft.h | 11 | ||||
-rw-r--r-- | testsuite.cpp (renamed from main.cpp) | 23 | ||||
-rw-r--r-- | tuner.cpp | 24 | ||||
-rw-r--r-- | tuner.h | 28 | ||||
-rw-r--r-- | tunerdemo.cpp | 35 |
10 files changed, 180 insertions, 48 deletions
@@ -1,2 +1,3 @@ *.o -fft +tunerdemo +testsuite @@ -7,20 +7,39 @@ CXXFLAGS=-stdlib=libc++ -Wall -O2 -std=c++17 #CXXFLAGS=-Wall -O2 -std=c++17 -nostdinc++ -I/usr/lib/llvm-7/include/c++/v1 -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc # -march=native -mtune=native # doesn't help for gcc -all: fft +DESTDIR=/ +PREFIX=/usr/local/bin -fft: fft.o main.o +all: tunerdemo testsuite + +tunerdemo: fft.o autocorrelation.o tuner.o tunerdemo.o + $(CXX) $(CXXFLAGS) -o $@ $^ + +testsuite: fft.o autocorrelation.o tuner.o testsuite.o $(CXX) $(CXXFLAGS) -o $@ $^ fft.o: fft.cpp fft.h $(CXX) $(CXXFLAGS) -c -o $@ $< -main.o: main.cpp fft.h +autocorrelation.o: autocorrelation.cpp autocorrelation.h + $(CXX) $(CXXFLAGS) -c -o $@ $< + +tuner.o: tuner.cpp tuner.h $(CXX) $(CXXFLAGS) -c -o $@ $< +testsuite.o: testsuite.cpp fft.h autocorrelation.h tuner.h + $(CXX) $(CXXFLAGS) -c -o $@ $< + +tunerdemo.o: tunerdemo.cpp fft.h autocorrelation.h tuner.h + $(CXX) $(CXXFLAGS) -c -o $@ $< + +test: testsuite + ./testsuite + install: + install tunerdemo $(DESTDIR)/$(PREFIX)/tunerdemo clean: - rm -f fft *.o + rm -f tunerdemo *.o -.PHONY: clean +.PHONY: clean install all test diff --git a/autocorrelation.cpp b/autocorrelation.cpp new file mode 100644 index 0000000..5c778c1 --- /dev/null +++ b/autocorrelation.cpp @@ -0,0 +1,29 @@ +#include "autocorrelation.h" + +#include "fft.h" + +struct RIT::AutoCorrelation::Impl { +public: + Impl(int size): mFft(std::make_shared<RIT::FFT>(size)), mIfft(mFft) {} + std::shared_ptr<RIT::FFT> mFft; + RIT::IFFT mIfft; +}; + +RIT::AutoCorrelation::AutoCorrelation(int size): mImpl(std::make_unique<RIT::AutoCorrelation::Impl>(size)) +{ +} + +RIT::AutoCorrelation::~AutoCorrelation() +{ +} + +std::vector<std::complex<double>> RIT::AutoCorrelation::operator()(const std::vector<std::complex<double>> &v) const +{ + auto result = (*mImpl->mFft)(v); + + std::transform(std::begin(result), std::end(result), std::begin(result), + [=](const auto& x){return x * std::conj(x);}); + + return mImpl->mIfft(result); +} + diff --git a/autocorrelation.h b/autocorrelation.h new file mode 100644 index 0000000..3be0802 --- /dev/null +++ b/autocorrelation.h @@ -0,0 +1,20 @@ +#pragma once + +#include <complex> +#include <memory> +#include <vector> + +namespace RIT { + +class AutoCorrelation { +public: + AutoCorrelation(int size); + ~AutoCorrelation(); + std::vector<std::complex<double>> operator()(const std::vector<std::complex<double>> &v) const; + +private: + struct Impl; + std::unique_ptr<Impl> mImpl; +}; // class AutoCorrelation + +} // namespace RIT @@ -42,7 +42,6 @@ RIT::FFT::FFT(int size, bool halfOnly): mSize(size), order(size), expLUT(size/2) } } - std::vector<std::complex<double>> RIT::FFT::operator()(const std::vector<std::complex<double>> &v) const { if (v.size() != mSize) throw std::length_error("Bad input size"); @@ -159,28 +158,3 @@ std::vector<std::complex<double>> RIT::IFFT::operator()(const std::vector<std::c return result; } -struct RIT::AutoCorrelation::Impl { -public: - Impl(int size): mFft(std::make_shared<RIT::FFT>(size)), mIfft(mFft) {} - std::shared_ptr<RIT::FFT> mFft; - RIT::IFFT mIfft; -}; - -RIT::AutoCorrelation::AutoCorrelation(int size): mImpl(std::make_unique<RIT::AutoCorrelation::Impl>(size)) -{ -} - -RIT::AutoCorrelation::~AutoCorrelation() -{ -} - -std::vector<std::complex<double>> RIT::AutoCorrelation::operator()(const std::vector<std::complex<double>> &v) const -{ - auto result = (*mImpl->mFft)(v); - - std::transform(std::begin(result), std::end(result), std::begin(result), - [=](const auto& x){return x * std::conj(x);}); - - return mImpl->mIfft(result); -} - @@ -44,17 +44,6 @@ private: std::unique_ptr<Impl> mImpl; }; // class IFFT -class AutoCorrelation { -public: - AutoCorrelation(int size); - ~AutoCorrelation(); - std::vector<std::complex<double>> operator()(const std::vector<std::complex<double>> &v) const; - -private: - struct Impl; - std::unique_ptr<Impl> mImpl; -}; // class AutoCorrelation - std::vector<double> magnitudes(std::vector<std::complex<double>>& v); } // namespace RIT @@ -1,6 +1,8 @@ // FFT Test #include "fft.h" +#include "autocorrelation.h" +#include "tuner.h" #include <complex> #include <chrono> @@ -236,6 +238,16 @@ public: } }; +class MeasureTuner_RR: public Measure { + RIT::Tuner mTuner; + RIT::Pitch mPitch; +public: + MeasureTuner_RR(const Data& in): Measure(in), mTuner(in.size(), 44100) { mName = "Tuner RR";} + void run_impl() override { + mPitch = mTuner(mIn); + } +}; + int main(int argc, char* argv[]) { std::vector<std::complex<double>> v(4096, 0); @@ -254,17 +266,18 @@ int main(int argc, char* argv[]) { MeasureFFT_RR_half measureFFT_RR_half(v, measureFFT_RR); measureFFT_RR_half.run(); - + MeasureFFT_RR_half_magnitudes measureFFT_RR_half_magnitudes(v, measureDFT); measureFFT_RR_half_magnitudes.run(); MeasureIFFT_RR measureIFFT_RR(v); measureIFFT_RR.run(); - + MeasureAutoCorrelation_RR measureAutoCorrelation_RR(v); measureAutoCorrelation_RR.run(); - - return 0; -} + MeasureTuner_RR measureTuner_RR(v); + measureTuner_RR.run(); + return 0; +} diff --git a/tuner.cpp b/tuner.cpp new file mode 100644 index 0000000..d1833a3 --- /dev/null +++ b/tuner.cpp @@ -0,0 +1,24 @@ +#include "tuner.h" + +#include "autocorrelation.h" +#include "fft.h" + +struct RIT::Tuner::Impl { +public: + Impl(int size, int f_sample): mAC(size), m_f_sample(f_sample) {} + RIT::AutoCorrelation mAC; + int m_f_sample; +}; + +RIT::Tuner::Tuner(int size, int f_sample): mImpl(std::make_unique<RIT::Tuner::Impl>(size, f_sample)) +{ +} + +RIT::Tuner::~Tuner(){} + +RIT::Pitch RIT::Tuner::operator() (const std::vector<std::complex<double>> &v) +{ + std::vector<std::complex<double>> autoCorrelation = mImpl->mAC(v); + + return Pitch(); +} @@ -0,0 +1,28 @@ +#pragma once + +#include <complex> +#include <memory> +#include <string> +#include <vector> + +namespace RIT { + +struct Pitch { + double f{}; // in Hz + double deviation{}; // 0.0 == perfect, +/-1.0: at next note + std::string name; // "" for none, "A", "A#", ... for notes +}; + +class Tuner { +public: + Tuner(int size, int f_sample); + ~Tuner(); + + Pitch operator() (const std::vector<std::complex<double>> &v); + +private: + struct Impl; + std::unique_ptr<Impl> mImpl; +}; // class Tuner + +} // namespace RIT diff --git a/tunerdemo.cpp b/tunerdemo.cpp new file mode 100644 index 0000000..716bd8e --- /dev/null +++ b/tunerdemo.cpp @@ -0,0 +1,35 @@ +#include "tuner.h" + +#include <chrono> +#include <iostream> +#include <thread> + +using namespace std::chrono_literals; + +const int sampleFrequency = 44100; +const int fftSize = 4096; + +std::vector<std::complex<double>> sample() +{ + return std::vector<std::complex<double>>(fftSize, 0.0); +} + +int main(int argc, char* argv[]) { + RIT::Tuner tuner(fftSize, sampleFrequency); + + std::vector<std::complex<double>> dataIn = sample(); + + while (true) { + auto start = std::chrono::high_resolution_clock::now(); + RIT::Pitch pitch = tuner(dataIn); + auto end = std::chrono::high_resolution_clock::now(); + std::cout << "Detected Note: " << pitch.name + << " Deviation: " << pitch.deviation + << " Frequency: " << pitch.f + << ", took " << std::chrono::nanoseconds(end - start).count() * 0.000001 << "ms" + << std::endl; + std::this_thread::sleep_until(start + 100ms); + } + + return 0; +} |