OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2016 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_RECORDER_H_ | |
12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_RECORDER_H_ | |
13 | |
14 #include <SLES/OpenSLES.h> | |
15 #include <SLES/OpenSLES_Android.h> | |
16 #include <SLES/OpenSLES_AndroidConfiguration.h> | |
17 | |
18 #include "webrtc/base/thread_checker.h" | |
19 #include "webrtc/modules/audio_device/android/audio_common.h" | |
20 #include "webrtc/modules/audio_device/android/audio_manager.h" | |
21 #include "webrtc/modules/audio_device/android/opensles_common.h" | |
22 #include "webrtc/modules/audio_device/include/audio_device_defines.h" | |
23 #include "webrtc/modules/audio_device/audio_device_generic.h" | |
24 #include "webrtc/modules/utility/include/helpers_android.h" | |
25 | |
26 namespace webrtc { | |
27 | |
28 class FineAudioBuffer; | |
29 | |
30 // Implements 16-bit mono PCM audio input support for Android using the | |
31 // C based OpenSL ES API. No calls from C/C++ to Java using JNI is done. | |
32 // | |
33 // An instance must be created and destroyed on one and the same thread. | |
34 // All public methods must also be called on the same thread. A thread checker | |
35 // will RTC_DCHECK if any method is called on an invalid thread. Recorded audio | |
36 // buffers are provided on a dedicated internal thread managed by the OpenSL | |
37 // ES layer. | |
38 // | |
39 // The existing design forces the user to call InitRecording() after | |
40 // StopRecording() to be able to call StartRecording() again. This is inline | |
41 // with how the Java-based implementation works. | |
42 // | |
43 // As of API level 21, lower latency audio input is supported on select devices. | |
44 // To take advantage of this feature, first confirm that lower latency output is | |
45 // available. The capability for lower latency output is a prerequisite for the | |
46 // lower latency input feature. Then, create an AudioRecorder with the same | |
47 // sample rate and buffer size as would be used for output. OpenSL ES interfaces | |
48 // for input effects preclude the lower latency path. | |
49 // See https://developer.android.com/ndk/guides/audio/opensl-prog-notes.html | |
50 // for more details. | |
51 class OpenSLESRecorder { | |
52 public: | |
53 // Beginning with API level 17 (Android 4.2), a buffer count of 2 or more is | |
54 // required for lower latency. Beginning with API level 18 (Android 4.3), a | |
55 // buffer count of 1 is sufficient for lower latency. In addition, the buffer | |
56 // size and sample rate must be compatible with the device's native input | |
57 // configuration provided via the audio manager at construction. | |
58 // TODO(henrika): perhaps set this value dynamically based on OS version. | |
59 static const int kNumOfOpenSLESBuffers = 2; | |
60 | |
61 explicit OpenSLESRecorder(AudioManager* audio_manager); | |
62 ~OpenSLESRecorder(); | |
63 | |
64 int Init(); | |
65 int Terminate(); | |
66 | |
67 int InitRecording(); | |
68 bool RecordingIsInitialized() const { return initialized_; } | |
69 | |
70 int StartRecording(); | |
71 int StopRecording(); | |
72 bool Recording() const { return recording_; } | |
73 | |
74 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer); | |
75 | |
76 // TODO(henrika): add support using OpenSL ES APIs when available. | |
77 int EnableBuiltInAEC(bool enable); | |
78 int EnableBuiltInAGC(bool enable); | |
79 int EnableBuiltInNS(bool enable); | |
80 | |
81 private: | |
82 // Obtaines the SL Engine Interface from the existing global Engine object. | |
83 // The interface exposes creation methods of all the OpenSL ES object types. | |
84 // This method defines the |engine_| member variable. | |
85 bool ObtainEngineInterface(); | |
86 | |
87 // Creates/destroys the audio recorder and the simple-buffer queue object. | |
88 bool CreateAudioRecorder(); | |
89 void DestroyAudioRecorder(); | |
90 | |
91 // Allocate memory for audio buffers which will be used to capture audio | |
92 // via the SLAndroidSimpleBufferQueueItf interface. | |
93 void AllocateDataBuffers(); | |
94 | |
95 // These callback methods are called when data has been written to the input | |
96 // buffer queue. They are both called from an internal "OpenSL ES thread" | |
97 // which is not attached to the Dalvik VM. | |
98 static void SimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf caller, | |
99 void* context); | |
100 void ReadBufferQueue(); | |
101 | |
102 // Wraps calls to SLAndroidSimpleBufferQueueState::Enqueue() and it can be | |
103 // called both on the main thread (but before recording has started) and from | |
104 // the internal audio thread while input streaming is active. It uses | |
105 // |simple_buffer_queue_| but no lock is needed since the initial calls from | |
106 // the main thread and the native callback thread are mutually exclusive. | |
107 bool EnqueueAudioBuffer(); | |
108 | |
109 // Returns the current recorder state. | |
110 SLuint32 GetRecordState() const; | |
111 | |
112 // Returns the current buffer queue state. | |
113 SLAndroidSimpleBufferQueueState GetBufferQueueState() const; | |
114 | |
115 // Number of buffers currently in the queue. | |
116 SLuint32 GetBufferCount(); | |
117 | |
118 // Prints a log message of the current queue state. Can be used for debugging | |
119 // purposes. | |
120 void LogBufferState() const; | |
121 | |
122 // Ensures that methods are called from the same thread as this object is | |
123 // created on. | |
124 rtc::ThreadChecker thread_checker_; | |
125 | |
126 // Stores thread ID in first call to SimpleBufferQueueCallback() from internal | |
127 // non-application thread which is not attached to the Dalvik JVM. | |
128 // Detached during construction of this object. | |
129 rtc::ThreadChecker thread_checker_opensles_; | |
130 | |
131 // Raw pointer to the audio manager injected at construction. Used to cache | |
132 // audio parameters and to access the global SL engine object needed by the | |
133 // ObtainEngineInterface() method. The audio manager outlives any instance of | |
134 // this class. | |
135 AudioManager* audio_manager_; | |
tommi
2016/09/15 09:34:13
AudioManager* const audio_manager_;
henrika_webrtc
2016/09/16 13:30:48
But of course.
| |
136 | |
137 // Contains audio parameters provided to this class at construction by the | |
138 // AudioManager. | |
139 const AudioParameters audio_parameters_; | |
140 | |
141 // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the | |
142 // AudioDeviceModuleImpl class and called by AudioDeviceModule::Create(). | |
143 AudioDeviceBuffer* audio_device_buffer_; | |
144 | |
145 // PCM-type format definition. | |
146 // TODO(henrika): add support for SLAndroidDataFormat_PCM_EX (android-21) if | |
147 // 32-bit float representation is needed. | |
148 SLDataFormat_PCM pcm_format_; | |
149 | |
150 bool initialized_; | |
151 bool recording_; | |
152 | |
153 // This interface exposes creation methods for all the OpenSL ES object types. | |
154 // It is the OpenSL ES API entry point. | |
155 SLEngineItf engine_; | |
156 | |
157 // The audio recorder media object records audio to the destination specified | |
158 // by the data sink capturing it from the input specified by the data source. | |
159 webrtc::ScopedSLObjectItf recorder_object_; | |
160 | |
161 // This interface is supported on the audio recorder object and it controls | |
162 // the state of the audio recorder. | |
163 SLRecordItf recorder_; | |
164 | |
165 // The Android Simple Buffer Queue interface is supported on the audio | |
166 // recorder. For recording, an app should enqueue empty buffers. When a | |
167 // registered callback sends notification that the system has finished writing | |
168 // data to the buffer, the app can read the buffer. | |
169 SLAndroidSimpleBufferQueueItf simple_buffer_queue_; | |
170 | |
171 // Consumes audio of native buffer size and feeds the WebRTC layer with 10ms | |
172 // chunks of audio. | |
173 std::unique_ptr<FineAudioBuffer> fine_audio_buffer_; | |
174 | |
175 // Queue of audio buffers to be used by the recorder object for capturing | |
176 // audio. They will be used in a Round-robin way and the size of each buffer | |
177 // is given by AudioParameters::GetBytesPerBuffer(), i.e., it corresponds to | |
178 // the native OpenSL ES buffer size. | |
179 std::unique_ptr<std::unique_ptr<SLint8[]>[]> audio_buffers_; | |
180 | |
181 // Keeps track of active audio buffer 'n' in the audio_buffers_[n] queue. | |
182 // Example (kNumOfOpenSLESBuffers = 2): counts 0, 1, 0, 1, ... | |
183 int buffer_index_; | |
184 | |
185 // Last time the OpenSL ES layer delivered recorded audio data. | |
186 uint32_t last_rec_time_; | |
187 }; | |
188 | |
189 } // namespace webrtc | |
190 | |
191 #endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_RECORDER_H_ | |
OLD | NEW |