blob: 1ce02e50865702dae74c57dbdff772c980b21409 [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);
henrike@webrtc.org573a1b42014-01-10 22:58:06 +000044 static void ClearAndroidAudioDeviceObjects();
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +000045
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000046 // 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
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +000062 // No-op
63 int32_t SetRecordingSampleRate(uint32_t sample_rate_hz) { return 0; }
64
henrike@webrtc.org82f014a2013-09-10 18:24:07 +000065 // 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 MicrophoneIsAvailable(bool& available); // NOLINT
81 int32_t InitMicrophone();
82 bool MicrophoneIsInitialized() const { return mic_initialized_; }
83
84 // Microphone volume controls
85 int32_t MicrophoneVolumeIsAvailable(bool& available); // NOLINT
86 // TODO(leozwang): Add microphone volume control when OpenSL APIs
87 // are available.
88 int32_t SetMicrophoneVolume(uint32_t volume) { return 0; }
89 int32_t MicrophoneVolume(uint32_t& volume) const { return -1; } // NOLINT
90 int32_t MaxMicrophoneVolume(
91 uint32_t& maxVolume) const { return 0; } // NOLINT
92 int32_t MinMicrophoneVolume(uint32_t& minVolume) const; // NOLINT
93 int32_t MicrophoneVolumeStepSize(
94 uint16_t& stepSize) const; // NOLINT
95
96 // Microphone mute control
97 int32_t MicrophoneMuteIsAvailable(bool& available); // NOLINT
98 int32_t SetMicrophoneMute(bool enable) { return -1; }
99 int32_t MicrophoneMute(bool& enabled) const { return -1; } // NOLINT
100
101 // Microphone boost control
102 int32_t MicrophoneBoostIsAvailable(bool& available); // NOLINT
103 int32_t SetMicrophoneBoost(bool enable);
104 int32_t MicrophoneBoost(bool& enabled) const; // NOLINT
105
106 // Stereo support
107 int32_t StereoRecordingIsAvailable(bool& available); // NOLINT
108 int32_t SetStereoRecording(bool enable) { return -1; }
109 int32_t StereoRecording(bool& enabled) const; // NOLINT
110
111 // Delay information and control
112 int32_t RecordingDelay(uint16_t& delayMS) const; // NOLINT
113
114 bool RecordingWarning() const { return false; }
115 bool RecordingError() const { return false; }
116 void ClearRecordingWarning() {}
117 void ClearRecordingError() {}
118
119 // Attach audio buffer
120 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
121
122 private:
123 enum {
124 kNumInterfaces = 2,
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000125 // Keep as few OpenSL buffers as possible to avoid wasting memory. 2 is
126 // minimum for playout. Keep 2 for recording as well.
127 kNumOpenSlBuffers = 2,
128 kNum10MsToBuffer = 3,
129 };
130
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000131 int InitSampleRate();
132 int buffer_size_samples() const;
133 int buffer_size_bytes() const;
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000134 void UpdateRecordingDelay();
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000135 void UpdateSampleRate();
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000136 void CalculateNumFifoBuffersNeeded();
137 void AllocateBuffers();
138 int TotalBuffersUsed() const;
139 bool EnqueueAllBuffers();
140 // This function also configures the audio recorder, e.g. sample rate to use
141 // etc, so it should be called when starting recording.
142 bool CreateAudioRecorder();
143 void DestroyAudioRecorder();
144
145 // When overrun happens there will be more frames received from OpenSL than
146 // the desired number of buffers. It is possible to expand the number of
147 // buffers as you go but that would greatly increase the complexity of this
148 // code. HandleOverrun gracefully handles the scenario by restarting playout,
149 // throwing away all pending audio data. This will sound like a click. This
150 // is also logged to identify these types of clicks.
151 // This function returns true if there has been overrun. Further processing
152 // of audio data should be avoided until this function returns false again.
153 // The function needs to be protected by |crit_sect_|.
154 bool HandleOverrun(int event_id, int event_msg);
155
156 static void RecorderSimpleBufferQueueCallback(
157 SLAndroidSimpleBufferQueueItf queueItf,
158 void* pContext);
159 // This function must not take any locks or do any heavy work. It is a
160 // requirement for the OpenSL implementation to work as intended. The reason
161 // for this is that taking locks exposes the OpenSL thread to the risk of
162 // priority inversion.
163 void RecorderSimpleBufferQueueCallbackHandler(
164 SLAndroidSimpleBufferQueueItf queueItf);
165
166 bool StartCbThreads();
167 void StopCbThreads();
168 static bool CbThread(void* context);
169 // This function must be protected against data race with threads calling this
170 // class' public functions. It is a requirement for this class to be
171 // Thread-compatible.
172 bool CbThreadImpl();
173
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000174 // Java API handle
175 AudioManagerJni audio_manager_;
176
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000177 int id_;
henrike@webrtc.org9ee75e92013-12-11 21:42:44 +0000178 PlayoutDelayProvider* delay_provider_;
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000179 bool initialized_;
180 bool mic_initialized_;
181 bool rec_initialized_;
182
183 // Members that are read/write accessed concurrently by the process thread and
184 // threads calling public functions of this class.
185 scoped_ptr<ThreadWrapper> rec_thread_; // Processing thread
186 scoped_ptr<CriticalSectionWrapper> crit_sect_;
187 // This member controls the starting and stopping of recording audio to the
188 // the device.
189 bool recording_;
190
191 // Only one thread, T1, may push and only one thread, T2, may pull. T1 may or
192 // may not be the same thread as T2. T2 is the process thread and T1 is the
193 // OpenSL thread.
194 scoped_ptr<SingleRwFifo> fifo_;
195 int num_fifo_buffers_needed_;
196 LowLatencyEvent event_;
197 int number_overruns_;
198
199 // OpenSL handles
200 SLObjectItf sles_engine_;
201 SLEngineItf sles_engine_itf_;
202 SLObjectItf sles_recorder_;
203 SLRecordItf sles_recorder_itf_;
204 SLAndroidSimpleBufferQueueItf sles_recorder_sbq_itf_;
205
206 // Audio buffers
207 AudioDeviceBuffer* audio_buffer_;
208 // Holds all allocated memory such that it is deallocated properly.
209 scoped_array<scoped_array<int8_t> > rec_buf_;
210 // Index in |rec_buf_| pointing to the audio buffer that will be ready the
211 // next time RecorderSimpleBufferQueueCallbackHandler is invoked.
212 // Ready means buffer contains audio data from the device.
213 int active_queue_;
214
215 // Audio settings
henrike@webrtc.orgc8dea6a2013-09-17 18:44:51 +0000216 uint32_t rec_sampling_rate_;
henrike@webrtc.org82f014a2013-09-10 18:24:07 +0000217 bool agc_enabled_;
218
219 // Audio status
220 uint16_t recording_delay_;
221};
222
223} // namespace webrtc
224
225#endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_