File: opensles_input.h

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (228 lines) | stat: -rw-r--r-- 8,458 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_
#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_

#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <SLES/OpenSLES_AndroidConfiguration.h>

#include "webrtc/modules/audio_device/android/audio_manager_jni.h"
#include "webrtc/modules/audio_device/android/low_latency_event.h"
#include "webrtc/modules/audio_device/include/audio_device.h"
#include "webrtc/modules/audio_device/include/audio_device_defines.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {

class AudioDeviceBuffer;
class CriticalSectionWrapper;
class PlayoutDelayProvider;
class SingleRwFifo;
class ThreadWrapper;

// OpenSL implementation that facilitate capturing PCM data from an android
// device's microphone.
// This class is Thread-compatible. I.e. Given an instance of this class, calls
// to non-const methods require exclusive access to the object.
class OpenSlesInput {
 public:
  OpenSlesInput(const int32_t id, PlayoutDelayProvider* delay_provider);
  ~OpenSlesInput();

  static int32_t SetAndroidAudioDeviceObjects(void* javaVM,
                                              void* env,
                                              void* context);
  static void ClearAndroidAudioDeviceObjects();

  // Main initializaton and termination
  int32_t Init();
  int32_t Terminate();
  bool Initialized() const { return initialized_; }

  // Device enumeration
  int16_t RecordingDevices() { return 1; }
  int32_t RecordingDeviceName(uint16_t index,
                              char name[kAdmMaxDeviceNameSize],
                              char guid[kAdmMaxGuidSize]);

  // Device selection
  int32_t SetRecordingDevice(uint16_t index);
  int32_t SetRecordingDevice(
      AudioDeviceModule::WindowsDeviceType device) { return -1; }

  // No-op
  int32_t SetRecordingSampleRate(uint32_t sample_rate_hz) { return 0; }

  // Audio transport initialization
  int32_t RecordingIsAvailable(bool& available);  // NOLINT
  int32_t InitRecording();
  bool RecordingIsInitialized() const { return rec_initialized_; }

  // Audio transport control
  int32_t StartRecording();
  int32_t StopRecording();
  bool Recording() const { return recording_; }

  // Microphone Automatic Gain Control (AGC)
  int32_t SetAGC(bool enable);
  bool AGC() const { return agc_enabled_; }

  // Audio mixer initialization
  int32_t InitMicrophone();
  bool MicrophoneIsInitialized() const { return mic_initialized_; }

  // Microphone volume controls
  int32_t MicrophoneVolumeIsAvailable(bool& available);  // NOLINT
  // TODO(leozwang): Add microphone volume control when OpenSL APIs
  // are available.
  int32_t SetMicrophoneVolume(uint32_t volume) { return 0; }
  int32_t MicrophoneVolume(uint32_t& volume) const { return -1; }  // NOLINT
  int32_t MaxMicrophoneVolume(
      uint32_t& maxVolume) const { return 0; }  // NOLINT
  int32_t MinMicrophoneVolume(uint32_t& minVolume) const;  // NOLINT
  int32_t MicrophoneVolumeStepSize(
      uint16_t& stepSize) const;  // NOLINT

  // Microphone mute control
  int32_t MicrophoneMuteIsAvailable(bool& available);  // NOLINT
  int32_t SetMicrophoneMute(bool enable) { return -1; }
  int32_t MicrophoneMute(bool& enabled) const { return -1; }  // NOLINT

  // Microphone boost control
  int32_t MicrophoneBoostIsAvailable(bool& available);  // NOLINT
  int32_t SetMicrophoneBoost(bool enable);
  int32_t MicrophoneBoost(bool& enabled) const;  // NOLINT

  // Stereo support
  int32_t StereoRecordingIsAvailable(bool& available);  // NOLINT
  int32_t SetStereoRecording(bool enable) { return -1; }
  int32_t StereoRecording(bool& enabled) const;  // NOLINT

  // Delay information and control
  int32_t RecordingDelay(uint16_t& delayMS) const;  // NOLINT

  bool RecordingWarning() const { return false; }
  bool RecordingError() const  { return false; }
  void ClearRecordingWarning() {}
  void ClearRecordingError() {}

