Android 实时获取播放音乐的频率 Visualizer用法

Android 实时获取播放音乐的频率 Visualizer用法

前言

笔者正在做的项目有播放声音并实时获取声音音频的需求,在网上搜了许久,都找不到一个满意的答案。于是自己去翻了谷歌文档和请教自己固件的同事,整理出来一套供大家参考

Visualizer 的用法

//声明MediaPlayer 
 mMediaPlayer = new MediaPlayer();
 //声明Visualizer
 visualizer = new Visualizer(mMediaPlayer.getAudioSessionId());
 //设置采样大小
 visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);  
 
 /**
 *设置采样监听    
 *参数一 监听回调
 *参数二 采样频率
 *参数三 是否获取波形信息
 * 参数四 是否获取fft变换后的信息
 */
 visualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
            @Override
            /**
            * 返回波形信息
            */
            public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
        

            }

            @Override
            /**
            *返回经过fft变换后的信息
            */
            public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) 					{
      


            }
        }, Visualizer.getMaxCaptureRate() / 2, true, true);
	//开启采样
        visualizer.setEnabled(true);

在结束时不要忘记调用

	 visualizer.setEnabled(false);	 
        if (visualizer != null) {
            visualizer.release();
        }

onFftDataCapture 讲解

/**
*
*visualizer  放返回采样的visualizer
*fft 经傅立叶快速变化后的数据
*samplingRate 手机的采样频率
*/
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) 

傅立叶变换 就是把时域变换为频域
简单来说 时域就是横坐标表示为时间
频域就是横坐标表示为频率
进入谷歌源码 文档关于onFftDataCapture的注解为

  /**
         * Method called when a new frequency capture is available.
         * 

Data in the fft buffer is valid only within the scope of the callback. * Applications which need access to the fft data after returning from the callback * should make a copy of the data instead of holding a reference. * *

In order to obtain magnitude and phase values the following formulas can * be used: *

         *       for (int i = 0; i < fft.size(); i += 2) {
         *           float magnitude = (float)Math.hypot(fft[i], fft[i + 1]);
         *           float phase = (float)Math.atan2(fft[i + 1], fft[i]);
         *       }
* @param visualizer Visualizer object on which the listener is registered. * @param fft array of bytes containing the frequency representation. * The fft array only contains the first half of the actual * FFT spectrum (frequencies up to Nyquist frequency), exploiting * the symmetry of the spectrum. For each frequencies bin i: *
    *
  • the element at index 2*i in the array contains * the real part of a complex number,
  • *
  • the element at index 2*i+1 contains the imaginary * part of the complex number.
  • *
* @param samplingRate sampling rate of the visualized audio. */
void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate);

其中 In order to obtain magnitude and phase values the following formulas can be used:表示要获取幅度和相位可以用一下公式:

//在网页中 < 表示小于号
//再快速傅立叶变换中 采取1024 的字节数组 会返回1024个复数,即有实数和虚数组成
//由于快速傅立叶的对称性。Google只返回前512个复数,其中下标为单数的为实数,下标为双的为虚数。
 for (int i = 0; i < fft.size(); i += 2) {
  float magnitude = (float)Math.hypot(fft[i], fft[i + 1]);
  float phase = (float)Math.atan2(fft[i + 1], fft[i]);
 }

相位对我们并无作用,幅度和频率相关,结果就是返回的幅度的数组。由于是频域信息 ,下标就表示频率的信息,幅度就表示该频率对应的能量。幅度越大能量越大 。表示该段声音有不同的频率组成,如果硬取一个频率的话就取幅度最大的,即能量最大的频率代表该段声音的频率
频率公式 :

(下标*采样频率)/采样大小

Demo

项目地址

你可能感兴趣的:(android)