PDA

View Full Version : Help with FFT



Setronon
28th November 2012, 16:18
Hello,

I'm using this class:



#ifndef WAVE_H
#define WAVE_H

#include <QAudioFormat>
#include <QVector>

namespace ffft
{
template <typename T>
class FFTReal;
}

class Wave {

private:
QVector<unsigned char> buffer;
QAudioFormat format;
int dirtyBegin, dirtyEnd; // dirty = modified with respect to parent
Wave* parent;
QString name;
int disposed;

ffft::FFTReal<float>* fftreal;
QList<QVector<float> > fftChunks;

// Helper functions for get/set left/right
short getLeftRight (int index, bool left) const;


void initfft();
QVector<float> do_fft(QVector<float> input);
QVector<float> do_ifft(QVector<float> input);

QVector<float> fftChunkLeftRight(int i);
void ifftChunkLeftRight(int i, QVector<float> input);
void setLeftRight (int index, short value, bool left);

public:
// Ctor
Wave(QString name, const QVector<unsigned char>& buffer, const QAudioFormat& format);

// Copy ctor
explicit Wave(const Wave& wave);

// Name
QString getName() const { return name; }
void setName(QString name) { this->name=name; }

// High level API
int sampleCount() const;
void stretch(int samples);
int frequency() const;
int channels() const;

short getLeft(int index) const { return getLeftRight(index,true); }
short getRight(int index) const { return getLeftRight(index,false); }
void setLeft(int index, short value) { setLeftRight(index,value,true); }
void setRight(int index, short value);

// Low level API
const QAudioFormat& getFormat() const { return format; }
const QVector<unsigned char>& getRealBuffer() const { return buffer; }
const QVector<unsigned char>& getBuffer();
void setFormat(const QAudioFormat& format);
void setBuffer(const QVector<unsigned char>& buffer);

// FFT operations
static const int fftChunkSize;
int countFftChunks() const { return sampleCount() / fftChunkSize + 1; }

QVector<float> fftChunkLeft(int i) { return fftChunkLeftRight(i*2); }
QVector<float> fftChunkRight(int i) { return fftChunkLeftRight(i*2+1); }

void ifftChunkLeft(int i, QVector<float> input) { ifftChunkLeftRight(i*2, input); }
void ifftChunkRight(int i, QVector<float> input) { ifftChunkLeftRight(i*2+1, input); }

friend class WaveManager;
};


#endif // WAVE_H



I want to use this function "QVector<float> do_fft(QVector<float> input);" but have no idea, where/how to get this input vector of floats. And if someone can explain what represents this input vector. Thanks in advance :)

ChrisW67
29th November 2012, 03:54
You cannot directly use that function from outside because it is private to the class.

The input to an FFT is a time-series of floating point samples of the waveform you are trying to analyse. The output is the equivalent of that series into the frequency domain. Where you get the input from is entirely driven by what you are trying to analyse. If you have a digital audio stream then the FFT input samples are the samples in the stream (converted to floats as required). If you have a weak analogue signal from a radio telescope then you need to apply analogue-to-digital conversion to obtain a suitable stream. You can fake a set of input data for testing fairly easily.

Setronon
30th November 2012, 13:27
Thanks for the reply.
Now I got the output from the fft and the output is QVector<float> within range [-1, 1]. I can calculate the amplitude like this:
qreal magnitude = sqrt(real*real + imag*imag);
qreal amplitude = 0.15 * log(magnitude);
But I cannot find the way to calculate the frequencies from this vector. Any help about this is welcome :)

d_stranz
1st December 2012, 17:15
The frequency starts at zero and has increment 1/(input sample delta). That is, if your inputs have a sample rate of 10, then the frequency increment is 1/10. There might be a factor of 2 PI in there somewhere as well. Depends on how this library was written.