如何触发声音input的振动?

我正在尝试创build一个Android应用程序,在此过滤一个特定频率的嘟嘟声,并使手机振动。

我正在从移动的MIC和使用MediaRecorder类的input,通过使用这个类,我可以logging,保存和播放input。 现在,只要有蜂鸣声或任何声音,我都需要手机振动。

input是通过电线给移动设备的耳机插孔,所以我知道只有一个频率input。

我有一个button,点击开始录制。 我有权限振动和logging在我的清单文件已经。

record.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { isRecording=true; myAudioRecorder.prepare(); myAudioRecorder.start(); ... } 

我也尝试search互联网,发现类似的问题在这里,但我无法find任何正确的答案。

不过,我可以让手机振动点击另一个button,这里是代码片段,

  Vibrator vibrate; vibrate = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); Btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { vibrate.vibrate(800); } } 

我试着在recorder.start()中调用一个振动器。 function,但即使没有声音,手机也会振动。 我也尝试从这个问题获得帮助,所以每当有沉默,手机不应该振动,但我感到困惑,我不知何故应该有一个布尔值得到真正的时候有声音,使手机振动,但我我无法把这个逻辑代码。 请让我知道我能在这方面做些什么,我应该在哪个方向寻找?

更新我发现这 toturial用input声音的幅度显示进度条,它工作正常,我试图让手机振动,当有一些价值的缓冲区,现在它振动,即使当幅度为零,我想这是因为每一次振动都会导致手机震动的噪音。 由于java.lang.RuntimeException,我无法通过TOAST检查函数:无法在未调用Looper.prepare()的线程中创build处理程序 。 有什么build议吗?

对于你的主要问题,也许你可以检查声音的幅度,只有达到最低门槛时才振动。 像这样的东西:

 private class DetectAmplitude extends AsyncTask<Void, Void, Void> { private MediaRecorder mRecorder = null; private final static int MAX_AMPLITUDE = 32768; //TODO: Investigate what is the ideal value for this parameter private final static int MINIMUM_REQUIRED_AVERAGE = 5000; @Override protected Void doInBackground(Void... params) { Boolean soundStarted = true; if (mRecorder == null) { mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mRecorder.setOutputFile("/dev/null"); try { mRecorder.prepare(); } catch (IllegalStateException e) { soundStarted = false; Log.e(TAG, "Could not detect background noise. Error preparing recorder: " + e.getMessage()); } catch (IOException e) { soundStarted = false; Log.e(TAG, "Could not detect background noise. Error preparing recorder: " + e.getMessage()); } try { mRecorder.start(); } catch (RuntimeException e) { Log.e(TAG, "Could not detect background noise. Error starting recorder: " + e.getMessage()); soundStarted = false; mRecorder.release(); mRecorder = null; } } if (soundStarted) { // Compute a simple average of the amplitude over one // second int nMeasures = 100; int sumAmpli = 0; mRecorder.getMaxAmplitude(); // First call returns 0 int n = 0; for (int i = 0; i < nMeasures; i++) { if (mRecorder != null) { int maxAmpli = mRecorder.getMaxAmplitude(); if (maxAmpli > 0) { sumAmpli += maxAmpli; n++; } } else { return null; } try { Thread.sleep(1000 / nMeasures); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } mRecorder.stop(); mRecorder.release(); mRecorder = null; final float avgAmpli = (float) sumAmpli / n; if (avgAmpli > MINIMUM_REQUIRED_AVERAGE) { //TODO: Vibrate the device here } } return null; } } 

有关声级检测的更多信息,请参阅以下内容:

  • android:检测声音级别
  • 对于MediaRecorder,Android的getMaxAmplitude()函数实际上给了我什么?

关于exceptionjava.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() ,这是因为Toast需要在应用程序的主线程上运行。 如果您的Thread代码(如AsyncTask )在一个Activity ,您可以尝试以下操作:

 runOnUiThread(new Runnable() { @Override public void run() { //Call your Toast here } }); 

否则,您需要以某种方式将您的方法的结论传递给Activity来运行Toast

编辑:

如果你想从Button使用它,你可以在你的ActivityonCreate()调用上设置它的OnClickListener ,并在那里执行AsyncTask 。 例如:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); Button button = (Button)findViewById(R.id.your_button_id); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new DetectAmplitude().execute(new Void[]{}); } }); } 

我build议你在生产代码中使用它之前,先看看AsyncTask是如何工作的 。

您想要对audio进行采样,并立即进行分析。

MediaRecorder对此似乎很高级,它只捕获文件。 您可能想要使用AudioRecorder ,因为它可以直接访问input样本。

为了检测特定的音色 ,可以在input样本上使用Goertzelalgorithm 。 这是我几年前做的一个C ++实现 ,可以作为一个例子。

为了检测超过某个阈值的任何声音,可以使用均方根分析对input样本进行分析,并在响度达到阈值时触发。 这是一个Python例子 ,可以响应来自麦克风的巨大噪音。

尝试这个:

 Btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { v.post(new Runnable() { @Override public void run() { vibrate.vibrate(800); } }); } }); 

你可以试试这个:

  Handler handler; Runnable r; handler = new Handler(); r = new Runnable() { public void run() { Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); vib.vibrate(500); handler.postDelayed(r, 1000); } }; handler.post(r);