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