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