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