aboutsummaryrefslogtreecommitdiff
path: root/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/AudioRecordThread.java
diff options
context:
space:
mode:
Diffstat (limited to 'apps/OboeTester/app/src/main/java/com/mobileer/oboetester/AudioRecordThread.java')
-rw-r--r--apps/OboeTester/app/src/main/java/com/mobileer/oboetester/AudioRecordThread.java162
1 files changed, 162 insertions, 0 deletions
diff --git a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/AudioRecordThread.java b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/AudioRecordThread.java
new file mode 100644
index 00000000..7b472237
--- /dev/null
+++ b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/AudioRecordThread.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.mobileer.oboetester;
+
+
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+
+/**
+ * Abstract class for recording.
+ * Call processBuffer(buffer) when data is read.
+ */
+class AudioRecordThread implements Runnable {
+ private static final String TAG = "AudioRecordThread";
+
+ private final int mSampleRate;
+ private final int mChannelCount;
+ private Thread mThread;
+ protected boolean mGo;
+ private AudioRecord mRecorder;
+ private CircularCaptureBuffer mCaptureBuffer;
+ protected float[] mBuffer = new float[256];
+ private static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_FLOAT;
+ private Runnable mTask;
+ private int mTaskCountdown;
+ private boolean mCaptureEnabled = true;
+
+ public AudioRecordThread(int frameRate, int channelCount, int maxFrames) {
+ mSampleRate = frameRate;
+ mChannelCount = channelCount;
+ mCaptureBuffer = new CircularCaptureBuffer(maxFrames);
+ }
+
+ private void createRecorder() {
+ int channelConfig = (mChannelCount == 1)
+ ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO;
+ int audioFormat = AudioFormat.ENCODING_PCM_FLOAT;
+ int minRecordBuffSizeInBytes = AudioRecord.getMinBufferSize(mSampleRate,
+ channelConfig,
+ audioFormat);
+ mRecorder = new AudioRecord(
+ MediaRecorder.AudioSource.VOICE_RECOGNITION,
+ mSampleRate,
+ channelConfig,
+ audioFormat,
+ 2 * minRecordBuffSizeInBytes);
+ if (mRecorder.getState() == AudioRecord.STATE_UNINITIALIZED) {
+ throw new RuntimeException("Could not make the AudioRecord - UNINITIALIZED");
+ }
+ }
+
+ @Override
+ public void run() {
+ startAudioRecording();
+
+ while (mGo) {
+ int result = handleAudioPeriod();
+ if (result < 0) {
+ mGo = false;
+ }
+ }
+
+ stopAudioRecording();
+ }
+
+ public void startAudio() {
+ if (mThread == null) {
+ mGo = true;
+ mThread = new Thread(this);
+ mThread.start();
+ }
+ }
+
+ public void stopAudio() {
+ mGo = false;
+ if (mThread != null) {
+ try {
+ mThread.join(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ mThread = null;
+ }
+ }
+
+ public int getSampleRate() {
+ return mSampleRate;
+ }
+
+ /**
+ * @return number of samples read or negative error
+ */
+ private int handleAudioPeriod() {
+ int numSamplesRead = mRecorder.read(mBuffer, 0, mBuffer.length,
+ AudioRecord.READ_BLOCKING);
+ if (numSamplesRead <= 0) {
+ return numSamplesRead;
+ } else {
+ if (mTaskCountdown > 0) {
+ mTaskCountdown -= numSamplesRead;
+ if (mTaskCountdown <= 0) {
+ mTaskCountdown = 0;
+ new Thread(mTask).start(); // run asynchronously with audio thread
+ }
+ }
+ if (mCaptureEnabled) {
+ return mCaptureBuffer.write(mBuffer, 0, numSamplesRead);
+ } else {
+ return numSamplesRead;
+ }
+ }
+ }
+
+ private void startAudioRecording() {
+ stopAudioRecording();
+ createRecorder();
+ mRecorder.startRecording();
+ }
+
+ private void stopAudioRecording() {
+ if (mRecorder != null) {
+ mRecorder.stop();
+ mRecorder.release();
+ mRecorder = null;
+ }
+ }
+
+ /**
+ * Schedule task to be run on its own thread when numSamples more samples have been recorded.
+ *
+ * @param numSamples
+ * @param task
+ */
+ public void scheduleTask(int numSamples, Runnable task) {
+ mTask = task;
+ mTaskCountdown = numSamples;
+ }
+
+ public void setCaptureEnabled(boolean captureEnabled) {
+ mCaptureEnabled = captureEnabled;
+ }
+
+ public int readMostRecent(float[] buffer) {
+ return mCaptureBuffer.readMostRecent(buffer);
+ }
+
+}