在Android

时间:2016-08-05 12:00:05

标签: android fft

我正在为孩子们制作小型Android应用程序,它只是播放旋律,然后孩子试图回唱。我记录和比较歌曲说你正确地唱歌等。

到目前为止,我设法使用TarsosDSP记录和计算麦克风的实时数据。我也投影到图表中。但我无法得到旋律的FFT值。我是音频处理领域的新人。

有人能举例说明如何计算简单mp3文件的FFT吗? 感谢。

2 个答案:

答案 0 :(得分:0)

使用Java,采样频率,折叠频率和FFT算法进行频谱分析http://www.developer.com/java/other/article.php/3380031

答案 1 :(得分:0)

将歌曲转换为字节后,即可使用此代码。

我使用了JTranforms库,它可以完美运行,您可以将其与Matlab使用的函数进行比较。

这是我的代码,其中带有注释,其引用了matlab如何转换任何信号并获取频率幅度(https://la.mathworks.com/help/matlab/ref/fft.html

首先,在build.gradle(应用程序)中添加以下内容

implementation 'com.github.wendykierp:JTransforms:3.1'

这是用于转换简单正弦波的代码,其工作原理就像一个魅力

double Fs = 8000;
double T = 1/Fs;
int L = 1600;

double freq = 338;

double sinValue_re_im[] = new double[L*2]; // because FFT takes an array where its positions alternate between real and imaginary
for( int i = 0; i < L; i++)
{
    sinValue_re_im[2*i] = Math.sin( 2*Math.PI*freq*(i * T) ); // real part
    sinValue_re_im[2*i+1] = 0; //imaginary part
}

// matlab
// tf = fft(y1);

DoubleFFT_1D fft = new DoubleFFT_1D(L);
fft.complexForward(sinValue_re_im);
double[] tf = sinValue_re_im.clone();

// matlab
// P2 = abs(tf/L);
double[] P2 = new double[L];
for(int i=0; i<L; i++){

    double re = tf[2*i]/L;
    double im = tf[2*i+1]/L;
    P2[i] = sqrt(re*re+im*im);
}

// P1 = P2(1:L/2+1);
double[] P1 = new double[L/2]; // single-sided: the second half of P2 has the same values as the first half
System.arraycopy(P2, 0, P1, 0, L/2);
// P1(2:end-1) = 2*P1(2:end-1);
System.arraycopy(P1, 1, P1, 1, L/2-2);
for(int i=1; i<P1.length-1; i++){
    P1[i] = 2*P1[i];
}
// f = Fs*(0:(L/2))/L;
double[] f = new double[L/2 + 1];
for(int i=0; i<L/2+1;i++){
    f[i] = Fs*((double) i)/L;
}