Распознавание звука в Android - PullRequest
11 голосов
/ 15 декабря 2011

Я хочу, чтобы мое приложение для Android распознало звук.Например, я хочу знать, является ли звук из микрофона хлопком или стуком, или что-то еще.

Нужно ли мне использовать математику или я могу просто использовать какую-то библиотеку для этого?

ЕслиЕсть ли библиотеки для анализа звука, пожалуйста, дайте мне знать.Спасибо.

Ответы [ 4 ]

11 голосов
/ 16 сентября 2014

Musicg библиотека полезна для обнаружения свистка. Что касается хлопков, я бы не рекомендовал использовать его, потому что он реагирует на каждый громкий звук (даже речь).

Для обнаружения хлопков и других ударных звуков я рекомендую TarsosDSP . Он имеет простой API с богатым функционалом (определение высоты тона и т. Д.). Для обнаружения хлопка вы можете использовать что-то вроде (если вы используете 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();

Вы можете настроить детектор, отрегулировав чувствительность (0-100) и порог (0-20).

Удачи!

4 голосов
/ 25 декабря 2012

На мой взгляд, есть Api, который очень хорошо подходит для ваших нужд.

http://code.google.com/p/musicg/

Удачи !!!

2 голосов
/ 01 марта 2012

Вам не нужна математика и вам не нужна AudioRecord.Просто проверяйте MediaRecorder.getMaxAmplitude () каждые 1000 миллисекунд.

этот код и этот код может быть полезным.

Вот код, который вы будете использоватьнужно.

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;
    }
}
1 голос
/ 03 декабря 2012

Я понимаю, что это год, но я наткнулся на это.Я уверен, что в целом распознавание звука в открытой области не является решенной проблемой.Итак, нет, вы не найдете какой-либо библиотеки, которая будет делать то, что вы хотите на Android, потому что такого кода еще нигде не существует.Если вы выберете какой-либо ограниченный домен, вы можете обучить классификатор распознавать типы звуков, которые вас интересуют, но для этого потребуется много математики и множество примеров каждого из потенциальных звуков.Было бы здорово, если бы библиотека, которую вы хотели, существовала, но, насколько я знаю, технологии просто еще не было.

...