blob: e3978a19909f7594981bf87423be8956c2c5df45 [file] [log] [blame]
henrikab2619892015-05-18 16:49:16 +02001/*
2 * Copyright (c) 2015 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_PLAYER_H_
12#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_
13
kwibergf01633e2016-02-24 05:00:36 -080014#include <memory>
15
henrikab2619892015-05-18 16:49:16 +020016#include <SLES/OpenSLES.h>
17#include <SLES/OpenSLES_Android.h>
18#include <SLES/OpenSLES_AndroidConfiguration.h>
19
henrikab2619892015-05-18 16:49:16 +020020#include "webrtc/base/thread_checker.h"
21#include "webrtc/modules/audio_device/android/audio_common.h"
22#include "webrtc/modules/audio_device/android/audio_manager.h"
23#include "webrtc/modules/audio_device/android/opensles_common.h"
24#include "webrtc/modules/audio_device/include/audio_device_defines.h"
25#include "webrtc/modules/audio_device/audio_device_generic.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010026#include "webrtc/modules/utility/include/helpers_android.h"
henrikab2619892015-05-18 16:49:16 +020027
28namespace webrtc {
29
30class FineAudioBuffer;
31
32// Implements 16-bit mono PCM audio output support for Android using the
33// C based OpenSL ES API. No calls from C/C++ to Java using JNI is done.
34//
35// An instance must be created and destroyed on one and the same thread.
36// All public methods must also be called on the same thread. A thread checker
henrikg91d6ede2015-09-17 00:24:34 -070037// will RTC_DCHECK if any method is called on an invalid thread. Decoded audio
henrikab2619892015-05-18 16:49:16 +020038// buffers are requested on a dedicated internal thread managed by the OpenSL
39// ES layer.
40//
41// The existing design forces the user to call InitPlayout() after Stoplayout()
42// to be able to call StartPlayout() again. This is inline with how the Java-
43// based implementation works.
44//
45// OpenSL ES is a native C API which have no Dalvik-related overhead such as
46// garbage collection pauses and it supports reduced audio output latency.
47// If the device doesn't claim this feature but supports API level 9 (Android
48// platform version 2.3) or later, then we can still use the OpenSL ES APIs but
49// the output latency may be higher.
50class OpenSLESPlayer {
51 public:
52 // The lower output latency path is used only if the application requests a
53 // buffer count of 2 or more, and a buffer size and sample rate that are
54 // compatible with the device's native output configuration provided via the
55 // audio manager at construction.
henrikae71b24e2015-11-12 01:48:32 -080056 static const int kNumOfOpenSLESBuffers = 4;
henrikab2619892015-05-18 16:49:16 +020057
henrikab2619892015-05-18 16:49:16 +020058 explicit OpenSLESPlayer(AudioManager* audio_manager);
59 ~OpenSLESPlayer();
60
61 int Init();
62 int Terminate();
63
64 int InitPlayout();
65 bool PlayoutIsInitialized() const { return initialized_; }
66
67 int StartPlayout();
68 int StopPlayout();
69 bool Playing() const { return playing_; }
70
71 int SpeakerVolumeIsAvailable(bool& available);
72 int SetSpeakerVolume(uint32_t volume);
73 int SpeakerVolume(uint32_t& volume) const;
74 int MaxSpeakerVolume(uint32_t& maxVolume) const;
75 int MinSpeakerVolume(uint32_t& minVolume) const;
76
77 void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
78
79 private:
80 // These callback methods are called when data is required for playout.
81 // They are both called from an internal "OpenSL ES thread" which is not
82 // attached to the Dalvik VM.
83 static void SimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf caller,
84 void* context);
85 void FillBufferQueue();
86 // Reads audio data in PCM format using the AudioDeviceBuffer.
87 // Can be called both on the main thread (during Start()) and from the
88 // internal audio thread while output streaming is active.
89 void EnqueuePlayoutData();
90
91 // Configures the SL_DATAFORMAT_PCM structure.
Peter Kasting69558702016-01-12 16:26:35 -080092 SLDataFormat_PCM CreatePCMConfiguration(size_t channels,
henrikab2619892015-05-18 16:49:16 +020093 int sample_rate,
Peter Kasting1380e262015-08-28 17:31:03 -070094 size_t bits_per_sample);
henrikab2619892015-05-18 16:49:16 +020095
96 // Allocate memory for audio buffers which will be used to render audio
97 // via the SLAndroidSimpleBufferQueueItf interface.
98 void AllocateDataBuffers();
99
henrika521f7a82016-05-31 07:03:17 -0700100 // Obtaines the SL Engine Interface from the existing global Engine object.
101 // The interface exposes creation methods of all the OpenSL ES object types.
102 // This method defines the |engine_| member variable.
103 bool ObtainEngineInterface();
henrikab2619892015-05-18 16:49:16 +0200104
105 // Creates/destroys the output mix object.
106 bool CreateMix();
107 void DestroyMix();
108
109 // Creates/destroys the audio player and the simple-buffer object.
110 // Also creates the volume object.
111 bool CreateAudioPlayer();
112 void DestroyAudioPlayer();
113
114 SLuint32 GetPlayState() const;
115
116 // Ensures that methods are called from the same thread as this object is
117 // created on.
118 rtc::ThreadChecker thread_checker_;
119
120 // Stores thread ID in first call to SimpleBufferQueueCallback() from internal
121 // non-application thread which is not attached to the Dalvik JVM.
122 // Detached during construction of this object.
123 rtc::ThreadChecker thread_checker_opensles_;
124
henrika521f7a82016-05-31 07:03:17 -0700125 // Raw pointer to the audio manager injected at construction. Used to cache
126 // audio parameters and to access the global SL engine object needed by the
127 // ObtainEngineInterface() method. The audio manager outlives any instance of
128 // this class.
129 AudioManager* audio_manager_;
130
henrikab2619892015-05-18 16:49:16 +0200131 // Contains audio parameters provided to this class at construction by the
132 // AudioManager.
133 const AudioParameters audio_parameters_;
134
135 // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the
Peter Boström4adbbcf2016-05-03 15:51:26 -0400136 // AudioDeviceModuleImpl class and called by AudioDeviceModule::Create().
henrikab2619892015-05-18 16:49:16 +0200137 AudioDeviceBuffer* audio_device_buffer_;
138
139 bool initialized_;
140 bool playing_;
141
142 // PCM-type format definition.
143 // TODO(henrika): add support for SLAndroidDataFormat_PCM_EX (android-21) if
144 // 32-bit float representation is needed.
145 SLDataFormat_PCM pcm_format_;
146
147 // Number of bytes per audio buffer in each |audio_buffers_[i]|.
148 // Typical sizes are 480 or 512 bytes corresponding to native output buffer
149 // sizes of 240 or 256 audio frames respectively.
Peter Kasting1380e262015-08-28 17:31:03 -0700150 size_t bytes_per_buffer_;
henrikab2619892015-05-18 16:49:16 +0200151
152 // Queue of audio buffers to be used by the player object for rendering
153 // audio. They will be used in a Round-robin way and the size of each buffer
154 // is given by FineAudioBuffer::RequiredBufferSizeBytes().
kwibergf01633e2016-02-24 05:00:36 -0800155 std::unique_ptr<SLint8[]> audio_buffers_[kNumOfOpenSLESBuffers];
henrikab2619892015-05-18 16:49:16 +0200156
157 // FineAudioBuffer takes an AudioDeviceBuffer which delivers audio data
158 // in chunks of 10ms. It then allows for this data to be pulled in
159 // a finer or coarser granularity. I.e. interacting with this class instead
160 // of directly with the AudioDeviceBuffer one can ask for any number of
161 // audio data samples.
162 // Example: native buffer size is 240 audio frames at 48kHz sample rate.
163 // WebRTC will provide 480 audio frames per 10ms but OpenSL ES asks for 240
164 // in each callback (one every 5ms). This class can then ask for 240 and the
165 // FineAudioBuffer will ask WebRTC for new data only every second callback
166 // and also cach non-utilized audio.
kwibergf01633e2016-02-24 05:00:36 -0800167 std::unique_ptr<FineAudioBuffer> fine_buffer_;
henrikab2619892015-05-18 16:49:16 +0200168
169 // Keeps track of active audio buffer 'n' in the audio_buffers_[n] queue.
170 // Example (kNumOfOpenSLESBuffers = 2): counts 0, 1, 0, 1, ...
171 int buffer_index_;
172
henrikab2619892015-05-18 16:49:16 +0200173 // This interface exposes creation methods for all the OpenSL ES object types.
174 // It is the OpenSL ES API entry point.
175 SLEngineItf engine_;
176
177 // Output mix object to be used by the player object.
178 webrtc::ScopedSLObjectItf output_mix_;
179
180 // The audio player media object plays out audio to the speakers. It also
181 // supports volume control.
182 webrtc::ScopedSLObjectItf player_object_;
183
184 // This interface is supported on the audio player and it controls the state
185 // of the audio player.
186 SLPlayItf player_;
187
188 // The Android Simple Buffer Queue interface is supported on the audio player
189 // and it provides methods to send audio data from the source to the audio
190 // player for rendering.
191 SLAndroidSimpleBufferQueueItf simple_buffer_queue_;
192
193 // This interface exposes controls for manipulating the object’s audio volume
194 // properties. This interface is supported on the Audio Player object.
195 SLVolumeItf volume_;
henrikae71b24e2015-11-12 01:48:32 -0800196
197 // Last time the OpenSL ES layer asked for audio data to play out.
198 uint32_t last_play_time_;
henrikab2619892015-05-18 16:49:16 +0200199};
200
201} // namespace webrtc
202
203#endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_