通过Record_Audio获取MediaPlayer播放器的声音,利用自带的FFT功能进行音频分析
放于线程中
visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1])
设置采样窗口1024点(实测:当大于1024时,例如4096,android仍然取1024)
n=getCaptureSize()
即 n = 1024
每1024个实数点放入一个数组,进行FFT快速傅里叶变换,得到1024个复数点,由于对称性,前512个点与后512个点对称,取前513个点(包括第0点)
其中第0点和第512点为实数,中间511点为复数
onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate)
FFT数据为byte类型,放于byte[1024]中,其中一共1+1+(1024-2)/2=513个有效FFT数据
除了直流和n/2对应的点占一个坑儿,其他频率数据都是 实部+i虚部 两个坑儿
直流 | 实数 | 实部 | 虚部 | 实部 | 虚部 | …… | 实部 | 虚部 |
0 | 1 | 2 | 3 | 4 | 5 | n-2 | n-1 | |
R0 | Rn/2 | R1 | L1 | R2 | L2 | R(n-1)/2 | L(n-1)/2 |
获得的频率范围= 0~采样率/2 = 0~22.05kHz之间
即513个频率分布在 [ 0Hz,22.05kHz ]之间
每相邻两个频率间隔(mHz) = 采样率 / (1024 / 2) = 44 100 000 / 512 = 86.132Hz分辨率为86.132Hz,再小的频率间隔将无法分辨
采样率:每秒采集音频流的点数
frequencyEach = samplingRate * 2 / visualizer.getCaptureSize(); //86132 samplingRate=44,100,000 mHz getCaptureSize()=1024
k为0~512中的某个点,第k个点对应的频率 = k * frequencyEach,亦即
k(Hz)=getSamplingRate() * k /(getCaptureSize()/2)
完整代码,写在线程中执行
new Thread(new Runnable()
{
@Override
public void run()
{
if (mediaPlayer.isPlaying())
{
try
{
Visualizer visualizer = new Visualizer(mediaPlayer.getAudioSessionId()); //mediaPlayer.getAudioSessionId()=1538 1540 1542...
visualizer.setEnabled(false);
visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]); /** 64,128,256,512,1024 */ //前面若没有setEnabled(false) 会在此出异常
visualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener()
{
//采集波形数据
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] wave, int samplingRate)
{
}
//采集FFT数据 bytes数组大小=
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate)
{
// 直流 实部 虚部 频率范围 0-采样率/2 getSamplingRate()
// 0 1 2 3 4 5 n-2 n-1 n=getCaptureSize()
// R0 Rn/2 R1 L1 R2 L2 R(n-1)/2 L(n-1)/2
// k次频率 = getSamplingRate() * k / (n/2) int getFft (byte[] fft)
int frequencyCounts = bytes.length/2+1; // =513
fft = new byte[frequencyCounts]; // (n-2)/2+2 = n/2+1 容量 = getCaptureSize()/2+
fft[0] = (byte) Math.abs(bytes[0]);
for (int i = 1; i390)
{
WaveHeight[i] = 390;
}
}
}
},Visualizer.getMaxCaptureRate()/2,false,true); //rate(采样周期 mHz) isWave isFFT
visualizer.setEnabled(true);
}
catch (Exception e)
{
e.printStackTrace();//这里没有WaveHeight异常
}
}
}
}).start();
}
catch (Exception e)
{
flagTest = 233;
e.printStackTrace();
}