2016-09-15 80 views
2

我與wav文件工作,想申請FFT它。我正在使用Aquila C++庫和SDL2.0。 我已經使用SDL的「SDL_LoadWav」功能已經加載wav文件。現在我有一個float類型的向量緩衝區。我想對其應用FFT。 我不知道怎麼給(常量SampleType X [])參數FFT。SDL與Aquila FFT

這裏是我做過什麼,當我申請DCT它,但我覺得我沒有正確使用它作爲其不給右側的聲音輸出。

struct SignalComponent { 
    float frequency; 
    float amplitude; 
}; 

auto buffer = audio_file->GetWavBuffer(); // float vector 
auto buffer_length = audio_file->GetWavLength(); 
auto sample_rate = audio_file->GetWavFile()->freq; 

for (unsigned int i=0; i < buffer_length/sample_rate; i++) { 
    // Conversion of float vector into Double vector; 
    std::vector<double> buffer_vector (buffer.begin()+(i*sample_rate), 
            buffer.begin()+((i+1)*sample_rate)); 

    std::vector<double> dctCoefficients = dct->dct(buffer_vector, 576); 
    int length = dctCoefficients.size(); 

    auto signal_components = std::vector<SignalComponent>() = {}; 

    for (int i = 0; i<length; i++) { 
     SignalComponent sComponent; 
      //sqrt(re*re+im*im) will be the magnitude of the signal at the   frequency of the given bin. 
     sComponent.amplitude = dctCoefficients[i]; 
     sComponent.frequency = (static_cast<float>(i) * 
          (static_cast<float>(sample_rate)/
          static_cast<float>(length))); 
     signal_components.push_back(sComponent); 
} 
SignalChunk sChunk = SignalChunk(signal_components); 
signal_chunks.push_back(sChunk); // One big signalChunk 

auto signal = Signal(signal_chunks); 

// Clean up the DCT generator 
delete dct; 
} 

對於FFT,我不太確定,因爲它涉及複數。因此,這裏是我的嘗試:

for (unsigned int i=0 ; i<buffer.size() ; i++){ 
    spec1.push_back(0); 
    spec1.push_back(buffer[i]) ; 
} 
for (unsigned int i=buffer_length-1 ; (signed)i>-1 ; i--){ 
    spec2.push_back(0); 
    spec2.push_back(buffer[i]) ; 
} 

mergedSpectrum.resize(spec1.size() + spec2.size()); 


merge(spec1.begin(),spec1.end(),spec2.begin(),spec2.end(),mergespec.begin()); 

Aquila::Fft* fft = new Aquila::Fft(576); 
Aquila::SpectrumType spect; 
for (unsigned int i=0; i < buffer_length/sample_rate; i++) { 
    std::vector<Aquila::SampleType> buffer_vector1 (buffer_vector.begin()+(i*sample_rate), 
            buffer_vector.begin()+((i+1)*sample_rate)); 
    calculate the FFT 
    auto fft = Aquila::FftFactory::getFft(576); 
    **spect = fft->fft(buffer_vector1); // This line is an error, because of complex type** 
} 

這是我收到的錯誤:

error: no matching function for call to ‘Aquila::Fft::fft(std::vector&)’ spect = fft->fft(buffer_vector1); /usr/local/include/aquila/transform/Fft.h:70:30: note: candidate: virtual Aquila::SpectrumType Aquila::Fft::fft(const SampleType*) virtual SpectrumType fft(const SampleType x[]) = 0; ^/usr/local/include/aquila/transform/Fft.h:70:30: note: no known conversion for argument 1 from ‘std::vector’ to ‘const SampleType* {aka const double*}’

有人可以幫助我?我想在應用DCT時實現類似的功能。

編輯:

Aquila::SpectrumType spect; 
typedef complex<double> ComplexType; 
typedef std::vector<ComplexType> SpectrumType 

一旦我得到了FFT的工作,我如何提取實部和虛值?

感謝,

+0

嘗試:'FFT的> FFT(&buffer_vector1 [0]);' –

回答

2

你存儲你的數據在向量,在C編碼時,這是一個很好的做法++。

現在您正在調用一個不知道std::vector(羞恥)的API,可能是因爲C++接口是C庫的廉價包裝。

你要通過對向量這樣的原始數據中的指針:

fft->fft(&buffer_vector1[0]); 

由於buffer_vector1std::vector<Aquila::SampleType>,得到了第一個元素的地址將其轉換爲Aquila::SampleType *現在是兼容const Aquila::SampleType []預期的API(矢量確保所有數據都是連續的,不要這樣做)std::list

請注意,如果您的矢量與初始化fft對象的大小相比太短,您將得到錯誤的結果/崩潰,因爲你沒有使用std::vector受保護的數據訪問,但原始指針(如在C)

我的FFT skils有點生疏,但我記得你傳遞真正的信號,並在輸出中得到複雜的信號。一定不要在輸入中傳遞複雜的數據(不確定,只是說)。

還看到:How to get std::vector pointer to the raw data?

要編譯和鏈接代碼,與2個庫鏈接:-lAquila -lOoura_fft

關於你的聲音的問題,以及你應該儘量縮小下來,問了另一個問題?

+0

謝謝,這解決了錯誤。但是我得到另一個錯誤: //usr/local/lib/libAquila.a(OouraFft.cpp.o):函數'Aquila :: OouraFft :: fft(double const *)': OouraFft.cpp: (。文本+ 0x2c1):未定義的引用'cdft' //usr/local/lib/libAquila.a(OouraFft.cpp.o):在函數'Aquila :: OouraFft :: ifft(std :: vector ,std :: allocator >>,double *)': OouraFft.cpp :(。text + 0x412):undefined reference to'cdft' –

+0

如何編譯&鏈接你的代碼?根據https://github.com/zsiciarz/aquila-standalone-example/issues/1,它應該有2個庫:'-lAquila -lOoura_fft' –

+0

是的,工作。 –