-
Notifications
You must be signed in to change notification settings - Fork 253
/
ccv.cpp
72 lines (59 loc) · 3.02 KB
/
ccv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
* ccv, part of KFR (https://www.kfr.dev)
* Copyright (C) 2016-2023 Dan Cazarin
* See LICENSE.txt for details
*/
// Complex convolution filter examples
#define CMT_BASETYPE_F32
#include <chrono>
#include <kfr/base.hpp>
#include <kfr/dft.hpp>
#include <kfr/dsp.hpp>
using namespace kfr;
int main()
{
println(library_version());
// low-pass filter
univector<fbase, 1023> taps127;
expression_handle<fbase> kaiser = to_handle(window_kaiser(taps127.size(), 3.0));
fir_lowpass(taps127, 0.2, kaiser, true);
// Create filters.
size_t const block_size = 256;
convolve_filter<complex<fbase>> conv_filter_complex(
univector<complex<fbase>>(make_complex(taps127, zeros())), block_size);
convolve_filter<fbase> conv_filter_real(taps127, block_size);
// Create noise to filter.
auto const size = 1024 * 100 + 33; // not a multiple of block_size
univector<complex<fbase>> cnoise =
make_complex(truncate(gen_random_range(random_init(1, 2, 3, 4), -1.f, +1.f), size),
truncate(gen_random_range(random_init(3, 4, 9, 8), -1.f, +1.f), size));
univector<fbase> noise = truncate(gen_random_range(random_init(3, 4, 9, 8), -1.f, +1.f), size);
// Filter results.
univector<complex<fbase>> filtered_cnoise_ccv(size), filtered_cnoise_fir(size);
univector<fbase> filtered_noise_ccv(size), filtered_noise_fir(size);
// Complex filtering (time and compare).
auto tic = std::chrono::high_resolution_clock::now();
conv_filter_complex.apply(filtered_cnoise_ccv, cnoise);
auto toc = std::chrono::high_resolution_clock::now();
auto const ccv_time_complex = std::chrono::duration_cast<std::chrono::duration<float>>(toc - tic);
tic = toc;
filtered_cnoise_fir = kfr::fir(cnoise, fir_params{ taps127 });
toc = std::chrono::high_resolution_clock::now();
auto const fir_time_complex = std::chrono::duration_cast<std::chrono::duration<float>>(toc - tic);
auto const cdiff = rms(cabs(filtered_cnoise_fir - filtered_cnoise_ccv));
// Real filtering (time and compare).
tic = std::chrono::high_resolution_clock::now();
conv_filter_real.apply(filtered_noise_ccv, noise);
toc = std::chrono::high_resolution_clock::now();
auto const ccv_time_real = std::chrono::duration_cast<std::chrono::duration<float>>(toc - tic);
tic = toc;
filtered_noise_fir = kfr::fir(noise, fir_params{ taps127 });
toc = std::chrono::high_resolution_clock::now();
auto const fir_time_real = std::chrono::duration_cast<std::chrono::duration<float>>(toc - tic);
auto const diff = rms(filtered_noise_fir - filtered_noise_ccv);
println("complex: convolution_filter ", ccv_time_complex.count(), " fir ", fir_time_complex.count(),
" diff=", cdiff);
println("real: convolution_filter ", ccv_time_real.count(), " fir ", fir_time_real.count(),
" diff=", diff);
return 0;
}