To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / vamp-sdk / FFT.cpp @ 532:569fc23fa37a

History | View | Annotate | Download (6.49 KB)

1
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2

    
3
/*
4
    Vamp
5

6
    An API for audio analysis and feature extraction plugins.
7

8
    Centre for Digital Music, Queen Mary, University of London.
9
    Copyright 2006-2012 Chris Cannam and QMUL.
10
  
11
    Permission is hereby granted, free of charge, to any person
12
    obtaining a copy of this software and associated documentation
13
    files (the "Software"), to deal in the Software without
14
    restriction, including without limitation the rights to use, copy,
15
    modify, merge, publish, distribute, sublicense, and/or sell copies
16
    of the Software, and to permit persons to whom the Software is
17
    furnished to do so, subject to the following conditions:
18

19
    The above copyright notice and this permission notice shall be
20
    included in all copies or substantial portions of the Software.
21

22
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
26
    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27
    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29

30
    Except as contained in this notice, the names of the Centre for
31
    Digital Music; Queen Mary, University of London; and Chris Cannam
32
    shall not be used in advertising or otherwise to promote the sale,
33
    use or other dealings in this Software without prior written
34
    authorization.
35
*/
36

    
37
#include <vamp-sdk/FFT.h>
38

    
39
#include <stdlib.h>
40
#include <stdio.h>
41
#include <math.h>
42
#include <string.h>
43

    
44
#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 9 )
45
#error Unexpected version of Vamp SDK header included
46
#endif
47

    
48
_VAMP_SDK_PLUGSPACE_BEGIN(FFT.cpp)
49

    
50
#include "FFTimpl.cpp"
51

    
52
namespace Vamp {
53

    
54
using namespace Kiss;
55

    
56
void
57
FFT::forward(unsigned int un,
58
             const double *ri, const double *ii,
59
             double *ro, double *io)
60
{
61
    int n(un);
62
    vamp_kiss_fft_cfg c = vamp_kiss_fft_alloc(n, false, 0, 0);
63
    vamp_kiss_fft_cpx *in = new vamp_kiss_fft_cpx[n];
64
    vamp_kiss_fft_cpx *out = new vamp_kiss_fft_cpx[n];
65
    for (int i = 0; i < n; ++i) {
66
        in[i].r = ri[i];
67
        in[i].i = 0;
68
    }
69
    if (ii) {
70
        for (int i = 0; i < n; ++i) {
71
            in[i].i = ii[i];
72
        }
73
    }
74
    vamp_kiss_fft(c, in, out);
75
    for (int i = 0; i < n; ++i) {
76
        ro[i] = out[i].r;
77
        io[i] = out[i].i;
78
    }
79
    vamp_kiss_fft_free(c);
80
    delete[] in;
81
    delete[] out;
82
}
83

    
84
void
85
FFT::inverse(unsigned int un,
86
             const double *ri, const double *ii,
87
             double *ro, double *io)
88
{
89
    int n(un);
90
    vamp_kiss_fft_cfg c = vamp_kiss_fft_alloc(n, true, 0, 0);
91
    vamp_kiss_fft_cpx *in = new vamp_kiss_fft_cpx[n];
92
    vamp_kiss_fft_cpx *out = new vamp_kiss_fft_cpx[n];
93
    for (int i = 0; i < n; ++i) {
94
        in[i].r = ri[i];
95
        in[i].i = 0;
96
    }
97
    if (ii) {
98
        for (int i = 0; i < n; ++i) {
99
            in[i].i = ii[i];
100
        }
101
    }
102
    vamp_kiss_fft(c, in, out);
103
    double scale = 1.0 / double(n);
104
    for (int i = 0; i < n; ++i) {
105
        ro[i] = out[i].r * scale;
106
        io[i] = out[i].i * scale;
107
    }
108
    vamp_kiss_fft_free(c);
109
    delete[] in;
110
    delete[] out;
111
}
112

    
113
class FFTComplex::D
114
{
115
public:
116
    D(int n) :
117
        m_n(n),
118
        m_fconf(vamp_kiss_fft_alloc(n, false, 0, 0)),
119
        m_iconf(vamp_kiss_fft_alloc(n, true, 0, 0)),
120
        m_ci(new vamp_kiss_fft_cpx[m_n]),
121
        m_co(new vamp_kiss_fft_cpx[m_n]) { }
122

    
123
    ~D() {
124
        vamp_kiss_fftr_free(m_fconf);
125
        vamp_kiss_fftr_free(m_iconf);
126
        delete[] m_ci;
127
        delete[] m_co;
128
    }
129

    
130
    void forward(const double *ci, double *co) {
131
        for (int i = 0; i < m_n; ++i) {
132
            m_ci[i].r = ci[i*2];
133
            m_ci[i].i = ci[i*2+1];
134
        }
135
        vamp_kiss_fft(m_fconf, m_ci, m_co);
136
        for (int i = 0; i < m_n; ++i) {
137
            co[i*2] = m_co[i].r;
138
            co[i*2+1] = m_co[i].i;
139
        }
140
    }
141

    
142
    void inverse(const double *ci, double *co) {
143
        for (int i = 0; i < m_n; ++i) {
144
            m_ci[i].r = ci[i*2];
145
            m_ci[i].i = ci[i*2+1];
146
        }
147
        vamp_kiss_fft(m_iconf, m_ci, m_co);
148
        double scale = 1.0 / double(m_n);
149
        for (int i = 0; i < m_n; ++i) {
150
            co[i*2] = m_co[i].r * scale;
151
            co[i*2+1] = m_co[i].i * scale;
152
        }
153
    }
154
    
155
private:
156
    int m_n;
157
    vamp_kiss_fft_cfg m_fconf;
158
    vamp_kiss_fft_cfg m_iconf;
159
    vamp_kiss_fft_cpx *m_ci;
160
    vamp_kiss_fft_cpx *m_co;
161
};
162

    
163
FFTComplex::FFTComplex(unsigned int n) :
164
    m_d(new D(n))
165
{
166
}
167

    
168
FFTComplex::~FFTComplex()
169
{
170
    delete m_d;
171
}
172

    
173
void
174
FFTComplex::forward(const double *ci, double *co)
175
{
176
    m_d->forward(ci, co);
177
}
178

    
179
void
180
FFTComplex::inverse(const double *ci, double *co)
181
{
182
    m_d->inverse(ci, co);
183
}
184

    
185
class FFTReal::D
186
{
187
public:
188
    D(int n) :
189
        m_n(n),
190
        m_fconf(vamp_kiss_fftr_alloc(n, false, 0, 0)),
191
        m_iconf(vamp_kiss_fftr_alloc(n, true, 0, 0)),
192
        m_ri(new vamp_kiss_fft_scalar[m_n]),
193
        m_ro(new vamp_kiss_fft_scalar[m_n]),
194
        m_freq(new vamp_kiss_fft_cpx[n/2+1]) { }
195

    
196
    ~D() {
197
        vamp_kiss_fftr_free(m_fconf);
198
        vamp_kiss_fftr_free(m_iconf);
199
        delete[] m_ri;
200
        delete[] m_ro;
201
        delete[] m_freq;
202
    }
203

    
204
    void forward(const double *ri, double *co) {
205
        for (int i = 0; i < m_n; ++i) {
206
            // in case vamp_kiss_fft_scalar is float
207
            m_ri[i] = ri[i];
208
        }
209
        vamp_kiss_fftr(m_fconf, m_ri, m_freq);
210
        int hs = m_n/2 + 1;
211
        for (int i = 0; i < hs; ++i) {
212
            co[i*2] = m_freq[i].r;
213
            co[i*2+1] = m_freq[i].i;
214
        }
215
    }
216

    
217
    void inverse(const double *ci, double *ro) {
218
        int hs = m_n/2 + 1;
219
        for (int i = 0; i < hs; ++i) {
220
            m_freq[i].r = ci[i*2];
221
            m_freq[i].i = ci[i*2+1];
222
        }
223
        vamp_kiss_fftri(m_iconf, m_freq, m_ro);
224
        double scale = 1.0 / double(m_n);
225
        for (int i = 0; i < m_n; ++i) {
226
            ro[i] = m_ro[i] * scale;
227
        }
228
    }
229
    
230
private:
231
    int m_n;
232
    vamp_kiss_fftr_cfg m_fconf;
233
    vamp_kiss_fftr_cfg m_iconf;
234
    vamp_kiss_fft_scalar *m_ri;
235
    vamp_kiss_fft_scalar *m_ro;
236
    vamp_kiss_fft_cpx *m_freq;
237
};
238

    
239
FFTReal::FFTReal(unsigned int n) :
240
    m_d(new D(n))
241
{
242
}
243

    
244
FFTReal::~FFTReal()
245
{
246
    delete m_d;
247
}
248

    
249
void
250
FFTReal::forward(const double *ri, double *co)
251
{
252
    m_d->forward(ri, co);
253
}
254

    
255
void
256
FFTReal::inverse(const double *ci, double *ro)
257
{
258
    m_d->inverse(ci, ro);
259
}
260

    
261
}
262

    
263
_VAMP_SDK_PLUGSPACE_END(FFT.cpp)
264