Android Open Source - api-ai-android-sdk Speaktoit Recognition Service Impl






From Project

Back to project page api-ai-android-sdk.

License

The source code is released under:

Apache License

If you think the Android project api-ai-android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package ai.api;
/*from   www.jav a  2s.  c  om*/
/***********************************************************************************************************************
 *
 * API.AI Android SDK - client-side libraries for API.AI
 * =================================================
 *
 * Copyright (C) 2014 by Speaktoit, Inc. (https://www.speaktoit.com)
 * https://www.api.ai
 *
 ***********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 ***********************************************************************************************************************/

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.util.Log;

import ai.api.model.AIContext;
import ai.api.model.AIError;
import ai.api.model.AIResponse;
import ai.api.util.VoiceActivityDetector;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SpeaktoitRecognitionServiceImpl extends AIService {

    public static final String TAG = SpeaktoitRecognitionServiceImpl.class.getName();

    private static final int SAMPLE_RATE_IN_HZ = 16000;
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;

    private AudioRecord mediaRecorder;
    private final Object mediaRecorderLock = new Object();

    private final ExecutorService eventsExecutor = Executors.newSingleThreadExecutor();

    private volatile boolean isRecording = false;

    private final VoiceActivityDetector voiceActivityDetector = new VoiceActivityDetector(SAMPLE_RATE_IN_HZ);

    protected SpeaktoitRecognitionServiceImpl(final Context context, final AIConfiguration config) {
        super(config, context);

        initMediaRecorder();
    }

    private void initMediaRecorder() {
        final int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT);
        mediaRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                SAMPLE_RATE_IN_HZ,
                CHANNEL_CONFIG,
                AUDIO_FORMAT,
                minBufferSize);

        voiceActivityDetector.setMinAudioBufferSize(minBufferSize);

        voiceActivityDetector.setSpeechListener(new VoiceActivityDetector.SpeechEventsListener() {
            @Override
            public void onSpeechBegin() {
                Log.v(TAG, "onSpeechBegin event");
            }

            @Override
            public void onSpeechEnd() {
                Log.v(TAG, "onSpeechEnd event");
                eventsExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        stopListening();
                    }
                });
            }

            @Override
            public void onAudioLevelChanged(final double energy) {
                SpeaktoitRecognitionServiceImpl.this.onAudioLevelChanged((float) energy);
            }
        });
    }

    @Override
    public void startListening() {
        startListening(null);
    }

    @Override
    public void startListening(final List<AIContext> contexts) {
        Log.v(TAG, "startListening");
        synchronized (mediaRecorderLock) {
            if (!isRecording) {
                voiceActivityDetector.reset();

                mediaRecorder.startRecording();
                isRecording = true;

                onListeningStarted();

                new RequestTask(new RecorderWrapper(mediaRecorder), contexts).execute();
            } else {
                Log.w(TAG, "Trying start listening when it already active");
            }
        }
    }

    @Override
    public void stopListening() {
        Log.v(TAG, "stopListening");
        synchronized (mediaRecorderLock) {
            if (isRecording) {
                try {
                    mediaRecorder.stop();
                    isRecording = false;

                    onListeningFinished();
                } catch (final IllegalStateException e) {
                    Log.w(TAG, "Attempt to stop mediaRecorder when it is stopped");
                }
            }
        }
    }

    @Override
    public void cancel() {
        synchronized (mediaRecorderLock) {
            if (isRecording) {
                mediaRecorder.stop();
                isRecording = false;

                onListeningFinished();
            }
        }
    }

    @Override
    public void pause() {
        super.pause();

        synchronized (mediaRecorderLock) {
            if (isRecording) {
                mediaRecorder.stop();
                isRecording = false;
            }
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

    @Override
    public void resume() {
        super.resume();

        if (mediaRecorder == null) {
            initMediaRecorder();
        }
    }

    private class RecorderWrapper extends InputStream {

        private final AudioRecord audioRecord;

        private RecorderWrapper(final AudioRecord audioRecord) {
            this.audioRecord = audioRecord;
        }

        @Override
        public int read() throws IOException {
            final byte[] buffer = new byte[1];
            audioRecord.read(buffer,0,1);
            return buffer[0];
        }

        @Override
        public int read(final byte[] buffer, final int byteOffset, final int byteCount) throws IOException {
            //Log.v(TAG, "RecorderWrapper: read");
            final int bytesRead = audioRecord.read(buffer, byteOffset, byteCount);
            if (bytesRead > 0) {
                voiceActivityDetector.processBuffer(buffer, bytesRead);
            }
            return bytesRead;
        }
    }

    private class RequestTask extends AsyncTask<Void, Void, AIResponse> {

        private final RecorderWrapper recorderWrapper;
        private final List<AIContext> contexts;

        private AIError aiError;


        private RequestTask(final RecorderWrapper recorderWrapper) {
            this.recorderWrapper = recorderWrapper;
            contexts = null;
        }

        private RequestTask(final RecorderWrapper recorderWrapper, final List<AIContext> contexts) {
            this.recorderWrapper = recorderWrapper;
            this.contexts = contexts;
        }

        @Override
        protected AIResponse doInBackground(final Void... params) {
            try {
                final AIResponse aiResponse = aiDataService.voiceRequest(recorderWrapper, contexts);
                return aiResponse;
            } catch (final AIServiceException e) {
                aiError = new AIError("Wrong answer from server " + e.toString());
            }

            return null;
        }

        @Override
        protected void onPostExecute(final AIResponse aiResponse) {
            super.onPostExecute(aiResponse);

            if (aiResponse != null) {
                onResult(aiResponse);
            } else {
                onError(aiError);
            }
        }
    }

}




Java Source Code List

ai.api.AIConfiguration.java
ai.api.AIDataService.java
ai.api.AIListener.java
ai.api.AIServiceException.java
ai.api.AIService.java
ai.api.AudioRequestTask.java
ai.api.AudioRequest.java
ai.api.GoogleRecognitionServiceImpl.java
ai.api.GsonFactory.java
ai.api.RecognitionEngine.java
ai.api.RequestTask.java
ai.api.SpeaktoitRecognitionServiceImpl.java
ai.api.http.HttpClient.java
ai.api.model.AIContext.java
ai.api.model.AIError.java
ai.api.model.AIRequest.java
ai.api.model.AIResponse.java
ai.api.model.Constants.java
ai.api.model.Metadata.java
ai.api.model.QuestionMetadata.java
ai.api.model.Result.java
ai.api.model.Status.java
ai.api.sample.AIButtonSampleActivity.java
ai.api.sample.AIServiceSampleActivity.java
ai.api.sample.Config.java
ai.api.sample.MainActivity.java
ai.api.ui.AIButton.java
ai.api.ui.MaskedColorView.java
ai.api.ui.SoundLevelButton.java
ai.api.ui.SoundLevelCircleDrawable.java
ai.api.util.RecognizerChecker.java
ai.api.util.VoiceActivityDetector.java