2011-12-15 16 views
8

Desidero che l'app per Android riconosca il suono. Ad esempio voglio sapere se il suono del microfono è un battito di mani o bussare o qualcos'altro.Riconoscimento audio in Android

Ho bisogno di usare la matematica, o posso semplicemente usare qualche libreria per quello?

Se ci sono librerie per l'analisi del suono, per favore fatemelo sapere. Grazie.

+0

Controlla questo post: http://stackoverflow.com/questions/2257075/real-time-audio-processing-in-android – coder

+0

Sì, ho letto sulla classe AudioRecord. Il metodo Read() di questa classe restituisce dati non elaborati, che devono essere analizzati utilizzando la matematica. Ma sto chiedendo se ci sono alcune API di terze parti per analizzare un suono senza matematica? – Elephant

risposta

2

Non hai bisogno di matematica e non hai bisogno di AudioRecord. Basta controllare MediaRecorder.getMaxAmplitude() ogni 1000 millisecondi.

this code e this code potrebbero essere utili.

Ecco un codice che è necessario.

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

Il codice dell'esempio reagirà a qualsiasi suono forte (non solo battendo le mani). Non può riconoscere la natura del suono. Ho ragione? – Elephant

+1

Corretto Questo codice riconosce solo i rumori forti o non forti in base a una soglia. È molto semplice ma utile per molte applicazioni – gregm

1

Mi rendo conto che questo è un anno, ma mi sono imbattuto in esso. Sono abbastanza sicuro che il riconoscimento generale del suono a dominio aperto non è un problema risolto. Quindi, no, non troverai nessun tipo di libreria per fare ciò che vuoi su Android, perché tale codice non esiste ancora. Se scegli un dominio limitato, potresti addestrare un classificatore per riconoscere i tipi di suoni che ti interessano, ma ciò richiederebbe molta matematica e molti esempi di ciascuno dei potenziali suoni. Sarebbe bello se la libreria che volevi esistesse, ma per quanto ne so, la tecnologia non è ancora lì.

10

Musicg la libreria è utile per il rilevamento del fischio. Per quanto riguarda gli applausi, non lo consiglierei di usarlo, perché reagisce ad ogni suono forte (anche parlato).

Per il rilevamento di battiti e altri suoni percussivi, suggerisco TarsosDSP. Ha una semplice API con una ricca funzionalità (rilevamento del pitch e così via). Per il rilevamento clap si può usare qualcosa di simile (se si utilizza 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(); 

È possibile sintonizzare il vostro rivelatore regolando sensibilità (0-100) e la soglia (0-20).

Buona fortuna!

+0

Non riesco a rilevare il suono clap usando questo. Rileva solo i fischietti ... Puoi aiutarmi? Voglio rilevare l'applauso, fischiare così come i suoni di schiocco delle dita. –

+0

@ArpitPatel hai rilevato correttamente il suono del whistle in musicg api ?? sto ricevendo errore per favore sostenimi http://stackoverflow.com/questions/37925382/detectionapi-supports-mono-wav-only –