  // Attach audio buffer
  void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);

  // Built-in AEC is only supported in combination with Java/AudioRecord.
  bool BuiltInAECIsAvailable() const { return false; }
  int32_t EnableBuiltInAEC(bool enable) { return -1; }

 private:
  enum {
    kNumInterfaces = 2,
    // Keep as few OpenSL buffers as possible to avoid wasting memory. 2 is
    // minimum for playout. Keep 2 for recording as well.
    kNumOpenSlBuffers = 2,
    kNum10MsToBuffer = 3,
  };

  int InitSampleRate();
  int buffer_size_samples() const;
  int buffer_size_bytes() const;
  void UpdateRecordingDelay();
  void UpdateSampleRate();
  void CalculateNumFifoBuffersNeeded();
  void AllocateBuffers();
  int TotalBuffersUsed() const;
  bool EnqueueAllBuffers();
  // This function also configures the audio recorder, e.g. sample rate to use
  // etc, so it should be called when starting recording.
  bool CreateAudioRecorder();
  void DestroyAudioRecorder();

  // When overrun happens there will be more frames received from OpenSL than
  // the desired number of buffers. It is possible to expand the number of
  // buffers as you go but that would greatly increase the complexity of this
  // code. HandleOverrun gracefully handles the scenario by restarting playout,
  // throwing away all pending audio data. This will sound like a click. This
  // is also logged to identify these types of clicks.
  // This function returns true if there has been overrun. Further processing
  // of audio data should be avoided until this function returns false again.
  // The function needs to be protected by |crit_sect_|.
  bool HandleOverrun(int event_id, int event_msg);

  static void RecorderSimpleBufferQueueCallback(
      SLAndroidSimpleBufferQueueItf queueItf,
      void* pContext);
  // This function must not take any locks or do any heavy work. It is a
  // requirement for the OpenSL implementation to work as intended. The reason
  // for this is that taking locks exposes the OpenSL thread to the risk of
  // priority inversion.
  void RecorderSimpleBufferQueueCallbackHandler(
      SLAndroidSimpleBufferQueueItf queueItf);

  bool StartCbThreads();
  void StopCbThreads();
  static bool CbThread(void* context);
  // This function must be protected against data race with threads calling this
  // class' public functions. It is a requirement for this class to be
  // Thread-compatible.
  bool CbThreadImpl();

  // Java API handle
  AudioManagerJni audio_manager_;

  int id_;
  PlayoutDelayProvider* delay_provider_;
  bool initialized_;
  bool mic_initialized_;
  bool rec_initialized_;

  // Members that are read/write accessed concurrently by the process thread and
  // threads calling public functions of this class.
  scoped_ptr<ThreadWrapper> rec_thread_;  // Processing thread
  scoped_ptr<CriticalSectionWrapper> crit_sect_;
  // This member controls the starting and stopping of recording audio to the
  // the device.
  bool recording_;

  // Only one thread, T1, may push and only one thread, T2, may pull. T1 may or
  // may not be the same thread as T2. T2 is the process thread and T1 is the
  // OpenSL thread.
  scoped_ptr<SingleRwFifo> fifo_;
  int num_fifo_buffers_needed_;
  LowLatencyEvent event_;
  int number_overruns_;

  // OpenSL handles
  SLObjectItf sles_engine_;
  SLEngineItf sles_engine_itf_;
  SLObjectItf sles_recorder_;
  SLRecordItf sles_recorder_itf_;
  SLAndroidSimpleBufferQueueItf sles_recorder_sbq_itf_;

  // Audio buffers
  AudioDeviceBuffer* audio_buffer_;
  // Holds all allocated memory such that it is deallocated properly.
  scoped_ptr<scoped_ptr<int8_t[]>[]> rec_buf_;
  // Index in |rec_buf_| pointing to the audio buffer that will be ready the
  // next time RecorderSimpleBufferQueueCallbackHandler is invoked.
  // Ready means buffer contains audio data from the device.
  int active_queue_;

  // Audio settings
  uint32_t rec_sampling_rate_;
  bool agc_enabled_;

  // Audio status
  uint16_t recording_delay_;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_