30#include <winpr/assert.h> 
   32#include "audin_main.h" 
   34#define CONV16BIT 32768 
   35#define CONVMYFLT (1. / 32768.) 
   46  SLObjectItf engineObject;
 
   47  SLEngineItf engineEngine;
 
   50  SLDeviceVolumeItf deviceVolume;
 
   53  SLObjectItf recorderObject;
 
   54  SLRecordItf recorderRecord;
 
   55  SLAndroidSimpleBufferQueueItf recorderBufferQueue;
 
   57  unsigned int inchannels;
 
   59  unsigned int buffersize;
 
   60  unsigned int bits_per_sample;
 
   66  opensl_receive_t receive;
 
   69static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, 
void* context);
 
   76  result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL);
 
   78  if (result != SL_RESULT_SUCCESS)
 
   82  result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE);
 
   84  if (result != SL_RESULT_SUCCESS)
 
   88  result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine));
 
   90  if (result != SL_RESULT_SUCCESS)
 
   95      (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME, &(p->deviceVolume));
 
   97  if (result != SL_RESULT_SUCCESS)
 
   99    p->deviceVolume = NULL;
 
  100    result = SL_RESULT_SUCCESS;
 
  104  WINPR_ASSERT(SL_RESULT_SUCCESS == result);
 
  113  SLuint32 channels = p->inchannels;
 
  114  WINPR_ASSERT(!p->recorderObject);
 
  121        sr = SL_SAMPLINGRATE_8;
 
  125        sr = SL_SAMPLINGRATE_11_025;
 
  129        sr = SL_SAMPLINGRATE_16;
 
  133        sr = SL_SAMPLINGRATE_22_05;
 
  137        sr = SL_SAMPLINGRATE_24;
 
  141        sr = SL_SAMPLINGRATE_32;
 
  145        sr = SL_SAMPLINGRATE_44_1;
 
  149        sr = SL_SAMPLINGRATE_48;
 
  153        sr = SL_SAMPLINGRATE_64;
 
  157        sr = SL_SAMPLINGRATE_88_2;
 
  161        sr = SL_SAMPLINGRATE_96;
 
  165        sr = SL_SAMPLINGRATE_192;
 
  173    SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
 
  174                                     SL_DEFAULTDEVICEID_AUDIOINPUT, NULL };
 
  175    SLDataSource audioSrc = { &loc_dev, NULL };
 
  180      speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
 
  182      speakers = SL_SPEAKER_FRONT_CENTER;
 
  184    SLDataLocator_AndroidSimpleBufferQueue loc_bq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
 
  186    SLDataFormat_PCM format_pcm;
 
  187    format_pcm.formatType = SL_DATAFORMAT_PCM;
 
  188    format_pcm.numChannels = channels;
 
  189    format_pcm.samplesPerSec = sr;
 
  190    format_pcm.channelMask = speakers;
 
  191    format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
 
  193    if (16 == p->bits_per_sample)
 
  195      format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
 
  196      format_pcm.containerSize = 16;
 
  198    else if (8 == p->bits_per_sample)
 
  200      format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8;
 
  201      format_pcm.containerSize = 8;
 
  206    SLDataSink audioSnk = { &loc_bq, &format_pcm };
 
  209    const SLInterfaceID 
id[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
 
  210    const SLboolean req[] = { SL_BOOLEAN_TRUE };
 
  211    result = (*p->engineEngine)
 
  212                 ->CreateAudioRecorder(p->engineEngine, &(p->recorderObject), &audioSrc,
 
  213                                       &audioSnk, 1, id, req);
 
  214    WINPR_ASSERT(!result);
 
  216    if (SL_RESULT_SUCCESS != result)
 
  220    result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE);
 
  221    WINPR_ASSERT(!result);
 
  223    if (SL_RESULT_SUCCESS != result)
 
  227    result = (*p->recorderObject)
 
  228                 ->GetInterface(p->recorderObject, SL_IID_RECORD, &(p->recorderRecord));
 
  229    WINPR_ASSERT(!result);
 
  231    if (SL_RESULT_SUCCESS != result)
 
  235    result = (*p->recorderObject)
 
  236                 ->GetInterface(p->recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
 
  237                                &(p->recorderBufferQueue));
 
  238    WINPR_ASSERT(!result);
 
  240    if (SL_RESULT_SUCCESS != result)
 
  244    result = (*p->recorderBufferQueue)
 
  245                 ->RegisterCallback(p->recorderBufferQueue, bqRecorderCallback, p);
 
  246    WINPR_ASSERT(!result);
 
  248    if (SL_RESULT_SUCCESS != result)
 
  255    return SL_RESULT_SUCCESS;
 
  262  if (p->recorderObject != NULL)
 
  264    (*p->recorderObject)->Destroy(p->recorderObject);
 
  265    p->recorderObject = NULL;
 
  266    p->recorderRecord = NULL;
 
  267    p->recorderBufferQueue = NULL;
 
  271  if (p->engineObject != NULL)
 
  273    (*p->engineObject)->Destroy(p->engineObject);
 
  274    p->engineObject = NULL;
 
  275    p->engineEngine = NULL;
 
  279static queue_element* opensles_queue_element_new(
size_t size)
 
  281  queue_element* q = calloc(1, 
sizeof(queue_element));
 
  287  q->data = malloc(size);
 
  298static void opensles_queue_element_free(
void* obj)
 
  300  queue_element* e = (queue_element*)obj;
 
  309OPENSL_STREAM* android_OpenRecDevice(
void* context, opensl_receive_t receive, 
int sr,
 
  310                                     int inchannels, 
int bufferframes, 
int bits_per_sample)
 
  314  if (!context || !receive)
 
  322  p->context = context;
 
  323  p->receive = receive;
 
  324  p->inchannels = inchannels;
 
  326  p->buffersize = bufferframes;
 
  327  p->bits_per_sample = bits_per_sample;
 
  329  if ((p->bits_per_sample != 8) && (p->bits_per_sample != 16))
 
  332  if (openSLCreateEngine(p) != SL_RESULT_SUCCESS)
 
  335  if (openSLRecOpen(p) != SL_RESULT_SUCCESS)
 
  339  p->prep = opensles_queue_element_new(p->buffersize * p->bits_per_sample / 8);
 
  340  p->next = opensles_queue_element_new(p->buffersize * p->bits_per_sample / 8);
 
  342  if (!p->prep || !p->next)
 
  345  (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, p->next->data, p->next->size);
 
  346  (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, p->prep->data, p->prep->size);
 
  347  (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING);
 
  350  android_CloseRecDevice(p);
 
  360  opensles_queue_element_free(p->next);
 
  361  opensles_queue_element_free(p->prep);
 
  362  openSLDestroyEngine(p);
 
  367static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, 
void* context)
 
  380  if (!p->context || !p->receive)
 
  381    WLog_WARN(TAG, 
"Missing receive callback=%p, context=%p", p->receive, p->context);
 
  383    p->receive(p->context, e->data, e->size);
 
  387  (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, e->data, e->size);