1+ // Copyright (C) 2010-2016 Lukas Lalinsky
2+ // Distributed under the MIT license, see the LICENSE file for details.
3+
4+ #include " fft_lib_avtx.h"
5+
6+ namespace chromaprint {
7+
8+ FFTLib::FFTLib (size_t frame_size) : m_frame_size(frame_size) {
9+ m_window = (float *) av_malloc (sizeof (float ) * frame_size);
10+ m_input = (float *) av_malloc (sizeof (float ) * frame_size);
11+ m_output = (AVComplexFloat *) av_malloc (sizeof (AVComplexFloat) * (frame_size / 2 + 1 ));
12+ PrepareHammingWindow (m_window, m_window + frame_size, 1.0 / INT16_MAX);
13+
14+ // Initialize the RDFT transform context
15+ // For real-to-complex transform: inv=0, no scaling, no special flags
16+ int ret = av_tx_init (&m_tx_ctx, &m_tx_fn, AV_TX_FLOAT_RDFT, 0 , frame_size, NULL , 0 );
17+ if (ret < 0 ) {
18+ // Handle initialization error - this should not happen with valid parameters
19+ m_tx_ctx = NULL ;
20+ m_tx_fn = NULL ;
21+ }
22+ }
23+
24+ FFTLib::~FFTLib () {
25+ av_tx_uninit (&m_tx_ctx);
26+ av_free (m_output);
27+ av_free (m_input);
28+ av_free (m_window);
29+ }
30+
31+ void FFTLib::Load (const int16_t *b1, const int16_t *e1 , const int16_t *b2, const int16_t *e2 ) {
32+ auto window = m_window;
33+ auto output = m_input;
34+ ApplyWindow (b1, e1 , window, output);
35+ ApplyWindow (b2, e2 , window, output);
36+ }
37+
38+ void FFTLib::Compute (FFTFrame &frame) {
39+ if (!m_tx_ctx || !m_tx_fn) {
40+ // Transform context initialization failed
41+ return ;
42+ }
43+
44+ // Perform the real-to-complex FFT
45+ // stride parameter: spacing between input samples in bytes
46+ m_tx_fn (m_tx_ctx, m_output, m_input, sizeof (float ));
47+
48+ // Convert complex output to power spectrum
49+ auto input = m_output;
50+ auto output = frame.begin ();
51+
52+ // Handle DC component (index 0)
53+ output[0 ] = input[0 ].re * input[0 ].re ;
54+
55+ // Handle Nyquist frequency (index frame_size/2)
56+ output[m_frame_size / 2 ] = input[m_frame_size / 2 ].re * input[m_frame_size / 2 ].re ;
57+
58+ // Handle intermediate frequencies (indices 1 to frame_size/2-1)
59+ output += 1 ;
60+ input += 1 ;
61+ for (size_t i = 1 ; i < m_frame_size / 2 ; i++) {
62+ *output++ = input->re * input->re + input->im * input->im ;
63+ input++;
64+ }
65+ }
66+
67+ }; // namespace chromaprint
0 commit comments