5 #include <QAndroidJniEnvironment>
11 #define LOC QString("AOSLES: ")
13 #define OPENSLES_BUFFERS 10
17 #define POSITIONUPDATEPERIOD 40
20 #define CHECK_OPENSL_ERROR(msg) \
21 if (result != SL_RESULT_SUCCESS) \
23 VBERROR(QString("Open Error: (%1)").arg(result)); \
28 #define CHECK_OPENSL_START_ERROR(msg) \
29 if (result != SL_RESULT_SUCCESS) \
31 VBERROR(QString("Start Error: (%1)").arg(result)); \
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)
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);
65 return QAndroidJniObject::CallStaticMethodInt(
"android/media/AudioTrack",
"getNativeOutputSampleRate",
"(I)I", 3);
70 int GetNativeOutputFramesPerBuffer(
void)
72 QAndroidJniObject activity = QtAndroid::androidActivity();
74 QAndroidJniObject audioManager = activity.CallObjectMethod(
"getSystemService",
"", );
75 jstring sValue = audioManager.CallMethod<jstring>(
"getProperty", PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
77 return QAndroidJniObject::CallStaticMethodInt(
"android/media/AudioManager",
"getProperty",
"(I)I", 3);
88 VBERROR(
"Error: Failed to load libOpenSLES");
96 VBERROR(
"Error: Failed to load symbol slCreateEngine");
101 #define OPENSL_DLSYM(dest, name) \
103 const SLInterfaceID *sym = (const SLInterfaceID *)dlsym(m_so_handle, "SL_IID_" name); \
104 if (sym == nullptr) \
106 LOG(VB_GENERAL, LOG_ERR, "AOOSLES Error: Failed to load symbol SL_IID_" name); \
133 const SLboolean req1[] = { SL_BOOLEAN_FALSE };
149 SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
150 SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
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;
161 case FORMAT_U8: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8;
break;
162 case FORMAT_S16: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
break;
164 case FORMAT_S24LSB: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_24;
break;
166 format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
167 format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_24;
169 case FORMAT_S32: format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
break;
176 format_pcm.containerSize = format_pcm.bitsPerSample;
177 format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
179 SLDataSource audioSrc = {&loc_bufq, &format_pcm};
182 SLDataLocator_OutputMix loc_outmix = {
183 SL_DATALOCATOR_OUTPUTMIX,
186 SLDataSink audioSnk = {&loc_outmix,
nullptr};
190 static const SLboolean req2[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
194 &audioSnk,
sizeof(ids2) /
sizeof(*ids2),
203 result = SL_RESULT_UNKNOWN_ERROR;
205 if (result != SL_RESULT_SUCCESS) {
208 format_pcm.samplesPerSec = ((SLuint32) 48000 * 1000) ;
210 &audioSnk,
sizeof(ids2) /
sizeof(*ids2),
339 VBGENERAL(QString(
"Native Rate %1").arg(nativeRate));
348 #if 0 // 32-bit floating point (AC3) is not supported on all platforms.
375 VBAUDIO(QString(
"Buffering %1 fragments of %2 bytes each, total: %3 bytes")
405 SLAndroidSimpleBufferQueueState st;
407 if (res != SL_RESULT_SUCCESS) {
408 VBERROR(QString(
"Could not query buffer queue state in %1 (%2)").arg(__func__).arg(res));
411 VBAUDIO(QString(
"Num Queued %1").arg(st.count));
417 VBAUDIO(QString(
"WriteAudio %1").arg(size));
422 if (numBufferesQueued < 0)
448 if (r != SL_RESULT_SUCCESS)
451 VBERROR(QString(
"error %1 when writing %2 bytes %3")
454 .arg((r == SL_RESULT_BUFFER_INSUFFICIENT) ?
" (buffer insufficient)" :
""));
469 if (numBufferesQueued < 0)
481 if (r == SL_RESULT_SUCCESS)
483 if (mb <= SL_MILLIBEL_MIN)
489 volume = lroundf(expf(mb / (3*2000.0F)) * 100);
491 VBAUDIO(QString(
"GetVolume(%1) %2 (%3)")
492 .arg(channel).arg(volume).arg(mb));
496 VBERROR(QString(
"GetVolume(%1) %2 (%3) : %4")
497 .arg(channel).arg(volume).arg(mb).arg(r));
506 VBERROR(
"Android volume only supports stereo!");
511 float vol = volume / 100.f;
516 mb = SL_MILLIBEL_MIN;
521 mb = lroundf(3 * 2000.F * log10f(vol));
522 if (mb < SL_MILLIBEL_MIN)
523 mb = SL_MILLIBEL_MIN;
529 if (r == SL_RESULT_SUCCESS)
531 VBAUDIO(QString(
"SetVolume(%1) %2(%3)")
532 .arg(channel).arg(volume).arg(mb));
536 VBERROR(QString(
"SetVolume(%1) %2(%3) : %4")
537 .arg(channel).arg(volume).arg(mb).arg(r));