/* * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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. */ package com.amazonaws.mobileconnectors.lex.interactionkit.internal.audio; import android.os.AsyncTask; import android.util.Log; import com.amazonaws.AmazonClientException; import com.amazonaws.mobileconnectors.lex.interactionkit.internal.audio.AudioRecordingTask.AudioRecordingTaskState; import com.amazonaws.mobileconnectors.lex.interactionkit.internal.audio.common.Progress; import com.google.common.base.Preconditions; /** * A task that do the audio recording in the background thread. */ public class AudioRecordingTask extends AsyncTask<Void, Progress<AudioRecordingTaskState>, Void> { private static final String TAG = AudioRecordingTask.class.getCanonicalName(); private final AudioRecorder mAudioRecorder; private final AudioRecordingTaskListener mListener; /** * Create an audio recording task. * @param audioRecorder the audio recorder that records audio. * @param listener the task listener used to handle the audio events. */ public AudioRecordingTask(final AudioRecorder audioRecorder, final AudioRecordingTaskListener listener) { mAudioRecorder = Preconditions.checkNotNull(audioRecorder, "Audio recorder cannot be null."); mListener = Preconditions.checkNotNull(listener, "Listener for this task cannot be null"); mAudioRecorder.setAudioSourceListener(new AudioRecorderListener()); } @SuppressWarnings("unchecked") @Override protected Void doInBackground(final Void... params) { try { mAudioRecorder.startRecording(); } catch (final Exception e) { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.Error, e)); } return null; } @Override protected void onProgressUpdate(final Progress<AudioRecordingTaskState>... updates) { Preconditions.checkNotNull(updates, "Updates cannot be null."); Preconditions.checkArgument(updates.length == 1, "Only one update is allowed."); final Progress<AudioRecordingTaskState> update = updates[0]; Log.v(TAG, "onProgressUpdate: " + update.getState().toString()); final Object payload = update.getPayload(); if (mListener != null) { switch (update.getState()) { case ReadyForSpeech: mListener.onReadyForSpeech(); break; case BeginningOfSpeech: mListener.onBeginningOfSpeech(); break; case BufferReceived: if (payload != null && payload instanceof byte[]) { mListener.onBufferReceived((byte[]) payload); } break; case RmsChanged: if (payload != null && payload instanceof Float) { mListener.onRmsChanged((Float) payload); } break; case SilenceDetected: mListener.onSilenceDetected(); break; case Error: if (payload != null && payload instanceof AmazonClientException) { mListener.onError((AmazonClientException) payload); } break; case NoSpeechTimeout: mListener.onNoSpeechTimeout(); break; case MaxSpeechTimeout: mListener.onMaxSpeechTimeout(); break; default: mListener.onError(new AmazonClientException("Received an unknown progress update")); break; } } else { Log.w(TAG, "Audio recording task listener is null."); } } /** * Stop the recorder. */ public void stopRecording() { Log.v(TAG, "stop recording"); mAudioRecorder.cancel(); } /** * The various states of the {@link AudioRecordingTask}. */ public static enum AudioRecordingTaskState { /** * The end pointer is ready for speech. */ ReadyForSpeech, /** * The audio recorder starts recording. */ BeginningOfSpeech, /** * Buffer received from the audio recorder. */ BufferReceived, /** * The sound level changed in the recorded audio. */ RmsChanged, /** * Silence detected by the end pointer. */ SilenceDetected, /** * Recorder stopped by the user. */ EndOfSpeech, /** * There is an error. */ Error, /** * No speech timeout fired. */ NoSpeechTimeout, /** * Max speech timeout fired. */ MaxSpeechTimeout } /** * An AudioSourceListener implementation for the {@link AudioRecordingTask}. */ @SuppressWarnings("unchecked") private class AudioRecorderListener implements AudioSourceListener { @Override public void onReadyForSpeech() { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.ReadyForSpeech)); } @Override public void onBeginningOfSpeech() { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.BeginningOfSpeech)); } @Override public void onRmsChanged(final float rmsdB) { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.RmsChanged, rmsdB)); } @Override public void onBufferReceived(final byte[] buffer) { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.BufferReceived, buffer)); } @Override public void onSilenceDetected() { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.SilenceDetected)); } @Override public void onNoSpeechTimeout() { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.NoSpeechTimeout)); } @Override public void onMaxSpeechTimeout() { publishProgress(new Progress<AudioRecordingTaskState>(AudioRecordingTaskState.MaxSpeechTimeout)); } } }