SDL и Aquila FFT

Я работаю с wav-файлом и хочу применить к нему fft. Я использую библиотеку Aquila C ++ и SDL2.0.
Я уже загрузил wav-файл, используя функцию SDL «SDL_LoadWav». Теперь у меня есть векторный буфер типа float. Я хочу применить БПФ к нему.
Я не уверен, как дать (const SampleType x []) аргумент для 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;
}

Для БПФ я не совсем уверен, так как он включает в себя комплексные числа. Итак, вот что я попробовал:

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**
}

Это ошибка, которую я получаю:

ошибка: нет соответствующей функции для вызова
«Aquila :: FFT :: FFT (станд :: вектор&)»
spect = fft-> fft (buffer_vector1); /usr/local/include/aquila/transform/Fft.h:70:30: примечание: кандидат:
виртуальная Aquila :: SpectrumType Aquila :: Fft :: fft (const SampleType *)
виртуальный SpectrumType fft (const SampleType x []) = 0;
^ /usr/local/include/aquila/transform/Fft.h:70:30: примечание: неизвестно
преобразование аргумента 1 из ‘std :: vector ’в‘ const
SampleType * {aka const double *} ’

Может кто-то помочь мне с этим? Я хочу добиться чего-то подобного, когда применил DCT.

Редактирует:

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

Как только я получу работу, как мне извлечь реальные и мнимые значения?

Спасибо,

2

Решение

Вы хранили свои данные в векторах, что является хорошей практикой при кодировании на C ++.

Теперь вы вызываете API, который не знает о std::vector (позор), вероятно, потому что интерфейс C ++ является дешевой оболочкой библиотеки C.

Вы должны передать указатель на необработанные данные вектора следующим образом:

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

поскольку buffer_vector1 это std::vector<Aquila::SampleType>, получая адрес первого элемента, преобразует его в Aquila::SampleType * который теперь совместим с const Aquila::SampleType [] ожидается API (вектор гарантирует, что все данные смежны, не делайте этого на std::list

Обратите внимание, что если ваш вектор слишком короткий по сравнению с размером, с которым вы инициализировали объект fft, вы получите неправильные результаты / сбой, так как вы не используете std::vector защищенный доступ к данным, но необработанный указатель (как в C)

Мои навыки FFT немного ржавые, но я помню, что вы пропускаете реальные сигналы и получаете сложные сигналы на выходе. Будьте уверены, чтобы не передавать сложные данные на входе (не уверен, просто сказать).

смотрите также: Как получить std :: vector указатель на необработанные данные?

Чтобы скомпилировать и связать ваш код, свяжите эти две библиотеки: -lAquila -lOoura_fft

Что касается вашей проблемы со звуком, хорошо, вы должны попытаться сузить это и задать другой вопрос …

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]