MythTV  master
audiooutputopensles.cpp
Go to the documentation of this file.
1 #include <iostream>
2 
3 #include <dlfcn.h>
4 
5 #include <QtGlobal>
6 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
7 #include <QAndroidJniEnvironment>
8 #else
9 #include <QJniEnvironment>
10 #include <QJniObject>
11 #define QAndroidJniEnvironment QJniEnvironment
12 #define QAndroidJniObject QJniObject
13 #endif
14 
16 #include "audiooutputopensles.h"
17 
18 
19 #define LOC QString("AOSLES: ")
20 
21 #define OPENSLES_BUFFERS 10 /* maximum number of buffers */
22 static constexpr std::chrono::milliseconds OPENSLES_BUFLEN { 10ms };
23 //#define POSITIONUPDATEPERIOD 1000
24 //#define POSITIONUPDATEPERIOD 25000
25 #define POSITIONUPDATEPERIOD 40
26 //#define POSITIONUPDATEPERIOD 200000
27 
28 #define CHECK_OPENSL_ERROR(msg) \
29  if (result != SL_RESULT_SUCCESS) \
30  { \
31  VBERROR(QString("Open Error: (%1)").arg(result)); \
32  Close(); \
33  return false; \
34  }
35 
36 #define CHECK_OPENSL_START_ERROR(msg) \
37  if (result != SL_RESULT_SUCCESS) \
38  { \
39  VBERROR(QString("Start Error: (%1)").arg(result)); \
40  Stop(); \
41  return false; \
42  }
43 
44 
45 #define Destroy(a) (*(a))->Destroy(a);
46 #define SetPlayState(a, b) (*(a))->SetPlayState(a, b)
47 #define RegisterCallback(a, b, c) (*(a))->RegisterCallback(a, b, c)
48 #define GetInterface(a, b, c) (*(a))->GetInterface(a, b, c)
49 #define Realize(a, b) (*(a))->Realize(a, b)
50 #define CreateOutputMix(a, b, c, d, e) (*(a))->CreateOutputMix(a, b, c, d, e)
51 #define CreateAudioPlayer(a, b, c, d, e, f, g) \
52  (*(a))->CreateAudioPlayer(a, b, c, d, e, f, g)
53 #define Enqueue(a, b, c) (*(a))->Enqueue(a, b, c)
54 #define Clear(a) (*(a))->Clear(a)
55 #define GetState(a, b) (*(a))->GetState(a, b)
56 #define SetPositionUpdatePeriod(a, b) (*(a))->SetPositionUpdatePeriod(a, b)
57 #define SetVolumeLevel(a, b) (*(a))->SetVolumeLevel(a, b)
58 #define GetVolumeLevel(a, b) (*(a))->GetVolumeLevel(a, b)
59 #define SetMute(a, b) (*(a))->SetMute(a, b)
60 
62 
64 {
65 #if 1
67  jclass cls = jniEnv->FindClass("android/media/AudioTrack");
68  jmethodID method = jniEnv->GetStaticMethodID (cls, "getNativeOutputSampleRate", "(I)I");
69  int sample_rate = jniEnv->CallStaticIntMethod (cls, method, 3); // AudioManager.STREAM_MUSIC
70  return sample_rate;
71 #else
72  //AudioManager.getProperty(PROPERTY_OUTPUT_SAMPLE_RATE)
73  return QAndroidJniObject::callStaticMethodInt("android/media/AudioTrack", "getNativeOutputSampleRate", "(I)I", 3);
74 #endif
75 }
76 
77 #if 0
78 int GetNativeOutputFramesPerBuffer(void)
79 {
80 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
81  QAndroidJniObject activity = QtAndroid::androidActivity();
82 #else
83  QJniObject activity = QNativeInterface::QAndroidApplication::context();
84 #endif
85  //Context.getSystemService(Context.AUDIO_SERVICE)
86  QAndroidJniObject audioManager = activity.callObjectMethod("getSystemService", "", );
87  jstring sValue = audioManager.callMethod<jstring>("getProperty", PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
88  // getNativeOutputFramesPerBuffer
89  return QAndroidJniObject::callStaticMethodInt("android/media/AudioManager", "getProperty", "(I)I", 3);
90 }
91 #endif
92 
94 {
95  SLresult result;
96 
97  m_so_handle = dlopen("libOpenSLES.so", RTLD_NOW);
98  if (m_so_handle == nullptr)
99  {
100  VBERROR("Error: Failed to load libOpenSLES");
101  Close();
102  return false;
103  }
104 
106  if (m_slCreateEnginePtr == nullptr)
107  {
108  VBERROR("Error: Failed to load symbol slCreateEngine");
109  Close();
110  return false;
111  }
112 
113 #define OPENSL_DLSYM(dest, name) \
114  do { \
115  const SLInterfaceID *sym = (const SLInterfaceID *)dlsym(m_so_handle, "SL_IID_" name); \
116  if (sym == nullptr) \
117  { \
118  LOG(VB_GENERAL, LOG_ERR, "AOOSLES Error: Failed to load symbol SL_IID_" name); \
119  Close(); \
120  return false; \
121  } \
122  (dest) = *sym; \
123  } while(0)
124 
125  OPENSL_DLSYM(m_SL_IID_ANDROIDSIMPLEBUFFERQUEUE, "ANDROIDSIMPLEBUFFERQUEUE");
126  OPENSL_DLSYM(m_SL_IID_ENGINE, "ENGINE");
127  OPENSL_DLSYM(m_SL_IID_PLAY, "PLAY");
128  OPENSL_DLSYM(m_SL_IID_VOLUME, "VOLUME");
129 #undef OPENSL_DLSYM
130 
131  // create engine
132  result = m_slCreateEnginePtr(&m_engineObject, 0, nullptr, 0, nullptr, nullptr);
133  CHECK_OPENSL_ERROR("Failed to create engine");
134 
135  // realize the engine in synchronous mode
136  result = Realize(m_engineObject, SL_BOOLEAN_FALSE);
137  CHECK_OPENSL_ERROR("Failed to realize engine");
138 
139  // get the engine interface, needed to create other objects
141  CHECK_OPENSL_ERROR("Failed to get the engine interface");
142 
143  // create output mix, with environmental reverb specified as a non-required interface
144  const SLInterfaceID ids1[] = { m_SL_IID_VOLUME };
145  const SLboolean req1[] = { SL_BOOLEAN_FALSE };
146  result = CreateOutputMix(m_engineEngine, &m_outputMixObject, 1, ids1, req1);
147  CHECK_OPENSL_ERROR("Failed to create output mix");
148 
149  // realize the output mix in synchronous mode
150  result = Realize(m_outputMixObject, SL_BOOLEAN_FALSE);
151  CHECK_OPENSL_ERROR("Failed to realize output mix");
152 
153  return true;
154 }
155 
157 {
158  SLresult result;
159 
160  // configure audio source - this defines the number of samples you can enqueue.
161  SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
162  SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
164  };
165 
166  SLDataFormat_PCM format_pcm;
167  format_pcm.formatType = SL_DATAFORMAT_PCM;
168  format_pcm.numChannels = 2;
169  format_pcm.samplesPerSec = ((SLuint32) m_sampleRate * 1000) ;
170  format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
171  switch (m_outputFormat)
172  {
173  case FORMAT_U8: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8; break;
174  case FORMAT_S16: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; break;
175 #if 0
176  case FORMAT_S24LSB: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_24; break;
177  case FORMAT_S24:
178  format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
179  format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_24;
180  break;
181  case FORMAT_S32: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32; break;
182  // case FORMAT_FLT: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32; break;
183 #endif
184  default:
185  Error(QObject::tr("Unknown sample format: %1").arg(m_outputFormat));
186  return false;
187  }
188  format_pcm.containerSize = format_pcm.bitsPerSample;
189  format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
190 
191  SLDataSource audioSrc = {&loc_bufq, &format_pcm};
192 
193  // configure audio sink
194  SLDataLocator_OutputMix loc_outmix = {
195  SL_DATALOCATOR_OUTPUTMIX,
197  };
198  SLDataSink audioSnk = {&loc_outmix, nullptr};
199 
200  //create audio player
201  const SLInterfaceID ids2[] = { m_SL_IID_ANDROIDSIMPLEBUFFERQUEUE, m_SL_IID_VOLUME };
202  static const SLboolean req2[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
203 
204  if (GetNativeOutputSampleRate() >= m_sampleRate) { // FIXME
205  result = CreateAudioPlayer(m_engineEngine, &m_playerObject, &audioSrc,
206  &audioSnk, sizeof(ids2) / sizeof(*ids2),
207  ids2, req2);
208  } else {
209  // Don't try to play back a sample rate higher than the native one,
210  // since OpenSL ES will try to use the fast path, which AudioFlinger
211  // will reject (fast path can't do resampling), and will end up with
212  // too small buffers for the resampling. See http://b.android.com/59453
213  // for details. This bug is still present in 4.4. If it is fixed later
214  // this workaround could be made conditional.
215  result = SL_RESULT_UNKNOWN_ERROR;
216  }
217  if (result != SL_RESULT_SUCCESS) {
218  /* Try again with a more sensible samplerate */
219  //fmt->i_rate = 44100;
220  format_pcm.samplesPerSec = ((SLuint32) 48000 * 1000) ;
221  result = CreateAudioPlayer(m_engineEngine, &m_playerObject, &audioSrc,
222  &audioSnk, sizeof(ids2) / sizeof(*ids2),
223  ids2, req2);
224  }
225  CHECK_OPENSL_ERROR("Failed to create audio player");
226 
227  result = Realize(m_playerObject, SL_BOOLEAN_FALSE);
228  CHECK_OPENSL_ERROR("Failed to realize player object.");
229 
231  CHECK_OPENSL_ERROR("Failed to get player interface.");
232 
234  CHECK_OPENSL_ERROR("failed to get volume interface.");
235 
238  CHECK_OPENSL_ERROR("Failed to get buff queue interface");
239 
242  (void*)this);
243  CHECK_OPENSL_ERROR("Failed to register buff queue callback.");
244 
245  // set the player's state to playing
246  result = SetPlayState(m_playerPlay, SL_PLAYSTATE_PLAYING);
247  CHECK_OPENSL_ERROR("Failed to switch to playing state");
248 
249  /* XXX: rounding shouldn't affect us at normal sampling rate */
250  uint32_t samplesPerBuf = OPENSLES_BUFLEN.count() * m_sampleRate / 1000;
251  m_buf = (uint8_t*)malloc(OPENSLES_BUFFERS * samplesPerBuf * m_bytesPerFrame);
252  if (!m_buf)
253  {
254  Stop();
255  return false;
256  }
257 
258  m_started = false;
259  m_bufWriteIndex = 0;
260  m_bufWriteBase = 0;
261 
262 
263  // we want 16bit signed data native endian.
264  //fmt->i_format = VLC_CODEC_S16N;
265  //fmt->i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
266 
267 /* Buffers which arrive after pts - AOUT_MIN_PREPARE_TIME will be trashed
268  to avoid too heavy resampling */
269  //SetPositionUpdatePeriod(m_playerPlay, 25000);
270  //SetPositionUpdatePeriod(m_playerPlay, 40);
272 
273  return true;
274 }
275 
277 {
278  SLresult result;
279  if (m_playerObject)
280  {
281  // set the player's state to playing
282  result = SetPlayState(m_playerPlay, SL_PLAYSTATE_STOPPED);
283  CHECK_OPENSL_ERROR("Failed to switch to not playing state");
285  m_playerObject = nullptr;
286  }
287  if (m_buf)
288  {
289  free(m_buf);
290  m_buf = nullptr;
291  }
292  return true;
293 }
294 
296 {
297  bool result = CreateEngine();
298  if (result)
299  {
300  result = StartPlayer();
301  }
302  if (!result)
303  {
304  Close();
305  }
306  return result;
307 }
308 
310 {
311  Stop();
312  if (m_outputMixObject)
313  {
315  m_outputMixObject = nullptr;
316  }
317  if (m_engineObject)
318  {
320  m_engineObject = nullptr;
321  }
322  if (m_so_handle)
323  {
325  m_so_handle = nullptr;
326  }
327 }
328 
329 
330 
332  AudioOutputBase(settings),
333  m_nativeOutputSampleRate(GetNativeOutputSampleRate())
334 {
335  InitSettings(settings);
336  if (settings.m_init)
337  Reconfigure(settings);
338 }
339 
341 {
342  KillAudio();
344 }
345 
347 {
348  AudioOutputSettings *settings = new AudioOutputSettings();
349 
350  int32_t nativeRate = GetNativeOutputSampleRate(); // in Hz
351  VBGENERAL(QString("Native Rate %1").arg(nativeRate));
352  //settings->AddSupportedRate(48000);
353  settings->AddSupportedRate(nativeRate);
354 
355  // Support all standard formats
356  settings->AddSupportedFormat(FORMAT_U8);
357  settings->AddSupportedFormat(FORMAT_S16);
358  // settings->AddSupportedFormat(FORMAT_S24);
359  // settings->AddSupportedFormat(FORMAT_S32);
360 #if 0 // 32-bit floating point (AC3) is not supported on all platforms.
361  settings->AddSupportedFormat(FORMAT_FLT);
362 #endif
363 
364  // Guess that we can do up to 2
365  settings->AddSupportedChannels(2);
366 
367  settings->setPassthrough(0); //No passthrough
368 
369  return settings;
370 }
371 
373 {
374  CloseDevice();
375 
376  if (!Open())
377  {
378  CloseDevice();
379  return false;
380  }
381 
382  // fragments are 10ms worth of samples
384  // OpenSLES buffer holds 10 fragments = 80ms worth of samples
386 
387  VBAUDIO(QString("Buffering %1 fragments of %2 bytes each, total: %3 bytes")
389 
390  return true;
391 }
392 
394 {
395  Stop();
396  Close();
397 }
398 
399 void AudioOutputOpenSLES::SPlayedCallback(SLAndroidSimpleBufferQueueItf caller, void *pContext)
400 {
401  ((AudioOutputOpenSLES*)pContext)->PlayedCallback(caller);
402 }
403 
404 void AudioOutputOpenSLES::PlayedCallback(SLAndroidSimpleBufferQueueItf caller)
405 {
406  assert (caller == m_playerBufferQueue);
407 
408  VBAUDIO(QString("Freed"));
409 
410  m_lock.lock();
411  m_started = true;
412  m_lock.unlock();
413 }
414 
416 {
417  SLAndroidSimpleBufferQueueState st;
418  SLresult res = GetState(m_playerBufferQueue, &st);
419  if (res != SL_RESULT_SUCCESS) {
420  VBERROR(QString("Could not query buffer queue state in %1 (%2)").arg(__func__).arg(res));
421  return -1;
422  }
423  VBAUDIO(QString("Num Queued %1").arg(st.count));
424  return st.count;
425 }
426 
427 void AudioOutputOpenSLES::WriteAudio(unsigned char * buffer, int size)
428 {
429  VBAUDIO(QString("WriteAudio %1").arg(size));
430  while (size > 0)
431  {
432  // check if there are any buffers available
433  int32_t numBufferesQueued = GetNumberOfBuffersQueued();
434  if (numBufferesQueued < 0)
435  return;
436 
437  if (numBufferesQueued == OPENSLES_BUFFERS)
438  {
439  // wait for a buffer period, should be clear next time around
441  continue;
442  }
443 
444  if (size < (m_fragmentSize + m_bufWriteIndex))
445  {
446  memcpy(&m_buf[m_bufWriteBase + m_bufWriteIndex], buffer, size);
447  size = 0;
448  // no more to do so exit now, dont have a full buffer
449  break;
450  }
451  else
452  {
455  }
456 
458  VBAUDIO(QString("Enqueue %1").arg(m_bufWriteBase));
459 
460  if (r != SL_RESULT_SUCCESS)
461  {
462  // should never happen so show a log
463  VBERROR(QString("error %1 when writing %2 bytes %3")
464  .arg(r)
465  .arg(m_fragmentSize)
466  .arg((r == SL_RESULT_BUFFER_INSUFFICIENT) ? " (buffer insufficient)" : ""));
467  // toss the remaining data, we got bigger problems
468  return;
469  }
470  // update pointers for next time only if the data was queued correctly
473  m_bufWriteBase = 0;
474  m_bufWriteIndex = 0;
475  }
476 }
477 
479 {
480  int numBufferesQueued = GetNumberOfBuffersQueued();
481  if (numBufferesQueued < 0)
482  {
483  return 0;
484  }
485  return numBufferesQueued * m_fragmentSize + m_bufWriteIndex;
486 }
487 
489 {
490  SLmillibel mb = 0;
491  int volume = 0;
492  SLresult r = GetVolumeLevel(m_volumeItf, &mb);
493  if (r == SL_RESULT_SUCCESS)
494  {
495  if (mb <= SL_MILLIBEL_MIN)
496  {
497  volume = 0;
498  }
499  else
500  {
501  volume = lroundf(expf(mb / (3*2000.0F)) * 100);
502  }
503  VBAUDIO(QString("GetVolume(%1) %2 (%3)")
504  .arg(channel).arg(volume).arg(mb));
505  }
506  else
507  {
508  VBERROR(QString("GetVolume(%1) %2 (%3) : %4")
509  .arg(channel).arg(volume).arg(mb).arg(r));
510  }
511 
512  return volume;
513 }
514 
515 void AudioOutputOpenSLES::SetVolumeChannel(int channel, int volume)
516 {
517  if (channel > 1)
518  VBERROR("Android volume only supports stereo!");
519 
520  // Volume is 0-100
521  // android expects 0-1.0 before conversion
522  // Convert UI volume to linear factor (cube) in log
523  float vol = volume / 100.f;
524 
525  int mb;
526  if (volume == 0)
527  {
528  mb = SL_MILLIBEL_MIN;
529  }
530  else
531  {
532  // millibels from linear amplification
533  mb = lroundf(3 * 2000.F * log10f(vol));
534  if (mb < SL_MILLIBEL_MIN)
535  mb = SL_MILLIBEL_MIN;
536  else if (mb > 0)
537  mb = 0; // maximum supported level could be higher: GetMaxVolumeLevel */
538  }
539 
540  SLresult r = SetVolumeLevel(m_volumeItf, mb);
541  if (r == SL_RESULT_SUCCESS)
542  {
543  VBAUDIO(QString("SetVolume(%1) %2(%3)")
544  .arg(channel).arg(volume).arg(mb));
545  }
546  else
547  {
548  VBERROR(QString("SetVolume(%1) %2(%3) : %4")
549  .arg(channel).arg(volume).arg(mb).arg(r));
550  }
551 
552 }
FORMAT_U8
@ FORMAT_U8
Definition: audiooutputsettings.h:26
GetNativeOutputSampleRate
int GetNativeOutputSampleRate(void)
Definition: audiooutputopensles.cpp:63
Destroy
#define Destroy(a)
Definition: audiooutputopensles.cpp:45
AudioOutputOpenSLES::m_engineObject
SLObjectItf m_engineObject
Definition: audiooutputopensles.h:50
AudioOutputOpenSLES::m_SL_IID_ANDROIDSIMPLEBUFFERQUEUE
SLInterfaceID m_SL_IID_ANDROIDSIMPLEBUFFERQUEUE
Definition: audiooutputopensles.h:63
AudioOutputSettings::setPassthrough
void setPassthrough(int val)
Definition: audiooutputsettings.h:76
VBAUDIO
#define VBAUDIO(str)
Definition: audiooutputbase.h:20
AudioOutputOpenSLES::GetOutputSettings
AudioOutputSettings * GetOutputSettings(bool digital) override
Definition: audiooutputopensles.cpp:346
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:27
AudioOutputOpenSLES::m_slCreateEnginePtr
slCreateEngine_t m_slCreateEnginePtr
Definition: audiooutputopensles.h:61
AudioOutputSettings::AddSupportedFormat
void AddSupportedFormat(AudioFormat format)
Definition: audiooutputsettings.cpp:127
AudioOutputOpenSLES::GetNumberOfBuffersQueued
int GetNumberOfBuffersQueued() const
Definition: audiooutputopensles.cpp:415
AudioOutputOpenSLES::GetVolumeChannel
int GetVolumeChannel(int channel) const override
Definition: audiooutputopensles.cpp:488
AudioOutput::Error
void Error(const QString &msg)
Definition: audiooutput.cpp:272
OPENSLES_BUFFERS
#define OPENSLES_BUFFERS
Definition: audiooutputopensles.cpp:21
AudioOutputOpenSLES::m_outputMixObject
SLObjectItf m_outputMixObject
Definition: audiooutputopensles.h:51
AudioOutputOpenSLES::m_bufWriteIndex
int m_bufWriteIndex
Definition: audiooutputopensles.h:70
AudioOutputBase::KillAudio
void KillAudio(void)
Kill the output thread and cleanup.
Definition: audiooutputbase.cpp:867
MThread::usleep
static void usleep(std::chrono::microseconds time)
Definition: mthread.cpp:335
AudioOutputOpenSLES::GetBufferedOnSoundcard
int GetBufferedOnSoundcard(void) const override
Return the size in bytes of frames currently in the audio buffer adjusted with the audio playback lat...
Definition: audiooutputopensles.cpp:478
VBERROR
#define VBERROR(str)
Definition: audiooutputbase.h:23
slCreateEngine_t
SLresult(*)(SLObjectItf *, SLuint32, const SLEngineOption *, SLuint32, const SLInterfaceID *, const SLboolean *) slCreateEngine_t
Definition: audiooutputopensles.h:15
AudioOutputOpenSLES::OpenDevice
bool OpenDevice(void) override
Definition: audiooutputopensles.cpp:372
AudioOutputBase::m_sampleRate
int m_sampleRate
Definition: audiooutputbase.h:180
OPENSL_DLSYM
#define OPENSL_DLSYM(dest, name)
QAndroidJniObject
#define QAndroidJniObject
Definition: audiooutputopensles.cpp:12
CHECK_OPENSL_ERROR
#define CHECK_OPENSL_ERROR(msg)
Definition: audiooutputopensles.cpp:28
AudioOutputOpenSLES::m_SL_IID_PLAY
SLInterfaceID m_SL_IID_PLAY
Definition: audiooutputopensles.h:65
SetPlayState
#define SetPlayState(a, b)
Definition: audiooutputopensles.cpp:46
AudioOutputOpenSLES::SPlayedCallback
static void SPlayedCallback(SLAndroidSimpleBufferQueueItf caller, void *pContext)
Definition: audiooutputopensles.cpp:399
AudioOutputSettings::AddSupportedChannels
void AddSupportedChannels(int channels)
Definition: audiooutputsettings.cpp:237
AudioSettings
Definition: audiosettings.h:28
AudioOutputOpenSLES::m_volumeItf
SLVolumeItf m_volumeItf
Definition: audiooutputopensles.h:54
audiooutputopensles.h
RegisterCallback
#define RegisterCallback(a, b, c)
Definition: audiooutputopensles.cpp:47
AudioOutputOpenSLES::AudioOutputOpenSLES
AudioOutputOpenSLES(const AudioSettings &settings)
Definition: audiooutputopensles.cpp:331
AudioOutputBase::m_soundcardBufferSize
long m_soundcardBufferSize
Definition: audiooutputbase.h:183
CreateOutputMix
#define CreateOutputMix(a, b, c, d, e)
Definition: audiooutputopensles.cpp:50
AudioOutputBase
Definition: audiooutputbase.h:51
AudioOutputOpenSLES::PlayedCallback
void PlayedCallback(SLAndroidSimpleBufferQueueItf caller)
Definition: audiooutputopensles.cpp:404
AudioSettings::m_init
bool m_init
If set to false, AudioOutput instance will not try to initially open the audio device.
Definition: audiosettings.h:85
mythlogging.h
AudioOutputOpenSLES::m_SL_IID_VOLUME
SLInterfaceID m_SL_IID_VOLUME
Definition: audiooutputopensles.h:64
FORMAT_S24
@ FORMAT_S24
Definition: audiooutputsettings.h:29
AudioOutputOpenSLES::Stop
bool Stop()
Definition: audiooutputopensles.cpp:276
AudioOutputOpenSLES
Definition: audiooutputopensles.h:17
FORMAT_FLT
@ FORMAT_FLT
Definition: audiooutputsettings.h:31
VBGENERAL
#define VBGENERAL(str)
Definition: audiooutputbase.h:22
AudioOutputBase::Reconfigure
void Reconfigure(const AudioSettings &settings) override
(Re)Configure AudioOutputBase
Definition: audiooutputbase.cpp:469
AudioOutputSettings::AddSupportedRate
void AddSupportedRate(int rate)
Definition: audiooutputsettings.cpp:78
dlclose
#define dlclose(x)
Definition: compat.h:155
FORMAT_S32
@ FORMAT_S32
Definition: audiooutputsettings.h:30
AudioOutputOpenSLES::m_started
bool m_started
Definition: audiooutputopensles.h:73
GetState
#define GetState(a, b)
Definition: audiooutputopensles.cpp:55
GetVolumeLevel
#define GetVolumeLevel(a, b)
Definition: audiooutputopensles.cpp:58
AudioOutputOpenSLES::CreateEngine
bool CreateEngine()
Definition: audiooutputopensles.cpp:93
Enqueue
#define Enqueue(a, b, c)
Definition: audiooutputopensles.cpp:53
QAndroidJniEnvironment
#define QAndroidJniEnvironment
Definition: audiooutputopensles.cpp:11
CreateAudioPlayer
#define CreateAudioPlayer(a, b, c, d, e, f, g)
Definition: audiooutputopensles.cpp:51
AudioOutputBase::m_outputFormat
AudioFormat m_outputFormat
Definition: audiooutputbase.h:179
AudioOutputOpenSLES::~AudioOutputOpenSLES
virtual ~AudioOutputOpenSLES()
Definition: audiooutputopensles.cpp:340
SetVolumeLevel
#define SetVolumeLevel(a, b)
Definition: audiooutputopensles.cpp:57
GetInterface
#define GetInterface(a, b, c)
Definition: audiooutputopensles.cpp:48
AudioOutputOpenSLES::CloseDevice
void CloseDevice(void) override
Definition: audiooutputopensles.cpp:393
dlsym
#define dlsym(x, y)
Definition: compat.h:156
assert
#define assert(x)
Definition: audiooutputalsa.cpp:16
AudioOutputBase::m_outputBytesPerFrame
int m_outputBytesPerFrame
Definition: audiooutputbase.h:177
AudioOutputOpenSLES::m_lock
QMutex m_lock
Definition: audiooutputopensles.h:76
AudioOutputOpenSLES::m_bufWriteBase
int m_bufWriteBase
Definition: audiooutputopensles.h:69
dlopen
#define dlopen(x, y)
Definition: compat.h:154
AudioOutputSettings
Definition: audiooutputsettings.h:48
Realize
#define Realize(a, b)
Definition: audiooutputopensles.cpp:49
AudioOutputOpenSLES::m_SL_IID_ENGINE
SLInterfaceID m_SL_IID_ENGINE
Definition: audiooutputopensles.h:62
AudioOutputBase::m_bytesPerFrame
int m_bytesPerFrame
Definition: audiooutputbase.h:176
AudioOutputBase::InitSettings
void InitSettings(const AudioSettings &settings)
Definition: audiooutputbase.cpp:120
AudioOutputOpenSLES::Close
void Close()
Definition: audiooutputopensles.cpp:309
AudioOutputOpenSLES::StartPlayer
bool StartPlayer()
Definition: audiooutputopensles.cpp:156
AudioOutputOpenSLES::m_engineEngine
SLEngineItf m_engineEngine
Definition: audiooutputopensles.h:55
AudioOutputBase::m_fragmentSize
int m_fragmentSize
Definition: audiooutputbase.h:182
AudioOutputOpenSLES::m_playerPlay
SLPlayItf m_playerPlay
Definition: audiooutputopensles.h:56
AudioOutputOpenSLES::Open
bool Open()
Definition: audiooutputopensles.cpp:295
SetPositionUpdatePeriod
#define SetPositionUpdatePeriod(a, b)
Definition: audiooutputopensles.cpp:56
AudioOutputOpenSLES::m_playerObject
SLObjectItf m_playerObject
Definition: audiooutputopensles.h:53
AudioOutputOpenSLES::m_playerBufferQueue
SLAndroidSimpleBufferQueueItf m_playerBufferQueue
Definition: audiooutputopensles.h:52
AudioOutputOpenSLES::WriteAudio
void WriteAudio(unsigned char *aubuf, int size) override
Definition: audiooutputopensles.cpp:427
OPENSLES_BUFLEN
static constexpr std::chrono::milliseconds OPENSLES_BUFLEN
Definition: audiooutputopensles.cpp:22
POSITIONUPDATEPERIOD
#define POSITIONUPDATEPERIOD
Definition: audiooutputopensles.cpp:25
AudioOutputOpenSLES::SetVolumeChannel
void SetVolumeChannel(int channel, int volume) override
Definition: audiooutputopensles.cpp:515
FORMAT_S24LSB
@ FORMAT_S24LSB
Definition: audiooutputsettings.h:28
AudioOutputOpenSLES::m_buf
uint8_t * m_buf
Definition: audiooutputopensles.h:68
AudioOutputOpenSLES::m_so_handle
void * m_so_handle
Definition: audiooutputopensles.h:59