2011-12-15 3 views
8

Android 앱에서 소리를 인식하도록합니다. 예를 들어, 마이크에서 나는 소리가 들리거나 두드리는 소리인지 알고 싶습니다.Android에서 소리 인식

수학을 사용해야합니까, 아니면 그 라이브러리를 사용할 수 있습니까?

사운드 분석을위한 라이브러리가 있다면 알려주십시오. 감사.

+0

이 게시물을 확인하십시오 : http://stackoverflow.com/questions/2257075/real-time-audio-processing-in-android – coder

+0

예, AudioRecord 클래스에 대해 읽었습니다. 메서드이 클래스의 Read()는 수학을 사용하여 분석해야하는 원시 데이터를 반환합니다. 그러나 수학없이 소리를 분석 할 수있는 세 번째 부분 API가 있는지 묻습니다. – Elephant

답변

2

수학이 필요하지 않으므로 AudioRecord가 필요하지 않습니다. 1000 밀리 초마다 MediaRecorder.getMaxAmplitude()를 확인하십시오.

this codethis 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 년 된 것을 알고 있지만, 나는 그것을 우연히 발견했다. 나는 일반적인 오픈 도메인 사운드 인식이 해결 된 문제가 아니라고 확신한다. 따라서 안드로이드에서 원하는 것을 할 수있는 라이브러리를 찾지 않을 것입니다. 왜냐하면 그러한 코드는 아직 어디에도 존재하지 않기 때문입니다. 제한된 도메인을 선택하면 분류기를 학습하여 관심있는 소리의 종류를 인식 할 수 있지만 많은 수학이 필요하며 각각의 잠재적 인 소리의 예제가 많이 필요합니다. 당신이 원했던 라이브러리가 존재했다면 아주 멋지 겠지만, 제가 아는 한, 그 기술은 아직 존재하지 않습니다.

10

Musicg 라이브러리는 호각 감지에 유용합니다. 박수와 관련해서는 사용하지 않는 것이 좋습니다. 모든 큰 소리 (심지어는 말)에 반응해야하기 때문입니다.

박수 소리 및 기타 퍼커션 사운드 감지에 대해서는 TarsosDSP을 권장합니다. 풍부한 기능 (피치 감지 등)을 갖춘 간단한 API를 가지고 있습니다. 박수 탐지를 들어 당신이 뭔가를 사용할 수 있습니다 (당신은 TarsosDSPAndroid-V3를 사용하는 경우) :

당신은 조정 감도 (0 ~ 100) 및 임계 값 (0 ~ 20)을 조정하여 검출기를 할 수
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

나는 이것을 사용하여 박수 소리를 감지 할 수 없습니다. 호루라기 만 감지 할거야 ... 도와 줄 수있어? 나는 박수와 휘파람뿐만 아니라 손가락 스냅 소리를 감지하고 싶다. –

+0

@ArpitPatel 음악 API에서 휘파람 소리를 성공적으로 감지 했습니까? 오류가 발생했습니다. 나를 지원하십시오 http://stackoverflow.com/questions/37925382/detectionapi-supports-mono-wav-only –