2016-09-15 7 views
2

私はwavファイルを扱っており、fftを適用したいと考えています。私はAquila C++ライブラリとSDL2.0を使用しています。 SDLの "SDL_LoadWav"機能を使用してwavファイルを読み込んでいます。今私は浮動小数点型のベクトルバッファを持っています。私はそれにFFTを適用したい。 fftに(const SampleType x [])引数を与える方法がわかりません。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(shame)を認識していない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スキルは少し錆びていますが、実際の信号を渡して出力で複雑な信号を得ることを覚えています。複雑なデータを入力に渡さないように注意してください(確かではありません)。

も参照してください。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

+0

: https://github.com/zsiciarz/aquila-standalone-example/issues/1によると、2つのライブラリが必要です: '-lAquila -lOoura_fft' –

+0

はい、それはうまくいきました。 –