2011-12-15 13 views
8

Androidアプリでサウンドを認識したい。たとえば、マイクの音が拍手やノックなどであるかどうかを知りたいです。Androidでのサウンド認識

数学を使用する必要がありますか、それともライブラリを使用するだけですか?

サウンド解析用のライブラリがある場合は、教えてください。ありがとう。

+0

この投稿をチェックしてください:http://stackoverflow.com/questions/2257075/real-time-audio-processing-in-android – coder

+0

はい、私はAudioRecordクラスについて読んだことがあります。メソッドこのクラスのRead()は、生のデータを返します。生データは、数学を使用して解析する必要があります。しかし、私は、数学を使わないで音を分析するために3番目の部分的なAPIがあるかどうか尋ねています。 – Elephant

答えて

2

あなたは数学を必要とせず、AudioRecordは必要ありません。 1000ミリ秒ごとにMediaRecorder.getMaxAmplitude()をチェックするだけです。

this codeおよびthis codeが役に立ちます。

ここに必要なコードがいくつかあります。

public class Clapper 
{ 
    private static final String TAG = "Clapper"; 

    private static final long DEFAULT_CLIP_TIME = 1000; 
    private long clipTime = DEFAULT_CLIP_TIME; 
    private AmplitudeClipListener clipListener; 

    private boolean continueRecording; 

    /** 
    * how much louder is required to hear a clap 10000, 18000, 25000 are good 
    * values 
    */ 
    private int amplitudeThreshold; 

    /** 
    * requires a little of noise by the user to trigger, background noise may 
    * trigger it 
    */ 
    public static final int AMPLITUDE_DIFF_LOW = 10000; 
    public static final int AMPLITUDE_DIFF_MED = 18000; 
    /** 
    * requires a lot of noise by the user to trigger. background noise isn't 
    * likely to be this loud 
    */ 
    public static final int AMPLITUDE_DIFF_HIGH = 25000; 

    private static final int DEFAULT_AMPLITUDE_DIFF = AMPLITUDE_DIFF_MED; 

    private MediaRecorder recorder; 

    private String tmpAudioFile; 

    public Clapper() throws IOException 
    { 
     this(DEFAULT_CLIP_TIME, "/tmp.3gp", DEFAULT_AMPLITUDE_DIFF, null, null); 
    } 

    public Clapper(long snipTime, String tmpAudioFile, 
      int amplitudeDifference, Context context, AmplitudeClipListener clipListener) 
      throws IOException 
    { 
     this.clipTime = snipTime; 
     this.clipListener = clipListener; 
     this.amplitudeThreshold = amplitudeDifference; 
     this.tmpAudioFile = tmpAudioFile; 
    } 

    public boolean recordClap() 
    { 
     Log.d(TAG, "record clap"); 
     boolean clapDetected = false; 

     try 
     { 
      recorder = AudioUtil.prepareRecorder(tmpAudioFile); 
     } 
     catch (IOException io) 
     { 
      Log.d(TAG, "failed to prepare recorder ", io); 
      throw new RecordingFailedException("failed to create recorder", io); 
     } 

     recorder.start(); 
     int startAmplitude = recorder.getMaxAmplitude(); 
     Log.d(TAG, "starting amplitude: " + startAmplitude); 

     do 
     { 
      Log.d(TAG, "waiting while recording..."); 
      waitSome(); 
      int finishAmplitude = recorder.getMaxAmplitude(); 
      if (clipListener != null) 
      { 
       clipListener.heard(finishAmplitude); 
      } 

      int ampDifference = finishAmplitude - startAmplitude; 
      if (ampDifference >= amplitudeThreshold) 
      { 
       Log.d(TAG, "heard a clap!"); 
       clapDetected = true; 
      } 
      Log.d(TAG, "finishing amplitude: " + finishAmplitude + " diff: " 
        + ampDifference); 
     } while (continueRecording || !clapDetected); 

     Log.d(TAG, "stopped recording"); 
     done(); 

     return clapDetected; 
    } 

    private void waitSome() 
    { 
     try 
     { 
      // wait a while 
      Thread.sleep(clipTime); 
     } catch (InterruptedException e) 
     { 
      Log.d(TAG, "interrupted"); 
     } 
    } 

    /** 
    * need to call this when completely done with recording 
    */ 
    public void done() 
    { 
     Log.d(TAG, "stop recording"); 
     if (recorder != null) 
     { 
      if (isRecording()) 
      { 
       stopRecording(); 
      } 
      //now stop the media player 
      recorder.stop(); 
      recorder.release(); 
     } 
    } 

    public boolean isRecording() 
    { 
     return continueRecording; 
    } 

    public void stopRecording() 
    { 
     continueRecording = false; 
    } 
} 
+4

あなたの例のコードは大きな音に反応します(拍手だけでなく)。音の性質を認識することはできません。私は正しい? – Elephant

+1

修正このコードでは、スレッショルドに基づいてラウドノイズとノーノイズは認識されません。これは非常にシンプルですが、多くのアプリケーションで便利です – gregm

1

私はこれが1年であることを認識していますが、私はそれを見つけました。私は一般的な、オープンドメインの音声認識は解決された問題ではないと確信しています。そういうわけで、あなたはAndroidで必要なことをするためのライブラリを見つけることはできません。なぜなら、そのようなコードはまだどこにも存在しないからです。制限されたドメインを選択すると、クラシファイアを訓練して興味のある種​​類の音を認識させることができますが、それには数多くの数学が必要であり、それぞれの可能性のある音の例がたくさんあります。あなたが望む図書館が存在していればそれはかなり涼しいですが、私が知る限り、その技術はまだそこにはありません。

10

Musicgライブラリはホイッスル検出に役立ちます。拍手に関しては、私はそれを使用することをお勧めしません。なぜなら、それはあらゆる大きな音(たとえスピーチ)にも反応するからです。

拍手などのパーカッションサウンドの検出については、TarsosDSPをお勧めします。豊富な機能(ピッチ検出など)を備えたシンプルなAPIを備えています。

MicrophoneAudioDispatcher mDispatcher = new MicrophoneAudioDispatcher((int) SAMPLE_RATE, BUFFER_SIZE, BUFFER_OVERLAP); 
double threshold = 8; 
double sensitivity = 20; 
mPercussionDetector = new PercussionOnsetDetector(22050, 1024, 
     new OnsetHandler() { 

      @Override 
      public void handleOnset(double time, double salience) { 
       Log.d(TAG, "Clap detected!"); 
      } 
     }, sensitivity, threshold); 
mDispatcher.addAudioProcessor(mPercussionDetector); 
new Thread(mDispatcher).start(); 

あなたは感度(0-100)としきい値(0-20)を調整することにより、チューニング検出器をすることができます:拍手の検出のために何か(あなたはTarsosDSPAndroid-V3を使用している場合)などを使用することができます。

幸運を祈る!

+0

私はこれを使用して拍手音を検出することができません。それだけで笛を検出します...あなたは私を助けることができますか?私は拍手、笛、指のスナップ音を検出したい。 –

+0

@ArpitPatelあなたは正常に音楽APIでホイッスルサウンドを検出しましたか?私はエラーが発生しています。私をサポートしてくださいhttp://stackoverflow.com/questions/37925382/detectionapi-supports-mono-wav-only –