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
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
);