30#include <winpr/assert.h> 
   32#include "rdpsnd_main.h" 
   34#define CONV16BIT 32768 
   35#define CONVMYFLT (1. / 32768.) 
   37static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, 
void* context);
 
   44  result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
 
   45  DEBUG_SND(
"engineObject=%p", (
void*)p->engineObject);
 
   47  if (result != SL_RESULT_SUCCESS)
 
   51  result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
 
   52  DEBUG_SND(
"Realize=%" PRIu32 
"", result);
 
   54  if (result != SL_RESULT_SUCCESS)
 
   58  result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
 
   59  DEBUG_SND(
"engineEngine=%p", (
void*)p->engineEngine);
 
   61  if (result != SL_RESULT_SUCCESS)
 
   73  SLuint32 channels = p->outchannels;
 
   74  WINPR_ASSERT(p->engineObject);
 
   75  WINPR_ASSERT(p->engineEngine);
 
   80    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
 
   86        sr = SL_SAMPLINGRATE_8;
 
   90        sr = SL_SAMPLINGRATE_11_025;
 
   94        sr = SL_SAMPLINGRATE_16;
 
   98        sr = SL_SAMPLINGRATE_22_05;
 
  102        sr = SL_SAMPLINGRATE_24;
 
  106        sr = SL_SAMPLINGRATE_32;
 
  110        sr = SL_SAMPLINGRATE_44_1;
 
  114        sr = SL_SAMPLINGRATE_48;
 
  118        sr = SL_SAMPLINGRATE_64;
 
  122        sr = SL_SAMPLINGRATE_88_2;
 
  126        sr = SL_SAMPLINGRATE_96;
 
  130        sr = SL_SAMPLINGRATE_192;
 
  137    const SLInterfaceID ids[] = { SL_IID_VOLUME };
 
  138    const SLboolean req[] = { SL_BOOLEAN_FALSE };
 
  139    result = (*p->engineEngine)
 
  140                 ->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req);
 
  141    DEBUG_SND(
"engineEngine=%p", (
void*)p->engineEngine);
 
  142    WINPR_ASSERT(!result);
 
  144    if (result != SL_RESULT_SUCCESS)
 
  148    result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE);
 
  149    DEBUG_SND(
"Realize=%" PRIu32 
"", result);
 
  150    WINPR_ASSERT(!result);
 
  152    if (result != SL_RESULT_SUCCESS)
 
  158      speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
 
  160      speakers = SL_SPEAKER_FRONT_CENTER;
 
  162    SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM,
 
  165                                  SL_PCMSAMPLEFORMAT_FIXED_16,
 
  166                                  SL_PCMSAMPLEFORMAT_FIXED_16,
 
  168                                  SL_BYTEORDER_LITTLEENDIAN };
 
  169    SLDataSource audioSrc = { &loc_bufq, &format_pcm };
 
  171    SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject };
 
  172    SLDataSink audioSnk = { &loc_outmix, NULL };
 
  174    const SLInterfaceID ids1[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME };
 
  175    const SLboolean req1[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
 
  176    result = (*p->engineEngine)
 
  177                 ->CreateAudioPlayer(p->engineEngine, &(p->bqPlayerObject), &audioSrc,
 
  178                                     &audioSnk, 2, ids1, req1);
 
  179    DEBUG_SND(
"bqPlayerObject=%p", (
void*)p->bqPlayerObject);
 
  180    WINPR_ASSERT(!result);
 
  182    if (result != SL_RESULT_SUCCESS)
 
  186    result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE);
 
  187    DEBUG_SND(
"Realize=%" PRIu32 
"", result);
 
  188    WINPR_ASSERT(!result);
 
  190    if (result != SL_RESULT_SUCCESS)
 
  195        (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay));
 
  196    DEBUG_SND(
"bqPlayerPlay=%p", (
void*)p->bqPlayerPlay);
 
  197    WINPR_ASSERT(!result);
 
  199    if (result != SL_RESULT_SUCCESS)
 
  203    result = (*p->bqPlayerObject)
 
  204                 ->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, &(p->bqPlayerVolume));
 
  205    DEBUG_SND(
"bqPlayerVolume=%p", (
void*)p->bqPlayerVolume);
 
  206    WINPR_ASSERT(!result);
 
  208    if (result != SL_RESULT_SUCCESS)
 
  212    result = (*p->bqPlayerObject)
 
  213                 ->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
 
  214                                &(p->bqPlayerBufferQueue));
 
  215    DEBUG_SND(
"bqPlayerBufferQueue=%p", (
void*)p->bqPlayerBufferQueue);
 
  216    WINPR_ASSERT(!result);
 
  218    if (result != SL_RESULT_SUCCESS)
 
  222    result = (*p->bqPlayerBufferQueue)
 
  223                 ->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p);
 
  224    DEBUG_SND(
"bqPlayerCallback=%p", (
void*)p->bqPlayerCallback);
 
  225    WINPR_ASSERT(!result);
 
  227    if (result != SL_RESULT_SUCCESS)
 
  231    result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
 
  232    DEBUG_SND(
"SetPlayState=%" PRIu32 
"", result);
 
  233    WINPR_ASSERT(!result);
 
  235    WINPR_ASSERT(!result);
 
  239  return SL_RESULT_SUCCESS;
 
  246  if (p->bqPlayerObject != NULL)
 
  248    (*p->bqPlayerObject)->Destroy(p->bqPlayerObject);
 
  249    p->bqPlayerObject = NULL;
 
  250    p->bqPlayerVolume = NULL;
 
  251    p->bqPlayerPlay = NULL;
 
  252    p->bqPlayerBufferQueue = NULL;
 
  253    p->bqPlayerEffectSend = NULL;
 
  257  if (p->outputMixObject != NULL)
 
  259    (*p->outputMixObject)->Destroy(p->outputMixObject);
 
  260    p->outputMixObject = NULL;
 
  264  if (p->engineObject != NULL)
 
  266    (*p->engineObject)->Destroy(p->engineObject);
 
  267    p->engineObject = NULL;
 
  268    p->engineEngine = NULL;
 
  273OPENSL_STREAM* android_OpenAudioDevice(
int sr, 
int outchannels, 
int bufferframes)
 
  281  p->queuesize = bufferframes;
 
  282  p->outchannels = outchannels;
 
  285  if (openSLCreateEngine(p) != SL_RESULT_SUCCESS)
 
  287    android_CloseAudioDevice(p);
 
  291  if (openSLPlayOpen(p) != SL_RESULT_SUCCESS)
 
  293    android_CloseAudioDevice(p);
 
  297  p->queue = Queue_New(TRUE, -1, -1);
 
  301    android_CloseAudioDevice(p);
 
  314  openSLDestroyEngine(p);
 
  317    Queue_Free(p->queue);
 
  323static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, 
