Ocean
Loading...
Searching...
No Matches
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
15
16#include <jni.h>
17
18#include <SLES/OpenSLES.h>
19#include <SLES/OpenSLES_Android.h>
20
21#include <queue>
22
23namespace Ocean
24{
25
26namespace Media
27{
28
29namespace Android
30{
31
32/**
33 * This class implements a LiveAudio class for Android.
34 * @ingroup mediaandroid
35 */
36class 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 * This class holds one stereo chunk.
57 */
59 {
60 protected:
61
62 /**
63 * Returns the number of elements in a stereo chunk.
64 * @return The size of one stereo chunk, in elements
65 */
66 static constexpr size_t stereoChunkElements();
67
68 /**
69 * Definition of a buffer holding the chunk elements
70 */
71 using Buffer = std::vector<int16_t>;
72
73 public:
74
75 /**
76 * Creates a new chunk object and initializes the internal buffer.
77 */
78 inline StereoChunk();
79
80 /**
81 * Adds new elements to this chunk
82 * @param sampleType The type of the elements to add
83 * @param elements The elements to add, must be valid
84 * @param size The number of elements to add
85 * @return The number of actually added elements, with range [1, size]
86 */
87 size_t addElements(const SampleType sampleType, const int16_t* elements, const size_t size);
88
89 /**
90 * Returns whether this chunk is full and whether it can be forwarded to the player.
91 * @return True, if so
92 */
93 inline bool isFull() const;
94
95 /**
96 * Returns the elements of this chunk
97 * @return The chunk's elements
98 */
99 inline const void* data() const;
100
101 /**
102 * Returns the number of elements the chunk currently holds.
103 * @return The chunk's number of elements, with range [0, stereoChunkElements()]
104 */
105 inline size_t size() const;
106
107 /**
108 * Resets the chunk so that it can be filled again.
109 */
110 inline void reset();
111
112 protected:
113
114 /// The buffer holding the chunk elements.
116
117 /// The number of elements currently stored in the buffer, with range [0, buffer_.size()].
118 size_t position_ = 0;
119 };
120
121 /**
122 * Definition of shared pointer holding a stereo chunk.
123 */
124 using UniqueStereoChunk = std::unique_ptr<StereoChunk>;
125
126 /**
127 * Definition of a vector holding stereo chunks.
128 */
129 using StereoChunks = std::vector<UniqueStereoChunk>;
130
131 /**
132 * Definition of a queue holding stereo chunks.
133 */
134 using StereoChunkQueue = std::queue<UniqueStereoChunk>;
135
136 public:
137
138 /**
139 * Creates a new manager object.
140 */
141 ChunkManager() = default;
142
143 /**
144 * Adds new samples to manager.
145 * @param sampleType The type of the given samples, must be valid
146 * @param data The samples to add, must be valid
147 * @param size The size of the given samples, in bytes, with range [1, infinity)
148 * @param bufferQueueInterface The interface of the OpenSL buffer queue, must be valid
149 */
150 bool addSamples(const SampleType sampleType, const void* data, const size_t size, SLAndroidSimpleBufferQueueItf bufferQueueInterface);
151
152 /**
153 * Returns whether new samples need to be added (because the queue is running out of samples).
154 * @return True, if so
155 */
156 inline bool needNewSamples() const;
157
158 /**
159 * Fills OpenSL's buffer queue with another buffer (if available).
160 * @param bufferQueueInterface The interface of the buffer queue in which the chunk will be queued, must be valid
161 * @return True, if succeeded; False, if there was no pending chunk
162 */
163 bool fillBufferQueue(SLAndroidSimpleBufferQueueItf bufferQueueInterface);
164
165 protected:
166
167 /**
168 * Enqueues a pending buffer into OpenSL's buffer queue.
169 * @param bufferQueueInterface The interface of the buffer queue in which the chunk will be queued, must be valid
170 */
171 void enqueueNextPendingChunk(SLAndroidSimpleBufferQueueItf bufferQueueInterface);
172
173 protected:
174
175 /// The queue with stereo chunks which have been queued in OpenSL (OpenSL is working on these chunks).
177
178 /// Pending stereo chunks which need to be queued in OpenSL (but OpenSL does not have a free buffer left).
180
181 /// Free stereo chunks which can be queued again.
183
184 /// The stereo chunk which is currently filled.
186
187 /// The position within the current (not yet entirely filled) stereo chunk.
188 size_t positionInFillingChunk_ = size_t(0);
189
190 /// The lock for the chunks.
191 mutable Lock lock_;
192 };
193
194 public:
195
196 /**
197 * Clones this movie medium and returns a new independent instance of this medium.
198 * @see Medium::clone()
199 */
200 MediumRef clone() const override;
201
202 /**
203 * Adds a new sample in case this audio object receives the audio data from a buffer/stream.
204 * @see LiveAudio::addSample().
205 */
206 bool addSamples(const SampleType sampleType, const void* data, const size_t size) override;
207
208 /**
209 * Returns whether a new sample needs to be added.
210 * @see LiveAudio::needNewSamples().
211 */
212 bool needNewSamples() const override;
213
214 /**
215 * Starts the medium.
216 * @see Medium::start().
217 */
218 bool start() override;
219
220 /**
221 * Pauses the medium.
222 * @see Medium::pause():
223 */
224 bool pause() override;
225
226 /**
227 * Stops the medium.
228 * @see Medium::stop().
229 */
230 bool stop() override;
231
232 /**
233 * Returns whether the medium is started currently.
234 * @see Medium::isStarted().
235 */
236 bool isStarted() const override;
237
238 /**
239 * Returns the volume of the sound in db.
240 * @see SoundMedium::soundVolume().
241 */
242 float soundVolume() const override;
243
244 /**
245 * Returns whether the sound medium is in a mute state.
246 * @see SoundMedium::soundMute().
247 */
248 bool soundMute() const override;
249
250 /**
251 * Sets the volume of the sound in db.
252 * @see SoundMedium::setSoundVolume().
253 */
254 bool setSoundVolume(const float volume) override;
255
256 /**
257 * Sets or un-sets the sound medium to a mute state.
258 * @see SoundMedium::setSoundMute().
259 */
260 bool setSoundMute(const bool mute) override;
261
262 /**
263 * Returns the start timestamp.
264 * @see FiniteMedium::startTimestamp().
265 */
266 Timestamp startTimestamp() const override;
267
268 /**
269 * Returns the pause timestamp.
270 * @see FiniteMedium::pauseTimestamp().
271 */
272 Timestamp pauseTimestamp() const override;
273
274 /**
275 * Returns the stop timestamp.
276 * @see FiniteMedium::stopTimestamp().
277 */
278 Timestamp stopTimestamp() const override;
279
280 protected:
281
282 /**
283 * Creates a new medium by a given url.
284 * @param slEngineInterface The interface of the SL engine, must be valid
285 * @param url Url of the medium
286 */
287 explicit ALiveAudio(const SLEngineItf& slEngineInterface, const std::string& url);
288
289 /**
290 * Destructs the live video object.
291 */
292 ~ALiveAudio() override;
293
294 /**
295 * Initializes the audio and all corresponding resources.
296 * @param slEngineInterface The interface of the SL engine, must be valid
297 * @return True, if succeeded
298 */
299 bool initialize(const SLEngineItf& slEngineInterface);
300
301 /**
302 * Releases the audio and all corresponding resources.
303 * @return True, if succeeded
304 */
305 bool release();
306
307 /**
308 * Returns the preferred playback stream type for this live audio object.
309 * @return The object's preferred stream type.
310 */
311 SLint32 preferredStreamType() const;
312
313 /**
314 * Event callback function to fill the OpenSL buffer queue.
315 * @param bufferQueue The buffer queue to fill with the next samples, must be valid
316 */
317 void onFillBufferQueueCallback(SLAndroidSimpleBufferQueueItf bufferQueue);
318
319 /**
320 * Static event callback function to fill the OpenSL buffer queue.
321 * @param bufferQueue The buffer queue to fill with the next samples, must be valid
322 * @param context The context of the event (the ALiveAudio object), must be valid
323 */
324 static void onFillBufferQueueCallback(SLAndroidSimpleBufferQueueItf bufferQueue, void* context);
325
326 protected:
327
328 /// Start timestamp.
329 Timestamp startTimestamp_ = Timestamp(false);
330
331 /// Pause timestamp.
332 Timestamp pauseTimestamp_ = Timestamp(false);
333
334 /// Stop timestamp.
335 Timestamp stopTimestamp_ = Timestamp(false);
336
337 /// The SL player object.
338 SLObjectItf slPlayer_ = nullptr;
339
340 /// The SL player interface.
341 SLPlayItf slPlayInterface_ = nullptr;
342
343 /// THe SL buffer queue interface.
344 SLAndroidSimpleBufferQueueItf slBufferQueueInterface_ = nullptr;
345
346 /// The SL output mix object.
347 SLObjectItf slOutputMix_ = nullptr;
348
349 /// The SL volume interface.
350 SLVolumeItf slVolumeInterface_ = nullptr;
351
352 /// The manager for chunks of samples.
354
355 /// The number of chunks which have to be queued manually before (not via the callback function).
356 size_t remainingManuallyEnqueuedChunks_ = numberBuffers_;
357
358 /// True, if the live audio has been stopped.
359 std::atomic<bool> hasBeenStopped_ = true;
360};
361
363{
364 constexpr size_t samplesPerSecondMono = 48000; // 48kHz
365 constexpr size_t samplesPerSecondStereo = samplesPerSecondMono * 2;
366
367 return samplesPerSecondStereo / 50; // 20ms
368}
369
371{
372 buffer_.resize(stereoChunkElements());
373}
374
376{
377 return position_ == stereoChunkElements();
378}
379
381{
382 return buffer_.data();
383}
384
386{
387 return position_;
388}
389
391{
392 position_ = 0;
393}
394
396{
397 const ScopedLock scopedLock(lock_);
398
399 return pendingStereoChunks_.empty();
400}
401
402}
403
404}
405
406}
407
408#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:37
This class holds one stereo chunk.
Definition ALiveAudio.h:59
std::vector< int16_t > Buffer
Definition of a buffer holding the chunk elements.
Definition ALiveAudio.h:71
bool isFull() const
Returns whether this chunk is full and whether it can be forwarded to the player.
Definition ALiveAudio.h:375
StereoChunk()
Creates a new chunk object and initializes the internal buffer.
Definition ALiveAudio.h:370
const void * data() const
Returns the elements of this chunk.
Definition ALiveAudio.h:380
size_t addElements(const SampleType sampleType, const int16_t *elements, const size_t size)
Adds new elements to this chunk.
Buffer buffer_
The buffer holding the chunk elements.
Definition ALiveAudio.h:115
void reset()
Resets the chunk so that it can be filled again.
Definition ALiveAudio.h:390
size_t size() const
Returns the number of elements the chunk currently holds.
Definition ALiveAudio.h:385
static constexpr size_t stereoChunkElements()
Returns the number of elements in a stereo chunk.
Definition ALiveAudio.h:362
This class implements a manager for sample chunks.
Definition ALiveAudio.h:52
Lock lock_
The lock for the chunks.
Definition ALiveAudio.h:191
ChunkManager()=default
Creates a new manager object.
void enqueueNextPendingChunk(SLAndroidSimpleBufferQueueItf bufferQueueInterface)
Enqueues a pending buffer into OpenSL's buffer queue.
StereoChunkQueue openslStereoChunkQueue_
The queue with stereo chunks which have been queued in OpenSL (OpenSL is working on these chunks).
Definition ALiveAudio.h:176
UniqueStereoChunk fillingStereoChunk_
The stereo chunk which is currently filled.
Definition ALiveAudio.h:185
std::vector< UniqueStereoChunk > StereoChunks
Definition of a vector holding stereo chunks.
Definition ALiveAudio.h:129
StereoChunks freeStereoChunks_
Free stereo chunks which can be queued again.
Definition ALiveAudio.h:182
bool addSamples(const SampleType sampleType, const void *data, const size_t size, SLAndroidSimpleBufferQueueItf bufferQueueInterface)
Adds new samples to manager.
std::unique_ptr< StereoChunk > UniqueStereoChunk
Definition of shared pointer holding a stereo chunk.
Definition ALiveAudio.h:124
std::queue< UniqueStereoChunk > StereoChunkQueue
Definition of a queue holding stereo chunks.
Definition ALiveAudio.h:134
StereoChunkQueue pendingStereoChunks_
Pending stereo chunks which need to be queued in OpenSL (but OpenSL does not have a free buffer left)...
Definition ALiveAudio.h:179
bool fillBufferQueue(SLAndroidSimpleBufferQueueItf bufferQueueInterface)
Fills OpenSL's buffer queue with another buffer (if available).
bool needNewSamples() const
Returns whether new samples need to be added (because the queue is running out of samples).
Definition ALiveAudio.h:395
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:353
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.
SLint32 preferredStreamType() const
Returns the preferred playback stream type for this live audio object.
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
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