1
// FHT - Fast Hartley Transform Class
3
// Copyright (C) 2004 Melchior FRANZ - mfranz@kde.org
5
// This program is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU General Public License as
7
// published by the Free Software Foundation; either version 2 of the
8
// License, or (at your option) any later version.
10
// This program is distributed in the hope that it will be useful, but
11
// WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19
// $Id: fht.cpp 871912 2008-10-16 02:27:10Z mitchell $
40
m_buf = new float[m_num];
41
m_tab = new float[m_num * 2];
55
void FHT::makeCasTable(void)
57
float d, *costab, *sintab;
58
int ul, ndiv2 = m_num / 2;
60
for (costab = m_tab, sintab = m_tab + m_num / 2 + 1, ul = 0; ul < m_num; ul++) {
61
d = M_PI * ul / ndiv2;
62
*costab = *sintab = cos(d);
64
costab += 2, sintab += 2;
65
if (sintab > m_tab + m_num * 2)
71
float* FHT::copy(float *d, float *s)
73
return (float *)memcpy(d, s, m_num * sizeof(float));
77
float* FHT::clear(float *d)
79
return (float *)memset(d, 0, m_num * sizeof(float));
83
void FHT::scale(float *p, float d)
85
for (int i = 0; i < (m_num / 2); i++)
90
void FHT::ewma(float *d, float *s, float w)
92
for (int i = 0; i < (m_num / 2); i++, d++, s++)
93
*d = *d * w + *s * (1 - w);
97
void FHT::logSpectrum(float *out, float *p)
99
int n = m_num / 2, i, j, k, *r;
102
float f = n / log10((double)n);
103
for (i = 0, r = m_log; i < n; i++, r++) {
104
j = int(rint(log10(i + 1.0) * f));
105
*r = j >= n ? n - 1 : j;
109
*out++ = *p = *p / 100;
110
for (k = i = 1, r = m_log; i < n; ++i) {
115
float base = p[k - 1];
116
float step = (p[j] - base) / (j - (k - 1));
117
for (float corr = 0; k <= j; k++, corr += step)
118
*out++ = base + corr;
124
void FHT::semiLogSpectrum(float *p)
128
for (int i = 0; i < (m_num / 2); i++, p++) {
129
e = 10.0 * log10(sqrt(*p * .5));
135
void FHT::spectrum(float *p)
138
for (int i = 0; i < (m_num / 2); i++, p++)
139
*p = (float)sqrt(*p * .5);
143
void FHT::power(float *p)
146
for (int i = 0; i < (m_num / 2); i++)
151
void FHT::power2(float *p)
155
_transform(p, m_num, 0);
157
*p = (*p * *p), *p += *p, p++;
159
for (i = 1, q = p + m_num - 2; i < (m_num / 2); i++, --q)
160
*p = (*p * *p) + (*q * *q), p++;
164
void FHT::transform(float *p)
169
_transform(p, m_num, 0);
173
void FHT::transform8(float *p)
175
float a, b, c, d, e, f, g, h, b_f2, d_h2;
176
float a_c_eg, a_ce_g, ac_e_g, aceg, b_df_h, bdfh;
178
a = *p++, b = *p++, c = *p++, d = *p++;
179
e = *p++, f = *p++, g = *p++, h = *p;
180
b_f2 = (b - f) * M_SQRT2;
181
d_h2 = (d - h) * M_SQRT2;
183
a_c_eg = a - c - e + g;
184
a_ce_g = a - c + e - g;
185
ac_e_g = a + c - e - g;
186
aceg = a + c + e + g;
188
b_df_h = b - d + f - h;
189
bdfh = b + d + f + h;
192
*--p = a_ce_g - b_df_h;
193
*--p = ac_e_g - b_f2;
195
*--p = a_c_eg + d_h2;
196
*--p = a_ce_g + b_df_h;
197
*--p = ac_e_g + b_f2;
202
void FHT::_transform(float *p, int n, int k)
209
int i, j, ndiv2 = n / 2;
210
float a, *t1, *t2, *t3, *t4, *ptab, *pp;
212
for (i = 0, t1 = m_buf, t2 = m_buf + ndiv2, pp = &p[k]; i < ndiv2; i++)
213
*t1++ = *pp++, *t2++ = *pp++;
215
memcpy(p + k, m_buf, sizeof(float) * n);
217
_transform(p, ndiv2, k);
218
_transform(p, ndiv2, k + ndiv2);
220
j = m_num / ndiv2 - 1;
234
for (i = 1, t4 = p + k + n; i < ndiv2; i++, ptab += j) {
241
memcpy(p + k, m_buf, sizeof(float) * n);