void* context)
 
  327  WINPR_ASSERT(p->queue);
 
  328  void* data = Queue_Dequeue(p->queue);
 
  333int android_AudioOut(
OPENSL_STREAM* p, 
const short* buffer, 
int size)
 
  337  WINPR_ASSERT(buffer);
 
  338  WINPR_ASSERT(size > 0);
 
  340  ev = Queue_Event(p->queue);
 
  342  if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(ev, INFINITE) == WAIT_FAILED)
 
  344    DEBUG_SND(
"WaitForSingleObject failed!");
 
  348  void* data = calloc(size, 
sizeof(
short));
 
  352    DEBUG_SND(
"unable to allocate a buffer");
 
  356  memcpy(data, buffer, size * 
sizeof(
short));
 
  357  Queue_Enqueue(p->queue, data);
 
  358  (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, data, 
sizeof(
short) * size);
 
  366  WINPR_ASSERT(p->bqPlayerVolume);
 
  367  SLresult rc = (*p->bqPlayerVolume)->GetMute(p->bqPlayerVolume, &mute);
 
  369  if (SL_RESULT_SUCCESS != rc)
 
  370    return SL_BOOLEAN_FALSE;
 
  377  SLboolean mute = _mute;
 
  379  WINPR_ASSERT(p->bqPlayerVolume);
 
  380  SLresult rc = (*p->bqPlayerVolume)->SetMute(p->bqPlayerVolume, mute);
 
  382  if (SL_RESULT_SUCCESS != rc)
 
  392  WINPR_ASSERT(p->bqPlayerVolume);
 
  393  SLresult rc = (*p->bqPlayerVolume)->GetVolumeLevel(p->bqPlayerVolume, &level);
 
  395  if (SL_RESULT_SUCCESS != rc)
 
  405  WINPR_ASSERT(p->bqPlayerVolume);
 
  406  SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, &level);
 
  408  if (SL_RESULT_SUCCESS != rc)
 
  416  SLresult rc = (*p->bqPlayerVolume)->SetVolumeLevel(p->bqPlayerVolume, level);
 
  418  if (SL_RESULT_SUCCESS != rc)