opensl.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135
  1. /*
  2. * Copyright (C) 2011 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /* This is an OpenAL backend for Android using the native audio APIs based on
  17. * OpenSL ES 1.0.1. It is based on source code for the native-audio sample app
  18. * bundled with NDK.
  19. */
  20. #include "config.h"
  21. #include <stdlib.h>
  22. #include <jni.h>
  23. #include "alMain.h"
  24. #include "alu.h"
  25. #include "compat.h"
  26. #include "threads.h"
  27. #include "backends/base.h"
  28. #include <SLES/OpenSLES.h>
  29. #include <SLES/OpenSLES_Android.h>
  30. #include <SLES/OpenSLES_AndroidConfiguration.h>
  31. /* Helper macros */
  32. #define VCALL(obj, func) ((*(obj))->func((obj), EXTRACT_VCALL_ARGS
  33. #define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
  34. static const ALCchar opensl_device[] = "OpenSL";
  35. static SLuint32 GetChannelMask(enum DevFmtChannels chans)
  36. {
  37. switch(chans)
  38. {
  39. case DevFmtMono: return SL_SPEAKER_FRONT_CENTER;
  40. case DevFmtStereo: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT;
  41. case DevFmtQuad: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
  42. SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT;
  43. case DevFmtX51: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
  44. SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
  45. SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
  46. case DevFmtX51Rear: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
  47. SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
  48. SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT;
  49. case DevFmtX61: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
  50. SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
  51. SL_SPEAKER_BACK_CENTER|
  52. SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
  53. case DevFmtX71: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT|
  54. SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY|
  55. SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT|
  56. SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT;
  57. case DevFmtAmbi3D:
  58. break;
  59. }
  60. return 0;
  61. }
  62. #ifdef SL_DATAFORMAT_PCM_EX
  63. static SLuint32 GetTypeRepresentation(enum DevFmtType type)
  64. {
  65. switch(type)
  66. {
  67. case DevFmtUByte:
  68. case DevFmtUShort:
  69. case DevFmtUInt:
  70. return SL_PCM_REPRESENTATION_UNSIGNED_INT;
  71. case DevFmtByte:
  72. case DevFmtShort:
  73. case DevFmtInt:
  74. return SL_PCM_REPRESENTATION_SIGNED_INT;
  75. case DevFmtFloat:
  76. return SL_PCM_REPRESENTATION_FLOAT;
  77. }
  78. return 0;
  79. }
  80. #endif
  81. static const char *res_str(SLresult result)
  82. {
  83. switch(result)
  84. {
  85. case SL_RESULT_SUCCESS: return "Success";
  86. case SL_RESULT_PRECONDITIONS_VIOLATED: return "Preconditions violated";
  87. case SL_RESULT_PARAMETER_INVALID: return "Parameter invalid";
  88. case SL_RESULT_MEMORY_FAILURE: return "Memory failure";
  89. case SL_RESULT_RESOURCE_ERROR: return "Resource error";
  90. case SL_RESULT_RESOURCE_LOST: return "Resource lost";
  91. case SL_RESULT_IO_ERROR: return "I/O error";
  92. case SL_RESULT_BUFFER_INSUFFICIENT: return "Buffer insufficient";
  93. case SL_RESULT_CONTENT_CORRUPTED: return "Content corrupted";
  94. case SL_RESULT_CONTENT_UNSUPPORTED: return "Content unsupported";
  95. case SL_RESULT_CONTENT_NOT_FOUND: return "Content not found";
  96. case SL_RESULT_PERMISSION_DENIED: return "Permission denied";
  97. case SL_RESULT_FEATURE_UNSUPPORTED: return "Feature unsupported";
  98. case SL_RESULT_INTERNAL_ERROR: return "Internal error";
  99. case SL_RESULT_UNKNOWN_ERROR: return "Unknown error";
  100. case SL_RESULT_OPERATION_ABORTED: return "Operation aborted";
  101. case SL_RESULT_CONTROL_LOST: return "Control lost";
  102. #ifdef SL_RESULT_READONLY
  103. case SL_RESULT_READONLY: return "ReadOnly";
  104. #endif
  105. #ifdef SL_RESULT_ENGINEOPTION_UNSUPPORTED
  106. case SL_RESULT_ENGINEOPTION_UNSUPPORTED: return "Engine option unsupported";
  107. #endif
  108. #ifdef SL_RESULT_SOURCE_SINK_INCOMPATIBLE
  109. case SL_RESULT_SOURCE_SINK_INCOMPATIBLE: return "Source/Sink incompatible";
  110. #endif
  111. }
  112. return "Unknown error code";
  113. }
  114. #define PRINTERR(x, s) do { \
  115. if((x) != SL_RESULT_SUCCESS) \
  116. ERR("%s: %s\n", (s), res_str((x))); \
  117. } while(0)
  118. typedef struct ALCopenslPlayback {
  119. DERIVE_FROM_TYPE(ALCbackend);
  120. /* engine interfaces */
  121. SLObjectItf mEngineObj;
  122. SLEngineItf mEngine;
  123. /* output mix interfaces */
  124. SLObjectItf mOutputMix;
  125. /* buffer queue player interfaces */
  126. SLObjectItf mBufferQueueObj;
  127. ll_ringbuffer_t *mRing;
  128. alcnd_t mCond;
  129. ALsizei mFrameSize;
  130. ATOMIC(ALenum) mKillNow;
  131. althrd_t mThread;
  132. } ALCopenslPlayback;
  133. static void ALCopenslPlayback_process(SLAndroidSimpleBufferQueueItf bq, void *context);
  134. static int ALCopenslPlayback_mixerProc(void *arg);
  135. static void ALCopenslPlayback_Construct(ALCopenslPlayback *self, ALCdevice *device);
  136. static void ALCopenslPlayback_Destruct(ALCopenslPlayback *self);
  137. static ALCenum ALCopenslPlayback_open(ALCopenslPlayback *self, const ALCchar *name);
  138. static void ALCopenslPlayback_close(ALCopenslPlayback *self);
  139. static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self);
  140. static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self);
  141. static void ALCopenslPlayback_stop(ALCopenslPlayback *self);
  142. static DECLARE_FORWARD2(ALCopenslPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
  143. static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, ALCuint, availableSamples)
  144. static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self);
  145. static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, void, lock)
  146. static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, void, unlock)
  147. DECLARE_DEFAULT_ALLOCATORS(ALCopenslPlayback)
  148. DEFINE_ALCBACKEND_VTABLE(ALCopenslPlayback);
  149. static void ALCopenslPlayback_Construct(ALCopenslPlayback *self, ALCdevice *device)
  150. {
  151. ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
  152. SET_VTABLE2(ALCopenslPlayback, ALCbackend, self);
  153. self->mEngineObj = NULL;
  154. self->mEngine = NULL;
  155. self->mOutputMix = NULL;
  156. self->mBufferQueueObj = NULL;
  157. self->mRing = NULL;
  158. alcnd_init(&self->mCond);
  159. self->mFrameSize = 0;
  160. ATOMIC_INIT(&self->mKillNow, AL_FALSE);
  161. }
  162. static void ALCopenslPlayback_Destruct(ALCopenslPlayback* self)
  163. {
  164. if(self->mBufferQueueObj != NULL)
  165. VCALL0(self->mBufferQueueObj,Destroy)();
  166. self->mBufferQueueObj = NULL;
  167. if(self->mOutputMix != NULL)
  168. VCALL0(self->mOutputMix,Destroy)();
  169. self->mOutputMix = NULL;
  170. if(self->mEngineObj != NULL)
  171. VCALL0(self->mEngineObj,Destroy)();
  172. self->mEngineObj = NULL;
  173. self->mEngine = NULL;
  174. ll_ringbuffer_free(self->mRing);
  175. self->mRing = NULL;
  176. alcnd_destroy(&self->mCond);
  177. ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
  178. }
  179. /* this callback handler is called every time a buffer finishes playing */
  180. static void ALCopenslPlayback_process(SLAndroidSimpleBufferQueueItf UNUSED(bq), void *context)
  181. {
  182. ALCopenslPlayback *self = context;
  183. /* A note on the ringbuffer usage: The buffer queue seems to hold on to the
  184. * pointer passed to the Enqueue method, rather than copying the audio.
  185. * Consequently, the ringbuffer contains the audio that is currently queued
  186. * and waiting to play. This process() callback is called when a buffer is
  187. * finished, so we simply move the read pointer up to indicate the space is
  188. * available for writing again, and wake up the mixer thread to mix and
  189. * queue more audio.
  190. */
  191. ll_ringbuffer_read_advance(self->mRing, 1);
  192. alcnd_signal(&self->mCond);
  193. }
  194. static int ALCopenslPlayback_mixerProc(void *arg)
  195. {
  196. ALCopenslPlayback *self = arg;
  197. ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
  198. SLAndroidSimpleBufferQueueItf bufferQueue;
  199. ll_ringbuffer_data_t data[2];
  200. SLPlayItf player;
  201. SLresult result;
  202. size_t padding;
  203. SetRTPriority();
  204. althrd_setname(althrd_current(), MIXER_THREAD_NAME);
  205. result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  206. &bufferQueue);
  207. PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
  208. if(SL_RESULT_SUCCESS == result)
  209. {
  210. result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
  211. PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY");
  212. }
  213. if(SL_RESULT_SUCCESS != result)
  214. {
  215. ALCopenslPlayback_lock(self);
  216. aluHandleDisconnect(device);
  217. ALCopenslPlayback_unlock(self);
  218. return 1;
  219. }
  220. /* NOTE: The ringbuffer will be larger than the desired buffer metrics.
  221. * Calculate the amount of extra space so we know how much to keep unused.
  222. */
  223. padding = ll_ringbuffer_write_space(self->mRing) - device->NumUpdates;
  224. ALCopenslPlayback_lock(self);
  225. while(ATOMIC_LOAD_SEQ(&self->mKillNow) == AL_FALSE && device->Connected)
  226. {
  227. size_t todo, len0, len1;
  228. if(ll_ringbuffer_write_space(self->mRing) <= padding)
  229. {
  230. SLuint32 state = 0;
  231. result = VCALL(player,GetPlayState)(&state);
  232. PRINTERR(result, "player->GetPlayState");
  233. if(SL_RESULT_SUCCESS == result && state != SL_PLAYSTATE_PLAYING)
  234. {
  235. result = VCALL(player,SetPlayState)(SL_PLAYSTATE_PLAYING);
  236. PRINTERR(result, "player->SetPlayState");
  237. }
  238. if(SL_RESULT_SUCCESS != result)
  239. {
  240. aluHandleDisconnect(device);
  241. break;
  242. }
  243. /* NOTE: Unfortunately, there is an unavoidable race condition
  244. * here. It's possible for the process() method to run, updating
  245. * the read pointer and signaling the condition variable, in
  246. * between checking the write size and waiting for the condition
  247. * variable here. This will cause alcnd_wait to wait until the
  248. * *next* process() invocation signals the condition variable
  249. * again.
  250. *
  251. * However, this should only happen if the mixer is running behind
  252. * anyway (as ideally we'll be asleep in alcnd_wait by the time the
  253. * process() method is invoked), so this behavior is not completely
  254. * unwarranted. It's unfortunate since it'll be wasting time
  255. * sleeping that could be used to catch up, but there's no way
  256. * around it without blocking in the process() method.
  257. */
  258. if(ll_ringbuffer_write_space(self->mRing) <= padding)
  259. {
  260. alcnd_wait(&self->mCond, &STATIC_CAST(ALCbackend,self)->mMutex);
  261. continue;
  262. }
  263. }
  264. ll_ringbuffer_get_write_vector(self->mRing, data);
  265. todo = data[0].len+data[1].len - padding;
  266. len0 = minu(todo, data[0].len);
  267. len1 = minu(todo-len0, data[1].len);
  268. aluMixData(device, data[0].buf, len0*device->UpdateSize);
  269. for(size_t i = 0;i < len0;i++)
  270. {
  271. result = VCALL(bufferQueue,Enqueue)(data[0].buf, device->UpdateSize*self->mFrameSize);
  272. PRINTERR(result, "bufferQueue->Enqueue");
  273. if(SL_RESULT_SUCCESS == result)
  274. ll_ringbuffer_write_advance(self->mRing, 1);
  275. data[0].buf += device->UpdateSize*self->mFrameSize;
  276. }
  277. if(len1 > 0)
  278. {
  279. aluMixData(device, data[1].buf, len1*device->UpdateSize);
  280. for(size_t i = 0;i < len1;i++)
  281. {
  282. result = VCALL(bufferQueue,Enqueue)(data[1].buf, device->UpdateSize*self->mFrameSize);
  283. PRINTERR(result, "bufferQueue->Enqueue");
  284. if(SL_RESULT_SUCCESS == result)
  285. ll_ringbuffer_write_advance(self->mRing, 1);
  286. data[1].buf += device->UpdateSize*self->mFrameSize;
  287. }
  288. }
  289. }
  290. ALCopenslPlayback_unlock(self);
  291. return 0;
  292. }
  293. static ALCenum ALCopenslPlayback_open(ALCopenslPlayback *self, const ALCchar *name)
  294. {
  295. ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
  296. SLresult result;
  297. if(!name)
  298. name = opensl_device;
  299. else if(strcmp(name, opensl_device) != 0)
  300. return ALC_INVALID_VALUE;
  301. // create engine
  302. result = slCreateEngine(&self->mEngineObj, 0, NULL, 0, NULL, NULL);
  303. PRINTERR(result, "slCreateEngine");
  304. if(SL_RESULT_SUCCESS == result)
  305. {
  306. result = VCALL(self->mEngineObj,Realize)(SL_BOOLEAN_FALSE);
  307. PRINTERR(result, "engine->Realize");
  308. }
  309. if(SL_RESULT_SUCCESS == result)
  310. {
  311. result = VCALL(self->mEngineObj,GetInterface)(SL_IID_ENGINE, &self->mEngine);
  312. PRINTERR(result, "engine->GetInterface");
  313. }
  314. if(SL_RESULT_SUCCESS == result)
  315. {
  316. result = VCALL(self->mEngine,CreateOutputMix)(&self->mOutputMix, 0, NULL, NULL);
  317. PRINTERR(result, "engine->CreateOutputMix");
  318. }
  319. if(SL_RESULT_SUCCESS == result)
  320. {
  321. result = VCALL(self->mOutputMix,Realize)(SL_BOOLEAN_FALSE);
  322. PRINTERR(result, "outputMix->Realize");
  323. }
  324. if(SL_RESULT_SUCCESS != result)
  325. {
  326. if(self->mOutputMix != NULL)
  327. VCALL0(self->mOutputMix,Destroy)();
  328. self->mOutputMix = NULL;
  329. if(self->mEngineObj != NULL)
  330. VCALL0(self->mEngineObj,Destroy)();
  331. self->mEngineObj = NULL;
  332. self->mEngine = NULL;
  333. return ALC_INVALID_VALUE;
  334. }
  335. alstr_copy_cstr(&device->DeviceName, name);
  336. return ALC_NO_ERROR;
  337. }
  338. static void ALCopenslPlayback_close(ALCopenslPlayback *self)
  339. {
  340. if(self->mBufferQueueObj != NULL)
  341. VCALL0(self->mBufferQueueObj,Destroy)();
  342. self->mBufferQueueObj = NULL;
  343. VCALL0(self->mOutputMix,Destroy)();
  344. self->mOutputMix = NULL;
  345. VCALL0(self->mEngineObj,Destroy)();
  346. self->mEngineObj = NULL;
  347. self->mEngine = NULL;
  348. }
  349. static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
  350. {
  351. ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
  352. SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
  353. SLDataLocator_OutputMix loc_outmix;
  354. SLDataSource audioSrc;
  355. SLDataSink audioSnk;
  356. ALuint sampleRate;
  357. SLInterfaceID ids[2];
  358. SLboolean reqs[2];
  359. SLresult result;
  360. JNIEnv *env;
  361. if(self->mBufferQueueObj != NULL)
  362. VCALL0(self->mBufferQueueObj,Destroy)();
  363. self->mBufferQueueObj = NULL;
  364. sampleRate = device->Frequency;
  365. if(!(device->Flags&DEVICE_FREQUENCY_REQUEST) && (env=Android_GetJNIEnv()) != NULL)
  366. {
  367. /* FIXME: Disabled until I figure out how to get the Context needed for
  368. * the getSystemService call.
  369. */
  370. #if 0
  371. /* Get necessary stuff for using java.lang.Integer,
  372. * android.content.Context, and android.media.AudioManager.
  373. */
  374. jclass int_cls = JCALL(env,FindClass)("java/lang/Integer");
  375. jmethodID int_parseint = JCALL(env,GetStaticMethodID)(int_cls,
  376. "parseInt", "(Ljava/lang/String;)I"
  377. );
  378. TRACE("Integer: %p, parseInt: %p\n", int_cls, int_parseint);
  379. jclass ctx_cls = JCALL(env,FindClass)("android/content/Context");
  380. jfieldID ctx_audsvc = JCALL(env,GetStaticFieldID)(ctx_cls,
  381. "AUDIO_SERVICE", "Ljava/lang/String;"
  382. );
  383. jmethodID ctx_getSysSvc = JCALL(env,GetMethodID)(ctx_cls,
  384. "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"
  385. );
  386. TRACE("Context: %p, AUDIO_SERVICE: %p, getSystemService: %p\n",
  387. ctx_cls, ctx_audsvc, ctx_getSysSvc);
  388. jclass audmgr_cls = JCALL(env,FindClass)("android/media/AudioManager");
  389. jfieldID audmgr_prop_out_srate = JCALL(env,GetStaticFieldID)(audmgr_cls,
  390. "PROPERTY_OUTPUT_SAMPLE_RATE", "Ljava/lang/String;"
  391. );
  392. jmethodID audmgr_getproperty = JCALL(env,GetMethodID)(audmgr_cls,
  393. "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"
  394. );
  395. TRACE("AudioManager: %p, PROPERTY_OUTPUT_SAMPLE_RATE: %p, getProperty: %p\n",
  396. audmgr_cls, audmgr_prop_out_srate, audmgr_getproperty);
  397. const char *strchars;
  398. jstring strobj;
  399. /* Now make the calls. */
  400. //AudioManager audMgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
  401. strobj = JCALL(env,GetStaticObjectField)(ctx_cls, ctx_audsvc);
  402. jobject audMgr = JCALL(env,CallObjectMethod)(ctx_cls, ctx_getSysSvc, strobj);
  403. strchars = JCALL(env,GetStringUTFChars)(strobj, NULL);
  404. TRACE("Context.getSystemService(%s) = %p\n", strchars, audMgr);
  405. JCALL(env,ReleaseStringUTFChars)(strobj, strchars);
  406. //String srateStr = audMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
  407. strobj = JCALL(env,GetStaticObjectField)(audmgr_cls, audmgr_prop_out_srate);
  408. jstring srateStr = JCALL(env,CallObjectMethod)(audMgr, audmgr_getproperty, strobj);
  409. strchars = JCALL(env,GetStringUTFChars)(strobj, NULL);
  410. TRACE("audMgr.getProperty(%s) = %p\n", strchars, srateStr);
  411. JCALL(env,ReleaseStringUTFChars)(strobj, strchars);
  412. //int sampleRate = Integer.parseInt(srateStr);
  413. sampleRate = JCALL(env,CallStaticIntMethod)(int_cls, int_parseint, srateStr);
  414. strchars = JCALL(env,GetStringUTFChars)(srateStr, NULL);
  415. TRACE("Got system sample rate %uhz (%s)\n", sampleRate, strchars);
  416. JCALL(env,ReleaseStringUTFChars)(srateStr, strchars);
  417. if(!sampleRate) sampleRate = device->Frequency;
  418. else sampleRate = maxu(sampleRate, MIN_OUTPUT_RATE);
  419. #endif
  420. }
  421. if(sampleRate != device->Frequency)
  422. {
  423. device->NumUpdates = (device->NumUpdates*sampleRate + (device->Frequency>>1)) /
  424. device->Frequency;
  425. device->NumUpdates = maxu(device->NumUpdates, 2);
  426. device->Frequency = sampleRate;
  427. }
  428. device->FmtChans = DevFmtStereo;
  429. device->FmtType = DevFmtShort;
  430. SetDefaultWFXChannelOrder(device);
  431. self->mFrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
  432. loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
  433. loc_bufq.numBuffers = device->NumUpdates;
  434. #ifdef SL_DATAFORMAT_PCM_EX
  435. SLDataFormat_PCM_EX format_pcm;
  436. format_pcm.formatType = SL_DATAFORMAT_PCM_EX;
  437. format_pcm.numChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
  438. format_pcm.sampleRate = device->Frequency * 1000;
  439. format_pcm.bitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
  440. format_pcm.containerSize = format_pcm.bitsPerSample;
  441. format_pcm.channelMask = GetChannelMask(device->FmtChans);
  442. format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
  443. SL_BYTEORDER_BIGENDIAN;
  444. format_pcm.representation = GetTypeRepresentation(device->FmtType);
  445. #else
  446. SLDataFormat_PCM format_pcm;
  447. format_pcm.formatType = SL_DATAFORMAT_PCM;
  448. format_pcm.numChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
  449. format_pcm.samplesPerSec = device->Frequency * 1000;
  450. format_pcm.bitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
  451. format_pcm.containerSize = format_pcm.bitsPerSample;
  452. format_pcm.channelMask = GetChannelMask(device->FmtChans);
  453. format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
  454. SL_BYTEORDER_BIGENDIAN;
  455. #endif
  456. audioSrc.pLocator = &loc_bufq;
  457. audioSrc.pFormat = &format_pcm;
  458. loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
  459. loc_outmix.outputMix = self->mOutputMix;
  460. audioSnk.pLocator = &loc_outmix;
  461. audioSnk.pFormat = NULL;
  462. ids[0] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
  463. reqs[0] = SL_BOOLEAN_TRUE;
  464. ids[1] = SL_IID_ANDROIDCONFIGURATION;
  465. reqs[1] = SL_BOOLEAN_FALSE;
  466. result = VCALL(self->mEngine,CreateAudioPlayer)(&self->mBufferQueueObj,
  467. &audioSrc, &audioSnk, COUNTOF(ids), ids, reqs
  468. );
  469. PRINTERR(result, "engine->CreateAudioPlayer");
  470. if(SL_RESULT_SUCCESS == result)
  471. {
  472. /* Set the stream type to "media" (games, music, etc), if possible. */
  473. SLAndroidConfigurationItf config;
  474. result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
  475. PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDCONFIGURATION");
  476. if(SL_RESULT_SUCCESS == result)
  477. {
  478. SLint32 streamType = SL_ANDROID_STREAM_MEDIA;
  479. result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE,
  480. &streamType, sizeof(streamType)
  481. );
  482. PRINTERR(result, "config->SetConfiguration");
  483. }
  484. /* Clear any error since this was optional. */
  485. result = SL_RESULT_SUCCESS;
  486. }
  487. if(SL_RESULT_SUCCESS == result)
  488. {
  489. result = VCALL(self->mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
  490. PRINTERR(result, "bufferQueue->Realize");
  491. }
  492. if(SL_RESULT_SUCCESS != result)
  493. {
  494. if(self->mBufferQueueObj != NULL)
  495. VCALL0(self->mBufferQueueObj,Destroy)();
  496. self->mBufferQueueObj = NULL;
  497. return ALC_FALSE;
  498. }
  499. return ALC_TRUE;
  500. }
  501. static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
  502. {
  503. ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
  504. SLAndroidSimpleBufferQueueItf bufferQueue;
  505. SLresult result;
  506. ll_ringbuffer_free(self->mRing);
  507. /* NOTE: Add an extra update since one period's worth of audio in the ring
  508. * buffer will always be left unfilled because one element of the ring
  509. * buffer will not be writeable, and we only write in period-sized chunks.
  510. */
  511. self->mRing = ll_ringbuffer_create(device->NumUpdates + 1,
  512. self->mFrameSize*device->UpdateSize);
  513. result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  514. &bufferQueue);
  515. PRINTERR(result, "bufferQueue->GetInterface");
  516. if(SL_RESULT_SUCCESS != result)
  517. return ALC_FALSE;
  518. result = VCALL(bufferQueue,RegisterCallback)(ALCopenslPlayback_process, self);
  519. PRINTERR(result, "bufferQueue->RegisterCallback");
  520. if(SL_RESULT_SUCCESS != result)
  521. return ALC_FALSE;
  522. ATOMIC_STORE_SEQ(&self->mKillNow, AL_FALSE);
  523. if(althrd_create(&self->mThread, ALCopenslPlayback_mixerProc, self) != althrd_success)
  524. {
  525. ERR("Failed to start mixer thread\n");
  526. return ALC_FALSE;
  527. }
  528. return ALC_TRUE;
  529. }
  530. static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
  531. {
  532. SLAndroidSimpleBufferQueueItf bufferQueue;
  533. SLPlayItf player;
  534. SLresult result;
  535. int res;
  536. if(ATOMIC_EXCHANGE_SEQ(&self->mKillNow, AL_TRUE))
  537. return;
  538. /* Lock the backend to ensure we don't flag the mixer to die and signal the
  539. * mixer to wake up in between it checking the flag and going to sleep and
  540. * wait for a wakeup (potentially leading to it never waking back up to see
  541. * the flag).
  542. */
  543. ALCopenslPlayback_lock(self);
  544. ALCopenslPlayback_unlock(self);
  545. alcnd_signal(&self->mCond);
  546. althrd_join(self->mThread, &res);
  547. result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
  548. PRINTERR(result, "bufferQueue->GetInterface");
  549. if(SL_RESULT_SUCCESS == result)
  550. {
  551. result = VCALL(player,SetPlayState)(SL_PLAYSTATE_STOPPED);
  552. PRINTERR(result, "player->SetPlayState");
  553. }
  554. result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  555. &bufferQueue);
  556. PRINTERR(result, "bufferQueue->GetInterface");
  557. if(SL_RESULT_SUCCESS == result)
  558. {
  559. result = VCALL0(bufferQueue,Clear)();
  560. PRINTERR(result, "bufferQueue->Clear");
  561. }
  562. if(SL_RESULT_SUCCESS == result)
  563. {
  564. result = VCALL(bufferQueue,RegisterCallback)(NULL, NULL);
  565. PRINTERR(result, "bufferQueue->RegisterCallback");
  566. }
  567. if(SL_RESULT_SUCCESS == result)
  568. {
  569. SLAndroidSimpleBufferQueueState state;
  570. do {
  571. althrd_yield();
  572. result = VCALL(bufferQueue,GetState)(&state);
  573. } while(SL_RESULT_SUCCESS == result && state.count > 0);
  574. PRINTERR(result, "bufferQueue->GetState");
  575. }
  576. ll_ringbuffer_free(self->mRing);
  577. self->mRing = NULL;
  578. }
  579. static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
  580. {
  581. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  582. ClockLatency ret;
  583. ALCopenslPlayback_lock(self);
  584. ret.ClockTime = GetDeviceClockTime(device);
  585. ret.Latency = ll_ringbuffer_read_space(self->mRing)*device->UpdateSize *
  586. DEVICE_CLOCK_RES / device->Frequency;
  587. ALCopenslPlayback_unlock(self);
  588. return ret;
  589. }
  590. typedef struct ALCopenslCapture {
  591. DERIVE_FROM_TYPE(ALCbackend);
  592. /* engine interfaces */
  593. SLObjectItf mEngineObj;
  594. SLEngineItf mEngine;
  595. /* recording interfaces */
  596. SLObjectItf mRecordObj;
  597. ll_ringbuffer_t *mRing;
  598. ALCuint mSplOffset;
  599. ALsizei mFrameSize;
  600. } ALCopenslCapture;
  601. static void ALCopenslCapture_process(SLAndroidSimpleBufferQueueItf bq, void *context);
  602. static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device);
  603. static void ALCopenslCapture_Destruct(ALCopenslCapture *self);
  604. static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name);
  605. static void ALCopenslCapture_close(ALCopenslCapture *self);
  606. static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, ALCboolean, reset)
  607. static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self);
  608. static void ALCopenslCapture_stop(ALCopenslCapture *self);
  609. static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples);
  610. static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self);
  611. static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, ClockLatency, getClockLatency)
  612. static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, void, lock)
  613. static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, void, unlock)
  614. DECLARE_DEFAULT_ALLOCATORS(ALCopenslCapture)
  615. DEFINE_ALCBACKEND_VTABLE(ALCopenslCapture);
  616. static void ALCopenslCapture_process(SLAndroidSimpleBufferQueueItf UNUSED(bq), void *context)
  617. {
  618. ALCopenslCapture *self = context;
  619. /* A new chunk has been written into the ring buffer, advance it. */
  620. ll_ringbuffer_write_advance(self->mRing, 1);
  621. }
  622. static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device)
  623. {
  624. ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
  625. SET_VTABLE2(ALCopenslCapture, ALCbackend, self);
  626. self->mEngineObj = NULL;
  627. self->mEngine = NULL;
  628. self->mRecordObj = NULL;
  629. self->mRing = NULL;
  630. self->mSplOffset = 0;
  631. self->mFrameSize = 0;
  632. }
  633. static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
  634. {
  635. ll_ringbuffer_free(self->mRing);
  636. self->mRing = NULL;
  637. if(self->mRecordObj != NULL)
  638. VCALL0(self->mRecordObj,Destroy)();
  639. self->mRecordObj = NULL;
  640. if(self->mEngineObj != NULL)
  641. VCALL0(self->mEngineObj,Destroy)();
  642. self->mEngineObj = NULL;
  643. self->mEngine = NULL;
  644. ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
  645. }
  646. static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name)
  647. {
  648. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  649. SLDataLocator_AndroidSimpleBufferQueue loc_bq;
  650. SLAndroidSimpleBufferQueueItf bufferQueue;
  651. SLDataLocator_IODevice loc_dev;
  652. SLDataSource audioSrc;
  653. SLDataSink audioSnk;
  654. SLresult result;
  655. if(!name)
  656. name = opensl_device;
  657. else if(strcmp(name, opensl_device) != 0)
  658. return ALC_INVALID_VALUE;
  659. result = slCreateEngine(&self->mEngineObj, 0, NULL, 0, NULL, NULL);
  660. PRINTERR(result, "slCreateEngine");
  661. if(SL_RESULT_SUCCESS == result)
  662. {
  663. result = VCALL(self->mEngineObj,Realize)(SL_BOOLEAN_FALSE);
  664. PRINTERR(result, "engine->Realize");
  665. }
  666. if(SL_RESULT_SUCCESS == result)
  667. {
  668. result = VCALL(self->mEngineObj,GetInterface)(SL_IID_ENGINE, &self->mEngine);
  669. PRINTERR(result, "engine->GetInterface");
  670. }
  671. if(SL_RESULT_SUCCESS == result)
  672. {
  673. /* Ensure the total length is at least 100ms */
  674. ALsizei length = maxi(device->NumUpdates * device->UpdateSize,
  675. device->Frequency / 10);
  676. /* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
  677. ALsizei update_len = clampi(device->NumUpdates*device->UpdateSize / 3,
  678. device->Frequency / 100,
  679. device->Frequency / 100 * 5);
  680. device->UpdateSize = update_len;
  681. device->NumUpdates = (length+update_len-1) / update_len;
  682. self->mFrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
  683. }
  684. loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
  685. loc_dev.deviceType = SL_IODEVICE_AUDIOINPUT;
  686. loc_dev.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
  687. loc_dev.device = NULL;
  688. audioSrc.pLocator = &loc_dev;
  689. audioSrc.pFormat = NULL;
  690. loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
  691. loc_bq.numBuffers = device->NumUpdates;
  692. #ifdef SL_DATAFORMAT_PCM_EX
  693. SLDataFormat_PCM_EX format_pcm;
  694. format_pcm.formatType = SL_DATAFORMAT_PCM_EX;
  695. format_pcm.numChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
  696. format_pcm.sampleRate = device->Frequency * 1000;
  697. format_pcm.bitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
  698. format_pcm.containerSize = format_pcm.bitsPerSample;
  699. format_pcm.channelMask = GetChannelMask(device->FmtChans);
  700. format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
  701. SL_BYTEORDER_BIGENDIAN;
  702. format_pcm.representation = GetTypeRepresentation(device->FmtType);
  703. #else
  704. SLDataFormat_PCM format_pcm;
  705. format_pcm.formatType = SL_DATAFORMAT_PCM;
  706. format_pcm.numChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
  707. format_pcm.samplesPerSec = device->Frequency * 1000;
  708. format_pcm.bitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
  709. format_pcm.containerSize = format_pcm.bitsPerSample;
  710. format_pcm.channelMask = GetChannelMask(device->FmtChans);
  711. format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
  712. SL_BYTEORDER_BIGENDIAN;
  713. #endif
  714. audioSnk.pLocator = &loc_bq;
  715. audioSnk.pFormat = &format_pcm;
  716. if(SL_RESULT_SUCCESS == result)
  717. {
  718. const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
  719. const SLboolean reqs[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE };
  720. result = VCALL(self->mEngine,CreateAudioRecorder)(&self->mRecordObj,
  721. &audioSrc, &audioSnk, COUNTOF(ids), ids, reqs
  722. );
  723. PRINTERR(result, "engine->CreateAudioRecorder");
  724. }
  725. if(SL_RESULT_SUCCESS == result)
  726. {
  727. /* Set the record preset to "generic", if possible. */
  728. SLAndroidConfigurationItf config;
  729. result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
  730. PRINTERR(result, "recordObj->GetInterface SL_IID_ANDROIDCONFIGURATION");
  731. if(SL_RESULT_SUCCESS == result)
  732. {
  733. SLuint32 preset = SL_ANDROID_RECORDING_PRESET_GENERIC;
  734. result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET,
  735. &preset, sizeof(preset)
  736. );
  737. PRINTERR(result, "config->SetConfiguration");
  738. }
  739. /* Clear any error since this was optional. */
  740. result = SL_RESULT_SUCCESS;
  741. }
  742. if(SL_RESULT_SUCCESS == result)
  743. {
  744. result = VCALL(self->mRecordObj,Realize)(SL_BOOLEAN_FALSE);
  745. PRINTERR(result, "recordObj->Realize");
  746. }
  747. if(SL_RESULT_SUCCESS == result)
  748. {
  749. self->mRing = ll_ringbuffer_create(device->NumUpdates + 1,
  750. device->UpdateSize * self->mFrameSize);
  751. result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  752. &bufferQueue);
  753. PRINTERR(result, "recordObj->GetInterface");
  754. }
  755. if(SL_RESULT_SUCCESS == result)
  756. {
  757. result = VCALL(bufferQueue,RegisterCallback)(ALCopenslCapture_process, self);
  758. PRINTERR(result, "bufferQueue->RegisterCallback");
  759. }
  760. if(SL_RESULT_SUCCESS == result)
  761. {
  762. ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
  763. ll_ringbuffer_data_t data[2];
  764. size_t i;
  765. ll_ringbuffer_get_write_vector(self->mRing, data);
  766. for(i = 0;i < data[0].len && SL_RESULT_SUCCESS == result;i++)
  767. {
  768. result = VCALL(bufferQueue,Enqueue)(data[0].buf + chunk_size*i, chunk_size);
  769. PRINTERR(result, "bufferQueue->Enqueue");
  770. }
  771. for(i = 0;i < data[1].len && SL_RESULT_SUCCESS == result;i++)
  772. {
  773. result = VCALL(bufferQueue,Enqueue)(data[1].buf + chunk_size*i, chunk_size);
  774. PRINTERR(result, "bufferQueue->Enqueue");
  775. }
  776. }
  777. if(SL_RESULT_SUCCESS != result)
  778. {
  779. if(self->mRecordObj != NULL)
  780. VCALL0(self->mRecordObj,Destroy)();
  781. self->mRecordObj = NULL;
  782. if(self->mEngineObj != NULL)
  783. VCALL0(self->mEngineObj,Destroy)();
  784. self->mEngineObj = NULL;
  785. self->mEngine = NULL;
  786. return ALC_INVALID_VALUE;
  787. }
  788. alstr_copy_cstr(&device->DeviceName, name);
  789. return ALC_NO_ERROR;
  790. }
  791. static void ALCopenslCapture_close(ALCopenslCapture *self)
  792. {
  793. ll_ringbuffer_free(self->mRing);
  794. self->mRing = NULL;
  795. if(self->mRecordObj != NULL)
  796. VCALL0(self->mRecordObj,Destroy)();
  797. self->mRecordObj = NULL;
  798. if(self->mEngineObj != NULL)
  799. VCALL0(self->mEngineObj,Destroy)();
  800. self->mEngineObj = NULL;
  801. self->mEngine = NULL;
  802. }
  803. static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self)
  804. {
  805. SLRecordItf record;
  806. SLresult result;
  807. result = VCALL(self->mRecordObj,GetInterface)(SL_IID_RECORD, &record);
  808. PRINTERR(result, "recordObj->GetInterface");
  809. if(SL_RESULT_SUCCESS == result)
  810. {
  811. result = VCALL(record,SetRecordState)(SL_RECORDSTATE_RECORDING);
  812. PRINTERR(result, "record->SetRecordState");
  813. }
  814. if(SL_RESULT_SUCCESS != result)
  815. {
  816. ALCopenslCapture_lock(self);
  817. aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice);
  818. ALCopenslCapture_unlock(self);
  819. return ALC_FALSE;
  820. }
  821. return ALC_TRUE;
  822. }
  823. static void ALCopenslCapture_stop(ALCopenslCapture *self)
  824. {
  825. SLRecordItf record;
  826. SLresult result;
  827. result = VCALL(self->mRecordObj,GetInterface)(SL_IID_RECORD, &record);
  828. PRINTERR(result, "recordObj->GetInterface");
  829. if(SL_RESULT_SUCCESS == result)
  830. {
  831. result = VCALL(record,SetRecordState)(SL_RECORDSTATE_PAUSED);
  832. PRINTERR(result, "record->SetRecordState");
  833. }
  834. }
  835. static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples)
  836. {
  837. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  838. ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
  839. SLAndroidSimpleBufferQueueItf bufferQueue;
  840. ll_ringbuffer_data_t data[2];
  841. SLresult result;
  842. size_t advance;
  843. ALCuint i;
  844. /* Read the desired samples from the ring buffer then advance its read
  845. * pointer.
  846. */
  847. ll_ringbuffer_get_read_vector(self->mRing, data);
  848. advance = 0;
  849. for(i = 0;i < samples;)
  850. {
  851. ALCuint rem = minu(samples - i, device->UpdateSize - self->mSplOffset);
  852. memcpy((ALCbyte*)buffer + i*self->mFrameSize,
  853. data[0].buf + self->mSplOffset*self->mFrameSize,
  854. rem * self->mFrameSize);
  855. self->mSplOffset += rem;
  856. if(self->mSplOffset == device->UpdateSize)
  857. {
  858. /* Finished a chunk, reset the offset and advance the read pointer. */
  859. self->mSplOffset = 0;
  860. advance++;
  861. data[0].len--;
  862. if(!data[0].len)
  863. data[0] = data[1];
  864. else
  865. data[0].buf += chunk_size;
  866. }
  867. i += rem;
  868. }
  869. ll_ringbuffer_read_advance(self->mRing, advance);
  870. result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  871. &bufferQueue);
  872. PRINTERR(result, "recordObj->GetInterface");
  873. /* Enqueue any newly-writable chunks in the ring buffer. */
  874. ll_ringbuffer_get_write_vector(self->mRing, data);
  875. for(i = 0;i < data[0].len && SL_RESULT_SUCCESS == result;i++)
  876. {
  877. result = VCALL(bufferQueue,Enqueue)(data[0].buf + chunk_size*i, chunk_size);
  878. PRINTERR(result, "bufferQueue->Enqueue");
  879. }
  880. for(i = 0;i < data[1].len && SL_RESULT_SUCCESS == result;i++)
  881. {
  882. result = VCALL(bufferQueue,Enqueue)(data[1].buf + chunk_size*i, chunk_size);
  883. PRINTERR(result, "bufferQueue->Enqueue");
  884. }
  885. if(SL_RESULT_SUCCESS != result)
  886. {
  887. ALCopenslCapture_lock(self);
  888. aluHandleDisconnect(device);
  889. ALCopenslCapture_unlock(self);
  890. return ALC_INVALID_DEVICE;
  891. }
  892. return ALC_NO_ERROR;
  893. }
  894. static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self)
  895. {
  896. ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
  897. return ll_ringbuffer_read_space(self->mRing) * device->UpdateSize;
  898. }
  899. typedef struct ALCopenslBackendFactory {
  900. DERIVE_FROM_TYPE(ALCbackendFactory);
  901. } ALCopenslBackendFactory;
  902. #define ALCOPENSLBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCopenslBackendFactory, ALCbackendFactory) } }
  903. static ALCboolean ALCopenslBackendFactory_init(ALCopenslBackendFactory* UNUSED(self))
  904. {
  905. return ALC_TRUE;
  906. }
  907. static void ALCopenslBackendFactory_deinit(ALCopenslBackendFactory* UNUSED(self))
  908. {
  909. }
  910. static ALCboolean ALCopenslBackendFactory_querySupport(ALCopenslBackendFactory* UNUSED(self), ALCbackend_Type type)
  911. {
  912. if(type == ALCbackend_Playback || type == ALCbackend_Capture)
  913. return ALC_TRUE;
  914. return ALC_FALSE;
  915. }
  916. static void ALCopenslBackendFactory_probe(ALCopenslBackendFactory* UNUSED(self), enum DevProbe type)
  917. {
  918. switch(type)
  919. {
  920. case ALL_DEVICE_PROBE:
  921. AppendAllDevicesList(opensl_device);
  922. break;
  923. case CAPTURE_DEVICE_PROBE:
  924. AppendAllDevicesList(opensl_device);
  925. break;
  926. }
  927. }
  928. static ALCbackend* ALCopenslBackendFactory_createBackend(ALCopenslBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
  929. {
  930. if(type == ALCbackend_Playback)
  931. {
  932. ALCopenslPlayback *backend;
  933. NEW_OBJ(backend, ALCopenslPlayback)(device);
  934. if(!backend) return NULL;
  935. return STATIC_CAST(ALCbackend, backend);
  936. }
  937. if(type == ALCbackend_Capture)
  938. {
  939. ALCopenslCapture *backend;
  940. NEW_OBJ(backend, ALCopenslCapture)(device);
  941. if(!backend) return NULL;
  942. return STATIC_CAST(ALCbackend, backend);
  943. }
  944. return NULL;
  945. }
  946. DEFINE_ALCBACKENDFACTORY_VTABLE(ALCopenslBackendFactory);
  947. ALCbackendFactory *ALCopenslBackendFactory_getFactory(void)
  948. {
  949. static ALCopenslBackendFactory factory = ALCOPENSLBACKENDFACTORY_INITIALIZER;
  950. return STATIC_CAST(ALCbackendFactory, &factory);
  951. }