Как распознать, когда пользователь START & STOP говорит в Android?(Распознавание голоса в Android) - PullRequest
3 голосов
/ 20 марта 2012

Я много занимался исследованиями и разработками, и потратил много ресурсов, чтобы решить мою проблему, но не смог найти правильного решения.

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

Необходимые функции:

1) когда USER начинает говорить, он должен записать аудио / видео и

2) когда пользователь перестает говорить, он должен воспроизвести записанное аудио / видео .

Примечание : Здесь видео означает, что пользователь выполняет в приложении в течение этого периода времени. Например, щелчки по кнопкам или какая-то анимация и т. Д.

Я не хочу использовать Google Voice Recognizer , доступный по умолчанию в Android, так как для этого требуется Интернет, но мое приложение работает в автономном режиме. Также я узнал о CMU-Sphinx . Но это не помогает в соответствии с моими требованиями.

РЕДАКТИРОВАНИЕ: - Кроме того, я хотел бы добавить, что я добился этого с помощью кнопки «Пуск и Стоп», но я не хочу использовать эти кнопки.

Если у кого-то есть идеи или предложения, пожалуйста, дайте мне знать.

Ответы [ 4 ]

3 голосов
/ 21 апреля 2012

Самый простой и распространенный метод - подсчитать количество пересечений нуля в аудио (т.е. когда знак меняется с положительного на отрицательный).

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

Объедините это с простым уровнем энергии (насколько громким является звук), и у вас есть решение, которое является довольно надежным.

Если вам нужна более точная система, она становится намного более сложной.Один из способов - извлечь аудиофункции (например, MFCC s) из «обучающих данных», смоделировать их с помощью чего-то вроде GMM , а затем протестировать функции, которые вы извлекаете из живого аудио.GMM.Таким образом, вы можете смоделировать вероятность того, что данный кадр звука является речью, а не речью.Однако это не простой процесс.

Я бы настоятельно рекомендовал идти по линиям пересечения нуля, поскольку он прост в реализации и отлично работает в 99% случаев:)

0 голосов
/ 22 апреля 2019

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

Recorder.getMaxAmplitude ();

пример кода:

public void startRecording() throws IOException {

    Thread thread = new Thread() {
        @Override
        public void run() {
            int i = 0;
            while (i == 0) {

                try {
                    sleep(100);

                    if (recorder != null) {

                        checkValue(recorder.getMaxAmplitude());

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };
    thread.start();


}

функция checkValue:

public void checkValue(int amplitude) {


    try{

        if (amplitude > 1000) {
            Log.d("I", "Amplitude : " + amplitude);
            amplitude = recorder.getMaxAmplitude();
            Thread.sleep(2000);
            isListened=true;
        }else if(isListened) {
            Log.d("I","Stop me");
            recordingDialog.dismiss();
        }

    }catch (Exception e){
        e.printStackTrace();
    }


}

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

0 голосов
/ 21 апреля 2012

ниже - это код, который я использую для приложения iPhone, которое делает точно то же самое. Код написан на Objective-C ++, но в нем много комментариев. Этот код выполняется внутри функции обратного вызова очереди записи. Я уверен, что подобный подход существует для платформы Android.

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

Попробуйте реализовать его на платформе Android, и все готово!

// If there are some audio samples in the audio buffer of the recording queue
if (inNumPackets > 0) {
        // The following 4 lines of code are vector functions that compute 
        // the average power of the current audio samples. 
        // Go [here][2] to view documentation about them. 
        vDSP_vflt16((SInt16*)inBuffer->mAudioData, 1, aqr->currentFrameSamplesArray, 1, inNumPackets);
        vDSP_vabs(aqr->currentFrameSamplesArray, 1, aqr->currentFrameSamplesArray, 1, inNumPackets);
        vDSP_vsmul(aqr->currentFrameSamplesArray, 1, &aqr->divider, aqr->currentFrameSamplesArray, 1, inNumPackets);
        vDSP_sve(aqr->currentFrameSamplesArray, 1, &aqr->instantPower, inNumPackets);
        // InstantPower holds the energy for the current audio samples
        aqr->instantPower /= (CGFloat)inNumPackets;
        // S.O.S. Avoid +-infs, NaNs add a small number to InstantPower
        aqr->instantPower = log10f(aqr->instantPower + 0.001f);
        // InstantAvgPower holds the energy for a bigger window 
        // of time than InstantPower
        aqr->instantAvgPower = aqr->instantAvgPower * 0.95f + 0.05f * aqr->instantPower;
        // AvgPower holds the energy for an even bigger window 
        // of time than InstantAvgPower
        aqr->avgPower = aqr->avgPower * 0.97f + 0.03f * aqr->instantAvgPower;
        // This is the ratio that tells us when to record
        CGFloat ratio = aqr->avgPower / aqr->instantPower;
        // If we are not already writing to an audio file and 
        // the ratio is bigger than a specific hardcoded value 
        // (this value has to do with the quality of the microphone 
        // of the device. I have set it to 1.5 for an iPhone) then start writing!
        if (!aqr->writeToFile && ratio > aqr->recordingThreshold) {
            aqr->writeToFile = YES;
        } 
        if (aqr->writeToFile) {
            // write packets to file
            XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize,
                                                inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData),
                          "AudioFileWritePackets failed");
            aqr->mRecordPacket += inNumPackets;
            // Now if we are recording but the instantAvgPower is lower 
            // than avgPower then we increase the countToStopRecording counter
            if (aqr->instantAvgPower < aqr->avgPower) {
                aqr->countToStopRecording++;
            } 
            // or else set him to 0.
            else {
                aqr->countToStopRecording = 0;
            }
            // If we have detected that there is not enough power in 30 consecutive
            // audio sample buffers OR we have recorded TOO much audio 
            // (the user speaks for more than a threshold of time) stop recording 
            if (aqr->countToStopRecording > 30 || aqr->mRecordPacket > kMaxAudioPacketsDuration) {
                aqr->countToStopRecording = 0;
                aqr->writeToFile = NO;
                // Notify the audio player that we finished recording 
                // and start playing the audio!!!
                dispatch_async(dispatch_get_main_queue(), ^{[[NSNotificationCenter defaultCenter] postNotificationName:@"RecordingEndedPlayNow" object:nil];});
            }
        }
    }

Best!

0 голосов
/ 21 марта 2012

Вы можете попробовать добавить слушателей к событиям приложения, таким как навигация, анимация и т. Д. в реализации слушателей вы можете запускать функции запуска / остановки ...

http://tseng -blog.nge-web.net / блог / 2009/02/14 / реализации-слушатели-в-ваш-андроида-Java-приложение /

посмотрите на эти примеры ... это может быть полезно для вас ....


но мне интересно, что то, что вы описали в поведении своего приложения, выглядит так, как будто вы собираетесь заново изобрести разговор с Томом, да? :-P

...