File: fftresampler.h

package info (click to toggle)
wsclean 2.8-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 2,196 kB
  • sloc: cpp: 34,504; ansic: 234; python: 174; makefile: 10
file content (109 lines) | stat: -rw-r--r-- 2,304 bytes parent folder | download
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#ifndef FFT_RESAMPLE_H
#define FFT_RESAMPLE_H

#include "lane.h"

#include <vector>
#include <thread>

#include <fftw3.h>

#include "uvector.h"
#include "windowfunction.h"

class FFTResampler
{
private:
	struct Task
	{
		double *input, *output;
	};
	
public:
	FFTResampler(size_t inWidth, size_t inHeight, size_t outWidth, size_t outHeight, size_t cpuCount, bool verbose=true);
	
	~FFTResampler();
	
	void AddTask(double* input, double* output)
	{
		Task task;
		task.input = input;
		task.output = output;
		_tasks.write(task);
	}
	
	void Start()
	{
		for(size_t i=0; i!=_tasks.capacity(); ++i)
		{
			_threads.emplace_back(&FFTResampler::runThread, this);
		}
	}
	
	void Finish()
	{
		_tasks.write_end();
		for(std::thread& t : _threads)
			t.join();
		_threads.clear();
		_tasks.clear();
	}
	
	void Resample(double* input, double* output)
	{
		Task task;
		task.input = input;
		task.output = output;
		runSingle(task, false);
	}
	
	void SingleFT(const double* input, double* realOutput, double* imaginaryOutput);
	
	/**
	 * Only to be used with SingleFT (it makes resampling thread unsafe!)
	 */
	void SetTukeyWindow(double insetSize, bool correctWindow)
	{
		_windowFunction = WindowFunction::Tukey;
		_tukeyInsetSize = insetSize;
		_correctWindow = correctWindow;
		_windowRowIn.clear();
		_windowColIn.clear();
		_windowOut.clear();
	}
	
	void SetWindowFunction(WindowFunction::Type window, bool correctWindow)
	{
		_windowFunction = window;
		_correctWindow = correctWindow;
		_windowRowIn.clear();
		_windowColIn.clear();
		_windowOut.clear();
	}
	
private:
	void runThread();
	void runSingle(const Task& task, bool skipWindow) const;
	void applyWindow(double* data) const;
	void unapplyWindow(double* data) const;
	void makeWindow(ao::uvector<double>& data, size_t width) const;
	void makeTukeyWindow(ao::uvector<double>& data, size_t width) const;
	
	size_t _inputWidth, _inputHeight;
	size_t _outputWidth, _outputHeight;
	size_t _fftWidth, _fftHeight;
	WindowFunction::Type _windowFunction;
	double _tukeyInsetSize;
	mutable ao::uvector<double> _windowRowIn;
	mutable ao::uvector<double> _windowColIn;
	mutable ao::uvector<double> _windowOut;
	bool _correctWindow;
	
	fftw_plan _inToFPlan, _fToOutPlan;
	
	ao::lane<Task> _tasks;
	std::vector<std::thread> _threads;
	bool _verbose;
};

#endif