Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Вообще, не думаю что человек воспринимает звук как разложение в спектр, скорее звук состоит из звуковых образов, которые состоят из волн разной длинны. Соответственно громкость какого либо звука это скорее средняя громкость всех волн из которых звук состоит. Но пока что не понятно какие параметры составляют звуковой образ, возможно средняя частота, стандартное отклонение или что то еще.
В общем, для цветомузыки сойдёт (если не медленней бпф, тогда нет особого смысла), а вот для анализа сигналов я бы уже не рискнул применять.
Бонус (раз уж цветомузыка): фильтр типа y(t) = 0.9y(t-T)+0.1x(t) выделяет частоту 1/T и её гармоники, если сделать пачку таких фильтров для 12 нот какой-то октавы — можно отрисовать 12 красивых осциллограмм, дёргающихся в такт нотам.

Можете дать ссылку на программу которая на ваш взгляд корректно отрабатывает FFT.
// Pow - степень массива сэмплов, т.е. для 16к Pow = 14.
// Результат будет симметричен в этом случае относительно 8к, т.е. половину массива сэмпла
void DP__Complex_FFT(double * Samples_Source,
double * Desination_R,
double * Desination_I,
u4x Pow)
{
int Le, Le1, jt, it, ip, lt, kt, num;
double re_T, re_U, re_W, im_T, im_U, im_W;
num = 1 << Pow;
for (it = 0; it < num; it++) {Desination_R[it] = Samples_Source[it]; Desination_I[it] = 0;}
for (it = 0; it < num; it++)
{
kt = num / 2;
jt = 0;
Le = 1;
Le1 = it;
for (lt = 1; lt <= Pow; lt++)
{
if (kt <= Le1)
{
jt = jt + Le;
Le1 = Le1 - kt;
}
Le = Le * 2;
kt = kt / 2;
}
if (it < jt)
{
re_T = Samples_Source[jt];
im_T = 0;
Desination_R[jt] = Desination_R[it];
Desination_I[jt] = Desination_I[it];
Desination_R[it] = re_T;
Desination_I[it] = im_T;
}
}
for (lt = 1; lt <= Pow; lt++)
{
Le = 1;
for (jt = 1; jt <= lt; jt++) Le = Le * 2;
Le1 = Le / 2;
re_U = 1.0;
im_U = 0.0;
re_W = cos(M_PI / Le1);
im_W = sin(M_PI / Le1);
for (jt = 0; jt < Le1; jt++)
{
it = jt;
while (it < num - Le1)
{
ip = it + Le1;
re_T = Desination_R[ip] * re_U - Desination_I[ip] * im_U;
im_T = Desination_R[ip] * im_U + Desination_I[ip] * re_U;
Desination_R[ip] = Desination_R[it] - re_T;
Desination_I[ip] = Desination_I[it] - im_T;
Desination_R[it] = Desination_R[it] + re_T;
Desination_I[it] = Desination_I[it] + im_T;
it = it + Le;
}
re_T = re_U * re_W - im_U * im_W;
im_T = re_U * im_W + im_U * re_W;
re_U = re_T;
im_U = im_T;
}
}
}
// Модуль комплексного спектра
// Рабочие массивы I и R - превращаются в Desination
double DP__Amplitude_FFT(double * Source_R,
double * Source_I,
double * Desination,
u4x Steps_amount)
{
double Max = 0.0;
double Y;
for(u4x i = 0; i<Steps_amount; i++)
{
Desination[i] = sqrt(((double)Source_R[i])*((double)Source_R[i]) + ((double)Source_I[i])*((double)Source_I[i]));
if(Desination[i] > Max)
Max = Desination[i];
}
return(Max);
}Т.е на мой взгляд после анализа суммы двух близких частот F1/F2<2, FFT даст весь набор между F1 и F2, возможно у F1 и F2 будут больше амплитуды, но будет и много лишнего.
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
printf("Start analyze\n");
uint size=16384;
double* Signal=new double[size];
double* Desination_R=new double[size];
double* Desination_I=new double[size];
double* Desination=new double[size];
memset(Signal,0,sizeof(double)*size);
memset(Desination_R,0,sizeof(double)*size);
memset(Desination_I,0,sizeof(double)*size);
memset(Desination,0,sizeof(double)*size);
for(uint i=0;i<size;i++)
Signal[i]=1000*sin(2*3.1415*float(i)*1000.0/44100.0)+1000*sin(2*3.1415*float(i)*1004.0/44100.0)+1000*sin(2*3.1415*float(i)*1008.0/44100.0);
DP__Complex_FFT(Signal,Desination_R,Desination_I,14);
//DP__Amplitude_FFT(Desination_R,Desination_I,Desination,14);
for(uint i=0;i<size;i++){
// if(Desination_R[i]>1)
// printf("%i %f\n",i,Desination_R[i]);
if(Desination_I[i]>1)
printf("%i %f\n",i,Desination_I[i]);
}
return a.exec();
}for(uint i=0;i<size;i++)
Signal[i]=1000.0*sin(2.0*3.1415*float(i)*1000.0/44100.0)+1000.0*sin(2.0*3.1415*float(i)*1004.0/44100.0)+1000.0*sin(2.0*3.1415*float(i)*1008.0/44100.0);
DP__Complex_FFT(Signal,Desination_R,Desination_I,14);
DP__Amplitude_FFT(Desination_R,Desination_I,Desination,size);
for(uint i=0;i<size;i++){
if(Desination[i]>1)
printf("%i %f\n",i,Desination[i]);
Еще один способ разложения сигнала в спектр