Я пытаюсь разработать простое приложение C, которое может давать значение от 0 до 100 в определенном диапазоне частот в заданную временную метку в WAV файле.
Пример: у меня есть частотный диапазон 44,1 кГц (обычный MP3 файл), и я хочу разбить этот диапазон на n количество диапазонов (начиная с 0). Затем мне нужно получить амплитуду каждого диапазона, от 0 до 100.
То, что мне удалось:
Использование libsndfile Теперь я могу прочитать данные WAV файла.
infile = sf_open(argv [1], SFM_READ, &sfinfo);
float samples[sfinfo.frames];
sf_read_float(infile, samples, 1);
Однако мое понимание БПФ довольно ограничено. Но я знаю, что это необходимо для того, чтобы получить амплитуды в диапазонах, которые мне нужны. Но как мне двигаться дальше? Я нашел библиотеку FFTW-3, которая, кажется, подходит для этой цели.
Я нашел некоторую помощь здесь: qaru.site/info/46893/...
и посмотрел учебник FFTW здесь: http://www.fftw.org/fftw2_doc/fftw_2.html
Но поскольку я не уверен в поведении FFTW, я не знаю, как продвигаться отсюда.
И еще один вопрос, предполагая, что вы используете libsndfile: если вы вынуждаете чтение быть одноканальным (со стереофайлом), а затем читаете образцы. Будете ли вы тогда читать только половину образцов всего файла? Поскольку половина из них относится к каналу 1 или автоматически отфильтровывает их?
Спасибо за вашу помощь.
EDIT: Мой код можно увидеть здесь:
double blackman_harris(int n, int N){
double a0, a1, a2, a3, seg1, seg2, seg3, w_n;
a0 = 0.35875;
a1 = 0.48829;
a2 = 0.14128;
a3 = 0.01168;
seg1 = a1 * (double) cos( ((double) 2 * (double) M_PI * (double) n) / ((double) N - (double) 1) );
seg2 = a2 * (double) cos( ((double) 4 * (double) M_PI * (double) n) / ((double) N - (double) 1) );
seg3 = a3 * (double) cos( ((double) 6 * (double) M_PI * (double) n) / ((double) N - (double) 1) );
w_n = a0 - seg1 + seg2 - seg3;
return w_n;
}
int main (int argc, char * argv [])
{ char *infilename ;
SNDFILE *infile = NULL ;
FILE *outfile = NULL ;
SF_INFO sfinfo ;
infile = sf_open(argv [1], SFM_READ, &sfinfo);
int N = pow(2, 10);
fftw_complex results[N/2 +1];
double samples[N];
sf_read_double(infile, samples, 1);
double normalizer;
int k;
for(k = 0; k < N;k++){
if(k == 0){
normalizer = blackman_harris(k, N);
} else {
normalizer = blackman_harris(k, N);
}
}
normalizer = normalizer * (double) N/2;
fftw_plan p = fftw_plan_dft_r2c_1d(N, samples, results, FFTW_ESTIMATE);
fftw_execute(p);
int i;
for(i = 0; i < N/2 +1; i++){
double value = ((double) sqrtf(creal(results[i])*creal(results[i])+cimag(results[i])*cimag(results[i]))/normalizer);
printf("%f\n", value);
}
sf_close (infile) ;
return 0 ;
} /* main */