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