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,
nullptr, 0,
nullptr,
nullptr);
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 =
nullptr;
100 result = SL_RESULT_SUCCESS;
112 SLuint32 channels = p->inchannels;
113 WINPR_ASSERT(!p->recorderObject);
120 sr = SL_SAMPLINGRATE_8;
124 sr = SL_SAMPLINGRATE_11_025;
128 sr = SL_SAMPLINGRATE_16;
132 sr = SL_SAMPLINGRATE_22_05;
136 sr = SL_SAMPLINGRATE_24;
140 sr = SL_SAMPLINGRATE_32;
144 sr = SL_SAMPLINGRATE_44_1;
148 sr = SL_SAMPLINGRATE_48;
152 sr = SL_SAMPLINGRATE_64;
156 sr = SL_SAMPLINGRATE_88_2;
160 sr = SL_SAMPLINGRATE_96;
164 sr = SL_SAMPLINGRATE_192;
168 WLog_ERR(TAG,
"Sample rate %" PRIu32
" unsupported", sr);
173 SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
174 SL_DEFAULTDEVICEID_AUDIOINPUT,
nullptr };
175 SLDataSource audioSrc = { &loc_dev,
nullptr };
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 = WINPR_C_ARRAY_INIT;
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;
205 WLog_ERR(TAG,
"bits_per_sample=%" PRIu32, p->bits_per_sample);
209 SLDataSink audioSnk = { &loc_bq, &format_pcm };
212 const SLInterfaceID
id[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
213 const SLboolean req[] = { SL_BOOLEAN_TRUE };
214 result = (*p->engineEngine)
215 ->CreateAudioRecorder(p->engineEngine, &(p->recorderObject), &audioSrc,
216 &audioSnk, 1, id, req);
217 if (SL_RESULT_SUCCESS != result)
219 WLog_ERR(TAG,
"CreateAudioRecorder failed with %d", result);
224 result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE);
225 if (SL_RESULT_SUCCESS != result)
227 WLog_ERR(TAG,
"recorderObject failed with %d", result);
232 result = (*p->recorderObject)
233 ->GetInterface(p->recorderObject, SL_IID_RECORD, &(p->recorderRecord));
234 if (SL_RESULT_SUCCESS != result)
236 WLog_ERR(TAG,
"GetInterface(SL_IID_RECORD) failed with %d", result);
241 result = (*p->recorderObject)
242 ->GetInterface(p->recorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
243 &(p->recorderBufferQueue));
244 if (SL_RESULT_SUCCESS != result)
246 WLog_ERR(TAG,
"GetInterface(SL_IID_ANDROIDSIMPLEBUFFERQUEUE) failed with %d", result);
251 result = (*p->recorderBufferQueue)
252 ->RegisterCallback(p->recorderBufferQueue, bqRecorderCallback, p);
253 if (SL_RESULT_SUCCESS != result)
255 WLog_ERR(TAG,
"RegisterCallback failed with %d", result);
263 return SL_RESULT_SUCCESS;
270 if (p->recorderObject !=
nullptr)
272 (*p->recorderObject)->Destroy(p->recorderObject);
273 p->recorderObject =
nullptr;
274 p->recorderRecord =
nullptr;
275 p->recorderBufferQueue =
nullptr;
279 if (p->engineObject !=
nullptr)
281 (*p->engineObject)->Destroy(p->engineObject);
282 p->engineObject =
nullptr;
283 p->engineEngine =
nullptr;
287static queue_element* opensles_queue_element_new(
size_t size)
289 queue_element* q = calloc(1,
sizeof(queue_element));
295 q->data = malloc(size);
306static void opensles_queue_element_free(
void* obj)
308 queue_element* e = (queue_element*)obj;
317OPENSL_STREAM* android_OpenRecDevice(
void* context, opensl_receive_t receive,
int sr,
318 int inchannels,
int bufferframes,
int bits_per_sample)
322 if (!context || !receive)
330 p->context = context;
331 p->receive = receive;
332 p->inchannels = inchannels;
334 p->buffersize = bufferframes;
335 p->bits_per_sample = bits_per_sample;
337 if ((p->bits_per_sample != 8) && (p->bits_per_sample != 16))
340 if (openSLCreateEngine(p) != SL_RESULT_SUCCESS)
343 if (openSLRecOpen(p) != SL_RESULT_SUCCESS)
347 p->prep = opensles_queue_element_new(p->buffersize * p->bits_per_sample / 8);
348 p->next = opensles_queue_element_new(p->buffersize * p->bits_per_sample / 8);
350 if (!p->prep || !p->next)
353 (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, p->next->data, p->next->size);
354 (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, p->prep->data, p->prep->size);
355 (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING);
358 android_CloseRecDevice(p);
368 opensles_queue_element_free(p->next);
369 opensles_queue_element_free(p->prep);
370 openSLDestroyEngine(p);
375static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq,
void* context)
388 if (!p->context || !p->receive)
389 WLog_WARN(TAG,
"Missing receive callback=%p, context=%p", p->receive, p->context);
391 p->receive(p->context, e->data, e->size);
395 (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, e->data, e->size);