blob: ea5144b70fe451f167e840887bdb68810e1f438a [file] [log] [blame]
henrike@webrtc.org82f014a2013-09-10 18:24:07 +00001/*
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
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +000018#include "webrtc/modules/audio_device/android/audio_manager_jni.h"
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000019#include "webrtc/modules/audio_device/android/low_latency_event.h"
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000020#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
24namespace webrtc {
25
26class AudioDeviceBuffer;
27class CriticalSectionWrapper;
28class PlayoutDelayProvider;
29class SingleRwFifo;
30class 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.
36class OpenSlesInput {
37 public:
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +000038 OpenSlesInput(const int32_t id, PlayoutDelayProvider* delay_provider);
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000039 ~OpenSlesInput();
40
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +000041 static int32_t SetAndroidAudioDeviceObjects(void* javaVM,
42 void* env,
43 void* context);
44
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000045 // Main initializaton and termination
46 int32_t Init();
47 int32_t Terminate();
48 bool Initialized() const { return initialized_; }
49
50 // Device enumeration
51 int16_t RecordingDevices() { return 1; }
52 int32_t RecordingDeviceName(uint16_t index,
53 char name[kAdmMaxDeviceNameSize],
54 char guid[kAdmMaxGuidSize]);
55
56 // Device selection
57 int32_t SetRecordingDevice(uint16_t index);
58 int32_t SetRecordingDevice(
59 AudioDeviceModule::WindowsDeviceType device) { return -1; }
60
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +000061 // No-op
62 int32_t SetRecordingSampleRate(uint32_t sample_rate_hz) { return 0; }
63
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000064 // Audio transport initialization
65 int32_t RecordingIsAvailable(bool& available); // NOLINT
66 int32_t InitRecording();
67 bool RecordingIsInitialized() const { return rec_initialized_; }
68
69 // Audio transport control
70 int32_t StartRecording();
71 int32_t StopRecording();
72 bool Recording() const { return recording_; }
73
74 // Microphone Automatic Gain Control (AGC)
75 int32_t SetAGC(bool enable);
76 bool AGC() const { return agc_enabled_; }
77
78 // Audio mixer initialization
79 int32_t MicrophoneIsAvailable(bool& available); // NOLINT
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,
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000124 // 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
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000130 int InitSampleRate();
131 int buffer_size_samples() const;
132 int buffer_size_bytes() const;
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000133 void UpdateRecordingDelay();
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000134 void UpdateSampleRate();
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000135 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
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000173 // Java API handle
174 AudioManagerJni audio_manager_;
175
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000176 int id_;
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +0000177 PlayoutDelayProvider* delay_provider_;
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000178 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_array<scoped_array<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
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000215 uint32_t rec_sampling_rate_;
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000216 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_