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