30 #include <winpr/assert.h>
32 #include "audin_main.h"
33 #include "opensl_io.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;
69 static 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;
279 static queue_element* opensles_queue_element_new(
size_t size)
281 queue_element* q = calloc(1,
sizeof(queue_element));
287 q->data = malloc(size);
298 static void opensles_queue_element_free(
void* obj)
300 queue_element* e = (queue_element*)obj;
309 OPENSL_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);
367 static 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);