1 /* 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ 12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ 13 14 #include <SLES/OpenSLES.h> 15 #include <SLES/OpenSLES_Android.h> 16 #include <SLES/OpenSLES_AndroidConfiguration.h> 17 18 #include "webrtc/base/scoped_ptr.h" 19 #include "webrtc/base/thread_checker.h" 20 #include "webrtc/modules/audio_device/android/audio_common.h" 21 #include "webrtc/modules/audio_device/android/audio_manager.h" 22 #include "webrtc/modules/audio_device/android/opensles_common.h" 23 #include "webrtc/modules/audio_device/include/audio_device_defines.h" 24 #include "webrtc/modules/audio_device/audio_device_generic.h" 25 #include "webrtc/modules/utility/include/helpers_android.h" 26 27 namespace webrtc { 28 29 class FineAudioBuffer; 30 31 // Implements 16-bit mono PCM audio output support for Android using the 32 // C based OpenSL ES API. No calls from C/C++ to Java using JNI is done. 33 // 34 // An instance must be created and destroyed on one and the same thread. 35 // All public methods must also be called on the same thread. A thread checker 36 // will RTC_DCHECK if any method is called on an invalid thread. Decoded audio 37 // buffers are requested on a dedicated internal thread managed by the OpenSL 38 // ES layer. 39 // 40 // The existing design forces the user to call InitPlayout() after Stoplayout() 41 // to be able to call StartPlayout() again. This is inline with how the Java- 42 // based implementation works. 43 // 44 // OpenSL ES is a native C API which have no Dalvik-related overhead such as 45 // garbage collection pauses and it supports reduced audio output latency. 46 // If the device doesn't claim this feature but supports API level 9 (Android 47 // platform version 2.3) or later, then we can still use the OpenSL ES APIs but 48 // the output latency may be higher. 49 class OpenSLESPlayer { 50 public: 51 // The lower output latency path is used only if the application requests a 52 // buffer count of 2 or more, and a buffer size and sample rate that are 53 // compatible with the device's native output configuration provided via the 54 // audio manager at construction. 55 static const int kNumOfOpenSLESBuffers = 4; 56 57 // There is no need for this class to use JNI. SetAndroidAudioDeviceObjects(void * javaVM,void * context)58 static int32_t SetAndroidAudioDeviceObjects(void* javaVM, void* context) { 59 return 0; 60 } ClearAndroidAudioDeviceObjects()61 static void ClearAndroidAudioDeviceObjects() {} 62 63 explicit OpenSLESPlayer(AudioManager* audio_manager); 64 ~OpenSLESPlayer(); 65 66 int Init(); 67 int Terminate(); 68 69 int InitPlayout(); PlayoutIsInitialized()70 bool PlayoutIsInitialized() const { return initialized_; } 71 72 int StartPlayout(); 73 int StopPlayout(); Playing()74 bool Playing() const { return playing_; } 75 76 int SpeakerVolumeIsAvailable(bool& available); 77 int SetSpeakerVolume(uint32_t volume); 78 int SpeakerVolume(uint32_t& volume) const; 79 int MaxSpeakerVolume(uint32_t& maxVolume) const; 80 int MinSpeakerVolume(uint32_t& minVolume) const; 81 82 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); 83 84 private: 85 // These callback methods are called when data is required for playout. 86 // They are both called from an internal "OpenSL ES thread" which is not 87 // attached to the Dalvik VM. 88 static void SimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf caller, 89 void* context); 90 void FillBufferQueue(); 91 // Reads audio data in PCM format using the AudioDeviceBuffer. 92 // Can be called both on the main thread (during Start()) and from the 93 // internal audio thread while output streaming is active. 94 void EnqueuePlayoutData(); 95 96 // Configures the SL_DATAFORMAT_PCM structure. 97 SLDataFormat_PCM CreatePCMConfiguration(size_t channels, 98 int sample_rate, 99 size_t bits_per_sample); 100 101 // Allocate memory for audio buffers which will be used to render audio 102 // via the SLAndroidSimpleBufferQueueItf interface. 103 void AllocateDataBuffers(); 104 105 // Creates/destroys the main engine object and the SLEngineItf interface. 106 bool CreateEngine(); 107 void DestroyEngine(); 108 109 // Creates/destroys the output mix object. 110 bool CreateMix(); 111 void DestroyMix(); 112 113 // Creates/destroys the audio player and the simple-buffer object. 114 // Also creates the volume object. 115 bool CreateAudioPlayer(); 116 void DestroyAudioPlayer(); 117 118 SLuint32 GetPlayState() const; 119 120 // Ensures that methods are called from the same thread as this object is 121 // created on. 122 rtc::ThreadChecker thread_checker_; 123 124 // Stores thread ID in first call to SimpleBufferQueueCallback() from internal 125 // non-application thread which is not attached to the Dalvik JVM. 126 // Detached during construction of this object. 127 rtc::ThreadChecker thread_checker_opensles_; 128 129 // Contains audio parameters provided to this class at construction by the 130 // AudioManager. 131 const AudioParameters audio_parameters_; 132 133 // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the 134 // AudioDeviceModuleImpl class and called by AudioDeviceModuleImpl::Create(). 135 AudioDeviceBuffer* audio_device_buffer_; 136 137 bool initialized_; 138 bool playing_; 139 140 // PCM-type format definition. 141 // TODO(henrika): add support for SLAndroidDataFormat_PCM_EX (android-21) if 142 // 32-bit float representation is needed. 143 SLDataFormat_PCM pcm_format_; 144 145 // Number of bytes per audio buffer in each |audio_buffers_[i]|. 146 // Typical sizes are 480 or 512 bytes corresponding to native output buffer 147 // sizes of 240 or 256 audio frames respectively. 148 size_t bytes_per_buffer_; 149 150 // Queue of audio buffers to be used by the player object for rendering 151 // audio. They will be used in a Round-robin way and the size of each buffer 152 // is given by FineAudioBuffer::RequiredBufferSizeBytes(). 153 rtc::scoped_ptr<SLint8[]> audio_buffers_[kNumOfOpenSLESBuffers]; 154 155 // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data 156 // in chunks of 10ms. It then allows for this data to be pulled in 157 // a finer or coarser granularity. I.e. interacting with this class instead 158 // of directly with the AudioDeviceBuffer one can ask for any number of 159 // audio data samples. 160 // Example: native buffer size is 240 audio frames at 48kHz sample rate. 161 // WebRTC will provide 480 audio frames per 10ms but OpenSL ES asks for 240 162 // in each callback (one every 5ms). This class can then ask for 240 and the 163 // FineAudioBuffer will ask WebRTC for new data only every second callback 164 // and also cach non-utilized audio. 165 rtc::scoped_ptr<FineAudioBuffer> fine_buffer_; 166 167 // Keeps track of active audio buffer 'n' in the audio_buffers_[n] queue. 168 // Example (kNumOfOpenSLESBuffers = 2): counts 0, 1, 0, 1, ... 169 int buffer_index_; 170 171 // The engine object which provides the SLEngineItf interface. 172 // Created by the global Open SL ES constructor slCreateEngine(). 173 webrtc::ScopedSLObjectItf engine_object_; 174 175 // This interface exposes creation methods for all the OpenSL ES object types. 176 // It is the OpenSL ES API entry point. 177 SLEngineItf engine_; 178 179 // Output mix object to be used by the player object. 180 webrtc::ScopedSLObjectItf output_mix_; 181 182 // The audio player media object plays out audio to the speakers. It also 183 // supports volume control. 184 webrtc::ScopedSLObjectItf player_object_; 185 186 // This interface is supported on the audio player and it controls the state 187 // of the audio player. 188 SLPlayItf player_; 189 190 // The Android Simple Buffer Queue interface is supported on the audio player 191 // and it provides methods to send audio data from the source to the audio 192 // player for rendering. 193 SLAndroidSimpleBufferQueueItf simple_buffer_queue_; 194 195 // This interface exposes controls for manipulating the object’s audio volume 196 // properties. This interface is supported on the Audio Player object. 197 SLVolumeItf volume_; 198 199 // Last time the OpenSL ES layer asked for audio data to play out. 200 uint32_t last_play_time_; 201 }; 202 203 } // namespace webrtc 204 205 #endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_ 206