Ocean
ALiveAudio.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MEDIA_ANDROID_A_LIVE_AUDIO_H
9 #define META_OCEAN_MEDIA_ANDROID_A_LIVE_AUDIO_H
10 
13 
14 #include "ocean/media/LiveAudio.h"
15 
16 #include <jni.h>
17 
18 #include <SLES/OpenSLES.h>
19 #include <SLES/OpenSLES_Android.h>
20 
21 #include <queue>
22 
23 namespace Ocean
24 {
25 
26 namespace Media
27 {
28 
29 namespace Android
30 {
31 
32 /**
33  * This class implements a LiveAudio class for Android.
34  * @ingroup mediaandroid
35  */
36 class OCEAN_MEDIA_A_EXPORT ALiveAudio final :
37  virtual public AMedium,
38  virtual public LiveAudio
39 {
40  friend class ALibrary;
41  friend class ALiveVideoManager;
42 
43  protected:
44 
45  /// The number of OpenSL buffers.
46  static constexpr SLuint32 numberBuffers_ = 2u;
47 
48  /**
49  * This class implements a manager for sample chunks.
50  */
52  {
53  protected:
54 
55  /**
56  * Definition of a chunk holding stereo samples.
57  */
58  using StereoChunk = std::vector<int16_t>;
59 
60  /**
61  * Returns the size of one stereo chunk in elements.
62  * @return The size of one stereo chunk, in elements
63  */
64  static constexpr size_t stereoChunkSize();
65 
66  /**
67  * Definition of shared pointer holding a stereo chunk.
68  */
69  using SharedStereoChunk = std::shared_ptr<StereoChunk>;
70 
71  /**
72  * Definition of a vector holding stereo chunks.
73  */
74  typedef std::vector<SharedStereoChunk> StereoChunks;
75 
76  /**
77  * Definition of a queue holding stereo chunks.
78  */
79  typedef std::queue<SharedStereoChunk> StereoChunkQueue;
80 
81  public:
82 
83  /**
84  * Creates a new manager object.
85  */
86  ChunkManager() = default;
87 
88  /**
89  * Adds new samples to manager.
90  * @param sampleType The type of the given samples, must be valid
91  * @param data The samples to add, must be valid
92  * @param size The size of the given samples, in bytes, with range [1, infinity)
93  * @param bufferQueueInterface The interface of the OpenSL buffer queue, must be valid
94  */
95  bool addSamples(const SampleType sampleType, const void* data, const size_t size, SLAndroidSimpleBufferQueueItf bufferQueueInterface);
96 
97  /**
98  * Returns whether new samples need to be added (because the queue is running out of samples).
99  * @return True, if so
100  */
101  inline bool needNewSamples() const;
102 
103  /**
104  * Enqueues the next pending chunk into OpenSL buffer.
105  * @param bufferQueueInterface The interface of the buffer queue in which the chunk will be queued, must be valid
106  * @return True, if succeeded; False, if there was no pending chunk
107  */
108  bool enqueueNextPendingChunk(SLAndroidSimpleBufferQueueItf bufferQueueInterface);
109 
110  protected:
111 
112  /// The queue with stereo chunks which have been queued in OpenSL (OpenSL is working on these chunks).
114 
115  /// Pending stereo chunks which need to be queued in OpenSL (but OpenSL does not have a free buffer left).
117 
118  /// Free stereo chunks which can be queued again.
120 
121  /// The stereo chunk which is currently filled.
123 
124  /// The position within the current (not yet entirely filled) stereo chunk.
125  size_t positionInFillingChunk_ = size_t(0);
126 
127  /// The lock for the chunks.
128  mutable Lock lock_;
129  };
130 
131  public:
132 
133  /**
134  * Clones this movie medium and returns a new independent instance of this medium.
135  * @see Medium::clone()
136  */
137  MediumRef clone() const override;
138 
139  /**
140  * Adds a new sample in case this audio object receives the audio data from a buffer/stream.
141  * @see LiveAudio::addSample().
142  */
143  bool addSamples(const SampleType sampleType, const void* data, const size_t size) override;
144 
145  /**
146  * Returns whether a new sample needs to be added.
147  * @see LiveAudio::needNewSamples().
148  */
149  bool needNewSamples() const override;
150 
151  /**
152  * Starts the medium.
153  * @see Medium::start().
154  */
155  bool start() override;
156 
157  /**
158  * Pauses the medium.
159  * @see Medium::pause():
160  */
161  bool pause() override;
162 
163  /**
164  * Stops the medium.
165  * @see Medium::stop().
166  */
167  bool stop() override;
168 
169  /**
170  * Returns whether the medium is started currently.
171  * @see Medium::isStarted().
172  */
173  bool isStarted() const override;
174 
175  /**
176  * Returns the volume of the sound in db.
177  * @see SoundMedium::soundVolume().
178  */
179  float soundVolume() const override;
180 
181  /**
182  * Returns whether the sound medium is in a mute state.
183  * @see SoundMedium::soundMute().
184  */
185  bool soundMute() const override;
186 
187  /**
188  * Sets the volume of the sound in db.
189  * @see SoundMedium::setSoundVolume().
190  */
191  bool setSoundVolume(const float volume) override;
192 
193  /**
194  * Sets or un-sets the sound medium to a mute state.
195  * @see SoundMedium::setSoundMute().
196  */
197  bool setSoundMute(const bool mute) override;
198 
199  /**
200  * Returns the start timestamp.
201  * @see FiniteMedium::startTimestamp().
202  */
203  Timestamp startTimestamp() const override;
204 
205  /**
206  * Returns the pause timestamp.
207  * @see FiniteMedium::pauseTimestamp().
208  */
209  Timestamp pauseTimestamp() const override;
210 
211  /**
212  * Returns the stop timestamp.
213  * @see FiniteMedium::stopTimestamp().
214  */
215  Timestamp stopTimestamp() const override;
216 
217  protected:
218 
219  /**
220  * Creates a new medium by a given url.
221  * @param slEngineInterface The interface of the SL engine, must be valid
222  * @param url Url of the medium
223  */
224  explicit ALiveAudio(const SLEngineItf& slEngineInterface, const std::string& url);
225 
226  /**
227  * Destructs the live video object.
228  */
229  ~ALiveAudio() override;
230 
231  /**
232  * Initializes the audio and all corresponding resources.
233  * @param slEngineInterface The interface of the SL engine, must be valid
234  * @return True, if succeeded
235  */
236  bool initialize(const SLEngineItf& slEngineInterface);
237 
238  /**
239  * Releases the audio and all corresponding resources.
240  * @return True, if succeeded
241  */
242  bool release();
243 
244  /**
245  * Event callback function to fill the OpenSL buffer queue.
246  * @param bufferQueue The buffer queue to fill with the next samples, must be valid
247  */
248  void onFillBufferQueueCallback(SLAndroidSimpleBufferQueueItf bufferQueue);
249 
250  /**
251  * Static event callback function to fill the OpenSL buffer queue.
252  * @param bufferQueue The buffer queue to fill with the next samples, must be valid
253  * @param context The context of the event (the ALiveAudio object), must be valid
254  */
255  static void onFillBufferQueueCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void* context);
256 
257  protected:
258 
259  /// Start timestamp.
260  Timestamp startTimestamp_ = Timestamp(false);
261 
262  /// Pause timestamp.
263  Timestamp pauseTimestamp_ = Timestamp(false);
264 
265  /// Stop timestamp.
266  Timestamp stopTimestamp_ = Timestamp(false);
267 
268  /// The SL player object.
269  SLObjectItf slPlayer_ = nullptr;
270 
271  /// The SL player interface.
272  SLPlayItf slPlayInterface_ = nullptr;
273 
274  /// THe SL buffer queue interface.
275  SLAndroidSimpleBufferQueueItf slBufferQueueInterface_ = nullptr;
276 
277  /// The SL output mix object.
278  SLObjectItf slOutputMix_ = nullptr;
279 
280  /// The SL volume interface.
281  SLVolumeItf slVolumeInterface_ = nullptr;
282 
283  /// The manager for chunks of samples.
285 
286  /// The number of chunks which have to be queued manually before (not via the callback function).
287  size_t remainingManuallyEnqueuedChunks_ = numberBuffers_;
288 
289  /// True, if the live audio has been stopped.
290  std::atomic<bool> hasBeenStopped_ = true;
291 };
292 
294 {
295  constexpr size_t samplesPerSecondMono = 48000; // 48kHz
296  constexpr size_t samplesPerSecondStereo = samplesPerSecondMono * 2;
297 
298  return samplesPerSecondStereo / 50; // 20ms
299 }
300 
302 {
303  const ScopedLock scopedLock(lock_);
304 
305  return pendingStereoChunks_.empty();
306 }
307 
308 }
309 
310 }
311 
312 }
313 
314 #endif // META_OCEAN_MEDIA_ANDROID_A_LIVE_AUDIO_H
This class implements a recursive lock object.
Definition: Lock.h:31
This class implements the android library.
Definition: ALibrary.h:36
This class implements a manager for sample chunks.
Definition: ALiveAudio.h:52
static constexpr size_t stereoChunkSize()
Returns the size of one stereo chunk in elements.
Definition: ALiveAudio.h:293
std::vector< int16_t > StereoChunk
Definition of a chunk holding stereo samples.
Definition: ALiveAudio.h:58
Lock lock_
The lock for the chunks.
Definition: ALiveAudio.h:128
ChunkManager()=default
Creates a new manager object.
SharedStereoChunk fillingStereoChunk_
The stereo chunk which is currently filled.
Definition: ALiveAudio.h:122
std::queue< SharedStereoChunk > StereoChunkQueue
Definition of a queue holding stereo chunks.
Definition: ALiveAudio.h:79
StereoChunkQueue openslStereoChunkQueue_
The queue with stereo chunks which have been queued in OpenSL (OpenSL is working on these chunks).
Definition: ALiveAudio.h:113
std::shared_ptr< StereoChunk > SharedStereoChunk
Definition of shared pointer holding a stereo chunk.
Definition: ALiveAudio.h:69
StereoChunks freeStereoChunks_
Free stereo chunks which can be queued again.
Definition: ALiveAudio.h:119
bool addSamples(const SampleType sampleType, const void *data, const size_t size, SLAndroidSimpleBufferQueueItf bufferQueueInterface)
Adds new samples to manager.
bool enqueueNextPendingChunk(SLAndroidSimpleBufferQueueItf bufferQueueInterface)
Enqueues the next pending chunk into OpenSL buffer.
std::vector< SharedStereoChunk > StereoChunks
Definition of a vector holding stereo chunks.
Definition: ALiveAudio.h:74
StereoChunkQueue pendingStereoChunks_
Pending stereo chunks which need to be queued in OpenSL (but OpenSL does not have a free buffer left)...
Definition: ALiveAudio.h:116
bool needNewSamples() const
Returns whether new samples need to be added (because the queue is running out of samples).
Definition: ALiveAudio.h:301
This class implements a LiveAudio class for Android.
Definition: ALiveAudio.h:39
bool release()
Releases the audio and all corresponding resources.
Timestamp pauseTimestamp() const override
Returns the pause timestamp.
bool initialize(const SLEngineItf &slEngineInterface)
Initializes the audio and all corresponding resources.
bool setSoundVolume(const float volume) override
Sets the volume of the sound in db.
static void onFillBufferQueueCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void *context)
Static event callback function to fill the OpenSL buffer queue.
bool isStarted() const override
Returns whether the medium is started currently.
bool stop() override
Stops the medium.
ALiveAudio(const SLEngineItf &slEngineInterface, const std::string &url)
Creates a new medium by a given url.
void onFillBufferQueueCallback(SLAndroidSimpleBufferQueueItf bufferQueue)
Event callback function to fill the OpenSL buffer queue.
Timestamp startTimestamp() const override
Returns the start timestamp.
bool setSoundMute(const bool mute) override
Sets or un-sets the sound medium to a mute state.
ChunkManager chunkManager_
The manager for chunks of samples.
Definition: ALiveAudio.h:284
MediumRef clone() const override
Clones this movie medium and returns a new independent instance of this medium.
float soundVolume() const override
Returns the volume of the sound in db.
bool addSamples(const SampleType sampleType, const void *data, const size_t size) override
Adds a new sample in case this audio object receives the audio data from a buffer/stream.
Timestamp stopTimestamp() const override
Returns the stop timestamp.
bool start() override
Starts the medium.
~ALiveAudio() override
Destructs the live video object.
bool needNewSamples() const override
Returns whether a new sample needs to be added.
bool pause() override
Pauses the medium.
bool soundMute() const override
Returns whether the sound medium is in a mute state.
This class implements the base class for all Medium objects in the Android library.
Definition: AMedium.h:35
This class is the base class for all live audios.
Definition: LiveAudio.h:39
SampleType
Definition of individual sample types.
Definition: LiveAudio.h:46
Lock lock_
Medium lock.
Definition: Medium.h:233
This template class implements a object reference with an internal reference counter.
Definition: base/ObjectRef.h:58
This class implements a scoped lock object for recursive lock objects.
Definition: Lock.h:135
This class implements a timestamp.
Definition: Timestamp.h:36
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15