У меня есть данные БПФ, 257 измерений, каждые 10 мс, 121 кадр, т.е. 1,21 сек. Я думаю, что первое измерение, вероятно, что-то еще, а остальные, я думаю, являются коэффициентами БПФ. Вероятно, это просто данные спектрограммы. Из комментария о данных БПФ к ним могли быть применены sqrt10 и нормализация среднего отклонения.
Оттуда я хочу вычислить некоторый сигнал PCM для 44,1 Гц, чтобы я мог воспроизвести звук. Я задал тот же вопрос более математически здесь, но, возможно, StackOverflow это лучшее место, потому что я действительно хочу реализовать это. Я также задал тот же вопрос о теории здесь, на DSP SE.
Как бы я это сделал? Может быть, мне нужна дополнительная информация (которую я должен как-то узнать) - какая? Может быть, эту недостающую информацию можно как-то разумно угадать?
Этот вопрос касается как теории, так и практической реализации. Реализация тривиальна, я думаю. Но конкретный пример на каком-то языке был бы полезен для понимания теории. Может быть, С++ с FFTW? Я пропустил документы FFTW, но не понимаю всей терминологии и некоторых предпосылок, например. здесь. Почему именно от сложного к реальному или наоборот, я хочу только реальное к реальному. Что это за РЕДФТ? Что такое DCT, DFT, DST? FFTW_HC2R?
Я прочитал все данные БПФ, т.е. 121 * 257 чисел с плавающей запятой, в вектор freq_bins
.
std::vector<float32_t> freq_bins; // FFT data
int freq_bins_count = 257;
size_t len = 121;
std::vector<float32_t> pcm; // output, PCM data
int N = freq_bins_count;
std::vector<double> out(N), orig_in(N);
// inspiration: https://stackoverflow.com/questions/2459295/invertible-stft-and-istft-in-python/6891772#6891772
for(int f = 0; f < len; ++f) {
size_t pos = freq_bins_count * f;
for(int i = 0; i < N; ++i)
out[i] = pow(freq_bins[pos + i] + offset, 10); // fft was sqrt10 + mvn
fftw_plan q = fftw_plan_r2r_1d(N, &out[0], &orig_in[0], FFTW_REDFT00, FFTW_ESTIMATE);
fftw_execute(q);
fftw_destroy_plan(q);
// naive overlap-and-add
auto start_frame = size_t(f * dt * sampleRate);
for(int i = 0; i < N; ++i) {
sample_t frame = orig_in[i] * scale / (2 * (N - 1));
size_t idx = start_frame + i;
while(idx >= pcm.size())
pcm.push_back(0);
pcm[idx] += frame;
}
}
Но это неправильно, я думаю. Я просто выбрасываю мусор.
Связанным может быть этот вопрос. Или это.