opensl.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  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 "opensl.h"
  22. #include <jni.h>
  23. #include <array>
  24. #include <cstdlib>
  25. #include <cstring>
  26. #include <mutex>
  27. #include <new>
  28. #include <thread>
  29. #include <functional>
  30. #include "albit.h"
  31. #include "alnumeric.h"
  32. #include "alsem.h"
  33. #include "alstring.h"
  34. #include "althrd_setname.h"
  35. #include "core/device.h"
  36. #include "core/helpers.h"
  37. #include "core/logging.h"
  38. #include "dynload.h"
  39. #include "opthelpers.h"
  40. #include "ringbuffer.h"
  41. #include <SLES/OpenSLES.h>
  42. #include <SLES/OpenSLES_Android.h>
  43. #include <SLES/OpenSLES_AndroidConfiguration.h>
  44. namespace {
  45. using namespace std::string_view_literals;
  46. #if HAVE_DYNLOAD
  47. #define SLES_SYMBOLS(MAGIC) \
  48. MAGIC(slCreateEngine); \
  49. MAGIC(SL_IID_ANDROIDCONFIGURATION); \
  50. MAGIC(SL_IID_ANDROIDSIMPLEBUFFERQUEUE); \
  51. MAGIC(SL_IID_ENGINE); \
  52. MAGIC(SL_IID_PLAY); \
  53. MAGIC(SL_IID_RECORD);
  54. void *sles_handle;
  55. #define MAKE_SYMBOL(f) decltype(f) * p##f
  56. SLES_SYMBOLS(MAKE_SYMBOL)
  57. #undef MAKE_SYMBOL
  58. #ifndef IN_IDE_PARSER
  59. #define slCreateEngine (*pslCreateEngine)
  60. #define SL_IID_ANDROIDCONFIGURATION (*pSL_IID_ANDROIDCONFIGURATION)
  61. #define SL_IID_ANDROIDSIMPLEBUFFERQUEUE (*pSL_IID_ANDROIDSIMPLEBUFFERQUEUE)
  62. #define SL_IID_ENGINE (*pSL_IID_ENGINE)
  63. #define SL_IID_PLAY (*pSL_IID_PLAY)
  64. #define SL_IID_RECORD (*pSL_IID_RECORD)
  65. #endif
  66. #endif
  67. /* Helper macros */
  68. #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
  69. #define VCALL(obj, func) ((*(obj))->func((obj), EXTRACT_VCALL_ARGS
  70. #define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
  71. [[nodiscard]] constexpr auto GetDeviceName() noexcept { return "OpenSL"sv; }
  72. [[nodiscard]]
  73. constexpr SLuint32 GetChannelMask(DevFmtChannels chans) noexcept
  74. {
  75. switch(chans)
  76. {
  77. case DevFmtMono: return SL_SPEAKER_FRONT_CENTER;
  78. case DevFmtStereo: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
  79. case DevFmtQuad: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
  80. SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT;
  81. case DevFmtX51: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
  82. SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_SIDE_LEFT |
  83. SL_SPEAKER_SIDE_RIGHT;
  84. case DevFmtX61: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
  85. SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_CENTER |
  86. SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
  87. case DevFmtX71:
  88. case DevFmtX3D71: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
  89. SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT |
  90. SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT;
  91. case DevFmtX714: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
  92. SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY | SL_SPEAKER_BACK_LEFT |
  93. SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT |
  94. SL_SPEAKER_TOP_FRONT_LEFT | SL_SPEAKER_TOP_FRONT_RIGHT | SL_SPEAKER_TOP_BACK_LEFT |
  95. SL_SPEAKER_TOP_BACK_RIGHT;
  96. case DevFmtX7144:
  97. case DevFmtAmbi3D:
  98. break;
  99. }
  100. return 0;
  101. }
  102. #ifdef SL_ANDROID_DATAFORMAT_PCM_EX
  103. constexpr SLuint32 GetTypeRepresentation(DevFmtType type) noexcept
  104. {
  105. switch(type)
  106. {
  107. case DevFmtUByte:
  108. case DevFmtUShort:
  109. case DevFmtUInt:
  110. return SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT;
  111. case DevFmtByte:
  112. case DevFmtShort:
  113. case DevFmtInt:
  114. return SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
  115. case DevFmtFloat:
  116. return SL_ANDROID_PCM_REPRESENTATION_FLOAT;
  117. }
  118. return 0;
  119. }
  120. #endif
  121. constexpr SLuint32 GetByteOrderEndianness() noexcept
  122. {
  123. if(al::endian::native == al::endian::little)
  124. return SL_BYTEORDER_LITTLEENDIAN;
  125. return SL_BYTEORDER_BIGENDIAN;
  126. }
  127. constexpr const char *res_str(SLresult result) noexcept
  128. {
  129. switch(result)
  130. {
  131. case SL_RESULT_SUCCESS: return "Success";
  132. case SL_RESULT_PRECONDITIONS_VIOLATED: return "Preconditions violated";
  133. case SL_RESULT_PARAMETER_INVALID: return "Parameter invalid";
  134. case SL_RESULT_MEMORY_FAILURE: return "Memory failure";
  135. case SL_RESULT_RESOURCE_ERROR: return "Resource error";
  136. case SL_RESULT_RESOURCE_LOST: return "Resource lost";
  137. case SL_RESULT_IO_ERROR: return "I/O error";
  138. case SL_RESULT_BUFFER_INSUFFICIENT: return "Buffer insufficient";
  139. case SL_RESULT_CONTENT_CORRUPTED: return "Content corrupted";
  140. case SL_RESULT_CONTENT_UNSUPPORTED: return "Content unsupported";
  141. case SL_RESULT_CONTENT_NOT_FOUND: return "Content not found";
  142. case SL_RESULT_PERMISSION_DENIED: return "Permission denied";
  143. case SL_RESULT_FEATURE_UNSUPPORTED: return "Feature unsupported";
  144. case SL_RESULT_INTERNAL_ERROR: return "Internal error";
  145. case SL_RESULT_UNKNOWN_ERROR: return "Unknown error";
  146. case SL_RESULT_OPERATION_ABORTED: return "Operation aborted";
  147. case SL_RESULT_CONTROL_LOST: return "Control lost";
  148. #ifdef SL_RESULT_READONLY
  149. case SL_RESULT_READONLY: return "ReadOnly";
  150. #endif
  151. #ifdef SL_RESULT_ENGINEOPTION_UNSUPPORTED
  152. case SL_RESULT_ENGINEOPTION_UNSUPPORTED: return "Engine option unsupported";
  153. #endif
  154. #ifdef SL_RESULT_SOURCE_SINK_INCOMPATIBLE
  155. case SL_RESULT_SOURCE_SINK_INCOMPATIBLE: return "Source/Sink incompatible";
  156. #endif
  157. }
  158. return "Unknown error code";
  159. }
  160. inline void PrintErr(SLresult res, const char *str)
  161. {
  162. if(res != SL_RESULT_SUCCESS) UNLIKELY
  163. ERR("{}: {}", str, res_str(res));
  164. }
  165. struct OpenSLPlayback final : public BackendBase {
  166. explicit OpenSLPlayback(DeviceBase *device) noexcept : BackendBase{device} { }
  167. ~OpenSLPlayback() override;
  168. void process(SLAndroidSimpleBufferQueueItf bq) noexcept;
  169. int mixerProc();
  170. void open(std::string_view name) override;
  171. bool reset() override;
  172. void start() override;
  173. void stop() override;
  174. ClockLatency getClockLatency() override;
  175. /* engine interfaces */
  176. SLObjectItf mEngineObj{nullptr};
  177. SLEngineItf mEngine{nullptr};
  178. /* output mix interfaces */
  179. SLObjectItf mOutputMix{nullptr};
  180. /* buffer queue player interfaces */
  181. SLObjectItf mBufferQueueObj{nullptr};
  182. RingBufferPtr mRing{nullptr};
  183. al::semaphore mSem;
  184. std::mutex mMutex;
  185. uint mFrameSize{0};
  186. std::atomic<bool> mKillNow{true};
  187. std::thread mThread;
  188. };
  189. OpenSLPlayback::~OpenSLPlayback()
  190. {
  191. if(mBufferQueueObj)
  192. VCALL0(mBufferQueueObj,Destroy)();
  193. mBufferQueueObj = nullptr;
  194. if(mOutputMix)
  195. VCALL0(mOutputMix,Destroy)();
  196. mOutputMix = nullptr;
  197. if(mEngineObj)
  198. VCALL0(mEngineObj,Destroy)();
  199. mEngineObj = nullptr;
  200. mEngine = nullptr;
  201. }
  202. /* this callback handler is called every time a buffer finishes playing */
  203. void OpenSLPlayback::process(SLAndroidSimpleBufferQueueItf) noexcept
  204. {
  205. /* A note on the ringbuffer usage: The buffer queue seems to hold on to the
  206. * pointer passed to the Enqueue method, rather than copying the audio.
  207. * Consequently, the ringbuffer contains the audio that is currently queued
  208. * and waiting to play. This process() callback is called when a buffer is
  209. * finished, so we simply move the read pointer up to indicate the space is
  210. * available for writing again, and wake up the mixer thread to mix and
  211. * queue more audio.
  212. */
  213. mRing->readAdvance(1);
  214. mSem.post();
  215. }
  216. int OpenSLPlayback::mixerProc()
  217. {
  218. SetRTPriority();
  219. althrd_setname(GetMixerThreadName());
  220. SLPlayItf player;
  221. SLAndroidSimpleBufferQueueItf bufferQueue;
  222. SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  223. &bufferQueue)};
  224. PrintErr(result, "bufferQueue->GetInterface SL_IID_ANDROIDSIMPLEBUFFERQUEUE");
  225. if(SL_RESULT_SUCCESS == result)
  226. {
  227. result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
  228. PrintErr(result, "bufferQueue->GetInterface SL_IID_PLAY");
  229. }
  230. const size_t frame_step{mDevice->channelsFromFmt()};
  231. if(SL_RESULT_SUCCESS != result)
  232. mDevice->handleDisconnect("Failed to get playback buffer: {:#08x}", result);
  233. while(SL_RESULT_SUCCESS == result && !mKillNow.load(std::memory_order_acquire)
  234. && mDevice->Connected.load(std::memory_order_acquire))
  235. {
  236. if(mRing->writeSpace() == 0)
  237. {
  238. SLuint32 state{0};
  239. result = VCALL(player,GetPlayState)(&state);
  240. PrintErr(result, "player->GetPlayState");
  241. if(SL_RESULT_SUCCESS == result && state != SL_PLAYSTATE_PLAYING)
  242. {
  243. result = VCALL(player,SetPlayState)(SL_PLAYSTATE_PLAYING);
  244. PrintErr(result, "player->SetPlayState");
  245. }
  246. if(SL_RESULT_SUCCESS != result)
  247. {
  248. mDevice->handleDisconnect("Failed to start playback: {:#08x}", result);
  249. break;
  250. }
  251. if(mRing->writeSpace() == 0)
  252. {
  253. mSem.wait();
  254. continue;
  255. }
  256. }
  257. std::unique_lock<std::mutex> dlock{mMutex};
  258. auto data = mRing->getWriteVector();
  259. mDevice->renderSamples(data[0].buf,
  260. static_cast<uint>(data[0].len)*mDevice->mUpdateSize, frame_step);
  261. if(data[1].len > 0)
  262. mDevice->renderSamples(data[1].buf,
  263. static_cast<uint>(data[1].len)*mDevice->mUpdateSize, frame_step);
  264. const auto todo = size_t{data[0].len + data[1].len};
  265. mRing->writeAdvance(todo);
  266. dlock.unlock();
  267. for(size_t i{0};i < todo;i++)
  268. {
  269. if(!data[0].len)
  270. {
  271. data[0] = data[1];
  272. data[1].buf = nullptr;
  273. data[1].len = 0;
  274. }
  275. result = VCALL(bufferQueue,Enqueue)(data[0].buf, mDevice->mUpdateSize*mFrameSize);
  276. PrintErr(result, "bufferQueue->Enqueue");
  277. if(SL_RESULT_SUCCESS != result)
  278. {
  279. mDevice->handleDisconnect("Failed to queue audio: {:#08x}", result);
  280. break;
  281. }
  282. data[0].len--;
  283. data[0].buf += mDevice->mUpdateSize*mFrameSize;
  284. }
  285. }
  286. return 0;
  287. }
  288. void OpenSLPlayback::open(std::string_view name)
  289. {
  290. if(name.empty())
  291. name = GetDeviceName();
  292. else if(name != GetDeviceName())
  293. throw al::backend_exception{al::backend_error::NoDevice, "Device name \"{}\" not found",
  294. name};
  295. /* There's only one device, so if it's already open, there's nothing to do. */
  296. if(mEngineObj) return;
  297. // create engine
  298. SLresult result{slCreateEngine(&mEngineObj, 0, nullptr, 0, nullptr, nullptr)};
  299. PrintErr(result, "slCreateEngine");
  300. if(SL_RESULT_SUCCESS == result)
  301. {
  302. result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
  303. PrintErr(result, "engine->Realize");
  304. }
  305. if(SL_RESULT_SUCCESS == result)
  306. {
  307. result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
  308. PrintErr(result, "engine->GetInterface");
  309. }
  310. if(SL_RESULT_SUCCESS == result)
  311. {
  312. result = VCALL(mEngine,CreateOutputMix)(&mOutputMix, 0, nullptr, nullptr);
  313. PrintErr(result, "engine->CreateOutputMix");
  314. }
  315. if(SL_RESULT_SUCCESS == result)
  316. {
  317. result = VCALL(mOutputMix,Realize)(SL_BOOLEAN_FALSE);
  318. PrintErr(result, "outputMix->Realize");
  319. }
  320. if(SL_RESULT_SUCCESS != result)
  321. {
  322. if(mOutputMix)
  323. VCALL0(mOutputMix,Destroy)();
  324. mOutputMix = nullptr;
  325. if(mEngineObj)
  326. VCALL0(mEngineObj,Destroy)();
  327. mEngineObj = nullptr;
  328. mEngine = nullptr;
  329. throw al::backend_exception{al::backend_error::DeviceError,
  330. "Failed to initialize OpenSL device: {:#08x}", result};
  331. }
  332. mDeviceName = name;
  333. }
  334. bool OpenSLPlayback::reset()
  335. {
  336. SLresult result;
  337. if(mBufferQueueObj)
  338. VCALL0(mBufferQueueObj,Destroy)();
  339. mBufferQueueObj = nullptr;
  340. mRing = nullptr;
  341. mDevice->FmtChans = DevFmtStereo;
  342. mDevice->FmtType = DevFmtShort;
  343. setDefaultWFXChannelOrder();
  344. mFrameSize = mDevice->frameSizeFromFmt();
  345. const std::array<SLInterfaceID,2> ids{{ SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION }};
  346. const std::array<SLboolean,2> reqs{{ SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE }};
  347. SLDataLocator_OutputMix loc_outmix{};
  348. loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
  349. loc_outmix.outputMix = mOutputMix;
  350. SLDataSink audioSnk{};
  351. audioSnk.pLocator = &loc_outmix;
  352. audioSnk.pFormat = nullptr;
  353. SLDataLocator_AndroidSimpleBufferQueue loc_bufq{};
  354. loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
  355. loc_bufq.numBuffers = mDevice->mBufferSize / mDevice->mUpdateSize;
  356. SLDataSource audioSrc{};
  357. #ifdef SL_ANDROID_DATAFORMAT_PCM_EX
  358. SLAndroidDataFormat_PCM_EX format_pcm_ex{};
  359. format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
  360. format_pcm_ex.numChannels = mDevice->channelsFromFmt();
  361. format_pcm_ex.sampleRate = mDevice->mSampleRate * 1000;
  362. format_pcm_ex.bitsPerSample = mDevice->bytesFromFmt() * 8;
  363. format_pcm_ex.containerSize = format_pcm_ex.bitsPerSample;
  364. format_pcm_ex.channelMask = GetChannelMask(mDevice->FmtChans);
  365. format_pcm_ex.endianness = GetByteOrderEndianness();
  366. format_pcm_ex.representation = GetTypeRepresentation(mDevice->FmtType);
  367. audioSrc.pLocator = &loc_bufq;
  368. audioSrc.pFormat = &format_pcm_ex;
  369. result = VCALL(mEngine,CreateAudioPlayer)(&mBufferQueueObj, &audioSrc, &audioSnk, ids.size(),
  370. ids.data(), reqs.data());
  371. if(SL_RESULT_SUCCESS != result)
  372. #endif
  373. {
  374. /* Alter sample type according to what SLDataFormat_PCM can support. */
  375. switch(mDevice->FmtType)
  376. {
  377. case DevFmtByte: mDevice->FmtType = DevFmtUByte; break;
  378. case DevFmtUInt: mDevice->FmtType = DevFmtInt; break;
  379. case DevFmtFloat:
  380. case DevFmtUShort: mDevice->FmtType = DevFmtShort; break;
  381. case DevFmtUByte:
  382. case DevFmtShort:
  383. case DevFmtInt:
  384. break;
  385. }
  386. SLDataFormat_PCM format_pcm{};
  387. format_pcm.formatType = SL_DATAFORMAT_PCM;
  388. format_pcm.numChannels = mDevice->channelsFromFmt();
  389. format_pcm.samplesPerSec = mDevice->mSampleRate * 1000;
  390. format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
  391. format_pcm.containerSize = format_pcm.bitsPerSample;
  392. format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
  393. format_pcm.endianness = GetByteOrderEndianness();
  394. audioSrc.pLocator = &loc_bufq;
  395. audioSrc.pFormat = &format_pcm;
  396. result = VCALL(mEngine,CreateAudioPlayer)(&mBufferQueueObj, &audioSrc, &audioSnk, ids.size(),
  397. ids.data(), reqs.data());
  398. PrintErr(result, "engine->CreateAudioPlayer");
  399. }
  400. if(SL_RESULT_SUCCESS == result)
  401. {
  402. /* Set the stream type to "media" (games, music, etc), if possible. */
  403. SLAndroidConfigurationItf config;
  404. result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
  405. PrintErr(result, "bufferQueue->GetInterface SL_IID_ANDROIDCONFIGURATION");
  406. if(SL_RESULT_SUCCESS == result)
  407. {
  408. SLint32 streamType = SL_ANDROID_STREAM_MEDIA;
  409. result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE, &streamType,
  410. sizeof(streamType));
  411. PrintErr(result, "config->SetConfiguration");
  412. }
  413. /* Clear any error since this was optional. */
  414. result = SL_RESULT_SUCCESS;
  415. }
  416. if(SL_RESULT_SUCCESS == result)
  417. {
  418. result = VCALL(mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
  419. PrintErr(result, "bufferQueue->Realize");
  420. }
  421. if(SL_RESULT_SUCCESS == result)
  422. {
  423. const uint num_updates{mDevice->mBufferSize / mDevice->mUpdateSize};
  424. mRing = RingBuffer::Create(num_updates, mFrameSize*mDevice->mUpdateSize, true);
  425. }
  426. if(SL_RESULT_SUCCESS != result)
  427. {
  428. if(mBufferQueueObj)
  429. VCALL0(mBufferQueueObj,Destroy)();
  430. mBufferQueueObj = nullptr;
  431. return false;
  432. }
  433. return true;
  434. }
  435. void OpenSLPlayback::start()
  436. {
  437. mRing->reset();
  438. SLAndroidSimpleBufferQueueItf bufferQueue;
  439. SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  440. &bufferQueue)};
  441. PrintErr(result, "bufferQueue->GetInterface");
  442. if(SL_RESULT_SUCCESS == result)
  443. {
  444. result = VCALL(bufferQueue,RegisterCallback)(
  445. [](SLAndroidSimpleBufferQueueItf bq, void *context) noexcept
  446. { static_cast<OpenSLPlayback*>(context)->process(bq); }, this);
  447. PrintErr(result, "bufferQueue->RegisterCallback");
  448. }
  449. if(SL_RESULT_SUCCESS != result)
  450. throw al::backend_exception{al::backend_error::DeviceError,
  451. "Failed to register callback: {:#08x}", result};
  452. try {
  453. mKillNow.store(false, std::memory_order_release);
  454. mThread = std::thread(&OpenSLPlayback::mixerProc, this);
  455. }
  456. catch(std::exception& e) {
  457. throw al::backend_exception{al::backend_error::DeviceError,
  458. "Failed to start mixing thread: {}", e.what()};
  459. }
  460. }
  461. void OpenSLPlayback::stop()
  462. {
  463. if(mKillNow.exchange(true, std::memory_order_acq_rel) || !mThread.joinable())
  464. return;
  465. mSem.post();
  466. mThread.join();
  467. SLPlayItf player;
  468. SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player)};
  469. PrintErr(result, "bufferQueue->GetInterface");
  470. if(SL_RESULT_SUCCESS == result)
  471. {
  472. result = VCALL(player,SetPlayState)(SL_PLAYSTATE_STOPPED);
  473. PrintErr(result, "player->SetPlayState");
  474. }
  475. SLAndroidSimpleBufferQueueItf bufferQueue;
  476. result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
  477. PrintErr(result, "bufferQueue->GetInterface");
  478. if(SL_RESULT_SUCCESS == result)
  479. {
  480. result = VCALL0(bufferQueue,Clear)();
  481. PrintErr(result, "bufferQueue->Clear");
  482. }
  483. if(SL_RESULT_SUCCESS == result)
  484. {
  485. result = VCALL(bufferQueue,RegisterCallback)(nullptr, nullptr);
  486. PrintErr(result, "bufferQueue->RegisterCallback");
  487. }
  488. if(SL_RESULT_SUCCESS == result)
  489. {
  490. SLAndroidSimpleBufferQueueState state;
  491. do {
  492. std::this_thread::yield();
  493. result = VCALL(bufferQueue,GetState)(&state);
  494. } while(SL_RESULT_SUCCESS == result && state.count > 0);
  495. PrintErr(result, "bufferQueue->GetState");
  496. mRing->reset();
  497. }
  498. }
  499. ClockLatency OpenSLPlayback::getClockLatency()
  500. {
  501. ClockLatency ret;
  502. std::lock_guard<std::mutex> dlock{mMutex};
  503. ret.ClockTime = mDevice->getClockTime();
  504. ret.Latency = std::chrono::seconds{mRing->readSpace() * mDevice->mUpdateSize};
  505. ret.Latency /= mDevice->mSampleRate;
  506. return ret;
  507. }
  508. struct OpenSLCapture final : public BackendBase {
  509. explicit OpenSLCapture(DeviceBase *device) noexcept : BackendBase{device} { }
  510. ~OpenSLCapture() override;
  511. void process(SLAndroidSimpleBufferQueueItf bq) noexcept;
  512. void open(std::string_view name) override;
  513. void start() override;
  514. void stop() override;
  515. void captureSamples(std::byte *buffer, uint samples) override;
  516. uint availableSamples() override;
  517. /* engine interfaces */
  518. SLObjectItf mEngineObj{nullptr};
  519. SLEngineItf mEngine;
  520. /* recording interfaces */
  521. SLObjectItf mRecordObj{nullptr};
  522. RingBufferPtr mRing{nullptr};
  523. uint mSplOffset{0u};
  524. uint mFrameSize{0};
  525. };
  526. OpenSLCapture::~OpenSLCapture()
  527. {
  528. if(mRecordObj)
  529. VCALL0(mRecordObj,Destroy)();
  530. mRecordObj = nullptr;
  531. if(mEngineObj)
  532. VCALL0(mEngineObj,Destroy)();
  533. mEngineObj = nullptr;
  534. mEngine = nullptr;
  535. }
  536. void OpenSLCapture::process(SLAndroidSimpleBufferQueueItf) noexcept
  537. {
  538. /* A new chunk has been written into the ring buffer, advance it. */
  539. mRing->writeAdvance(1);
  540. }
  541. void OpenSLCapture::open(std::string_view name)
  542. {
  543. if(name.empty())
  544. name = GetDeviceName();
  545. else if(name != GetDeviceName())
  546. throw al::backend_exception{al::backend_error::NoDevice, "Device name \"{}\" not found",
  547. name};
  548. SLresult result{slCreateEngine(&mEngineObj, 0, nullptr, 0, nullptr, nullptr)};
  549. PrintErr(result, "slCreateEngine");
  550. if(SL_RESULT_SUCCESS == result)
  551. {
  552. result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
  553. PrintErr(result, "engine->Realize");
  554. }
  555. if(SL_RESULT_SUCCESS == result)
  556. {
  557. result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
  558. PrintErr(result, "engine->GetInterface");
  559. }
  560. if(SL_RESULT_SUCCESS == result)
  561. {
  562. mFrameSize = mDevice->frameSizeFromFmt();
  563. /* Ensure the total length is at least 100ms */
  564. uint length{std::max(mDevice->mBufferSize, mDevice->mSampleRate/10u)};
  565. /* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
  566. uint update_len{std::clamp(mDevice->mBufferSize/3u, mDevice->mSampleRate/100u,
  567. mDevice->mSampleRate/100u*5u)};
  568. uint num_updates{(length+update_len-1) / update_len};
  569. mRing = RingBuffer::Create(num_updates, update_len*mFrameSize, false);
  570. mDevice->mUpdateSize = update_len;
  571. mDevice->mBufferSize = static_cast<uint>(mRing->writeSpace() * update_len);
  572. }
  573. if(SL_RESULT_SUCCESS == result)
  574. {
  575. const std::array<SLInterfaceID,2> ids{{ SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION }};
  576. const std::array<SLboolean,2> reqs{{ SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE }};
  577. SLDataLocator_IODevice loc_dev{};
  578. loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
  579. loc_dev.deviceType = SL_IODEVICE_AUDIOINPUT;
  580. loc_dev.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
  581. loc_dev.device = nullptr;
  582. SLDataSource audioSrc{};
  583. audioSrc.pLocator = &loc_dev;
  584. audioSrc.pFormat = nullptr;
  585. SLDataLocator_AndroidSimpleBufferQueue loc_bq{};
  586. loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
  587. loc_bq.numBuffers = mDevice->mBufferSize / mDevice->mUpdateSize;
  588. SLDataSink audioSnk{};
  589. #ifdef SL_ANDROID_DATAFORMAT_PCM_EX
  590. SLAndroidDataFormat_PCM_EX format_pcm_ex{};
  591. format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
  592. format_pcm_ex.numChannels = mDevice->channelsFromFmt();
  593. format_pcm_ex.sampleRate = mDevice->mSampleRate * 1000;
  594. format_pcm_ex.bitsPerSample = mDevice->bytesFromFmt() * 8;
  595. format_pcm_ex.containerSize = format_pcm_ex.bitsPerSample;
  596. format_pcm_ex.channelMask = GetChannelMask(mDevice->FmtChans);
  597. format_pcm_ex.endianness = GetByteOrderEndianness();
  598. format_pcm_ex.representation = GetTypeRepresentation(mDevice->FmtType);
  599. audioSnk.pLocator = &loc_bq;
  600. audioSnk.pFormat = &format_pcm_ex;
  601. result = VCALL(mEngine,CreateAudioRecorder)(&mRecordObj, &audioSrc, &audioSnk,
  602. ids.size(), ids.data(), reqs.data());
  603. if(SL_RESULT_SUCCESS != result)
  604. #endif
  605. {
  606. /* Fallback to SLDataFormat_PCM only if it supports the desired
  607. * sample type.
  608. */
  609. if(mDevice->FmtType == DevFmtUByte || mDevice->FmtType == DevFmtShort
  610. || mDevice->FmtType == DevFmtInt)
  611. {
  612. SLDataFormat_PCM format_pcm{};
  613. format_pcm.formatType = SL_DATAFORMAT_PCM;
  614. format_pcm.numChannels = mDevice->channelsFromFmt();
  615. format_pcm.samplesPerSec = mDevice->mSampleRate * 1000;
  616. format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
  617. format_pcm.containerSize = format_pcm.bitsPerSample;
  618. format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
  619. format_pcm.endianness = GetByteOrderEndianness();
  620. audioSnk.pLocator = &loc_bq;
  621. audioSnk.pFormat = &format_pcm;
  622. result = VCALL(mEngine,CreateAudioRecorder)(&mRecordObj, &audioSrc, &audioSnk,
  623. ids.size(), ids.data(), reqs.data());
  624. }
  625. PrintErr(result, "engine->CreateAudioRecorder");
  626. }
  627. }
  628. if(SL_RESULT_SUCCESS == result)
  629. {
  630. /* Set the record preset to "generic", if possible. */
  631. SLAndroidConfigurationItf config;
  632. result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
  633. PrintErr(result, "recordObj->GetInterface SL_IID_ANDROIDCONFIGURATION");
  634. if(SL_RESULT_SUCCESS == result)
  635. {
  636. SLuint32 preset = SL_ANDROID_RECORDING_PRESET_GENERIC;
  637. result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET, &preset,
  638. sizeof(preset));
  639. PrintErr(result, "config->SetConfiguration");
  640. }
  641. /* Clear any error since this was optional. */
  642. result = SL_RESULT_SUCCESS;
  643. }
  644. if(SL_RESULT_SUCCESS == result)
  645. {
  646. result = VCALL(mRecordObj,Realize)(SL_BOOLEAN_FALSE);
  647. PrintErr(result, "recordObj->Realize");
  648. }
  649. SLAndroidSimpleBufferQueueItf bufferQueue;
  650. if(SL_RESULT_SUCCESS == result)
  651. {
  652. result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
  653. PrintErr(result, "recordObj->GetInterface");
  654. }
  655. if(SL_RESULT_SUCCESS == result)
  656. {
  657. result = VCALL(bufferQueue,RegisterCallback)(
  658. [](SLAndroidSimpleBufferQueueItf bq, void *context) noexcept
  659. { static_cast<OpenSLCapture*>(context)->process(bq); }, this);
  660. PrintErr(result, "bufferQueue->RegisterCallback");
  661. }
  662. if(SL_RESULT_SUCCESS == result)
  663. {
  664. const uint chunk_size{mDevice->mUpdateSize * mFrameSize};
  665. const auto silence = (mDevice->FmtType == DevFmtUByte) ? std::byte{0x80} : std::byte{0};
  666. auto data = mRing->getWriteVector();
  667. std::fill_n(data[0].buf, data[0].len*chunk_size, silence);
  668. std::fill_n(data[1].buf, data[1].len*chunk_size, silence);
  669. for(size_t i{0u};i < data[0].len && SL_RESULT_SUCCESS == result;i++)
  670. {
  671. result = VCALL(bufferQueue,Enqueue)(data[0].buf + chunk_size*i, chunk_size);
  672. PrintErr(result, "bufferQueue->Enqueue");
  673. }
  674. for(size_t i{0u};i < data[1].len && SL_RESULT_SUCCESS == result;i++)
  675. {
  676. result = VCALL(bufferQueue,Enqueue)(data[1].buf + chunk_size*i, chunk_size);
  677. PrintErr(result, "bufferQueue->Enqueue");
  678. }
  679. }
  680. if(SL_RESULT_SUCCESS != result)
  681. {
  682. if(mRecordObj)
  683. VCALL0(mRecordObj,Destroy)();
  684. mRecordObj = nullptr;
  685. if(mEngineObj)
  686. VCALL0(mEngineObj,Destroy)();
  687. mEngineObj = nullptr;
  688. mEngine = nullptr;
  689. throw al::backend_exception{al::backend_error::DeviceError,
  690. "Failed to initialize OpenSL device: {:#08x}", result};
  691. }
  692. mDeviceName = name;
  693. }
  694. void OpenSLCapture::start()
  695. {
  696. SLRecordItf record;
  697. SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
  698. PrintErr(result, "recordObj->GetInterface");
  699. if(SL_RESULT_SUCCESS == result)
  700. {
  701. result = VCALL(record,SetRecordState)(SL_RECORDSTATE_RECORDING);
  702. PrintErr(result, "record->SetRecordState");
  703. }
  704. if(SL_RESULT_SUCCESS != result)
  705. throw al::backend_exception{al::backend_error::DeviceError,
  706. "Failed to start capture: {:#08x}", result};
  707. }
  708. void OpenSLCapture::stop()
  709. {
  710. SLRecordItf record;
  711. SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
  712. PrintErr(result, "recordObj->GetInterface");
  713. if(SL_RESULT_SUCCESS == result)
  714. {
  715. result = VCALL(record,SetRecordState)(SL_RECORDSTATE_PAUSED);
  716. PrintErr(result, "record->SetRecordState");
  717. }
  718. }
  719. void OpenSLCapture::captureSamples(std::byte *buffer, uint samples)
  720. {
  721. const uint update_size{mDevice->mUpdateSize};
  722. const uint chunk_size{update_size * mFrameSize};
  723. /* Read the desired samples from the ring buffer then advance its read
  724. * pointer.
  725. */
  726. size_t adv_count{0};
  727. auto rdata = mRing->getReadVector();
  728. for(uint i{0};i < samples;)
  729. {
  730. const uint rem{std::min(samples - i, update_size - mSplOffset)};
  731. std::copy_n(rdata[0].buf + mSplOffset*size_t{mFrameSize}, rem*size_t{mFrameSize},
  732. buffer + i*size_t{mFrameSize});
  733. mSplOffset += rem;
  734. if(mSplOffset == update_size)
  735. {
  736. /* Finished a chunk, reset the offset and advance the read pointer. */
  737. mSplOffset = 0;
  738. ++adv_count;
  739. rdata[0].len -= 1;
  740. if(!rdata[0].len)
  741. rdata[0] = rdata[1];
  742. else
  743. rdata[0].buf += chunk_size;
  744. }
  745. i += rem;
  746. }
  747. SLAndroidSimpleBufferQueueItf bufferQueue{};
  748. if(mDevice->Connected.load(std::memory_order_acquire)) LIKELY
  749. {
  750. const SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
  751. &bufferQueue)};
  752. PrintErr(result, "recordObj->GetInterface");
  753. if(SL_RESULT_SUCCESS != result) UNLIKELY
  754. {
  755. mDevice->handleDisconnect("Failed to get capture buffer queue: {:#08x}", result);
  756. bufferQueue = nullptr;
  757. }
  758. }
  759. if(!bufferQueue || adv_count == 0)
  760. return;
  761. /* For each buffer chunk that was fully read, queue another writable buffer
  762. * chunk to keep the OpenSL queue full. This is rather convoluted, as a
  763. * result of the ring buffer holding more elements than are writable at a
  764. * given time. The end of the write vector increments when the read pointer
  765. * advances, which will "expose" a previously unwritable element. So for
  766. * every element that we've finished reading, we queue that many elements
  767. * from the end of the write vector.
  768. */
  769. mRing->readAdvance(adv_count);
  770. SLresult result{SL_RESULT_SUCCESS};
  771. auto wdata = mRing->getWriteVector();
  772. if(adv_count > wdata[1].len) LIKELY
  773. {
  774. auto len1 = std::min(wdata[0].len, adv_count-wdata[1].len);
  775. auto buf1 = wdata[0].buf + chunk_size*(wdata[0].len-len1);
  776. for(size_t i{0u};i < len1 && SL_RESULT_SUCCESS == result;i++)
  777. {
  778. result = VCALL(bufferQueue,Enqueue)(buf1 + chunk_size*i, chunk_size);
  779. PrintErr(result, "bufferQueue->Enqueue");
  780. }
  781. }
  782. if(wdata[1].len > 0)
  783. {
  784. auto len2 = std::min(wdata[1].len, adv_count);
  785. auto buf2 = wdata[1].buf + chunk_size*(wdata[1].len-len2);
  786. for(size_t i{0u};i < len2 && SL_RESULT_SUCCESS == result;i++)
  787. {
  788. result = VCALL(bufferQueue,Enqueue)(buf2 + chunk_size*i, chunk_size);
  789. PrintErr(result, "bufferQueue->Enqueue");
  790. }
  791. }
  792. }
  793. uint OpenSLCapture::availableSamples()
  794. { return static_cast<uint>(mRing->readSpace()*mDevice->mUpdateSize - mSplOffset); }
  795. } // namespace
  796. bool OSLBackendFactory::init()
  797. {
  798. #if HAVE_DYNLOAD
  799. if(!sles_handle)
  800. {
  801. #define SLES_LIBNAME "libOpenSLES.so"
  802. sles_handle = LoadLib(SLES_LIBNAME);
  803. if(!sles_handle)
  804. {
  805. WARN("Failed to load {}", SLES_LIBNAME);
  806. return false;
  807. }
  808. std::string missing_syms;
  809. #define LOAD_SYMBOL(f) do { \
  810. p##f = reinterpret_cast<decltype(p##f)>(GetSymbol(sles_handle, #f)); \
  811. if(p##f == nullptr) missing_syms += "\n" #f; \
  812. } while(0)
  813. SLES_SYMBOLS(LOAD_SYMBOL);
  814. #undef LOAD_SYMBOL
  815. if(!missing_syms.empty())
  816. {
  817. WARN("Missing expected symbols:{}", missing_syms);
  818. CloseLib(sles_handle);
  819. sles_handle = nullptr;
  820. return false;
  821. }
  822. }
  823. #endif
  824. return true;
  825. }
  826. bool OSLBackendFactory::querySupport(BackendType type)
  827. { return (type == BackendType::Playback || type == BackendType::Capture); }
  828. auto OSLBackendFactory::enumerate(BackendType type) -> std::vector<std::string>
  829. {
  830. switch(type)
  831. {
  832. case BackendType::Playback:
  833. case BackendType::Capture:
  834. return std::vector{std::string{GetDeviceName()}};
  835. }
  836. return {};
  837. }
  838. BackendPtr OSLBackendFactory::createBackend(DeviceBase *device, BackendType type)
  839. {
  840. if(type == BackendType::Playback)
  841. return BackendPtr{new OpenSLPlayback{device}};
  842. if(type == BackendType::Capture)
  843. return BackendPtr{new OpenSLCapture{device}};
  844. return nullptr;
  845. }
  846. BackendFactory &OSLBackendFactory::getFactory()
  847. {
  848. static OSLBackendFactory factory{};
  849. return factory;
  850. }