| 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 19 matching lines...) Expand all  Loading... | 
| 30 static void AddDefaultDevice(AudioDeviceNames* device_names) { | 30 static void AddDefaultDevice(AudioDeviceNames* device_names) { | 
| 31   DCHECK(device_names->empty()); | 31   DCHECK(device_names->empty()); | 
| 32   device_names->push_front( | 32   device_names->push_front( | 
| 33       AudioDeviceName(AudioManagerBase::kDefaultDeviceName, | 33       AudioDeviceName(AudioManagerBase::kDefaultDeviceName, | 
| 34                       AudioManagerBase::kDefaultDeviceId)); | 34                       AudioManagerBase::kDefaultDeviceId)); | 
| 35 } | 35 } | 
| 36 | 36 | 
| 37 // Maximum number of output streams that can be open simultaneously. | 37 // Maximum number of output streams that can be open simultaneously. | 
| 38 static const int kMaxOutputStreams = 10; | 38 static const int kMaxOutputStreams = 10; | 
| 39 | 39 | 
|  | 40 static const int kAudioModeNormal = 0x00000000; | 
|  | 41 static const int kAudioModeInCommunication = 0x00000003; | 
|  | 42 | 
| 40 static const int kDefaultInputBufferSize = 1024; | 43 static const int kDefaultInputBufferSize = 1024; | 
| 41 static const int kDefaultOutputBufferSize = 2048; | 44 static const int kDefaultOutputBufferSize = 2048; | 
| 42 | 45 | 
| 43 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { | 46 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { | 
| 44   return new AudioManagerAndroid(audio_log_factory); | 47   return new AudioManagerAndroid(audio_log_factory); | 
| 45 } | 48 } | 
| 46 | 49 | 
| 47 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory) | 50 AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory) | 
| 48     : AudioManagerBase(audio_log_factory) { | 51     : AudioManagerBase(audio_log_factory) { | 
| 49   SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 52   SetMaxOutputStreamsAllowed(kMaxOutputStreams); | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 116       AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0, | 119       AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 0, | 
| 117       GetNativeOutputSampleRate(), 16, | 120       GetNativeOutputSampleRate(), 16, | 
| 118       buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects); | 121       buffer_size <= 0 ? kDefaultInputBufferSize : buffer_size, effects); | 
| 119   return params; | 122   return params; | 
| 120 } | 123 } | 
| 121 | 124 | 
| 122 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( | 125 AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( | 
| 123     const AudioParameters& params, | 126     const AudioParameters& params, | 
| 124     const std::string& device_id, | 127     const std::string& device_id, | 
| 125     const std::string& input_device_id) { | 128     const std::string& input_device_id) { | 
| 126   bool had_no_streams = HadNoAudioStreams(); |  | 
| 127   AudioOutputStream* stream = | 129   AudioOutputStream* stream = | 
| 128       AudioManagerBase::MakeAudioOutputStream(params, std::string(), | 130       AudioManagerBase::MakeAudioOutputStream(params, std::string(), | 
| 129           std::string()); | 131           std::string()); | 
| 130 | 132   if (stream && output_stream_count() == 1) { | 
| 131   // The audio manager for Android creates streams intended for real-time | 133     SetAudioMode(kAudioModeInCommunication); | 
| 132   // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. | 134   } | 
| 133   // If a Bluetooth headset is used, the audio stream will use the SCO |  | 
| 134   // channel and therefore have a limited bandwidth (8-16kHz). |  | 
| 135   if (stream && had_no_streams) |  | 
| 136     SetCommunicationAudioModeOn(true); |  | 
| 137 | 135 | 
| 138   { | 136   { | 
| 139     base::AutoLock lock(streams_lock_); | 137     base::AutoLock lock(streams_lock_); | 
| 140     streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); | 138     streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); | 
| 141   } | 139   } | 
| 142 | 140 | 
| 143   return stream; | 141   return stream; | 
| 144 } | 142 } | 
| 145 | 143 | 
| 146 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( | 144 AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( | 
| 147     const AudioParameters& params, const std::string& device_id) { | 145     const AudioParameters& params, const std::string& device_id) { | 
| 148   bool had_no_streams = HadNoAudioStreams(); |  | 
| 149   AudioInputStream* stream = | 146   AudioInputStream* stream = | 
| 150       AudioManagerBase::MakeAudioInputStream(params, device_id); | 147       AudioManagerBase::MakeAudioInputStream(params, device_id); | 
| 151 |  | 
| 152   // The audio manager for Android creates streams intended for real-time |  | 
| 153   // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. |  | 
| 154   // If a Bluetooth headset is used, the audio stream will use the SCO |  | 
| 155   // channel and therefore have a limited bandwidth (8kHz). |  | 
| 156   if (stream && had_no_streams) |  | 
| 157     SetCommunicationAudioModeOn(true); |  | 
| 158   return stream; | 148   return stream; | 
| 159 } | 149 } | 
| 160 | 150 | 
| 161 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { | 151 void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { | 
| 162   AudioManagerBase::ReleaseOutputStream(stream); | 152   AudioManagerBase::ReleaseOutputStream(stream); | 
| 163 | 153   if (!output_stream_count()) { | 
| 164   // Restore the audio mode which was used before the first communication- | 154     SetAudioMode(kAudioModeNormal); | 
| 165   // mode stream was created. | 155   } | 
| 166   if (HadNoAudioStreams()) |  | 
| 167     SetCommunicationAudioModeOn(false); |  | 
| 168   base::AutoLock lock(streams_lock_); | 156   base::AutoLock lock(streams_lock_); | 
| 169   streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); | 157   streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); | 
| 170 } | 158 } | 
| 171 | 159 | 
| 172 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { | 160 void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { | 
| 173   AudioManagerBase::ReleaseInputStream(stream); | 161   AudioManagerBase::ReleaseInputStream(stream); | 
| 174 |  | 
| 175   // Restore the audio mode which was used before the first communication- |  | 
| 176   // mode stream was created. |  | 
| 177   if (HadNoAudioStreams()) |  | 
| 178     SetCommunicationAudioModeOn(false); |  | 
| 179 } | 162 } | 
| 180 | 163 | 
| 181 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( | 164 AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( | 
| 182     const AudioParameters& params) { | 165     const AudioParameters& params) { | 
| 183   DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 166   DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 
| 184   return new OpenSLESOutputStream(this, params); | 167   return new OpenSLESOutputStream(this, params); | 
| 185 } | 168 } | 
| 186 | 169 | 
| 187 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( | 170 AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( | 
| 188     const AudioParameters& params, | 171     const AudioParameters& params, | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 199   // needs it. | 182   // needs it. | 
| 200   DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; | 183   DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; | 
| 201   DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 184   DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); | 
| 202   return new OpenSLESInputStream(this, params); | 185   return new OpenSLESInputStream(this, params); | 
| 203 } | 186 } | 
| 204 | 187 | 
| 205 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( | 188 AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( | 
| 206     const AudioParameters& params, const std::string& device_id) { | 189     const AudioParameters& params, const std::string& device_id) { | 
| 207   DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); | 190   DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); | 
| 208   DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; | 191   DLOG_IF(ERROR, device_id.empty()) << "Invalid device ID!"; | 
| 209   // Use the device ID to select the correct input device. | 192   // Utilize the device ID to select the correct input device. | 
| 210   // Note that the input device is always associated with a certain output | 193   // Note that the input device is always associated with a certain output | 
| 211   // device, i.e., this selection does also switch the output device. | 194   // device, i.e., this selection does also switch the output device. | 
| 212   // All input and output streams will be affected by the device selection. | 195   // All input and output streams will be affected by the device selection. | 
| 213     if (!SetAudioDevice(device_id)) { | 196   SetAudioDevice(device_id); | 
| 214     LOG(ERROR) << "Unable to select audio device!"; |  | 
| 215     return NULL; |  | 
| 216   } |  | 
| 217 | 197 | 
| 218   if (params.effects() != AudioParameters::NO_EFFECTS) { | 198   if (params.effects() != AudioParameters::NO_EFFECTS) { | 
| 219     // Platform effects can only be enabled through the AudioRecord path. | 199     // Platform effects can only be enabled through the AudioRecord path. | 
| 220     // An effect should only have been requested here if recommended by | 200     // An effect should only have been requested here if recommended by | 
| 221     // AudioManagerAndroid.shouldUse<Effect>. | 201     // AudioManagerAndroid.shouldUse<Effect>. | 
| 222     // | 202     // | 
| 223     // Creating this class requires Jelly Bean, which is already guaranteed by | 203     // Creating this class requires Jelly Bean, which is already guaranteed by | 
| 224     // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use | 204     // shouldUse<Effect>. Only DCHECK on that condition to allow tests to use | 
| 225     // the effect settings as a way to select the input path. | 205     // the effect settings as a way to select the input path. | 
| 226     DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); | 206     DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(), 16); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 265 | 245 | 
| 266   int user_buffer_size = GetUserBufferSize(); | 246   int user_buffer_size = GetUserBufferSize(); | 
| 267   if (user_buffer_size) | 247   if (user_buffer_size) | 
| 268     buffer_size = user_buffer_size; | 248     buffer_size = user_buffer_size; | 
| 269 | 249 | 
| 270   return AudioParameters( | 250   return AudioParameters( | 
| 271       AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, | 251       AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, | 
| 272       sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); | 252       sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); | 
| 273 } | 253 } | 
| 274 | 254 | 
| 275 bool AudioManagerAndroid::HadNoAudioStreams() { |  | 
| 276   return output_stream_count() == 0 && input_stream_count() == 0; |  | 
| 277 } |  | 
| 278 |  | 
| 279 // static | 255 // static | 
| 280 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { | 256 bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { | 
| 281   return RegisterNativesImpl(env); | 257   return RegisterNativesImpl(env); | 
| 282 } | 258 } | 
| 283 | 259 | 
| 284 void AudioManagerAndroid::Init() { | 260 void AudioManagerAndroid::Init() { | 
| 285   Java_AudioManagerAndroid_init( | 261   Java_AudioManagerAndroid_init( | 
| 286       base::android::AttachCurrentThread(), | 262       base::android::AttachCurrentThread(), | 
| 287       j_audio_manager_.obj()); | 263       j_audio_manager_.obj()); | 
| 288 } | 264 } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 303 } | 279 } | 
| 304 | 280 | 
| 305 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { | 281 void AudioManagerAndroid::DoSetMuteOnAudioThread(bool muted) { | 
| 306   base::AutoLock lock(streams_lock_); | 282   base::AutoLock lock(streams_lock_); | 
| 307   for (OutputStreams::iterator it = streams_.begin(); | 283   for (OutputStreams::iterator it = streams_.begin(); | 
| 308        it != streams_.end(); ++it) { | 284        it != streams_.end(); ++it) { | 
| 309     (*it)->SetMute(muted); | 285     (*it)->SetMute(muted); | 
| 310   } | 286   } | 
| 311 } | 287 } | 
| 312 | 288 | 
| 313 void AudioManagerAndroid::SetCommunicationAudioModeOn(bool on) { | 289 void AudioManagerAndroid::SetAudioMode(int mode) { | 
| 314   Java_AudioManagerAndroid_setCommunicationAudioModeOn( | 290   Java_AudioManagerAndroid_setMode( | 
| 315       base::android::AttachCurrentThread(), | 291       base::android::AttachCurrentThread(), | 
| 316       j_audio_manager_.obj(), on); | 292       j_audio_manager_.obj(), mode); | 
| 317 } | 293 } | 
| 318 | 294 | 
| 319 bool AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { | 295 void AudioManagerAndroid::SetAudioDevice(const std::string& device_id) { | 
| 320   JNIEnv* env = AttachCurrentThread(); | 296   JNIEnv* env = AttachCurrentThread(); | 
| 321 | 297 | 
| 322   // Send the unique device ID to the Java audio manager and make the | 298   // Send the unique device ID to the Java audio manager and make the | 
| 323   // device switch. Provide an empty string to the Java audio manager | 299   // device switch. Provide an empty string to the Java audio manager | 
| 324   // if the default device is selected. | 300   // if the default device is selected. | 
| 325   ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( | 301   ScopedJavaLocalRef<jstring> j_device_id = ConvertUTF8ToJavaString( | 
| 326       env, | 302       env, | 
| 327       device_id == AudioManagerBase::kDefaultDeviceId ? | 303       device_id == AudioManagerBase::kDefaultDeviceId ? | 
| 328           std::string() : device_id); | 304           std::string() : device_id); | 
| 329   return Java_AudioManagerAndroid_setDevice( | 305   Java_AudioManagerAndroid_setDevice( | 
| 330       env, j_audio_manager_.obj(), j_device_id.obj()); | 306       env, j_audio_manager_.obj(), j_device_id.obj()); | 
| 331 } | 307 } | 
| 332 | 308 | 
| 333 int AudioManagerAndroid::GetNativeOutputSampleRate() { | 309 int AudioManagerAndroid::GetNativeOutputSampleRate() { | 
| 334   return Java_AudioManagerAndroid_getNativeOutputSampleRate( | 310   return Java_AudioManagerAndroid_getNativeOutputSampleRate( | 
| 335       base::android::AttachCurrentThread(), | 311       base::android::AttachCurrentThread(), | 
| 336       j_audio_manager_.obj()); | 312       j_audio_manager_.obj()); | 
| 337 } | 313 } | 
| 338 | 314 | 
| 339 bool AudioManagerAndroid::IsAudioLowLatencySupported() { | 315 bool AudioManagerAndroid::IsAudioLowLatencySupported() { | 
| 340   return Java_AudioManagerAndroid_isAudioLowLatencySupported( | 316   return Java_AudioManagerAndroid_isAudioLowLatencySupported( | 
| 341       base::android::AttachCurrentThread(), | 317       base::android::AttachCurrentThread(), | 
| 342       j_audio_manager_.obj()); | 318       j_audio_manager_.obj()); | 
| 343 } | 319 } | 
| 344 | 320 | 
| 345 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { | 321 int AudioManagerAndroid::GetAudioLowLatencyOutputFrameSize() { | 
| 346   return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( | 322   return Java_AudioManagerAndroid_getAudioLowLatencyOutputFrameSize( | 
| 347       base::android::AttachCurrentThread(), | 323       base::android::AttachCurrentThread(), | 
| 348       j_audio_manager_.obj()); | 324       j_audio_manager_.obj()); | 
| 349 } | 325 } | 
| 350 | 326 | 
| 351 }  // namespace media | 327 }  // namespace media | 
| OLD | NEW | 
|---|