OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/audio/android/audio_manager_android.h" | 5 #include "media/audio/android/audio_manager_android.h" |
6 | 6 |
7 #include "base/android/build_info.h" | 7 #include "base/android/build_info.h" |
8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
10 #include "base/android/scoped_java_ref.h" | 10 #include "base/android/scoped_java_ref.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size); | 117 buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size); |
118 } | 118 } |
119 | 119 |
120 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( | 120 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( |
121 const AudioParameters& params, | 121 const AudioParameters& params, |
122 const std::string& device_id, | 122 const std::string& device_id, |
123 const std::string& input_device_id) { | 123 const std::string& input_device_id) { |
124 AudioOutputStream* stream = | 124 AudioOutputStream* stream = |
125 AudioManagerBase::MakeAudioOutputStream(params, std::string(), | 125 AudioManagerBase::MakeAudioOutputStream(params, std::string(), |
126 std::string()); | 126 std::string()); |
127 if (stream && output_stream_count() == 1) { | 127 |
128 SetAudioMode(kAudioModeInCommunication); | 128 // The audio manager for Android creates streams intended for real-time |
129 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. | |
130 if (stream && IsFirstCreatedAudioStream()) { | |
tommi (sloooow) - chröme
2013/12/10 21:19:11
you don't really need both IsFirst (or HasOne) and
henrika (OOO until Aug 14)
2013/12/11 13:16:38
Done.
| |
131 SetCommunicationAudioModeOn(true); | |
tommi (sloooow) - chröme
2013/12/10 21:19:11
Here, we should store what the previous mode is.
henrika (OOO until Aug 14)
2013/12/11 13:16:38
I do save the state and restore the state in Java.
tommi (sloooow) - chröme
2013/12/11 17:25:05
Yes that's great. I meant to update this comment
henrika (OOO until Aug 14)
2013/12/12 10:58:00
OK, get your point but note that BT is just one ca
tommi (sloooow) - chröme
2013/12/12 11:43:15
I'm not convinced that bluetooth is and forever wi
henrika (OOO until Aug 14)
2013/12/12 12:53:11
Discussed offline; think we are in phase now.
| |
129 } | 132 } |
130 | 133 |
131 { | 134 { |
132 base::AutoLock lock(streams_lock_); | 135 base::AutoLock lock(streams_lock_); |
133 streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); | 136 streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); |
134 } | 137 } |
135 | 138 |
136 return stream; | 139 return stream; |
137 } | 140 } |
138 | 141 |
139 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( | 142 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( |
140 const AudioParameters& params, const std::string& device_id) { | 143 const AudioParameters& params, const std::string& device_id) { |
141 AudioInputStream* stream = | 144 AudioInputStream* stream = |
142 AudioManagerBase::MakeAudioInputStream(params, device_id); | 145 AudioManagerBase::MakeAudioInputStream(params, device_id); |
146 | |
147 // The audio manager for Android creates streams intended for real-time | |
148 // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. | |
149 if (stream && IsFirstCreatedAudioStream()) { | |
150 SetCommunicationAudioModeOn(true); | |
151 } | |
143 return stream; | 152 return stream; |
144 } | 153 } |
145 | 154 |
146 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { | 155 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { |
147 AudioManagerBase::ReleaseOutputStream(stream); | 156 AudioManagerBase::ReleaseOutputStream(stream); |
148 if (!output_stream_count()) { | 157 |
149 SetAudioMode(kAudioModeNormal); | 158 // Restore the audio mode which was used before the first communication- |
159 // mode stream was created. | |
160 if (IsLastDestroyedAudioStream()) { | |
161 SetCommunicationAudioModeOn(false); | |
150 } | 162 } |
151 base::AutoLock lock(streams_lock_); | 163 base::AutoLock lock(streams_lock_); |
152 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); | 164 streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); |
153 } | 165 } |
154 | 166 |
155 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { | 167 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { |
156 AudioManagerBase::ReleaseInputStream(stream); | 168 AudioManagerBase::ReleaseInputStream(stream); |
169 | |
170 // Restore the audio mode which was used before the first communication- | |
171 // mode stream was created. | |
172 if (IsLastDestroyedAudioStream()) { | |
173 SetCommunicationAudioModeOn(false); | |
174 } | |
157 } | 175 } |
158 | 176 |
159 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( | 177 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( |
160 const AudioParameters& params) { | 178 const AudioParameters& params) { |
161 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 179 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); |
162 return new OpenSLESOutputStream(this, params); | 180 return new OpenSLESOutputStream(this, params); |
163 } | 181 } |
164 | 182 |
165 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( | 183 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( |
166 const AudioParameters& params, | 184 const AudioParameters& params, |
(...skipping 14 matching lines...) Expand all Loading... | |
181 } | 199 } |
182 | 200 |
183 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( | 201 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( |
184 const AudioParameters& params, const std::string& device_id) { | 202 const AudioParameters& params, const std::string& device_id) { |
185 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); | 203 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); |
186 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; | 204 DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; |
187 // Utilize the device ID to select the correct input device. | 205 // Utilize the device ID to select the correct input device. |
188 // Note that the input device is always associated with a certain output | 206 // Note that the input device is always associated with a certain output |
189 // device, i.e., this selection does also switch the output device. | 207 // device, i.e., this selection does also switch the output device. |
190 // All input and output streams will be affected by the device selection. | 208 // All input and output streams will be affected by the device selection. |
191 SetAudioDevice(device_id); | 209 if (!SetAudioDevice(device_id)) { |
210 LOG(ERROR) << "Unable to select audio device!"; | |
211 return NULL; | |
212 } | |
192 return new OpenSLESInputStream(this, params); | 213 return new OpenSLESInputStream(this, params); |
193 } | 214 } |
194 | 215 |
195 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, | 216 int AudioManagerAndroid::GetOptimalOutputFrameSize(int sample_rate, |
196 int channels) { | 217 int channels) { |
197 if (IsAudioLowLatencySupported()) { | 218 if (IsAudioLowLatencySupported()) { |
198 return GetAudioLowLatencyOutputFrameSize(); | 219 return GetAudioLowLatencyOutputFrameSize(); |
199 } else { | 220 } else { |
200 return std::max(kDefaultOutputBufferSize, | 221 return std::max(kDefaultOutputBufferSize, |
201 Java_AudioManagerAndroid_getMinOutputFrameSize( | 222 Java_AudioManagerAndroid_getMinOutputFrameSize( |
(...skipping 24 matching lines...) Expand all Loading... | |
226 | 247 |
227 int user_buffer_size = GetUserBufferSize(); | 248 int user_buffer_size = GetUserBufferSize(); |
228 if (user_buffer_size) | 249 if (user_buffer_size) |
229 buffer_size = user_buffer_size; | 250 buffer_size = user_buffer_size; |
230 | 251 |
231 return AudioParameters( | 252 return AudioParameters( |
232 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, | 253 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, |
233 sample_rate, bits_per_sample, buffer_size); | 254 sample_rate, bits_per_sample, buffer_size); |
234 } | 255 } |
235 | 256 |
257 bool AudioManagerAndroid::IsFirstCreatedAudioStream() { | |
258 const int out_count = output_stream_count(); | |
259 const int in_count = input_stream_count(); | |
260 return (out_count == 1 && in_count == 0) || (out_count == 0 && in_count == 1); | |
tommi (sloooow) - chröme
2013/12/10 21:19:11
return (output_stream_count() + input_stream_count
henrika (OOO until Aug 14)
2013/12/11 13:16:38
removed
| |
261 } | |
262 | |
263 bool AudioManagerAndroid::IsLastDestroyedAudioStream() { | |
tommi (sloooow) - chröme
2013/12/10 21:19:11
HasNoAudioStreams? I don't see a stream being che
henrika (OOO until Aug 14)
2013/12/11 13:16:38
Done.
| |
264 return (output_stream_count() == 0 && input_stream_count() == 0); | |
tommi (sloooow) - chröme
2013/12/10 21:19:11
nit: remove superflous parenthesis
henrika (OOO until Aug 14)
2013/12/11 13:16:38
Done.
| |
265 } | |
266 | |
236 // static | 267 // static |
237 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { | 268 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { |
238 return RegisterNativesImpl(env); | 269 return RegisterNativesImpl(env); |
239 } | 270 } |
240 | 271 |
241 void AudioManagerAndroid::Init() { | 272 void AudioManagerAndroid::Init() { |
242 Java_AudioManagerAndroid_init( | 273 Java_AudioManagerAndroid_init( |
243 base::android::AttachCurrentThread(), | 274 base::android::AttachCurrentThread(), |
244 j_audio_manager_.obj()); | 275 j_audio_manager_.obj()); |
245 } | 276 } |
(...skipping 14 matching lines...) Expand all Loading... | |
260 } | 291 } |
261 | 292 |
262 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { | 293 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { |
263 base::AutoLock lock(streams_lock_); | 294 base::AutoLock lock(streams_lock_); |
264 for (OutputStreams::iterator it = streams_.begin(); | 295 for (OutputStreams::iterator it = streams_.begin(); |
265 it != streams_.end(); ++it) { | 296 it != streams_.end(); ++it) { |
266 (*it)->SetMute(muted); | 297 (*it)->SetMute(muted); |
267 } | 298 } |
268 } | 299 } |
269 | 300 |
270 void AudioManagerAndroid::SetAudioMode(int mode) { | 301 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { |
271 Java_AudioManagerAndroid_setMode( | 302 Java_AudioManagerAndroid_setCommunicationAudioModeOn( |
272 base::android::AttachCurrentThread(), | 303 base::android::AttachCurrentThread(), |
273 j_audio_manager_.obj(), mode); | 304 j_audio_manager_.obj(), on); |
tommi (sloooow) - chröme
2013/12/10 21:19:11
see comment on this above. since this doesn't rem
henrika (OOO until Aug 14)
2013/12/11 13:16:38
So you want me to move the cache to this class ins
tommi (sloooow) - chröme
2013/12/11 17:25:05
Doing it in Java as you're currently doing, is fin
henrika (OOO until Aug 14)
2013/12/12 10:58:00
Great.
| |
274 } | 305 } |
275 | 306 |
276 void AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { | 307 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { |
277 JNIEnv* env = AttachCurrentThread(); | 308 JNIEnv* env = AttachCurrentThread(); |
278 | 309 |
279 // Send the unique device ID to the Java audio manager and make the | 310 // Send the unique device ID to the Java audio manager and make the |
280 // device switch. Provide an empty string to the Java audio manager | 311 // device switch. Provide an empty string to the Java audio manager |
281 // if the default device is selected. | 312 // if the default device is selected. |
282 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( | 313 ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( |
283 env, | 314 env, |
284 device_id == AudioManagerBase::kDefaultDeviceId ? | 315 device_id == AudioManagerBase::kDefaultDeviceId ? |
285 std::string() : device_id); | 316 std::string() : device_id); |
286 Java_AudioManagerAndroid_setDevice( | 317 return Java_AudioManagerAndroid_setDevice( |
287 env, j_audio_manager_.obj(), j_device_id.obj()); | 318 env, j_audio_manager_.obj(), j_device_id.obj()); |
288 } | 319 } |
289 | 320 |
290 int AudioManagerAndroid::GetNativeOutputSampleRate() { | 321 int AudioManagerAndroid::GetNativeOutputSampleRate() { |
291 return Java_AudioManagerAndroid_getNativeOutputSampleRate( | 322 return Java_AudioManagerAndroid_getNativeOutputSampleRate( |
292 base::android::AttachCurrentThread(), | 323 base::android::AttachCurrentThread(), |
293 j_audio_manager_.obj()); | 324 j_audio_manager_.obj()); |
294 } | 325 } |
295 | 326 |
296 bool AudioManagerAndroid::IsAudioLowLatencySupported() { | 327 bool AudioManagerAndroid::IsAudioLowLatencySupported() { |
297 return Java_AudioManagerAndroid_isAudioLowLatencySupported( | 328 return Java_AudioManagerAndroid_isAudioLowLatencySupported( |
298 base::android::AttachCurrentThread(), | 329 base::android::AttachCurrentThread(), |
299 j_audio_manager_.obj()); | 330 j_audio_manager_.obj()); |
300 } | 331 } |
301 | 332 |
302 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { | 333 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { |
303 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( | 334 return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( |
304 base::android::AttachCurrentThread(), | 335 base::android::AttachCurrentThread(), |
305 j_audio_manager_.obj()); | 336 j_audio_manager_.obj()); |
306 } | 337 } |
307 | 338 |
308 } // namespace media | 339 } // namespace media |
OLD | NEW |