• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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/include/helpers_android.h"
26 
27 namespace webrtc {
28 
29 class 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 RTC_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.
49 class 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 = 4;
56 
57   // There is no need for this class to use JNI.
SetAndroidAudioDeviceObjects(void * javaVM,void * context)58   static int32_t SetAndroidAudioDeviceObjects(void* javaVM, void* context) {
59     return 0;
60   }
ClearAndroidAudioDeviceObjects()61   static void ClearAndroidAudioDeviceObjects() {}
62 
63   explicit OpenSLESPlayer(AudioManager* audio_manager);
64   ~OpenSLESPlayer();
65 
66   int Init();
67   int Terminate();
68 
69   int InitPlayout();
PlayoutIsInitialized()70   bool PlayoutIsInitialized() const { return initialized_; }
71 
72   int StartPlayout();
73   int StopPlayout();
Playing()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(size_t channels,
98                                           int sample_rate,
99                                           size_t bits_per_sample);
100 
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.
148   size_t bytes_per_buffer_;
149 
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   // Last time the OpenSL ES layer asked for audio data to play out.
200   uint32_t last_play_time_;
201 };
202 
203 }  // namespace webrtc
204 
205 #endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_PLAYER_H_
206