1 /* 2 * Copyright (c) 2013 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_INPUT_H_ 12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_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 // Not defined in the android version we use to build with 20 #define SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION ((SLuint32) 0x00000004) 21 22 #if !defined(WEBRTC_GONK) 23 #include "webrtc/modules/audio_device/android/audio_manager_jni.h" 24 #else 25 #include "media/AudioEffect.h" 26 #endif 27 #include "webrtc/modules/audio_device/android/low_latency_event.h" 28 #include "webrtc/modules/audio_device/include/audio_device.h" 29 #include "webrtc/modules/audio_device/include/audio_device_defines.h" 30 31 namespace webrtc { 32 33 class AudioDeviceBuffer; 34 class AudioManager; 35 class CriticalSectionWrapper; 36 class PlayoutDelayProvider; 37 class SingleRwFifo; 38 class ThreadWrapper; 39 40 // OpenSL implementation that facilitate capturing PCM data from an android 41 // device's microphone. 42 // This class is Thread-compatible. I.e. Given an instance of this class, calls 43 // to non-const methods require exclusive access to the object. 44 class OpenSlesInput { 45 public: 46 OpenSlesInput( 47 PlayoutDelayProvider* delay_provider, AudioManager* audio_manager); 48 ~OpenSlesInput(); 49 50 static int32_t SetAndroidAudioDeviceObjects(void* javaVM, 51 void* context); 52 static void ClearAndroidAudioDeviceObjects(); 53 54 // Main initializaton and termination 55 int32_t Init(); 56 int32_t Terminate(); Initialized()57 bool Initialized() const { return initialized_; } 58 59 // Device enumeration RecordingDevices()60 int16_t RecordingDevices() { return 1; } 61 int32_t RecordingDeviceName(uint16_t index, 62 char name[kAdmMaxDeviceNameSize], 63 char guid[kAdmMaxGuidSize]); 64 65 // Device selection 66 int32_t SetRecordingDevice(uint16_t index); SetRecordingDevice(AudioDeviceModule::WindowsDeviceType device)67 int32_t SetRecordingDevice( 68 AudioDeviceModule::WindowsDeviceType device) { return -1; } 69 70 // No-op SetRecordingSampleRate(uint32_t sample_rate_hz)71 int32_t SetRecordingSampleRate(uint32_t sample_rate_hz) { return 0; } 72 73 // Audio transport initialization 74 int32_t RecordingIsAvailable(bool& available); // NOLINT 75 int32_t InitRecording(); RecordingIsInitialized()76 bool RecordingIsInitialized() const { return rec_initialized_; } 77 78 // Audio transport control 79 int32_t StartRecording(); 80 int32_t StopRecording(); Recording()81 bool Recording() const { return recording_; } 82 83 // Microphone Automatic Gain Control (AGC) 84 int32_t SetAGC(bool enable); AGC()85 bool AGC() const { return agc_enabled_; } 86 87 // Audio mixer initialization 88 int32_t InitMicrophone(); MicrophoneIsInitialized()89 bool MicrophoneIsInitialized() const { return mic_initialized_; } 90 91 // Microphone volume controls 92 int32_t MicrophoneVolumeIsAvailable(bool& available); // NOLINT 93 // TODO(leozwang): Add microphone volume control when OpenSL APIs 94 // are available. SetMicrophoneVolume(uint32_t volume)95 int32_t SetMicrophoneVolume(uint32_t volume) { return 0; } MicrophoneVolume(uint32_t & volume)96 int32_t MicrophoneVolume(uint32_t& volume) const { return -1; } // NOLINT MaxMicrophoneVolume(uint32_t & maxVolume)97 int32_t MaxMicrophoneVolume( 98 uint32_t& maxVolume) const { return 0; } // NOLINT 99 int32_t MinMicrophoneVolume(uint32_t& minVolume) const; // NOLINT 100 int32_t MicrophoneVolumeStepSize( 101 uint16_t& stepSize) const; // NOLINT 102 103 // Microphone mute control 104 int32_t MicrophoneMuteIsAvailable(bool& available); // NOLINT SetMicrophoneMute(bool enable)105 int32_t SetMicrophoneMute(bool enable) { return -1; } MicrophoneMute(bool & enabled)106 int32_t MicrophoneMute(bool& enabled) const { return -1; } // NOLINT 107 108 // Microphone boost control 109 int32_t MicrophoneBoostIsAvailable(bool& available); // NOLINT 110 int32_t SetMicrophoneBoost(bool enable); 111 int32_t MicrophoneBoost(bool& enabled) const; // NOLINT 112 113 // Stereo support 114 int32_t StereoRecordingIsAvailable(bool& available); // NOLINT 115 int32_t SetStereoRecording(bool enable); 116 int32_t StereoRecording(bool& enabled) const; // NOLINT 117 118 // Delay information and control 119 int32_t RecordingDelay(uint16_t& delayMS) const; // NOLINT 120 RecordingWarning()121 bool RecordingWarning() const { return false; } RecordingError()122 bool RecordingError() const { return false; } ClearRecordingWarning()123 void ClearRecordingWarning() {} ClearRecordingError()124 void ClearRecordingError() {} 125 126 // Attach audio buffer 127 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); 128 129 // Built-in AEC is only supported in combination with Java/AudioRecord. BuiltInAECIsAvailable()130 bool BuiltInAECIsAvailable() const { return false; } EnableBuiltInAEC(bool enable)131 int32_t EnableBuiltInAEC(bool enable) { return -1; } 132 133 private: 134 enum { 135 kNumInterfaces = 2, 136 // Keep as few OpenSL buffers as possible to avoid wasting memory. 2 is 137 // minimum for playout. Keep 2 for recording as well. 138 kNumOpenSlBuffers = 2, 139 kNum10MsToBuffer = 8, 140 }; 141 142 int InitSampleRate(); 143 int buffer_size_samples() const; 144 int buffer_size_bytes() const; 145 void UpdateRecordingDelay(); 146 void UpdateSampleRate(); 147 void CalculateNumFifoBuffersNeeded(); 148 void AllocateBuffers(); 149 int TotalBuffersUsed() const; 150 bool EnqueueAllBuffers(); 151 // This function also configures the audio recorder, e.g. sample rate to use 152 // etc, so it should be called when starting recording. 153 bool CreateAudioRecorder(); 154 void DestroyAudioRecorder(); 155 void SetupVoiceMode(); 156 #if defined(WEBRTC_GONK) && defined(WEBRTC_HARDWARE_AEC_NS) 157 void SetupAECAndNS(); 158 bool CheckPlatformAEC(); 159 #endif 160 161 // When overrun happens there will be more frames received from OpenSL than 162 // the desired number of buffers. It is possible to expand the number of 163 // buffers as you go but that would greatly increase the complexity of this 164 // code. HandleOverrun gracefully handles the scenario by restarting playout, 165 // throwing away all pending audio data. This will sound like a click. This 166 // is also logged to identify these types of clicks. 167 // This function returns true if there has been overrun. Further processing 168 // of audio data should be avoided until this function returns false again. 169 // The function needs to be protected by |crit_sect_|. 170 bool HandleOverrun(int event_id, int event_msg); 171 172 static void RecorderSimpleBufferQueueCallback( 173 SLAndroidSimpleBufferQueueItf queueItf, 174 void* pContext); 175 // This function must not take any locks or do any heavy work. It is a 176 // requirement for the OpenSL implementation to work as intended. The reason 177 // for this is that taking locks exposes the OpenSL thread to the risk of 178 // priority inversion. 179 void RecorderSimpleBufferQueueCallbackHandler( 180 SLAndroidSimpleBufferQueueItf queueItf); 181 182 bool StartCbThreads(); 183 void StopCbThreads(); 184 static bool CbThread(void* context); 185 // This function must be protected against data race with threads calling this 186 // class' public functions. It is a requirement for this class to be 187 // Thread-compatible. 188 bool CbThreadImpl(); 189 190 PlayoutDelayProvider* delay_provider_; 191 192 #if !defined(WEBRTC_GONK) 193 // Java API handle 194 AudioManagerJni audio_manager_; 195 #endif 196 197 // TODO(henrika): improve this area 198 // PlayoutDelayProvider* delay_provider_; 199 200 bool initialized_; 201 bool mic_initialized_; 202 bool rec_initialized_; 203 204 // Members that are read/write accessed concurrently by the process thread and 205 // threads calling public functions of this class. 206 rtc::scoped_ptr<ThreadWrapper> rec_thread_; // Processing thread 207 rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; 208 // This member controls the starting and stopping of recording audio to the 209 // the device. 210 bool recording_; 211 212 // Only one thread, T1, may push and only one thread, T2, may pull. T1 may or 213 // may not be the same thread as T2. T2 is the process thread and T1 is the 214 // OpenSL thread. 215 rtc::scoped_ptr<SingleRwFifo> fifo_; 216 int num_fifo_buffers_needed_; 217 LowLatencyEvent event_; 218 int number_overruns_; 219 220 // OpenSL handles 221 SLObjectItf sles_engine_; 222 SLEngineItf sles_engine_itf_; 223 SLObjectItf sles_recorder_; 224 SLRecordItf sles_recorder_itf_; 225 SLAndroidSimpleBufferQueueItf sles_recorder_sbq_itf_; 226 227 // Audio buffers 228 AudioDeviceBuffer* audio_buffer_; 229 // Holds all allocated memory such that it is deallocated properly. 230 rtc::scoped_ptr<rtc::scoped_ptr<int8_t[]>[]> rec_buf_; 231 // Index in |rec_buf_| pointing to the audio buffer that will be ready the 232 // next time RecorderSimpleBufferQueueCallbackHandler is invoked. 233 // Ready means buffer contains audio data from the device. 234 int active_queue_; 235 236 // Audio settings 237 uint32_t rec_sampling_rate_; 238 bool agc_enabled_; 239 240 #if defined(WEBRTC_GONK) && defined(WEBRTC_HARDWARE_AEC_NS) 241 android::AudioEffect* aec_; 242 android::AudioEffect* ns_; 243 #endif 244 // Audio status 245 uint16_t recording_delay_; 246 247 // dlopen for OpenSLES 248 void *opensles_lib_; 249 typedef SLresult (*slCreateEngine_t)(SLObjectItf *, 250 SLuint32, 251 const SLEngineOption *, 252 SLuint32, 253 const SLInterfaceID *, 254 const SLboolean *); 255 slCreateEngine_t f_slCreateEngine; 256 SLInterfaceID SL_IID_ENGINE_; 257 SLInterfaceID SL_IID_BUFFERQUEUE_; 258 SLInterfaceID SL_IID_ANDROIDCONFIGURATION_; 259 SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE_; 260 SLInterfaceID SL_IID_RECORD_; 261 }; 262 263 } // namespace webrtc 264 265 #endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_ 266