diff options
author | henrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 19:00:04 +0000 |
---|---|---|
committer | henrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 19:00:04 +0000 |
commit | 3989fd396df575f42424e9aa22c3050742a5e486 (patch) | |
tree | 3e483eb14689c8aacc95f2aebc74f7eb060c216f /media/audio/android | |
parent | e1d51c34fa0d0d9eec1560baa74c4eb726dacdce (diff) | |
download | chromium_src-3989fd396df575f42424e9aa22c3050742a5e486.zip chromium_src-3989fd396df575f42424e9aa22c3050742a5e486.tar.gz chromium_src-3989fd396df575f42424e9aa22c3050742a5e486.tar.bz2 |
Volume button now controls media volume for WebAudio.
Today, WebAudio uses the OpenSL ES low-latency audio backend in media/audio but the stream type is always communication mode (which is OK for WebRTC but not for WebAudio).
This patch ensures that:
- Only switch to system-wide Communication mode when a low-latency input stream is created (e.g. from getUserMedia).
- Opens the native output stream in Media mode if system mode is Media and in Communication mode if system mode is Communication.
To summarize: an application which renders WebAudio audio should now be able to see the default media volume icon and change the volume accordingly.
TEST=http://chromium.googlecode.com/svn/trunk/samples/audio/shiny-drum-machine.html
BUG=342114
Review URL: https://codereview.chromium.org/173503003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252341 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/android')
-rw-r--r-- | media/audio/android/audio_manager_android.cc | 40 | ||||
-rw-r--r-- | media/audio/android/audio_manager_android.h | 6 | ||||
-rw-r--r-- | media/audio/android/opensles_output.cc | 11 | ||||
-rw-r--r-- | media/audio/android/opensles_output.h | 7 |
4 files changed, 36 insertions, 28 deletions
diff --git a/media/audio/android/audio_manager_android.cc b/media/audio/android/audio_manager_android.cc index a8d81c7..273a741 100644 --- a/media/audio/android/audio_manager_android.cc +++ b/media/audio/android/audio_manager_android.cc @@ -45,7 +45,8 @@ AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { } AudioManagerAndroid::AudioManagerAndroid(AudioLogFactory* audio_log_factory) - : AudioManagerBase(audio_log_factory) { + : AudioManagerBase(audio_log_factory), + communication_mode_is_on_(false) { SetMaxOutputStreamsAllowed(kMaxOutputStreams); j_audio_manager_.Reset( @@ -123,17 +124,8 @@ AudioParameters AudioManagerAndroid::GetInputStreamParameters( AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( const AudioParameters& params, const std::string& device_id) { - bool had_no_streams = HadNoAudioStreams(); AudioOutputStream* stream = AudioManagerBase::MakeAudioOutputStream(params, std::string()); - - // The audio manager for Android creates streams intended for real-time - // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. - // If a Bluetooth headset is used, the audio stream will use the SCO - // channel and therefore have a limited bandwidth (8-16kHz). - if (stream && had_no_streams) - SetCommunicationAudioModeOn(true); - { base::AutoLock lock(streams_lock_); streams_.insert(static_cast<OpenSLESOutputStream*>(stream)); @@ -144,7 +136,7 @@ AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( const AudioParameters& params, const std::string& device_id) { - bool had_no_streams = HadNoAudioStreams(); + bool has_no_input_streams = HasNoAudioInputStreams(); AudioInputStream* stream = AudioManagerBase::MakeAudioInputStream(params, device_id); @@ -152,18 +144,15 @@ AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( // VoIP sessions and therefore sets the audio mode to MODE_IN_COMMUNICATION. // If a Bluetooth headset is used, the audio stream will use the SCO // channel and therefore have a limited bandwidth (8kHz). - if (stream && had_no_streams) + if (stream && has_no_input_streams) { + communication_mode_is_on_ = true; SetCommunicationAudioModeOn(true); + } return stream; } void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { AudioManagerBase::ReleaseOutputStream(stream); - - // Restore the audio mode which was used before the first communication- - // mode stream was created. - if (HadNoAudioStreams()) - SetCommunicationAudioModeOn(false); base::AutoLock lock(streams_lock_); streams_.erase(static_cast<OpenSLESOutputStream*>(stream)); } @@ -173,14 +162,16 @@ void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { // Restore the audio mode which was used before the first communication- // mode stream was created. - if (HadNoAudioStreams()) + if (HasNoAudioInputStreams()) { + communication_mode_is_on_ = false; SetCommunicationAudioModeOn(false); + } } AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( const AudioParameters& params) { DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); - return new OpenSLESOutputStream(this, params); + return new OpenSLESOutputStream(this, params, SL_ANDROID_STREAM_MEDIA); } AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( @@ -188,7 +179,12 @@ AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( const std::string& device_id) { DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!"; DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); - return new OpenSLESOutputStream(this, params); + + // Set stream type which matches the current system-wide audio mode used by + // the Android audio manager. + const SLint32 stream_type = communication_mode_is_on_ ? + SL_ANDROID_STREAM_VOICE : SL_ANDROID_STREAM_MEDIA; + return new OpenSLESOutputStream(this, params, stream_type); } AudioInputStream* AudioManagerAndroid::MakeLinearInputStream( @@ -270,8 +266,8 @@ AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters( sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS); } -bool AudioManagerAndroid::HadNoAudioStreams() { - return output_stream_count() == 0 && input_stream_count() == 0; +bool AudioManagerAndroid::HasNoAudioInputStreams() { + return input_stream_count() == 0; } // static diff --git a/media/audio/android/audio_manager_android.h b/media/audio/android/audio_manager_android.h index ac67d08..b65e593 100644 --- a/media/audio/android/audio_manager_android.h +++ b/media/audio/android/audio_manager_android.h @@ -65,7 +65,7 @@ class MEDIA_EXPORT AudioManagerAndroid : public AudioManagerBase { const AudioParameters& input_params) OVERRIDE; private: - bool HadNoAudioStreams(); + bool HasNoAudioInputStreams(); void Init(); void Close(); void SetCommunicationAudioModeOn(bool on); @@ -90,6 +90,10 @@ class MEDIA_EXPORT AudioManagerAndroid : public AudioManagerBase { // lock is used to guard access to |streams_|. base::Lock streams_lock_; + // Enabled when first input stream is created and set to false when last + // input stream is destroyed. Also affects the stream type of output streams. + bool communication_mode_is_on_; + DISALLOW_COPY_AND_ASSIGN(AudioManagerAndroid); }; diff --git a/media/audio/android/opensles_output.cc b/media/audio/android/opensles_output.cc index b71680f..41c03c7 100644 --- a/media/audio/android/opensles_output.cc +++ b/media/audio/android/opensles_output.cc @@ -20,8 +20,10 @@ namespace media { OpenSLESOutputStream::OpenSLESOutputStream(AudioManagerAndroid* manager, - const AudioParameters& params) + const AudioParameters& params, + SLint32 stream_type) : audio_manager_(manager), + stream_type_(stream_type), callback_(NULL), player_(NULL), simple_buffer_queue_(NULL), @@ -30,7 +32,8 @@ OpenSLESOutputStream::OpenSLESOutputStream(AudioManagerAndroid* manager, started_(false), muted_(false), volume_(1.0) { - DVLOG(2) << "OpenSLESOutputStream::OpenSLESOutputStream()"; + DVLOG(2) << "OpenSLESOutputStream::OpenSLESOutputStream(" + << "stream_type=" << stream_type << ")"; format_.formatType = SL_DATAFORMAT_PCM; format_.numChannels = static_cast<SLuint32>(params.channels()); // Provides sampling rate in milliHertz to OpenSLES. @@ -248,11 +251,11 @@ bool OpenSLESOutputStream::CreatePlayer() { player_object_.Get(), SL_IID_ANDROIDCONFIGURATION, &player_config), false); - SLint32 stream_type = SL_ANDROID_STREAM_VOICE; + // Set configuration using the stream type provided at construction. LOG_ON_FAILURE_AND_RETURN( (*player_config)->SetConfiguration(player_config, SL_ANDROID_KEY_STREAM_TYPE, - &stream_type, + &stream_type_, sizeof(SLint32)), false); diff --git a/media/audio/android/opensles_output.h b/media/audio/android/opensles_output.h index 623b019..b0b678c 100644 --- a/media/audio/android/opensles_output.h +++ b/media/audio/android/opensles_output.h @@ -28,7 +28,8 @@ class OpenSLESOutputStream : public AudioOutputStream { static const int kMaxNumOfBuffersInQueue = 2; OpenSLESOutputStream(AudioManagerAndroid* manager, - const AudioParameters& params); + const AudioParameters& params, + SLint32 stream_type); virtual ~OpenSLESOutputStream(); @@ -77,6 +78,10 @@ class OpenSLESOutputStream : public AudioOutputStream { AudioManagerAndroid* audio_manager_; + // Audio playback stream type. + // See SLES/OpenSLES_Android.h for details. + SLint32 stream_type_; + AudioSourceCallback* callback_; // Shared engine interfaces for the app. |