从用户的声音中获取振幅

时间:2013-02-21 05:44:32

标签: android audio record microphone

如何从用户的声音中检测振幅? 只是检测用户是否说话。 AudioRecorder,MediaRecorder,Audio Capture之间有什么不同? 请给我一个完整的解释和代码

我在教程中尝试了这个类,但它在“mRecorder.prepare()中有错误:”

import android.media.MediaRecorder;

 public class SoundMeter {
    static final private double EMA_FILTER = 0.6;

    private MediaRecorder mRecorder = null;
    private double mEMA = 0.0;

    public void start() {
            if (mRecorder == null) {
                    mRecorder = new MediaRecorder();
                    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    mRecorder.prepare();
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                mRecorder.setOutputFile("/dev/null"); 

                mRecorder.start();
                mEMA = 0.0;
            }
    }

    public void stop() {
            if (mRecorder != null) {
                    mRecorder.stop();       
                    mRecorder.release();
                    mRecorder = null;
            }
    }

    public double getAmplitude() {
            if (mRecorder != null)
                    return  (mRecorder.getMaxAmplitude()/2700.0);
            else
                    return 0;

    }

    public double getAmplitudeEMA() {
            double amp = getAmplitude();
            mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
            return mEMA;
    }

}

更新我的第二次尝试

     public class MainActivity extends Activity {


 static final private double EMA_FILTER = 0.6;
private MediaRecorder mRecorder = null;
private double mEMA = 0.0;
TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


      mRecorder = new MediaRecorder();
      mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

      mRecorder.start();
      mEMA = 0.0;


     tv = (TextView) findViewById(R.id.textView1);
    double a = getAmplitude();
    tv.setText(String.valueOf(a));
    new Timer().schedule(new TimerTask() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            down();
        }
    }, 500, 10);

}
public void down() {
    this.runOnUiThread(Update);
}
private Runnable Update=new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        double a = getAmplitude();
        tv.setText(String.valueOf(a));
    }
};


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
public double getAmplitude() {
       if (mRecorder != null)
               return  (mRecorder.getMaxAmplitude());
       else
               return 0;

} }

1 个答案:

答案 0 :(得分:1)

有几件事:

  1. 您需要在 prepare()语句之前设置输出格式。来自documentation for prepare():如果在IllegalStateException之后或start()

  2. 之前调用,则会setOutputFormat()
  3. MediaRecorder.prepare()也会抛出IOException。您可能希望使用try / catch构造包围prepare()。

  4. 尝试:

    if (mRecorder == null) {
        try {
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mRecorder.setOutputFile("/dev/null"); 
    
            mRecorder.prepare();
            mRecorder.start();
            mEMA = 0.0;
        }
        catch (IOException e) {
            //do something with e
        }
    }