28#include <SLES/OpenSLES_AndroidConfiguration.h>
52 using namespace std::placeholders;
54 std::lock_guard lock(
mutex_);
67 player_->setBufQueue(&playBufQueue_, &freePlayBufQueue_);
71 }
catch (
const std::exception&
e) {
72 JAMI_ERR(
"Error initializing audio playback: %s",
e.what());
84 ringtone_->setBufQueue(&ringBufQueue_, &freeRingBufQueue_);
87 }
catch (
const std::exception&
e) {
88 JAMI_ERR(
"Error initializing ringtone playback: %s",
e.what());
93 std::lock_guard
lck(recMtx);
97 recorder_->setBufQueues(&freeRecBufQueue_, &recBufQueue_);
101 }
catch (
const std::exception&
e) {
102 JAMI_ERR(
"Error initializing audio capture: %s",
e.what());
115 std::lock_guard lock(
mutex_);
118 JAMI_WARN(
"Stopping OpenSL audio layer for type %u", (
unsigned) stream);
126 freePlayBufQueue_.
clear();
128 freePlayBufQueue_.
push(&bufs_[
i]);
129 playBufQueue_.
clear();
136 freeRingBufQueue_.
clear();
138 freeRingBufQueue_.
push(&bufs_[
i]);
139 ringBufQueue_.
clear();
143 freeRecBufQueue_.
clear();
145 freeRecBufQueue_.
push(&bufs_[
i]);
146 recBufQueue_.
clear();
155std::vector<sample_buf>
158 std::vector<sample_buf>
bufs;
163 for (
unsigned i = 0;
i < count;
i++)
184 JAMI_LOG(
"OpenSL init: using buffer of {:d} bytes to support {} with {:d} samples per channel",
190 freePlayBufQueue_.
push(&bufs_[
i]);
192 freeRingBufQueue_.
push(&bufs_[
i]);
194 freeRecBufQueue_.
push(&bufs_[
i]);
215 if (engineObject_ !=
nullptr) {
216 (*engineObject_)->Destroy(engineObject_);
217 engineObject_ =
nullptr;
218 engineInterface_ =
nullptr;
221 freeRecBufQueue_.
clear();
222 recBufQueue_.
clear();
223 freePlayBufQueue_.
clear();
224 playBufQueue_.
clear();
225 freeRingBufQueue_.
clear();
226 ringBufQueue_.
clear();
233OpenSLLayer::dbgEngineGetBufCount()
243 JAMI_ERR(
"Buf Disrtibutions: PlayerDev=%zu, PlayQ=%u, FreePlayQ=%u",
244 player_->dbgGetDevBufCount(),
245 playBufQueue_.
size(),
246 freePlayBufQueue_.
size());
247 JAMI_ERR(
"Buf Disrtibutions: RingDev=%zu, RingQ=%u, FreeRingQ=%u",
248 ringtone_->dbgGetDevBufCount(),
249 ringBufQueue_.
size(),
250 freeRingBufQueue_.
size());
253 JAMI_ERR(
"====Lost Bufs among the queue(supposed = %d, found = %u)",
264 while (player_
and freePlayBufQueue_.
front(&
buf)) {
265 if (
auto dat =
getToPlay(hardwareFormat_, hardwareBuffSize_)) {
266 buf->
size_ =
dat->pointer()->nb_samples *
dat->getFormat().getBytesPerFrame();
267 if (
buf->size_ >
buf->cap_) {
268 JAMI_ERR(
"buf->size_(%zu) > buf->cap_(%zu)",
buf->size_,
buf->cap_);
273 dat->pointer()->data[0],
275 dat->pointer()->nb_samples);
279 if (!playBufQueue_.
push(
buf)) {
280 JAMI_WARN(
"playThread player_ PLAY_KICKSTART_BUFFER_COUNT 1");
283 freePlayBufQueue_.
pop();
294 while (ringtone_
and freeRingBufQueue_.
front(&
buf)) {
295 if (
auto dat =
getToRing(hardwareFormat_, hardwareBuffSize_)) {
296 buf->
size_ =
dat->pointer()->nb_samples *
dat->getFormat().getBytesPerFrame();
297 if (
buf->size_ >
buf->cap_) {
298 JAMI_ERR(
"buf->size_(%zu) > buf->cap_(%zu)",
buf->size_,
buf->cap_);
303 dat->pointer()->data[0],
305 dat->pointer()->nb_samples);
309 if (!ringBufQueue_.
push(
buf)) {
310 JAMI_WARN(
"playThread ringtone_ PLAY_KICKSTART_BUFFER_COUNT 1");
313 freeRingBufQueue_.
pop();
333 if (recThread.joinable())
335 recThread = std::thread([&]() {
336 std::unique_lock
lck(recMtx);
341 recCv.wait_for(
lck, std::chrono::seconds(1));
347 if (
buf->size_ > 0) {
349 auto out = std::make_shared<AudioFrame>(hardwareFormat_,
nb_samples);
372 std::lock_guard
lck(recMtx);
378 if (recThread.joinable()) {
386std::vector<std::string>
405 res = (*engineObject_)
406 ->GetInterface(engineObject_,
413 res = (*deviceCapabilities)
422 res = (*deviceCapabilities)
452std::vector<std::string>
480 const char*
nm =
"unknown iid";
487 nm =
"audiodevicecapabilities";
493 nm =
"metadataextraction";
495 nm =
"metadatatraversal";
497 nm =
"dynamicsource";
503 nm =
"prefetchstatus";
521 nm =
"environmentalreverb";
535 nm =
"3dmacroscopic";
539 nm =
"dynamicinterfacemanagement";
549 nm =
"audiodecodercapabilities";
551 nm =
"audioencodercapabilities";
563 nm =
"visualization";
567 nm =
"enginecapabilities";
571 nm =
"androideffect";
573 nm =
"androideffectsend";
575 nm =
"androideffectcapabilities";
577 nm =
"androidconfiguration";
579 nm =
"simplebuferqueue";
bool isCaptureMuted_
True if capture is not to be used.
std::mutex mutex_
Lock for the entire audio layer.
std::atomic< Status > status_
Whether or not the audio layer's playback stream is started.
void playbackChanged(bool started)
void setHasNativeNS(bool hasNS)
void hardwareFormatAvailable(AudioFormat playback, size_t bufSize=0)
Callback to be called by derived classes when the audio output is opened.
std::shared_ptr< AudioFrame > getToRing(AudioFormat format, size_t writableSamples)
void setHasNativeAEC(bool hasEAC)
std::shared_ptr< AudioFrame > getToPlay(AudioFormat format, size_t writableSamples)
void recordChanged(bool started)
std::condition_variable startedCv_
void putRecorded(std::shared_ptr< AudioFrame > &&frame)
void shutdownAudioEngine()
std::vector< std::string > getCaptureDeviceList() const override
Scan the sound card available for capture on the system.
void startStream(AudioDeviceType stream=AudioDeviceType::ALL) override
Start the capture stream and prepare the playback stream.
OpenSLLayer(const AudioPreference &pref)
Constructor.
std::vector< std::string > getPlaybackDeviceList() const override
Scan the sound card available for capture on the system.
~OpenSLLayer()
Destructor.
void stopStream(AudioDeviceType stream=AudioDeviceType::ALL) override
Stop the playback and capture streams.
#define JAMI_LOG(formatstr,...)
void fillWithSilence(AVFrame *frame)
void emitSignal(Args... args)
std::vector< sample_buf > allocateSampleBufs(unsigned count, size_t sizeInByte)
void dumpAvailableEngineInterfaces()
#define MAX_NUMBER_INPUT_DEVICES