commit 081388e674a62c448c7372503b6969c309a51cdd
parent 1ea2976070eb563c7b2938486e322e0b543d5f7c
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Mon, 18 Jul 2016 16:26:32 +0300
Feature added: Fractional delay
Diffstat:
5 files changed, 90 insertions(+), 0 deletions(-)
diff --git a/include/kfr/all.hpp b/include/kfr/all.hpp
@@ -68,6 +68,7 @@
#include "data/sincos.hpp"
#include "dsp/biquad.hpp"
#include "dsp/fir.hpp"
+#include "dsp/fracdelay.hpp"
#include "dsp/goertzel.hpp"
#include "dsp/interpolation.hpp"
#include "dsp/oscillators.hpp"
diff --git a/include/kfr/dsp/fracdelay.hpp b/include/kfr/dsp/fracdelay.hpp
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
+ * This file is part of KFR
+ *
+ * KFR 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KFR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KFR.
+ *
+ * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ * Buying a commercial license is mandatory as soon as you develop commercial activities without
+ * disclosing the source code of your own applications.
+ * See http://www.kfrlib.com for details.
+ */
+#pragma once
+
+#include "fir.hpp"
+
+namespace kfr
+{
+
+namespace native
+{
+
+template <typename T, typename E1>
+KFR_INLINE internal::in_fir<>::expression_short_fir<2, T, E1> fracdelay(E1&& e1, T delay)
+{
+ if (delay < 0)
+ delay = 0;
+ if (delay > 1)
+ delay = fract(delay);
+ univector<T, 2> taps({ 1 - delay, delay });
+ return internal::in_fir<>::expression_short_fir<2, T, E1>(std::forward<E1>(e1), taps.ref());
+}
+}
+}
diff --git a/sources.cmake b/sources.cmake
@@ -57,6 +57,7 @@ set(
${PROJECT_SOURCE_DIR}/include/kfr/dsp/oscillators.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/units.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/fir.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/dsp/fracdelay.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/goertzel.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/interpolation.hpp
${PROJECT_SOURCE_DIR}/include/kfr/dsp/resample.hpp
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
@@ -27,6 +27,7 @@ include_directories(../include)
add_executable(basic_vector_test basic_vector_test.cpp ${KFR_SRC})
add_executable(dft_test dft_test.cpp ${KFR_SRC})
add_executable(conv_test conv_test.cpp ${KFR_SRC})
+add_executable(fracdelay_test fracdelay_test.cpp ${KFR_SRC})
add_executable(empty_test empty_test.cpp ${KFR_SRC})
add_executable(complex_test complex_test.cpp ${KFR_SRC})
add_executable(vec_test vec_test.cpp ${KFR_SRC})
@@ -35,6 +36,8 @@ enable_testing()
add_test(NAME dft_test
COMMAND ${PROJECT_BINARY_DIR}/tests/dft_test)
+add_test(NAME fracdelay_test
+ COMMAND ${PROJECT_BINARY_DIR}/tests/fracdelay_test)
add_test(NAME conv_test
COMMAND ${PROJECT_BINARY_DIR}/tests/conv_test)
add_test(NAME complex_test
diff --git a/tests/fracdelay_test.cpp b/tests/fracdelay_test.cpp
@@ -0,0 +1,41 @@
+/**
+ * KFR (http://kfrlib.com)
+ * Copyright (C) 2016 D Levin
+ * See LICENSE.txt for details
+ */
+
+// library_version()
+#include <kfr/io/tostring.hpp>
+#include <kfr/version.hpp>
+
+#include <kfr/expressions/reduce.hpp>
+
+#include <tuple>
+
+#include "testo/testo.hpp"
+#include <kfr/dsp/fracdelay.hpp>
+
+using namespace kfr;
+
+TEST(test_fracdelay)
+{
+ univector<double, 5> a({ 1, 2, 3, 4, 5 });
+ univector<double, 5> b = native::fracdelay(a, 0.5);
+ CHECK(native::rms(b - univector<double>({ 0.5, 1.5, 2.5, 3.5, 4.5 })) < c_epsilon<double> * 5);
+
+ b = native::fracdelay(a, 0.1);
+ CHECK(native::rms(b - univector<double>({ 0.9, 1.9, 2.9, 3.9, 4.9 })) < c_epsilon<double> * 5);
+
+ b = native::fracdelay(a, 0.0);
+ CHECK(native::rms(b - univector<double>({ 1, 2, 3, 4, 5 })) < c_epsilon<double> * 5);
+
+ b = native::fracdelay(a, 1.0);
+ CHECK(native::rms(b - univector<double>({ 0, 1, 2, 3, 4 })) < c_epsilon<double> * 5);
+}
+
+int main(int argc, char** argv)
+{
+ println(library_version());
+
+ return testo::run_all("", true);
+}