kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit db2b24572df2f0fcae53c5fc059e069665ac2b34
parent 3b0b3915beb3c10bedc0654e40bb76782993351f
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Mon, 18 Jul 2016 14:14:01 +0300

Feature added: Convolution

Diffstat:
Minclude/kfr/all.hpp | 1+
Ainclude/kfr/dft/conv.hpp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msources.cmake | 1+
Mtests/CMakeLists.txt | 3+++
Atests/conv_test.cpp | 34++++++++++++++++++++++++++++++++++
5 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/include/kfr/all.hpp b/include/kfr/all.hpp @@ -84,6 +84,7 @@ #include "vec.hpp" #include "dft/bitrev.hpp" +#include "dft/conv.hpp" #include "dft/fft.hpp" #include "dft/ft.hpp" #include "dft/reference_dft.hpp" diff --git a/include/kfr/dft/conv.hpp b/include/kfr/dft/conv.hpp @@ -0,0 +1,59 @@ +/** + * 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 "../base/complex.hpp" +#include "../base/constants.hpp" +#include "../base/memory.hpp" +#include "../base/read_write.hpp" +#include "../base/vec.hpp" +#include "../expressions/operators.hpp" + +#include "fft.hpp" + +#pragma clang diagnostic push +#if CID_HAS_WARNING("-Wshadow") +#pragma clang diagnostic ignored "-Wshadow" +#endif + +namespace kfr +{ + +template <typename T, size_t Tag1, size_t Tag2> +KFR_INTRIN univector<T> convolve(const univector<T, Tag1>& src1, const univector<T, Tag2>& src2) +{ + const size_t size = next_poweroftwo(src1.size() + src2.size() - 1); + univector<complex<T>> src1padded = src1; + univector<complex<T>> src2padded = src2; + src1padded.resize(size, 0); + src2padded.resize(size, 0); + dft_plan<T> plan(size); + univector<u8> temp(plan.temp_size); + plan.execute(src1padded, src1padded, temp); + plan.execute(src2padded, src2padded, temp); + src1padded = src1padded * src2padded; + plan.execute(src1padded, src1padded, temp, true); + return typed<T>( real(src1padded), src1.size() + src2.size() - 1 ) / T(size); +} +} +#pragma clang diagnostic pop diff --git a/sources.cmake b/sources.cmake @@ -50,6 +50,7 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/dft/fft.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dft/ft.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dft/reference_dft.hpp + ${PROJECT_SOURCE_DIR}/include/kfr/dft/conv.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dispatch/cpuid.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dispatch/runtimedispatch.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/biquad.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt @@ -26,6 +26,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(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}) @@ -34,6 +35,8 @@ enable_testing() add_test(NAME dft_test COMMAND ${PROJECT_BINARY_DIR}/tests/dft_test) +add_test(NAME conv_test + COMMAND ${PROJECT_BINARY_DIR}/tests/conv_test) add_test(NAME complex_test COMMAND ${PROJECT_BINARY_DIR}/tests/complex_test) add_test(NAME vec_test diff --git a/tests/conv_test.cpp b/tests/conv_test.cpp @@ -0,0 +1,34 @@ +/** + * 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/dft/conv.hpp> + +using namespace kfr; + +TEST(test_convolve) +{ + univector<double, 5> a({ 1, 2, 3, 4, 5 }); + univector<double, 5> b({ 0.25, 0.5, 1.0, 0.5, 0.25 }); + univector<double> c = convolve(a, b); + CHECK(c.size() == 9); + CHECK(native::rms(c - univector<double>({ 0.25, 1., 2.75, 5., 7.5, 8.5, 7.75, 3.5, 1.25 })) < 0.0001); +} + +int main(int argc, char** argv) +{ + println(library_version()); + + return testo::run_all("", true); +}