Android:检查麦克风是否收到任何声音

时间:2016-06-18 16:54:02

标签: java android audio android-studio-2.0

我是Android新手,我正在开发Android Studio上的听力计。其中一个步骤是查看麦克风是否正在接收我从耳机发送的声音,以检查它们是否正常工作。

我在同一个活动中做两件事,发送声音,并检查是否有声音进入。

我能够使用AudioTrack类发送1kHz频率的音调2秒钟,下一步是检查麦克风是否接收到接近该频率的信号。由于我甚至无法使麦克风工作,我正在降低我的目标,只是检查麦克风是否正在接收任何东西。

我检查了几个链接,没有人帮助我,或者因为我不熟悉android或者因为它不是我需要的,其中包括: Detect sound levelHow to detect when a user stops talking into the microphoneDetect 'Whistle' sound in android

我已经将权限放在Manifest上了:

<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我的CalibrationActivity.java是:

import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack; 
import android.media.MediaRecorder;    
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.IOException;

public class CalibrationActivity extends AppCompatActivity {

private MediaRecorder myRecorder;
private String outputFile = null;

private final int duration = 2; // seconds
private final int sampleRate = 4000;
private final int numSamples = duration * sampleRate;
private final double sample[] = new double[numSamples];
private final double freqOfTone = 1000; // hz

private final byte generatedSnd[] = new byte[2 * numSamples];

Handler handler = new Handler();

int getAmplitude = myRecorder.getMaxAmplitude();

public int result(){
    if (getAmplitude != 0) {
        return 1;
    }else {
        return 0;
    }
}


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

    outputFile = Environment.getExternalStorageDirectory().
        getAbsolutePath() + "/teste.3gpp";

    myRecorder = new MediaRecorder();
    myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
    myRecorder.setOutputFile(outputFile);


    Intent intent;
    if(result()==1){
        intent = new Intent(this, FirstTestActivity.class);
    }else{
        intent = new Intent(this, End1Activity.class);
    }

}

void start_recording() {
    try {
        myRecorder.prepare();
        myRecorder.start();
    } catch (IllegalStateException e) {
        // start:it is called before prepare()
        // prepare: it is called after start() or before setOutputFormat()
        e.printStackTrace();
    } catch (IOException e) {
        // prepare() fails
        e.printStackTrace();
    }
}

void stop_recording(){

    try {
        myRecorder.stop();
        myRecorder.release();
        myRecorder  = null;
    } catch (IllegalStateException e) {
        //  it is called before start()
        e.printStackTrace();
    } catch (RuntimeException e) {
        // no valid audio/video data has been received
        e.printStackTrace();
    }
}

@Override
protected void onResume() {
    super.onResume();
    // Use a new tread as this can take a while
    final Thread thread = new Thread(new Runnable() {
        public void run() {
            genTone();
            handler.post(new Runnable() {

                public void run() {
                    playSound();

                }
            });
        }
    });
    thread.start();
            start_recording();
            SystemClock.sleep(3000);
            stop_recording();
}


void genTone() {
    // fill out the array
    for (int i = 0; i < numSamples; ++i) {
        sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / freqOfTone));
    }

    // convert to 16 bit pcm sound array
    // assumes the sample buffer is normalised.
    int idx = 0;
    for (final double dVal : sample) {
        // scale to maximum amplitude
        final short val = (short) ((dVal * 32767));
        // in 16 bit wav PCM, first byte is the low order byte
        generatedSnd[idx++] = (byte) (val & 0x00ff);
        generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);

    }
}

void playSound() {
    final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
            AudioTrack.MODE_STATIC);
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
    audioTrack.play();
  }

  }

我根据我在网上找到的示例写了这些内容,主要来自hereherehere,所以代码的一些部分我并不真正理解

这里的想法是从耳机发送声音,并且将通知用户将他们的耳机靠近麦克风。然后,代码应让麦克风录音3秒,然后检查声音的幅度是否不同于0,如果是这种情况,则应用程序转到FirstTestActivity,否则转到End1Activity。但是一旦我尝试运行代码,应用程序突然崩溃,我不知道为什么。我已经工作了几个星期,我找不到一个可能非常简单的解决方案。先谢谢你。

1 个答案:

答案 0 :(得分:0)

根据您对该主题的了解不足,您可能只需使用一个库,而不是here