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 |
11 package org.webrtc.voiceengine; | 11 package org.webrtc.voiceengine; |
12 | 12 |
13 import android.annotation.TargetApi; | 13 import android.annotation.TargetApi; |
14 import android.content.Context; | 14 import android.content.Context; |
15 import android.content.pm.PackageManager; | 15 import android.content.pm.PackageManager; |
16 import android.media.AudioFormat; | 16 import android.media.AudioFormat; |
17 import android.media.AudioManager; | 17 import android.media.AudioManager; |
18 import android.media.AudioRecord; | 18 import android.media.AudioRecord; |
19 import android.media.AudioTrack; | 19 import android.media.AudioTrack; |
20 import android.os.Build; | 20 import android.os.Build; |
21 import java.util.Timer; | 21 import java.util.Timer; |
22 import java.util.TimerTask; | 22 import java.util.TimerTask; |
| 23 import org.webrtc.ContextUtils; |
23 import org.webrtc.Logging; | 24 import org.webrtc.Logging; |
24 | 25 |
25 // WebRtcAudioManager handles tasks that uses android.media.AudioManager. | 26 // WebRtcAudioManager handles tasks that uses android.media.AudioManager. |
26 // At construction, storeAudioParameters() is called and it retrieves | 27 // At construction, storeAudioParameters() is called and it retrieves |
27 // fundamental audio parameters like native sample rate and number of channels. | 28 // fundamental audio parameters like native sample rate and number of channels. |
28 // The result is then provided to the caller by nativeCacheAudioParameters(). | 29 // The result is then provided to the caller by nativeCacheAudioParameters(). |
29 // It is also possible to call init() to set up the audio environment for best | 30 // It is also possible to call init() to set up the audio environment for best |
30 // possible "VoIP performance". All settings done in init() are reverted by | 31 // possible "VoIP performance". All settings done in init() are reverted by |
31 // dispose(). This class can also be used without calling init() if the user | 32 // dispose(). This class can also be used without calling init() if the user |
32 // prefers to set up the audio environment separately. However, it is | 33 // prefers to set up the audio environment separately. However, it is |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 | 129 |
129 private void stop() { | 130 private void stop() { |
130 if (timer != null) { | 131 if (timer != null) { |
131 timer.cancel(); | 132 timer.cancel(); |
132 timer = null; | 133 timer = null; |
133 } | 134 } |
134 } | 135 } |
135 } | 136 } |
136 | 137 |
137 private final long nativeAudioManager; | 138 private final long nativeAudioManager; |
138 private final Context context; | |
139 private final AudioManager audioManager; | 139 private final AudioManager audioManager; |
140 | 140 |
141 private boolean initialized = false; | 141 private boolean initialized = false; |
142 private int nativeSampleRate; | 142 private int nativeSampleRate; |
143 private int nativeChannels; | 143 private int nativeChannels; |
144 | 144 |
145 private boolean hardwareAEC; | 145 private boolean hardwareAEC; |
146 private boolean hardwareAGC; | 146 private boolean hardwareAGC; |
147 private boolean hardwareNS; | 147 private boolean hardwareNS; |
148 private boolean lowLatencyOutput; | 148 private boolean lowLatencyOutput; |
149 private boolean lowLatencyInput; | 149 private boolean lowLatencyInput; |
150 private boolean proAudio; | 150 private boolean proAudio; |
151 private int sampleRate; | 151 private int sampleRate; |
152 private int outputChannels; | 152 private int outputChannels; |
153 private int inputChannels; | 153 private int inputChannels; |
154 private int outputBufferSize; | 154 private int outputBufferSize; |
155 private int inputBufferSize; | 155 private int inputBufferSize; |
156 | 156 |
157 private final VolumeLogger volumeLogger; | 157 private final VolumeLogger volumeLogger; |
158 | 158 |
159 WebRtcAudioManager(Context context, long nativeAudioManager) { | 159 WebRtcAudioManager(long nativeAudioManager) { |
160 Logging.d(TAG, "ctor" + WebRtcAudioUtils.getThreadInfo()); | 160 Logging.d(TAG, "ctor" + WebRtcAudioUtils.getThreadInfo()); |
161 this.context = context; | |
162 this.nativeAudioManager = nativeAudioManager; | 161 this.nativeAudioManager = nativeAudioManager; |
163 audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE
); | 162 audioManager = |
| 163 (AudioManager) ContextUtils.getApplicationContext().getSystemService(Con
text.AUDIO_SERVICE); |
164 if (DEBUG) { | 164 if (DEBUG) { |
165 WebRtcAudioUtils.logDeviceInfo(TAG); | 165 WebRtcAudioUtils.logDeviceInfo(TAG); |
166 } | 166 } |
167 volumeLogger = new VolumeLogger(audioManager); | 167 volumeLogger = new VolumeLogger(audioManager); |
168 storeAudioParameters(); | 168 storeAudioParameters(); |
169 nativeCacheAudioParameters(sampleRate, outputChannels, inputChannels, hardwa
reAEC, hardwareAGC, | 169 nativeCacheAudioParameters(sampleRate, outputChannels, inputChannels, hardwa
reAEC, hardwareAGC, |
170 hardwareNS, lowLatencyOutput, lowLatencyInput, proAudio, outputBufferSiz
e, inputBufferSize, | 170 hardwareNS, lowLatencyOutput, lowLatencyInput, proAudio, outputBufferSiz
e, inputBufferSize, |
171 nativeAudioManager); | 171 nativeAudioManager); |
172 } | 172 } |
173 | 173 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 lowLatencyInput = isLowLatencyInputSupported(); | 217 lowLatencyInput = isLowLatencyInputSupported(); |
218 proAudio = isProAudioSupported(); | 218 proAudio = isProAudioSupported(); |
219 outputBufferSize = lowLatencyOutput ? getLowLatencyOutputFramesPerBuffer() | 219 outputBufferSize = lowLatencyOutput ? getLowLatencyOutputFramesPerBuffer() |
220 : getMinOutputFrameSize(sampleRate, outp
utChannels); | 220 : getMinOutputFrameSize(sampleRate, outp
utChannels); |
221 inputBufferSize = lowLatencyInput ? getLowLatencyInputFramesPerBuffer() | 221 inputBufferSize = lowLatencyInput ? getLowLatencyInputFramesPerBuffer() |
222 : getMinInputFrameSize(sampleRate, inputCh
annels); | 222 : getMinInputFrameSize(sampleRate, inputCh
annels); |
223 } | 223 } |
224 | 224 |
225 // Gets the current earpiece state. | 225 // Gets the current earpiece state. |
226 private boolean hasEarpiece() { | 226 private boolean hasEarpiece() { |
227 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_T
ELEPHONY); | 227 return ContextUtils.getApplicationContext().getPackageManager().hasSystemFea
ture( |
| 228 PackageManager.FEATURE_TELEPHONY); |
228 } | 229 } |
229 | 230 |
230 // Returns true if low-latency audio output is supported. | 231 // Returns true if low-latency audio output is supported. |
231 private boolean isLowLatencyOutputSupported() { | 232 private boolean isLowLatencyOutputSupported() { |
232 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_A
UDIO_LOW_LATENCY); | 233 return ContextUtils.getApplicationContext().getPackageManager().hasSystemFea
ture( |
| 234 PackageManager.FEATURE_AUDIO_LOW_LATENCY); |
233 } | 235 } |
234 | 236 |
235 // Returns true if low-latency audio input is supported. | 237 // Returns true if low-latency audio input is supported. |
236 // TODO(henrika): remove the hardcoded false return value when OpenSL ES | 238 // TODO(henrika): remove the hardcoded false return value when OpenSL ES |
237 // input performance has been evaluated and tested more. | 239 // input performance has been evaluated and tested more. |
238 public boolean isLowLatencyInputSupported() { | 240 public boolean isLowLatencyInputSupported() { |
239 // TODO(henrika): investigate if some sort of device list is needed here | 241 // TODO(henrika): investigate if some sort of device list is needed here |
240 // as well. The NDK doc states that: "As of API level 21, lower latency | 242 // as well. The NDK doc states that: "As of API level 21, lower latency |
241 // audio input is supported on select devices. To take advantage of this | 243 // audio input is supported on select devices. To take advantage of this |
242 // feature, first confirm that lower latency output is available". | 244 // feature, first confirm that lower latency output is available". |
243 return WebRtcAudioUtils.runningOnLollipopOrHigher() && isLowLatencyOutputSup
ported(); | 245 return WebRtcAudioUtils.runningOnLollipopOrHigher() && isLowLatencyOutputSup
ported(); |
244 } | 246 } |
245 | 247 |
246 // Returns true if the device has professional audio level of functionality | 248 // Returns true if the device has professional audio level of functionality |
247 // and therefore supports the lowest possible round-trip latency. | 249 // and therefore supports the lowest possible round-trip latency. |
248 @TargetApi(23) | 250 @TargetApi(23) |
249 private boolean isProAudioSupported() { | 251 private boolean isProAudioSupported() { |
250 return WebRtcAudioUtils.runningOnMarshmallowOrHigher() | 252 return WebRtcAudioUtils.runningOnMarshmallowOrHigher() |
251 && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_A
UDIO_PRO); | 253 && ContextUtils.getApplicationContext().getPackageManager().hasSystemFea
ture( |
| 254 PackageManager.FEATURE_AUDIO_PRO); |
252 } | 255 } |
253 | 256 |
254 // Returns the native output sample rate for this device's output stream. | 257 // Returns the native output sample rate for this device's output stream. |
255 private int getNativeOutputSampleRate() { | 258 private int getNativeOutputSampleRate() { |
256 // Override this if we're running on an old emulator image which only | 259 // Override this if we're running on an old emulator image which only |
257 // supports 8 kHz and doesn't support PROPERTY_OUTPUT_SAMPLE_RATE. | 260 // supports 8 kHz and doesn't support PROPERTY_OUTPUT_SAMPLE_RATE. |
258 if (WebRtcAudioUtils.runningOnEmulator()) { | 261 if (WebRtcAudioUtils.runningOnEmulator()) { |
259 Logging.d(TAG, "Running emulator, overriding sample rate to 8 kHz."); | 262 Logging.d(TAG, "Running emulator, overriding sample rate to 8 kHz."); |
260 return 8000; | 263 return 8000; |
261 } | 264 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 if (!condition) { | 348 if (!condition) { |
346 throw new AssertionError("Expected condition to be true"); | 349 throw new AssertionError("Expected condition to be true"); |
347 } | 350 } |
348 } | 351 } |
349 | 352 |
350 private native void nativeCacheAudioParameters(int sampleRate, int outputChann
els, | 353 private native void nativeCacheAudioParameters(int sampleRate, int outputChann
els, |
351 int inputChannels, boolean hardwareAEC, boolean hardwareAGC, boolean hardw
areNS, | 354 int inputChannels, boolean hardwareAEC, boolean hardwareAGC, boolean hardw
areNS, |
352 boolean lowLatencyOutput, boolean lowLatencyInput, boolean proAudio, int o
utputBufferSize, | 355 boolean lowLatencyOutput, boolean lowLatencyInput, boolean proAudio, int o
utputBufferSize, |
353 int inputBufferSize, long nativeAudioManager); | 356 int inputBufferSize, long nativeAudioManager); |
354 } | 357 } |
OLD | NEW |