SDL 和 Aquila FFT
SDL and Aquila FFT
我正在处理 wav 文件并想对其应用 fft。我正在使用 Aquila C++ 库和 SDL2.0。
我已经使用 SDL 的 "SDL_LoadWav" 函数加载了 wav 文件。现在我有一个 float 类型的向量缓冲区。我想对其应用 FFT。
我不确定如何将 (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;
}
对于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 运算后,如何提取实数值和虚数值?
您将数据存储在向量中,这是用 C++ 编码时的一个好习惯。
现在您正在调用一个 API,它不知道 std::vector
(可耻)可能是因为 C++ 接口是 C 库的廉价包装器。
您必须像这样在向量的原始数据上传递指针:
fft->fft(&buffer_vector1[0]);
或更好:使用data
成员方法:
fft->fft(buffer_vector1.data());
由于 buffer_vector1
是 std::vector<Aquila::SampleType>
,获取第一个元素的地址会将其转换为 Aquila::SampleType *
,现在与 const Aquila::SampleType []
所期望的 const Aquila::SampleType []
兼容40=](向量确保所有数据都是连续的,不要在 std::list
上这样做
请注意,如果您的向量与您初始化 fft 对象的大小相比太短,您将得到错误的结果/崩溃,因为您没有使用 std::vector
受保护的数据访问,而是使用原始指针 (就像在 C)
我的 FFT 技能有点生疏,但我记得你传递的是真实信号并在输出中得到复杂信号。一定不要在输入中传递复杂的数据(不确定,只是说)。
另请参阅:How to get std::vector pointer to the raw data?
要编译和 link 您的代码,link 使用这两个库:-lAquila -lOoura_fft
我正在处理 wav 文件并想对其应用 fft。我正在使用 Aquila C++ 库和 SDL2.0。 我已经使用 SDL 的 "SDL_LoadWav" 函数加载了 wav 文件。现在我有一个 float 类型的向量缓冲区。我想对其应用 FFT。 我不确定如何将 (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;
}
对于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 运算后,如何提取实数值和虚数值?
您将数据存储在向量中,这是用 C++ 编码时的一个好习惯。
现在您正在调用一个 API,它不知道 std::vector
(可耻)可能是因为 C++ 接口是 C 库的廉价包装器。
您必须像这样在向量的原始数据上传递指针:
fft->fft(&buffer_vector1[0]);
或更好:使用data
成员方法:
fft->fft(buffer_vector1.data());
由于 buffer_vector1
是 std::vector<Aquila::SampleType>
,获取第一个元素的地址会将其转换为 Aquila::SampleType *
,现在与 const Aquila::SampleType []
所期望的 const Aquila::SampleType []
兼容40=](向量确保所有数据都是连续的,不要在 std::list
请注意,如果您的向量与您初始化 fft 对象的大小相比太短,您将得到错误的结果/崩溃,因为您没有使用 std::vector
受保护的数据访问,而是使用原始指针 (就像在 C)
我的 FFT 技能有点生疏,但我记得你传递的是真实信号并在输出中得到复杂信号。一定不要在输入中传递复杂的数据(不确定,只是说)。
另请参阅:How to get std::vector pointer to the raw data?
要编译和 link 您的代码,link 使用这两个库:-lAquila -lOoura_fft