1 package com.android.cts.verifier.audio; 2 3 import android.media.AudioFormat; 4 import android.media.AudioManager; 5 import android.media.AudioRecord; 6 import android.media.AudioTrack; 7 import android.media.MediaRecorder; 8 import android.util.Log; 9 10 import java.io.ByteArrayOutputStream; 11 import java.io.IOException; 12 13 /** 14 * A wrapper on AudioRecord class. 15 */ 16 public class AudioRecordHelper { 17 18 private static final int[] SOURCE = { 19 MediaRecorder.AudioSource.MIC, MediaRecorder.AudioSource.VOICE_RECOGNITION}; 20 private static final int[] SAMPLE_RATES_HZ = { 21 AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC), 48000, 44100}; 22 23 private static final int CHANNEL = AudioFormat.CHANNEL_CONFIGURATION_MONO; 24 private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT; 25 private static final String TAG = "AudioRecordHelper"; 26 private static AudioRecordHelper instance; 27 private final int bufferSize; 28 private final int sampleRate; 29 private final int source; 30 private ByteArrayOutputStream os; 31 private AudioRecord audioRecord; 32 private volatile boolean isRecording = false; 33 AudioRecordHelper()34 private AudioRecordHelper() { 35 int tmpBufferSize = 0; 36 int tmpSampleRate = 0; 37 int tmpSource = 0; 38 initialization: 39 for (int source : SOURCE) { 40 for (int rate : SAMPLE_RATES_HZ) { 41 tmpBufferSize = AudioRecord.getMinBufferSize(rate, CHANNEL, ENCODING); 42 AudioRecord testAudioRecord = new AudioRecord(source, rate, CHANNEL, ENCODING, 43 tmpBufferSize); 44 if (testAudioRecord.getState() == AudioRecord.STATE_INITIALIZED) { 45 testAudioRecord.release(); 46 tmpSampleRate = rate; 47 tmpSource = source; 48 break initialization; 49 } 50 } 51 } 52 if (tmpBufferSize == 0 || tmpSampleRate == 0) { 53 Log.e(TAG, "Failed to initialize"); 54 } 55 bufferSize = tmpBufferSize; 56 sampleRate = tmpSampleRate; 57 source = tmpSource; 58 Log.d(TAG, "Sample rate = " + sampleRate + "Hz, Source = " 59 + source + " (VOICE_RECOGNITION = 6 , MIC = 1)"); 60 } 61 getInstance()62 public static AudioRecordHelper getInstance() { 63 if (instance == null) { 64 instance = new AudioRecordHelper(); 65 } 66 return instance; 67 } 68 69 /** 70 * Start recording. 71 */ start()72 public void start() { 73 if (!isRecording) { 74 isRecording = true; 75 os = new ByteArrayOutputStream(); 76 audioRecord = new AudioRecord(source, sampleRate, CHANNEL, ENCODING, bufferSize); 77 audioRecord.startRecording(); 78 startPullingData(); 79 } 80 } 81 82 /** 83 * Stop recording 84 */ stop()85 public void stop() { 86 if (isRecording) { 87 isRecording = false; 88 audioRecord.stop(); 89 audioRecord.release(); 90 audioRecord = null; 91 try { 92 os.close(); 93 } catch (IOException e) { 94 e.printStackTrace(); 95 } 96 } 97 } 98 startPullingData()99 private void startPullingData() { 100 new Thread() { 101 @Override 102 public void run(){ 103 byte data[] = new byte[bufferSize]; 104 while (isRecording) { 105 int read = audioRecord.read(data, 0, bufferSize); 106 if (read > 0) { 107 os.write(data, 0, read); 108 } 109 if (read < 0) { 110 break; 111 } 112 } 113 } 114 }.start(); 115 } 116 117 /** 118 * Returns the sample rate for this recorder. 119 */ getSampleRate()120 public int getSampleRate() { 121 return sampleRate; 122 } 123 124 /** 125 * Returns the audio source currently being used. 126 */ getAudioSource()127 public int getAudioSource() { 128 return source; 129 } 130 131 /** 132 * Returns true if recorder is recording; False if not. 133 */ isRecording()134 public boolean isRecording() { 135 return isRecording; 136 } 137 138 /** 139 * Returns the raw data. 140 */ getByte()141 public byte[] getByte() { 142 return os.toByteArray(); 143 } 144 } 145