19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.media; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.IllegalArgumentException; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.IllegalStateException; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.Thread; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.ByteBuffer; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The AudioRecord class manages the audio resources for Java applications 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to record audio from the audio input hardware of the platform. This is 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * achieved by "pulling" (reading) the data from the AudioRecord object. The 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * application is responsible for polling the AudioRecord object in time using one of 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the following three methods: {@link #read(byte[],int, int)}, {@link #read(short[], int, int)} 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #read(ByteBuffer, int)}. The choice of which method to use will be based 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on the audio data storage format that is the most convenient for the user of AudioRecord. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Upon creation, an AudioRecord object initializes its associated audio buffer that it will 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fill with the new audio data. The size of this buffer, specified during the construction, 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * determines how long an AudioRecord can record before "over-running" data that has not 43ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * been read yet. Data should be read from the audio hardware in chunks of sizes inferior to 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the total recording buffer size. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AudioRecord 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Constants 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 52ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * indicates AudioRecord state is not successfully initialized. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STATE_UNINITIALIZED = 0; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 56ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * indicates AudioRecord state is ready to be used 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STATE_INITIALIZED = 1; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 61ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * indicates AudioRecord recording state is not recording 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RECORDSTATE_STOPPED = 1; // matches SL_RECORDSTATE_STOPPED 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 65ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * indicates AudioRecord recording state is recording 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RECORDSTATE_RECORDING = 3;// matches SL_RECORDSTATE_RECORDING 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Error codes: 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to keep in sync with frameworks/base/core/jni/android_media_AudioRecord.cpp 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a successful operation. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SUCCESS = 0; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a generic operation failure. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ERROR = -1; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a failure due to the use of an invalid value. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ERROR_BAD_VALUE = -2; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a failure due to the improper use of a method. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ERROR_INVALID_OPERATION = -3; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT = -16; 89a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELMASK = -17; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int AUDIORECORD_ERROR_SETUP_INVALIDFORMAT = -18; 914bc035a65cac177be9294e69f110497e3b6e34e6Eric Laurent private static final int AUDIORECORD_ERROR_SETUP_INVALIDSOURCE = -19; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED = -20; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Events: 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to keep in sync with frameworks/base/include/media/AudioRecord.h 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 97ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Event id denotes when record head has reached a previously set marker. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NATIVE_EVENT_MARKER = 2; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 101ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Event id denotes when previously set update period has elapsed during recording. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NATIVE_EVENT_NEW_POS = 3; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String TAG = "AudioRecord-Java"; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used exclusively by native code 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Accessed by native methods: provides access to C++ AudioRecord object 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unused") 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNativeRecorderInJavaObj; 1164bc035a65cac177be9294e69f110497e3b6e34e6Eric Laurent 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Accessed by native methods: provides access to the callback data. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unused") 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNativeCallbackCookie; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Member variables 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The audio data sampling rate in Hz. 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSampleRate = 22050; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of input audio channels (1 is mono, 2 is stereo) 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mChannelCount = 1; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1363026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent * The audio channel mask 1373026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent */ 1383026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent private int mChannels = AudioFormat.CHANNEL_IN_MONO; 1393026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent /** 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The current audio channel configuration 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 142a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent private int mChannelConfiguration = AudioFormat.CHANNEL_IN_MONO; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The encoding of the audio samples. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioFormat#ENCODING_PCM_8BIT 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioFormat#ENCODING_PCM_16BIT 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Where the audio data is recorded from. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRecordSource = MediaRecorder.AudioSource.DEFAULT; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates the state of the AudioRecord instance. 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mState = STATE_UNINITIALIZED; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates the recording state of the AudioRecord instance. 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRecordingState = RECORDSTATE_STOPPED; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Lock to make sure mRecordingState updates are reflecting the actual state of the object. 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mRecordingStateLock = new Object(); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 166470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * The listener the AudioRecord notifies when the record position reaches a marker 167470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * or for periodic updates during the progression of the record head. 168470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * @see #setRecordPositionUpdateListener(OnRecordPositionUpdateListener) 169470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * @see #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler) 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 171470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi private OnRecordPositionUpdateListener mPositionListener = null; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 173470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Lock to protect position listener updates against event notifications 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 175470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi private final Object mPositionListenerLock = new Object(); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 177470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Handler for marker events coming from the native code 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 179470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi private NativeEventHandler mEventHandler = null; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 181470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Looper associated with the thread that creates the AudioRecord instance 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 183470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi private Looper mInitializationLooper = null; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Size of the native audio buffer. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNativeBufferSizeInBytes = 0; 18844ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent /** 18944ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent * Audio session ID 19044ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent */ 19144ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent private int mSessionId = 0; 192ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Constructor, Finalize 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class constructor. 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioSource the recording source. See {@link MediaRecorder.AudioSource} for 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * recording source definitions. 200635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * @param sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only 201635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * rate that is guaranteed to work on all devices, but other rates such as 22050, 202635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * 16000, and 11025 may work on some devices. 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param channelConfig describes the configuration of the audio channels. 204a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See {@link AudioFormat#CHANNEL_IN_MONO} and 205635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is guaranteed 206635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * to work on all devices. 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioFormat the format in which the audio data is represented. 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link AudioFormat#ENCODING_PCM_16BIT} and 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioFormat#ENCODING_PCM_8BIT} 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to during the recording. New audio data can be read from this buffer in smaller chunks 212ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum 213ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * required buffer size for the successful creation of an AudioRecord instance. Using values 214ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * smaller than getMinBufferSize() will result in an initialization failure. 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws java.lang.IllegalArgumentException 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bufferSizeInBytes) 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalArgumentException { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_UNINITIALIZED; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordingState = RECORDSTATE_STOPPED; 222470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 223470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi // remember which looper is associated with the AudioRecord instanciation 224470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi if ((mInitializationLooper = Looper.myLooper()) == null) { 225470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi mInitializationLooper = Looper.getMainLooper(); 226470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioParamCheck(audioSource, sampleRateInHz, channelConfig, audioFormat); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioBuffSizeCheck(bufferSizeInBytes); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // native initialization 23344ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent int[] session = new int[1]; 23444ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent session[0] = 0; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //TODO: update native initialization when information about hardware init failure 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // due to capture device already open is available. 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int initResult = native_setup( new WeakReference<AudioRecord>(this), 23844ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent mRecordSource, mSampleRate, mChannels, mAudioFormat, mNativeBufferSizeInBytes, 23944ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent session); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (initResult != SUCCESS) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("Error code "+initResult+" when initializing native AudioRecord object."); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; // with mState == STATE_UNINITIALIZED 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24544ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent mSessionId = session[0]; 24644ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_INITIALIZED; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Convenience method for the constructor's parameter checks. 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is where constructor IllegalArgumentException-s are thrown 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // postconditions: 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mRecordSource is valid 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mChannelCount is valid 2563026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent // mChannels is valid 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mAudioFormat is valid 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mSampleRate is valid 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void audioParamCheck(int audioSource, int sampleRateInHz, 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int channelConfig, int audioFormat) { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // audio source 2644bc035a65cac177be9294e69f110497e3b6e34e6Eric Laurent if ( (audioSource < MediaRecorder.AudioSource.DEFAULT) || 2654bc035a65cac177be9294e69f110497e3b6e34e6Eric Laurent (audioSource > MediaRecorder.getAudioSourceMax()) ) { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException("Invalid audio source.")); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordSource = audioSource; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sample rate 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException(sampleRateInHz 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "Hz is not a supported sample rate.")); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleRate = sampleRateInHz; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // channel config 2823026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannelConfiguration = channelConfig; 2833026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (channelConfig) { 2853026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT 286a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_IN_MONO: 2873026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_MONO: 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChannelCount = 1; 2893026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannels = AudioFormat.CHANNEL_IN_MONO; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 291a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_IN_STEREO: 2923026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_STEREO: 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChannelCount = 2; 2943026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannels = AudioFormat.CHANNEL_IN_STEREO; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChannelCount = 0; 2983026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannels = AudioFormat.CHANNEL_INVALID; 2993026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannelConfiguration = AudioFormat.CHANNEL_INVALID; 3003026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent throw (new IllegalArgumentException("Unsupported channel configuration.")); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // audio format 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (audioFormat) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AudioFormat.ENCODING_DEFAULT: 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AudioFormat.ENCODING_PCM_16BIT: 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AudioFormat.ENCODING_PCM_8BIT: 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioFormat = audioFormat; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioFormat = AudioFormat.ENCODING_INVALID; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException("Unsupported sample encoding." 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT.")); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Convenience method for the contructor's audio buffer size check. 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preconditions: 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mChannelCount is valid 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mAudioFormat is AudioFormat.ENCODING_PCM_8BIT OR AudioFormat.ENCODING_PCM_16BIT 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // postcondition: 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mNativeBufferSizeInBytes is valid (multiple of frame size, positive) 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void audioBuffSizeCheck(int audioBufferSize) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // NB: this section is only valid with PCM data. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // To update when supporting compressed formats 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int frameSizeInBytes = mChannelCount 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException("Invalid audio buffer size.")); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNativeBufferSizeInBytes = audioBufferSize; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 338ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 339ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Releases the native AudioRecord resources. 343ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * The object can no longer be used and the reference should be set to null 344ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * after a call to release() 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void release() { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stop(); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch(IllegalStateException ise) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't raise an exception, we're releasing the resources. 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_release(); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_UNINITIALIZED; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 355ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_finalize(); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------------------------------------------------- 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Getters 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured audio data sample rate in Hz 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSampleRate() { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSampleRate; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the audio recording source. 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see MediaRecorder.AudioSource 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAudioSource() { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRecordSource; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link AudioFormat#ENCODING_PCM_8BIT}. 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAudioFormat() { 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAudioFormat; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured channel configuration. 391a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See {@link AudioFormat#CHANNEL_IN_MONO} 392a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * and {@link AudioFormat#CHANNEL_IN_STEREO}. 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChannelConfiguration() { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChannelConfiguration; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured number of channels. 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChannelCount() { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChannelCount; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the state of the AudioRecord instance. This is useful after the 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AudioRecord instance has been created to check if it was initialized 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * properly. This ensures that the appropriate hardware resources have been 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * acquired. 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioRecord#STATE_INITIALIZED 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioRecord#STATE_UNINITIALIZED 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getState() { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the recording state of the AudioRecord instance. 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioRecord#RECORDSTATE_STOPPED 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioRecord#RECORDSTATE_RECORDING 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getRecordingState() { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRecordingState; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 425ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 427ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Returns the notification marker position expressed in frames. 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getNotificationMarkerPosition() { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_marker_pos(); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 434ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Returns the notification update period expressed in frames. 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPositionNotificationPeriod() { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_pos_update_period(); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 439ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the minimum buffer size required for the successful creation of an AudioRecord 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object. 443ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Note that this size doesn't guarantee a smooth recording under load, and higher values 444ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * should be chosen according to the expected frequency at which the AudioRecord instance 445ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * will be polled for new data. 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sampleRateInHz the sample rate expressed in Hertz. 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param channelConfig describes the configuration of the audio channels. 448a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See {@link AudioFormat#CHANNEL_IN_MONO} and 449a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * {@link AudioFormat#CHANNEL_IN_STEREO} 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioFormat the format in which the audio data is represented. 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link AudioFormat#ENCODING_PCM_16BIT}. 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@link #ERROR_BAD_VALUE} if the recording parameters are not supported by the 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hardware, or an invalid parameter was passed, 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #ERROR} if the implementation was unable to query the hardware for its 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output properties, 456ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * or the minimum buffer size expressed in bytes. 457635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * @see #AudioRecord(int, int, int, int, int) for more information on valid 458635fefec06458224750170e7ce127bc2c8e4215bDan Tasse * configuration values. 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int channelCount = 0; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(channelConfig) { 4633026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT 464a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_IN_MONO: 4653026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_MONO: 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project channelCount = 1; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 468a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_IN_STEREO: 4693026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_STEREO: 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project channelCount = 2; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 472a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_INVALID: 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("getMinBufferSize(): Invalid channel configuration."); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioRecord.ERROR_BAD_VALUE; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // PCM_8BIT is not supported at the moment 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (audioFormat != AudioFormat.ENCODING_PCM_16BIT) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("getMinBufferSize(): Invalid audio format."); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioRecord.ERROR_BAD_VALUE; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size == 0) { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioRecord.ERROR_BAD_VALUE; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (size == -1) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioRecord.ERROR; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return size; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49644ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent /** 49744ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent * Returns the audio session ID. 49844ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent * 49944ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent * @return the ID of the audio session this AudioRecord belongs to. 50044ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent * @hide 50144ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent */ 50244ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent public int getAudioSessionId() { 50344ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent return mSessionId; 50444ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Transport control methods 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Starts recording from the AudioRecord instance. 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startRecording() 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalStateException { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalStateException("startRecording() called on an " 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project +"uninitialized AudioRecord.")); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // start recording 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mRecordingStateLock) { 5229cc489a2196e449dbe090ad9bdbc5cedd0b8334fEric Laurent if (native_start() == SUCCESS) { 5239cc489a2196e449dbe090ad9bdbc5cedd0b8334fEric Laurent mRecordingState = RECORDSTATE_RECORDING; 5249cc489a2196e449dbe090ad9bdbc5cedd0b8334fEric Laurent } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Stops recording. 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stop() 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalStateException { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalStateException("stop() called on an uninitialized AudioRecord.")); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // stop recording 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mRecordingStateLock) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordingState = RECORDSTATE_STOPPED; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Audio data supply 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reads audio data from the audio hardware for recording into a buffer. 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioData the array to which the recorded audio data is written. 554ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * @param offsetInBytes index in audioData from which the data is written expressed in bytes. 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sizeInBytes the number of requested bytes. 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of bytes that were read or or {@link #ERROR_INVALID_OPERATION} 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the parameters don't resolve to valid data and indexes. 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of bytes will not exceed sizeInBytes. 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(byte[] audioData, int offsetInBytes, int sizeInBytes) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0) 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (offsetInBytes + sizeInBytes > audioData.length)) { 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_BAD_VALUE; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_read_in_byte_array(audioData, offsetInBytes, sizeInBytes); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reads audio data from the audio hardware for recording into a buffer. 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioData the array to which the recorded audio data is written. 578ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * @param offsetInShorts index in audioData from which the data is written expressed in shorts. 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sizeInShorts the number of requested shorts. 580ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * @return the number of shorts that were read or or {@link #ERROR_INVALID_OPERATION} 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the parameters don't resolve to valid data and indexes. 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of shorts will not exceed sizeInShorts. 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(short[] audioData, int offsetInShorts, int sizeInShorts) { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0) 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (offsetInShorts + sizeInShorts > audioData.length)) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_BAD_VALUE; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reads audio data from the audio hardware for recording into a direct buffer. If this buffer 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is not a direct buffer, this method will always return 0. 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioBuffer the direct buffer to which the recorded audio data is written. 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sizeInBytes the number of requested bytes. 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of bytes that were read or or {@link #ERROR_INVALID_OPERATION} 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the parameters don't resolve to valid data and indexes. 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of bytes will not exceed sizeInBytes. 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int read(ByteBuffer audioBuffer, int sizeInBytes) { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (audioBuffer == null) || (sizeInBytes < 0) ) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_BAD_VALUE; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_read_in_direct_buffer(audioBuffer, sizeInBytes); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------------------------------------------------- 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Initialization / configuration 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 626470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Sets the listener the AudioRecord notifies when a previously set marker is reached or 627470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * for each periodic record head position update. 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 630470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi public void setRecordPositionUpdateListener(OnRecordPositionUpdateListener listener) { 631470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi setRecordPositionUpdateListener(listener, null); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 633470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 634ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi /** 635ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Sets the listener the AudioRecord notifies when a previously set marker is reached or 636ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * for each periodic record head position update. 637ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * Use this method to receive AudioRecord events in the Handler associated with another 638ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * thread than the one in which you created the AudioTrack instance. 639ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * @param listener 640ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * @param handler the Handler that will receive the event notification messages. 641ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi */ 642470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi public void setRecordPositionUpdateListener(OnRecordPositionUpdateListener listener, 643470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi Handler handler) { 644470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi synchronized (mPositionListenerLock) { 645470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 646470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi mPositionListener = listener; 647470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 648470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi if (listener != null) { 649470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi if (handler != null) { 650470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi mEventHandler = new NativeEventHandler(this, handler.getLooper()); 651470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi } else { 652470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi // no given handler, use the looper the AudioRecord was created in 653470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi mEventHandler = new NativeEventHandler(this, mInitializationLooper); 654470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi } 655470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi } else { 656470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi mEventHandler = null; 657470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 659470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 661ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 662ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 664470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Sets the marker position at which the listener is called, if set with 665470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or 666470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}. 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param markerInFrames marker position expressed in frames 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setNotificationMarkerPosition(int markerInFrames) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_set_marker_pos(markerInFrames); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 674ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 675ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 677470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Sets the period at which the listener is called, if set with 678470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or 679470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}. 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param periodInFrames update period expressed in frames 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION} 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setPositionNotificationPeriod(int periodInFrames) { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_set_pos_update_period(periodInFrames); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Interface definitions 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Interface definition for a callback to be invoked when an AudioRecord has 693ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * reached a notification marker set by {@link AudioRecord#setNotificationMarkerPosition(int)} 694ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * or for periodic updates on the progress of the record head, as set by 695ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi * {@link AudioRecord#setPositionNotificationPeriod(int)}. 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 697470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi public interface OnRecordPositionUpdateListener { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called on the listener to notify it that the previously set marker has been reached 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the recording head. 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onMarkerReached(AudioRecord recorder); 703470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 705470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Called on the listener to periodically notify it that the record head has reached 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a multiple of the notification period. 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onPeriodicNotification(AudioRecord recorder); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 711ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 712ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inner classes 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 716470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 718470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * Helper class to handle the forwarding of native events to the appropriate listener 719470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi * (potentially) handled in a different thread 720470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi */ 721470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi private class NativeEventHandler extends Handler { 722470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 723470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi private final AudioRecord mAudioRecord; 724ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 725470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi NativeEventHandler(AudioRecord recorder, Looper looper) { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(looper); 727470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi mAudioRecord = recorder; 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729ea63a41d269abd25d070c9fc9c5a249763cb549dJean-Michel Trivi 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 732470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi OnRecordPositionUpdateListener listener = null; 733470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi synchronized (mPositionListenerLock) { 734470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi listener = mAudioRecord.mPositionListener; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 736470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(msg.what) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NATIVE_EVENT_MARKER: 739470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi if (listener != null) { 740470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi listener.onMarkerReached(mAudioRecord); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NATIVE_EVENT_NEW_POS: 744470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi if (listener != null) { 745470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi listener.onPeriodicNotification(mAudioRecord); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "[ android.media.AudioRecord.NativeEventHandler ] " + 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Unknown event type: " + msg.what); 751470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi break; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 754470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi }; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Java methods called from the native side 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unused") 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void postEventFromNative(Object audiorecord_ref, 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int what, int arg1, int arg2, Object obj) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AudioRecord recorder = (AudioRecord)((WeakReference)audiorecord_ref).get(); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (recorder == null) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi if (recorder.mEventHandler != null) { 770470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi Message m = 771470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi recorder.mEventHandler.obtainMessage(what, arg1, arg2, obj); 772470f71f4a4d6d3a504b62473bd435bf80493414fJean-Michel Trivi recorder.mEventHandler.sendMessage(m); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Native methods called from the Java side 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_setup(Object audiorecord_this, 78344ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent int recordSource, int sampleRate, int nbChannels, int audioFormat, 78444ff4cd8be50768d5bd471bc6c034acefa0b59caEric Laurent int buffSizeInBytes, int[] sessionId); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_finalize(); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_release(); 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909cc489a2196e449dbe090ad9bdbc5cedd0b8334fEric Laurent private native final int native_start(); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_stop(); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_read_in_byte_array(byte[] audioData, 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offsetInBytes, int sizeInBytes); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_read_in_short_array(short[] audioData, 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offsetInShorts, int sizeInShorts); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_read_in_direct_buffer(Object jBuffer, int sizeInBytes); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_set_marker_pos(int marker); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_get_marker_pos(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_set_pos_update_period(int updatePeriod); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_get_pos_update_period(); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private native final int native_get_min_buff_size( 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int sampleRateInHz, int channelCount, int audioFormat); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Utility methods 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //------------------ 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void logd(String msg) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "[ android.media.AudioRecord ] " + msg); 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void loge(String msg) { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "[ android.media.AudioRecord ] " + msg); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 826