1
/****************************************************************************************
2
 * Copyright (c) 2004 Melchior FRANZ <mfranz@kde.org>                                   *
3
 *                                                                                      *
4
 * This program is free software; you can redistribute it and/or modify it under        *
5
 * the terms of the GNU General Public License as published by the Free Software        *
6
 * Foundation; either version 2 of the License, or (at your option) any later           *
7
 * version.                                                                             *
8
 *                                                                                      *
9
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12
 *                                                                                      *
13
 * You should have received a copy of the GNU General Public License along with         *
14
 * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15
 ****************************************************************************************/
16
17
#ifndef FHT_H
18
#define FHT_H
19
20
/**
21
 * Implementation of the Hartley Transform after Bracewell's discrete
22
 * algorithm. The algorithm is subject to US patent No. 4,646,256 (1987)
23
 * but was put into public domain by the Board of Trustees of Stanford
24
 * University in 1994 and is now freely available[1].
25
 *
26
 * [1] Computer in Physics, Vol. 9, No. 4, Jul/Aug 1995 pp 373-379
27
 */
28
class FHT
29
{
30
	int	m_exp2;
31
	int	m_num;
32
	float	*m_buf;
33
	float	*m_tab;
34
	int	*m_log;
35
36
	/**
37
	 * Create a table of "cas" (cosine and sine) values.
38
	 * Has only to be done in the constructor and saves from
39
	 * calculating the same values over and over while transforming.
40
	 */
41
	void	makeCasTable();
42
43
	/**
44
	 * Recursive in-place Hartley transform. For internal use only!
45
	 */
46
	void	_transform(float *, int, int);
47
48
   public:
49
	/**
50
	* Prepare transform for data sets with @f$2^n@f$ numbers, whereby @f$n@f$
51
	* should be at least 3. Values of more than 3 need a trigonometry table.
52
	* @see makeCasTable()
53
	*/
54
	FHT(int);
55
56
	~FHT();
57
	inline int sizeExp() const { return m_exp2; }
58
	inline int size() const { return m_num; }
59
	float	*copy(float *, float *);
60
	float	*clear(float *);
61
	void	scale(float *, float);
62
63
	/**
64
	 * Exponentially Weighted Moving Average (EWMA) filter.
65
	 * @param d is the filtered data.
66
	 * @param s is fresh input.
67
	 * @param w is the weighting factor.
68
	 */
69
	void	ewma(float *d, float *s, float w);
70
71
	/**
72
	 * Logarithmic audio spectrum. Maps semi-logarithmic spectrum
73
	 * to logarithmic frequency scale, interpolates missing values.
74
	 * A logarithmic index map is calculated at the first run only.
75
	 * @param p is the input array.
76
	 * @param out is the spectrum.
77
	 */
78
	void	logSpectrum(float *out, float *p);
79
80
	/**
81
	 * Semi-logarithmic audio spectrum.
82
	 */
83
	void	semiLogSpectrum(float *);
84
85
	/**
86
	 * Fourier spectrum.
87
	 */
88
	void	spectrum(float *);
89
90
	/**
91
	 * Calculates a mathematically correct FFT power spectrum.
92
	 * If further scaling is applied later, use power2 instead
93
	 * and factor the 0.5 in the final scaling factor.
94
	 * @see FHT::power2()
95
	 */
96
	void	power(float *);
97
98
	/**
99
	 * Calculates an FFT power spectrum with doubled values as a
100
	 * result. The values need to be multiplied by 0.5 to be exact.
101
	 * Note that you only get @f$2^{n-1}@f$ power values for a data set
102
	 * of @f$2^n@f$ input values. This is the fastest transform.
103
	 * @see FHT::power()
104
	 */
105
	void	power2(float *);
106
107
	/**
108
	 * Discrete Hartley transform of data sets with 8 values.
109
	 */
110
	void	transform8(float *);
111
112
	void	transform(float *);
113
};
114
115
#endif