2011-12-15 39 views
8

Tôi muốn ứng dụng Android của mình nhận ra âm thanh. Ví dụ tôi muốn biết nếu âm thanh từ micro là một vỗ tay hoặc gõ hay cái gì khác.Nhận dạng âm thanh trong Android

Tôi có cần sử dụng toán học không hoặc tôi có thể sử dụng một số thư viện cho điều đó không?

Nếu có bất kỳ thư viện nào để phân tích âm thanh, vui lòng cho tôi biết. Cảm ơn.

+0

Khám phá bài đăng này: http://stackoverflow.com/questions/2257075/real-time-audio-processing-in-android – coder

+0

Có, tôi đã đọc về lớp AudioRecord. Phương thức Read() của lớp này trả về dữ liệu thô, cần được phân tích bằng cách sử dụng toán học. Nhưng tôi hỏi liệu có một số API phần ba để phân tích một âm thanh không có toán học? – Elephant

Trả lời

2

Bạn không cần toán và bạn không cần AudioRecord. Chỉ cần kiểm tra MediaRecorder.getMaxAmplitude() sau mỗi 1000 mili giây.

this codethis code có thể hữu ích.

Dưới đây là một số mã bạn sẽ cần.

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

Mã từ ví dụ của bạn sẽ phản ứng với bất kỳ âm thanh lớn nào (không chỉ vỗ tay). Nó không thể nhận ra bản chất của âm thanh. Tôi có đúng không? – Elephant

+1

Đúng Mã này sẽ chỉ nhận ra tiếng ồn lớn và không ồn ào dựa trên ngưỡng. Nó rất đơn giản nhưng hữu ích cho nhiều ứng dụng – gregm

1

Tôi nhận thấy đây là một năm cũ, nhưng tôi tình cờ gặp nó. Tôi khá chắc chắn rằng chung, mở công nhận âm thanh miền không phải là một vấn đề giải quyết. Vì vậy, không, bạn sẽ không tìm thấy bất kỳ loại thư viện nào để làm những gì bạn muốn trên Android, bởi vì mã như vậy không tồn tại ở bất cứ đâu. Nếu bạn chọn một số miền bị hạn chế, bạn có thể đào tạo một trình phân loại để nhận ra các loại âm thanh mà bạn quan tâm, nhưng điều đó đòi hỏi nhiều toán và rất nhiều ví dụ về từng âm thanh tiềm năng. Sẽ rất tuyệt nếu thư viện bạn muốn tồn tại, nhưng theo như tôi biết, công nghệ này chưa có.

10

Musicg thư viện rất hữu ích để phát hiện tiếng còi. Liên quan đến vỗ tay, tôi sẽ không khuyên bạn nên sử dụng nó, gây ra nó phản ứng với mọi âm thanh lớn (ngay cả bài phát biểu).

Để vỗ tay và phát hiện âm thanh bộ gõ khác, tôi khuyên bạn nên TarsosDSP. Nó có một API đơn giản với một chức năng phong phú (phát hiện sân và vân vân). Để phát hiện vỗ tay bạn có thể sử dụng một cái gì đó tương tự (nếu bạn sử dụng TarsosDSPAndroid-v3):

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(); 

Bạn có thể điều chỉnh dò ​​của bạn bằng cách điều chỉnh độ nhạy cảm (0-100) và ngưỡng (0-20).

Chúc may mắn!

+0

Tôi không thể phát hiện âm thanh vỗ tay bằng cách sử dụng này. Nó sẽ chỉ phát hiện còi ... Bạn có thể giúp tôi không? Tôi muốn phát hiện tiếng vỗ tay, tiếng huýt sáo và tiếng ngón tay. –

+0

@ArpitPatel bạn đã phát hiện thành công âm thanh tiếng còi trong musicg api chưa ?? tôi đang gặp lỗi. hãy ủng hộ tôi http://stackoverflow.com/questions/37925382/detectionapi-supports-mono-wav-only –

Các vấn đề liên quan