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