audio_manager_android.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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 3// found in the LICENSE file. 4 5#include "media/audio/android/audio_manager_android.h" 6 7#include "base/logging.h" 8#include "jni/AudioManagerAndroid_jni.h" 9#include "media/audio/android/opensles_input.h" 10#include "media/audio/android/opensles_output.h" 11#include "media/audio/audio_manager.h" 12#include "media/audio/audio_parameters.h" 13#include "media/audio/audio_util.h" 14#include "media/audio/fake_audio_input_stream.h" 15#include "media/base/channel_layout.h" 16 17namespace media { 18 19// Maximum number of output streams that can be open simultaneously. 20static const int kMaxOutputStreams = 10; 21 22static const int kAudioModeNormal = 0x00000000; 23static const int kAudioModeInCommunication = 0x00000003; 24 25AudioManager* CreateAudioManager() { 26 return new AudioManagerAndroid(); 27} 28 29AudioManagerAndroid::AudioManagerAndroid() { 30 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 31 32 j_audio_manager_.Reset( 33 Java_AudioManagerAndroid_createAudioManagerAndroid( 34 base::android::AttachCurrentThread(), 35 base::android::GetApplicationContext())); 36} 37 38AudioManagerAndroid::~AudioManagerAndroid() { 39 Shutdown(); 40} 41 42bool AudioManagerAndroid::HasAudioOutputDevices() { 43 return true; 44} 45 46bool AudioManagerAndroid::HasAudioInputDevices() { 47 return true; 48} 49 50void AudioManagerAndroid::GetAudioInputDeviceNames( 51 media::AudioDeviceNames* device_names) { 52 DCHECK(device_names->empty()); 53 device_names->push_front( 54 media::AudioDeviceName(kDefaultDeviceName, kDefaultDeviceId)); 55} 56 57AudioParameters AudioManagerAndroid::GetInputStreamParameters( 58 const std::string& device_id) { 59 // TODO(xians): figure out the right input sample rate and buffer size to 60 // achieve the best audio performance for Android devices. 61 // TODO(xians): query the native channel layout for the specific device. 62 static const int kDefaultSampleRate = 16000; 63 static const int kDefaultBufferSize = 1024; 64 return AudioParameters( 65 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 66 kDefaultSampleRate, 16, kDefaultBufferSize); 67} 68 69AudioOutputStream* AudioManagerAndroid::MakeAudioOutputStream( 70 const AudioParameters& params) { 71 AudioOutputStream* stream = 72 AudioManagerBase::MakeAudioOutputStream(params); 73 if (stream && output_stream_count() == 1) 74 RegisterHeadsetReceiver(); 75 return stream; 76} 77 78AudioInputStream* AudioManagerAndroid::MakeAudioInputStream( 79 const AudioParameters& params, const std::string& device_id) { 80 AudioInputStream* stream = 81 AudioManagerBase::MakeAudioInputStream(params, device_id); 82 if (stream && input_stream_count() == 1) 83 SetAudioMode(kAudioModeInCommunication); 84 return stream; 85} 86 87void AudioManagerAndroid::ReleaseOutputStream(AudioOutputStream* stream) { 88 AudioManagerBase::ReleaseOutputStream(stream); 89 if (!output_stream_count()) 90 UnregisterHeadsetReceiver(); 91} 92 93void AudioManagerAndroid::ReleaseInputStream(AudioInputStream* stream) { 94 AudioManagerBase::ReleaseInputStream(stream); 95 if (!input_stream_count()) 96 SetAudioMode(kAudioModeNormal); 97} 98 99AudioOutputStream* AudioManagerAndroid::MakeLinearOutputStream( 100 const AudioParameters& params) { 101 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 102 return new OpenSLESOutputStream(this, params); 103} 104 105AudioOutputStream* AudioManagerAndroid::MakeLowLatencyOutputStream( 106 const AudioParameters& params) { 107 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 108 return new OpenSLESOutputStream(this, params); 109} 110 111AudioInputStream* AudioManagerAndroid::MakeLinearInputStream( 112 const AudioParameters& params, const std::string& device_id) { 113 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format()); 114 return new OpenSLESInputStream(this, params); 115} 116 117AudioInputStream* AudioManagerAndroid::MakeLowLatencyInputStream( 118 const AudioParameters& params, const std::string& device_id) { 119 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format()); 120 return new OpenSLESInputStream(this, params); 121} 122 123AudioParameters AudioManagerAndroid::GetPreferredOutputStreamParameters( 124 const AudioParameters& input_params) { 125 // TODO(xians): figure out the right output sample rate and buffer size to 126 // achieve the best audio performance for Android devices. 127 static const int kDefaultSampleRate = 44100; 128 static const int kDefaultBufferSize = 2048; 129 130 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 131 int sample_rate = kDefaultSampleRate; 132 int buffer_size = kDefaultBufferSize; 133 int bits_per_sample = 16; 134 int input_channels = 0; 135 if (input_params.IsValid()) { 136 // Use the client's input parameters if they are valid. 137 sample_rate = input_params.sample_rate(); 138 bits_per_sample = input_params.bits_per_sample(); 139 channel_layout = input_params.channel_layout(); 140 input_channels = input_params.input_channels(); 141 142 // TODO(leozwang): Android defines the minimal buffer size requirment 143 // we should follow it. From Android 4.1, a new audio low latency api 144 // set was introduced and is under development, we want to take advantage 145 // of it. 146 buffer_size = std::min(buffer_size, input_params.frames_per_buffer()); 147 } 148 149 int user_buffer_size = GetUserBufferSize(); 150 if (user_buffer_size) 151 buffer_size = user_buffer_size; 152 153 return AudioParameters( 154 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 155 sample_rate, bits_per_sample, buffer_size); 156} 157 158// static 159bool AudioManagerAndroid::RegisterAudioManager(JNIEnv* env) { 160 return RegisterNativesImpl(env); 161} 162 163void AudioManagerAndroid::SetAudioMode(int mode) { 164 Java_AudioManagerAndroid_setMode( 165 base::android::AttachCurrentThread(), 166 j_audio_manager_.obj(), mode); 167} 168 169void AudioManagerAndroid::RegisterHeadsetReceiver() { 170 Java_AudioManagerAndroid_registerHeadsetReceiver( 171 base::android::AttachCurrentThread(), 172 j_audio_manager_.obj()); 173} 174 175void AudioManagerAndroid::UnregisterHeadsetReceiver() { 176 Java_AudioManagerAndroid_unregisterHeadsetReceiver( 177 base::android::AttachCurrentThread(), 178 j_audio_manager_.obj()); 179} 180 181} // namespace media 182