OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 } | 138 } |
139 | 139 |
140 private int InitRecording(int sampleRate, int channels) { | 140 private int InitRecording(int sampleRate, int channels) { |
141 Logd("InitRecording(sampleRate=" + sampleRate + ", channels=" + | 141 Logd("InitRecording(sampleRate=" + sampleRate + ", channels=" + |
142 channels + ")"); | 142 channels + ")"); |
143 if (!WebRtcAudioUtils.hasPermission( | 143 if (!WebRtcAudioUtils.hasPermission( |
144 context, android.Manifest.permission.RECORD_AUDIO)) { | 144 context, android.Manifest.permission.RECORD_AUDIO)) { |
145 Loge("RECORD_AUDIO permission is missing"); | 145 Loge("RECORD_AUDIO permission is missing"); |
146 return -1; | 146 return -1; |
147 } | 147 } |
| 148 if (audioRecord != null) { |
| 149 Loge("InitRecording() called twice without StopRecording()"); |
| 150 return -1; |
| 151 } |
148 final int bytesPerFrame = channels * (BITS_PER_SAMPLE / 8); | 152 final int bytesPerFrame = channels * (BITS_PER_SAMPLE / 8); |
149 final int framesPerBuffer = sampleRate / BUFFERS_PER_SECOND; | 153 final int framesPerBuffer = sampleRate / BUFFERS_PER_SECOND; |
150 byteBuffer = ByteBuffer.allocateDirect(bytesPerFrame * framesPerBuffer); | 154 byteBuffer = ByteBuffer.allocateDirect(bytesPerFrame * framesPerBuffer); |
151 Logd("byteBuffer.capacity: " + byteBuffer.capacity()); | 155 Logd("byteBuffer.capacity: " + byteBuffer.capacity()); |
152 // Rather than passing the ByteBuffer with every callback (requiring | 156 // Rather than passing the ByteBuffer with every callback (requiring |
153 // the potentially expensive GetDirectBufferAddress) we simply have the | 157 // the potentially expensive GetDirectBufferAddress) we simply have the |
154 // the native class cache the address to the memory once. | 158 // the native class cache the address to the memory once. |
155 nativeCacheDirectBufferAddress(byteBuffer, nativeAudioRecord); | 159 nativeCacheDirectBufferAddress(byteBuffer, nativeAudioRecord); |
156 | 160 |
157 // Get the minimum buffer size required for the successful creation of | 161 // Get the minimum buffer size required for the successful creation of |
158 // an AudioRecord object, in byte units. | 162 // an AudioRecord object, in byte units. |
159 // Note that this size doesn't guarantee a smooth recording under load. | 163 // Note that this size doesn't guarantee a smooth recording under load. |
160 // TODO(henrika): Do we need to make this larger to avoid underruns? | 164 // TODO(henrika): Do we need to make this larger to avoid underruns? |
161 int minBufferSize = AudioRecord.getMinBufferSize( | 165 int minBufferSize = AudioRecord.getMinBufferSize( |
162 sampleRate, | 166 sampleRate, |
163 AudioFormat.CHANNEL_IN_MONO, | 167 AudioFormat.CHANNEL_IN_MONO, |
164 AudioFormat.ENCODING_PCM_16BIT); | 168 AudioFormat.ENCODING_PCM_16BIT); |
165 Logd("AudioRecord.getMinBufferSize: " + minBufferSize); | 169 Logd("AudioRecord.getMinBufferSize: " + minBufferSize); |
166 | 170 |
167 if (aec != null) { | |
168 aec.release(); | |
169 aec = null; | |
170 } | |
171 assertTrue(audioRecord == null); | |
172 | 171 |
173 int bufferSizeInBytes = Math.max(byteBuffer.capacity(), minBufferSize); | 172 int bufferSizeInBytes = Math.max(byteBuffer.capacity(), minBufferSize); |
174 Logd("bufferSizeInBytes: " + bufferSizeInBytes); | 173 Logd("bufferSizeInBytes: " + bufferSizeInBytes); |
175 try { | 174 try { |
176 audioRecord = new AudioRecord(AudioSource.VOICE_COMMUNICATION, | 175 audioRecord = new AudioRecord(AudioSource.VOICE_COMMUNICATION, |
177 sampleRate, | 176 sampleRate, |
178 AudioFormat.CHANNEL_IN_MONO, | 177 AudioFormat.CHANNEL_IN_MONO, |
179 AudioFormat.ENCODING_PCM_16BIT, | 178 AudioFormat.ENCODING_PCM_16BIT, |
180 bufferSizeInBytes); | 179 bufferSizeInBytes); |
181 | 180 |
182 } catch (IllegalArgumentException e) { | 181 } catch (IllegalArgumentException e) { |
183 Logd(e.getMessage()); | 182 Loge(e.getMessage()); |
184 return -1; | 183 return -1; |
185 } | 184 } |
186 assertTrue(audioRecord.getState() == AudioRecord.STATE_INITIALIZED); | 185 if (audioRecord == null || |
| 186 audioRecord.getState() != AudioRecord.STATE_INITIALIZED) { |
| 187 Loge("Failed to create a new AudioRecord instance"); |
| 188 return -1; |
| 189 } |
187 | 190 |
188 Logd("AudioRecord " + | 191 Logd("AudioRecord " + |
189 "session ID: " + audioRecord.getAudioSessionId() + ", " + | 192 "session ID: " + audioRecord.getAudioSessionId() + ", " + |
190 "audio format: " + audioRecord.getAudioFormat() + ", " + | 193 "audio format: " + audioRecord.getAudioFormat() + ", " + |
191 "channels: " + audioRecord.getChannelCount() + ", " + | 194 "channels: " + audioRecord.getChannelCount() + ", " + |
192 "sample rate: " + audioRecord.getSampleRate()); | 195 "sample rate: " + audioRecord.getSampleRate()); |
193 Logd("AcousticEchoCanceler.isAvailable: " + builtInAECIsAvailable()); | 196 Logd("AcousticEchoCanceler.isAvailable: " + builtInAECIsAvailable()); |
194 if (!builtInAECIsAvailable()) { | 197 if (!builtInAECIsAvailable()) { |
195 return framesPerBuffer; | 198 return framesPerBuffer; |
196 } | 199 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 276 |
274 private static void Loge(String msg) { | 277 private static void Loge(String msg) { |
275 Log.e(TAG, msg); | 278 Log.e(TAG, msg); |
276 } | 279 } |
277 | 280 |
278 private native void nativeCacheDirectBufferAddress( | 281 private native void nativeCacheDirectBufferAddress( |
279 ByteBuffer byteBuffer, long nativeAudioRecord); | 282 ByteBuffer byteBuffer, long nativeAudioRecord); |
280 | 283 |
281 private native void nativeDataIsRecorded(int bytes, long nativeAudioRecord); | 284 private native void nativeDataIsRecorded(int bytes, long nativeAudioRecord); |
282 } | 285 } |
OLD | NEW |