-2

如何检测用户语音的幅度?只需检测用户是否说话。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;

} }

4

1 回答 1

1

有几件事:

  1. 您需要在 prepare() 语句之前设置输出格式。来自prepare()的文档:如果在之后或之前IllegalStateException调用它,则抛出start()setOutputFormat()

  2. MediaRecorder.prepare() 也会抛出 IOException。您可能希望用 try/catch 构造包围 prepare()。

尝试:

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
    }
}
于 2013-02-21T06:53:19.760 回答