diff options
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.java | 162 |
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); + } + +} |